feat(用户界面): 添加客服功能并优化格口选择界面
- 新增微信客服功能入口及处理逻辑 - 添加不同尺寸格口的SVG图标资源 - 重构格口类型选择为卡片式布局,增加视觉反馈 - 简化取件流程,取消自动清空格口步骤 - 调整页面按钮布局,优化用户体验
This commit is contained in:
parent
8239ed657f
commit
364cba07b9
|
|
@ -216,32 +216,41 @@ async function handleRetrieveFlow() {
|
||||||
password: String(password)
|
password: String(password)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 4. 成功提示并询问是否清空
|
// 4. 成功提示
|
||||||
|
uni.showToast({
|
||||||
|
title: '格口已打开',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 注释掉清空格口部分,打开格口即显示打开成功结束流程
|
||||||
|
/*
|
||||||
|
// 成功提示并询问是否清空
|
||||||
await message.alert({
|
await message.alert({
|
||||||
title: '格口已打开',
|
title: '格口已打开',
|
||||||
msg: '柜子已开,请取物品!如不再使用柜子请点击 “清空” 。',
|
msg: '柜子已开,请取物品!如不再使用柜子请点击 "清空" 。',
|
||||||
confirmButtonText: '清空',
|
confirmButtonText: '清空',
|
||||||
closeOnClickModal: false
|
closeOnClickModal: false
|
||||||
})
|
})
|
||||||
|
|
||||||
// 5. 确认清空弹窗
|
// 确认清空弹窗
|
||||||
await message.confirm({
|
await message.confirm({
|
||||||
title: '确认清空',
|
title: '确认清空',
|
||||||
msg: '清空后密码将不能再次使用,确认清空?',
|
msg: '清空后密码将不能再次使用,确认清空?',
|
||||||
closeOnClickModal: false
|
closeOnClickModal: false
|
||||||
})
|
})
|
||||||
|
|
||||||
// 6. 重置格口状态
|
// 重置格口状态
|
||||||
await resetByPassword({
|
await resetByPassword({
|
||||||
shopId: props.shopId,
|
shopId: props.shopId,
|
||||||
password: String(password)
|
password: String(password)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 7. 重置成功提示
|
// 重置成功提示
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '格口已清空',
|
title: '格口已清空',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
|
*/
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 错误处理
|
// 错误处理
|
||||||
// 用户取消操作(message.prompt/confirm/alert 返回 'cancel' 字符串或包含 cancel 的错误)
|
// 用户取消操作(message.prompt/confirm/alert 返回 'cancel' 字符串或包含 cancel 的错误)
|
||||||
|
|
@ -265,6 +274,42 @@ async function handleRetrieveFlow() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 格口类型图标映射(需验证图标名称可用性)
|
||||||
|
const CELL_TYPE_ICON_MAP = {
|
||||||
|
1: 'box', // 小格
|
||||||
|
2: 'archive', // 中格
|
||||||
|
3: 'package', // 大格
|
||||||
|
4: 'cube' // 超大格
|
||||||
|
} as const
|
||||||
|
|
||||||
|
function getCellImg(type: number): string {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return '/static/svg/small-cell.svg'
|
||||||
|
case 2:
|
||||||
|
return '/static/svg/medium-cell.svg'
|
||||||
|
case 3:
|
||||||
|
return '/static/svg/large-cell.svg'
|
||||||
|
case 4:
|
||||||
|
return '/static/svg/extra-large-cell.svg'
|
||||||
|
default:
|
||||||
|
return '/static/svg/small-cell.svg'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理格口类型选择
|
||||||
|
function handleCellTypeSelect(stat: { type: number; count: number }) {
|
||||||
|
if (stat.count === 0) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '该类型格口暂不可用',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedCellType.value = stat.type
|
||||||
|
}
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.autoLoad !== false) {
|
if (props.autoLoad !== false) {
|
||||||
|
|
@ -310,16 +355,28 @@ onMounted(() => {
|
||||||
|
|
||||||
<!-- 格口类型选择区域 -->
|
<!-- 格口类型选择区域 -->
|
||||||
<view v-else class="cell-type-selection">
|
<view v-else class="cell-type-selection">
|
||||||
<wd-radio-group v-model="selectedCellType" shape="button" size="large" inline>
|
<view class="cell-type-grid">
|
||||||
<wd-radio
|
<view
|
||||||
v-for="stat in cellTypeStats"
|
v-for="stat in cellTypeStats"
|
||||||
:key="stat.type"
|
:key="stat.type"
|
||||||
:value="stat.type"
|
class="cell-type-card"
|
||||||
:disabled="stat.count === 0"
|
:class="{
|
||||||
|
'cell-type-card--selected': selectedCellType === stat.type,
|
||||||
|
'cell-type-card--disabled': stat.count === 0
|
||||||
|
}"
|
||||||
|
@click="handleCellTypeSelect(stat)"
|
||||||
>
|
>
|
||||||
{{ stat.name }} ({{ stat.count }})
|
<view class="cell-type-icon">
|
||||||
</wd-radio>
|
<image :src="getCellImg(stat.type)" class="product-image">
|
||||||
</wd-radio-group>
|
</image>
|
||||||
|
</view>
|
||||||
|
<text class="cell-type-name">{{ stat.name }}</text>
|
||||||
|
<text class="cell-type-count">剩余{{ stat.count }}个可用</text>
|
||||||
|
<!-- <view v-if="selectedCellType === stat.type" class="cell-type-selected-indicator">
|
||||||
|
<wd-icon name="check" size="16px" color="#fff" />
|
||||||
|
</view> -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 操作按钮区域 -->
|
<!-- 操作按钮区域 -->
|
||||||
|
|
@ -384,9 +441,84 @@ onMounted(() => {
|
||||||
.cell-type-selection {
|
.cell-type-selection {
|
||||||
margin-bottom: 48rpx;
|
margin-bottom: 48rpx;
|
||||||
|
|
||||||
.wd-radio {
|
.cell-type-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 16rpx;
|
||||||
|
|
||||||
|
.cell-type-card {
|
||||||
|
position: relative;
|
||||||
|
padding: 32rpx 24rpx;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:active:not(.cell-type-card--disabled) {
|
||||||
|
transform: translateY(2px);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
border-color: #2979ff;
|
||||||
|
background: rgba(41, 121, 255, 0.04);
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(41, 121, 255, 0.15);
|
||||||
|
|
||||||
|
.cell-type-name {
|
||||||
|
color: #2979ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-type-count {
|
||||||
|
color: #2979ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-color: #f0f0f0;
|
||||||
|
opacity: 0.6;
|
||||||
|
|
||||||
|
.cell-type-name,
|
||||||
|
.cell-type-count {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-type-icon {
|
||||||
margin-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cell-type-name {
|
||||||
|
display: block;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-type-count {
|
||||||
|
display: block;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-type-selected-indicator {
|
||||||
|
position: absolute;
|
||||||
|
top: -8rpx;
|
||||||
|
right: -8rpx;
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background: #2979ff;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 2rpx 8rpx rgba(41, 121, 255, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-buttons {
|
.action-buttons {
|
||||||
|
|
@ -424,5 +556,11 @@ onMounted(() => {
|
||||||
/* 保留空白,自动换行 */
|
/* 保留空白,自动换行 */
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.product-image {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -9,7 +9,7 @@ import { generateDynamicCode, getWxUserByOpenid } from '@/api/users'
|
||||||
import { DynamicCodeResponse } from '@/api/users/types'
|
import { DynamicCodeResponse } from '@/api/users/types'
|
||||||
import { bindWxMpUserByOpenid } from '@/api/ab98'
|
import { bindWxMpUserByOpenid } from '@/api/ab98'
|
||||||
import { BindWxMpUserByOpenidCommand } from '@/api/ab98/types'
|
import { BindWxMpUserByOpenidCommand } from '@/api/ab98/types'
|
||||||
import { useToast } from 'wot-design-uni'
|
import { useToast, useMessage } from 'wot-design-uni'
|
||||||
|
|
||||||
definePage({
|
definePage({
|
||||||
style: {
|
style: {
|
||||||
|
|
@ -43,6 +43,7 @@ const showProfileSetupButton = computed(() => {
|
||||||
const dynamicCodeActionSheet = ref<boolean>(false)
|
const dynamicCodeActionSheet = ref<boolean>(false)
|
||||||
const dynamicCodeData = ref<DynamicCodeResponse | null>(null)
|
const dynamicCodeData = ref<DynamicCodeResponse | null>(null)
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
// 汇邦云登录相关
|
// 汇邦云登录相关
|
||||||
const hbLoginPopupVisible = ref<boolean>(false)
|
const hbLoginPopupVisible = ref<boolean>(false)
|
||||||
|
|
@ -111,6 +112,32 @@ const navigateToPage = (pagePath: string, options: { type?: 'navigateTo' | 'swit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const openWxService = async () => {
|
||||||
|
try {
|
||||||
|
// 确认是否转到客服
|
||||||
|
await message.confirm({
|
||||||
|
title: '客服咨询',
|
||||||
|
msg: '确认离开小程序,前往客服中心?',
|
||||||
|
closeOnClickModal: false
|
||||||
|
})
|
||||||
|
|
||||||
|
wx.openCustomerServiceChat({
|
||||||
|
extInfo: {
|
||||||
|
url: 'https://work.weixin.qq.com/kfid/kfce354fbeb3c58be22',
|
||||||
|
},
|
||||||
|
corpId: 'ww25c80308cbccc46a',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// 用户取消操作
|
||||||
|
if (error === 'cancel' || (error as any)?.message?.includes?.('cancel')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error('打开客服失败:', error)
|
||||||
|
toast.show('打开客服失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
wxStore.refreshBalance();
|
wxStore.refreshBalance();
|
||||||
});
|
});
|
||||||
|
|
@ -246,32 +273,35 @@ const handleHbLoginSubmit = async () => {
|
||||||
<wd-icon name="star" size="20px" color="#fff"></wd-icon>
|
<wd-icon name="star" size="20px" color="#fff"></wd-icon>
|
||||||
<text>我的柜子</text>
|
<text>我的柜子</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="button-item" @click="openWxService()">
|
||||||
|
<wd-icon name="user-talk" size="20px" color="#fff"></wd-icon>
|
||||||
|
<text>系统客服</text>
|
||||||
|
</view>
|
||||||
<view v-if="!wxUserDTO?.ab98UserId" class="button-item" @click="handleGenerateDynamicCode">
|
<view v-if="!wxUserDTO?.ab98UserId" class="button-item" @click="handleGenerateDynamicCode">
|
||||||
<wd-icon name="qrcode" size="20px" color="#fff"></wd-icon>
|
<wd-icon name="qrcode" size="20px" color="#fff"></wd-icon>
|
||||||
<text>动态码</text>
|
<text>动态码</text>
|
||||||
</view>
|
</view>
|
||||||
<view v-else class="button-placeholder"></view>
|
<view v-else class="button-placeholder"></view>
|
||||||
<view v-if="!wxUserDTO?.ab98UserId" class="button-item" @click="hbLoginPopupVisible = true">
|
|
||||||
<wd-icon name="login" size="20px" color="#fff"></wd-icon>
|
|
||||||
<text>绑定汇邦云</text>
|
|
||||||
</view>
|
|
||||||
<view v-else class="button-placeholder"></view>
|
|
||||||
<!-- <view v-if="wxStore.isCabinetAdmin" class="button-item" @click="navigateToPage('/pages/cabinet/index')">
|
<!-- <view v-if="wxStore.isCabinetAdmin" class="button-item" @click="navigateToPage('/pages/cabinet/index')">
|
||||||
<wd-icon name="tools" size="20px" color="#fff"></wd-icon>
|
<wd-icon name="tools" size="20px" color="#fff"></wd-icon>
|
||||||
<text>柜机管理</text>
|
<text>柜机管理</text>
|
||||||
</view> -->
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="button-row">
|
<view class="button-row">
|
||||||
<view v-if="wxStore.isCabinetAdmin" class="button-item" @click="navigateToPage('/pages/approval/list/index')">
|
<view v-if="!wxUserDTO?.ab98UserId" class="button-item" @click="hbLoginPopupVisible = true">
|
||||||
|
<wd-icon name="login" size="20px" color="#fff"></wd-icon>
|
||||||
|
<text>绑定汇邦云</text>
|
||||||
|
</view>
|
||||||
|
<!-- <view v-if="wxStore.isCabinetAdmin" class="button-item" @click="navigateToPage('/pages/approval/list/index')">
|
||||||
<wd-icon name="secured" size="20px" color="#fff"></wd-icon>
|
<wd-icon name="secured" size="20px" color="#fff"></wd-icon>
|
||||||
<text>审批中心</text>
|
<text>审批中心</text>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="wxStore.isCabinetAdmin" class="button-item" @click="navigateToPage('/pages/approvalAsset/list/index')">
|
<view v-if="wxStore.isCabinetAdmin" class="button-item" @click="navigateToPage('/pages/approvalAsset/list/index')">
|
||||||
<wd-icon name="edit-1" size="20px" color="#fff"></wd-icon>
|
<wd-icon name="edit-1" size="20px" color="#fff"></wd-icon>
|
||||||
<text>耗材核销</text>
|
<text>耗材核销</text>
|
||||||
</view>
|
|
||||||
<view class="button-placeholder"></view>
|
|
||||||
</view> -->
|
</view> -->
|
||||||
|
<view class="button-placeholder"></view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 动态码弹窗 -->
|
<!-- 动态码弹窗 -->
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M200 24H56a12 12 0 0 0-12 12v184a12 12 0 0 0 12 12h144a12 12 0 0 0 12-12V36a12 12 0 0 0-12-12m4 196a4 4 0 0 1-4 4H56a4 4 0 0 1-4-4V36a4 4 0 0 1 4-4h144a4 4 0 0 1 4 4v184Zm-64-92a4 4 0 0 1-4 4h-16a4 4 0 0 1 0-8h16a4 4 0 0 1 4 4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 367 B |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M200 48H56a12 12 0 0 0-12 12v136a12 12 0 0 0 12 12h144a12 12 0 0 0 12-12V60a12 12 0 0 0-12-12m4 148a4 4 0 0 1-4 4H56a4 4 0 0 1-4-4V60a4 4 0 0 1 4-4h144a4 4 0 0 1 4 4v136Zm-64-68a4 4 0 0 1-4 4h-16a4 4 0 0 1 0-8h16a4 4 0 0 1 4 4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 367 B |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M200 72H56a12 12 0 0 0-12 12v88a12 12 0 0 0 12 12h144a12 12 0 0 0 12-12V84a12 12 0 0 0-12-12m4 100a4 4 0 0 1-4 4H56a4 4 0 0 1-4-4V84a4 4 0 0 1 4-4h144a4 4 0 0 1 4 4v88Zm-64-44a4 4 0 0 1-4 4h-16a4 4 0 0 1 0-8h16a4 4 0 0 1 4 4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 365 B |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M200 96H56a12 12 0 0 0-12 12v40a12 12 0 0 0 12 12h144a12 12 0 0 0 12-12v-40a12 12 0 0 0-12-12m4 52a4 4 0 0 1-4 4H56a4 4 0 0 1-4-4v-40a4 4 0 0 1 4-4h144a4 4 0 0 1 4 4v40Zm-64-20a4 4 0 0 1-4 4h-16a4 4 0 0 1 0-8h16a4 4 0 0 1 4 4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 366 B |
Loading…
Reference in New Issue