align(撞款): 店铺数据重复按登录角色区分范围——超管看全分组、管理员只看本组
撞款控制台角色收口:前端读会话角色(isSuperAdmin),非超管隐藏筛选「分组」下拉、 「分组撞款」分段与「分组说明」按钮(分组专属交互仅超管需要);普通管理员数据已由 后端 resolveVisibleShopKeys 裁剪到所管分组店铺(超管 null=全量)。前端 1554 测试全绿 + build 通过。
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
* 分组归属来自「店铺管理」真实店铺分组,本页只读展示,仅用于分组撞款范围切换。
|
||||
*/
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { useAdminSessionStore } from '@/stores/admin-session'
|
||||
import type { DuplicateItem, DuplicateOccurrence, DuplicateMetrics, DuplicateShop } from './duplicate-model.ts'
|
||||
import { fetchDuplicateConsole, fetchDuplicateLedger, requestDuplicateExportBlob, type LedgerSortKey } from './duplicate-console-api.ts'
|
||||
import { aggregateDrawerRows, drawerSummaryOf, dupWithinGroup, indexShopGroups, type DrawerAggRow, type DrawerSummary, type ShopGroups } from './duplicate-console-logic.ts'
|
||||
@@ -21,6 +22,10 @@ const reanalyzing = ref(false)
|
||||
|
||||
const filter = reactive({ asin: '', shop: '', group: '', country: '', dateFrom: '', dateTo: '' })
|
||||
|
||||
/** 角色范围:超管可看全部分组店铺并可跨分组筛选;普通管理员数据已由后端裁剪到自己分组,无需分组筛选。 */
|
||||
const session = useAdminSessionStore()
|
||||
const isSuper = computed(() => session.isSuperAdmin)
|
||||
|
||||
const activeTab = ref<Tab>('dup')
|
||||
const scope = ref<Scope>('global')
|
||||
const selectedGroup = ref('')
|
||||
@@ -393,7 +398,7 @@ onMounted(() => {
|
||||
<option v-for="shop in orderedShops" :key="shop.shopName" :value="shop.shopName">{{ shop.shopName }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="f-group">
|
||||
<div v-if="isSuper" class="f-group">
|
||||
<label>分组</label>
|
||||
<select v-model="filter.group">
|
||||
<option value="">全部分组</option>
|
||||
@@ -466,7 +471,7 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="actions">
|
||||
<span v-if="overview" class="updated">数据更新时间 {{ overview.scannedAt || '—' }}</span>
|
||||
<button class="btn btn-ghost btn-sm" type="button" @click="groupInfoVisible = true">
|
||||
<button v-if="isSuper" class="btn btn-ghost btn-sm" type="button" @click="groupInfoVisible = true">
|
||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><path d="M23 21v-2a4 4 0 0 0-3-3.87" /><path d="M16 3.13a4 4 0 0 1 0 7.75" /></svg>
|
||||
分组说明
|
||||
</button>
|
||||
@@ -483,7 +488,7 @@ onMounted(() => {
|
||||
|
||||
<!-- ============ 撞款监控 ============ -->
|
||||
<template v-if="activeTab === 'dup'">
|
||||
<div class="scope-bar">
|
||||
<div v-if="isSuper" class="scope-bar">
|
||||
<div class="seg">
|
||||
<button class="seg-btn" :class="{ active: scope === 'global' }" type="button" @click="switchScope('global')">全店撞款</button>
|
||||
<button class="seg-btn" :class="{ active: scope === 'group' }" type="button" @click="switchScope('group')">分组撞款</button>
|
||||
|
||||
@@ -56,3 +56,22 @@ test('align_dup_console_matrix_sticky', () => {
|
||||
assert.match(page, /table\.matrix th\s*\{[^}]*position:\s*sticky/, '矩阵表头吸顶')
|
||||
assert.match(page, /\.matrix-wrap\s*\{[^}]*max-height/, '矩阵容器限高滚动')
|
||||
})
|
||||
|
||||
test('align_dup_console_role_scope_group_filter_only_super', () => {
|
||||
// 角色范围:分组筛选下拉仅超管需要;管理员数据由后端裁到本组。
|
||||
const page = readSource('src/pages/tasks/DuplicateCheckPage.vue')
|
||||
assert.match(page, /useAdminSessionStore/, '页面读取登录会话取角色')
|
||||
assert.match(page, /const isSuper = computed\(\(\) => session\.isSuperAdmin\)/, 'isSuper 由会话角色推导')
|
||||
assert.match(page, /<div v-if="isSuper" class="f-group">\s*<label>分组<\/label>/s, '分组筛选仅超管可见')
|
||||
assert.match(page, /group: filter\.group\.trim\(\)/, '分组筛选仍参与查询参数')
|
||||
})
|
||||
|
||||
test('align_dup_console_role_scope_group_controls_only_super', () => {
|
||||
// 分组撞款/分组说明为超管专属交互;后端超管全量、普通管理员所管分组店铺。
|
||||
const page = readSource('src/pages/tasks/DuplicateCheckPage.vue')
|
||||
assert.match(page, /<div v-if="isSuper" class="scope-bar">/, '分组撞款分段仅超管可见')
|
||||
assert.match(page, /v-if="isSuper" class="btn btn-ghost btn-sm" type="button" @click="groupInfoVisible = true"/, '分组说明按钮仅超管可见')
|
||||
const service = readSource('../backend-java/src/main/java/com/nanri/aiimage/modules/shopduplicatecheck/service/ShopDataDuplicateCheckQueryService.java')
|
||||
assert.match(service, /if \(superAdmin\) \{\s*return null;/, '超管可见范围=全量(null)')
|
||||
assert.match(service, /selectManagedShopNames\(operatorId\)/, '普通管理员可见范围=所管分组店铺')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user