Merge branch 'Branch_1' of https://git.u8t.cn/tangxinyue/alipay-emulator into Branch_1

# Conflicts:
#	main.js
This commit is contained in:
tangxinyue 2026-05-27 16:48:30 +08:00
commit ca12683f7e
56 changed files with 2889 additions and 165 deletions

View File

@ -3,9 +3,10 @@
<view v-for="(item, index) in list" :key="index" class="item" @touchstart="touchStart($event, index)"
@touchmove="touchMove($event, index)" @touchend="touchEnd($event, index)"
:style="{ 'transform': 'translateX(' + swiperList[index] + 'px)', 'transition': swiperList[index] == 0 ? 'all 0.3s' : '' }">
<view class="avatar" v-if="type != 'xiaomi'">
<view class="avatar" v-if="type != 'xiaomi'" @click="goDetail(item,index)">
<!-- 显示文字头像 -->
<view v-if="type == 'ios' && item.name && item.avatarType === 'text'" class="text-avatar" :class="{'text-avatar-18':getAvatarLength(item.name)==2}">
<view v-if="type == 'ios' && item.name && item.avatarType === 'text'" class="text-avatar"
:class="{'text-avatar-18':getAvatarLength(item.name)==2}">
{{ getAvatarText(item.name) }}
</view>
<!-- 显示图片头像 -->
@ -30,7 +31,7 @@
<image v-else-if="type == 'vivo'&&(item.status==1||item.status==2)"
:src="`/static/image/call/vivoStatusIcon1.png`" mode="widthFix"> </image>
</view>
<view class="infoBox">
<view class="infoBox" @click="goDetail(item,index)">
<view class="left-box">
<view class="leftInfo">
<view class="title" :class="{ 'title-red': item.status == 3 }">
@ -133,7 +134,7 @@
</view>
<view class="form-item">
<text class="form-label">运营商</text>
<uni-data-select class="form-select" v-model="editForm.yys" :localdata="yysOptions" @change="onYysChange"
<uni-data-select class="form-select" v-model="editForm.yys" :localdata="yysOptions" @change="onYysChange"
:clear="false"></uni-data-select>
</view>
<view class="form-item">
@ -148,14 +149,14 @@
</view>
<view class="form-item">
<text class="form-label">卡几</text>
<uni-data-select class="form-select" v-model="editForm.kj" :localdata="kjOptions" @change="onKjChange"
<uni-data-select class="form-select" v-model="editForm.kj" :localdata="kjOptions" @change="onKjChange"
:clear="false"></uni-data-select>
</view>
<view class="form-item">
<text class="form-label">状态</text>
<uni-data-select class="form-select" v-model="editForm.status" :localdata="statusOptions" @change="onStatusChange"
:clear="false"></uni-data-select>
<uni-data-select class="form-select" v-model="editForm.status" :localdata="statusOptions"
@change="onStatusChange" :clear="false"></uni-data-select>
</view>
<view class="form-item">
<text class="form-label">电话备注</text>
@ -163,8 +164,8 @@
</view>
<view class="form-item">
<text class="form-label">头像类型</text>
<uni-data-select class="form-select" v-model="editForm.avatarType" :localdata="avatarTypeOptions" @change="onAvatarTypeChange"
:clear="false"></uni-data-select>
<uni-data-select class="form-select" v-model="editForm.avatarType" :localdata="avatarTypeOptions"
@change="onAvatarTypeChange" :clear="false"></uni-data-select>
</view>
<view class="form-item">
<text class="form-label">头像</text>
@ -216,7 +217,7 @@
</view>
<view class="form-item">
<text class="form-label">运营商 <text>*</text></text>
<uni-data-select class="form-select" v-model="addForm.yys" :localdata="yysOptions" @change="onAddYysChange"
<uni-data-select class="form-select" v-model="addForm.yys" :localdata="yysOptions" @change="onAddYysChange"
:clear="false"></uni-data-select>
</view>
<view class="form-item">
@ -227,12 +228,12 @@
</view>
<view class="form-item">
<text class="form-label">状态 <text>*</text></text>
<uni-data-select class="form-select" v-model="addForm.status" :localdata="statusOptions" @change="onAddStatusChange"
:clear="false"></uni-data-select>
<uni-data-select class="form-select" v-model="addForm.status" :localdata="statusOptions"
@change="onAddStatusChange" :clear="false"></uni-data-select>
</view>
<view class="form-item">
<text class="form-label">卡几</text>
<uni-data-select class="form-select" v-model="addForm.kj" :localdata="kjOptions" @change="onAddKjChange"
<uni-data-select class="form-select" v-model="addForm.kj" :localdata="kjOptions" @change="onAddKjChange"
:clear="false"></uni-data-select>
</view>
<view class="form-item">
@ -249,8 +250,8 @@
</view>
<view class="form-item">
<text class="form-label">头像类型</text>
<uni-data-select class="form-select" v-model="addForm.avatarType" :localdata="avatarTypeOptions" @change="onAddAvatarTypeChange"
:clear="false"></uni-data-select>
<uni-data-select class="form-select" v-model="addForm.avatarType" :localdata="avatarTypeOptions"
@change="onAddAvatarTypeChange" :clear="false"></uni-data-select>
</view>
<view class="form-item">
<text class="form-label">头像</text>
@ -304,8 +305,12 @@
import {
onUnload
} from "@dcloudio/uni-app";
import DateTimePicker from '@/components/dengrq-datetime-picker/dateTimePicker/index.vue';
import DateTimePicker from '@/components/dengrq-datetime-picker/dateTimePicker/index.vue'; import {
useStore
} from '@/store/index.js'
const {
setCallDetail
} = useStore()
const props = defineProps({
isHuise: {
type: Boolean,
@ -690,7 +695,13 @@
text: '文字头像'
}
]);
const goDetail = (value,index) => {
setCallDetail(value)
uni.navigateTo({
url:'/pages/call-log/detail/callDetail?type='+props.type+'&index='+index
})
};
//
const getKjText = (value) => {
return value || '请选择';
@ -795,7 +806,7 @@
editForm.kj = item.kj || '1';
editForm.address = item.address || '';
editForm.time = item.time || '';
editForm.status = item.status ||0;
editForm.status = item.status || 0;
editForm.notes = item.notes || '';
showEditModal.value = true;
};
@ -1093,7 +1104,7 @@
//
const cleanStr = str.replace(/\s+/g, '');
if (cleanStr.length <= 3) {
if (cleanStr.length !=11) {
return cleanStr;
}
@ -1121,61 +1132,61 @@
}
function choose() {
uni.chooseImage({
count: 1,
sourceType: [ 'album' , 'camera'],
maxDuration: 30,
camera: 'back',
success(res) {
let tempFilePath = res.tempFiles[0].path
//
uni.saveFile({
tempFilePath: tempFilePath,
success: function(ress) {
// 使
const localPath = ress.savedFilePath;
if (showEditModal.value) {
editForm.avatar = localPath;
} else if (showAddModal.value) {
addForm.avatar = localPath;
uni.chooseImage({
count: 1,
sourceType: ['album', 'camera'],
maxDuration: 30,
camera: 'back',
success(res) {
let tempFilePath = res.tempFiles[0].path
//
uni.saveFile({
tempFilePath: tempFilePath,
success: function(ress) {
// 使
const localPath = ress.savedFilePath;
if (showEditModal.value) {
editForm.avatar = localPath;
} else if (showAddModal.value) {
addForm.avatar = localPath;
}
//
uni.showToast({
title: '图片保存成功',
icon: 'success'
});
},
fail: function(err) {
console.log('保存文件失败:', err);
// 使
if (showEditModal.value) {
editForm.avatar = tempFilePath;
} else if (showAddModal.value) {
addForm.avatar = tempFilePath;
}
uni.showToast({
title: '图片保存失败,使用临时路径',
icon: 'none'
});
}
//
uni.showToast({
title: '图片保存成功',
icon: 'success'
});
},
fail: function(err) {
console.log('保存文件失败:', err);
// 使
if (showEditModal.value) {
editForm.avatar = tempFilePath;
} else if (showAddModal.value) {
addForm.avatar = tempFilePath;
}
uni.showToast({
title: '图片保存失败,使用临时路径',
icon: 'none'
});
}
});
},
fail(err) {
console.log('选择图片失败:', err);
uni.showToast({
title: '选择图片失败',
icon: 'none'
});
}
})
}
});
},
fail(err) {
console.log('选择图片失败:', err);
uni.showToast({
title: '选择图片失败',
icon: 'none'
});
}
})
}
//
const getAvatarText = (name) => {
if (!name) return '';
//
const length = name.length;
if (length === 2) {
//
return name;
@ -1429,7 +1440,8 @@
padding: 24rpx 32rpx 24rpx 0;
height: 100%;
box-sizing: border-box;
box-shadow: 0 -0.3px 0 0 #C2C2C2;
box-shadow: 0 -0.3px 0 0 #C2C2C2;
.left-box {
.title {
font-weight: 400;
@ -1528,10 +1540,11 @@
}
.call-list-oppo {
.kj{
.kj {
width: 20rpx !important;
height: 24rpx !important;
}
.item {
padding: 32rpx 36rpx 0 36rpx !important;
justify-content: space-between;
@ -1543,7 +1556,7 @@
padding-bottom: 36rpx;
height: 100%;
box-sizing: border-box;
box-shadow: 0 0.3px 0 0 #C2C2C2;
box-shadow: 0 0.3px 0 0 #C2C2C2;
.title {
font-weight: 400;
@ -1603,7 +1616,7 @@
padding-bottom: 32rpx;
height: 100%;
box-sizing: border-box;
box-shadow: 0 0.3px 0 0 #C2C2C2;
box-shadow: 0 0.3px 0 0 #C2C2C2;
.title {
font-weight: 400;
@ -1645,10 +1658,11 @@
}
.call-list-huawei {
.kj{
.kj {
width: 18rpx !important;
height: 22rpx !important;
}
.item {
padding: 24rpx 32rpx 0 32rpx !important;
justify-content: space-between;
@ -1660,7 +1674,7 @@
padding-bottom: 24rpx;
height: 100%;
box-sizing: border-box;
box-shadow: 0 0.3px 0 0 #C2C2C2;
box-shadow: 0 0.3px 0 0 #C2C2C2;
.title {
font-weight: 400;
@ -1757,7 +1771,8 @@
font-size: 28rpx;
color: #666;
margin-bottom: 16rpx;
text{
text {
color: red;
}
}
@ -1772,18 +1787,22 @@
box-sizing: border-box;
color: #1A1A1A;
}
.form-select{
.form-select {
width: 364rpx !important;
flex: none;
}
.form-avatar-container {
display: flex;
align-items: center;
}
.suiji{
.suiji {
width: 50rpx;
height: 50rpx;
}
.form-avatar {
width: 80px;
height: 80px;
@ -1828,9 +1847,11 @@
font-weight: bold;
background: linear-gradient(180deg, #A1A8B8 0%, #878B94 100%);
}
.text-avatar-18{
font-size: 36rpx !important;
}
.text-avatar-18 {
font-size: 36rpx !important;
}
.form-input-time {
line-height: 40px;
}

View File

@ -6,10 +6,7 @@
</view>
</view>
<view class="footer footerZhangwei" :class="['footer_'+type]">
<view class="item" v-for="(item,index) in list" :key="index">
<image :src="`/static/image/call/${type}TabbarImg${index+1}.png`" mode=""></image>
<text>{{item}}</text>
</view>
</view>
</template>
@ -86,10 +83,7 @@
</script>
<style scoped lang="scss">
.footerZhangwei{
position: relative !important;
opacity: 0 !important;
}
.footer {
position: fixed;
left: 0;
@ -98,7 +92,7 @@
display: flex;
justify-content: space-around;
background: #f7f7f7;
padding-top: 2px;
.item {
display: flex;
flex-direction: column;
@ -118,7 +112,6 @@
}
.footer_ios {
padding-top: 2px;
padding-bottom: constant(safe-area-inset-bottom) !important; // IOS<11.2
padding-bottom: env(safe-area-inset-bottom) !important; // IOS>11.2
.item:nth-child(2) {
@ -127,6 +120,13 @@
}
}
}
.footerZhangwei{
position: relative !important;
opacity: 0 !important;
padding-top: 0 !important;
height: 47px;
background-color: rgba(0, 0, 0, 0) !important;
}
.footer_huawei {
background: #FAFAFA !important;
padding-top: 3px;

View File

@ -60,7 +60,7 @@ export default {
justify-content: center;
z-index: 99 !important;
background-image: url('/static/image/watermarkBG.png');
background-size: 125px 125px;
background-size: 500rpx 500rpx;
.watermarkBox {
width: 200px;

View File

@ -29,7 +29,7 @@ export function createApp() {
app.config.globalProperties.$system = plus.os.name;
// #endif
app.config.globalProperties.$systemInfo = systemInfo
uni.setStorageSync('version', '1.0.5.sp12')
uni.setStorageSync('version', '1.0.5.sp11')
app.config.globalProperties.$version = uni.getStorageSync('version')
app.use(globalMethods);
return {

View File

@ -17,6 +17,12 @@
"navigationBarTitleText": "通话记录页面",
"navigationStyle": "custom"
}
},{
"path": "detail/callDetail",
"style": {
"navigationBarTitleText": "通话记录详情",
"navigationStyle": "custom"
}
}]
},
{

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,108 +1,127 @@
import { reactive, ref, watch } from 'vue';
import { storage } from '../utils/storage';
import {
reactive,
ref,
watch
} from 'vue';
import {
storage
} from '../utils/storage';
// 防抖函数
const debounce = (fn, delay = 300) => {
let timer = null
return function (...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
// 定义应用的全局状态
export const store = reactive({
// 用户信息
userInfo: storage.get('userInfo') || null,
// 用户信息
userInfo: storage.get('userInfo') || null,
// 应用设置
settings: storage.get('settings') || {
theme: 'light',
language: 'zh-CN',
notifications: true
},
// 应用设置
settings: storage.get('settings') || {
theme: 'light',
language: 'zh-CN',
notifications: true
},
// 系统信息(从缓存读取,避免重复调用)
systemInfo: uni.getStorageSync('systemInfo') || {
statusBarHeight: 0,
windowHeight: 0,
windowWidth: 0,
platform: ''
},
// 系统信息(从缓存读取,避免重复调用)
systemInfo: uni.getStorageSync('systemInfo') || {
statusBarHeight: 0,
windowHeight: 0,
windowWidth: 0,
platform: ''
},
// 账单列表
billList: JSON.parse(JSON.stringify(storage.get('bill_list') || [])),
// 账单列表
billList: JSON.parse(JSON.stringify(storage.get('bill_list') || [])),
callInfo: {}
});
// 定义操作方法
export const useStore = () => {
// 账单相关操作
const addBill = (bill) => {
store.billList.unshift(bill);
return bill;
};
// 账单相关操作
const addBill = (bill) => {
store.billList.unshift(bill);
return bill;
};
const updateBill = (id, updates) => {
const index = store.billList.findIndex(bill => bill.id === id);
if (index !== -1) {
store.billList[index] = { ...store.billList[index], ...updates };
return store.billList[index];
}
return null;
};
const updateBill = (id, updates) => {
const index = store.billList.findIndex(bill => bill.id === id);
if (index !== -1) {
store.billList[index] = {
...store.billList[index],
...updates
};
return store.billList[index];
}
return null;
};
const deleteBill = (id) => {
const index = store.billList.findIndex(bill => bill.id === id);
if (index !== -1) {
store.billList.splice(index, 1);
return true;
}
return false;
};
const deleteBill = (id) => {
const index = store.billList.findIndex(bill => bill.id === id);
if (index !== -1) {
store.billList.splice(index, 1);
return true;
}
return false;
};
const getBillList = () => {
return JSON.parse(JSON.stringify(store.billList))
}
return {
store,
addBill,
updateBill,
deleteBill,
getBillList
};
const getBillList = () => {
return JSON.parse(JSON.stringify(store.billList))
}
const getCallDetail = () => {
return JSON.parse(JSON.stringify(store.callInfo))
}
const setCallDetail = (info) => {
return store.callInfo = info
};
return {
store,
addBill,
updateBill,
deleteBill,
getBillList,
setCallDetail,
getCallDetail
};
};
// 优化后的监听:使用防抖减少存储频率
const debouncedSaveSettings = debounce((newValue) => {
storage.set('settings', newValue)
storage.set('settings', newValue)
}, 500)
watch(
() => store.userInfo,
(newValue) => storage.set('userInfo', newValue),
{ deep: true }
() => store.userInfo,
(newValue) => storage.set('userInfo', newValue), {
deep: true
}
);
watch(
() => store.settings,
(newValue) => debouncedSaveSettings(newValue),
{ deep: true }
() => store.settings,
(newValue) => debouncedSaveSettings(newValue), {
deep: true
}
);
// 监听billList改变自动保存
watch(
() => store.billList,
(newValue) => {
console.log("store.billList changed, saving...")
storage.set('bill_list', newValue)
},
{ deep: true }
);
() => store.billList,
(newValue) => {
console.log("store.billList changed, saving...")
storage.set('bill_list', newValue)
}, {
deep: true
}
);