fix(样办反馈): ①生成记录查询按钮与输入框对齐(修复登录页非scoped .form-group{margin-bottom:20px}全局泄漏,登录页样式收窄scoped+页面内显式重置) ②去重汇总移除数据权限分组摘要块(模型纯函数保留) ③分组筛选下拉显示真实分组名(解析器兼容Java groupName字段)

This commit is contained in:
2026-09-06 22:37:27 +08:00
parent c200fa4f32
commit 66082af52a
6 changed files with 25 additions and 81 deletions
@@ -4,7 +4,6 @@ import { formatDateTime } from '@/utils/datetime'
* script 逻辑沿用现有 Vue 实现(查询/编辑/删除/导入轮询/导出秒表)。 */
import { computed, onMounted, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { useAdminSessionStore } from '@/stores/admin-session'
import {
fetchDedupeTotalList,
updateDedupeTotal,
@@ -12,7 +11,7 @@ import {
fetchDedupeTotalGroups,
type DedupeGroupOption,
} from './dedupe-total-api.ts'
import { dedupeGroupSummaryOf, type DedupeTotalItem } from './dedupe-total-model.ts'
import type { DedupeTotalItem } from './dedupe-total-model.ts'
import { ASIN_COUNTRY_CODES, asinCountryLabel } from './asin-country.ts'
import { createDedupeTotalFilterState, toDedupeListParams } from './dedupe-total-filter.ts'
import {
@@ -25,7 +24,6 @@ import { importOutcomeText, importTaskFinished, isAllowedImportFile } from './de
import type { DedupeImportProgress } from './dedupe-import-model.ts'
import { toExportUrl } from './dedupe-total-export.ts'
const session = useAdminSessionStore()
const loading = ref(false)
const rows = ref<DedupeTotalItem[]>([])
const total = ref(0)
@@ -35,10 +33,6 @@ const filter = reactive(createDedupeTotalFilterState())
const groups = ref<DedupeGroupOption[]>([])
const jumpPage = ref('')
/** 页顶数据权限分组汇总(对齐 admin.js renderDedupeGroupSummary)。 */
const groupSummary = computed(() =>
dedupeGroupSummaryOf(groups.value, session.user?.id ?? null, session.user?.role || ''),
)
const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize)))
const editVisible = ref(false)
@@ -287,26 +281,6 @@ onMounted(() => {
<template>
<div class="dedupe-view">
<section class="form-box">
<div class="dedupe-group-access">
<div class="dedupe-group-access-main">
<span class="dedupe-group-access-title">数据权限分组</span>
<div class="dedupe-group-summary">
<template v-if="groupSummary.kind === 'all'">
<span class="dedupe-group-summary-chip">全部分组 · {{ groupSummary.count }} </span>
</template>
<span v-else-if="groupSummary.kind === 'none'" class="no-group">未加入分组</span>
<template v-else>
<span v-for="chip in groupSummary.chips" :key="chip.name" class="dedupe-group-summary-chip" :title="chip.name">
{{ chip.name }} · {{ chip.relation }}
</span>
<span v-if="groupSummary.extra > 0" class="extra-groups"> {{ groupSummary.extra }} </span>
</template>
</div>
</div>
</div>
</section>
<section class="panel-box">
<div class="dedupe-panel-head">
<h3>ASIN列表</h3>
@@ -505,54 +479,6 @@ h3 {
color: #24384d;
letter-spacing: 0.2px;
}
.dedupe-group-access {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 18px;
padding: 0 0 14px;
border-bottom: 1px solid #edf0f5;
}
.dedupe-group-access-main {
min-width: 0;
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.dedupe-group-access-title {
flex: 0 0 auto;
font-size: 14px;
font-weight: 600;
color: #24384d;
}
.dedupe-group-summary {
min-width: 0;
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
color: #5b6f83;
font-size: 13px;
}
.dedupe-group-summary-chip {
display: inline-flex;
align-items: center;
max-width: 220px;
padding: 4px 10px;
border: 1px solid #d8e3ee;
border-radius: 6px;
background: #f8f9fc;
color: #5b6f83;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.no-group,
.extra-groups {
color: #8293a5;
}
.dedupe-panel-head {
display: flex;
align-items: center;
@@ -97,7 +97,7 @@ export function parseDedupeGroupOptionList(payload: unknown): DedupeGroupOption[
const record = raw as Record<string, unknown>
const id = typeof record.id === 'number' ? Math.floor(record.id) : Number(record.group_id)
if (!Number.isFinite(id) || id <= 0) continue
const nameRaw = record.group_name ?? record.name
const nameRaw = record.groupName ?? record.group_name ?? record.name
const name = typeof nameRaw === 'string' ? nameRaw.trim() : ''
const option: DedupeGroupOption = { id, name: name || `分组${id}` }
const leaderRaw = record.leader_user_id ?? record.leaderUserId
@@ -154,7 +154,7 @@ onMounted(() => {
</div>
</template>
<style>
<style scoped>
.auth-page {
min-height: 100vh;
display: grid;
@@ -277,6 +277,7 @@ h3 {
display: flex;
flex-direction: column;
gap: 7px;
margin-bottom: 0;
}
.form-group label {
color: #5b6f83;
@@ -53,11 +53,20 @@ test('align_dedupe_group_option_parses_leader', () => {
assert.deepEqual(options, [{ id: 3, name: 'C组', leaderUserId: 12 }])
})
test('align_dedupe_page_summary_and_export_wait_wiring', () => {
test('align_dedupe_group_option_parses_java_groupName_field', () => {
// Java /api/admin/shop-manages/groups 返回 groupName(驼峰);解析器需同时认驼峰与 snake。
const options = parseDedupeGroupOptionList({
success: true,
data: { items: [{ id: 2, groupName: '周丽娥', leaderUserId: 23 }] },
})
assert.deepEqual(options, [{ id: 2, name: '周丽娥', leaderUserId: 23 }])
})
test('align_dedupe_page_no_summary_block', () => {
// 用户反馈(样办2):数据权限分组摘要块多余,从页面移除;模型纯函数保留。
const page = readSource('src/pages/asin/DedupeRegistryPage.vue')
assert.match(page, /数据权限分组/, '页顶数据权限分组汇总卡')
assert.match(page, /dedupeGroupSummaryOf/, '汇总走纯模型')
assert.doesNotMatch(page, /dedupe-group-access|dedupeGroupSummaryOf|groupSummary/, '页面不再有分组摘要块与接线')
assert.match(page, /正在生成导出文件/, '导出等待遮罩文案对齐')
assert.match(page, /已等待/, '导出等待含等待秒数')
assert.match(page, /未分组/, '分组空值显示未分组')
assert.match(page, /未分组/, '分组空值行内显示未分组')
})
@@ -18,3 +18,11 @@ test('align_history_empty_text', () => {
assert.equal(historyEmptyText({ hasFilter: false, total: 0 }), '暂无记录')
assert.equal(historyEmptyText({ hasFilter: false, total: 2 }), '')
})
test('align_history_form_group_no_global_margin_leak', () => {
// 修复按钮与筛选输入框不对齐:全局 .form-group{margin-bottom:20px} 由登录页非 scoped 样式泄漏;登录页样式收窄为 scoped,页面内显式重置。
const login = readSource('src/pages/login/LoginPage.vue')
assert.match(login, /<style scoped>/, '登录页样式 scoped,不再全局泄漏 .form-group')
const page = readSource('src/pages/records/RecordsHistoryPage.vue')
assert.match(page, /\.form-group \{[^}]*margin-bottom: 0/, '页面内 form-group 显式重置 margin')
})