From 5e4a2a9d11202cb70a96da900376c606c275ab4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Sat, 5 Sep 2026 22:04:20 +0800 Subject: [PATCH] =?UTF-8?q?task-263(admin.html=E8=A7=82=E6=84=9F=E5=AF=B9?= =?UTF-8?q?=E9=BD=90):=20=E5=BA=97=E9=93=BA=E7=AE=A1=E7=90=86=E9=A1=B5?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=EF=BC=88=E5=AF=86=E7=A0=81=E7=9C=BC=E7=9D=9B?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E8=AF=BB=E5=8F=96/=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E5=88=97/=E6=95=B4=E5=8F=A5=E5=BF=85?= =?UTF-8?q?=E5=A1=AB=E6=A0=A1=E9=AA=8C/=E7=BC=96=E8=BE=91=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E5=BF=85=E5=A1=AB=E8=AF=AD=E4=B9=89/=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=96=87=E6=A1=88=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/shop/ShopManagePage.vue | 60 +++++++++++++++++-- admin-frontend-vue/tests/task-263.test.ts | 59 ++++++++++++++++++ 2 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 admin-frontend-vue/tests/task-263.test.ts diff --git a/admin-frontend-vue/src/pages/shop/ShopManagePage.vue b/admin-frontend-vue/src/pages/shop/ShopManagePage.vue index e9756c5f..47f36a87 100644 --- a/admin-frontend-vue/src/pages/shop/ShopManagePage.vue +++ b/admin-frontend-vue/src/pages/shop/ShopManagePage.vue @@ -33,8 +33,35 @@ const form = reactive(emptyShopManageForm()) const credentialVisible = ref(false) const credential = ref(null) +/** 密码列“眼睛”实时读取:仅展示已读明文,其余保持掩码;读取中占位。 */ +const revealedPasswordCache = ref>({}) +const revealedRowId = ref(null) + const groupOptions = computed(() => groups.value) +function shownPassword(row: ShopSummary): string { + if (revealedRowId.value !== row.id) return row.passwordMasked || '******' + const plain = revealedPasswordCache.value[row.id] + return plain != null && plain !== '' ? plain : '读取中...' +} + +async function togglePassword(row: ShopSummary) { + if (revealedRowId.value === row.id) { + revealedRowId.value = null + return + } + revealedRowId.value = row.id + if (revealedPasswordCache.value[row.id] == null) { + try { + const cred = await fetchShopCredential(row.id, row.shopName) + revealedPasswordCache.value[row.id] = cred.password + } catch (error) { + revealedRowId.value = null + ElMessage.error(error instanceof Error ? error.message : '读取密码失败') + } + } +} + async function loadGroups() { try { groups.value = await fetchShopManageGroups() @@ -94,6 +121,16 @@ function openEdit(row: ShopSummary) { } async function submit() { + if ( + form.groupId == null || + !(form.shopName || '').trim() || + !(form.mallName || '').trim() || + !(form.account || '').trim() || + !(form.password || '').trim() + ) { + ElMessage.warning('请完整填写分组、店铺名、店铺商城名、账号、密码') + return + } saving.value = true try { const createdById = session.user?.id ?? 0 @@ -124,7 +161,7 @@ async function showCredential(row: ShopSummary) { async function remove(row: ShopSummary) { try { - await ElMessageBox.confirm(`确认删除店铺「${row.shopName}」?`, '删除店铺', { type: 'warning' }) + await ElMessageBox.confirm(`确定删除店铺“${row.shopName}”吗?`, '删除确认', { type: 'warning' }) } catch { return } @@ -188,8 +225,19 @@ onMounted(() => { - - + + @@ -197,6 +245,9 @@ onMounted(() => { + + +