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

# Conflicts:
#	main.js
This commit is contained in:
小李 2026-03-19 15:20:07 +08:00
commit 7b1d55dfa3
7 changed files with 209 additions and 27 deletions

View File

@ -43,7 +43,7 @@
</view> </view>
</slot> </slot>
</view> </view>
<view class="center-box flex-1"> <view class="center-box flex-1" @click="handleBoxClick">
<scroll-view :scroll-top="scrollTop" scroll-y="true" scroll-with-animation :show-scrollbar="false" <scroll-view :scroll-top="scrollTop" scroll-y="true" scroll-with-animation :show-scrollbar="false"
class="scroll-view h100"> class="scroll-view h100">
<slot></slot> <slot></slot>
@ -142,12 +142,13 @@ const data = reactive({
content: "", content: "",
simIndex: 1, simIndex: 1,
scrollTop: 0, scrollTop: 0,
keyboardHeight: 0 keyboardHeight: 0,
lastClickTime: 0
}) })
let { isSend, content, simIndex, scrollTop } = toRefs(data) let { isSend, content, simIndex, scrollTop, lastClickTime } = toRefs(data)
const emit = defineEmits(['send']) const emit = defineEmits(['send', 'dblclick-left', 'dblclick-right'])
onMounted(() => { onMounted(() => {
// DOM // DOM
@ -220,6 +221,38 @@ const sendMessage = () => {
}, 100); }, 100);
} }
/**
* 处理 center-box 点击事件检测双击并区分左右
*/
const handleBoxClick = (e) => {
const now = Date.now();
const clickInterval = now - data.lastClickTime;
// 300ms
if (clickInterval > 0 && clickInterval < 300) {
// X
const clientX = e.detail.x || (e.touches && e.touches[0] ? e.touches[0].clientX : 0);
//
const systemInfo = uni.getSystemInfoSync();
const halfWidth = systemInfo.screenWidth / 2;
if (clientX < halfWidth) {
console.log('双击左侧');
emit('dblclick-left');
} else {
console.log('双击右侧');
emit('dblclick-right');
}
//
data.lastClickTime = 0;
} else {
data.lastClickTime = now;
}
}
// //
const showInfo = computed(() => { const showInfo = computed(() => {
let placeholder let placeholder

View File

@ -18,7 +18,8 @@
</view> </view>
<view style="flex: 1; overflow: hidden;"> <view style="flex: 1; overflow: hidden;">
<view class="time m-t-44" v-if="shouldShowTime(index)"> <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 == 'iphone' && index == 0">信息 · 短信</view>
<view class="top-text" v-if="phone == 'huawei' && 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-if="phone == 'huawei'">{{ formatHuaweiTopTime(message.time) }}</text>
@ -345,8 +346,8 @@ const formatMessageContent = (content, isMe) => {
* @param index * @param index
* @param message * @param message
*/ */
const onMessageLongPress = (index, message) => { const onMessageLongPress = (index, message, type = 'message') => {
emit('onLongPress', index, message) emit('onLongPress', index, message, type)
} }
// ===================== ===================== // ===================== =====================

View File

@ -111,19 +111,9 @@ import {
util util
} from '@/utils/common.js'; } from '@/utils/common.js';
const emit = defineEmits(['add']) const emit = defineEmits(['add', 'setSim', 'setNoticeCount'])
const buttonGroup = [{
name: "添加短信",
click: () => {
emit('add')
}
}, {
name: "设置卡1卡2运营商",
click: () => {
emit('setSim')
}
}]
const props = defineProps({ const props = defineProps({
// //
@ -138,6 +128,31 @@ const props = defineProps({
} }
}) })
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({ const data = reactive({
navBar: { navBar: {
@ -538,15 +553,17 @@ page {
padding: 0 10rpx; padding: 0 10rpx;
.icon { .icon {
width: 32rpx; width: 40rpx;
height: 32rpx; height: 40rpx;
flex-shrink: 0;
} }
.input { .input {
flex: 1;
margin: 0 20rpx; margin: 0 20rpx;
::v-deep .input-placeholder { ::v-deep .input-placeholder {
color: #646464; color: #9A9A9A;
font-size: 32rpx; font-size: 32rpx;
} }
} }

View File

@ -8,7 +8,7 @@
</view> </view>
<view :class="`${data.phone}-style`"> <view :class="`${data.phone}-style`">
<ChatLayout :phone="data.phone" :chatInfo="data.data" :sortMode="isSortMode" @send="handleSend" <ChatLayout :phone="data.phone" :chatInfo="data.data" :sortMode="isSortMode" @send="handleSend"
:number="data.number"> :number="data.number" @dblclick-left="onDblclickLeft" @dblclick-right="onDblclickRight">
<!-- 弹出操作层及遮罩 --> <!-- 弹出操作层及遮罩 -->
<view v-if="showActionPopup" class="action-mask" @tap="closeActionPopup"> <view v-if="showActionPopup" class="action-mask" @tap="closeActionPopup">
<view class="action-popup" :style="{ top: popupTop + 'px', left: popupLeft + 'px' }"> <view class="action-popup" :style="{ top: popupTop + 'px', left: popupLeft + 'px' }">
@ -194,10 +194,13 @@ const onEditorReady = () => {
}).exec() }).exec()
} }
let longpressType = ref('message')
// //
const onMessageLongPress = (index, message) => { const onMessageLongPress = (index, message, type) => {
selectedMessage.value = message; selectedMessage.value = message;
uni.createSelectorQuery().select('#msg-' + index).boundingClientRect(rect => { longpressType.value = type
const selector = type === 'time' ? '#time-' + index : '#msg-' + index;
uni.createSelectorQuery().select(selector).boundingClientRect(rect => {
if (rect) { if (rect) {
// (bottom + ) // (bottom + )
popupTop.value = rect.bottom + 10; popupTop.value = rect.bottom + 10;
@ -443,6 +446,28 @@ const handleSend = (params) => {
messageList.value.push(params) messageList.value.push(params)
saveChatList() saveChatList()
} }
/**
* 双击左侧
*/
const onDblclickLeft = () => {
isMe.value = false
uni.showToast({
title: "现在是对方发言",
icon: "none"
})
}
/**
* 双击右侧
*/
const onDblclickRight = () => {
isMe.value = true
uni.showToast({
title: "现在是自己发言",
icon: "none"
})
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -7,7 +7,17 @@
</liu-drag-button> </liu-drag-button>
</view> </view>
<view> <view>
<MessageNavBar :phone="data.phone" :isScroll="data.isScroll" @add="openAddPopup" @setSim="setSim"> <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" <MessageList :phone="data.phone" :list="defaultList" @item-click="itemClick" @delete-item="deleteItem"
@edit-item="editItem"> @edit-item="editItem">
</MessageList> </MessageList>
@ -94,6 +104,23 @@
</view> </view>
</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> </view>
</template> </template>
@ -123,7 +150,8 @@ const data = reactive({
bgColor: '#FFFFFF', bgColor: '#FFFFFF',
}, },
phone: 'iphone', phone: 'iphone',
isScroll: false isScroll: false,
noticeCount: 256
}) })
const shape = [{ const shape = [{
@ -136,6 +164,7 @@ const shape = [{
const STORAGE_KEY = 'message_list' const STORAGE_KEY = 'message_list'
const SIM_STORAGE_KEY = 'sim_info' const SIM_STORAGE_KEY = 'sim_info'
const NOTICE_COUNT_KEY = 'huawei_notice_count'
onLoad((options) => { onLoad((options) => {
if (options.phone) { if (options.phone) {
@ -161,6 +190,11 @@ onShow(() => {
if (cached) { if (cached) {
defaultList.value = JSON.parse(cached) defaultList.value = JSON.parse(cached)
} }
//
const cachedNotice = uni.getStorageSync(NOTICE_COUNT_KEY)
if (cachedNotice !== '') {
data.noticeCount = Number(cachedNotice)
}
} catch (e) { } } catch (e) { }
}) })
@ -425,6 +459,31 @@ const confirmSim = () => {
closeSimPopup() 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> </script>
<style> <style>
@ -613,4 +672,51 @@ page {
color: #333333; color: #333333;
text-align: center; 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> </style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B