Compare commits
2 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
9d14b1bb0d | |
|
|
3da8a73f1d |
5
App.vue
|
|
@ -163,9 +163,6 @@ export default {
|
||||||
Object.keys(storageData).forEach(key => {
|
Object.keys(storageData).forEach(key => {
|
||||||
uni.setStorageSync(key, storageData[key])
|
uni.setStorageSync(key, storageData[key])
|
||||||
})
|
})
|
||||||
if (extraData['isCombo']) {
|
|
||||||
uni.setStorageSync('isCombo', extraData['isCombo'])
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -177,7 +174,7 @@ export default {
|
||||||
// 批量设置开发环境配置
|
// 批量设置开发环境配置
|
||||||
const devConfig = {
|
const devConfig = {
|
||||||
host: "https://flaunt.batiao8.com/",
|
host: "https://flaunt.batiao8.com/",
|
||||||
header: { "x-token": "da884e6e-fbd7-4d8d-ab0e-cb7b07f9f6fa" },
|
header: { "x-token": "ebe14dab-1879-4c5d-9148-727b96b30aad" },
|
||||||
decrypt: "e4rOtnF8tJjtHO7ecZeJHN1rapED5ImB",
|
decrypt: "e4rOtnF8tJjtHO7ecZeJHN1rapED5ImB",
|
||||||
encrypt: "xn08hYoizXhZ1zHP8DVqfCm2yHxPmhil"
|
encrypt: "xn08hYoizXhZ1zHP8DVqfCm2yHxPmhil"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,401 +130,401 @@ text {
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-2 {
|
.codefun-ml-2 {
|
||||||
margin-left: 2px;
|
margin-left: 4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-2 {
|
.codefun-mt-2 {
|
||||||
margin-top: 2px;
|
margin-top: 4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-4 {
|
.codefun-ml-4 {
|
||||||
margin-left: 4px;
|
margin-left: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-4 {
|
.codefun-mt-4 {
|
||||||
margin-top: 4px;
|
margin-top: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-6 {
|
.codefun-ml-6 {
|
||||||
margin-left: 6px;
|
margin-left: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-6 {
|
.codefun-mt-6 {
|
||||||
margin-top: 6px;
|
margin-top: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-8 {
|
.codefun-ml-8 {
|
||||||
margin-left: 8px;
|
margin-left: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-8 {
|
.codefun-mt-8 {
|
||||||
margin-top: 8px;
|
margin-top: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-10 {
|
.codefun-ml-10 {
|
||||||
margin-left: 10px;
|
margin-left: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-10 {
|
.codefun-mt-10 {
|
||||||
margin-top: 10px;
|
margin-top: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-12 {
|
.codefun-ml-12 {
|
||||||
margin-left: 12px;
|
margin-left: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-12 {
|
.codefun-mt-12 {
|
||||||
margin-top: 12px;
|
margin-top: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-14 {
|
.codefun-ml-14 {
|
||||||
margin-left: 14px;
|
margin-left: 28rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-14 {
|
.codefun-mt-14 {
|
||||||
margin-top: 14px;
|
margin-top: 28rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-16 {
|
.codefun-ml-16 {
|
||||||
margin-left: 16px;
|
margin-left: 32rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-16 {
|
.codefun-mt-16 {
|
||||||
margin-top: 16px;
|
margin-top: 32rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-18 {
|
.codefun-ml-18 {
|
||||||
margin-left: 18px;
|
margin-left: 36rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-18 {
|
.codefun-mt-18 {
|
||||||
margin-top: 18px;
|
margin-top: 36rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-20 {
|
.codefun-ml-20 {
|
||||||
margin-left: 20px;
|
margin-left: 40rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-20 {
|
.codefun-mt-20 {
|
||||||
margin-top: 20px;
|
margin-top: 40rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-22 {
|
.codefun-ml-22 {
|
||||||
margin-left: 22px;
|
margin-left: 44rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-22 {
|
.codefun-mt-22 {
|
||||||
margin-top: 22px;
|
margin-top: 44rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-24 {
|
.codefun-ml-24 {
|
||||||
margin-left: 24px;
|
margin-left: 48rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-24 {
|
.codefun-mt-24 {
|
||||||
margin-top: 24px;
|
margin-top: 48rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-26 {
|
.codefun-ml-26 {
|
||||||
margin-left: 26px;
|
margin-left: 52rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-26 {
|
.codefun-mt-26 {
|
||||||
margin-top: 26px;
|
margin-top: 52rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-28 {
|
.codefun-ml-28 {
|
||||||
margin-left: 28px;
|
margin-left: 56rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-28 {
|
.codefun-mt-28 {
|
||||||
margin-top: 28px;
|
margin-top: 56rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-30 {
|
.codefun-ml-30 {
|
||||||
margin-left: 30px;
|
margin-left: 60rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-30 {
|
.codefun-mt-30 {
|
||||||
margin-top: 30px;
|
margin-top: 60rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-32 {
|
.codefun-ml-32 {
|
||||||
margin-left: 32px;
|
margin-left: 64rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-32 {
|
.codefun-mt-32 {
|
||||||
margin-top: 32px;
|
margin-top: 64rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-34 {
|
.codefun-ml-34 {
|
||||||
margin-left: 34px;
|
margin-left: 68rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-34 {
|
.codefun-mt-34 {
|
||||||
margin-top: 34px;
|
margin-top: 68rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-36 {
|
.codefun-ml-36 {
|
||||||
margin-left: 36px;
|
margin-left: 72rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-36 {
|
.codefun-mt-36 {
|
||||||
margin-top: 36px;
|
margin-top: 72rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-38 {
|
.codefun-ml-38 {
|
||||||
margin-left: 38px;
|
margin-left: 76rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-38 {
|
.codefun-mt-38 {
|
||||||
margin-top: 38px;
|
margin-top: 76rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-40 {
|
.codefun-ml-40 {
|
||||||
margin-left: 40px;
|
margin-left: 80rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-40 {
|
.codefun-mt-40 {
|
||||||
margin-top: 40px;
|
margin-top: 80rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-42 {
|
.codefun-ml-42 {
|
||||||
margin-left: 42px;
|
margin-left: 84rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-42 {
|
.codefun-mt-42 {
|
||||||
margin-top: 42px;
|
margin-top: 84rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-44 {
|
.codefun-ml-44 {
|
||||||
margin-left: 44px;
|
margin-left: 88rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-44 {
|
.codefun-mt-44 {
|
||||||
margin-top: 44px;
|
margin-top: 88rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-46 {
|
.codefun-ml-46 {
|
||||||
margin-left: 46px;
|
margin-left: 92rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-46 {
|
.codefun-mt-46 {
|
||||||
margin-top: 46px;
|
margin-top: 92rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-48 {
|
.codefun-ml-48 {
|
||||||
margin-left: 48px;
|
margin-left: 96rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-48 {
|
.codefun-mt-48 {
|
||||||
margin-top: 48px;
|
margin-top: 96rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-50 {
|
.codefun-ml-50 {
|
||||||
margin-left: 50px;
|
margin-left: 100rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-50 {
|
.codefun-mt-50 {
|
||||||
margin-top: 50px;
|
margin-top: 100rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-52 {
|
.codefun-ml-52 {
|
||||||
margin-left: 52px;
|
margin-left: 104rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-52 {
|
.codefun-mt-52 {
|
||||||
margin-top: 52px;
|
margin-top: 104rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-54 {
|
.codefun-ml-54 {
|
||||||
margin-left: 54px;
|
margin-left: 108rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-54 {
|
.codefun-mt-54 {
|
||||||
margin-top: 54px;
|
margin-top: 108rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-56 {
|
.codefun-ml-56 {
|
||||||
margin-left: 56px;
|
margin-left: 112rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-56 {
|
.codefun-mt-56 {
|
||||||
margin-top: 56px;
|
margin-top: 112rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-58 {
|
.codefun-ml-58 {
|
||||||
margin-left: 58px;
|
margin-left: 116rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-58 {
|
.codefun-mt-58 {
|
||||||
margin-top: 58px;
|
margin-top: 116rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-60 {
|
.codefun-ml-60 {
|
||||||
margin-left: 60px;
|
margin-left: 120rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-60 {
|
.codefun-mt-60 {
|
||||||
margin-top: 60px;
|
margin-top: 120rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-62 {
|
.codefun-ml-62 {
|
||||||
margin-left: 62px;
|
margin-left: 124rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-62 {
|
.codefun-mt-62 {
|
||||||
margin-top: 62px;
|
margin-top: 124rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-64 {
|
.codefun-ml-64 {
|
||||||
margin-left: 64px;
|
margin-left: 128rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-64 {
|
.codefun-mt-64 {
|
||||||
margin-top: 64px;
|
margin-top: 128rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-66 {
|
.codefun-ml-66 {
|
||||||
margin-left: 66px;
|
margin-left: 132rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-66 {
|
.codefun-mt-66 {
|
||||||
margin-top: 66px;
|
margin-top: 132rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-68 {
|
.codefun-ml-68 {
|
||||||
margin-left: 68px;
|
margin-left: 136rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-68 {
|
.codefun-mt-68 {
|
||||||
margin-top: 68px;
|
margin-top: 136rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-70 {
|
.codefun-ml-70 {
|
||||||
margin-left: 70px;
|
margin-left: 140rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-70 {
|
.codefun-mt-70 {
|
||||||
margin-top: 70px;
|
margin-top: 140rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-72 {
|
.codefun-ml-72 {
|
||||||
margin-left: 72px;
|
margin-left: 144rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-72 {
|
.codefun-mt-72 {
|
||||||
margin-top: 72px;
|
margin-top: 144rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-74 {
|
.codefun-ml-74 {
|
||||||
margin-left: 74px;
|
margin-left: 148rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-74 {
|
.codefun-mt-74 {
|
||||||
margin-top: 74px;
|
margin-top: 148rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-76 {
|
.codefun-ml-76 {
|
||||||
margin-left: 76px;
|
margin-left: 152rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-76 {
|
.codefun-mt-76 {
|
||||||
margin-top: 76px;
|
margin-top: 152rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-78 {
|
.codefun-ml-78 {
|
||||||
margin-left: 78px;
|
margin-left: 156rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-78 {
|
.codefun-mt-78 {
|
||||||
margin-top: 78px;
|
margin-top: 156rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-80 {
|
.codefun-ml-80 {
|
||||||
margin-left: 80px;
|
margin-left: 160rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-80 {
|
.codefun-mt-80 {
|
||||||
margin-top: 80px;
|
margin-top: 160rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-82 {
|
.codefun-ml-82 {
|
||||||
margin-left: 82px;
|
margin-left: 164rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-82 {
|
.codefun-mt-82 {
|
||||||
margin-top: 82px;
|
margin-top: 164rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-84 {
|
.codefun-ml-84 {
|
||||||
margin-left: 84px;
|
margin-left: 168rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-84 {
|
.codefun-mt-84 {
|
||||||
margin-top: 84px;
|
margin-top: 168rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-86 {
|
.codefun-ml-86 {
|
||||||
margin-left: 86px;
|
margin-left: 172rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-86 {
|
.codefun-mt-86 {
|
||||||
margin-top: 86px;
|
margin-top: 172rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-88 {
|
.codefun-ml-88 {
|
||||||
margin-left: 88px;
|
margin-left: 176rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-88 {
|
.codefun-mt-88 {
|
||||||
margin-top: 88px;
|
margin-top: 176rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-90 {
|
.codefun-ml-90 {
|
||||||
margin-left: 90px;
|
margin-left: 180rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-90 {
|
.codefun-mt-90 {
|
||||||
margin-top: 90px;
|
margin-top: 180rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-92 {
|
.codefun-ml-92 {
|
||||||
margin-left: 92px;
|
margin-left: 184rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-92 {
|
.codefun-mt-92 {
|
||||||
margin-top: 92px;
|
margin-top: 184rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-94 {
|
.codefun-ml-94 {
|
||||||
margin-left: 94px;
|
margin-left: 188rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-94 {
|
.codefun-mt-94 {
|
||||||
margin-top: 94px;
|
margin-top: 188rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-96 {
|
.codefun-ml-96 {
|
||||||
margin-left: 96px;
|
margin-left: 192rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-96 {
|
.codefun-mt-96 {
|
||||||
margin-top: 96px;
|
margin-top: 192rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-98 {
|
.codefun-ml-98 {
|
||||||
margin-left: 98px;
|
margin-left: 196rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-98 {
|
.codefun-mt-98 {
|
||||||
margin-top: 98px;
|
margin-top: 196rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-ml-100 {
|
.codefun-ml-100 {
|
||||||
margin-left: 100px;
|
margin-left: 200rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codefun-mt-100 {
|
.codefun-mt-100 {
|
||||||
margin-top: 100px;
|
margin-top: 200rpx;
|
||||||
}
|
}
|
||||||
|
|
@ -256,12 +256,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shrink-0 {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-column {
|
.flex-column {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,11 +282,6 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-align-start {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-justify-center {
|
.flex-justify-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
|
||||||
|
|
@ -1,225 +0,0 @@
|
||||||
<template>
|
|
||||||
<view class="header" :class="['header_'+type]">
|
|
||||||
<view class="title" v-if="type!='vivo'">
|
|
||||||
{{title}}
|
|
||||||
</view>
|
|
||||||
<view class="search" v-if="type!='oppo'&&type!='huawei'&&type!='vivo'">
|
|
||||||
<view class="left">
|
|
||||||
<image src="/static/image/call/iosSearchLeft.png" mode=""></image>
|
|
||||||
{{searchTitle}}
|
|
||||||
</view>
|
|
||||||
<image v-if="type=='ios'" src="/static/image/call/iosSearchRight.png" mode=""></image>
|
|
||||||
</view>
|
|
||||||
<view class="selectType" v-if="type=='huawei'">
|
|
||||||
<view class="btn " :class="{'active':active}" @click.stop="setActive(true)">
|
|
||||||
全部来电
|
|
||||||
</view>
|
|
||||||
<view class="btn" :class="{'active':!active}" @click.stop="setActive(false)">
|
|
||||||
未接来电
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="selectTypeVivo" v-if="type=='vivo'">
|
|
||||||
<view class="btn " :class="{'active':active}" @click.stop="setActive(true)">
|
|
||||||
全部
|
|
||||||
</view>
|
|
||||||
<view class="btn" :class="{'active':!active}" @click.stop="setActive(false)">
|
|
||||||
未接
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="select" v-if="type=='xiaomi'">
|
|
||||||
全部通话
|
|
||||||
<image src="/static/image/call/xiaomiHeaderSelectImg.png" mode=""></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import {
|
|
||||||
onMounted,
|
|
||||||
reactive,
|
|
||||||
ref,
|
|
||||||
toRefs
|
|
||||||
} from 'vue'
|
|
||||||
|
|
||||||
const topPopup = ref()
|
|
||||||
|
|
||||||
// 定义组件属性
|
|
||||||
const props = defineProps({
|
|
||||||
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'ios'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
active:true,
|
|
||||||
statusBarHeight: 0,
|
|
||||||
showTipLayer: true,
|
|
||||||
title:'最近通话',
|
|
||||||
searchTitle:"搜索",
|
|
||||||
list:[
|
|
||||||
"个人收藏",
|
|
||||||
"最近通话",
|
|
||||||
"通讯录",
|
|
||||||
"拨号键盘",
|
|
||||||
"语音留言"
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
let {
|
|
||||||
active,
|
|
||||||
searchTitle,
|
|
||||||
title,
|
|
||||||
list,
|
|
||||||
showTipLayer
|
|
||||||
} = toRefs(data)
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if(props.type=='xiaomi'){
|
|
||||||
searchTitle.value="搜索联系人"
|
|
||||||
title.value="通话"
|
|
||||||
// console.log('aaaaaaaaaaa')
|
|
||||||
}else if(props.type=='oppo'){
|
|
||||||
title.value="通话"
|
|
||||||
}else if(props.type=='huawei'){
|
|
||||||
title.value="电话"
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
function setActive(status){
|
|
||||||
active.value=status
|
|
||||||
uni.$emit('setActive',status)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.header{
|
|
||||||
padding: 0 15px;
|
|
||||||
background-color: #fff;
|
|
||||||
.title{
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 32px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
.search{
|
|
||||||
margin-top: 10px;
|
|
||||||
width: 100%;
|
|
||||||
height: 34px;
|
|
||||||
background: #EEEEF0;
|
|
||||||
border-radius: 12px 12px 12px 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
.left{
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #838383;
|
|
||||||
}
|
|
||||||
image{
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin: 0 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.select{
|
|
||||||
padding-left: 15px;
|
|
||||||
margin-top: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #8B8DA5;
|
|
||||||
image{
|
|
||||||
width: 13px;
|
|
||||||
height: 13px;
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.selectTypeVivo{
|
|
||||||
padding-top: 18px;
|
|
||||||
height: 48px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
.btn{
|
|
||||||
width: 62px;
|
|
||||||
background-color: #F6F6F6;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #555555;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-radius: 8px 0 0 8px;
|
|
||||||
margin: 0 1px;
|
|
||||||
}
|
|
||||||
.btn:nth-child(2){
|
|
||||||
border-radius:0 8px 8px 0;
|
|
||||||
}
|
|
||||||
.active{
|
|
||||||
font-size: 13px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
background: #DCF6E6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.header_huawei{
|
|
||||||
padding-bottom: 14px;
|
|
||||||
.title{
|
|
||||||
padding-left: 3px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 30px !important;
|
|
||||||
color: #1A1A1A !important;
|
|
||||||
}
|
|
||||||
.selectType{
|
|
||||||
margin-top: 18px;
|
|
||||||
height: 38px;
|
|
||||||
background: #F4F4F4;
|
|
||||||
border-radius: 19px 19px 19px 19px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 2px;
|
|
||||||
.btn{
|
|
||||||
width: 50%;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #555555;
|
|
||||||
height: 34px;
|
|
||||||
line-height: 34px;
|
|
||||||
}
|
|
||||||
.active{
|
|
||||||
font-size: 13px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 19px 19px 19px 19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.header_xiaomi{
|
|
||||||
.title{
|
|
||||||
padding-left: 15px;
|
|
||||||
font-weight: 400 !important;
|
|
||||||
font-size: 30px !important;
|
|
||||||
color: #1A1A1A !important;
|
|
||||||
}
|
|
||||||
.search{
|
|
||||||
margin-top: 10px;
|
|
||||||
height: 41px !important;
|
|
||||||
background: #F0F0F0 !important;
|
|
||||||
border-radius: 21px 21px 21px 21px !important;
|
|
||||||
.left{
|
|
||||||
font-size: 16px !important;
|
|
||||||
color: #AAAAAA !important;
|
|
||||||
}
|
|
||||||
image{
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin: 0 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,375 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<uni-nav-bar :backgroundColor="navBgColor" class="nav-bar" :border="false" :title="title" fixed="true"
|
|
||||||
statusBar="true">
|
|
||||||
<template v-slot:left>
|
|
||||||
<slot name="left">
|
|
||||||
<view :class="[type+'LeftTitle']" :style="{opacity:(type!='huawei'&&type!='oppo'?1: navOpacity)}">
|
|
||||||
{{LeftTitle}}
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</slot>
|
|
||||||
</template>
|
|
||||||
<view class="nav-bar-title " :class="['nav-bar-title-'+type]">
|
|
||||||
<slot>
|
|
||||||
<view class="iosBox" v-if="type=='ios'">
|
|
||||||
<view class="btn " :class="{'active':active}" @click.stop="setActive(true)">
|
|
||||||
全部来电
|
|
||||||
</view>
|
|
||||||
<view class="btn" :class="{'active':!active}" @click.stop="setActive(false)">
|
|
||||||
未接来电
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="oppoBox" v-if="type=='oppo'" :style="{opacity: navOpacity?1-navOpacity:1}">
|
|
||||||
<view class="btn " :class="{'active':active}" @click.stop="setActive(true)">
|
|
||||||
全部
|
|
||||||
</view>
|
|
||||||
<view class="btn" :class="{'active':!active}" @click.stop="setActive(false)">
|
|
||||||
未接
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="title" v-else-if="type=='xiaomi'" :style="{opacity: navOpacity}">
|
|
||||||
通话
|
|
||||||
</view>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
<template v-slot:right>
|
|
||||||
<slot name="right">
|
|
||||||
<view class="rightImgBox" :class="['rightImgBox'+type]">
|
|
||||||
|
|
||||||
<image v-if="type=='oppo'||type=='vivo'" class="rightImg"
|
|
||||||
:src="`/static/image/call/${type}NavRightImg2.png`"></image>
|
|
||||||
<image v-if="type!='ios'" class="rightImg" :class="['rightImg_'+type]"
|
|
||||||
:src="`/static/image/call/${type}NavRightImg.png`"></image>
|
|
||||||
</view>
|
|
||||||
</slot>
|
|
||||||
</template>
|
|
||||||
</uni-nav-bar>
|
|
||||||
|
|
||||||
<view class="tipLayer" :style="{ top: `${45 + data.statusBarHeight}px` }" v-if="isTipLayer&&showTipLayer">
|
|
||||||
<view class="tipLayer-content">
|
|
||||||
<view class="title">
|
|
||||||
<slot name="tipLayer">点击此处<text>[{{ tipLayerText }}]</text></slot>
|
|
||||||
</view>
|
|
||||||
<image class="close" src="/static/image/common/tipLayer-close.png" mode="" @click="closeTipLayer"></image>
|
|
||||||
<image v-if="type=='ios'||type=='oppo'" class="triangleImg" src="/static/image/common/tipLayer-eye2.png"></image>
|
|
||||||
<image v-else class="triangleImg" src="/static/image/common/tipLayer-eye.png"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import {
|
|
||||||
onMounted,
|
|
||||||
reactive,
|
|
||||||
ref,
|
|
||||||
toRefs,
|
|
||||||
watch
|
|
||||||
} from 'vue'
|
|
||||||
|
|
||||||
const topPopup = ref()
|
|
||||||
|
|
||||||
// 定义组件属性
|
|
||||||
const props = defineProps({
|
|
||||||
bgColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#fff'
|
|
||||||
},
|
|
||||||
textColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#000'
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'ios'
|
|
||||||
},
|
|
||||||
scrollTop: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
tipLayerText: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
isTipLayer: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
active: true,
|
|
||||||
statusBarHeight: 0,
|
|
||||||
LeftTitle: '',
|
|
||||||
showTipLayer: true,
|
|
||||||
navOpacity: 0, // 导航栏透明度
|
|
||||||
navBgColor: props.bgColor // 导航栏背景色
|
|
||||||
})
|
|
||||||
|
|
||||||
let {
|
|
||||||
active,
|
|
||||||
LeftTitle,
|
|
||||||
showTipLayer,
|
|
||||||
navOpacity,
|
|
||||||
navBgColor
|
|
||||||
} = toRefs(data)
|
|
||||||
|
|
||||||
// 监听 scrollTop 变化
|
|
||||||
watch(() => props.scrollTop, (newValue, oldValue) => {
|
|
||||||
// console.log('scrollTop changed:', newValue);
|
|
||||||
// 根据 scrollTop 的值计算导航栏透明度
|
|
||||||
if (newValue > 0) {
|
|
||||||
// 当 scrollTop 大于 0 时,透明度逐渐增加
|
|
||||||
navOpacity.value = Math.min(1, newValue / 100);
|
|
||||||
// 可以根据需要调整背景色
|
|
||||||
// navBgColor.value = `rgba(255, 255, 255, ${navOpacity.value})`;
|
|
||||||
} else {
|
|
||||||
// 当 scrollTop 为 0 时,透明度为 1
|
|
||||||
navOpacity.value = 0;
|
|
||||||
// navBgColor.value = props.bgColor;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (props.type == 'ios') {
|
|
||||||
LeftTitle.value = '编辑'
|
|
||||||
} else if (props.type == 'vivo') {
|
|
||||||
LeftTitle.value = '拨号'
|
|
||||||
} else if (props.type == 'oppo') {
|
|
||||||
LeftTitle.value = '通话'
|
|
||||||
} else if (props.type == 'huawei') {
|
|
||||||
LeftTitle.value = '电话'
|
|
||||||
} else {
|
|
||||||
LeftTitle.value = ''
|
|
||||||
}
|
|
||||||
// 同步获取系统信息
|
|
||||||
const systemInfo = uni.getSystemInfoSync();
|
|
||||||
data.statusBarHeight = systemInfo.statusBarHeight || 0;
|
|
||||||
if (props.isTipLayer) {
|
|
||||||
if (uni.getStorageSync("call_" + props.type) == props.type) {
|
|
||||||
showTipLayer.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function setActive(status) {
|
|
||||||
active.value = status
|
|
||||||
uni.$emit('setActive', status)
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeTipLayer = () => {
|
|
||||||
showTipLayer.value = false
|
|
||||||
uni.setStorageSync("call_" + props.type, props.type)
|
|
||||||
emit("refresh")
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
::v-deep .uni-navbar__header-btns {
|
|
||||||
width: 27vw !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iosLeftTitle {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #018AE0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightImgBox {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightImg_oppo {
|
|
||||||
margin-left: 26px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightImg_vivo {
|
|
||||||
margin-left: 26px;
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.oppoLeftTitle {
|
|
||||||
padding-left: 8px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 32px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.huaweiLeftTitle {
|
|
||||||
padding-left: 8px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 30px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vivoLeftTitle {
|
|
||||||
padding-left: 34px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 30px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-bar-title-xiaomi {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-bar-title-oppo {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.oppoBox {
|
|
||||||
padding: 0 2px;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-around;
|
|
||||||
width: 137px;
|
|
||||||
height: 34px;
|
|
||||||
background: #E9E9E9;
|
|
||||||
border-radius: 17px 17px 17px 17px;
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #6B6B6B;
|
|
||||||
width: 67px;
|
|
||||||
height: 30px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
color: #1A1A1A;
|
|
||||||
background: #FFFFFF;
|
|
||||||
border-radius: 17px 17px 17px 17px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-bar-title-ios {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.iosBox {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-around;
|
|
||||||
width: 145px;
|
|
||||||
height: 30px;
|
|
||||||
background: #EEEEEE;
|
|
||||||
border-radius: 8px 8px 8px 8px;
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
width: 69px;
|
|
||||||
height: 26px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 26px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
background: #FFFFFF;
|
|
||||||
box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.1);
|
|
||||||
border-radius: 6px 6px 6px 6px;
|
|
||||||
margin: 0 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightImg_xiaomi {
|
|
||||||
width: 20px !important;
|
|
||||||
height: 20px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightImg_huawei {
|
|
||||||
width: 38px !important;
|
|
||||||
height: 38px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tipLayer {
|
|
||||||
box-sizing: border-box;
|
|
||||||
min-width: 200px !important;
|
|
||||||
height: 48px;
|
|
||||||
background: #B8EDFE;
|
|
||||||
border-radius: 8px 8px 8px 8px;
|
|
||||||
position: fixed;
|
|
||||||
/* top: 115px; */
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
.tipLayer-content {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-weight: 450;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #268FFF;
|
|
||||||
line-height: 48px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #006ADD;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep text {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #006ADD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.triangleImg {
|
|
||||||
width: 111px;
|
|
||||||
height: 52px;
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
top: -23px;
|
|
||||||
left: calc(50% - 111px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.triangle {
|
|
||||||
position: absolute;
|
|
||||||
top: -57px;
|
|
||||||
left: calc(50% - 40px);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close {
|
|
||||||
position: absolute;
|
|
||||||
top: -5px;
|
|
||||||
right: -5px;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,184 +0,0 @@
|
||||||
<template>
|
|
||||||
<view class="footer" :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>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import {
|
|
||||||
onMounted,
|
|
||||||
reactive,
|
|
||||||
ref,
|
|
||||||
toRefs
|
|
||||||
} from 'vue'
|
|
||||||
|
|
||||||
const topPopup = ref()
|
|
||||||
|
|
||||||
// 定义组件属性
|
|
||||||
const props = defineProps({
|
|
||||||
bgColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#fff'
|
|
||||||
},
|
|
||||||
textColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#000'
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'ios'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
statusBarHeight: 0,
|
|
||||||
showTipLayer: true,
|
|
||||||
list: [
|
|
||||||
"个人收藏",
|
|
||||||
"最近通话",
|
|
||||||
"通讯录",
|
|
||||||
"拨号键盘",
|
|
||||||
"语音留言"
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
let {
|
|
||||||
list,
|
|
||||||
showTipLayer
|
|
||||||
} = toRefs(data)
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (props.type == 'xiaomi') {
|
|
||||||
list.value = ["通话",
|
|
||||||
"联系人",
|
|
||||||
"营业厅"
|
|
||||||
]
|
|
||||||
}else if (props.type == 'oppo') {
|
|
||||||
list.value = ["通话",
|
|
||||||
"联系人",
|
|
||||||
"营业厅"
|
|
||||||
]
|
|
||||||
}else if (props.type == 'huawei') {
|
|
||||||
list.value = ["电话",
|
|
||||||
"联系人",
|
|
||||||
"收藏"
|
|
||||||
]
|
|
||||||
}else if (props.type == 'vivo') {
|
|
||||||
list.value = ["拨号",
|
|
||||||
"联系人",
|
|
||||||
"收藏"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.footerZhangwei{
|
|
||||||
position: relative !important;
|
|
||||||
opacity: 0 !important;
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
background: #f7f7f7;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
text-align: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-size: 10px;
|
|
||||||
color: #959597;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.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) {
|
|
||||||
text {
|
|
||||||
color: #007AFC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.footer_huawei {
|
|
||||||
background: #FAFAFA !important;
|
|
||||||
padding-top: 3px;
|
|
||||||
.item {
|
|
||||||
image {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item:nth-child(1) {
|
|
||||||
text {
|
|
||||||
color: #0060EA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.footer_vivo {
|
|
||||||
background: #FAFAFA !important;
|
|
||||||
padding-top: 13px;
|
|
||||||
padding-bottom: 13px;
|
|
||||||
.item {
|
|
||||||
image {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item:nth-child(1) {
|
|
||||||
text {
|
|
||||||
color: #1BA552;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer_xiaomi ,.footer_oppo{
|
|
||||||
padding-top: 7px;
|
|
||||||
padding-bottom: 17px;
|
|
||||||
background-color: #fff !important;
|
|
||||||
.item {
|
|
||||||
image {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-size: 10px;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item:nth-child(1) {
|
|
||||||
text {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,874 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<view v-for="(message, index) in displayList" :key="message.id || index" class="message-item" :class="{
|
|
||||||
isMe: message.isMe,
|
|
||||||
'm-t-16': shouldApplyMt16(index) && !shouldShowTime(index),
|
|
||||||
'is-sort-mode': sortMode,
|
|
||||||
'sort-dragging': sortMode && dragIndex === index,
|
|
||||||
'sort-drop-before': sortMode && dragOverIndex === index && dragIndex !== index && dropPosition === 'before',
|
|
||||||
'sort-drop-after': sortMode && dragOverIndex === index && dragIndex !== index && dropPosition === 'after'
|
|
||||||
}">
|
|
||||||
|
|
||||||
<!-- 排序模式下的拖拽手柄 -->
|
|
||||||
<view v-if="sortMode" class="sort-handle-wrap" @longpress="onSortLongPress(index, $event)"
|
|
||||||
@touchmove.stop.prevent="onSortTouchMove(index, $event)" @touchend.stop="onSortTouchEnd(index, $event)">
|
|
||||||
<view class="sort-handle-bar"></view>
|
|
||||||
<view class="sort-handle-bar"></view>
|
|
||||||
<view class="sort-handle-bar"></view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view style="flex: 1; overflow: hidden;">
|
|
||||||
<view class="time m-t-44" :id="'time-' + index" v-if="shouldShowTime(index)"
|
|
||||||
@longpress="!sortMode && onMessageLongPress(index, message, 'time')">
|
|
||||||
<view class="top-text" v-if="phone == 'iphone' && index == 0">信息 · 短信</view>
|
|
||||||
<view class="top-text" v-if="phone == 'huawei' && index == 0">短信/彩信</view>
|
|
||||||
<text v-if="phone == 'huawei'">{{ formatHuaweiTopTime(message.time) }}</text>
|
|
||||||
<text v-else>{{ formatChatTime(message.time) }} <text
|
|
||||||
v-if="(phone == 'oppo' || (phone == 'vivo' && message.isMe)) && message.simIndex">
|
|
||||||
{{ simInfo[`sim${message.simIndex}`] }}
|
|
||||||
</text></text>
|
|
||||||
|
|
||||||
<image style="width: 20rpx;height: 24rpx;margin-left: 8rpx; "
|
|
||||||
v-if="phone == 'oppo' || (phone == 'vivo' && message.isMe)"
|
|
||||||
:src="`/static/image/phone-message/huawei/chat-ka${message.simIndex}.png`">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
<view class="chat-box" :id="'msg-' + index" :class="{
|
|
||||||
'tail-right': shouldApplyTailRight(index),
|
|
||||||
'tail-left': shouldApplyTailLeft(index),
|
|
||||||
'delivered': isLastMeMessage(index)
|
|
||||||
}" @longpress="!sortMode && onMessageLongPress(index, message)">
|
|
||||||
<text v-if="message.isMe && phone == 'mi'" class="send-text">送达</text>
|
|
||||||
<view class="chat-bubble">
|
|
||||||
<view v-html="formatMessageContent(message.content, message.isMe)"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="phone == 'huawei'" class="second-info">
|
|
||||||
<text>{{ formatHuaweiBottomTime(message.time) }}</text>
|
|
||||||
<image :src="`/static/image/phone-message/huawei/chat-ka${message.simIndex}.png`"></image>
|
|
||||||
</view>
|
|
||||||
<view v-if="(phone == 'oppo' || phone == 'vivo') && message.isMe" class="second-info">
|
|
||||||
<text v-if="message.isMe" class="delivered">已送达</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue'
|
|
||||||
import { onLoad, onPageScroll } from "@dcloudio/uni-app";
|
|
||||||
import { stringUtil, util } from '@/utils/common.js';
|
|
||||||
const props = defineProps({
|
|
||||||
// 手机品牌
|
|
||||||
phone: {
|
|
||||||
type: String,
|
|
||||||
default: 'iphone'
|
|
||||||
},
|
|
||||||
messageList: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
// 是否处于拖拽排序模式
|
|
||||||
sortMode: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const SIM_STORAGE_KEY = 'sim_info'
|
|
||||||
const emit = defineEmits(['onMessageLongPress', 'sort'])
|
|
||||||
|
|
||||||
const simInfo = ref({
|
|
||||||
sim1: '中国电信',
|
|
||||||
sim2: '中国移动'
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
try {
|
|
||||||
const cached = uni.getStorageSync(SIM_STORAGE_KEY)
|
|
||||||
simInfo.value = cached ? JSON.parse(cached) : { sim1: '中国电信', sim2: '中国移动' }
|
|
||||||
} catch (e) {
|
|
||||||
simInfo.value = { sim1: '中国电信', sim2: '中国移动' }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 排序模式下的本地唦本列表
|
|
||||||
// 不直接修改 props.messageList,排序完成后 emit 给父组件
|
|
||||||
const localSortList = ref([])
|
|
||||||
const dragIndex = ref(-1)
|
|
||||||
const dragOverIndex = ref(-1)
|
|
||||||
const dropPosition = ref('after') // 'before'=插入目标上方, 'after'=插入目标下方
|
|
||||||
let isDragging = false
|
|
||||||
let sortItemRects = []
|
|
||||||
|
|
||||||
// 当 sortMode 切换时同步本地副本
|
|
||||||
watch(() => props.sortMode, (val) => {
|
|
||||||
if (val) {
|
|
||||||
localSortList.value = props.messageList.map(item => ({ ...item }))
|
|
||||||
} else {
|
|
||||||
dragIndex.value = -1
|
|
||||||
dragOverIndex.value = -1
|
|
||||||
isDragging = false
|
|
||||||
sortItemRects = []
|
|
||||||
localSortList.value = []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 实际渲染用的列表:排序模式下用内部副本,否则用原始列表
|
|
||||||
const displayList = computed(() => {
|
|
||||||
if (props.sortMode) return localSortList.value
|
|
||||||
return props.messageList
|
|
||||||
})
|
|
||||||
|
|
||||||
// 判断消息isMe==true时上一条消息是否也是isMe==true,如果不是则应用m-t-16样式
|
|
||||||
const shouldApplyMt16 = (index) => {
|
|
||||||
if (index === 0) return false;
|
|
||||||
const currentMsg = displayList.value[index];
|
|
||||||
const prevMsg = displayList.value[index - 1];
|
|
||||||
if (currentMsg.isMe && !prevMsg.isMe) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断消息isMe==true时下一条消息是否也是isMe==true,如果不是则应用m-t-16样式
|
|
||||||
const shouldApplyNextIsMe = (index) => {
|
|
||||||
const currentMsg = displayList.value[index];
|
|
||||||
// 拦截:如果已经是数组的最后一条消息,必然不存在下一条消息
|
|
||||||
if (index >= displayList.value.length - 1) return false;
|
|
||||||
|
|
||||||
const nextMsg = displayList.value[index + 1];
|
|
||||||
if (currentMsg.isMe && nextMsg.isMe) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断是否为最后一条自己发出的消息
|
|
||||||
const isLastMeMessage = (currentIndex) => {
|
|
||||||
const currentMsg = displayList.value[currentIndex];
|
|
||||||
if (!currentMsg.isMe) return false;
|
|
||||||
|
|
||||||
// 往后遍历,如果还能找到isMe=true的消息,说明当前这条不是最后一条
|
|
||||||
for (let i = currentIndex + 1; i < displayList.value.length; i++) {
|
|
||||||
if (displayList.value[i].isMe) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断 tail-right(右侧我方气泡尾巴)样式是否生效
|
|
||||||
const shouldApplyTailRight = (index) => {
|
|
||||||
const currentMsg = displayList.value[index];
|
|
||||||
if (!currentMsg.isMe) return false; // 不是我发的直接没右侧尾巴
|
|
||||||
|
|
||||||
// 如果这是整体列表最后一条消息,必然有尾巴
|
|
||||||
if (index === displayList.value.length - 1) return true;
|
|
||||||
|
|
||||||
const nextMsg = displayList.value[index + 1];
|
|
||||||
|
|
||||||
// 条件 c: 下一条消息 isMe == false (也就是被打断了)
|
|
||||||
if (!nextMsg.isMe) return true;
|
|
||||||
|
|
||||||
// 条件 a: 下一条消息间隔三分钟以上 (180000 毫秒) - 时间分割线导致当前段落结束
|
|
||||||
const currentMsgTime = new Date(currentMsg.time.replace(/-/g, '/')).getTime();
|
|
||||||
const nextMsgTime = new Date(nextMsg.time.replace(/-/g, '/')).getTime();
|
|
||||||
if (!isNaN(currentMsgTime) && !isNaN(nextMsgTime) && (nextMsgTime - currentMsgTime > 180000)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其他情况(连绵不断的连发,中间没超时间也没被对方打断),则隐藏中间环节气泡尾巴
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断 tail-left 样式是否生效
|
|
||||||
const shouldApplyTailLeft = (index) => {
|
|
||||||
const currentMsg = displayList.value[index];
|
|
||||||
if (currentMsg.isMe) return false;
|
|
||||||
|
|
||||||
// 如果这是整体列表最后一条消息,也就符合最后一条isMe==false的特征
|
|
||||||
if (index === displayList.value.length - 1) return true;
|
|
||||||
|
|
||||||
const nextMsg = displayList.value[index + 1];
|
|
||||||
|
|
||||||
// 条件 c: 下一条消息 isMe == true
|
|
||||||
if (nextMsg.isMe) return true;
|
|
||||||
|
|
||||||
// 条件 a: 下一条消息间隔三分钟以上 (180000 毫秒)
|
|
||||||
const currentMsgTime = new Date(currentMsg.time.replace(/-/g, '/')).getTime();
|
|
||||||
const nextMsgTime = new Date(nextMsg.time.replace(/-/g, '/')).getTime();
|
|
||||||
if (!isNaN(currentMsgTime) && !isNaN(nextMsgTime) && (nextMsgTime - currentMsgTime > 180000)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 条件 b: 这是最后一条 isMe == false 的消息
|
|
||||||
for (let i = index + 1; i < displayList.value.length; i++) {
|
|
||||||
if (!displayList.value[i].isMe) {
|
|
||||||
return false; // 往后还有不是自己发的消息,所以当前并非最后一条 isMe==false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取格式化后的聊天时间显示
|
|
||||||
const formatChatTime = (timeStr) => {
|
|
||||||
if (!timeStr) return '';
|
|
||||||
const date = new Date(timeStr.replace(/-/g, '/'));
|
|
||||||
if (isNaN(date.getTime())) return timeStr;
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
||||||
const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
||||||
|
|
||||||
const diffDays = Math.floor((today.getTime() - target.getTime()) / (1000 * 60 * 60 * 24));
|
|
||||||
|
|
||||||
const hours = String(date.getHours()).padStart(2, '0');
|
|
||||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
||||||
const timeNum = `${hours}:${minutes}`;
|
|
||||||
|
|
||||||
if (diffDays === 0) {
|
|
||||||
if (props.phone == 'iphone' || props.phone == 'oppo') return `今天 ${timeNum}`;
|
|
||||||
return `${timeNum}`;
|
|
||||||
} else if (diffDays === 1) {
|
|
||||||
return `昨天 ${timeNum}`;
|
|
||||||
} else if (diffDays > 1 && diffDays < 7) {
|
|
||||||
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
|
||||||
return `${weekDays[date.getDay()]} ${timeNum}`;
|
|
||||||
} else {
|
|
||||||
// 超过一周,同一年显示 月日 时分,跨年显示 年月日 时分
|
|
||||||
if (date.getFullYear() === now.getFullYear()) {
|
|
||||||
return `${date.getMonth() + 1}月${date.getDate()}日 ${timeNum}`;
|
|
||||||
} else {
|
|
||||||
return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 ${timeNum}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 华为顶部时间栏:只显示日期维度的信息,无具体时分秒
|
|
||||||
const formatHuaweiTopTime = (timeStr) => {
|
|
||||||
if (!timeStr) return '';
|
|
||||||
const date = new Date(timeStr.replace(/-/g, '/'));
|
|
||||||
if (isNaN(date.getTime())) return timeStr;
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
||||||
const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
||||||
const diffDays = Math.floor((today.getTime() - target.getTime()) / (1000 * 60 * 60 * 24));
|
|
||||||
|
|
||||||
if (diffDays === 0) {
|
|
||||||
return `今天`;
|
|
||||||
} else if (diffDays === 1) {
|
|
||||||
return `昨天`;
|
|
||||||
} else {
|
|
||||||
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
|
||||||
const weekdayStr = weekDays[date.getDay()];
|
|
||||||
return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日${weekdayStr}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 华为底部小尾巴附加时间:上下午时分、或者“刚刚”
|
|
||||||
const formatHuaweiBottomTime = (timeStr) => {
|
|
||||||
if (!timeStr) return '';
|
|
||||||
const date = new Date(timeStr.replace(/-/g, '/'));
|
|
||||||
if (isNaN(date.getTime())) return timeStr;
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
// 判断是否在一分钟内(差值在 60000 毫秒以内)
|
|
||||||
const diffMs = now.getTime() - date.getTime();
|
|
||||||
if (diffMs >= 0 && diffMs <= 60000) {
|
|
||||||
return '刚刚';
|
|
||||||
}
|
|
||||||
|
|
||||||
const ampm = date.getHours() >= 12 ? '下午' : '上午';
|
|
||||||
// 转换为 12 小时制
|
|
||||||
let displayHour = date.getHours() % 12;
|
|
||||||
displayHour = displayHour ? displayHour : 12; // 如果是 0(午夜) 则是12
|
|
||||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
||||||
|
|
||||||
return `${ampm}${displayHour}:${minutes}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断是否显示时间
|
|
||||||
// timeMode: 'show'=强制显示, 'hide'=强制隐藏, 'auto'或无=按间隔逻辑判断
|
|
||||||
const shouldShowTime = (index) => {
|
|
||||||
const currentMsg = displayList.value[index];
|
|
||||||
const mode = currentMsg.timeMode;
|
|
||||||
|
|
||||||
// 强制隐藏(兼容旧 hideTime 字段)
|
|
||||||
if (mode === 'hide' || currentMsg.hideTime) return false;
|
|
||||||
|
|
||||||
// 强制显示
|
|
||||||
if (mode === 'show') return true;
|
|
||||||
|
|
||||||
// 以下为 auto / 默认 逻辑
|
|
||||||
if (index === 0) return true; // 第一条必定显示
|
|
||||||
|
|
||||||
// 排序模式下每条均显示时间
|
|
||||||
if (props.sortMode) return true;
|
|
||||||
|
|
||||||
const currentMsgTime = new Date(currentMsg.time.replace(/-/g, '/')).getTime();
|
|
||||||
const prevMsgTime = new Date(displayList.value[index - 1].time.replace(/-/g, '/')).getTime();
|
|
||||||
|
|
||||||
if (isNaN(currentMsgTime) || isNaN(prevMsgTime)) return true;
|
|
||||||
|
|
||||||
// 绝对值比较,兼容排序后时间倒序
|
|
||||||
return Math.abs(currentMsgTime - prevMsgTime) > 180000;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化文本:给网址和 5 位以上连续数字加上下划线样式,非我方消息同时赋予文字蓝色
|
|
||||||
const formatMessageContent = (content, isMe) => {
|
|
||||||
if (!content) return '';
|
|
||||||
|
|
||||||
// 匹配 url 或 5位以上连续数字
|
|
||||||
// URL: http(s)://... 或 xxx.xxx/...
|
|
||||||
const combinedRegex = /((?:https?:\/\/)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(?:\/[a-zA-Z0-9_/%-]*)*)|(\b\d{5,}(?:\.\d+)?\b)/g;
|
|
||||||
|
|
||||||
return content.replace(combinedRegex, (match, p1, p2) => {
|
|
||||||
// 如果是数字且包含小数点(通常是金额),则不添加下划线样式
|
|
||||||
if (p2 && p2.includes('.')) {
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
let color = '#3A85F8'
|
|
||||||
if (props.phone == 'iphone') color = '#0B7AE3'
|
|
||||||
if (props.phone == 'mi') color = '#3A85F8'
|
|
||||||
const colorStyle = !isMe ? `color: ${color};` : '';
|
|
||||||
return `<span style="text-decoration: underline; ${colorStyle}">${match}</span>`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 长按信息
|
|
||||||
* @param index
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
const onMessageLongPress = (index, message, type = 'message') => {
|
|
||||||
emit('onLongPress', index, message, type)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================== 拖拽排序逻辑 =====================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新所有排序条目的 rect 坐标缓存
|
|
||||||
*/
|
|
||||||
const refreshSortRects = (callback) => {
|
|
||||||
const query = uni.createSelectorQuery()
|
|
||||||
const len = localSortList.value.length
|
|
||||||
let collected = []
|
|
||||||
let done = 0
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
query.select('#msg-' + i).boundingClientRect(rect => {
|
|
||||||
collected[i] = rect
|
|
||||||
done++
|
|
||||||
if (done === len && callback) callback(collected)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
query.exec()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 长按手柄开始拖拽
|
|
||||||
*/
|
|
||||||
const onSortLongPress = (idx, e) => {
|
|
||||||
dragIndex.value = idx
|
|
||||||
dragOverIndex.value = idx
|
|
||||||
isDragging = true
|
|
||||||
refreshSortRects(rects => {
|
|
||||||
sortItemRects = rects
|
|
||||||
})
|
|
||||||
uni.vibrateShort({ type: 'medium' })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拖拽移动 - 根据触摸点 Y 坐标確定悬停位置和插入方向
|
|
||||||
*/
|
|
||||||
const onSortTouchMove = (idx, e) => {
|
|
||||||
if (!isDragging || dragIndex.value === -1) return
|
|
||||||
if (!e.touches || !e.touches[0]) return
|
|
||||||
const touchY = e.touches[0].clientY
|
|
||||||
if (!sortItemRects || sortItemRects.length === 0) return
|
|
||||||
let overIdx = dragOverIndex.value
|
|
||||||
for (let i = 0; i < sortItemRects.length; i++) {
|
|
||||||
const rect = sortItemRects[i]
|
|
||||||
if (rect && touchY >= rect.top && touchY <= rect.bottom) {
|
|
||||||
overIdx = i
|
|
||||||
// 判断手指在该元素的上半区还是下半区
|
|
||||||
const mid = rect.top + rect.height / 2
|
|
||||||
dropPosition.value = touchY < mid ? 'before' : 'after'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dragOverIndex.value = overIdx
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拖拽结束 - 根据 dropPosition 決定插入到目标的上方还是下方
|
|
||||||
*/
|
|
||||||
const onSortTouchEnd = (idx, e) => {
|
|
||||||
if (!isDragging) return
|
|
||||||
const from = dragIndex.value
|
|
||||||
const to = dragOverIndex.value
|
|
||||||
if (from !== -1 && to !== -1 && from !== to) {
|
|
||||||
const list = [...localSortList.value]
|
|
||||||
const [removed] = list.splice(from, 1)
|
|
||||||
// from 被移除后,如果 to 在 from 后面,to 需要 -1
|
|
||||||
let insertAt = to > from ? to - 1 : to
|
|
||||||
if (dropPosition.value === 'after') insertAt += 1
|
|
||||||
list.splice(insertAt, 0, removed)
|
|
||||||
localSortList.value = list
|
|
||||||
emit('sort', list.map(item => ({ ...item })))
|
|
||||||
nextTick(() => {
|
|
||||||
refreshSortRects(rects => {
|
|
||||||
sortItemRects = rects
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
dragIndex.value = -1
|
|
||||||
dragOverIndex.value = -1
|
|
||||||
dropPosition.value = 'after'
|
|
||||||
isDragging = false
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
/* ===== 排序模式公共样式(跨所有手机品牌通用)===== */
|
|
||||||
/* 排序模式下每条消息左右横排(手柄 + 气泡取剩余宽度)*/
|
|
||||||
.is-sort-mode {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 拖拽手柄区域 */
|
|
||||||
.sort-handle-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 60rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding: 0 8rpx;
|
|
||||||
|
|
||||||
.sort-handle-bar {
|
|
||||||
margin: 3rpx 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sort-handle-bar {
|
|
||||||
width: 30rpx;
|
|
||||||
height: 4rpx;
|
|
||||||
border-radius: 2rpx;
|
|
||||||
background-color: #CCCCCC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 被拖拽中的条目:高亮蓝边 + 轻微缩进 */
|
|
||||||
.sort-dragging {
|
|
||||||
opacity: 0.7;
|
|
||||||
background-color: rgba(0, 122, 255, 0.06) !important;
|
|
||||||
border-left: 4rpx solid #007AFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 插入线:将拖拽项放在目标上方 */
|
|
||||||
.sort-drop-before {
|
|
||||||
border-top: 3rpx dashed #007AFF !important;
|
|
||||||
padding-top: 4rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 插入线:将拖拽项放在目标下方 */
|
|
||||||
.sort-drop-after {
|
|
||||||
border-bottom: 3rpx dashed #007AFF !important;
|
|
||||||
padding-bottom: 4rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 苹果样式
|
|
||||||
.iphone-style {
|
|
||||||
.m-t-16 {
|
|
||||||
margin-top: 16rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-text {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 20rpx;
|
|
||||||
color: #838383;
|
|
||||||
margin-top: 26rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #838383;
|
|
||||||
font-size: 20rpx;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
margin-top: 36rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-box {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
padding: 18rpx 22rpx;
|
|
||||||
background-color: #E9E9EB;
|
|
||||||
border-radius: 34rpx;
|
|
||||||
max-width: 600rpx;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 38rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
margin: 4rpx 30rpx 0;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.isMe {
|
|
||||||
.chat-box {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
background-color: #34C85A;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tail-left {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tail-left::after {
|
|
||||||
position: absolute;
|
|
||||||
left: 18rpx;
|
|
||||||
bottom: 0;
|
|
||||||
content: '';
|
|
||||||
background: url('/static/image/phone-message/iphone/left-msg-box.png') no-repeat center bottom;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
width: 28rpx;
|
|
||||||
height: 36rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tail-right {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delivered::before {
|
|
||||||
position: absolute;
|
|
||||||
right: 18rpx;
|
|
||||||
bottom: -12rpx;
|
|
||||||
content: '已送达';
|
|
||||||
font-size: 20rpx;
|
|
||||||
line-height: 20rpx;
|
|
||||||
color: #8B8B8B;
|
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tail-right::after {
|
|
||||||
position: absolute;
|
|
||||||
right: 18rpx;
|
|
||||||
bottom: 0;
|
|
||||||
content: '';
|
|
||||||
background: url('/static/image/phone-message/iphone/right-msg-box.png') no-repeat center bottom;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
width: 28rpx;
|
|
||||||
height: 36rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 小米样式
|
|
||||||
.mi-style {
|
|
||||||
.top-text {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 20rpx;
|
|
||||||
color: #838383;
|
|
||||||
margin-top: 26rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
padding: 0 54rpx;
|
|
||||||
color: #646464;
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
margin-bottom: 16rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-box {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
padding: 22rpx 42rpx;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 32rpx;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 50rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
max-width: 550rpx;
|
|
||||||
margin: 0 24rpx;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-item {
|
|
||||||
margin-top: 16rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-t-44 {
|
|
||||||
margin-top: 44rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.isMe {
|
|
||||||
|
|
||||||
.time {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-box {
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.send-text {
|
|
||||||
color: #646464;
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
margin-left: 12rpx;
|
|
||||||
background-color: #3681FF;
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// oppo样式
|
|
||||||
.oppo-style {
|
|
||||||
.m-t-16 {
|
|
||||||
margin-top: 24rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #727377;
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
margin-top: 48rpx;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-item {
|
|
||||||
margin-top: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-box {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
padding: 28rpx 48rpx;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 32rpx;
|
|
||||||
max-width: 600rpx;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 44rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
margin: 0 32rpx;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.isMe {
|
|
||||||
.chat-box {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
background-color: #00A1FF;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.second-info {
|
|
||||||
font-size: 24rpx;
|
|
||||||
text-align: right;
|
|
||||||
padding: 0 34rpx;
|
|
||||||
margin-top: 14rpx;
|
|
||||||
padding-bottom: 6rpx;
|
|
||||||
|
|
||||||
.delivered {
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
color: #727377;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 华为样式
|
|
||||||
.huawei-style {
|
|
||||||
.top-text {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 22rpx;
|
|
||||||
line-height: 22rpx;
|
|
||||||
color: #545454;
|
|
||||||
margin-bottom: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 22rpx;
|
|
||||||
line-height: 22rpx;
|
|
||||||
color: #545454;
|
|
||||||
margin-top: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-box {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
padding: 12rpx 24rpx;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 4rpx 28rpx 28rpx 28rpx;
|
|
||||||
max-width: 550rpx;
|
|
||||||
margin: 0 30rpx;
|
|
||||||
margin-top: 34rpx;
|
|
||||||
font-size: 30rpx;
|
|
||||||
line-height: 38rpx;
|
|
||||||
color: #1a1a1a;
|
|
||||||
font-weight: 500;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.second-info {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: #545454;
|
|
||||||
font-size: 20rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
margin-top: 16rpx;
|
|
||||||
padding-left: 52rpx;
|
|
||||||
padding-right: 56rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 14rpx;
|
|
||||||
height: 18rpx;
|
|
||||||
margin-left: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.m-t-44 {
|
|
||||||
margin-top: 44rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.isMe {
|
|
||||||
.second-info {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-item {
|
|
||||||
margin-top: 34rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-box {
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.send-text {
|
|
||||||
color: #646464;
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
margin-left: 12rpx;
|
|
||||||
background-color: #3681FF;
|
|
||||||
color: #FFFFFF;
|
|
||||||
border-radius: 28rpx 4rpx 28rpx 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// vivo样式
|
|
||||||
.vivo-style {
|
|
||||||
.m-t-16 {
|
|
||||||
margin-top: 24rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #ACACAC;
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
text-align: center;
|
|
||||||
margin: 40rpx 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-item {
|
|
||||||
margin-top: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-box {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
padding: 38rpx 38rpx 32rpx 40rpx;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 32rpx;
|
|
||||||
max-width: 100%;
|
|
||||||
font-size: 36rpx;
|
|
||||||
line-height: 48rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
margin: 0 32rpx;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.isMe {
|
|
||||||
.chat-box {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
background-color: #0078FE;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.second-info {
|
|
||||||
font-size: 24rpx;
|
|
||||||
text-align: right;
|
|
||||||
padding: 0 34rpx;
|
|
||||||
margin-top: 12rpx;
|
|
||||||
padding-bottom: 6rpx;
|
|
||||||
|
|
||||||
.delivered {
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
color: #ACACAC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,716 +0,0 @@
|
||||||
<template>
|
|
||||||
<view :style="`${phone}-style`">
|
|
||||||
<uni-swipe-action class="swipe-action">
|
|
||||||
<!-- 使用插槽 (请自行给定插槽内容宽度)-->
|
|
||||||
<uni-swipe-action-item class="swipe-action-item" v-for="(item, index) in list" :key="item.id">
|
|
||||||
<view class="flex flex-align-center " @click="clickItem(item)">
|
|
||||||
|
|
||||||
<view class="item flex w100">
|
|
||||||
<view class="flex flex-align-center left-box">
|
|
||||||
<view :class="{ 'opacity-0': !item.unRead }" class="dot shrink-0"><text
|
|
||||||
v-if="phone == 'huawei' || phone == 'oppo'">{{ item.unReadNumber
|
|
||||||
> 99
|
|
||||||
? '99+' : (item.unReadNumber || 1) }}</text>
|
|
||||||
</view>
|
|
||||||
<image class="img avatar shrink-0" :class="item.imgShape"
|
|
||||||
:src="item.img || `/static/image/phone-message/${phone}/default.png`" mode="aspectFill">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
<view class="border-box m-l-24 flex-1 flex flex-align-start">
|
|
||||||
<view class="main-box flex-1">
|
|
||||||
<view class="title-box flex-between">
|
|
||||||
<text class="title">{{ item.title }}</text>
|
|
||||||
<text class="time">{{ formatDate(item.chatList?.[item.chatList?.length -
|
|
||||||
1]?.time || item.time)
|
|
||||||
}}</text>
|
|
||||||
</view>
|
|
||||||
<view class="content"
|
|
||||||
v-html="item.chatList?.[item.chatList?.length - 1]?.content || ''"></view>
|
|
||||||
</view>
|
|
||||||
<view class="box-right h100 flex-column flex-align-center">
|
|
||||||
<image v-if="phone == 'iphone'" src="/static/image/phone-message/iphone/right.png">
|
|
||||||
</image>
|
|
||||||
<image v-if="item.noNotice && phone == 'iphone'" class="m-t-8"
|
|
||||||
src="/static/image/phone-message/iphone/notice.png"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<template v-slot:right>
|
|
||||||
<view class="flex flex-align-center" style="margin-left: 1px;">
|
|
||||||
<view class="btn flex-center flex-align-center edit" style="color: #fff;"
|
|
||||||
@click="editItem(item)">
|
|
||||||
<image :src="`/static/image/phone-message/edit.png`">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
<view class="btn flex-center flex-align-center delete" @click="deleteItem(item)">
|
|
||||||
<image
|
|
||||||
:src="`/static/image/phone-message/${phone == 'huawei' || phone == 'vivo' ? 'huawei' : 'iphone'}/delete.png`">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</uni-swipe-action-item>
|
|
||||||
</uni-swipe-action>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import { stringUtil } from '@/utils/common.js';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<script setup>
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
computed
|
|
||||||
} from 'vue'
|
|
||||||
import {
|
|
||||||
util,
|
|
||||||
dateUtil
|
|
||||||
} from '@/utils/common.js';
|
|
||||||
// 定义事件
|
|
||||||
const emit = defineEmits(['item-click', 'delete-item', 'edit-item'])
|
|
||||||
const props = defineProps({
|
|
||||||
// 手机品牌
|
|
||||||
phone: {
|
|
||||||
type: String,
|
|
||||||
default: 'iphone'
|
|
||||||
},
|
|
||||||
list: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间日期格式化判断
|
|
||||||
* @param date
|
|
||||||
*/
|
|
||||||
const formatDate = (date) => {
|
|
||||||
if (props.phone == 'oppo') {
|
|
||||||
return dateUtil.formatMessageTime(date, true)
|
|
||||||
} else if (props.phone == 'huawei') {
|
|
||||||
return dateUtil.formatMessageTime(date, true, 'YYYY年M月D日')
|
|
||||||
} else if (props.phone == 'vivo') {
|
|
||||||
let d = date;
|
|
||||||
if (typeof d === 'string') {
|
|
||||||
d = new Date(d.replace(/-/g, '/'));
|
|
||||||
} else if (typeof d === 'number') {
|
|
||||||
d = new Date(d);
|
|
||||||
}
|
|
||||||
const isCurrentYear = d.getFullYear() === new Date().getFullYear();
|
|
||||||
return dateUtil.formatMessageTime(date, true, isCurrentYear ? 'M月D日' : 'YYYY/M/D')
|
|
||||||
} else {
|
|
||||||
return dateUtil.formatMessageTime(date)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击列表元素
|
|
||||||
*/
|
|
||||||
const clickItem = (item) => {
|
|
||||||
emit('item-click', item)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除列表元素
|
|
||||||
*/
|
|
||||||
const deleteItem = (item) => {
|
|
||||||
emit('delete-item', item)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改元素
|
|
||||||
* @param item
|
|
||||||
*/
|
|
||||||
const editItem = (item) => {
|
|
||||||
emit('edit-item', item)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
@import '@/common/main.css';
|
|
||||||
</style>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.m-t-4 {
|
|
||||||
margin-top: 4rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-t-8 {
|
|
||||||
margin-top: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-l-24 {
|
|
||||||
margin-left: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.opacity-0 {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swipe-action-item {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.edit {
|
|
||||||
background-color: #5855D6;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-box {
|
|
||||||
.title-box {
|
|
||||||
margin-bottom: 6rpx;
|
|
||||||
|
|
||||||
|
|
||||||
.title {
|
|
||||||
width: 20px;
|
|
||||||
flex: 1;
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 32rpx;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-weight: 600;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-left: 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 苹果样式
|
|
||||||
.iphone-style {
|
|
||||||
.circle {
|
|
||||||
border-radius: 50% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.square {
|
|
||||||
border-radius: 16rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swipe-action {
|
|
||||||
margin-top: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swipe-action-item:first-child {
|
|
||||||
.border-box {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-box::before {
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
background-color: #D8D8D8;
|
|
||||||
transform: scaleY(0.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
padding: 0 0 0 14rpx;
|
|
||||||
height: 146rpx;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
width: 20rpx;
|
|
||||||
height: 20rpx;
|
|
||||||
background-color: #007BFD;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img {
|
|
||||||
width: 84rpx;
|
|
||||||
height: 84rpx;
|
|
||||||
margin-left: 16rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-box {
|
|
||||||
position: relative;
|
|
||||||
padding: 18rpx 24rpx 14rpx 0;
|
|
||||||
height: 100%;
|
|
||||||
// box-shadow: inset 0 -0.3px 0 0 #D8D8D8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-box::after {
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
background-color: #D8D8D8;
|
|
||||||
transform: scaleY(0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-box {
|
|
||||||
.title-box {
|
|
||||||
margin-bottom: 6rpx;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 32rpx;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #838383;
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
margin-right: 18rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 38rpx;
|
|
||||||
color: #838383;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-right {
|
|
||||||
image {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 140rpx;
|
|
||||||
height: 146rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
background-color: #FC3E30;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit {
|
|
||||||
background-color: #5855D6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 小米样式
|
|
||||||
.mi-style {
|
|
||||||
.item {
|
|
||||||
padding-top: 44rpx;
|
|
||||||
height: 170rpx;
|
|
||||||
|
|
||||||
.left-box {
|
|
||||||
position: relative;
|
|
||||||
height: 40px;
|
|
||||||
align-items: flex-start;
|
|
||||||
padding-left: 54rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
position: absolute;
|
|
||||||
width: 20rpx;
|
|
||||||
height: 20rpx;
|
|
||||||
background-color: #FA3D30;
|
|
||||||
border-radius: 50%;
|
|
||||||
left: 16rpx;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.img {
|
|
||||||
width: 76rpx;
|
|
||||||
height: 76rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-box {
|
|
||||||
position: relative;
|
|
||||||
padding: 4rpx 52rpx 8rpx 0;
|
|
||||||
margin-left: 22rpx;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-box {
|
|
||||||
.title-box {
|
|
||||||
margin-bottom: 6rpx;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #9A9A9A;
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 38rpx;
|
|
||||||
color: #656565;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-right {
|
|
||||||
image {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 140rpx;
|
|
||||||
height: 146rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
background-color: #FC3E30;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit {
|
|
||||||
background-color: #5855D6;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// oppo样式
|
|
||||||
.oppo-style {
|
|
||||||
.item {
|
|
||||||
padding-top: 28rpx;
|
|
||||||
height: 178rpx;
|
|
||||||
|
|
||||||
.left-box {
|
|
||||||
position: relative;
|
|
||||||
height: 40px;
|
|
||||||
align-items: flex-start;
|
|
||||||
padding-left: 34rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
position: absolute;
|
|
||||||
padding: 4rpx 10rpx;
|
|
||||||
background-color: #E93A22;
|
|
||||||
color: #FFFFFF;
|
|
||||||
line-height: 20rpx;
|
|
||||||
font-size: 20rpx;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
right: -8rpx;
|
|
||||||
top: -4rpx;
|
|
||||||
z-index: 1;
|
|
||||||
border: 2rpx solid #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img {
|
|
||||||
width: 76rpx;
|
|
||||||
height: 76rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-box {
|
|
||||||
position: relative;
|
|
||||||
padding: 4rpx 34rpx 28rpx 0;
|
|
||||||
margin-left: 32rpx;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-box {
|
|
||||||
.title-box {
|
|
||||||
margin-bottom: 16rpx;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 32rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #656565;
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 38rpx;
|
|
||||||
color: #737373;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-right {
|
|
||||||
image {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 140rpx;
|
|
||||||
height: 146rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
background-color: #FC3E30;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 华为样式
|
|
||||||
.huawei-style {
|
|
||||||
.item {
|
|
||||||
padding: 0 32rpx;
|
|
||||||
height: 156rpx;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.left-box {
|
|
||||||
position: relative;
|
|
||||||
height: 40px;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
position: absolute;
|
|
||||||
padding: 6rpx 10rpx;
|
|
||||||
background-color: #E93A22;
|
|
||||||
color: #FFFFFF;
|
|
||||||
line-height: 20rpx;
|
|
||||||
font-size: 20rpx;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
right: -8rpx;
|
|
||||||
top: -12rpx;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img {
|
|
||||||
width: 76rpx;
|
|
||||||
height: 76rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-box {
|
|
||||||
padding: 18rpx 0;
|
|
||||||
position: relative;
|
|
||||||
margin-left: 30rpx;
|
|
||||||
margin-top: 2rpx;
|
|
||||||
height: 100%;
|
|
||||||
box-shadow: 0 -0.3px 0 0 #CFCFCF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// .border-box::after {
|
|
||||||
// position: absolute;
|
|
||||||
// content: '';
|
|
||||||
// width: 100%;
|
|
||||||
// height: 1px;
|
|
||||||
// bottom: 0;
|
|
||||||
// left: 0;
|
|
||||||
// right: 0;
|
|
||||||
// background-color: #CFCFCF;
|
|
||||||
// transform: scaleY(0.3);
|
|
||||||
// }
|
|
||||||
|
|
||||||
.main-box {
|
|
||||||
.title-box {
|
|
||||||
margin-bottom: 6rpx;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 32rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #656565;
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 38rpx;
|
|
||||||
color: #6F6F6F;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-right {
|
|
||||||
image {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 140rpx;
|
|
||||||
height: 156rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 76rpx;
|
|
||||||
height: 76rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
background-color: #F4F4F4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit {
|
|
||||||
background-color: #5855D6;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// vivo样式
|
|
||||||
.vivo-style {
|
|
||||||
.item {
|
|
||||||
padding: 0 50rpx 0 24rpx;
|
|
||||||
height: 172rpx;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
width: 12rpx;
|
|
||||||
height: 12rpx;
|
|
||||||
background-color: #409DFE;
|
|
||||||
border-radius: 50%;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.img {
|
|
||||||
width: 80rpx;
|
|
||||||
height: 80rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-box {
|
|
||||||
padding: 28rpx 0 18rpx;
|
|
||||||
position: relative;
|
|
||||||
margin-left: 24rpx;
|
|
||||||
margin-top: 2rpx;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-box {
|
|
||||||
.title-box {
|
|
||||||
margin-bottom: 18rpx;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 32rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
color: #7C7C7C;
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 26rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 38rpx;
|
|
||||||
color: #6F6F6F;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-right {
|
|
||||||
image {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 140rpx;
|
|
||||||
height: 156rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 76rpx;
|
|
||||||
height: 76rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
background-color: #F4F4F4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit {
|
|
||||||
background-color: #5855D6;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,584 +0,0 @@
|
||||||
<template>
|
|
||||||
<view :class="`${phone}-style`">
|
|
||||||
<!-- 导航样式 -->
|
|
||||||
<view class="nav-bar-box" :class="{ 'border-nav-bar-box': isScroll }">
|
|
||||||
<NavBar :isBack="false" :bgColor="isScroll ? data.navBar.bgColor : '#fff'" :buttonGroup="buttonGroup"
|
|
||||||
@button-click="util.clickTitlePopupButton" tipLayerType="message-list-tip" isTipLayer
|
|
||||||
tipLayerText="添加短信" @add="emit('add')">
|
|
||||||
<!-- 左侧文字图标 -->
|
|
||||||
<template v-slot:left>
|
|
||||||
<view v-if="phone == 'iphone'" class="flex flex-align-center">
|
|
||||||
<image @click="util.goBack" class="left-icon" src="/static/image/phone-message/iphone/back.png"
|
|
||||||
mode=""></image>
|
|
||||||
<text class="left-text">过滤条件</text>
|
|
||||||
</view>
|
|
||||||
<view v-if="(phone == 'huawei' && isScroll) || phone == 'vivo'" class="flex flex-align-center">
|
|
||||||
<text class="left-text">信息</text>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<!-- 中间标题 -->
|
|
||||||
<template v-slot:center>
|
|
||||||
<view v-if="phone == 'iphone' && isScroll" class="center-text">
|
|
||||||
信息
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<!-- 右侧图标 -->
|
|
||||||
<template v-slot:right>
|
|
||||||
<!-- iphone -->
|
|
||||||
<view v-if="phone == 'iphone'">
|
|
||||||
<image class="right-icon mg-r-30" src="/static/image/phone-message/iphone/more.png" mode="">
|
|
||||||
</image>
|
|
||||||
<image class="right-icon mg-r-5" src="/static/image/phone-message/iphone/edit.png" mode="">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
<!-- mi -->
|
|
||||||
<view v-if="phone == 'mi'">
|
|
||||||
<image class="right-icon" src="/static/image/phone-message/mi/setting.png" mode=""></image>
|
|
||||||
</view>
|
|
||||||
<!-- oppo -->
|
|
||||||
<view v-if="phone == 'oppo'">
|
|
||||||
<image class="right-icon mg-r-52" src="/static/image/phone-message/oppo/search.png" mode="">
|
|
||||||
</image>
|
|
||||||
<image class="right-icon mg-r-14" src="/static/image/phone-message/oppo/more.png" mode="">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
<!-- huawei -->
|
|
||||||
<view v-if="phone == 'huawei'">
|
|
||||||
<image v-if="isScroll" class="right-icon"
|
|
||||||
src="/static/image/phone-message/huawei/nav-search.png" mode="">
|
|
||||||
</image>
|
|
||||||
<image class="right-icon" src="/static/image/phone-message/huawei/add.png" mode=""></image>
|
|
||||||
<image class="right-icon" src="/static/image/phone-message/huawei/more.png" mode=""></image>
|
|
||||||
</view>
|
|
||||||
<!-- vivo -->
|
|
||||||
<view v-if="phone == 'vivo'">
|
|
||||||
<image class="right-icon" src="/static/image/phone-message/vivo/select.png" mode="">
|
|
||||||
</image>
|
|
||||||
<image class="right-icon" src="/static/image/phone-message/vivo/add.png" mode=""></image>
|
|
||||||
<image class="right-icon m-r-34" src="/static/image/phone-message/vivo/more.png" mode="">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</NavBar>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 主体内容 -->
|
|
||||||
<view class="main-container">
|
|
||||||
<!-- 顶部搜索栏样式 -->
|
|
||||||
<view class="top-box">
|
|
||||||
<view v-if="showInfo.text" class="text">{{ showInfo.text }}</view>
|
|
||||||
<view v-if="showInfo.secondText" class="second-text">{{ showInfo.secondText }}</view>
|
|
||||||
<view v-if="showInfo.placeholder" class="search-box flex flex-align-center">
|
|
||||||
<image class="icon" :src="`/static/image/phone-message/${props.phone}/search.png`">
|
|
||||||
</image>
|
|
||||||
<input class="input flex-1" :placeholder="showInfo.placeholder" type="text" disabled>
|
|
||||||
<image v-if="phone != 'mi'" class="icon"
|
|
||||||
:src="`/static/image/phone-message/${props.phone}/mic.png`">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<slot>
|
|
||||||
</slot>
|
|
||||||
</view>
|
|
||||||
<view class="bottom-placeholder"></view>
|
|
||||||
<!-- 底部样式 -->
|
|
||||||
<template v-if="phone == 'mi' || phone == 'oppo'">
|
|
||||||
<image class="add-message" @click="emit('add')"
|
|
||||||
:src="`/static/image/phone-message/${props.phone}/add-message.png`"></image>
|
|
||||||
<view class="bottom-box flex">
|
|
||||||
<view class="item flex-1 h100">
|
|
||||||
<image class="icon" :src="`/static/image/phone-message/${props.phone}/bottom-left.png`"></image>
|
|
||||||
<text>{{ showInfo.bottomLtext }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="item flex-1 h100">
|
|
||||||
<image class="icon" :src="`/static/image/phone-message/${props.phone}/bottom-right.png`"></image>
|
|
||||||
<text class="grey">{{ showInfo.bottomRtext }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import NavBar from '@/components/nav-bar/nav-bar.vue'
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
computed
|
|
||||||
} from 'vue'
|
|
||||||
import {
|
|
||||||
util
|
|
||||||
} from '@/utils/common.js';
|
|
||||||
|
|
||||||
const emit = defineEmits(['add', 'setSim', 'setNoticeCount'])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
// 手机品牌
|
|
||||||
phone: {
|
|
||||||
type: String,
|
|
||||||
default: 'iphone'
|
|
||||||
},
|
|
||||||
// 是否向下滚动
|
|
||||||
isScroll: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const buttonGroup = computed(() => {
|
|
||||||
const groups = [{
|
|
||||||
name: "添加短信",
|
|
||||||
click: () => {
|
|
||||||
emit('add')
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
name: "设置卡1卡2运营商",
|
|
||||||
click: () => {
|
|
||||||
emit('setSim')
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
if (props.phone == 'huawei') {
|
|
||||||
groups.push({
|
|
||||||
name: "设置通知信息未读数",
|
|
||||||
click: () => {
|
|
||||||
emit('setNoticeCount')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return groups
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
navBar: {
|
|
||||||
title: '信息',
|
|
||||||
bgColor: '#FFFFFF',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 展示文字信息
|
|
||||||
const showInfo = computed(() => {
|
|
||||||
let text, placeholder, secondText, bottomLtext, bottomRtext
|
|
||||||
switch (props.phone) {
|
|
||||||
case "iphone":
|
|
||||||
text = "信息"
|
|
||||||
placeholder = '搜索'
|
|
||||||
data.navBar.bgColor = '#F8F8F8'
|
|
||||||
break;
|
|
||||||
case "mi":
|
|
||||||
text = "主要"
|
|
||||||
placeholder = '搜索短信'
|
|
||||||
bottomLtext = "主要"
|
|
||||||
bottomRtext = "推广"
|
|
||||||
break;
|
|
||||||
case "oppo":
|
|
||||||
text = "消息"
|
|
||||||
placeholder = ''
|
|
||||||
bottomLtext = "消息"
|
|
||||||
bottomRtext = "通知"
|
|
||||||
break;
|
|
||||||
case "huawei":
|
|
||||||
text = "信息"
|
|
||||||
placeholder = '搜索信息'
|
|
||||||
secondText = "388 条未读"
|
|
||||||
break;
|
|
||||||
case "vivo":
|
|
||||||
placeholder = '搜索信息'
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return { text, placeholder, secondText, bottomLtext, bottomRtext }
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import '@/common/main.css';
|
|
||||||
|
|
||||||
page {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
::v-deep .uni-navbar__header-btns {
|
|
||||||
width: 100px !important;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .uni-navbar__header {
|
|
||||||
align-items: center !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-box {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 120rpx;
|
|
||||||
border-top: 1rpx solid #E7E7E7;
|
|
||||||
background-color: #ffffff;
|
|
||||||
z-index: 9;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 44rpx;
|
|
||||||
height: 44rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-size: 20rpx;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey {
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 苹果机型样式
|
|
||||||
.iphone-style {
|
|
||||||
.mg-r-30 {
|
|
||||||
margin-right: 60rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mg-r-5 {
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-icon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-icon {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-text {
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #0278E2;
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-text {
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #1a1a1a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-nav-bar-box {
|
|
||||||
::v-deep .nav-bar-container {
|
|
||||||
box-shadow: 0 -0.3px 0 0 #B5B5B5 inset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-container {
|
|
||||||
.top-box {
|
|
||||||
padding: 20rpx 32rpx 0;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 64rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 72rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
margin-top: 20rpx;
|
|
||||||
background-color: #EEEEF0;
|
|
||||||
height: 68rpx;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
padding: 0 16rpx;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 32rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
margin: 0 14rpx;
|
|
||||||
|
|
||||||
::v-deep .input-placeholder {
|
|
||||||
color: #838383;
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 小米机型样式
|
|
||||||
.mi-style {
|
|
||||||
.right-icon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
margin-right: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-container {
|
|
||||||
|
|
||||||
.top-box {
|
|
||||||
padding: 0 22rpx 0;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 60rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
margin-top: 32rpx;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
height: 84rpx;
|
|
||||||
border-radius: 42rpx;
|
|
||||||
padding: 0 34rpx;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 32rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
margin: 0 18rpx;
|
|
||||||
|
|
||||||
::v-deep .input-placeholder {
|
|
||||||
color: #A9A9A9;
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-message {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 168rpx;
|
|
||||||
right: 44rpx;
|
|
||||||
width: 120rpx;
|
|
||||||
height: 120rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-placeholder {
|
|
||||||
height: 120rpx;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// oppo机型
|
|
||||||
.oppo-style {
|
|
||||||
.mg-r-52 {
|
|
||||||
margin-right: 52rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mg-r-14 {
|
|
||||||
margin-right: 14rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-icon {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-container {
|
|
||||||
|
|
||||||
|
|
||||||
.top-box {
|
|
||||||
padding: 16rpx 34rpx 0;
|
|
||||||
margin-bottom: 50rpx;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 64rpx;
|
|
||||||
font-weight: 900;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-message {
|
|
||||||
width: 116rpx;
|
|
||||||
height: 116rpx;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 200rpx;
|
|
||||||
right: 46rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-placeholder {
|
|
||||||
height: 148rpx;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.bottom-box {
|
|
||||||
height: 148rpx;
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
border-top: 1rpx solid #DCDCDC;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
.icon {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
margin-bottom: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
color: #191919;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey {
|
|
||||||
color: #717171;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 华为机型
|
|
||||||
.huawei-style {
|
|
||||||
|
|
||||||
::v-deep .uni-navbar__header-container {
|
|
||||||
flex: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-text {
|
|
||||||
color: #1a1a1a;
|
|
||||||
font-size: 50rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-icon {
|
|
||||||
width: 76rpx;
|
|
||||||
height: 76rpx;
|
|
||||||
margin: 0 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-nav-bar-box {
|
|
||||||
::v-deep .nav-bar {
|
|
||||||
border-bottom: 1rpx solid #D1D1D1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-container {
|
|
||||||
|
|
||||||
|
|
||||||
.top-box {
|
|
||||||
padding: 40rpx 34rpx 0;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 60rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 60rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.second-text {
|
|
||||||
color: #646464;
|
|
||||||
font-size: 28rpx;
|
|
||||||
margin-top: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
margin-top: 40rpx;
|
|
||||||
background-color: #F4F4F4;
|
|
||||||
height: 76rpx;
|
|
||||||
border-radius: 38rpx;
|
|
||||||
padding: 0 24rpx;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 32rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
margin: 0 14rpx;
|
|
||||||
|
|
||||||
::v-deep .input-placeholder {
|
|
||||||
color: #646464;
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// vivo机型
|
|
||||||
.vivo-style {
|
|
||||||
::v-deep .uni-navbar__header-container {
|
|
||||||
flex: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.m-r-34 {
|
|
||||||
margin-right: 34rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-icon {
|
|
||||||
width: 44rpx;
|
|
||||||
height: 44rpx;
|
|
||||||
margin-right: 52rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-text {
|
|
||||||
font-size: 54rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-left: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-container {
|
|
||||||
.top-box {
|
|
||||||
padding: 0 46rpx;
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
position: relative;
|
|
||||||
margin-top: 70rpx;
|
|
||||||
background-color: #ffffff;
|
|
||||||
height: 76rpx;
|
|
||||||
border-radius: 38rpx;
|
|
||||||
padding: 0 10rpx;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
flex: 1;
|
|
||||||
margin: 0 20rpx;
|
|
||||||
|
|
||||||
::v-deep .input-placeholder {
|
|
||||||
color: #9A9A9A;
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box::after {
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
width: 100%;
|
|
||||||
height: 12rpx;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<template v-slot:left>
|
<template v-slot:left>
|
||||||
<view class="nav-bar-left">
|
<view class="nav-bar-left">
|
||||||
<slot name="left">
|
<slot name="left">
|
||||||
<view v-if="isBack" class="left-icon" @click.stop="onBack">
|
<view class="left-icon" @click.stop="onBack">
|
||||||
<image class="nav-icon-back"
|
<image class="nav-icon-back"
|
||||||
:src="`/static/image/nav-bar/back-${textColor == '#fff' || textColor == '#fffffff' ? 'white' : 'black'}.png`"
|
:src="`/static/image/nav-bar/back-${textColor == '#fff' || textColor == '#fffffff' ? 'white' : 'black'}.png`"
|
||||||
mode="">
|
mode="">
|
||||||
|
|
@ -130,10 +130,6 @@ const props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
isBack: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
tipLayerText: {
|
tipLayerText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
|
|
||||||
2
main.js
|
|
@ -27,7 +27,7 @@ export function createApp() {
|
||||||
const systemInfo = uni.getStorageSync('systemInfo') || {}
|
const systemInfo = uni.getStorageSync('systemInfo') || {}
|
||||||
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
|
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
|
||||||
app.config.globalProperties.$systemInfo = systemInfo
|
app.config.globalProperties.$systemInfo = systemInfo
|
||||||
uni.setStorageSync('version', '1.0.3.sp8')
|
uni.setStorageSync('version', '1.0.2.sp4')
|
||||||
app.config.globalProperties.$version = uni.getStorageSync('version')
|
app.config.globalProperties.$version = uni.getStorageSync('version')
|
||||||
|
|
||||||
app.use(globalMethods);
|
app.use(globalMethods);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"splashscreen": {
|
"splashscreen": {
|
||||||
"alwaysShowBeforeRender": true,
|
"alwaysShowBeforeRender": true,
|
||||||
"waiting": true,
|
"waiting": true,
|
||||||
"autoclose": false,
|
"autoclose": true,
|
||||||
"delay": 0
|
"delay": 0
|
||||||
},
|
},
|
||||||
"optimization": {
|
"optimization": {
|
||||||
|
|
|
||||||
32
package.json
|
|
@ -1,25 +1,21 @@
|
||||||
{
|
{
|
||||||
"id": "lius-DomVideoPlayer",
|
"name": "alipay-emulator",
|
||||||
"name": "video-player 视频播放器 html5视频播放器-解决频层级、覆盖",
|
"version": "1.0.0",
|
||||||
"displayName": "video-player 视频播放器 html5视频播放器-解决频层级、覆盖",
|
"description": "支付宝模拟器 UniApp 项目",
|
||||||
"version": "2.0.0",
|
"scripts": {
|
||||||
"description": "APP 项目中,uniapp 提供的的 video 原生视频组件层级太高,难以遮挡;该视频播放器可以被其他元素进行覆盖、遮挡,页面具有更高的定制性。",
|
"dev:h5": "uni",
|
||||||
"keywords": [
|
"build:h5": "uni build"
|
||||||
"video-player",
|
|
||||||
"视频播放器",
|
|
||||||
"视频覆盖",
|
|
||||||
"视频层级",
|
|
||||||
"视频遮挡"
|
|
||||||
],
|
|
||||||
"dcloudext": {
|
|
||||||
"category": [
|
|
||||||
"前端组件",
|
|
||||||
"通用组件"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-app": "^3.0.0-alpha-3060620230810001",
|
||||||
|
"@dcloudio/uni-h5": "^3.0.0-alpha-3060620230810001",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"lottie-web": "^5.13.0",
|
"lottie-web": "^5.13.0",
|
||||||
"uuid": "^13.0.0"
|
"uuid": "^9.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/uni-cli-shared": "^3.0.0-alpha-3060620230810001",
|
||||||
|
"@dcloudio/vite-plugin-uni": "^3.0.0-alpha-3060620230810001",
|
||||||
|
"vite": "^5.2.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
95
pages.json
|
|
@ -9,38 +9,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"subPackages": [
|
||||||
"subPackages": [{
|
|
||||||
"root": "pages/call-log",
|
|
||||||
"pages": [{
|
|
||||||
"path": "call",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "通话记录页面",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"root": "pages/message",
|
|
||||||
"pages": [{
|
|
||||||
"path": "list-index",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "短信列表首页",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "chat-page/chat-page",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "短信聊天页面",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"root": "pages/balance",
|
"root": "pages/balance",
|
||||||
"pages": [{
|
"pages": [
|
||||||
|
{
|
||||||
"path": "index",
|
"path": "index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "余额页面",
|
"navigationBarTitleText": "余额页面",
|
||||||
|
|
@ -59,7 +32,8 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"root": "pages/bill",
|
"root": "pages/bill",
|
||||||
"pages": [{
|
"pages": [
|
||||||
|
{
|
||||||
"path": "bill-list/bill-list",
|
"path": "bill-list/bill-list",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "账单列表页面",
|
"navigationBarTitleText": "账单列表页面",
|
||||||
|
|
@ -84,7 +58,8 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"root": "pages/ant-credit-pay",
|
"root": "pages/ant-credit-pay",
|
||||||
"pages": [{
|
"pages": [
|
||||||
|
{
|
||||||
"path": "index",
|
"path": "index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "花呗首页",
|
"navigationBarTitleText": "花呗首页",
|
||||||
|
|
@ -102,7 +77,8 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"root": "pages/finance-management",
|
"root": "pages/finance-management",
|
||||||
"pages": [{
|
"pages": [
|
||||||
|
{
|
||||||
"path": "index",
|
"path": "index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "理财首页",
|
"navigationBarTitleText": "理财首页",
|
||||||
|
|
@ -127,7 +103,8 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"root": "pages/other",
|
"root": "pages/other",
|
||||||
"pages": [{
|
"pages": [
|
||||||
|
{
|
||||||
"path": "/video-group-chat/video-group-chat",
|
"path": "/video-group-chat/video-group-chat",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "视频群聊",
|
"navigationBarTitleText": "视频群聊",
|
||||||
|
|
@ -193,48 +170,13 @@
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
"navigationBarTextStyle": "white"
|
"navigationBarTextStyle": "white"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "card/card",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "身份证",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "qf-image/qf-image",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "图片裁剪",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"path": "train-tickets/ctrip-train-tickets/ctrip-train-tickets",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "携程火车票",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "train-tickets/qunar-train-tickets/qunar-train-tickets",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "去哪儿火车票",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "train-tickets/fliggy-train-tickets/fliggy-train-tickets",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "飞猪火车票",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"root": "pages/common",
|
"root": "pages/common",
|
||||||
"pages": [{
|
"pages": [
|
||||||
|
{
|
||||||
"path": "hot-icon/hot-icon",
|
"path": "hot-icon/hot-icon",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "热门图标",
|
"navigationBarTitleText": "热门图标",
|
||||||
|
|
@ -261,13 +203,6 @@
|
||||||
"navigationBarTitleText": "充值页",
|
"navigationBarTitleText": "充值页",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "call-and-message-entry/call-and-message-entry",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "呼叫和短信入口",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -281,9 +216,7 @@
|
||||||
"pages/common",
|
"pages/common",
|
||||||
"pages/finance-management",
|
"pages/finance-management",
|
||||||
"pages/ant-credit-pay",
|
"pages/ant-credit-pay",
|
||||||
"pages/other",
|
"pages/other"
|
||||||
"pages/message",
|
|
||||||
"pages/call-log"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,8 @@
|
||||||
<view class="detail-info-container">
|
<view class="detail-info-container">
|
||||||
<template v-for="item in billData.itemInfoList" :key="item.id">
|
<template v-for="item in billData.itemInfoList" :key="item.id">
|
||||||
<view class="info-item-box" v-if="item.key != 'paymentReward'">
|
<view class="info-item-box" v-if="item.key != 'paymentReward'">
|
||||||
<view class="item-label" :class="{ 'switchable-label': item.key === 'createTime' }"
|
<view class="item-label">
|
||||||
@click="toggleCreateTimeLabel(item)">
|
{{ item.label }}
|
||||||
<text>{{ item.label }}</text>
|
|
||||||
<image v-if="item.key === 'createTime'" class="switch-icon"
|
|
||||||
src="/static/image/bill/add-bill/edit.png"></image>
|
|
||||||
</view>
|
</view>
|
||||||
<view v-if="item.type != 'link'" class="info-item-input" @click="onClickItemInfo(item)">
|
<view v-if="item.type != 'link'" class="info-item-input" @click="onClickItemInfo(item)">
|
||||||
<!-- 隐藏的text用于测量宽度 -->
|
<!-- 隐藏的text用于测量宽度 -->
|
||||||
|
|
@ -885,15 +882,6 @@ const onRightClick = async () => {
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换创建时间/支付时间标签
|
|
||||||
*/
|
|
||||||
const toggleCreateTimeLabel = (item) => {
|
|
||||||
if (item.key === 'createTime') {
|
|
||||||
item.label = item.label === '创建时间' ? '支付时间' : '创建时间'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击itemInfo
|
// 点击itemInfo
|
||||||
const onClickItemInfo = async (item, action) => {
|
const onClickItemInfo = async (item, action) => {
|
||||||
console.log(item)
|
console.log(item)
|
||||||
|
|
@ -1242,22 +1230,6 @@ page {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.switchable-label {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 4rpx 10rpx 4rpx 10rpx;
|
|
||||||
margin-left: -10rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
border: 1px dashed #d9d9d9;
|
|
||||||
background-color: #fcfcfc;
|
|
||||||
|
|
||||||
.switch-icon {
|
|
||||||
width: 18rpx;
|
|
||||||
height: 18rpx;
|
|
||||||
margin-left: 6rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-item-input {
|
.info-item-input {
|
||||||
|
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- 水印 -->
|
|
||||||
<view v-if="$isVip()">
|
|
||||||
<watermark dark="light" />
|
|
||||||
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
|
|
||||||
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
|
|
||||||
</liu-drag-button>
|
|
||||||
</view>
|
|
||||||
<view class="container">
|
|
||||||
<!-- 自定义头部导航栏 -->
|
|
||||||
<ZdyNavbar tipLayerText="新增记录" :isTipLayer="true" :type="data.type" :scrollTop="data.scrollTop" @click="open"/>
|
|
||||||
<ZdyHeader :type="data.type" />
|
|
||||||
<callList :type="data.type" ref="callLogList"></callList>
|
|
||||||
<tabbar :type="data.type" />
|
|
||||||
<image v-if="data.type!='ios'" :src="`/static/image/call/${data.type}BtnImg.png`" mode="" class="btnImg" :class="['btnImg_'+data.type]"></image>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import ZdyNavbar from "@/components/call-log/nav-bar/nav-bar.vue"
|
|
||||||
import ZdyHeader from "@/components/call-log/header/header.vue"
|
|
||||||
import callList from "@/components/call-log/list/list.vue"
|
|
||||||
import tabbar from "@/components/call-log/tabbar/tabbar.vue"
|
|
||||||
import {util} from"@/utils/common.js"
|
|
||||||
|
|
||||||
import { ref, reactive, watch, nextTick, getCurrentInstance } from "vue";
|
|
||||||
import { onLoad, onShow, onReady, onPageScroll, onReachBottom } from "@dcloudio/uni-app";
|
|
||||||
const { appContext, proxy } = getCurrentInstance();
|
|
||||||
const data = reactive({
|
|
||||||
type: 'vivo',
|
|
||||||
scrollTop:0
|
|
||||||
})
|
|
||||||
let callLogList = ref();
|
|
||||||
onLoad((option) => {
|
|
||||||
data.type=option.type
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
onReady(() => {
|
|
||||||
|
|
||||||
})
|
|
||||||
onShow(() => {
|
|
||||||
try {
|
|
||||||
if (plus.os.name === 'Android') {
|
|
||||||
let colorTabbar="#FAFAFA"
|
|
||||||
if(data.type=='xiaomi'||data.type=='oppo'){
|
|
||||||
colorTabbar="#FFFFFF"
|
|
||||||
}
|
|
||||||
console.log(colorTabbar);
|
|
||||||
util.setAndroidSystemBarColor(colorTabbar)
|
|
||||||
setTimeout(() => {
|
|
||||||
plus.navigator.setStatusBarStyle("dark");
|
|
||||||
}, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.log("修改导航条颜色失败", error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
onPageScroll((e) => {
|
|
||||||
// console.log(e)
|
|
||||||
data.scrollTop=e.scrollTop
|
|
||||||
|
|
||||||
})
|
|
||||||
onReachBottom(() => {
|
|
||||||
|
|
||||||
})
|
|
||||||
function open(){
|
|
||||||
// console.log(callLogList.value)
|
|
||||||
callLogList.value.openAddModal()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" >
|
|
||||||
page{
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.btnImg{
|
|
||||||
position: fixed;
|
|
||||||
|
|
||||||
}
|
|
||||||
.btnImg_vivo{
|
|
||||||
width: 80px;
|
|
||||||
height: 96px;
|
|
||||||
left: 40px;
|
|
||||||
bottom: 130px;
|
|
||||||
}
|
|
||||||
.btnImg_huawei{
|
|
||||||
width: 54px;
|
|
||||||
height: 54px;
|
|
||||||
left: calc(50% - 27px);
|
|
||||||
bottom: 65px;
|
|
||||||
}
|
|
||||||
.btnImg_oppo{
|
|
||||||
width: 58px;
|
|
||||||
height: 58px;
|
|
||||||
right: 20px;
|
|
||||||
bottom: 100px;
|
|
||||||
}
|
|
||||||
.btnImg_xiaomi{
|
|
||||||
width: 55px;
|
|
||||||
height: 55px;
|
|
||||||
right: 34px;
|
|
||||||
bottom: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<NavBar :title="data.navBar.title" :bgColor="data.navBar.bgColor" />
|
|
||||||
<view class="list-container">
|
|
||||||
<view class="item" v-for="item in source" :key="item.id"
|
|
||||||
:style="{ background: `linear-gradient( -270deg, ${item.color.bgColor} 0%, #FFFFFF 70%), #FFFFFF` }">
|
|
||||||
<view class="content flex flex-align-center">
|
|
||||||
<image class="logo" :src="`/static/image/common/phone/${item.icon}.png`" mode=""></image>
|
|
||||||
<view class="name flex-1">{{ item.name }}机型</view>
|
|
||||||
<view class="right-button" :style="{ background: item.color.buttonColor }"
|
|
||||||
@click="goPage(data.type == 'message' ? item.messageUrl : item.callUrl)">立即进入</view>
|
|
||||||
</view>
|
|
||||||
<view class="line" :style="{ background: item.color.lineColor }"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import NavBar from '@/components/nav-bar/nav-bar.vue'
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
getCurrentInstance
|
|
||||||
} from 'vue'
|
|
||||||
import {
|
|
||||||
onLoad
|
|
||||||
} from "@dcloudio/uni-app";
|
|
||||||
import {
|
|
||||||
util
|
|
||||||
} from '@/utils/common.js';
|
|
||||||
|
|
||||||
const { appContext, proxy } = getCurrentInstance();
|
|
||||||
// 列表
|
|
||||||
const source = ref([{
|
|
||||||
name: '苹果',
|
|
||||||
color: {
|
|
||||||
bgColor: '#F3EAFF',
|
|
||||||
lineColor: '#B78EF5',
|
|
||||||
buttonColor: '#BA8DFF',
|
|
||||||
},
|
|
||||||
icon: 'iphone',
|
|
||||||
messageUrl: "/pages/message/list-index?phone=iphone",
|
|
||||||
callUrl: "/pages/call-log/call?type=ios"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '华为',
|
|
||||||
color: {
|
|
||||||
bgColor: '#FFE9E9',
|
|
||||||
lineColor: '#FF6969',
|
|
||||||
buttonColor: '#FB6767',
|
|
||||||
},
|
|
||||||
icon: 'huawei',
|
|
||||||
messageUrl: "/pages/message/list-index?phone=huawei",
|
|
||||||
callUrl: "/pages/call-log/call?type=huawei"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '小米',
|
|
||||||
color: {
|
|
||||||
bgColor: '#FFF0DD',
|
|
||||||
lineColor: '#FFA143',
|
|
||||||
buttonColor: '#FFA64D',
|
|
||||||
},
|
|
||||||
icon: 'mi',
|
|
||||||
messageUrl: "/pages/message/list-index?phone=mi",
|
|
||||||
callUrl: "/pages/call-log/call?type=xiaomi"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'oppo',
|
|
||||||
color: {
|
|
||||||
bgColor: '#E0FFD9',
|
|
||||||
lineColor: '#56B745',
|
|
||||||
buttonColor: '#5DCD49',
|
|
||||||
},
|
|
||||||
icon: 'oppo',
|
|
||||||
messageUrl: "/pages/message/list-index?phone=oppo",
|
|
||||||
callUrl: "/pages/call-log/call?type=oppo"
|
|
||||||
}, {
|
|
||||||
name: 'vivo',
|
|
||||||
color: {
|
|
||||||
bgColor: '#D4F4FF',
|
|
||||||
lineColor: '#52C2FF',
|
|
||||||
buttonColor: '#50C1FE',
|
|
||||||
},
|
|
||||||
icon: 'vivo',
|
|
||||||
messageUrl: "/pages/message/list-index?phone=vivo",
|
|
||||||
callUrl: "/pages/call-log/call?type=vivo"
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
navBar: {
|
|
||||||
title: '选择机型',
|
|
||||||
bgColor: '#F0F4F9',
|
|
||||||
},
|
|
||||||
type: "message"
|
|
||||||
})
|
|
||||||
|
|
||||||
onLoad((options) => {
|
|
||||||
if (options.type) {
|
|
||||||
data.type = options.type
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function goPage(url) {
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
proxy.$apiUserEvent('all', {
|
|
||||||
type: 'event',
|
|
||||||
key: data.type=='message'?'message':'call-log',
|
|
||||||
prefix: '.uni.other.',
|
|
||||||
value: data.type=='message'?'短信':"通话"
|
|
||||||
})
|
|
||||||
util.goPage(url)
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '开发中',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import '@/common/main.css';
|
|
||||||
</style>
|
|
||||||
<style lang="less">
|
|
||||||
.list-container {
|
|
||||||
background-color: #F0F4F9;
|
|
||||||
padding: 24rpx 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
width: 100%;
|
|
||||||
height: 188rpx;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
padding: 40rpx 36rpx 24rpx 28rpx;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
.logo {
|
|
||||||
width: 96rpx;
|
|
||||||
height: 96rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
margin-left: 32rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 36rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-button {
|
|
||||||
width: 140rpx;
|
|
||||||
height: 64rpx;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 64rpx !important;
|
|
||||||
text-align: center;
|
|
||||||
// display: flex;
|
|
||||||
// align-items: center;
|
|
||||||
// justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.line {
|
|
||||||
width: 100rpx;
|
|
||||||
height: 8rpx;
|
|
||||||
filter: blur(5px);
|
|
||||||
opacity: 0.5;
|
|
||||||
margin-top: 4rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -4,19 +4,8 @@
|
||||||
<view>
|
<view>
|
||||||
<image :src="data.banner" style="width: 100%;height: 244px;"></image>
|
<image :src="data.banner" style="width: 100%;height: 244px;"></image>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view style="margin-top:-90px;position: relative;">
|
<view style="margin-top:-90px;position: relative;">
|
||||||
<customTab :isHuise="shouldBeTrue(data.goods)" />
|
<customTab :isHuise="shouldBeTrue(data.goods)" />
|
||||||
</view> -->
|
|
||||||
<view class="vipContent" style="margin-top:-90px;position: relative;">
|
|
||||||
<view class="top">
|
|
||||||
<image src="/static/image/recharge/vipContentTopBgImg.png" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
<view class="vipList">
|
|
||||||
<view class="item" v-for="(item, index) in data.benefitList" :key="index">
|
|
||||||
<image :src="item.url"></image>
|
|
||||||
<text>{{ item.name }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<scroll-view class="package-items-box" scroll-x="true" v-if="data.goodsList.length">
|
<scroll-view class="package-items-box" scroll-x="true" v-if="data.goodsList.length">
|
||||||
<view class="package-items-container">
|
<view class="package-items-container">
|
||||||
|
|
@ -28,7 +17,7 @@
|
||||||
</view>
|
</view>
|
||||||
<text class="del-text">¥{{ item.origin_price }}</text>
|
<text class="del-text">¥{{ item.origin_price }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="price-box wx-font-regular">
|
<view class="price-box">
|
||||||
<text>¥</text><text class="price">{{ item.price }}</text>
|
<text>¥</text><text class="price">{{ item.price }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="shen ">
|
<view class="shen ">
|
||||||
|
|
@ -372,43 +361,43 @@ const data = reactive({
|
||||||
url: "/static/image/recharge/icon2.png"
|
url: "/static/image/recharge/icon2.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "微信模拟",
|
name: "专属客服",
|
||||||
url: "/static/image/recharge/icon3.png"
|
url: "/static/image/recharge/icon3.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "小宝模拟",
|
name: "多设备",
|
||||||
url: "/static/image/recharge/icon4.png"
|
url: "/static/image/recharge/icon4.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "机票",
|
name: "AI聊天模板",
|
||||||
url: "/static/image/recharge/icon5.png"
|
url: "/static/image/recharge/icon5.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "高铁票",
|
name: "聊天转账",
|
||||||
url: "/static/image/recharge/icon6.png"
|
url: "/static/image/recharge/icon6.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "工资单",
|
name: "限额设置",
|
||||||
url: "/static/image/recharge/icon7.png"
|
url: "/static/image/recharge/icon7.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "群聊",
|
name: "零钱修改",
|
||||||
url: "/static/image/recharge/icon8.png"
|
url: "/static/image/recharge/icon8.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "豪车模拟",
|
name: "零钱通",
|
||||||
url: "/static/image/recharge/icon9.png"
|
url: "/static/image/recharge/icon9.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "模拟来电",
|
name: "分付",
|
||||||
url: "/static/image/recharge/icon10.png"
|
url: "/static/image/recharge/icon10.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "多设备",
|
name: "账单",
|
||||||
url: "/static/image/recharge/icon11.png"
|
url: "/static/image/recharge/icon11.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "其他权益",
|
name: "朋友圈",
|
||||||
url: "/static/image/recharge/icon12.png"
|
url: "/static/image/recharge/icon12.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -444,7 +433,6 @@ const data = reactive({
|
||||||
// 添加一个标志位来防止快速连续点击导致的价格显示错误
|
// 添加一个标志位来防止快速连续点击导致的价格显示错误
|
||||||
isProcessingClick: false,
|
isProcessingClick: false,
|
||||||
banner: '/static/image/recharge/banner1.png',
|
banner: '/static/image/recharge/banner1.png',
|
||||||
isCombo: false,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
|
@ -609,24 +597,8 @@ onLoad(async () => {
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
onShow(async () => {
|
||||||
if (data.isCombo) {
|
|
||||||
uni.showModal({
|
|
||||||
title: '提示',
|
|
||||||
content: '是否支付成功?',
|
|
||||||
cancelText: '未支付',
|
|
||||||
confirmText: "已支付",
|
|
||||||
success: function (res) {
|
|
||||||
if (res.confirm) {
|
|
||||||
console.log('用户点击确定');
|
|
||||||
paymentResult(uni.getStorageSync('orderId'), paymentMethod.value)
|
|
||||||
} else if (res.cancel) {
|
|
||||||
console.log('用户点击取消');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
data.isCombo = false
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
onUnload(() => {
|
onUnload(() => {
|
||||||
// uni.offNativeEventReceive()
|
// uni.offNativeEventReceive()
|
||||||
|
|
@ -1134,11 +1106,11 @@ async function activateVip(type = '') {
|
||||||
"支付方式": paymentMethod.value == "wxpay" ? '微信' : "支付宝",
|
"支付方式": paymentMethod.value == "wxpay" ? '微信' : "支付宝",
|
||||||
})
|
})
|
||||||
|
|
||||||
let isComBo = uni.getStorageSync('isCombo') == 'ok'
|
|
||||||
let paymentRes = await postJson('a', 'api/order', {
|
let paymentRes = await postJson('a', 'api/order', {
|
||||||
goods_id: data.goods.goods_id,
|
goods_id: data.goods.goods_id,
|
||||||
coupon: data.active_id ? data.active_id : '',
|
coupon: data.active_id ? data.active_id : '',
|
||||||
pay_type: paymentMethod.value == "wxpay" ? (data.goods.weixinMpOriId && isComBo ? 'combo' : 'weixin') : "alipay",
|
pay_type: paymentMethod.value == "wxpay" ? 'weixin' : "alipay",
|
||||||
"pay_source": "app",
|
"pay_source": "app",
|
||||||
source: "uni_alipay",
|
source: "uni_alipay",
|
||||||
})
|
})
|
||||||
|
|
@ -1148,21 +1120,6 @@ async function activateVip(type = '') {
|
||||||
if (paymentRes.code == 0) {
|
if (paymentRes.code == 0) {
|
||||||
let payData = {}
|
let payData = {}
|
||||||
if (paymentMethod.value == "wxpay") {
|
if (paymentMethod.value == "wxpay") {
|
||||||
|
|
||||||
if (data.goods.weixinMpOriId && isComBo) {
|
|
||||||
console.log(paymentRes)
|
|
||||||
let SZappData = {
|
|
||||||
weixinMpOriId: data.goods.weixinMpOriId,
|
|
||||||
outTradeNo: paymentRes.data.outTradeNo
|
|
||||||
}
|
|
||||||
uni.setStorageSync('orderId', paymentRes.data.orderId)
|
|
||||||
uni.sendNativeEvent('start_combo_pay', SZappData, ret => {
|
|
||||||
console.log('宿主App回传的数据:' + ret);
|
|
||||||
});
|
|
||||||
data.isCombo = true
|
|
||||||
uni.hideLoading();
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
payData = {
|
payData = {
|
||||||
"appid": paymentRes.data.appId, // 应用ID
|
"appid": paymentRes.data.appId, // 应用ID
|
||||||
"noncestr": paymentRes.data.nonceStr, // 随机字符串
|
"noncestr": paymentRes.data.nonceStr, // 随机字符串
|
||||||
|
|
@ -1179,7 +1136,7 @@ async function activateVip(type = '') {
|
||||||
console.log('宿主App回传的数据:' + ret);
|
console.log('宿主App回传的数据:' + ret);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
payData = paymentRes.data.payParam
|
payData = paymentRes.data.payParam
|
||||||
uni.setStorageSync('orderId', paymentRes.data.orderId)
|
uni.setStorageSync('orderId', paymentRes.data.orderId)
|
||||||
|
|
@ -1510,9 +1467,7 @@ function shouldBeTrue(obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
|
||||||
@import "@/common/main.css";
|
|
||||||
</style>
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
* {
|
* {
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
|
|
@ -2454,46 +2409,4 @@ function shouldBeTrue(obj) {
|
||||||
left: 15px;
|
left: 15px;
|
||||||
z-index: 999999;
|
z-index: 999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vipContent {
|
|
||||||
background-color: #fff;
|
|
||||||
margin-left: 16px;
|
|
||||||
width: calc(100% - 32px);
|
|
||||||
border-radius: 16px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.top {
|
|
||||||
image {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.vipList {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
width: 25%;
|
|
||||||
height: 75px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 38px;
|
|
||||||
height: 38px;
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 10px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
line-height: 15px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -16,12 +16,13 @@
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
<view class="content-box" :style="{ height: windowHeight + 'px' }">
|
<view class="content-box" :style="{ height: windowHeight + 'px' }">
|
||||||
|
|
||||||
<scroll-view scroll-y="true" class="scroll-view"
|
<scroll-view scroll-y="true" class="scroll-view"
|
||||||
:style="{ height: (windowHeight - statusBarHeight - 44) + 'px', marginTop: (statusBarHeight + 44) + 'px' }"
|
:style="{ height: (windowHeight - statusBarHeight - 44) + 'px', marginTop: (statusBarHeight + 44) + 'px' }"
|
||||||
@scroll="handleScroll">
|
@scroll="handleScroll">
|
||||||
<view>
|
<view>
|
||||||
<!-- iOS专用:透明点击区域覆盖导航栏左上角 -->
|
<!-- iOS专用:透明点击区域覆盖导航栏左上角 -->
|
||||||
<view @click="exit" :style="{
|
<view @click="exit" @tap="exit" :style="{
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
top: statusBarHeight + 'px',
|
top: statusBarHeight + 'px',
|
||||||
left: '0px',
|
left: '0px',
|
||||||
|
|
@ -79,7 +80,7 @@
|
||||||
<view class="group-box">
|
<view class="group-box">
|
||||||
<image class="title-img" src="/static/image/index/shipingjiaocheng.png"></image>
|
<image class="title-img" src="/static/image/index/shipingjiaocheng.png"></image>
|
||||||
<view class="video-help-box">
|
<view class="video-help-box">
|
||||||
<view class="video-help-item" :style="{ width: (windowWidth - 32) / 4 + 'px' }"
|
<view class="video-help-item" :style="{ width: (windowWidth - 50) / 4 + 'px' }"
|
||||||
v-for="item in videoHelpList" :key="item.id" @click="clickVideoHelp(item)">
|
v-for="item in videoHelpList" :key="item.id" @click="clickVideoHelp(item)">
|
||||||
<image class="video-help-img" :src="item.icon"></image>
|
<image class="video-help-img" :src="item.icon"></image>
|
||||||
<text class="video-help-title">{{ item.text }}</text>
|
<text class="video-help-title">{{ item.text }}</text>
|
||||||
|
|
@ -114,7 +115,7 @@
|
||||||
<view class="group-box">
|
<view class="group-box">
|
||||||
<image class="title-img" src="/static/image/index/qita.png"></image>
|
<image class="title-img" src="/static/image/index/qita.png"></image>
|
||||||
<view class="video-help-box">
|
<view class="video-help-box">
|
||||||
<view class="video-help-item" :style="{ width: (windowWidth - 32) / 4 + 'px' }"
|
<view class="video-help-item" :style="{ width: (windowWidth - 50) / 4 + 'px' }"
|
||||||
v-for="item in otherList" :key="item.id" @click="clickMenu(item)">
|
v-for="item in otherList" :key="item.id" @click="clickMenu(item)">
|
||||||
<image class="video-help-img" :src="item.icon"></image>
|
<image class="video-help-img" :src="item.icon"></image>
|
||||||
<text class="video-help-title">{{ item.name }}</text>
|
<text class="video-help-title">{{ item.name }}</text>
|
||||||
|
|
@ -157,19 +158,9 @@ import {
|
||||||
onLoad,
|
onLoad,
|
||||||
onShow,
|
onShow,
|
||||||
onHide,
|
onHide,
|
||||||
onUnload,
|
onUnload
|
||||||
onReady
|
|
||||||
} from '@dcloudio/uni-app';
|
} from '@dcloudio/uni-app';
|
||||||
|
|
||||||
onReady(() => {
|
|
||||||
// NVUE 挂载极快,但给它 100~200ms 的喘息让原生视图确认渲染
|
|
||||||
setTimeout(() => {
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
plus.navigator.closeSplashscreen();
|
|
||||||
// #endif
|
|
||||||
}, 150);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 内部埋点方法
|
// 内部埋点方法
|
||||||
const apiUserEvent = async (type, adminData) => {
|
const apiUserEvent = async (type, adminData) => {
|
||||||
let uni_version = uni.getStorageSync("version")
|
let uni_version = uni.getStorageSync("version")
|
||||||
|
|
@ -229,16 +220,17 @@ const menuList = [{
|
||||||
path: "/pages/ant-credit-pay/index"
|
path: "/pages/ant-credit-pay/index"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
const otherList = [{
|
const otherList = [{
|
||||||
icon: "/static/image/index/qita/jipiao.png",
|
icon: "/static/image/index/qita/jipiao.png",
|
||||||
name: "机票",
|
name: "机票",
|
||||||
path: "/pages/other/tickets-app/index?type=airTicket"
|
path: "/pages/other/tickets-app/index"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "/static/image/index/qita/huochepiao.png",
|
icon: "/static/image/index/qita/huochepiao.png",
|
||||||
name: "火车票",
|
name: "火车票",
|
||||||
// path: "/pages/other/train-tickets/12306-tickets/12306-tickets"
|
path: "/pages/other/train-tickets/12306-tickets/12306-tickets"
|
||||||
path: "/pages/other/tickets-app/index?type=trainTicket"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "/static/image/index/qita/gongzidan.png",
|
icon: "/static/image/index/qita/gongzidan.png",
|
||||||
|
|
@ -250,21 +242,6 @@ const otherList = [{
|
||||||
name: "视频群聊",
|
name: "视频群聊",
|
||||||
path: "/pages/other/video-group-chat/video-group-chat"
|
path: "/pages/other/video-group-chat/video-group-chat"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
icon: "/static/image/index/qita/card.png",
|
|
||||||
name: "身份证",
|
|
||||||
path: "/pages/other/card/card"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "/static/image/index/qita/message.png",
|
|
||||||
name: "短信",
|
|
||||||
path: "/pages/common/call-and-message-entry/call-and-message-entry?type=message"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "/static/image/index/qita/call.png",
|
|
||||||
name: "通话",
|
|
||||||
path: "/pages/common/call-and-message-entry/call-and-message-entry?type=call"
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
|
|
@ -853,7 +830,7 @@ onUnload(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-box {
|
.group-box {
|
||||||
margin: 16px;
|
margin: 32rpx;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -866,7 +843,7 @@ onUnload(() => {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: space-between;
|
||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
padding: 24rpx 0;
|
padding: 24rpx 0;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
|
|
|
||||||
|
|
@ -1,741 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- 水印 -->
|
|
||||||
<view v-if="$isVip()">
|
|
||||||
<watermark :dark="data.dark" />
|
|
||||||
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
|
|
||||||
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
|
|
||||||
</liu-drag-button>
|
|
||||||
</view>
|
|
||||||
<view :class="`${data.phone}-style`">
|
|
||||||
<ChatLayout :phone="data.phone" :chatInfo="data.data" :sortMode="isSortMode" @send="handleSend"
|
|
||||||
:number="data.number" @dblclick-left="onDblclickLeft" @dblclick-right="onDblclickRight">
|
|
||||||
<!-- 弹出操作层及遮罩 -->
|
|
||||||
<view v-if="showActionPopup" class="action-mask" @tap="closeActionPopup">
|
|
||||||
<view class="action-popup" :style="{ top: popupTop + 'px', left: popupLeft + 'px' }">
|
|
||||||
<view class="action-item" @tap.stop="handleEdit">
|
|
||||||
<image class="action-icon" src="/static/image/phone-message/bianji.png"></image>
|
|
||||||
<text>编辑</text>
|
|
||||||
</view>
|
|
||||||
<view class="action-item" @tap.stop="handleSwap">
|
|
||||||
<image class="action-icon" src="/static/image/phone-message/huhuan.png"></image>
|
|
||||||
<text>消息互换</text>
|
|
||||||
</view>
|
|
||||||
<view class="action-item" @tap.stop="handleSort">
|
|
||||||
<image class="action-icon" src="/static/image/phone-message/sort.png"></image>
|
|
||||||
<text>排序</text>
|
|
||||||
</view>
|
|
||||||
<view class="action-item" @tap.stop="handleChangeSpeaker">
|
|
||||||
<image class="action-icon" src="/static/image/phone-message/change.png"></image>
|
|
||||||
<text>切换发言人</text>
|
|
||||||
</view>
|
|
||||||
<view class="action-item" @tap.stop="handleDelete">
|
|
||||||
<image class="action-icon" src="/static/image/phone-message/shanchu.png"></image>
|
|
||||||
<text>删除</text>
|
|
||||||
</view>
|
|
||||||
<!-- 向上指的三角形,因为要求在长按元素下方 -->
|
|
||||||
<view class="triangle"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 编辑消息弹窗 -->
|
|
||||||
<view v-if="showEditPopup" class="edit-mask" @tap="closeEditPopup">
|
|
||||||
<view class="edit-popup" @tap.stop>
|
|
||||||
<view class="edit-header">编辑消息</view>
|
|
||||||
<view class="edit-body">
|
|
||||||
<view class="edit-row">
|
|
||||||
<text class="edit-label">时间:</text>
|
|
||||||
<view class="time-picker-group">
|
|
||||||
<picker mode="date" :fields="$system == 'Android' ? 'day' : ''" :value="editingDate"
|
|
||||||
@change="onDateChange">
|
|
||||||
<view class="time-picker-item">
|
|
||||||
<text>{{ editingDate || '选择日期' }}</text>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
<picker mode="time" :fields="$system == 'Android' ? 'minute' : ''"
|
|
||||||
:value="editingTimeOfDay" @change="onTimeOfDayChange">
|
|
||||||
<view class="time-picker-item">
|
|
||||||
<text>{{ editingTimeOfDay || '选择时刻' }}</text>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="edit-row" style="align-items: flex-start;">
|
|
||||||
<text class="edit-label" style="padding-top: 6rpx;">时间显示:</text>
|
|
||||||
<view class="time-mode-group">
|
|
||||||
<view class="time-mode-btn" :class="{ active: editingTimeMode === 'auto' }"
|
|
||||||
@tap="editingTimeMode = 'auto'">自动</view>
|
|
||||||
<view class="time-mode-btn" :class="{ active: editingTimeMode === 'show' }"
|
|
||||||
@tap="editingTimeMode = 'show'">强制显示</view>
|
|
||||||
<view class="time-mode-btn" :class="{ active: editingTimeMode === 'hide' }"
|
|
||||||
@tap="editingTimeMode = 'hide'">强制隐藏</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="edit-row"
|
|
||||||
v-if="data.phone == 'huawei' || data.phone == 'oppo' || data.phone == 'vivo'">
|
|
||||||
<text class="edit-label">SIM卡:</text>
|
|
||||||
<view class="edit-input"
|
|
||||||
style="padding: 0; background: transparent; display: flex; align-items: center; border-radius: 8rpx; height: 70rpx;">
|
|
||||||
<uni-data-select v-model="editingSimKa" :localdata="simList" :clear="false"
|
|
||||||
placeholder="请选择卡号" @change="onSimKaChange"
|
|
||||||
style="flex: 1; border: none !important; width: 100%;"></uni-data-select>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="edit-row">
|
|
||||||
<text class="edit-label">内容:</text>
|
|
||||||
</view>
|
|
||||||
<editor id="editor" class="edit-textarea" placeholder="请输入消息内容..." @ready="onEditorReady">
|
|
||||||
</editor>
|
|
||||||
</view>
|
|
||||||
<view class="edit-footer">
|
|
||||||
<view class="edit-btn cancel" @tap="closeEditPopup">取消</view>
|
|
||||||
<view class="edit-btn confirm" @tap="confirmEdit">确定</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<ChatList :messageList="messageList" :phone="data.phone" :sortMode="isSortMode"
|
|
||||||
@onLongPress="onMessageLongPress" @sort="onSortChange"></ChatList>
|
|
||||||
|
|
||||||
|
|
||||||
</ChatLayout>
|
|
||||||
|
|
||||||
<!-- 排序模式底部工具条 -->
|
|
||||||
<view v-if="isSortMode" class="sort-toolbar">
|
|
||||||
<view class="sort-toolbar-tip">长按消息并拖动调整顺序</view>
|
|
||||||
<view class="sort-toolbar-actions">
|
|
||||||
<view class="sort-toolbar-btn cancel" @tap="cancelSort">取消</view>
|
|
||||||
<view class="sort-toolbar-btn confirm" @tap="confirmSort">完成</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import ChatLayout from '@/components/message/chat/chat-layout.vue'
|
|
||||||
import ChatList from '@/components/message/chat/chat-list.vue'
|
|
||||||
import defaultData from '../defaultData.json'
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
computed,
|
|
||||||
nextTick
|
|
||||||
} from 'vue'
|
|
||||||
import {
|
|
||||||
onLoad,
|
|
||||||
onShow,
|
|
||||||
onPageScroll
|
|
||||||
} from "@dcloudio/uni-app";
|
|
||||||
import {
|
|
||||||
stringUtil,
|
|
||||||
util
|
|
||||||
} from '@/utils/common.js';
|
|
||||||
|
|
||||||
const defaultList = defaultData
|
|
||||||
|
|
||||||
// 与 list-index.vue 共用同一个缓存 key
|
|
||||||
const STORAGE_KEY = 'message_list'
|
|
||||||
let currentId = null // 当前会话的 id
|
|
||||||
|
|
||||||
let isMe = ref(true)
|
|
||||||
|
|
||||||
const messageList = ref([])
|
|
||||||
const showActionPopup = ref(false)
|
|
||||||
const popupTop = ref(0)
|
|
||||||
const popupLeft = ref(0)
|
|
||||||
const selectedMessage = ref(null)
|
|
||||||
|
|
||||||
const showEditPopup = ref(false)
|
|
||||||
const editingMessage = ref(null)
|
|
||||||
const editingTime = ref("") // 完整时间字符串 "YYYY-MM-DD HH:mm"
|
|
||||||
const editingDate = ref("") // 日期部分 "YYYY-MM-DD"
|
|
||||||
const editingTimeOfDay = ref("") // 时刻部分 "HH:mm"
|
|
||||||
const editingSimKa = ref("")
|
|
||||||
const editingTimeMode = ref('auto') // 'auto' | 'show' | 'hide'
|
|
||||||
let editorCtx = null // 用于保存 editor 上下文
|
|
||||||
|
|
||||||
// ===== 排序模式相关状态 =====
|
|
||||||
const isSortMode = ref(false)
|
|
||||||
let sortingListCache = [] // 拖拽过程中的中间列表,由 ChatList emit 过来
|
|
||||||
|
|
||||||
const simList = [
|
|
||||||
{ text: "无卡号(不显)", value: "" },
|
|
||||||
{ text: "卡1", value: 1 },
|
|
||||||
{ text: "卡2", value: 2 }
|
|
||||||
]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将当前 messageList 写回缓存中对应会话的 chatList
|
|
||||||
* 同时更新列表条目顶层的 time(最新消息时间)
|
|
||||||
*/
|
|
||||||
const saveChatList = () => {
|
|
||||||
if (!currentId) return
|
|
||||||
try {
|
|
||||||
const cached = uni.getStorageSync(STORAGE_KEY)
|
|
||||||
const list = cached ? JSON.parse(cached) : defaultList
|
|
||||||
const idx = list.findIndex(item => item.id == currentId)
|
|
||||||
if (idx > -1) {
|
|
||||||
list[idx].chatList = messageList.value.map(m => ({ ...m }))
|
|
||||||
const chatArr = list[idx].chatList
|
|
||||||
const last = chatArr.length ? chatArr[chatArr.length - 1] : null
|
|
||||||
if (last && last.time) list[idx].time = last.time
|
|
||||||
uni.setStorageSync(STORAGE_KEY, JSON.stringify(list))
|
|
||||||
}
|
|
||||||
} catch (e) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
const onEditorReady = () => {
|
|
||||||
uni.createSelectorQuery().select('#editor').context((res) => {
|
|
||||||
editorCtx = res.context
|
|
||||||
if (editingMessage.value && editingMessage.value.content) {
|
|
||||||
editorCtx.setContents({
|
|
||||||
html: editingMessage.value.content
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).exec()
|
|
||||||
}
|
|
||||||
|
|
||||||
let longpressType = ref('message')
|
|
||||||
// 长按弹出弹出层
|
|
||||||
const onMessageLongPress = (index, message, type) => {
|
|
||||||
selectedMessage.value = message;
|
|
||||||
longpressType.value = type
|
|
||||||
const selector = type === 'time' ? '#time-' + index : '#msg-' + index;
|
|
||||||
uni.createSelectorQuery().select(selector).boundingClientRect(rect => {
|
|
||||||
if (rect) {
|
|
||||||
// 将弹窗定位在元素正下方 (bottom边界 + 一点点边距)
|
|
||||||
popupTop.value = rect.bottom + 10;
|
|
||||||
// 弹窗水平居中于该内容
|
|
||||||
let left = rect.left + rect.width / 2;
|
|
||||||
|
|
||||||
// 获取系统信息,防止弹出框超出屏幕左右侧
|
|
||||||
uni.getSystemInfo({
|
|
||||||
success: (info) => {
|
|
||||||
let popupWidth = 150; // 预估弹出层的固定宽度(可根据实际情况微调)
|
|
||||||
if (left < popupWidth / 2 + 10) left = popupWidth / 2 + 10;
|
|
||||||
if (left > info.windowWidth - popupWidth / 2 - 10) left = info.windowWidth - popupWidth / 2 - 10;
|
|
||||||
popupLeft.value = left;
|
|
||||||
showActionPopup.value = true;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeActionPopup = () => {
|
|
||||||
showActionPopup.value = false;
|
|
||||||
selectedMessage.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑消息
|
|
||||||
*/
|
|
||||||
const handleEdit = () => {
|
|
||||||
editingMessage.value = selectedMessage.value;
|
|
||||||
editingTime.value = selectedMessage.value.time || "";
|
|
||||||
// 拆分日期和时刻部分
|
|
||||||
const parts = (selectedMessage.value.time || "").split(' ')
|
|
||||||
editingDate.value = parts[0] || ""
|
|
||||||
editingTimeOfDay.value = parts[1] || ""
|
|
||||||
editingSimKa.value = selectedMessage.value.simIndex !== undefined ? selectedMessage.value.simIndex : "";
|
|
||||||
editingTimeMode.value = selectedMessage.value.timeMode || 'auto';
|
|
||||||
|
|
||||||
showEditPopup.value = true;
|
|
||||||
closeActionPopup();
|
|
||||||
|
|
||||||
// 如果已经初始化过了直接赋值
|
|
||||||
if (editorCtx) {
|
|
||||||
setTimeout(() => {
|
|
||||||
editorCtx.setContents({
|
|
||||||
html: editingMessage.value.content
|
|
||||||
})
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeEditPopup = () => {
|
|
||||||
showEditPopup.value = false;
|
|
||||||
editingMessage.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 日期选择器回调 - 更新日期部分并同步 editingTime
|
|
||||||
*/
|
|
||||||
const onDateChange = (e) => {
|
|
||||||
editingDate.value = e.detail.value
|
|
||||||
editingTime.value = `${editingDate.value} ${editingTimeOfDay.value}`.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时刻选择器回调 - 更新时刻部分并同步 editingTime
|
|
||||||
*/
|
|
||||||
const onTimeOfDayChange = (e) => {
|
|
||||||
editingTimeOfDay.value = e.detail.value
|
|
||||||
editingTime.value = `${editingDate.value} ${editingTimeOfDay.value}`.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换sim卡
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
const onSimKaChange = (value) => {
|
|
||||||
editingSimKa.value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirmEdit = () => {
|
|
||||||
if (editingMessage.value && editorCtx) {
|
|
||||||
editorCtx.getContents({
|
|
||||||
success: (res) => {
|
|
||||||
const index = messageList.value.findIndex(item => item.id === editingMessage.value.id)
|
|
||||||
if (index > -1) {
|
|
||||||
messageList.value[index].content = res.html;
|
|
||||||
messageList.value[index].time = editingTime.value;
|
|
||||||
// 保存 timeMode: 'auto'|'show'|'hide'
|
|
||||||
if (editingTimeMode.value === 'auto') {
|
|
||||||
delete messageList.value[index].timeMode;
|
|
||||||
} else {
|
|
||||||
messageList.value[index].timeMode = editingTimeMode.value;
|
|
||||||
}
|
|
||||||
// 兼容旧 hideTime 字段:一并清除
|
|
||||||
delete messageList.value[index].hideTime;
|
|
||||||
if (editingSimKa.value) {
|
|
||||||
messageList.value[index].simIndex = Number(editingSimKa.value);
|
|
||||||
} else {
|
|
||||||
delete messageList.value[index].simIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closeEditPopup();
|
|
||||||
saveChatList();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
closeEditPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息互换
|
|
||||||
*/
|
|
||||||
const handleSwap = () => {
|
|
||||||
const index = messageList.value.findIndex(item => item.id === selectedMessage.value.id)
|
|
||||||
messageList.value[index].isMe = !messageList.value[index].isMe
|
|
||||||
closeActionPopup();
|
|
||||||
saveChatList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进入拖动排序模式
|
|
||||||
*/
|
|
||||||
const handleSort = () => {
|
|
||||||
isSortMode.value = true
|
|
||||||
sortingListCache = messageList.value.map(item => ({ ...item }))
|
|
||||||
closeActionPopup()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ChatList 拖拽排序后回调 - 实时更新中间缓存
|
|
||||||
*/
|
|
||||||
const onSortChange = (newList) => {
|
|
||||||
sortingListCache = newList
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消排序,还原 messageList
|
|
||||||
*/
|
|
||||||
const cancelSort = () => {
|
|
||||||
isSortMode.value = false
|
|
||||||
// 不应用排序结果,无需重置messageList
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确认排序,将拖拽结果写回 messageList
|
|
||||||
*/
|
|
||||||
const confirmSort = () => {
|
|
||||||
if (sortingListCache.length > 0) {
|
|
||||||
messageList.value = sortingListCache.map(item => ({ ...item }))
|
|
||||||
}
|
|
||||||
isSortMode.value = false
|
|
||||||
saveChatList()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const handleChangeSpeaker = () => {
|
|
||||||
isMe.value = !isMe.value
|
|
||||||
if (isMe.value) {
|
|
||||||
uni.showToast({
|
|
||||||
title: "现在是自己发言",
|
|
||||||
icon: "none"
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: "现在是对方发言",
|
|
||||||
icon: "none"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
closeActionPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除消息
|
|
||||||
*/
|
|
||||||
const handleDelete = () => {
|
|
||||||
const index = messageList.value.findIndex(item => item.id === selectedMessage.value.id)
|
|
||||||
messageList.value.splice(index, 1)
|
|
||||||
closeActionPopup();
|
|
||||||
saveChatList()
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
phone: "iphone",
|
|
||||||
data: {},
|
|
||||||
number: 0
|
|
||||||
})
|
|
||||||
onLoad((options) => {
|
|
||||||
console.log(options)
|
|
||||||
if (options.phone) {
|
|
||||||
data.phone = options.phone
|
|
||||||
}
|
|
||||||
if (options.id) {
|
|
||||||
currentId = options.id
|
|
||||||
// 优先从缓存读取
|
|
||||||
try {
|
|
||||||
const cached = uni.getStorageSync(STORAGE_KEY)
|
|
||||||
let list = cached ? JSON.parse(cached) : defaultList
|
|
||||||
const found = list.find(item => item.id == options.id)
|
|
||||||
if (found) {
|
|
||||||
data.data = found
|
|
||||||
let number = 0
|
|
||||||
list.forEach(item => {
|
|
||||||
if (item.id == options.id) {
|
|
||||||
item.unRead = false
|
|
||||||
item.unReadNumber = 1
|
|
||||||
}
|
|
||||||
console.log(number + item.unRead ? item.unReadNumber : 0)
|
|
||||||
number = number + Number(item.unRead ? item.unReadNumber : 0)
|
|
||||||
})
|
|
||||||
data.number = number
|
|
||||||
console.log(data.data)
|
|
||||||
uni.setStorageSync(STORAGE_KEY, JSON.stringify(list))
|
|
||||||
|
|
||||||
messageList.value = found.chatList || []
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} catch (e) { }
|
|
||||||
// 缓存未命中时降级用内建默认数据
|
|
||||||
data.data = defaultList.find(item => item.id == options.id)
|
|
||||||
messageList.value = data.data?.chatList || []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
if (data.phone == 'oppo') {
|
|
||||||
util.setAndroidSystemBarColor('#FAFAFA')
|
|
||||||
} else {
|
|
||||||
util.setAndroidSystemBarColor('#ffffff')
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
plus.navigator.setStatusBarStyle("dark");
|
|
||||||
}, 500)
|
|
||||||
// #endif
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleSend = (params) => {
|
|
||||||
console.log(params)
|
|
||||||
params.id = stringUtil.uuid()
|
|
||||||
params.isMe = isMe.value
|
|
||||||
messageList.value.push(params)
|
|
||||||
saveChatList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 双击左侧
|
|
||||||
*/
|
|
||||||
const onDblclickLeft = () => {
|
|
||||||
isMe.value = false
|
|
||||||
uni.showToast({
|
|
||||||
title: "现在是对方发言",
|
|
||||||
icon: "none"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 双击右侧
|
|
||||||
*/
|
|
||||||
const onDblclickRight = () => {
|
|
||||||
isMe.value = true
|
|
||||||
uni.showToast({
|
|
||||||
title: "现在是自己发言",
|
|
||||||
icon: "none"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.action-mask {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 拖动排序弹窗样式 */
|
|
||||||
.sort-mask {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 1100;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sort-popup {
|
|
||||||
width: 680rpx;
|
|
||||||
max-height: 80vh;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 排序模式底部工具条 - 覆盖在输入框上,高度与输入框一致 */
|
|
||||||
.sort-toolbar {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1200;
|
|
||||||
background-color: rgba(255, 255, 255, 0.97);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding: 16rpx 32rpx;
|
|
||||||
box-shadow: 0 -1rpx 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sort-toolbar-tip {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #999999;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sort-toolbar-actions {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sort-toolbar-btn {
|
|
||||||
height: 72rpx;
|
|
||||||
line-height: 72rpx;
|
|
||||||
padding: 0 44rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 30rpx;
|
|
||||||
border-radius: 36rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sort-toolbar-btn.cancel {
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
color: #666666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sort-toolbar-btn.confirm {
|
|
||||||
background-color: #007AFF;
|
|
||||||
color: #FFFFFF;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.action-popup {
|
|
||||||
position: fixed;
|
|
||||||
background-color: #4C4C4C;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
padding: 20rpx 30rpx;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 540rpx;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-popup .triangle {
|
|
||||||
position: absolute;
|
|
||||||
top: -12rpx;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 12rpx solid transparent;
|
|
||||||
border-right: 12rpx solid transparent;
|
|
||||||
border-bottom: 14rpx solid #4C4C4C;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
color: #FFFFFF;
|
|
||||||
font-size: 20rpx;
|
|
||||||
margin: 0 20rpx;
|
|
||||||
|
|
||||||
text {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-icon {
|
|
||||||
width: 36rpx;
|
|
||||||
height: 36rpx;
|
|
||||||
margin-bottom: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 编辑弹窗样式 */
|
|
||||||
.edit-mask {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 99;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-popup {
|
|
||||||
width: 600rpx;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-header {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
text-align: center;
|
|
||||||
padding: 30rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-body {
|
|
||||||
padding: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-textarea {
|
|
||||||
width: 100%;
|
|
||||||
height: 200rpx;
|
|
||||||
background-color: #F8F8F8;
|
|
||||||
padding: 20rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #333;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .ql-container {
|
|
||||||
min-height: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-footer {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-btn {
|
|
||||||
flex: 1;
|
|
||||||
height: 90rpx;
|
|
||||||
line-height: 90rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 32rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
margin: 32rpx 16rpx;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-btn.cancel {
|
|
||||||
color: #767676;
|
|
||||||
background-color: #F1F1F1;
|
|
||||||
margin-left: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-btn.confirm {
|
|
||||||
color: #FFFFFF;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: #1777FF;
|
|
||||||
margin-right: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-label {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #333;
|
|
||||||
width: 150rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-input {
|
|
||||||
flex: 1;
|
|
||||||
height: 70rpx;
|
|
||||||
background-color: #F8F8F8;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-mode-group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-mode-btn {
|
|
||||||
padding: 4rpx 12rpx;
|
|
||||||
border-radius: 32rpx;
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #666666;
|
|
||||||
margin: 0 6rpx;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
border: 2rpx solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-mode-btn.active {
|
|
||||||
color: #007AFF;
|
|
||||||
background-color: #E8F2FF;
|
|
||||||
border-color: #007AFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 时间选择器组合样式 */
|
|
||||||
.time-picker-group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 16rpx;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-picker-item {
|
|
||||||
flex: 1;
|
|
||||||
height: 70rpx;
|
|
||||||
line-height: 70rpx;
|
|
||||||
background-color: #F8F8F8;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #333333;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,234 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": 12365458895222,
|
|
||||||
"unRead": true,
|
|
||||||
"unReadNumber": 2,
|
|
||||||
"noNotice": true,
|
|
||||||
"img": "",
|
|
||||||
"title": "京东快递",
|
|
||||||
"content": "【京东快递】您的快递已送达博朗郡二期...",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-001-a1",
|
|
||||||
"time": "2026-03-15 10:24",
|
|
||||||
"content": "<p>【京东快递】快递尾号29398已放在博朗郡二期惠美家便利店,快递员电话15320547739。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "uuid-001-a2",
|
|
||||||
"time": "2026-03-16 08:31",
|
|
||||||
"content": "<p>【京东快递】您的包裹已签收,感谢使用京东快递,期待再次为您服务。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-16 08:31:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895223,
|
|
||||||
"unRead": false,
|
|
||||||
"unReadNumber": 0,
|
|
||||||
"noNotice": false,
|
|
||||||
"img": "",
|
|
||||||
"title": "招商银行",
|
|
||||||
"content": "【招商银行】账户变动提醒",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-002-b1",
|
|
||||||
"time": "2026-03-15 12:00",
|
|
||||||
"content": "<p>【招商银行】您尾号8888的账户于03月15日11:58收入人民币90000.00元,余额965600.50元。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-15 12:00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895224,
|
|
||||||
"unRead": true,
|
|
||||||
"unReadNumber": 1,
|
|
||||||
"noNotice": false,
|
|
||||||
"img": "",
|
|
||||||
"title": "中国移动",
|
|
||||||
"content": "【中国移动】流量使用周报",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-003-c1",
|
|
||||||
"time": "2026-03-14 09:00",
|
|
||||||
"content": "<p>【中国移动】截至14日09时,您本月已使用通用流量18.5GB,剩余3.2GB。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "uuid-003-c2",
|
|
||||||
"time": "2026-03-14 18:30",
|
|
||||||
"content": "<p>【中国移动】流量包订购成功!您已成功领取5GB周末流量包,立即生效。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa: 1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-14 18:30:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895225,
|
|
||||||
"unRead": false,
|
|
||||||
"unReadNumber": 0,
|
|
||||||
"noNotice": false,
|
|
||||||
"img": "",
|
|
||||||
"title": "验证码中心",
|
|
||||||
"content": "【抖音】您的验证码是 882931",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-004-d1",
|
|
||||||
"time": "2026-03-16 01:10",
|
|
||||||
"content": "<p>【抖音】验证码 882931,用于手机绑定。5分钟内有效,请勿泄露给他人。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-16 01:10:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895226,
|
|
||||||
"unRead": false,
|
|
||||||
"unReadNumber": 0,
|
|
||||||
"noNotice": true,
|
|
||||||
"img": "",
|
|
||||||
"title": "美团外卖",
|
|
||||||
"content": "【美团】订单配送通知",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-005-e1",
|
|
||||||
"time": "2026-03-15 18:30",
|
|
||||||
"content": "<p>【美团】商家已接单,骑手正在赶往商家,请耐心等待。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "uuid-005-e2",
|
|
||||||
"time": "2026-03-15 19:15",
|
|
||||||
"content": "<p>【美团】骑手已送达!祝您用餐愉快,给个五星好评吧!</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-15 19:15:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895227,
|
|
||||||
"unRead": true,
|
|
||||||
"unReadNumber": 3,
|
|
||||||
"noNotice": false,
|
|
||||||
"img": "",
|
|
||||||
"title": "建设银行",
|
|
||||||
"content": "【建设银行】还款提醒",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-006-f1",
|
|
||||||
"time": "2026-03-10 10:00",
|
|
||||||
"content": "<p>【建设银行】您03月信用卡账单已出,应还款额为¥3,200.00。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "uuid-006-f2",
|
|
||||||
"time": "2026-03-13 14:00",
|
|
||||||
"content": "<p>【建设银行】温馨提醒:您的账单将于3天后到期,请确保扣款账户余额充足。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "uuid-006-f3",
|
|
||||||
"time": "2026-03-16 09:00",
|
|
||||||
"content": "<p>【建设银行】扣款成功。感谢您使用建设银行信用卡。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-16 09:00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895228,
|
|
||||||
"unRead": false,
|
|
||||||
"unReadNumber": 0,
|
|
||||||
"noNotice": false,
|
|
||||||
"img": "",
|
|
||||||
"title": "12306",
|
|
||||||
"content": "【12306】购票成功通知",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-007-g1",
|
|
||||||
"time": "2026-03-11 11:00",
|
|
||||||
"content": "<p>【12306】订单EG12345678支付成功。北京南-上海虹桥,03月20日14:00开。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-11 11:00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895229,
|
|
||||||
"unRead": false,
|
|
||||||
"unReadNumber": 0,
|
|
||||||
"noNotice": true,
|
|
||||||
"img": "",
|
|
||||||
"title": "腾讯科技",
|
|
||||||
"content": "【腾讯科技】安全提醒",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-008-h1",
|
|
||||||
"time": "2026-03-13 22:30",
|
|
||||||
"content": "<p>【腾讯科技】您的QQ账号在异地登录,登录地点:广州。如非本人操作请及时改密。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-13 22:30:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895230,
|
|
||||||
"unRead": true,
|
|
||||||
"unReadNumber": 1,
|
|
||||||
"noNotice": false,
|
|
||||||
"img": "",
|
|
||||||
"title": "菜鸟驿站",
|
|
||||||
"content": "【菜鸟驿站】取件通知",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-009-i1",
|
|
||||||
"time": "2026-03-16 10:15",
|
|
||||||
"content": "<p>【菜鸟驿站】您的中通包裹已到达。凭取件码 8-2-4002 领取,地址:博朗郡东门。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa: 1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-16 10:15:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12365458895231,
|
|
||||||
"unRead": false,
|
|
||||||
"unReadNumber": 0,
|
|
||||||
"noNotice": false,
|
|
||||||
"img": "",
|
|
||||||
"title": "阿里云",
|
|
||||||
"content": "【阿里云】资源包即将到期",
|
|
||||||
"chatList": [
|
|
||||||
{
|
|
||||||
"id": "uuid-010-j1",
|
|
||||||
"time": "2026-03-12 09:00",
|
|
||||||
"content": "<p>【阿里云】尊敬的用户,您的OSS存储包将于7天后到期,请及时续费。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "uuid-010-j2",
|
|
||||||
"time": "2026-03-15 15:00",
|
|
||||||
"content": "<p>【阿里云】续费成功。您的OSS存储包有效期已延长至2027年03月。</p>",
|
|
||||||
"isMe": false,
|
|
||||||
"simKa": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2026-03-15 15:00:00"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -1,722 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- 水印 -->
|
|
||||||
<view v-if="$isVip()">
|
|
||||||
<watermark :dark="data.dark" />
|
|
||||||
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
|
|
||||||
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
|
|
||||||
</liu-drag-button>
|
|
||||||
</view>
|
|
||||||
<view>
|
|
||||||
<MessageNavBar :phone="data.phone" :isScroll="data.isScroll" @add="openAddPopup" @setSim="setSim"
|
|
||||||
@setNoticeCount="setNoticeCount">
|
|
||||||
<view v-if="data.phone == 'huawei'" class="huawei-notice">
|
|
||||||
<view class="img-box">
|
|
||||||
<image class="img" src="/static/image/phone-message/huawei/notice.png" mode="aspectFill"></image>
|
|
||||||
<view class="dot" v-if="data.noticeCount > 0">{{ data.noticeCount > 99 ? '99+' : data.noticeCount }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="text">通知信息</view>
|
|
||||||
<image class="right-img" src="/static/image/phone-message/huawei/right.png" mode="aspectFill"></image>
|
|
||||||
</view>
|
|
||||||
<MessageList :phone="data.phone" :list="defaultList" @item-click="itemClick" @delete-item="deleteItem"
|
|
||||||
@edit-item="editItem">
|
|
||||||
</MessageList>
|
|
||||||
</MessageNavBar>
|
|
||||||
|
|
||||||
<!-- 添加短信弹窗 -->
|
|
||||||
<view v-if="showAddPopup" class="add-mask" @tap="closeAddPopup">
|
|
||||||
<view class="add-popup" @tap.stop>
|
|
||||||
<view class="add-header">{{ editingItem ? '编辑短信' : '新建短信' }}</view>
|
|
||||||
<view class="add-body">
|
|
||||||
<view class="add-row">
|
|
||||||
<text class="add-label">头像URL:</text>
|
|
||||||
<view class="image-box" :class="addForm.imgShape" style="width: 84rpx;height: 84rpx;"
|
|
||||||
@tap="selectImage">
|
|
||||||
<image v-if="addForm.img" class="image w100 h100" :src="addForm.img" mode="aspectFill">
|
|
||||||
</image>
|
|
||||||
<image v-else class="image w100 h100" src="/static/image/phone-message/add.png"
|
|
||||||
mode="aspectFill">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
<view v-if="data.phone == 'iphone'"
|
|
||||||
style="flex: 1;display: flex;align-items: center;justify-content: flex-end;">
|
|
||||||
<uni-data-checkbox style="display: flex;justify-content: flex-end;"
|
|
||||||
v-model="addForm.imgShape" :localdata="shape"></uni-data-checkbox>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="add-row">
|
|
||||||
<text class="add-label required">联系人</text>
|
|
||||||
<input class="add-input" v-model="addForm.title" placeholder="请输入名称或号码" />
|
|
||||||
</view>
|
|
||||||
<view class="add-row between" v-if="data.phone == 'iphone'">
|
|
||||||
<text class="add-label">取消通知</text>
|
|
||||||
<switch :checked="addForm.noNotice" @change="addForm.noNotice = !addForm.noNotice" />
|
|
||||||
</view>
|
|
||||||
<view class="add-row between">
|
|
||||||
<text class="add-label">是否未读</text>
|
|
||||||
<switch :checked="addForm.unRead" @change="addForm.unRead = !addForm.unRead" />
|
|
||||||
</view>
|
|
||||||
<view class="add-row"
|
|
||||||
v-if="addForm.unRead && (data.phone == 'oppo' || data.phone == 'huawei' || data.phone == 'iphone')">
|
|
||||||
<text class="add-label">未读数量</text>
|
|
||||||
<input class="add-input" type="number" v-model="addForm.unReadNumber" placeholder="请输入未读数量" />
|
|
||||||
</view>
|
|
||||||
<view class="add-row" v-if="addForm.chatList.length == 0 && editingItem">
|
|
||||||
<text class="add-label">消息时间</text>
|
|
||||||
<view class="time-picker-group">
|
|
||||||
<picker mode="date" :value="addForm.date" @change="onAddDateChange">
|
|
||||||
<view class="time-picker-item">
|
|
||||||
<text>{{ addForm.date || '选择日期' }}</text>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
<picker mode="time" :value="addForm.timeOfDay" @change="onAddTimeChange">
|
|
||||||
<view class="time-picker-item">
|
|
||||||
<text>{{ addForm.timeOfDay || '选择时刻' }}</text>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="add-footer">
|
|
||||||
<view class="add-btn cancel" @tap="closeAddPopup">取消</view>
|
|
||||||
<view class="add-btn confirm" @tap="confirmAdd">确定</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 设置运营商弹窗 -->
|
|
||||||
<view v-if="showSimPopup" class="add-mask" @tap="closeSimPopup">
|
|
||||||
<view class="add-popup" @tap.stop>
|
|
||||||
<view class="add-header">设置卡1卡2运营商</view>
|
|
||||||
<view class="add-body">
|
|
||||||
<view class="add-row">
|
|
||||||
<text class="add-label">卡1运营商</text>
|
|
||||||
<input class="add-input" v-model="simForm.sim1" placeholder="请输入卡1运营商名称" />
|
|
||||||
</view>
|
|
||||||
<view class="add-row">
|
|
||||||
<text class="add-label">卡2运营商</text>
|
|
||||||
<input class="add-input" v-model="simForm.sim2" placeholder="请输入卡2运营商名称" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="add-footer">
|
|
||||||
<view class="add-btn cancel" @tap="closeSimPopup">取消</view>
|
|
||||||
<view class="add-btn confirm" @tap="confirmSim">确定</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 设置通知信息未读数弹窗 -->
|
|
||||||
<view v-if="showNoticePopup" class="add-mask" @tap="closeNoticePopup">
|
|
||||||
<view class="add-popup" @tap.stop>
|
|
||||||
<view class="add-header">设置通知信息</view>
|
|
||||||
<view class="add-body">
|
|
||||||
<view class="add-row">
|
|
||||||
<text class="add-label">未读数量</text>
|
|
||||||
<input class="add-input" type="number" v-model="noticeForm.count" placeholder="请输入通知信息数量" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="add-footer">
|
|
||||||
<view class="add-btn cancel" @tap="closeNoticePopup">取消</view>
|
|
||||||
<view class="add-btn confirm" @tap="confirmNotice">确定</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import MessageNavBar from '@/components/message/list/message-nav-bar.vue'
|
|
||||||
import MessageList from '@/components/message/list/list.vue'
|
|
||||||
import defaultData from './defaultData.json'
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
reactive
|
|
||||||
} from 'vue'
|
|
||||||
import {
|
|
||||||
onLoad,
|
|
||||||
onShow,
|
|
||||||
onPageScroll
|
|
||||||
} from "@dcloudio/uni-app";
|
|
||||||
import {
|
|
||||||
stringUtil,
|
|
||||||
util
|
|
||||||
} from '@/utils/common.js';
|
|
||||||
|
|
||||||
const defaultList = ref(defaultData)
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
navBar: {
|
|
||||||
title: '信息',
|
|
||||||
bgColor: '#FFFFFF',
|
|
||||||
},
|
|
||||||
phone: 'iphone',
|
|
||||||
isScroll: false,
|
|
||||||
noticeCount: 256
|
|
||||||
})
|
|
||||||
|
|
||||||
const shape = [{
|
|
||||||
text: '圆形',
|
|
||||||
value: 'circle'
|
|
||||||
}, {
|
|
||||||
text: '方形',
|
|
||||||
value: 'square',
|
|
||||||
}]
|
|
||||||
|
|
||||||
const STORAGE_KEY = 'message_list'
|
|
||||||
const SIM_STORAGE_KEY = 'sim_info'
|
|
||||||
const NOTICE_COUNT_KEY = 'huawei_notice_count'
|
|
||||||
|
|
||||||
onLoad((options) => {
|
|
||||||
if (options.phone) {
|
|
||||||
data.phone = options.phone
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
if (data.phone == 'oppo') {
|
|
||||||
util.setAndroidSystemBarColor('#FAFAFA')
|
|
||||||
} else {
|
|
||||||
util.setAndroidSystemBarColor('#ffffff')
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
plus.navigator.setStatusBarStyle("dark");
|
|
||||||
}, 500)
|
|
||||||
// #endif
|
|
||||||
// 优先从缓存加载列表
|
|
||||||
try {
|
|
||||||
const cached = uni.getStorageSync(STORAGE_KEY)
|
|
||||||
if (cached) {
|
|
||||||
defaultList.value = JSON.parse(cached)
|
|
||||||
}
|
|
||||||
// 加载通知数量
|
|
||||||
const cachedNotice = uni.getStorageSync(NOTICE_COUNT_KEY)
|
|
||||||
if (cachedNotice !== '') {
|
|
||||||
data.noticeCount = Number(cachedNotice)
|
|
||||||
}
|
|
||||||
} catch (e) { }
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
onPageScroll((e) => {
|
|
||||||
if (e.scrollTop > 60) {
|
|
||||||
data.isScroll = true
|
|
||||||
} else {
|
|
||||||
data.isScroll = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将图片保存到本地持久化存储
|
|
||||||
* @param {string} tempFilePath 临时文件路径
|
|
||||||
* @returns {Promise<string>} 持久化后的文件路径
|
|
||||||
*/
|
|
||||||
const saveImageToLocal = (tempFilePath) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// 如果是已经持久化的路径或是静态资源,直接返回
|
|
||||||
if (!tempFilePath || tempFilePath.startsWith('_doc') || tempFilePath.startsWith('/static')) {
|
|
||||||
return resolve(tempFilePath)
|
|
||||||
}
|
|
||||||
uni.saveFile({
|
|
||||||
tempFilePath: tempFilePath,
|
|
||||||
success: (res) => {
|
|
||||||
console.log('图片持久化成功:', res.savedFilePath)
|
|
||||||
resolve(res.savedFilePath)
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('图片持久化失败:', err)
|
|
||||||
resolve(tempFilePath) // 失败则回退使用原路径,确保业务不中断
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除本地持久化文件
|
|
||||||
* @param {string} filePath 文件路径
|
|
||||||
*/
|
|
||||||
const removeLocalFile = (filePath) => {
|
|
||||||
if (filePath && filePath.startsWith('_doc')) {
|
|
||||||
uni.removeSavedFile({
|
|
||||||
filePath: filePath,
|
|
||||||
success: () => {
|
|
||||||
console.log('本地文件删除成功:', filePath)
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.warn('本地文件删除失败:', filePath, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除元素
|
|
||||||
* @param item
|
|
||||||
*/
|
|
||||||
const deleteItem = (item) => {
|
|
||||||
uni.showModal({
|
|
||||||
title: '提示',
|
|
||||||
content: '确定要删除吗?',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
const idx = defaultList.value.findIndex(i => i.id === item.id)
|
|
||||||
if (idx > -1) {
|
|
||||||
// 删除关联的本地图片文件
|
|
||||||
if (item.img) {
|
|
||||||
removeLocalFile(item.img)
|
|
||||||
}
|
|
||||||
defaultList.value.splice(idx, 1)
|
|
||||||
uni.setStorageSync(STORAGE_KEY, JSON.stringify(defaultList.value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择图片
|
|
||||||
*/
|
|
||||||
const selectImage = () => {
|
|
||||||
uni.chooseImage({
|
|
||||||
count: 1,
|
|
||||||
sizeType: ['original', 'compressed'],
|
|
||||||
sourceType: ['album', 'camera'],
|
|
||||||
success: (res) => {
|
|
||||||
addForm.img = res.tempFilePaths[0]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemClick = (item) => {
|
|
||||||
util.goPage(`/pages/message/chat-page/chat-page?phone=${data.phone}&id=${item.id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== 添加短信弹窗 =====
|
|
||||||
const showAddPopup = ref(false)
|
|
||||||
const addForm = reactive({
|
|
||||||
title: '',
|
|
||||||
img: '',
|
|
||||||
content: '',
|
|
||||||
date: '',
|
|
||||||
timeOfDay: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
// 弹窗模式:null=新增,有值=编辑中的条目
|
|
||||||
const editingItem = ref(null)
|
|
||||||
|
|
||||||
const openAddPopup = () => {
|
|
||||||
// 重置表单,默认时间为当前
|
|
||||||
const now = new Date()
|
|
||||||
const pad = v => String(v).padStart(2, '0')
|
|
||||||
editingItem.value = null
|
|
||||||
addForm.title = ''
|
|
||||||
addForm.img = ''
|
|
||||||
addForm.content = ''
|
|
||||||
addForm.unRead = false
|
|
||||||
addForm.unReadNumber = 1
|
|
||||||
addForm.noNotice = false
|
|
||||||
addForm.chatList = []
|
|
||||||
addForm.imgShape = 'circle'
|
|
||||||
addForm.date = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`
|
|
||||||
addForm.timeOfDay = `${pad(now.getHours())}:${pad(now.getMinutes())}`
|
|
||||||
showAddPopup.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeAddPopup = () => {
|
|
||||||
showAddPopup.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const onAddDateChange = (e) => {
|
|
||||||
addForm.date = e.detail.value
|
|
||||||
}
|
|
||||||
|
|
||||||
const onAddTimeChange = (e) => {
|
|
||||||
addForm.timeOfDay = e.detail.value
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑元素:回填表单并打开弹窗
|
|
||||||
*/
|
|
||||||
const editItem = (item) => {
|
|
||||||
editingItem.value = item
|
|
||||||
const lastMsg = item.chatList && item.chatList.length ? item.chatList[item.chatList.length - 1] : null
|
|
||||||
const timeStr = lastMsg ? lastMsg.time : (item.time || '')
|
|
||||||
const parts = timeStr.split(' ')
|
|
||||||
addForm.title = item.title || ''
|
|
||||||
addForm.img = item.img || ''
|
|
||||||
addForm.imgShape = item.imgShape || 'circle'
|
|
||||||
addForm.content = ''
|
|
||||||
addForm.unRead = !!item.unRead
|
|
||||||
addForm.unReadNumber = item.unReadNumber || 0
|
|
||||||
addForm.noNotice = item.noNotice || false
|
|
||||||
addForm.date = parts[0] || ''
|
|
||||||
addForm.timeOfDay = parts[1] || ''
|
|
||||||
addForm.chatList = item.chatList || []
|
|
||||||
showAddPopup.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirmAdd = async () => {
|
|
||||||
if (!addForm.title.trim()) {
|
|
||||||
uni.showToast({ title: '请输入联系人名称', icon: 'none' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const time = `${addForm.date} ${addForm.timeOfDay}`.trim()
|
|
||||||
|
|
||||||
// 处理图片持久化
|
|
||||||
let finalImgPath = addForm.img
|
|
||||||
if (editingItem.value) {
|
|
||||||
// 编辑模式:如果图片发生了变化,保存新图并删除旧图
|
|
||||||
if (addForm.img !== editingItem.value.img) {
|
|
||||||
finalImgPath = await saveImageToLocal(addForm.img)
|
|
||||||
removeLocalFile(editingItem.value.img)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 新增模式:直接持久化
|
|
||||||
finalImgPath = await saveImageToLocal(addForm.img)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (editingItem.value) {
|
|
||||||
// ===== 编辑模式:更新已有条目 =====
|
|
||||||
const idx = defaultList.value.findIndex(i => i.id === editingItem.value.id)
|
|
||||||
if (idx > -1) {
|
|
||||||
defaultList.value[idx].title = addForm.title.trim()
|
|
||||||
defaultList.value[idx].img = finalImgPath
|
|
||||||
defaultList.value[idx].unRead = addForm.unRead
|
|
||||||
defaultList.value[idx].unReadNumber = addForm.unReadNumber
|
|
||||||
defaultList.value[idx].noNotice = addForm.noNotice
|
|
||||||
defaultList.value[idx].imgShape = addForm.imgShape
|
|
||||||
defaultList.value[idx].time = time
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// ===== 新增模式 =====
|
|
||||||
const newItem = {
|
|
||||||
id: Date.now(),
|
|
||||||
unRead: addForm.unRead,
|
|
||||||
unReadNumber: addForm.unReadNumber,
|
|
||||||
noNotice: addForm.noNotice,
|
|
||||||
img: finalImgPath,
|
|
||||||
title: addForm.title.trim(),
|
|
||||||
imgShape: addForm.imgShape,
|
|
||||||
chatList: addForm.content.trim() ? [
|
|
||||||
{
|
|
||||||
id: stringUtil.uuid(),
|
|
||||||
time: time,
|
|
||||||
content: `<p>${addForm.content.trim()}</p>`,
|
|
||||||
isMe: false
|
|
||||||
}
|
|
||||||
] : [],
|
|
||||||
time: time
|
|
||||||
}
|
|
||||||
defaultList.value.unshift(newItem)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按最新消息时间降序排列
|
|
||||||
defaultList.value.sort((a, b) => {
|
|
||||||
const timeA = new Date(((a.chatList && a.chatList.length ? a.chatList[a.chatList.length - 1].time : null) || a.time || '').replace(/-/g, '/')).getTime()
|
|
||||||
const timeB = new Date(((b.chatList && b.chatList.length ? b.chatList[b.chatList.length - 1].time : null) || b.time || '').replace(/-/g, '/')).getTime()
|
|
||||||
return timeB - timeA
|
|
||||||
})
|
|
||||||
try {
|
|
||||||
uni.setStorageSync(STORAGE_KEY, JSON.stringify(defaultList.value))
|
|
||||||
} catch (e) { }
|
|
||||||
closeAddPopup()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== 设置运营商弹窗 =====
|
|
||||||
const showSimPopup = ref(false)
|
|
||||||
const simForm = reactive({
|
|
||||||
sim1: '',
|
|
||||||
sim2: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const setSim = () => {
|
|
||||||
try {
|
|
||||||
const cached = uni.getStorageSync(SIM_STORAGE_KEY)
|
|
||||||
const simInfo = cached ? JSON.parse(cached) : { sim1: '中国电信', sim2: '中国移动' }
|
|
||||||
simForm.sim1 = simInfo.sim1
|
|
||||||
simForm.sim2 = simInfo.sim2
|
|
||||||
} catch (e) {
|
|
||||||
simForm.sim1 = '中国电信'
|
|
||||||
simForm.sim2 = '中国移动'
|
|
||||||
}
|
|
||||||
showSimPopup.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeSimPopup = () => {
|
|
||||||
showSimPopup.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirmSim = () => {
|
|
||||||
try {
|
|
||||||
uni.setStorageSync(SIM_STORAGE_KEY, JSON.stringify({
|
|
||||||
sim1: simForm.sim1.trim() || '联通',
|
|
||||||
sim2: simForm.sim2.trim() || '移动'
|
|
||||||
}))
|
|
||||||
uni.showToast({ title: '保存成功', icon: 'success' })
|
|
||||||
} catch (e) { }
|
|
||||||
closeSimPopup()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== 设置通知信息未读数弹窗 =====
|
|
||||||
const showNoticePopup = ref(false)
|
|
||||||
const noticeForm = reactive({
|
|
||||||
count: 256
|
|
||||||
})
|
|
||||||
|
|
||||||
const setNoticeCount = () => {
|
|
||||||
noticeForm.count = data.noticeCount
|
|
||||||
showNoticePopup.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeNoticePopup = () => {
|
|
||||||
showNoticePopup.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirmNotice = () => {
|
|
||||||
data.noticeCount = Number(noticeForm.count) || 0
|
|
||||||
try {
|
|
||||||
uni.setStorageSync(NOTICE_COUNT_KEY, data.noticeCount)
|
|
||||||
uni.showToast({ title: '保存成功', icon: 'success' })
|
|
||||||
} catch (e) { }
|
|
||||||
closeNoticePopup()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import '@/common/main.css';
|
|
||||||
|
|
||||||
page {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="less">
|
|
||||||
::v-deep .uni-navbar__header-btns {
|
|
||||||
width: 100px !important;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iphone-style {
|
|
||||||
.mg-r-30 {
|
|
||||||
margin-right: 60rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mg-r-5 {
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-icon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-icon {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-text {
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #0278E2;
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-text {
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #1a1a1a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mi-style {
|
|
||||||
.right-icon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
margin-right: 30rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== 添加短信弹窗 ===== */
|
|
||||||
.add-mask {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 999;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-popup {
|
|
||||||
width: 88%;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-header {
|
|
||||||
padding: 36rpx 40rpx 20rpx;
|
|
||||||
font-size: 34rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #1A1A1A;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-body {
|
|
||||||
padding: 8rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20rpx 32rpx;
|
|
||||||
gap: 16rpx;
|
|
||||||
|
|
||||||
.image-box {
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.circle {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.square {
|
|
||||||
border-radius: 16rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.between {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.required {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.required::before {
|
|
||||||
position: absolute;
|
|
||||||
left: -10px;
|
|
||||||
content: '*';
|
|
||||||
top: 0;
|
|
||||||
color: #EA0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-label {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
width: 150rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-input {
|
|
||||||
flex: 1;
|
|
||||||
height: 70rpx;
|
|
||||||
background-color: #F6F6F6;
|
|
||||||
border-radius: 14rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
|
|
||||||
::v-deep .uni-input {
|
|
||||||
color: #aaaaaa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-footer {
|
|
||||||
padding: 32rpx 24rpx;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-btn {
|
|
||||||
flex: 1;
|
|
||||||
height: 90rpx;
|
|
||||||
line-height: 90rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 32rpx;
|
|
||||||
background-color: #F1F1F1;
|
|
||||||
margin: 0 16rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-btn.cancel {
|
|
||||||
color: #767676;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-btn.confirm {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #1777FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-picker-group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 16rpx;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-picker-item {
|
|
||||||
flex: 1;
|
|
||||||
height: 70rpx;
|
|
||||||
line-height: 70rpx;
|
|
||||||
background-color: #F8F8F8;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #333333;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.huawei-notice {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 32rpx;
|
|
||||||
height: 124rpx;
|
|
||||||
|
|
||||||
.img-box {
|
|
||||||
position: relative;
|
|
||||||
width: 76rpx;
|
|
||||||
height: 76rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
.img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
position: absolute;
|
|
||||||
top: -12rpx;
|
|
||||||
right: -8rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
line-height: 30rpx;
|
|
||||||
padding: 0 10rpx;
|
|
||||||
background-color: #EA0000;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
font-size: 20rpx;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 30rpx;
|
|
||||||
color: #1A1A1A;
|
|
||||||
margin: 0 32rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-img {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -218,7 +218,8 @@
|
||||||
<text class="label">等级</text>
|
<text class="label">等级</text>
|
||||||
<view class="input"
|
<view class="input"
|
||||||
:style="{ color: !ticketsInfo.ctripOrderInfo.level ? '#999' : '#333' }">
|
:style="{ color: !ticketsInfo.ctripOrderInfo.level ? '#999' : '#333' }">
|
||||||
{{ getLevelLabel(ticketsInfo.ctripOrderInfo.level) || '请选择等级' }}</view>
|
{{ getLevelLabel(ticketsInfo.ctripOrderInfo.level) || '请选择等级' }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</picker>
|
||||||
<view class="tips-container">
|
<view class="tips-container">
|
||||||
|
|
@ -256,8 +257,14 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import NavBar from '@/components/nav-bar/nav-bar.vue'
|
import NavBar from '@/components/nav-bar/nav-bar.vue'
|
||||||
import { reactive, toRefs, onMounted } from 'vue';
|
import {
|
||||||
import { onLoad } from '@dcloudio/uni-app';
|
reactive,
|
||||||
|
toRefs,
|
||||||
|
onMounted
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
onLoad
|
||||||
|
} from '@dcloudio/uni-app';
|
||||||
import defualtData from '@/pages/other/air-tickets/commom/defualt.json';
|
import defualtData from '@/pages/other/air-tickets/commom/defualt.json';
|
||||||
import airlineJson from '@/static/json/air-line.json';
|
import airlineJson from '@/static/json/air-line.json';
|
||||||
|
|
||||||
|
|
@ -280,7 +287,11 @@ const data = reactive({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const { ticketsInfo, collapsed, dragInfo } = toRefs(data)
|
const {
|
||||||
|
ticketsInfo,
|
||||||
|
collapsed,
|
||||||
|
dragInfo
|
||||||
|
} = toRefs(data)
|
||||||
|
|
||||||
const onAirlineChange = (e) => {
|
const onAirlineChange = (e) => {
|
||||||
const index = e.detail.value;
|
const index = e.detail.value;
|
||||||
|
|
@ -292,8 +303,7 @@ const onAirlineChange = (e) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
//携程会员等级
|
//携程会员等级
|
||||||
const ctripLevelList = [
|
const ctripLevelList = [{
|
||||||
{
|
|
||||||
label: "白银",
|
label: "白银",
|
||||||
value: 1
|
value: 1
|
||||||
},
|
},
|
||||||
|
|
@ -548,8 +558,12 @@ const onFlightDateChange = (e) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom Time Picker Data
|
// Custom Time Picker Data
|
||||||
const hours = Array.from({ length: 24 }, (_, i) => i.toString().padStart(2, '0'));
|
const hours = Array.from({
|
||||||
const minutes = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'));
|
length: 24
|
||||||
|
}, (_, i) => i.toString().padStart(2, '0'));
|
||||||
|
const minutes = Array.from({
|
||||||
|
length: 60
|
||||||
|
}, (_, i) => i.toString().padStart(2, '0'));
|
||||||
const timeRange = [hours, minutes];
|
const timeRange = [hours, minutes];
|
||||||
|
|
||||||
const getTimeIndex = (timeStr) => {
|
const getTimeIndex = (timeStr) => {
|
||||||
|
|
@ -586,7 +600,11 @@ const updateDuration = () => {
|
||||||
|
|
||||||
const h = Math.floor(diffMin / 60)
|
const h = Math.floor(diffMin / 60)
|
||||||
const m = diffMin % 60
|
const m = diffMin % 60
|
||||||
|
if (h > 0) {
|
||||||
ft.duration = `${h}时${m}分`
|
ft.duration = `${h}时${m}分`
|
||||||
|
} else {
|
||||||
|
ft.duration = `${m}分`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -204,8 +204,8 @@
|
||||||
<text class="label" :class="{ 'empty': index !== 0 }">乘机人</text>
|
<text class="label" :class="{ 'empty': index !== 0 }">乘机人</text>
|
||||||
<view class="info" @click="goEdit">
|
<view class="info" @click="goEdit">
|
||||||
<text class="name">{{ item.name }}</text>
|
<text class="name">{{ item.name }}</text>
|
||||||
<text class="id-card">{{ item.idType }}:{{ item.idType.includes('身份证') ?
|
<text class="id-card">{{ item.idType }}:{{ item.idType === '身份证' ?
|
||||||
showFristAndLastNumber(item.idNumber) : (item.idType.includes('护照') ?
|
stringUtil.maskIdCard(item.idNumber) : (item.idType === '护照' ?
|
||||||
stringUtil.maskPassport(item.idNumber) : item.idNumber) }}</text>
|
stringUtil.maskPassport(item.idNumber) : item.idNumber) }}</text>
|
||||||
<view class="ticket-row">
|
<view class="ticket-row">
|
||||||
<text class="ticket-no">票号:{{ item.ticketNo }}</text>
|
<text class="ticket-no">票号:{{ item.ticketNo }}</text>
|
||||||
|
|
@ -371,17 +371,6 @@ const deepMerge = (target, source) => {
|
||||||
return target;
|
return target;
|
||||||
};
|
};
|
||||||
|
|
||||||
const showFristAndLastNumber = (str) => {
|
|
||||||
if (!str) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const len = str.length;
|
|
||||||
if (len <= 2) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
return str.slice(0, 1) + '*'.repeat(len - 2) + str.slice(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
const stored = uni.getStorageSync(data.STORAGE_KEY) || "";
|
const stored = uni.getStorageSync(data.STORAGE_KEY) || "";
|
||||||
if (stored) {
|
if (stored) {
|
||||||
|
|
|
||||||
|
|
@ -198,8 +198,8 @@
|
||||||
<view class="row-content"
|
<view class="row-content"
|
||||||
@click="util.goPage('/pages/other/air-tickets/edit/edit')">
|
@click="util.goPage('/pages/other/air-tickets/edit/edit')">
|
||||||
<view class="p-name">{{ p.name }}</view>
|
<view class="p-name">{{ p.name }}</view>
|
||||||
<view class="p-sub">{{ p.idType }}: {{ p.idType.includes('身份证') ?
|
<view class="p-sub">{{ p.idType }}: {{ p.idType === '身份证' ?
|
||||||
stringUtil.maskIdCard(p.idNumber) : (p.idType.includes('护照') ?
|
stringUtil.maskIdCard(p.idNumber) : (p.idType === '护照' ?
|
||||||
stringUtil.maskPassport(p.idNumber) : p.idNumber) }}</view>
|
stringUtil.maskPassport(p.idNumber) : p.idNumber) }}</view>
|
||||||
<view class="p-sub">
|
<view class="p-sub">
|
||||||
<text>票号:{{ p.ticketNo }}</text>
|
<text>票号:{{ p.ticketNo }}</text>
|
||||||
|
|
|
||||||
|
|
@ -1,650 +0,0 @@
|
||||||
<template>
|
|
||||||
<view class="container">
|
|
||||||
<!-- 自定义头部导航栏 -->
|
|
||||||
<ZdyNavbar @right-click="edit" isRightButton rightButtonText="编辑" :title="data.navbar.title"
|
|
||||||
:bgColor="data.navbar.bgColor" :isBack="true" />
|
|
||||||
|
|
||||||
<image :src="data.code" mode="widthFix" style="width: 100vw;" @click="previewImage"></image>
|
|
||||||
<view class="button-container">
|
|
||||||
<button class="btn-save-image" @click="saveImage">保存图片</button>
|
|
||||||
</view>
|
|
||||||
<view style="width: 0px;height: 0;overflow: hidden;" v-if="data.shuaxing">
|
|
||||||
<l-painter isCanvasToTempFilePath @success="successImage" @progress="progress"
|
|
||||||
:css="`width:${data.width}px;height:${data.height }px;background-color:#fff;`">
|
|
||||||
<l-painter-view
|
|
||||||
:css="`margin-top:109px;margin-left:75px;position: relative;width:666px;height:406px;background-image: url('/static/image/other/card/cardBGImg.png');background-size:6660px 406px;`">
|
|
||||||
<!-- 头部年月 -->
|
|
||||||
<l-painter-view :css="`position: absolute;left:122px;top:54px;`">
|
|
||||||
<l-painter-text :css="data.textCss+data.textCssLeft" :text="data.form.name" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;left:122px;top:102px;`">
|
|
||||||
<l-painter-text :css="data.textCss2+data.textCssLeft" :text="data.form.gender" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;left:262px;top:102px;`">
|
|
||||||
<l-painter-text :css="data.textCss2+data.textCssLeft" :text="data.form.nation" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;left:122px;top:152px;`">
|
|
||||||
<l-painter-text v-for="(item,index) in data.form.year.toString()" :css="data.textCss3+data.textCssLeft"
|
|
||||||
:text="item" :key="index" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;left:192px;top:152px;`">
|
|
||||||
<l-painter-text :css="data.textCss2+data.textCssCenter" :text="data.form.month.toString()" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;left:254px;top:152px;`">
|
|
||||||
<l-painter-text :css="data.textCss2+data.textCssCenter" :text="data.form.day.toString()" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;left:122px;top:200px;width:274px;`">
|
|
||||||
<l-painter-text v-for="(item,index) in data.form.address" :css="data.textCss3+data.textCssLeft" :text="item"
|
|
||||||
:key="index" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;left:223px;top:322px;`">
|
|
||||||
<l-painter-text v-for="(item,index) in data.form.idNumber" :css="data.textCss4+data.textCssLeft" :text="item"
|
|
||||||
:key="index" />
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view :css="`position: absolute;right:48px;top:62px;`">
|
|
||||||
<l-painter-image v-if="data.form.photo" :src="data.form.photo" css="width: 196px; height: 230px;" />
|
|
||||||
<l-painter-view v-else css="width: 196px; height: 230px;background-color:#fff;">
|
|
||||||
</l-painter-view>
|
|
||||||
</l-painter-view>
|
|
||||||
<l-painter-view v-if="$isVip()" :css="`position: absolute;left:535px;bottom:-78px;`">
|
|
||||||
<l-painter-image src="/static/image/other/card/shuiyin2.png" css="width: 170px;height: 50px;" />
|
|
||||||
</l-painter-view>
|
|
||||||
</l-painter-view>
|
|
||||||
</l-painter>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 编辑弹窗 -->
|
|
||||||
<view v-if="showEditPopup" class="popup-overlay">
|
|
||||||
<view class="popup-content">
|
|
||||||
<view class="popup-header">
|
|
||||||
<text class="popup-title">编辑身份证</text>
|
|
||||||
<text class="popup-close" @click="closeEditPopup">×</text>
|
|
||||||
</view>
|
|
||||||
<view class="popup-body">
|
|
||||||
<view class="form-row">
|
|
||||||
<text class="form-label">姓名:</text>
|
|
||||||
<input class="form-input" v-model="editForm.name" type="text" />
|
|
||||||
</view>
|
|
||||||
<view class="form-row">
|
|
||||||
<text class="form-label">性别:</text>
|
|
||||||
<input class="form-input" v-model="editForm.gender" type="text" />
|
|
||||||
</view>
|
|
||||||
<view class="form-row">
|
|
||||||
<text class="form-label">民族:</text>
|
|
||||||
<input class="form-input" v-model="editForm.nation" type="text" />
|
|
||||||
</view>
|
|
||||||
<view class="form-row">
|
|
||||||
<text class="form-label">出生日期:</text>
|
|
||||||
<input class="form-input" v-model="editForm.year" type="number" style="width: 100px;" />
|
|
||||||
<text class="form-separator">-</text>
|
|
||||||
<input class="form-input" v-model="editForm.month" type="number" style="width: 80px;" />
|
|
||||||
<text class="form-separator">-</text>
|
|
||||||
<input class="form-input" v-model="editForm.day" type="number" style="width: 80px;" />
|
|
||||||
</view>
|
|
||||||
<view class="form-row">
|
|
||||||
<text class="form-label">住址:</text>
|
|
||||||
<input class="form-input" v-model="editForm.address" type="text" />
|
|
||||||
</view>
|
|
||||||
<view class="form-row">
|
|
||||||
<text class="form-label">身份证号:</text>
|
|
||||||
<input class="form-input" v-model="editForm.idNumber" type="text" />
|
|
||||||
</view>
|
|
||||||
<view class="form-row">
|
|
||||||
<text class="form-label">照片:</text>
|
|
||||||
<view class="upload-container">
|
|
||||||
<image v-if="editForm.photo" :src="editForm.photo" class="upload-image" @click="chooseImage" />
|
|
||||||
<view v-else class="upload-btn" @click="chooseImage">
|
|
||||||
<text class="upload-text">点击上传照片</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="popup-footer">
|
|
||||||
<button class="btn-cancel" @click="closeEditPopup">取消</button>
|
|
||||||
<button class="btn-save" @click="saveEditForm">保存</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
// 自定义头部
|
|
||||||
import ZdyNavbar from "@/components/nav-bar/nav-bar.vue"
|
|
||||||
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
watch,
|
|
||||||
nextTick,
|
|
||||||
getCurrentInstance
|
|
||||||
} from "vue";
|
|
||||||
import {
|
|
||||||
onLoad,
|
|
||||||
onShow,
|
|
||||||
onUnload,
|
|
||||||
onReady,
|
|
||||||
onPullDownRefresh,
|
|
||||||
onReachBottom
|
|
||||||
} from "@dcloudio/uni-app";
|
|
||||||
const {
|
|
||||||
appContext,
|
|
||||||
proxy
|
|
||||||
} = getCurrentInstance();
|
|
||||||
const data = reactive({
|
|
||||||
shuaxing:true,
|
|
||||||
navbar: {
|
|
||||||
title: "身份证",
|
|
||||||
bgColor: '#EDEDED',
|
|
||||||
},
|
|
||||||
width: 800,
|
|
||||||
height: 600,
|
|
||||||
code: '',
|
|
||||||
form: {
|
|
||||||
name: '某某',
|
|
||||||
gender: '男',
|
|
||||||
nation: '汉',
|
|
||||||
year: 2000,
|
|
||||||
month: 1,
|
|
||||||
day: 1,
|
|
||||||
address: '翻斗大街翻斗花园二号楼1001室',
|
|
||||||
idNumber: '110000200001010000',
|
|
||||||
photo: '',
|
|
||||||
},
|
|
||||||
textCss: 'word-spacing: 20px;font-family: "SimHei", "Microsoft YaHei", sans-serif;width:100px;color:#3D3D3D;font-size:24px; mix-blend-mode: overlay;',
|
|
||||||
textCss2: 'word-spacing: 20px;font-family: "SimHei", "Microsoft YaHei", sans-serif;width:100px;text-align: left;color:#3D3D3D;font-size:22px;mix-blend-mode: overlay;',
|
|
||||||
textCss3: 'word-spacing: 20px;letter-spacing: 10px;margin-right:2px;font-family: "SimHei", "Microsoft YaHei", sans-serif;text-align: left;color:#3D3D3D;font-size:22px;mix-blend-mode: overlay;',
|
|
||||||
textCss4: 'word-spacing: 20px;margin-right:3px;letter-spacing: 10px;font-family: "card", "Microsoft YaHei", sans-serif;text-align: left;color:#1a1a1a;font-size:28px;mix-blend-mode: overlay;display:flex;',
|
|
||||||
|
|
||||||
textCssLeft: 'text-align: left;',
|
|
||||||
textCssCenter: 'text-align: center;'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 弹窗相关
|
|
||||||
const showEditPopup = ref(false);
|
|
||||||
const editForm = ref({});
|
|
||||||
onLoad((option) => {
|
|
||||||
uni.showLoading({
|
|
||||||
title: "生成中"
|
|
||||||
})
|
|
||||||
// 进入身份证页面埋点
|
|
||||||
proxy.$apiUserEvent('all', {
|
|
||||||
type: 'event',
|
|
||||||
key: 'idcard',
|
|
||||||
prefix: '.uni.other.',
|
|
||||||
value: "身份证"
|
|
||||||
})
|
|
||||||
let formdata=uni.getStorageSync("cardForm")
|
|
||||||
if(formdata){
|
|
||||||
data.form=formdata
|
|
||||||
}
|
|
||||||
uni.$on("editFormPhoto",(info)=>{
|
|
||||||
data.code = ""
|
|
||||||
editForm.value.photo = info;
|
|
||||||
data.form.photo = info;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
onUnload(() => {
|
|
||||||
uni.$off('editFormPhoto')
|
|
||||||
})
|
|
||||||
onReady(() => {
|
|
||||||
|
|
||||||
})
|
|
||||||
onShow(() => {})
|
|
||||||
onPullDownRefresh(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
uni.stopPullDownRefresh();
|
|
||||||
}, 1000);
|
|
||||||
})
|
|
||||||
onReachBottom(() => {
|
|
||||||
|
|
||||||
})
|
|
||||||
function successImage(e) {
|
|
||||||
data.code = e
|
|
||||||
uni.hideLoading()
|
|
||||||
}
|
|
||||||
|
|
||||||
function progress(e) {
|
|
||||||
// console.log(e)
|
|
||||||
|
|
||||||
}
|
|
||||||
// 打开编辑弹窗
|
|
||||||
function edit() {
|
|
||||||
console.log(data.form)
|
|
||||||
// 复制当前表单数据到编辑表单
|
|
||||||
editForm.value = JSON.parse(JSON.stringify(data.form));
|
|
||||||
// 显示弹窗
|
|
||||||
showEditPopup.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭编辑弹窗
|
|
||||||
function closeEditPopup() {
|
|
||||||
showEditPopup.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存编辑表单
|
|
||||||
function saveEditForm() {
|
|
||||||
uni.showLoading({
|
|
||||||
title: "生成中"
|
|
||||||
})
|
|
||||||
data.shuaxing=false
|
|
||||||
// 将编辑后的数据复制回原始表单
|
|
||||||
data.form = editForm.value
|
|
||||||
data.form.photo=editForm.value.photo
|
|
||||||
setTimeout(()=>{
|
|
||||||
data.shuaxing=true
|
|
||||||
},100)
|
|
||||||
uni.setStorageSync("cardForm",data.form)
|
|
||||||
// 关闭弹窗
|
|
||||||
showEditPopup.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 选择图片
|
|
||||||
function chooseImage() {
|
|
||||||
uni.chooseImage({
|
|
||||||
count: 1,
|
|
||||||
sizeType: ['original', 'compressed'],
|
|
||||||
sourceType: ['album', 'camera'],
|
|
||||||
// crop:{
|
|
||||||
// width:'196px',
|
|
||||||
// height:"230px"
|
|
||||||
// },
|
|
||||||
success: (res) => {
|
|
||||||
uni.navigateTo({
|
|
||||||
url:'/pages/other/qf-image/qf-image?src='+res.tempFilePaths[0]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log('选择图片失败', err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将本地图片路径通过 Canvas 转换为 File 对象
|
|
||||||
* @param {string} localPath - 本地图片路径(如从 uni.chooseImage 获取的 tempFilePath)
|
|
||||||
* @param {Object} options - 可选参数
|
|
||||||
* @param {string} options.format - 输出格式 'image/png' 或 'image/jpeg',默认 'image/png'
|
|
||||||
* @param {number} options.quality - 图片质量(仅 jpeg 有效),0~1,默认 0.92
|
|
||||||
* @param {number} options.maxWidth - 最大宽度(等比缩放),不填则使用原图尺寸
|
|
||||||
* @param {number} options.maxHeight - 最大高度(等比缩放),不填则使用原图尺寸
|
|
||||||
* @returns {Promise<File>} 返回一个 Promise,resolve 为 File 对象
|
|
||||||
*/
|
|
||||||
function convertLocalImageToFile(localPath) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// 1. 读取本地图片为 Base64(避免 Image 对象直接加载本地路径的兼容问题)
|
|
||||||
plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
|
|
||||||
entry.file((file) => {
|
|
||||||
const reader = new plus.io.FileReader();
|
|
||||||
reader.onload = (e) => {
|
|
||||||
const base64Data = e.target.result; // 格式如 data:image/jpeg;base64,/9j/...
|
|
||||||
resolve(e.target.result)
|
|
||||||
};
|
|
||||||
reader.onerror = (err) => reject(err);
|
|
||||||
reader.readAsDataURL(file); // 读取为 DataURL
|
|
||||||
}, reject);
|
|
||||||
}, reject);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 预览图片
|
|
||||||
function previewImage() {
|
|
||||||
if (data.code) {
|
|
||||||
uni.previewImage({
|
|
||||||
urls: [data.code],
|
|
||||||
current: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存图片
|
|
||||||
function saveImage() {
|
|
||||||
if (data.code) {
|
|
||||||
console.log(data.code)
|
|
||||||
uni.showLoading({
|
|
||||||
title: '保存中...'
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
// 检查是否为base64格式
|
|
||||||
if (data.code.startsWith('data:image')) {
|
|
||||||
// 处理base64格式图片
|
|
||||||
console.log('开始处理base64图片');
|
|
||||||
uni.base64ToTempFile({
|
|
||||||
base64: data.code.split(',')[1], // 去除base64前缀
|
|
||||||
success: (res) => {
|
|
||||||
console.log('base64转换成功', res);
|
|
||||||
if (res.tempFilePath) {
|
|
||||||
uni.saveImageToPhotosAlbum({
|
|
||||||
filePath: res.tempFilePath,
|
|
||||||
success: () => {
|
|
||||||
console.log('保存图片成功');
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '保存成功',
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log('保存图片失败', err);
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '保存失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log('base64转换失败,无临时文件路径');
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '转换失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log('base64转换失败', err);
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '转换失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (data.code.startsWith('_') || data.code.includes('temp') || data.code.includes('cache') || data
|
|
||||||
.code.includes('_doc') || data.code.includes('_tmp')) {
|
|
||||||
// 处理本地临时文件
|
|
||||||
console.log('开始处理本地临时文件');
|
|
||||||
uni.saveImageToPhotosAlbum({
|
|
||||||
filePath: data.code,
|
|
||||||
success: () => {
|
|
||||||
console.log('保存本地文件成功');
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '保存成功',
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log('保存本地文件失败', err);
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '保存失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// 处理网络图片
|
|
||||||
console.log('开始处理网络图片');
|
|
||||||
uni.downloadFile({
|
|
||||||
url: data.code,
|
|
||||||
success: (res) => {
|
|
||||||
console.log('下载图片成功', res);
|
|
||||||
if (res.statusCode === 200 && res.tempFilePath) {
|
|
||||||
uni.saveImageToPhotosAlbum({
|
|
||||||
filePath: res.tempFilePath,
|
|
||||||
success: () => {
|
|
||||||
console.log('保存图片成功');
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '保存成功',
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log('保存图片失败', err);
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '保存失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log('下载图片失败,状态码:', res.statusCode);
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '下载失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log('下载图片失败', err);
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '下载失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('保存图片异常', error);
|
|
||||||
uni.hideLoading();
|
|
||||||
uni.showToast({
|
|
||||||
title: '保存失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '暂无图片可保存',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@font-face {
|
|
||||||
font-family: "card";
|
|
||||||
src: url("/static/font/card.ttf");
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: content-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aadadad {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heiti {
|
|
||||||
font-family: "SimHei", "Microsoft YaHei", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 弹窗样式 */
|
|
||||||
.popup-overlay {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 9999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-content {
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 10px;
|
|
||||||
width: 90%;
|
|
||||||
max-width: 500px;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20rpx;
|
|
||||||
border-bottom: 1rpx solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-title {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-close {
|
|
||||||
font-size: 48rpx;
|
|
||||||
color: #999;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-body {
|
|
||||||
padding: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-section {
|
|
||||||
margin-bottom: 30rpx;
|
|
||||||
padding: 20rpx;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-title {
|
|
||||||
font-size: 28rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-label {
|
|
||||||
width: 200rpx;
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-input {
|
|
||||||
flex: 1;
|
|
||||||
padding: 15rpx;
|
|
||||||
border: 1rpx solid #ddd;
|
|
||||||
border-radius: 4rpx;
|
|
||||||
font-size: 26rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-separator {
|
|
||||||
margin: 0 10rpx;
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-total {
|
|
||||||
margin-top: 10rpx;
|
|
||||||
padding-top: 10rpx;
|
|
||||||
border-top: 1rpx dashed #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-total-input {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
color: #ff6b35;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 上传图片样式 */
|
|
||||||
.upload-container {
|
|
||||||
flex: 1;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.upload-btn {
|
|
||||||
width: 120rpx;
|
|
||||||
height: 160rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
border: 1rpx dashed #ddd;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.upload-text {
|
|
||||||
font-size: 22rpx;
|
|
||||||
color: #999;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.upload-image {
|
|
||||||
width: 98rpx;
|
|
||||||
height: 115rpx;
|
|
||||||
border-radius: 1rpx;
|
|
||||||
object-fit: cover;
|
|
||||||
border: 1px dashed #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 20rpx;
|
|
||||||
border-top: 1rpx solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-cancel,
|
|
||||||
.btn-save {
|
|
||||||
width: 48%;
|
|
||||||
padding: 20rpx;
|
|
||||||
border-radius: 4rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-cancel {
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
color: #333;
|
|
||||||
border: 1rpx solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save {
|
|
||||||
background-color: #187AFF;
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 保存图片按钮 */
|
|
||||||
.button-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 30rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-image {
|
|
||||||
background: linear-gradient(90deg, #187AFF 0%, #3295FC 100%);
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
padding: 18rpx 60rpx;
|
|
||||||
border-radius: 40rpx;
|
|
||||||
font-size: 26rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
box-shadow: 0 3rpx 10rpx rgba(7, 66, 193, 0.3);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
text-align: center;
|
|
||||||
min-width: 160rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-image:hover {
|
|
||||||
transform: translateY(-2rpx);
|
|
||||||
box-shadow: 0 4rpx 12rpx rgba(7, 72, 193, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-save-image:active {
|
|
||||||
transform: translateY(0);
|
|
||||||
box-shadow: 0 2rpx 6rpx rgba(7, 140, 193, 0.3);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<qf-image-cropper :src="data.src" :width="196" :height="230" :radius="0" @crop="handleCrop"
|
|
||||||
:reverseRotatable="true"></qf-image-cropper>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
watch,
|
|
||||||
nextTick,
|
|
||||||
getCurrentInstance
|
|
||||||
} from "vue";
|
|
||||||
import {
|
|
||||||
onLoad,
|
|
||||||
onShow,
|
|
||||||
onReady,
|
|
||||||
onPullDownRefresh,
|
|
||||||
onReachBottom
|
|
||||||
} from "@dcloudio/uni-app";
|
|
||||||
const {
|
|
||||||
appContext,
|
|
||||||
proxy
|
|
||||||
} = getCurrentInstance();
|
|
||||||
const data = reactive({
|
|
||||||
src: ""
|
|
||||||
})
|
|
||||||
onLoad((option) => {
|
|
||||||
console.log(option)
|
|
||||||
data.src = option.src
|
|
||||||
})
|
|
||||||
|
|
||||||
function handleCrop(e) {
|
|
||||||
uni.showLoading({
|
|
||||||
title:"抠图中"
|
|
||||||
})
|
|
||||||
convertLocalImageToFile(e.tempFilePath).then(file => {
|
|
||||||
proxy.$imageUpload(file.split(',', 2)[1]).then(resimage => {
|
|
||||||
uni.hideLoading()
|
|
||||||
// editForm.value.photo = decodeURI(resimage.data);
|
|
||||||
uni.$emit("editFormPhoto", decodeURI(resimage.data))
|
|
||||||
uni.navigateBack()
|
|
||||||
}).catch(err => {
|
|
||||||
uni.hideLoading()
|
|
||||||
console.log(err.data.message)
|
|
||||||
uni.showToast({
|
|
||||||
icon: "none",
|
|
||||||
title: "图片不是人像或者过大"
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
}).catch(err => {
|
|
||||||
uni.hideLoading()
|
|
||||||
})
|
|
||||||
// uni.saveFile({
|
|
||||||
// tempFilePath: e.tempFilePath,
|
|
||||||
// success: function(res) {
|
|
||||||
// console.log(res)
|
|
||||||
// // res.avatar = res.savedFilePath
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 将本地图片路径通过 Canvas 转换为 File 对象
|
|
||||||
* @param {string} localPath - 本地图片路径(如从 uni.chooseImage 获取的 tempFilePath)
|
|
||||||
* @param {Object} options - 可选参数
|
|
||||||
* @param {string} options.format - 输出格式 'image/png' 或 'image/jpeg',默认 'image/png'
|
|
||||||
* @param {number} options.quality - 图片质量(仅 jpeg 有效),0~1,默认 0.92
|
|
||||||
* @param {number} options.maxWidth - 最大宽度(等比缩放),不填则使用原图尺寸
|
|
||||||
* @param {number} options.maxHeight - 最大高度(等比缩放),不填则使用原图尺寸
|
|
||||||
* @returns {Promise<File>} 返回一个 Promise,resolve 为 File 对象
|
|
||||||
*/
|
|
||||||
function convertLocalImageToFile(localPath) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// 1. 读取本地图片为 Base64(避免 Image 对象直接加载本地路径的兼容问题)
|
|
||||||
plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
|
|
||||||
entry.file((file) => {
|
|
||||||
const reader = new plus.io.FileReader();
|
|
||||||
reader.onload = (e) => {
|
|
||||||
const base64Data = e.target.result; // 格式如 data:image/jpeg;base64,/9j/...
|
|
||||||
resolve(e.target.result)
|
|
||||||
};
|
|
||||||
reader.onerror = (err) => reject(err);
|
|
||||||
reader.readAsDataURL(file); // 读取为 DataURL
|
|
||||||
}, reject);
|
|
||||||
}, reject);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<view class="button-container">
|
<view class="button-container">
|
||||||
<button class="btn-save-image" @click="saveImage">保存图片</button>
|
<button class="btn-save-image" @click="saveImage">保存图片</button>
|
||||||
</view>
|
</view>
|
||||||
<l-painter isCanvasToTempFilePath @success="successImage" @progress="progress" hidden
|
<l-painter isCanvasToTempFilePath @success="data.code = $event" hidden
|
||||||
:css="`width:${data.width}px;height:${data.width / 4 * 3}px;`">
|
:css="`width:${data.width}px;height:${data.width / 4 * 3}px;`">
|
||||||
<l-painter-view
|
<l-painter-view
|
||||||
:css="`position: relative;width:${data.width}px;height:${data.width / 4 * 3}px;background-image: url('/static/image/other/gzd.png');`">
|
:css="`position: relative;width:${data.width}px;height:${data.width / 4 * 3}px;background-image: url('/static/image/other/gzd.png');`">
|
||||||
|
|
@ -228,21 +228,7 @@ const data = reactive({
|
||||||
// 弹窗相关
|
// 弹窗相关
|
||||||
const showEditPopup = ref(false);
|
const showEditPopup = ref(false);
|
||||||
const editForm = ref({});
|
const editForm = ref({});
|
||||||
//
|
|
||||||
function successImage(e){
|
|
||||||
data.code=e
|
|
||||||
}
|
|
||||||
function progress(e){
|
|
||||||
if(e<0.03){
|
|
||||||
uni.showLoading({
|
|
||||||
title:"生成中"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(e==1){
|
|
||||||
uni.hideLoading()
|
|
||||||
}
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
// 打开编辑弹窗
|
// 打开编辑弹窗
|
||||||
function edit() {
|
function edit() {
|
||||||
console.log(data.form)
|
console.log(data.form)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<NavBar :title="`选择${type == 'airTicket' ? '机票' : '火车票'}`" bgColor="#F0F4F9" isBack></NavBar>
|
<NavBar title="选择机票" bgColor="#F0F4F9" isBack></NavBar>
|
||||||
|
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<template v-for="(item, index) in appList" :key="index">
|
<view class="app-card" v-for="(item, index) in appList" :key="index" @click="handleItemClick(item)">
|
||||||
<view class="app-card"
|
|
||||||
v-if="(type == 'airTicket' && item.airPath) || (type == 'trainTicket' && item.trainPath)"
|
|
||||||
@click="handleItemClick(item)">
|
|
||||||
<!-- Background Watermark -->
|
<!-- Background Watermark -->
|
||||||
<image class="watermark" :src="item.bgImage" mode="heightFix"></image>
|
<image class="watermark" :src="item.bgImage" mode="heightFix"></image>
|
||||||
|
|
||||||
|
|
@ -25,79 +22,52 @@
|
||||||
|
|
||||||
<uni-icons type="right" size="18" color="#CCCCCC"></uni-icons>
|
<uni-icons type="right" size="18" color="#CCCCCC"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import NavBar from '@/components/nav-bar/nav-bar.vue';
|
import NavBar from '@/components/nav-bar/nav-bar.vue';
|
||||||
import {
|
import { reactive, toRefs, getCurrentInstance } from 'vue';
|
||||||
reactive,
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
toRefs,
|
import { util } from '@/utils/common.js'; // Assuming util exists for navigation, similar to previous tasks
|
||||||
getCurrentInstance,
|
|
||||||
ref
|
|
||||||
} from 'vue';
|
|
||||||
import {
|
|
||||||
onLoad
|
|
||||||
} from '@dcloudio/uni-app';
|
|
||||||
import {
|
|
||||||
util
|
|
||||||
} from '@/utils/common.js'; // Assuming util exists for navigation, similar to previous tasks
|
|
||||||
const {
|
const {
|
||||||
appContext,
|
appContext,
|
||||||
proxy
|
proxy
|
||||||
} = getCurrentInstance();
|
} = getCurrentInstance();
|
||||||
|
|
||||||
let type = ref('airTicket')
|
|
||||||
|
|
||||||
const appList = [
|
const appList = [
|
||||||
{
|
{
|
||||||
name: '携程APP',
|
|
||||||
logo: '/static/image/other/tickets-app/trip-com-logo.png',
|
|
||||||
bgImage: '/static/image/other/tickets-app/trip-com-bg.png',
|
|
||||||
airPath: '/pages/other/air-tickets/ctrip-air-tickets/ctrip-air-tickets',
|
|
||||||
trainPath: "/pages/other/train-tickets/ctrip-train-tickets/ctrip-train-tickets",
|
|
||||||
isHot: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '铁路12306',
|
|
||||||
logo: '/static/image/other/tickets-app/12306-logo.png',
|
|
||||||
bgImage: '/static/image/other/tickets-app/12306-bg.png',
|
|
||||||
airPath: '',
|
|
||||||
trainPath: "/pages/other/train-tickets/12306-tickets/12306-tickets",
|
|
||||||
isHot: false
|
|
||||||
}, {
|
|
||||||
name: '去哪儿APP',
|
name: '去哪儿APP',
|
||||||
logo: '/static/image/other/tickets-app/qvnar-logo.png',
|
logo: '/static/image/other/tickets-app/qvnar-logo.png',
|
||||||
bgImage: '/static/image/other/tickets-app/qvnar-bg.png',
|
bgImage: '/static/image/other/tickets-app/qvnar-bg.png',
|
||||||
airPath: '/pages/other/air-tickets/qunar-air-tickets/qunar-air-tickets',
|
path: '/pages/other/air-tickets/qunar-air-tickets/qunar-air-tickets',
|
||||||
trainPath: "/pages/other/train-tickets/qunar-train-tickets/qunar-train-tickets",
|
|
||||||
isHot: false
|
isHot: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '飞猪APP',
|
name: '飞猪APP',
|
||||||
logo: '/static/image/other/tickets-app/fliggy-logo.png',
|
logo: '/static/image/other/tickets-app/fliggy-logo.png',
|
||||||
bgImage: '/static/image/other/tickets-app/fliggy-bg.png',
|
bgImage: '/static/image/other/tickets-app/fliggy-bg.png',
|
||||||
airPath: '/pages/other/air-tickets/fliggy-air-tickets/fliggy-air-tickets',
|
path: '/pages/other/air-tickets/fliggy-air-tickets/fliggy-air-tickets',
|
||||||
trainPath: "/pages/other/train-tickets/fliggy-train-tickets/fliggy-train-tickets",
|
|
||||||
isHot: true
|
isHot: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: '携程APP',
|
||||||
|
logo: '/static/image/other/tickets-app/trip-com-logo.png',
|
||||||
|
bgImage: '/static/image/other/tickets-app/trip-com-bg.png',
|
||||||
|
path: '/pages/other/air-tickets/ctrip-air-tickets/ctrip-air-tickets',
|
||||||
|
isHot: false
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: '铁路12306',
|
||||||
|
// logo: '/static/image/other/tickets-app/12306-logo.png',
|
||||||
|
// bgImage: '/static/image/other/tickets-app/12306-bg.png',
|
||||||
|
// path: '/pages/other/train-tickets/12306-tickets/12306-tickets',
|
||||||
|
// isHot: false
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
|
|
||||||
onLoad((option) => {
|
onLoad((option) => {
|
||||||
const appType = option.type
|
|
||||||
if (appType == "trainTicket") {
|
|
||||||
type.value = "trainTicket"
|
|
||||||
// 进入高铁票页面埋点
|
|
||||||
proxy.$apiUserEvent('all', {
|
|
||||||
type: 'event',
|
|
||||||
key: 'train_ticket',
|
|
||||||
prefix: '.uni.other.',
|
|
||||||
value: "高铁票"
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
type.value = "airTicket"
|
|
||||||
// 进入机票页面埋点
|
// 进入机票页面埋点
|
||||||
proxy.$apiUserEvent('all', {
|
proxy.$apiUserEvent('all', {
|
||||||
type: 'event',
|
type: 'event',
|
||||||
|
|
@ -105,27 +75,11 @@ onLoad((option) => {
|
||||||
prefix: '.uni.other.',
|
prefix: '.uni.other.',
|
||||||
value: "机票"
|
value: "机票"
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 跳转火车票/飞机票页面
|
|
||||||
*/
|
|
||||||
const handleItemClick = (item) => {
|
const handleItemClick = (item) => {
|
||||||
if (type.value == 'trainTicket') {
|
if (item.path) {
|
||||||
if (item.trainPath && item.trainPath != "开发中") {
|
util.goPage(item.path)
|
||||||
util.goPage(item.trainPath)
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '开发中',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (item.airPath) {
|
|
||||||
util.goPage(item.airPath)
|
|
||||||
} else {
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '开发中',
|
title: '开发中',
|
||||||
|
|
@ -134,7 +88,6 @@ const handleItemClick = (item) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.container {
|
.container {
|
||||||
|
|
|
||||||
|
|
@ -364,6 +364,14 @@ const calculateNightCount = () => {
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
const sys = uni.getSystemInfoSync();
|
const sys = uni.getSystemInfoSync();
|
||||||
statusBarHeight.value = sys.statusBarHeight || 20;
|
statusBarHeight.value = sys.statusBarHeight || 20;
|
||||||
|
|
||||||
|
// 进入高铁票页面埋点
|
||||||
|
proxy.$apiUserEvent('all', {
|
||||||
|
type: 'event',
|
||||||
|
key: 'train_ticket',
|
||||||
|
prefix: '.uni.other.',
|
||||||
|
value: "高铁票"
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
|
|
|
||||||
|
|
@ -14,21 +14,13 @@
|
||||||
<text class="label">订单号</text>
|
<text class="label">订单号</text>
|
||||||
<input class="input" v-model="ticketsInfo.orderInfo.orderNo" />
|
<input class="input" v-model="ticketsInfo.orderInfo.orderNo" />
|
||||||
</view>
|
</view>
|
||||||
<picker v-if="app == '12306'" mode="date" fields="day"
|
<picker mode="date" fields="day" :value="getPickerDate(ticketsInfo.orderInfo.orderTime)"
|
||||||
:value="getPickerDate(ticketsInfo.orderInfo.orderTime)" @change="onOrderTimeChange">
|
@change="onOrderTimeChange">
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="label">下单时间</text>
|
<text class="label">下单时间</text>
|
||||||
<view class="input">{{ ticketsInfo.orderInfo.orderTime }}</view>
|
<view class="input">{{ ticketsInfo.orderInfo.orderTime }}</view>
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</picker>
|
||||||
<view v-if="app != '12306' && app != 'fliggy'" class="form-item">
|
|
||||||
<text class="label">订单总价</text>
|
|
||||||
<input class="input" type="number" v-model="ticketsInfo.orderInfo.price" />
|
|
||||||
</view>
|
|
||||||
<view v-if="app == 'fliggy'" class="form-item">
|
|
||||||
<text class="label">已购服务</text>
|
|
||||||
<input class="input" v-model="ticketsInfo.serviceText" />
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
@ -79,18 +71,10 @@
|
||||||
<view class="input">{{ ticketsInfo.ticketInfo.arrivalTime }}</view>
|
<view class="input">{{ ticketsInfo.ticketInfo.arrivalTime }}</view>
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</picker>
|
||||||
<view class="form-item">
|
<!-- <view class="form-item">
|
||||||
<text class="label">历时</text>
|
<text class="label">历时</text>
|
||||||
<input class="input" v-model="ticketsInfo.ticketInfo.duration" />
|
<input class="input" v-model="ticketsInfo.ticketInfo.duration" disabled />
|
||||||
</view>
|
</view> -->
|
||||||
<view v-if="app == 'ctrip'" class="form-item">
|
|
||||||
<text class="label">火车名称</text>
|
|
||||||
<input class="input" v-model="ticketsInfo.ticketInfo.trainName" />
|
|
||||||
</view>
|
|
||||||
<view v-if="app == 'fliggy'" class="form-item">
|
|
||||||
<text class="label">车票状态</text>
|
|
||||||
<input class="input" v-model="ticketsInfo.ticketInfo.status" />
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
@ -111,8 +95,7 @@
|
||||||
<text class="label">姓名</text>
|
<text class="label">姓名</text>
|
||||||
<input class="input" v-model="passenger.name" />
|
<input class="input" v-model="passenger.name" />
|
||||||
</view>
|
</view>
|
||||||
<picker v-if="app != 'fliggy'" :range="ticketType" range-key="label"
|
<picker :range="ticketType" range-key="label" @change="(e) => onTicketTypeChange(e, index)">
|
||||||
@change="(e) => onTicketTypeChange(e, index)">
|
|
||||||
<view class="form-item" style="border-bottom: 1rpx solid #F5F5F5;">
|
<view class="form-item" style="border-bottom: 1rpx solid #F5F5F5;">
|
||||||
<text class="label">票种</text>
|
<text class="label">票种</text>
|
||||||
<view class="input">{{ passenger.type }}</view>
|
<view class="input">{{ passenger.type }}</view>
|
||||||
|
|
@ -133,21 +116,13 @@
|
||||||
|
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="label">票价</text>
|
<text class="label">票价</text>
|
||||||
<input class="input" type="number" v-model="passenger.price" @input="onPriceInput" />
|
<input class="input" v-model="passenger.price" />
|
||||||
</view>
|
</view>
|
||||||
<view v-if="app == 'ctrip'" class="form-item">
|
<view class="form-item">
|
||||||
<text class="label">积分</text>
|
|
||||||
<input class="input" type="number" v-model="passenger.points" />
|
|
||||||
</view>
|
|
||||||
<view v-if="app != 'ctrip'" class="form-item">
|
|
||||||
<text class="label">证件类型</text>
|
<text class="label">证件类型</text>
|
||||||
<input class="input" v-model="passenger.idType" />
|
<input class="input" v-model="passenger.idType" />
|
||||||
</view>
|
</view>
|
||||||
<view v-if="app != 'ctrip'" class="form-item">
|
<view class="form-item">
|
||||||
<text class="label">证件号</text>
|
|
||||||
<input class="input" v-model="passenger.idNumber" />
|
|
||||||
</view>
|
|
||||||
<view v-if="app != 'qunar'" class="form-item">
|
|
||||||
<text class="label">是否本人</text>
|
<text class="label">是否本人</text>
|
||||||
<switch :checked="passenger.isMe" @change="(e) => passenger.isMe = e.detail.value" />
|
<switch :checked="passenger.isMe" @change="(e) => passenger.isMe = e.detail.value" />
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -161,20 +136,16 @@
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 酒店广告 -->
|
<!-- 酒店广告 -->
|
||||||
<view v-if="app == '12306' || app == 'ctrip'" class="section-container">
|
<view class="section-container">
|
||||||
<view class="section-header" @click="toggleSection('hotelInfo')">
|
<view class="section-header" @click="toggleSection('hotelInfo')">
|
||||||
<text class="section-title">{{ app == '12306' ? '酒店广告' : '返现任务' }}</text>
|
<text class="section-title">酒店广告</text>
|
||||||
<uni-icons :type="collapsed.hotelInfo ? 'bottom' : 'top'" size="16" color="#666"></uni-icons>
|
<uni-icons :type="collapsed.hotelInfo ? 'bottom' : 'top'" size="16" color="#666"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
<view class="card" v-show="!collapsed.hotelInfo">
|
<view class="card" v-show="!collapsed.hotelInfo">
|
||||||
<view v-if="app == '12306'" class="form-item">
|
<view class="form-item">
|
||||||
<text class="label">城市</text>
|
<text class="label">城市</text>
|
||||||
<input class="input" v-model="ticketsInfo.hotelInfo.city" />
|
<input class="input" v-model="ticketsInfo.hotelInfo.city" />
|
||||||
</view>
|
</view>
|
||||||
<view v-if="app == 'ctrip'" class="form-item">
|
|
||||||
<text class="label">返现金额</text>
|
|
||||||
<input class="input" type="number" v-model="ticketsInfo.hotelInfo.cashback" />
|
|
||||||
</view>
|
|
||||||
<uni-datetime-picker type="daterange" v-model="hotelDateRange" :border="false">
|
<uni-datetime-picker type="daterange" v-model="hotelDateRange" :border="false">
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="label">入住/离店日期</text>
|
<text class="label">入住/离店日期</text>
|
||||||
|
|
@ -192,19 +163,12 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import NavBar from '@/components/nav-bar/nav-bar.vue'
|
import NavBar from '@/components/nav-bar/nav-bar.vue'
|
||||||
import {
|
import { reactive, toRefs, onMounted, computed } from 'vue';
|
||||||
reactive,
|
|
||||||
toRefs,
|
|
||||||
onMounted,
|
|
||||||
computed
|
|
||||||
} from 'vue';
|
|
||||||
import { onLoad } from '@dcloudio/uni-app';
|
|
||||||
|
|
||||||
const defaultData = {
|
const defaultData = {
|
||||||
"orderInfo": {
|
"orderInfo": {
|
||||||
"orderNo": "EJ66223536",
|
"orderNo": "EJ66223536",
|
||||||
"orderTime": "2026.01.01",
|
"orderTime": "2026.01.01"
|
||||||
"price": "4440"
|
|
||||||
},
|
},
|
||||||
"ticketInfo": {
|
"ticketInfo": {
|
||||||
"departureTime": "01-01 09:19",
|
"departureTime": "01-01 09:19",
|
||||||
|
|
@ -215,32 +179,30 @@ const defaultData = {
|
||||||
"duration": "4时45分",
|
"duration": "4时45分",
|
||||||
"date": "2026.01.01",
|
"date": "2026.01.01",
|
||||||
"weekDay": "星期四",
|
"weekDay": "星期四",
|
||||||
"gate": "6B",
|
"gate": "6B"
|
||||||
"trainName": "复兴号"
|
|
||||||
},
|
},
|
||||||
"passengerList": [{
|
"passengerList": [
|
||||||
|
{
|
||||||
"name": "张元英",
|
"name": "张元英",
|
||||||
"type": "成人票",
|
"type": "成人票",
|
||||||
"seatType": "商务座",
|
"seatType": "商务座",
|
||||||
"carriage": "01",
|
"carriage": "01",
|
||||||
"seatNo": "03C",
|
"seatNo": "03C",
|
||||||
"idType": "外国护照(KR)",
|
"idType": "外国护照(KR)",
|
||||||
"idNumber": "123456789012345678",
|
|
||||||
"price": "2110",
|
"price": "2110",
|
||||||
"status": "已支付",
|
"status": "已支付",
|
||||||
"isMe": true,
|
"isMe": true
|
||||||
"points": 9632
|
}
|
||||||
}],
|
],
|
||||||
"hotelInfo": {
|
"hotelInfo": {
|
||||||
"city": "上海",
|
"city": "上海",
|
||||||
"cashback": "25",
|
|
||||||
"startDay": "01-01",
|
"startDay": "01-01",
|
||||||
"endDay": "01-02"
|
"endDay": "01-02"
|
||||||
},
|
}
|
||||||
serviceText: "多人连坐 ¥10x2份"
|
|
||||||
}
|
}
|
||||||
// 车票类型
|
// 车票类型
|
||||||
const ticketType = [{
|
const ticketType = [
|
||||||
|
{
|
||||||
label: '成人票',
|
label: '成人票',
|
||||||
value: '1'
|
value: '1'
|
||||||
},
|
},
|
||||||
|
|
@ -265,29 +227,12 @@ const data = reactive({
|
||||||
ticketInfo: false, // Default open ticket info as it is most likely to be edited
|
ticketInfo: false, // Default open ticket info as it is most likely to be edited
|
||||||
passengerList: false,
|
passengerList: false,
|
||||||
hotelInfo: true
|
hotelInfo: true
|
||||||
},
|
|
||||||
app: '12306',
|
|
||||||
STORAGE_KEY: 'ticketsInfo'
|
|
||||||
})
|
|
||||||
|
|
||||||
let { app } = toRefs(data)
|
|
||||||
|
|
||||||
|
|
||||||
const {
|
|
||||||
ticketsInfo,
|
|
||||||
collapsed
|
|
||||||
} = toRefs(data)
|
|
||||||
|
|
||||||
onLoad((options) => {
|
|
||||||
console.log("options", options)
|
|
||||||
if (options.app) {
|
|
||||||
data.app = options.app
|
|
||||||
}
|
|
||||||
if (options.storageKey) {
|
|
||||||
data.STORAGE_KEY = options.storageKey
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const { ticketsInfo, collapsed } = toRefs(data)
|
||||||
|
|
||||||
const ticketYear = computed(() => {
|
const ticketYear = computed(() => {
|
||||||
const dateStr = data.ticketsInfo.ticketInfo.date;
|
const dateStr = data.ticketsInfo.ticketInfo.date;
|
||||||
if (dateStr && dateStr.length >= 4) {
|
if (dateStr && dateStr.length >= 4) {
|
||||||
|
|
@ -297,17 +242,14 @@ const ticketYear = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取酒店日期范围
|
* 获取酒店日期范围
|
||||||
*/
|
*/
|
||||||
const hotelDateRange = computed({
|
const hotelDateRange = computed({
|
||||||
get() {
|
get() {
|
||||||
const year = ticketYear.value;
|
const year = ticketYear.value;
|
||||||
const start = data.ticketsInfo.hotelInfo.startDay ?
|
const start = data.ticketsInfo.hotelInfo.startDay ? `${year}-${data.ticketsInfo.hotelInfo.startDay}` : '';
|
||||||
`${year}-${data.ticketsInfo.hotelInfo.startDay}` : '';
|
const end = data.ticketsInfo.hotelInfo.endDay ? `${year}-${data.ticketsInfo.hotelInfo.endDay}` : '';
|
||||||
const end = data.ticketsInfo.hotelInfo.endDay ? `${year}-${data.ticketsInfo.hotelInfo.endDay}` :
|
|
||||||
'';
|
|
||||||
if (start && end) {
|
if (start && end) {
|
||||||
return [start, end];
|
return [start, end];
|
||||||
}
|
}
|
||||||
|
|
@ -322,26 +264,12 @@ const hotelDateRange = computed({
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const stored = uni.getStorageSync(data.STORAGE_KEY)
|
const stored = uni.getStorageSync('ticketsInfo')
|
||||||
if (stored) {
|
if (stored) {
|
||||||
Object.assign(data.ticketsInfo, stored)
|
Object.assign(data.ticketsInfo, stored)
|
||||||
}
|
}
|
||||||
updateDuration();
|
updateDuration();
|
||||||
})
|
})
|
||||||
/**
|
|
||||||
* 更新总价
|
|
||||||
*/
|
|
||||||
const onPriceInput = () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
let total = 0;
|
|
||||||
data.ticketsInfo.passengerList.forEach(item => {
|
|
||||||
const price = Number(item.price) || 0;
|
|
||||||
total += price;
|
|
||||||
});
|
|
||||||
data.ticketsInfo.orderInfo.price = total.toString();
|
|
||||||
}, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确认
|
* 确认
|
||||||
*/
|
*/
|
||||||
|
|
@ -377,7 +305,7 @@ const handleRightButtonClick = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.setStorageSync(data.STORAGE_KEY, data.ticketsInfo)
|
uni.setStorageSync('ticketsInfo', data.ticketsInfo)
|
||||||
uni.navigateBack()
|
uni.navigateBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,8 +327,7 @@ const removePassenger = (index) => {
|
||||||
content: '确定要删除该乘客吗?',
|
content: '确定要删除该乘客吗?',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
data.ticketsInfo.passengerList.splice(index, 1);
|
data.ticketsInfo.passengerList.splice(index, 1)
|
||||||
onPriceInput();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -420,11 +347,9 @@ const addPassenger = () => {
|
||||||
idType: '中国居民身份证',
|
idType: '中国居民身份证',
|
||||||
price: oldPassenger.price || '0',
|
price: oldPassenger.price || '0',
|
||||||
status: '已支付',
|
status: '已支付',
|
||||||
isMe: false,
|
isMe: false
|
||||||
points: oldPassenger.points || '2898',
|
|
||||||
}
|
}
|
||||||
data.ticketsInfo.passengerList.push(newPassenger);
|
data.ticketsInfo.passengerList.push(newPassenger)
|
||||||
onPriceInput();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -507,12 +432,8 @@ const departureTimeHHMM = computed(() => {
|
||||||
* 获取出发时间选择器范围
|
* 获取出发时间选择器范围
|
||||||
*/
|
*/
|
||||||
const departureTimeRange = computed(() => {
|
const departureTimeRange = computed(() => {
|
||||||
const hours = Array.from({
|
const hours = Array.from({ length: 24 }, (_, i) => i < 10 ? '0' + i : '' + i);
|
||||||
length: 24
|
const minutes = Array.from({ length: 60 }, (_, i) => i < 10 ? '0' + i : '' + i);
|
||||||
}, (_, i) => i < 10 ? '0' + i : '' + i);
|
|
||||||
const minutes = Array.from({
|
|
||||||
length: 60
|
|
||||||
}, (_, i) => i < 10 ? '0' + i : '' + i);
|
|
||||||
return [hours, minutes];
|
return [hours, minutes];
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -549,12 +470,8 @@ const arrivalRange = computed(() => {
|
||||||
} else {
|
} else {
|
||||||
dates.push('MM-DD');
|
dates.push('MM-DD');
|
||||||
}
|
}
|
||||||
const hours = Array.from({
|
const hours = Array.from({ length: 24 }, (_, i) => i < 10 ? '0' + i : '' + i);
|
||||||
length: 24
|
const minutes = Array.from({ length: 60 }, (_, i) => i < 10 ? '0' + i : '' + i);
|
||||||
}, (_, i) => i < 10 ? '0' + i : '' + i);
|
|
||||||
const minutes = Array.from({
|
|
||||||
length: 60
|
|
||||||
}, (_, i) => i < 10 ? '0' + i : '' + i);
|
|
||||||
return [dates, hours, minutes];
|
return [dates, hours, minutes];
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,279 +0,0 @@
|
||||||
<template>
|
|
||||||
<view class="box">
|
|
||||||
<view class="codefun-flex-row codefun-justify-between codefun-items-center section_5 codefun-mt-8">
|
|
||||||
<view class="codefun-flex-row codefun-items-center">
|
|
||||||
<image class="codefun-shrink-0 image_11" src="/static/image/other/train-tickets/qunar/plan.png" />
|
|
||||||
<text class="font_3 text_31 codefun-ml-4">抢票方案详情</text>
|
|
||||||
</view>
|
|
||||||
<image class="image_4 image_12" src="/static/image/other/train-tickets/qunar/right.png" />
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row codefun-items-center section_6 codefun-mt-8">
|
|
||||||
<view class="codefun-flex-row codefun-flex-1">
|
|
||||||
<image class="codefun-shrink-0 image_13" src="/static/image/other/train-tickets/qunar/child.png" />
|
|
||||||
<view class="codefun-flex-col codefun-items-start codefun-flex-1 group_14 codefun-ml-10">
|
|
||||||
<text class="font_9 text_32">免费携带儿童申报</text>
|
|
||||||
<text class="font_5 text_34 codefun-mt-8">每名成人可免费携带1名6岁以下儿童</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="codefun-flex-col codefun-justify-start codefun-items-center codefun-shrink-0 text-wrapper_4 ml-15 codefun-justify-center">
|
|
||||||
<text class="font_9 text_33">去申报</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-col codefun-justify-start section_7 codefun-mt-8">
|
|
||||||
<view class="codefun-flex-col group_15">
|
|
||||||
<text class="codefun-self-start text_35">专属服务</text>
|
|
||||||
<view
|
|
||||||
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch group_16">
|
|
||||||
<view class="codefun-flex-row codefun-items-baseline">
|
|
||||||
<text class="codefun-shrink-0 font_3 text_36">全能抢票套餐</text>
|
|
||||||
<text class="font_19 codefun-ml-24">20元接送站代金券 x2份</text>
|
|
||||||
</view>
|
|
||||||
<image class="image_7" src="/static/image/other/train-tickets/qunar/right.png" />
|
|
||||||
</view>
|
|
||||||
<view v-for="(item, index) in services" :key="index"
|
|
||||||
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-end service-item-right">
|
|
||||||
<text class="font_19">{{ item }}</text>
|
|
||||||
<image class="image_7" src="/static/image/other/train-tickets/qunar/right.png" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-col section_8 codefun-mt-8">
|
|
||||||
<text class="codefun-self-start font_12 text_41">你可能遇到的问题</text>
|
|
||||||
<view class="codefun-flex-col codefun-self-stretch mt-25">
|
|
||||||
<view v-for="(question, index) in questions" :key="index"
|
|
||||||
class="codefun-flex-row codefun-justify-between codefun-items-center faq-item"
|
|
||||||
:class="{ 'mt-34': index > 0 }">
|
|
||||||
<view class="codefun-flex-row codefun-items-center codefun-flex-1">
|
|
||||||
<view class="codefun-flex-col codefun-items-center indicator-wrap">
|
|
||||||
<view class="codefun-shrink-0 section_9"></view>
|
|
||||||
</view>
|
|
||||||
<text class="font_3" style="margin-left: 14rpx;">{{ question.text }}</text>
|
|
||||||
</view>
|
|
||||||
<image class="image_7 faq-arrow" src="/static/image/other/train-tickets/qunar/right.png" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
const services = ref([
|
|
||||||
'腾讯视频vip月卡 x2份',
|
|
||||||
'加速包 x2份',
|
|
||||||
'24小时专人抢票 x2份'
|
|
||||||
]);
|
|
||||||
|
|
||||||
const questions = ref([
|
|
||||||
{ text: '为什么会退票失败' },
|
|
||||||
{ text: '退款什么时候到账' },
|
|
||||||
{ text: '已在车站或12306办理退票,退款何时到账' },
|
|
||||||
{ text: '如何退票' }
|
|
||||||
]);
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
@import '/common/global.css';
|
|
||||||
|
|
||||||
page {
|
|
||||||
background-color: #F2F5F9;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.mt-25 {
|
|
||||||
margin-top: 50rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box {
|
|
||||||
// padding: 0 16rpx;
|
|
||||||
|
|
||||||
.section_5 {
|
|
||||||
padding: 24rpx 28rpx 23.5rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
background-color: #ffffff;
|
|
||||||
|
|
||||||
.image_11 {
|
|
||||||
width: 32rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_3 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_31 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 26.04rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_4 {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_12 {
|
|
||||||
margin-right: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section_6 {
|
|
||||||
padding: 24rpx 32rpx;
|
|
||||||
background-color: #ffffff;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
|
|
||||||
.image_13 {
|
|
||||||
width: 72rpx;
|
|
||||||
height: 72rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_14 {
|
|
||||||
margin-top: 6.4rpx;
|
|
||||||
|
|
||||||
.text_32 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 26.12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_5 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 21.14rpx;
|
|
||||||
color: #666666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_34 {
|
|
||||||
color: #999999;
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 22.48rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-wrapper_4 {
|
|
||||||
background-image: linear-gradient(106.4deg, #ff912b -19.9%, #fc6a11 100.3%);
|
|
||||||
border-radius: 32rpx;
|
|
||||||
width: 140rpx;
|
|
||||||
height: 64rpx;
|
|
||||||
|
|
||||||
.text_33 {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_9 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section_7 {
|
|
||||||
padding: 46rpx 0 48rpx;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
|
|
||||||
.group_15 {
|
|
||||||
margin-left: 30rpx;
|
|
||||||
margin-right: 36rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.text_35 {
|
|
||||||
color: #363636;
|
|
||||||
font-size: 30rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 27.7rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_16 {
|
|
||||||
margin-top: 34.76rpx;
|
|
||||||
|
|
||||||
.font_3 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_36 {
|
|
||||||
line-height: 24.24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_19 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
color: #666666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_7 {
|
|
||||||
width: 20rpx;
|
|
||||||
height: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.service-item-right {
|
|
||||||
margin-top: 24rpx;
|
|
||||||
width: 450rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section_8 {
|
|
||||||
padding: 36.12rpx 20.54rpx 46.56rpx 28.54rpx;
|
|
||||||
background-image: linear-gradient(180deg, #f1fbfb -21.5%, #ffffff 67.4%);
|
|
||||||
border-radius: 20rpx;
|
|
||||||
border: solid 4rpx #ffffff;
|
|
||||||
|
|
||||||
.font_12 {
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 29.6rpx;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_41 {
|
|
||||||
font-size: 34rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 31.44rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section_9 {
|
|
||||||
background-color: #02c8e7;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 8rpx;
|
|
||||||
height: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.indicator-wrap {
|
|
||||||
width: 20rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_3 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_7 {
|
|
||||||
width: 20rpx;
|
|
||||||
height: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.faq-arrow {
|
|
||||||
margin-right: 15rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-34 {
|
|
||||||
margin-top: 34rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_21 {
|
|
||||||
line-height: 24.62rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,679 +0,0 @@
|
||||||
<template>
|
|
||||||
<!-- 水印 -->
|
|
||||||
<view v-if="$isVip()">
|
|
||||||
<watermark dark="light" />
|
|
||||||
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
|
|
||||||
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
|
|
||||||
</liu-drag-button>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-col section">
|
|
||||||
<NavBar :bgColor="data.navBar.bgColor" :buttonGroup="buttonGroup" @button-click="util.clickTitlePopupButton"
|
|
||||||
tipLayerType="qunar-train-tickets-tip" isTipLayer tipLayerText="修改车票信息">
|
|
||||||
<template v-slot:right>
|
|
||||||
<view class="codefun-flex-col group_2">
|
|
||||||
<view class="codefun-flex-row group_3">
|
|
||||||
<image class="image_4" src="/static/image/other/train-tickets/qunar/tuigaishuoming.png" />
|
|
||||||
<image class="image_4 ml-25" src="/static/image/other/train-tickets/qunar/kefu.png" />
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row codefun-mt-4">
|
|
||||||
<text class="font text">退改说明</text>
|
|
||||||
<text class="font text_2 ml-11">客服</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</NavBar>
|
|
||||||
<view class="codefun-flex-col">
|
|
||||||
<view class="codefun-flex-row codefun-justify-between codefun-items-center group_4">
|
|
||||||
<view class="codefun-flex-row codefun-items-center">
|
|
||||||
<image class="codefun-shrink-0 image_5" src="/static/image/other/train-tickets/qunar/success.png" />
|
|
||||||
<text class="text_5 ml-7">出票完成</text>
|
|
||||||
<view
|
|
||||||
class="codefun-flex-col codefun-justify-start codefun-items-center codefun-shrink-0 text-wrapper ml-7 codefun-justify-center">
|
|
||||||
<text class="font_5 text_6">订返程</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-col section_2">
|
|
||||||
<view class="codefun-self-start group_5">
|
|
||||||
<text class="font_2 text_3">¥</text>
|
|
||||||
<text class="font_2 text_4">{{ trainTickets.orderInfo.price }}</text>
|
|
||||||
</view>
|
|
||||||
<image class="codefun-shrink-0 codefun-self-end image_7 image_8"
|
|
||||||
src="/static/image/other/train-tickets/qunar/right.png" />
|
|
||||||
<text class="codefun-self-start text_7">支付明细</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="main-box">
|
|
||||||
<view class="codefun-flex-col section_3">
|
|
||||||
<view class="codefun-flex-col view">
|
|
||||||
<view class="codefun-flex-row codefun-items-baseline codefun-self-stretch codefun-justify-between">
|
|
||||||
<text class="font_5 text_8">取票号:{{ trainTickets.orderInfo.orderNo }}</text>
|
|
||||||
<view class="group_9 ml-25">
|
|
||||||
<text class="font_6">{{ trainTickets.ticketInfo.gate }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row equal-division codefun-justify-between">
|
|
||||||
<view class="codefun-flex-col group_10 group_28">
|
|
||||||
<text class="codefun-self-stretch font_3 text_16">{{
|
|
||||||
formatDateTime(trainTickets.ticketInfo.departureTime,
|
|
||||||
trainTickets.ticketInfo.date) }}</text>
|
|
||||||
<text class="codefun-self-start font_8 mt-7">{{
|
|
||||||
trainTickets.ticketInfo.departureTime.split(' ')[1]
|
|
||||||
}}</text>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-col codefun-items-center group_10 group_29">
|
|
||||||
<text class="font_5 text_17">{{ trainTickets.ticketInfo.duration }}</text>
|
|
||||||
<image class="image_9 mt-11" src="/static/image/other/train-tickets/qunar/jingtingzhan.png" />
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-col group_10 group_26">
|
|
||||||
<text class="codefun-self-start font_3 text_18">{{
|
|
||||||
formatDateTime(trainTickets.ticketInfo.arrivalTime,
|
|
||||||
trainTickets.ticketInfo.date) }}</text>
|
|
||||||
<text class="codefun-self-end font_8 mt-7">{{ trainTickets.ticketInfo.arrivalTime.split(' ')[1]
|
|
||||||
}}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row codefun-justify-center codefun-self-stretch codefun-relative group_11">
|
|
||||||
<view class="codefun-flex-row codefun-items-center pos">
|
|
||||||
<text class="font_9 text_19">{{ trainTickets.ticketInfo.departureStation }}</text>
|
|
||||||
<image class="codefun-shrink-0 image_4 ml-3"
|
|
||||||
src="/static/image/other/train-tickets/qunar/location.png" />
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row codefun-items-center">
|
|
||||||
<text class="font_19 text_21">{{ trainTickets.ticketInfo.trainNo }}</text>
|
|
||||||
<image class="codefun-shrink-0 image_10 codefun-ml-2"
|
|
||||||
src="/static/image/other/train-tickets/qunar/info.png" />
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row codefun-items-center pos_2">
|
|
||||||
<image class="codefun-shrink-0 image_4"
|
|
||||||
src="/static/image/other/train-tickets/qunar/location.png" />
|
|
||||||
<text class="font_9 text_20 codefun-ml-4">{{ trainTickets.ticketInfo.arrivalStation }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-col group_12">
|
|
||||||
<view class="codefun-flex-col section_1" v-for="item in trainTickets.passengerList" :key="item.id">
|
|
||||||
<view class="codefun-flex-col">
|
|
||||||
<view class="codefun-flex-row codefun-justify-between codefun-items-center">
|
|
||||||
<view class="codefun-flex-row codefun-items-baseline">
|
|
||||||
<text class="font_10">{{ item.name }}</text>
|
|
||||||
<text class="font_11 text_22 codefun-ml-10">{{ item.idType }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row">
|
|
||||||
<view
|
|
||||||
class="codefun-flex-col codefun-justify-start codefun-items-center codefun-shrink-0 text-wrapper_8">
|
|
||||||
<text v-if="computeSeatNo(item.seatNo)" class="font_4 text_23">{{
|
|
||||||
computeSeatNo(item.seatNo) }}</text>
|
|
||||||
</view>
|
|
||||||
<text class="font_12 text_51 codefun-ml-6">{{ item.carriage }}车{{ item.seatNo }}号</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row codefun-justify-between codefun-mt-8">
|
|
||||||
<text class="codefun-self-start font_13">{{ item.idType.includes('身份证') ?
|
|
||||||
stringUtil.maskIdCard(item.idNumber) : (item.idType.includes('护照') ?
|
|
||||||
stringUtil.maskPassport(item.idNumber) : item.idNumber) }}</text>
|
|
||||||
<text class="codefun-self-center font_14 text_25">{{ item.seatType }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="codefun-flex-row codefun-justify-between codefun-items-center group_27 mt-19">
|
|
||||||
<text class="font_15 text_50">出票成功</text>
|
|
||||||
<view class="codefun-flex-row">
|
|
||||||
<view class="codefun-flex-col codefun-justify-center codefun-items-center action-btn">
|
|
||||||
<text class="font_16">分享</text>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="codefun-flex-col codefun-justify-center codefun-items-center action-btn codefun-ml-6">
|
|
||||||
<text class="font_16">改签</text>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="codefun-flex-col codefun-justify-center codefun-items-center action-btn codefun-ml-6">
|
|
||||||
<text class="font_16">退票</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<Box />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import NavBar from '@/components/nav-bar/nav-bar.vue';
|
|
||||||
import Box from './components/box.vue';
|
|
||||||
import { reactive, ref, computed, toRefs } from 'vue';
|
|
||||||
import { onShow, onPageScroll } from '@dcloudio/uni-app';
|
|
||||||
import { util, stringUtil } from '@/utils/common.js';
|
|
||||||
import CtripTrainTickets from '../ctrip-train-tickets/ctrip-train-tickets.vue';
|
|
||||||
|
|
||||||
const buttonGroup = [{
|
|
||||||
name: "编辑机票信息",
|
|
||||||
click: () => {
|
|
||||||
goEdit()
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
function goEdit() {
|
|
||||||
util.goPage(`/pages/other/train-tickets/edit/edit?app=qunar&storageKey=${data.STORAGE_KEY}`)
|
|
||||||
}
|
|
||||||
const data = reactive({
|
|
||||||
navBar: {
|
|
||||||
bgColor: 'transparent'
|
|
||||||
},
|
|
||||||
trainTickets: {
|
|
||||||
"orderInfo": {
|
|
||||||
"orderNo": "EJ66223536",
|
|
||||||
"price": "4440"
|
|
||||||
},
|
|
||||||
"ticketInfo": {
|
|
||||||
"departureTime": "01-01 09:19",
|
|
||||||
"departureStation": "北京南",
|
|
||||||
"arrivalTime": "01-01 14:04",
|
|
||||||
"arrivalStation": "上海虹桥",
|
|
||||||
"trainNo": "G905",
|
|
||||||
"duration": "4时45分",
|
|
||||||
"date": "2026.01.01",
|
|
||||||
"weekDay": "星期四",
|
|
||||||
"gate": "6A、7A进站检票口,6B、7B进站检票",
|
|
||||||
"trainName": "复兴号"
|
|
||||||
},
|
|
||||||
"passengerList": [
|
|
||||||
{
|
|
||||||
"name": "张元英",
|
|
||||||
"type": "成人票",
|
|
||||||
"seatType": "商务座",
|
|
||||||
"carriage": "01",
|
|
||||||
"seatNo": "03C",
|
|
||||||
"idType": "外国护照(KR)",
|
|
||||||
"idNumber": "KR123456789",
|
|
||||||
"price": "2110",
|
|
||||||
"status": "已支付",
|
|
||||||
"isMe": true,
|
|
||||||
"points": 9632
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
STORAGE_KEY: 'qunarTrainTickets'
|
|
||||||
})
|
|
||||||
|
|
||||||
let { trainTickets } = toRefs(data)
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
const stored = uni.getStorageSync(data.STORAGE_KEY)
|
|
||||||
if (stored) {
|
|
||||||
Object.assign(data.trainTickets, stored)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onPageScroll((e) => {
|
|
||||||
data.navBar.bgColor = e.scrollTop > 40 ? '#F2F5F9' : 'transparent';
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const computeSeatNo = (seatNo) => {
|
|
||||||
if (seatNo.includes('C') || seatNo.includes('F')) {
|
|
||||||
return '靠窗';
|
|
||||||
} else if (seatNo.includes('A') || seatNo.includes('D')) {
|
|
||||||
return '过道';
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatDateTime = (timeStr, dateStr) => {
|
|
||||||
if (!timeStr) return '';
|
|
||||||
const parts = timeStr.split(' ');
|
|
||||||
const md = parts[0];
|
|
||||||
if (!md) return '';
|
|
||||||
const mdParts = md.split('-');
|
|
||||||
let year, month, day;
|
|
||||||
|
|
||||||
if (mdParts.length === 3) {
|
|
||||||
year = mdParts[0];
|
|
||||||
month = mdParts[1];
|
|
||||||
day = mdParts[2];
|
|
||||||
} else if (mdParts.length === 2) {
|
|
||||||
month = mdParts[0];
|
|
||||||
day = mdParts[1];
|
|
||||||
year = new Date().getFullYear();
|
|
||||||
if (dateStr) {
|
|
||||||
year = dateStr.split('.')[0];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const dateObj = new Date(Number(year), Number(month) - 1, Number(day));
|
|
||||||
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
|
||||||
const week = isNaN(dateObj.getTime()) ? '' : weekDays[dateObj.getDay()];
|
|
||||||
|
|
||||||
return `${month}月${day}日 ${week}`;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import '/common/global.css';
|
|
||||||
|
|
||||||
page {
|
|
||||||
background-color: #F2F5F9;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
::v-deep .uni-navbar__header-btns-right {
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ml-11 {
|
|
||||||
margin-left: 22rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ml-7 {
|
|
||||||
margin-left: 14rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ml-25 {
|
|
||||||
margin-left: 50rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-7 {
|
|
||||||
margin-top: 14rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-11 {
|
|
||||||
margin-top: 22rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ml-3 {
|
|
||||||
margin-left: 6rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-19 {
|
|
||||||
margin-top: 38rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section {
|
|
||||||
background: linear-gradient(180deg, #CDF2F6 0%, #F2F5F9 100%);
|
|
||||||
|
|
||||||
.image_5 {
|
|
||||||
width: 44rpx;
|
|
||||||
height: 44rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_2 {
|
|
||||||
.group_3 {
|
|
||||||
padding-left: 23.26rpx;
|
|
||||||
padding-right: 4.64rpx;
|
|
||||||
|
|
||||||
.image_4 {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.font {
|
|
||||||
font-size: 18rpx;
|
|
||||||
line-height: 16.88rpx;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
line-height: 16.68rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_2 {
|
|
||||||
line-height: 16.74rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_4 {
|
|
||||||
padding-left: 20rpx;
|
|
||||||
padding-bottom: 30rpx;
|
|
||||||
|
|
||||||
.text_5 {
|
|
||||||
color: #363636;
|
|
||||||
font-size: 44rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 41.18rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-wrapper {
|
|
||||||
border-radius: 25rpx;
|
|
||||||
width: 106rpx;
|
|
||||||
height: 50rpx;
|
|
||||||
border: solid 1rpx #28c2dd;
|
|
||||||
|
|
||||||
.text_6 {
|
|
||||||
color: #28c2dd;
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 50rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section_2 {
|
|
||||||
padding: 19.76rpx 16.2rpx 13.54rpx;
|
|
||||||
background: linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, #FFFFFF 100%);
|
|
||||||
border-radius: 16rpx 0rpx 0rpx 16rpx;
|
|
||||||
width: 160rpx;
|
|
||||||
height: 94rpx;
|
|
||||||
|
|
||||||
.group_5 {
|
|
||||||
line-height: 20.46rpx;
|
|
||||||
|
|
||||||
.font_2 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 21.14rpx;
|
|
||||||
color: #fb8517;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_3 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 19.9rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_4 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 20.46rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_7 {
|
|
||||||
width: 20rpx;
|
|
||||||
height: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_8 {
|
|
||||||
margin-right: 11.8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_7 {
|
|
||||||
margin-left: 2.52rpx;
|
|
||||||
margin-top: 3.84rpx;
|
|
||||||
color: #363636;
|
|
||||||
font-size: 20rpx;
|
|
||||||
line-height: 18.62rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-box {
|
|
||||||
padding: 10rpx 16rpx;
|
|
||||||
padding-bottom: 10rpx;
|
|
||||||
padding-bottom: calc(10rpx + constant(safe-area-inset-bottom));
|
|
||||||
padding-bottom: calc(10rpx + env(safe-area-inset-bottom));
|
|
||||||
|
|
||||||
.ml-25 {
|
|
||||||
margin-left: 50rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section_3 {
|
|
||||||
padding: 20rpx 18rpx 0;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
|
|
||||||
.view {
|
|
||||||
margin: 0 14rpx;
|
|
||||||
padding-top: 2.96rpx;
|
|
||||||
|
|
||||||
.font_5 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 21.14rpx;
|
|
||||||
color: #666666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_8 {
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_9 {
|
|
||||||
line-height: 21.76rpx;
|
|
||||||
height: 21.76rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
overflow-x: auto;
|
|
||||||
flex: 1;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
/* 隐藏横向滚动条,但保留滑动效果 */
|
|
||||||
scrollbar-width: none;
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_6 {
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 22rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #4FB26E;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.equal-division {
|
|
||||||
align-self: flex-start;
|
|
||||||
margin-top: 21rpx;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.group_10 {
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
.font_3 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_16 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_8 {
|
|
||||||
font-size: 52rpx;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_17 {
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 22.04rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_9 {
|
|
||||||
width: 234rpx;
|
|
||||||
height: 44rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_18 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 24rpx;
|
|
||||||
text-align: right;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_28 {
|
|
||||||
padding: 16rpx 0;
|
|
||||||
width: 200rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_29 {
|
|
||||||
padding: 18.84rpx 0 3.54rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_26 {
|
|
||||||
padding: 16rpx 0;
|
|
||||||
width: 200rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_11 {
|
|
||||||
|
|
||||||
.pos {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
|
|
||||||
.text_19 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 25.96rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_19 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
color: #666666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_21 {
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 17.54rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_10 {
|
|
||||||
width: 30rpx;
|
|
||||||
height: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pos_2 {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
|
|
||||||
.text_20 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 25.82rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.image_4 {
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_9 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_12 {
|
|
||||||
padding: 38rpx 0 0;
|
|
||||||
|
|
||||||
.section_1 {
|
|
||||||
padding: 28rpx 10.58rpx 22rpx 19.1rpx;
|
|
||||||
background-color: #f9fbfc;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
|
|
||||||
.text_22 {
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 22.22rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-wrapper_8 {
|
|
||||||
background-color: #9db2bd;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
width: 56rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
|
|
||||||
.text_23 {
|
|
||||||
line-height: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_51 {
|
|
||||||
margin-top: 2.92rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_25 {
|
|
||||||
margin-right: 4.38rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_27 {
|
|
||||||
padding: 0 8.98rpx;
|
|
||||||
|
|
||||||
.text_50 {
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_10 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 23.74rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_11 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 21.14rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_4 {
|
|
||||||
font-size: 20rpx;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_12 {
|
|
||||||
font-size: 32rpx;
|
|
||||||
line-height: 29.6rpx;
|
|
||||||
color: #363636;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_13 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 19rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_14 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
color: #545356;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_15 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 25.92rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #f5882c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font_16 {
|
|
||||||
font-size: 26rpx;
|
|
||||||
line-height: 21.14rpx;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #363636;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-btn {
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 30rpx;
|
|
||||||
width: 104rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
border: solid 1rpx #e0e4e3;
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 381 B |
|
Before Width: | Height: | Size: 583 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 949 B |
|
Before Width: | Height: | Size: 982 B |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1023 B |
|
Before Width: | Height: | Size: 839 B |
|
Before Width: | Height: | Size: 714 B |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 333 B |
|
Before Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 468 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 348 B |
|
Before Width: | Height: | Size: 331 B |
|
Before Width: | Height: | Size: 335 B |
|
Before Width: | Height: | Size: 833 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 827 B |
|
Before Width: | Height: | Size: 799 B |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 898 B |
|
Before Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 418 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 967 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 50 KiB |