feat(储物柜): 改进格口控制弹窗的UI和交互

- 增加密码显示/隐藏切换功能
- 优化信息卡片布局和样式
- 调整弹窗高度为75%
- 添加状态标签样式
- 改进按钮样式和布局
- 优化备注输入区域设计
This commit is contained in:
dzq 2026-01-05 17:49:25 +08:00
parent 3d99b20754
commit 3fd842fc79
4 changed files with 163 additions and 37 deletions

View File

@ -12,7 +12,7 @@
"preview": "vite preview",
"prepare": "husky",
"test": "vitest",
"zip": "7z a -tzip dist/shop-web-%date:~0,4%%date:~5,2%%date:~8,2%-%time:~0,2%%time:~3,2%%time:~6,2%.zip .\\dist\\* -xr!*.zip"
"zip": "powershell -Command \"$timestamp = (Get-Date).ToString('yyyyMMdd-HHmmss'); 7z a -tzip dist/shop-web-$timestamp.zip ./dist/* -xr'!*.zip'\""
},
"dependencies": {
"@vant/touch-emulator": "1.4.0",

View File

@ -44,7 +44,7 @@ onMounted(async () => {
//
// isAdmin = '1';
// cid = '4';
// code = 'zeK9RSFXnM-Ruo-YIp5pBUmRpBuTD-I1o2nNPPkUy14';
// code = 'admin-0MW6LmhsCm3MXM';
if (cid && Number(cid)) {
try {

View File

@ -450,14 +450,6 @@ function handleRetrieveFlow() {
transitionTo({ type: 'retrieve-input' })
}
//
const CELL_TYPE_ICON_MAP = {
1: 'box', //
2: 'archive', //
3: 'package', //
4: 'cube' //
} as const
function getCellImg(type: number): string {
// public/images/cabinet/
const basePath = publicPath + 'images/cabinet/'

View File

@ -199,42 +199,64 @@
</VanPopup>
<!-- 格口控制弹窗 -->
<VanPopup v-model:show="showLockerPopup" position="bottom" :style="{ height: '45%' }" round>
<VanPopup v-model:show="showLockerPopup" position="bottom" :style="{ height: '75%' }" round>
<div class="locker-popup-content" v-if="selectedLocker">
<div class="popup-header">
<span class="popup-title">格口 {{ selectedLocker.cellNo }}</span>
<van-icon name="cross" @click="showLockerPopup = false" />
<van-icon name="cross" class="close-btn" @click="showLockerPopup = false" />
</div>
<div class="locker-info">
<div class="info-row">
<span>状态: {{ selectedLocker.usageStatus === 1 ? '空闲' : '占用' }}</span>
<span v-if="selectedLocker.goodsName">商品: {{ selectedLocker.goodsName }}</span>
<!-- 信息卡片 -->
<div class="locker-info-card">
<div class="info-item">
<span class="info-label">状态</span>
<span class="info-value status-tag"
:class="selectedLocker.usageStatus === 1 ? 'status-free' : 'status-occupied'">
{{ selectedLocker.usageStatus === 1 ? '空闲' : '占用' }}
</span>
</div>
<div class="info-row" v-if="selectedShop?.mode !== 5">
<span>价格: ¥{{ (selectedLocker.price || 0).toFixed(2) }}</span>
<div class="info-item" v-if="selectedLocker.goodsName">
<span class="info-label">商品</span>
<span class="info-value">{{ selectedLocker.goodsName }}</span>
</div>
<div class="info-item" v-if="selectedShop?.mode !== 5">
<span class="info-label">价格</span>
<span class="info-value price">¥{{ (selectedLocker.price || 0).toFixed(2) }}</span>
</div>
<div class="info-item" v-if="selectedShop?.mode === 5 && selectedLocker?.password">
<span class="info-label">密码</span>
<span class="info-value password-value">
<span class="password-text">{{ showPassword ? selectedLocker.password : '***' }}</span>
<van-icon :name="showPassword ? 'eye' : 'eye-o'" size="18"
class="password-toggle" @click="showPassword = !showPassword" />
</span>
</div>
</div>
<van-field v-model="editingRemark" label="备注" placeholder="请输入备注" rows="2" type="textarea"
class="remark-field" />
<!-- 备注输入 -->
<div class="remark-section">
<div class="section-title">备注</div>
<van-field v-model="editingRemark" placeholder="请输入备注信息" rows="2" type="textarea"
class="remark-input" />
</div>
<!-- 按钮区域 -->
<div class="popup-actions">
<van-button type="primary" :loading="openingLockerId === selectedLocker.lockerId"
@click="handleOpenLocker(selectedLocker)" style="flex: 1;">
立即开启
开启格口
</van-button>
<van-button v-if="selectedShop?.mode === 5 && selectedLocker.password" plain
<van-button v-if="selectedShop?.mode === 5 && selectedLocker.password" plain type="danger"
@click="handleClearPassword(selectedLocker)" style="flex: 1;">
清除密码
</van-button>
<van-button v-else-if="selectedShop?.mode !== 5" plain
<van-button v-else-if="selectedShop?.mode !== 5" plain type="warning"
@click="handleBindFromLocker(selectedLocker)" style="flex: 1;">
绑定商品
</van-button>
</div>
<van-button @click="handleSaveRemark" :loading="isSavingRemark" style="margin-top: 8px;">
<van-button @click="handleSaveRemark" :loading="isSavingRemark" class="save-btn">
保存备注
</van-button>
</div>
@ -282,6 +304,7 @@ const showLockerPopup = ref(false)
const selectedLocker = ref<LockerItem | null>(null)
const editingRemark = ref('')
const isSavingRemark = ref(false)
const showPassword = ref(false)
//
const activeModeIndex = ref(0); //
const modeList = ref<number[]>([]);
@ -1028,8 +1051,9 @@ onBeforeUnmount(() => {
padding: 16px;
display: flex;
flex-direction: column;
gap: 12px;
gap: 16px;
height: 100%;
background: #f5f5f5;
}
.popup-header {
@ -1041,34 +1065,144 @@ onBeforeUnmount(() => {
.popup-title {
font-size: 18px;
font-weight: bold;
font-weight: 600;
color: #333;
}
.van-icon {
font-size: 20px;
.close-btn {
font-size: 22px;
color: #999;
padding: 4px;
padding: 4px 8px;
border-radius: 4px;
transition: background-color 0.2s;
&:hover {
background-color: #f0f0f0;
}
}
}
.locker-info {
.info-row {
.locker-info-card {
background: white;
border-radius: 12px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
.info-item {
display: flex;
gap: 16px;
margin-bottom: 8px;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
}
.info-label {
font-size: 14px;
color: #666;
color: #999;
}
.info-value {
font-size: 14px;
color: #333;
font-weight: 500;
&.price {
color: #e95d5d;
font-weight: 600;
font-size: 16px;
}
&.password-value {
display: flex;
align-items: center;
gap: 8px;
.password-text {
font-family: monospace;
font-size: 16px;
letter-spacing: 2px;
}
.password-toggle {
color: #999;
cursor: pointer;
padding: 4px;
&:active {
color: var(--van-primary-color);
}
}
}
}
.status-tag {
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
&.status-free {
background: #e8f5e9;
color: #2e7d32;
}
&.status-occupied {
background: #fff3e0;
color: #ef6c00;
}
}
}
.remark-field {
margin-top: 8px;
.remark-section {
background: white;
border-radius: 12px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
.section-title {
font-size: 14px;
font-weight: 500;
color: #333;
margin-bottom: 12px;
}
.remark-input {
background: #f7f8fa;
border-radius: 8px;
padding: 12px;
:deep(.van-field__control) {
background: transparent;
}
}
}
.popup-actions {
display: flex;
gap: 12px;
margin-top: 4px;
.van-button {
flex: 1;
height: 44px;
border-radius: 22px;
font-size: 15px;
}
}
.save-btn {
width: 100%;
height: 52px;
border-radius: 26px;
background: #4e80ee;
border: none;
color: white;
font-size: 15px;
&:disabled {
background: #a0c3ff;
}
}
</style>