fix(样办反馈): ①生成记录查询按钮与输入框对齐(修复登录页非scoped .form-group{margin-bottom:20px}全局泄漏,登录页样式收窄scoped+页面内显式重置) ②去重汇总移除数据权限分组摘要块(模型纯函数保留) ③分组筛选下拉显示真实分组名(解析器兼容Java groupName字段)
This commit is contained in:
@@ -4,7 +4,6 @@ import { formatDateTime } from '@/utils/datetime'
|
|||||||
* script 逻辑沿用现有 Vue 实现(查询/编辑/删除/导入轮询/导出秒表)。 */
|
* script 逻辑沿用现有 Vue 实现(查询/编辑/删除/导入轮询/导出秒表)。 */
|
||||||
import { computed, onMounted, reactive, ref } from 'vue'
|
import { computed, onMounted, reactive, ref } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useAdminSessionStore } from '@/stores/admin-session'
|
|
||||||
import {
|
import {
|
||||||
fetchDedupeTotalList,
|
fetchDedupeTotalList,
|
||||||
updateDedupeTotal,
|
updateDedupeTotal,
|
||||||
@@ -12,7 +11,7 @@ import {
|
|||||||
fetchDedupeTotalGroups,
|
fetchDedupeTotalGroups,
|
||||||
type DedupeGroupOption,
|
type DedupeGroupOption,
|
||||||
} from './dedupe-total-api.ts'
|
} 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 { ASIN_COUNTRY_CODES, asinCountryLabel } from './asin-country.ts'
|
||||||
import { createDedupeTotalFilterState, toDedupeListParams } from './dedupe-total-filter.ts'
|
import { createDedupeTotalFilterState, toDedupeListParams } from './dedupe-total-filter.ts'
|
||||||
import {
|
import {
|
||||||
@@ -25,7 +24,6 @@ import { importOutcomeText, importTaskFinished, isAllowedImportFile } from './de
|
|||||||
import type { DedupeImportProgress } from './dedupe-import-model.ts'
|
import type { DedupeImportProgress } from './dedupe-import-model.ts'
|
||||||
import { toExportUrl } from './dedupe-total-export.ts'
|
import { toExportUrl } from './dedupe-total-export.ts'
|
||||||
|
|
||||||
const session = useAdminSessionStore()
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const rows = ref<DedupeTotalItem[]>([])
|
const rows = ref<DedupeTotalItem[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
@@ -35,10 +33,6 @@ const filter = reactive(createDedupeTotalFilterState())
|
|||||||
const groups = ref<DedupeGroupOption[]>([])
|
const groups = ref<DedupeGroupOption[]>([])
|
||||||
const jumpPage = ref('')
|
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 totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize)))
|
||||||
|
|
||||||
const editVisible = ref(false)
|
const editVisible = ref(false)
|
||||||
@@ -287,26 +281,6 @@ onMounted(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dedupe-view">
|
<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">
|
<section class="panel-box">
|
||||||
<div class="dedupe-panel-head">
|
<div class="dedupe-panel-head">
|
||||||
<h3>ASIN列表</h3>
|
<h3>ASIN列表</h3>
|
||||||
@@ -505,54 +479,6 @@ h3 {
|
|||||||
color: #24384d;
|
color: #24384d;
|
||||||
letter-spacing: 0.2px;
|
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 {
|
.dedupe-panel-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export function parseDedupeGroupOptionList(payload: unknown): DedupeGroupOption[
|
|||||||
const record = raw as Record<string, unknown>
|
const record = raw as Record<string, unknown>
|
||||||
const id = typeof record.id === 'number' ? Math.floor(record.id) : Number(record.group_id)
|
const id = typeof record.id === 'number' ? Math.floor(record.id) : Number(record.group_id)
|
||||||
if (!Number.isFinite(id) || id <= 0) continue
|
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 name = typeof nameRaw === 'string' ? nameRaw.trim() : ''
|
||||||
const option: DedupeGroupOption = { id, name: name || `分组${id}` }
|
const option: DedupeGroupOption = { id, name: name || `分组${id}` }
|
||||||
const leaderRaw = record.leader_user_id ?? record.leaderUserId
|
const leaderRaw = record.leader_user_id ?? record.leaderUserId
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style scoped>
|
||||||
.auth-page {
|
.auth-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ h3 {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 7px;
|
gap: 7px;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
.form-group label {
|
.form-group label {
|
||||||
color: #5b6f83;
|
color: #5b6f83;
|
||||||
|
|||||||
@@ -53,11 +53,20 @@ test('align_dedupe_group_option_parses_leader', () => {
|
|||||||
assert.deepEqual(options, [{ id: 3, name: 'C组', leaderUserId: 12 }])
|
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')
|
const page = readSource('src/pages/asin/DedupeRegistryPage.vue')
|
||||||
assert.match(page, /数据权限分组/, '页顶数据权限分组汇总卡')
|
assert.doesNotMatch(page, /dedupe-group-access|dedupeGroupSummaryOf|groupSummary/, '页面不再有分组摘要块与接线')
|
||||||
assert.match(page, /dedupeGroupSummaryOf/, '汇总走纯模型')
|
|
||||||
assert.match(page, /正在生成导出文件/, '导出等待遮罩文案对齐')
|
assert.match(page, /正在生成导出文件/, '导出等待遮罩文案对齐')
|
||||||
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: 0 }), '暂无记录')
|
||||||
assert.equal(historyEmptyText({ hasFilter: false, total: 2 }), '')
|
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')
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user