Commit 6c31a476 authored by liguangyu06's avatar liguangyu06
Browse files

同步基础管理与统计报表用例文档,并更新 Playwright 脚本与 PO。

对齐 CSV/MD/测试点与现网列名及组合查询;补充厂商资质子 Tab 与基础模块复跑脚本。
parent aa8987ce
/** 各主 Tab 列设置用例(证件效期提醒 QUL-005/006 在 vendor-qual.spec.ts;其余 QUL-058~073)。 */
export type VendorQualColumnSettingsCase = {
tab: string;
openCaseId: string;
toggleCaseId: string;
};
export const vendorQualColumnSettingsCertExpiry: VendorQualColumnSettingsCase = {
tab: '证件效期提醒',
openCaseId: 'VENDOR-QUL-005',
toggleCaseId: 'VENDOR-QUL-006',
};
/** 除证件效期提醒外 8 个主 Tab ×(打开面板 + 列隐藏恢复) */
export const vendorQualColumnSettingsOtherTabs: VendorQualColumnSettingsCase[] = [
{ tab: '授权链路效期预警', openCaseId: 'VENDOR-QUL-058', toggleCaseId: 'VENDOR-QUL-059' },
{ tab: '供应商三证', openCaseId: 'VENDOR-QUL-060', toggleCaseId: 'VENDOR-QUL-061' },
{ tab: '器械注册人', openCaseId: 'VENDOR-QUL-062', toggleCaseId: 'VENDOR-QUL-063' },
{ tab: '器械注册证号', openCaseId: 'VENDOR-QUL-064', toggleCaseId: 'VENDOR-QUL-065' },
{ tab: '授权书', openCaseId: 'VENDOR-QUL-066', toggleCaseId: 'VENDOR-QUL-067' },
{ tab: '承诺书', openCaseId: 'VENDOR-QUL-068', toggleCaseId: 'VENDOR-QUL-069' },
{ tab: '法人委托书', openCaseId: 'VENDOR-QUL-070', toggleCaseId: 'VENDOR-QUL-071' },
{ tab: '二级供应商三证', openCaseId: 'VENDOR-QUL-072', toggleCaseId: 'VENDOR-QUL-073' },
];
export const vendorQualColumnSettingsAllTabs: VendorQualColumnSettingsCase[] = [
vendorQualColumnSettingsCertExpiry,
...vendorQualColumnSettingsOtherTabs,
];
/**
* 供应商资质管理 · 各主 Tab 下列表区子页签(来自 UI-SPEC-SPD-VENDOR-002 现网截图探查,2026-10)。
* 运行 `node scripts/probe-vendor-qual-subtabs.mjs` 可在登录环境下复核并写入 vendor-qual-subtabs.probe.json。
*/
export type VendorQualListSubTab = {
title: string;
pattern: RegExp;
};
export type VendorQualMainTabSubTabs = {
mainTab: string;
subTabs: VendorQualListSubTab[];
/** 子 Tab 标签上的数字是否与分页「共 N 条」一致(可读时断言) */
matchCountWithPagination: boolean;
};
export const vendorQualMainTabSubTabs: VendorQualMainTabSubTabs[] = [
{
mainTab: '证件效期提醒',
subTabs: [
{ title: '三个月内过期', pattern: /三个月内过期|近三个月到期|近三个月/ },
{ title: '一个月内过期', pattern: /一个月内过期|近一个月到期|近一个月/ },
{ title: '已过期', pattern: /已过期/ },
],
matchCountWithPagination: true,
},
/** 列表区效期子 Tab;查询:授权书名称、授权单位、被授权单位 */
{
mainTab: '授权链路效期预警',
subTabs: [
{ title: '三个月内过期', pattern: /三个月内过期|近三个月到期|近三个月/ },
{ title: '一个月内过期', pattern: /一个月内过期|近一个月到期|近一个月/ },
{ title: '已过期', pattern: /已过期/ },
],
matchCountWithPagination: true,
},
/** 列表区子 Tab;查询:销售商(自定义)名称 */
{
mainTab: '供应商三证',
subTabs: [
{ title: '全部', pattern: /^全部\b/ },
{ title: '未过期', pattern: /未过期/ },
{ title: '已过期', pattern: /已过期/ },
{ title: '已缺失', pattern: /已缺失/ },
],
matchCountWithPagination: true,
},
/** 列表区子 Tab;收起:器械注册人、状态、全国总代理;展开:类别、销售商(自定义)名称 */
{
mainTab: '器械注册人',
subTabs: [
{ title: '全部', pattern: /^全部\b/ },
{ title: '已维护', pattern: /已维护/ },
{ title: '未维护', pattern: /未维护/ },
],
matchCountWithPagination: true,
},
/** 列表区子 Tab;收起:器械注册人、销售商(自定义)名称、状态;展开:注册证号等五项 */
{
mainTab: '器械注册证号',
subTabs: [
{ title: '全部', pattern: /^全部\b/ },
{ title: '未过期', pattern: /未过期/ },
{ title: '已过期', pattern: /已过期/ },
],
matchCountWithPagination: true,
},
/** 列表区子 Tab;收起区:器械注册人、销售商(自定义)名称、状态;展开:授权书名称、注册证号、被授权单位 */
{
mainTab: '授权书',
subTabs: [
{ title: '全部', pattern: /^全部\b/ },
{ title: '未过期', pattern: /未过期/ },
{ title: '已过期', pattern: /已过期/ },
],
matchCountWithPagination: true,
},
/** 列表区子 Tab;查询:销售商(自定义)名称、承诺类型、状态 */
{
mainTab: '承诺书',
subTabs: [
{ title: '全部', pattern: /^全部\b/ },
{ title: '未过期', pattern: /未过期/ },
{ title: '已过期', pattern: /已过期/ },
],
matchCountWithPagination: true,
},
/** 列表区子 Tab;查询:销售商(自定义)名称、业务员、状态 */
{
mainTab: '法人委托书',
subTabs: [
{ title: '全部', pattern: /^全部\b/ },
{ title: '未过期', pattern: /未过期/ },
{ title: '已过期', pattern: /已过期/ },
],
matchCountWithPagination: true,
},
/** 列表区子 Tab(非顶部证件分类);查询:销售商(自定义)名称、供应商名称、数据来源类型 */
{
mainTab: '二级供应商三证',
subTabs: [
{ title: '全部', pattern: /^全部\b/ },
{ title: '未过期', pattern: /未过期/ },
{ title: '已过期', pattern: /已过期/ },
],
matchCountWithPagination: true,
},
];
export function subTabsForMainTab(mainTab: string): VendorQualMainTabSubTabs {
const found = vendorQualMainTabSubTabs.find((t) => t.mainTab === mainTab);
if (!found) {
throw new Error(`未配置主 Tab「${mainTab}」的列表子页签,请更新 data/vendor-qual-subtabs.data.ts`);
}
return found;
}
/** 用例标题 / CSV 摘要:子页签名称以「/」连接 */
export function listSubTabTitleSummary(mainTab: string): string {
return subTabsForMainTab(mainTab)
.subTabs.map((s) => s.title)
.join('/');
}
/** 供应商资质管理 · 除「证件效期提醒」外需与 002–009 同步的主 Tab 用例矩阵(CSV 编号一致)。 */
export type VendorQualSecondFieldKind = 'text' | 'select';
export type VendorQualComboField = {
filter: string;
/** 列表列名(按顺序尝试取首行样本) */
columnHeaders: string[];
kind: VendorQualSecondFieldKind;
};
export type VendorQualTabProfile = {
tab: string;
secondFilter?: string;
secondColumn?: string;
secondKind?: VendorQualSecondFieldKind;
/** 三项及以上组合查询(销售商(自定义)名称由 PO 统一处理) */
comboFields?: VendorQualComboField[];
/** 点击「展开」后出现的筛选项(在 comboFields 与销售商填写之后填写) */
expandedComboFields?: VendorQualComboField[];
/** 查询区字段文案(含销售商时写全;与页面 label 一致) */
queryFilters?: string[];
/** 收起态可见筛选项(文档用) */
queryFiltersCollapsed?: string[];
/** 展开后额外筛选项(文档用) */
queryFiltersExpanded?: string[];
/** 组合查询用例标题摘要(spec / 文档) */
comboQuerySummary?: string;
/** 列表区子页签(非顶部证件分类 Tab),配置见 vendor-qual-subtabs.data.ts */
hasExpirySubTabs: boolean;
/** 销售商(自定义)名称仅在点击「展开」后的筛选项中填写 */
supplierInExpandedFilters?: boolean;
/** 组合查询仅填写销售商(自定义)名称 */
comboSupplierOnly?: boolean;
/** 组合查询不含销售商(自定义)(仅 comboFields) */
comboWithoutSupplier?: boolean;
};
export type VendorQualTabCaseIds = {
combo: string;
reset: string;
export: string;
view: string;
expirySwitch?: string;
expiryCount?: string;
};
export type VendorQualSyncTab = VendorQualTabProfile & { caseIds: VendorQualTabCaseIds };
export const vendorQualCertExpiryProfile: VendorQualTabProfile = {
tab: '证件效期提醒',
secondFilter: '证件类型',
secondColumn: '证件类型',
secondKind: 'select',
hasExpirySubTabs: true,
};
/** 证件效期提醒:002–009 已在 spec 中单独维护。 */
export const vendorQualSyncTabs: VendorQualSyncTab[] = [
{
tab: '授权链路效期预警',
queryFilters: ['授权书名称', '授权单位', '被授权单位'],
comboQuerySummary: '授权书名称、授权单位、被授权单位',
comboWithoutSupplier: true,
comboFields: [
{
filter: '授权书名称',
columnHeaders: ['授权书名称'],
kind: 'text',
},
{
filter: '授权单位',
columnHeaders: ['授权单位'],
kind: 'text',
},
{
filter: '被授权单位',
columnHeaders: ['被授权单位'],
kind: 'text',
},
],
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-010',
reset: 'VENDOR-QUL-011',
export: 'VENDOR-QUL-012',
view: 'VENDOR-QUL-013',
expirySwitch: 'VENDOR-QUL-014',
expiryCount: 'VENDOR-QUL-015',
},
},
{
tab: '供应商三证',
queryFilters: ['销售商(自定义)名称'],
comboQuerySummary: '销售商(自定义)名称',
comboSupplierOnly: true,
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-016',
reset: 'VENDOR-QUL-017',
export: 'VENDOR-QUL-018',
view: 'VENDOR-QUL-019',
expirySwitch: 'VENDOR-QUL-044',
expiryCount: 'VENDOR-QUL-045',
},
},
{
tab: '器械注册人',
supplierInExpandedFilters: true,
queryFiltersCollapsed: ['器械注册人', '状态', '全国总代理'],
queryFiltersExpanded: ['类别', '销售商(自定义)名称'],
queryFilters: ['器械注册人', '状态', '全国总代理', '类别', '销售商(自定义)名称'],
comboQuerySummary: '器械注册人、状态、全国总代理与展开区类别、销售商(自定义)名称',
comboFields: [
{
filter: '器械注册人',
columnHeaders: ['器械注册人', '注册人'],
kind: 'text',
},
{
filter: '状态',
columnHeaders: ['状态'],
kind: 'select',
},
{
filter: '全国总代理',
columnHeaders: ['全国总代理'],
kind: 'text',
},
],
expandedComboFields: [
{
filter: '类别',
columnHeaders: ['类别'],
kind: 'select',
},
{
filter: '销售商(自定义)名称',
columnHeaders: ['销售商(自定义)名称', '销售商(自定义)', '销售商', '进院供应商'],
kind: 'text',
},
],
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-020',
reset: 'VENDOR-QUL-021',
export: 'VENDOR-QUL-022',
view: 'VENDOR-QUL-023',
expirySwitch: 'VENDOR-QUL-046',
expiryCount: 'VENDOR-QUL-047',
},
},
{
tab: '器械注册证号',
queryFiltersCollapsed: ['器械注册人', '销售商(自定义)名称', '状态'],
queryFiltersExpanded: ['注册证号', '是否有附件', '注册产品名称', '是否新证', '产品名称'],
queryFilters: [
'器械注册人',
'销售商(自定义)名称',
'状态',
'注册证号',
'是否有附件',
'注册产品名称',
'是否新证',
'产品名称',
],
comboQuerySummary:
'器械注册人、销售商(自定义)名称、状态与展开区注册证号、是否有附件、注册产品名称、是否新证、产品名称',
comboFields: [
{
filter: '器械注册人',
columnHeaders: ['器械注册人', '注册人'],
kind: 'text',
},
{
filter: '状态',
columnHeaders: ['状态'],
kind: 'select',
},
],
expandedComboFields: [
{
filter: '注册证号',
columnHeaders: ['注册证号', '注册证编号'],
kind: 'text',
},
{
filter: '是否有附件',
columnHeaders: ['是否有附件', '附件'],
kind: 'select',
},
{
filter: '注册产品名称',
columnHeaders: ['注册产品名称'],
kind: 'text',
},
{
filter: '是否新证',
columnHeaders: ['是否新证', '新证'],
kind: 'select',
},
{
filter: '产品名称',
columnHeaders: ['产品名称'],
kind: 'text',
},
],
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-024',
reset: 'VENDOR-QUL-025',
export: 'VENDOR-QUL-026',
view: 'VENDOR-QUL-027',
expirySwitch: 'VENDOR-QUL-048',
expiryCount: 'VENDOR-QUL-049',
},
},
{
tab: '授权书',
queryFiltersCollapsed: ['器械注册人', '销售商(自定义)名称', '状态'],
queryFiltersExpanded: ['授权书名称', '注册证号', '被授权单位'],
queryFilters: [
'器械注册人',
'销售商(自定义)名称',
'状态',
'授权书名称',
'注册证号',
'被授权单位',
],
comboQuerySummary:
'器械注册人、销售商(自定义)名称、状态与展开区授权书名称、注册证号、被授权单位',
comboFields: [
{
filter: '器械注册人',
columnHeaders: ['器械注册人', '注册人'],
kind: 'text',
},
{
filter: '状态',
columnHeaders: ['状态'],
kind: 'select',
},
],
expandedComboFields: [
{
filter: '授权书名称',
columnHeaders: ['授权书名称'],
kind: 'text',
},
{
filter: '注册证号',
columnHeaders: ['注册证号', '注册证编号'],
kind: 'text',
},
{
filter: '被授权单位',
columnHeaders: ['被授权单位'],
kind: 'text',
},
],
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-028',
reset: 'VENDOR-QUL-029',
export: 'VENDOR-QUL-030',
view: 'VENDOR-QUL-031',
expirySwitch: 'VENDOR-QUL-050',
expiryCount: 'VENDOR-QUL-051',
},
},
{
tab: '承诺书',
queryFilters: ['销售商(自定义)名称', '承诺类型', '状态'],
comboQuerySummary: '销售商(自定义)名称、承诺类型、状态',
comboFields: [
{
filter: '承诺类型',
columnHeaders: ['承诺类型', '承诺书类型'],
kind: 'select',
},
{
filter: '状态',
columnHeaders: ['状态'],
kind: 'select',
},
],
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-032',
reset: 'VENDOR-QUL-033',
export: 'VENDOR-QUL-034',
view: 'VENDOR-QUL-035',
expirySwitch: 'VENDOR-QUL-052',
expiryCount: 'VENDOR-QUL-053',
},
},
{
tab: '法人委托书',
queryFilters: ['销售商(自定义)名称', '业务员', '状态'],
comboQuerySummary: '销售商(自定义)名称、业务员、状态',
comboFields: [
{
filter: '业务员',
columnHeaders: ['业务员', '业务人员', '业务员姓名'],
kind: 'text',
},
{
filter: '状态',
columnHeaders: ['状态'],
kind: 'select',
},
],
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-036',
reset: 'VENDOR-QUL-037',
export: 'VENDOR-QUL-038',
view: 'VENDOR-QUL-039',
expirySwitch: 'VENDOR-QUL-054',
expiryCount: 'VENDOR-QUL-055',
},
},
{
tab: '二级供应商三证',
queryFilters: ['销售商(自定义)名称', '供应商名称', '数据来源类型'],
comboQuerySummary: '销售商(自定义)名称、供应商名称、数据来源类型',
comboFields: [
{
filter: '供应商名称',
columnHeaders: ['供应商名称', '二级供应商名称', '二级供应商'],
kind: 'text',
},
{
filter: '数据来源类型',
columnHeaders: ['数据来源类型', '数据来源'],
kind: 'select',
},
],
hasExpirySubTabs: true,
caseIds: {
combo: 'VENDOR-QUL-040',
reset: 'VENDOR-QUL-041',
export: 'VENDOR-QUL-042',
view: 'VENDOR-QUL-043',
expirySwitch: 'VENDOR-QUL-056',
expiryCount: 'VENDOR-QUL-057',
},
},
];
/** 各主 Tab 列表区子页签用例(证件效期提醒为 QUL-007/008,其余见 caseIds.expirySwitch/expiryCount)。 */
export const vendorQualExpirySubTabCaseIds: Array<{ tab: string; switchId: string; countId: string }> = [
{ tab: '证件效期提醒', switchId: 'VENDOR-QUL-007', countId: 'VENDOR-QUL-008' },
...vendorQualSyncTabs.filter((t) => t.caseIds.expirySwitch && t.caseIds.expiryCount).map((t) => ({
tab: t.tab,
switchId: t.caseIds.expirySwitch!,
countId: t.caseIds.expiryCount!,
})),
];
export const vendorQualRegistrantProfile: VendorQualTabProfile = vendorQualSyncTabs.find(
(t) => t.tab === '器械注册人',
)!;
export const vendorQualRegCertNoProfile: VendorQualTabProfile = vendorQualSyncTabs.find(
(t) => t.tab === '器械注册证号',
)!;
export const vendorQualAuthLetterProfile: VendorQualTabProfile = vendorQualSyncTabs.find(
(t) => t.tab === '授权书',
)!;
export const vendorQualCommitmentProfile: VendorQualTabProfile = vendorQualSyncTabs.find(
(t) => t.tab === '承诺书',
)!;
export const vendorQualLegalRepProfile: VendorQualTabProfile = vendorQualSyncTabs.find(
(t) => t.tab === '法人委托书',
)!;
export const vendorQualSubThreeCertProfile: VendorQualTabProfile =
vendorQualSyncTabs.find((t) => t.tab === '二级供应商三证')!;
export function vendorQualResetTestLabel(tabCase: VendorQualTabProfile): string {
if (tabCase.comboWithoutSupplier && tabCase.comboFields?.[0]) {
return `填写${tabCase.comboFields[0].filter}后重置清空`;
}
return '填写销售商(自定义)名称后重置清空';
}
export function vendorQualComboTestLabel(tabCase: VendorQualTabProfile): string {
if (tabCase.comboQuerySummary) {
return tabCase.comboQuerySummary;
}
if (tabCase.comboSupplierOnly) {
return '销售商(自定义)名称';
}
return `销售商与${tabCase.secondFilter ?? '第二条件'}`;
}
export const vendorQualAuthLinkExpiryProfile: VendorQualTabProfile = vendorQualSyncTabs.find(
(t) => t.tab === '授权链路效期预警',
)!;
export const vendorQualSupplierThreeCertProfile: VendorQualTabProfile = vendorQualSyncTabs.find(
(t) => t.tab === '供应商三证',
)!;
...@@ -18,12 +18,30 @@ export const vendorData = { ...@@ -18,12 +18,30 @@ export const vendorData = {
mockMfrsName: '__NOT_EXIST_MFRS__99999', mockMfrsName: '__NOT_EXIST_MFRS__99999',
mockSupplier: '__NOT_EXIST_SUPPLIER__99999', mockSupplier: '__NOT_EXIST_SUPPLIER__99999',
mockOrder: '__NOT_EXIST_ORDER__99999', mockOrder: '__NOT_EXIST_ORDER__99999',
/** 厂商查询页分页下拉最小档位(扫描为 20/50/100/200,无 10) */
paginationPageSizeTo: '20 条/页',
/** 列设置可 toggle 的非核心列(按表头可见性择一) */
columnSettingsToggleCandidates: ['简称', '开户银行', '银行账号', '产地', '详细地址'],
menuAuthFirst: '授权变更初审', menuAuthFirst: '授权变更初审',
/** 授权变更初审 · 状态筛选默认值 */
authFirstDefaultStatus: '通过',
menuAuthFinal: '授权变更终审', menuAuthFinal: '授权变更终审',
menuCertFirst: '注册证变更初审', menuCertFirst: '注册证变更初审',
menuCertFinal: '注册证变更终审', menuCertFinal: '注册证变更终审',
menuCertDiff: '注册证差异对比', menuCertDiff: '注册证差异对比',
menuEvalScheme: '评价方案维护', menuEvalScheme: '评价方案维护',
/** 评价方案维护 VENDOR-EVS-001:前置默认创建日期区间 */
evalSchemeDefaultCreateDateStart: '2026-04-27',
evalSchemeDefaultCreateDateEnd: '2026-10-27',
/** 评价方案维护 · 列设置可 toggle 的非核心列(按表头或列设置面板可见性择一) */
evalSchemeColumnSettingsToggleCandidates: ['备注', '备注信息', '停用人', '停用人/时间', '启用人', '创建人'],
menuEvalIndicator: '评价指标维护', menuEvalIndicator: '评价指标维护',
menuHoliday: '供应商节假日管理', menuHoliday: '供应商节假日管理',
/** 供应商节假日管理 · 右侧自定义列表列设置可 toggle 的非核心列 */
holidayColumnSettingsToggleCandidates: ['备注', '创建人时间', '进院供应商编码'],
/** 供应商资质管理 · 证件效期提醒列设置可 toggle 的非核心列 */
qualColumnSettingsToggleCandidates: ['数据来源', '证件编码', '制单日期', '备注'],
} as const; } as const;
/** @deprecated 请使用 subTabsForMainTab(mainTab)(data/vendor-qual-subtabs.data.ts) */
export { subTabsForMainTab as vendorQualSubTabsForMainTab } from './vendor-qual-subtabs.data';
...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs'; ...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs';
export const warnDetainColumns = { export const warnDetainColumns = {
productName: '物料名称', productName: '物料名称',
field: '默认供应商', field: '默认销售商',
productType: '产品类型', productType: '产品类型',
campus: '院区名称', campus: '院区名称',
field2: '库房名称', field2: '库房名称',
...@@ -30,7 +30,7 @@ export const warnDetainComboQuickFields: readonly DeptQuickFieldDef[] = [ ...@@ -30,7 +30,7 @@ export const warnDetainComboQuickFields: readonly DeptQuickFieldDef[] = [
export const warnDetainComboDrawerFields: readonly CenterReportDrawerField[] = [ export const warnDetainComboDrawerFields: readonly CenterReportDrawerField[] = [
{ key: 'productName', type: 'text', label: '物料名称' }, { key: 'productName', type: 'text', label: '物料名称' },
{ key: 'field', type: 'text', label: '默认供应商' }, { key: 'field', type: 'text', label: '默认销售商' },
{ key: 'productType', type: 'select', label: '产品类型' }, { key: 'productType', type: 'select', label: '产品类型' },
{ key: 'campus', type: 'select', label: '院区名称' }, { key: 'campus', type: 'select', label: '院区名称' },
{ key: 'field2', type: 'text', label: '库房名称' }, { key: 'field2', type: 'text', label: '库房名称' },
......
...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs'; ...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs';
export const warnExpdtColumns = { export const warnExpdtColumns = {
productName: '物料名称', productName: '物料名称',
supplierName: '进院供应商名称', supplierName: '销售商(自定义)名称',
field: '近效期', field: '近效期',
field2: '条码', field2: '条码',
campus: '院区', campus: '院区',
...@@ -21,7 +21,7 @@ export const warnExpdtColumns = { ...@@ -21,7 +21,7 @@ export const warnExpdtColumns = {
field10: '器械注册人-术语配置', field10: '器械注册人-术语配置',
batchNo: '批号', batchNo: '批号',
field11: '单位', field11: '单位',
supplierName2: '进院供应商', supplierName2: '销售商(自定义)',
field12: '生产日期', field12: '生产日期',
field13: '库存数量', field13: '库存数量',
statDate: '统计日期', statDate: '统计日期',
...@@ -30,16 +30,16 @@ export const warnExpdtColumns = { ...@@ -30,16 +30,16 @@ export const warnExpdtColumns = {
export const warnExpdtComboFullQuickFields: readonly DeptQuickFieldDef[] = [ export const warnExpdtComboFullQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'supplierName', label: '进院供应商名称', type: 'text' }, { key: 'supplierName', label: '销售商(自定义)名称', type: 'text' },
]; ];
export const warnExpdtComboQuickFields: readonly DeptQuickFieldDef[] = [ export const warnExpdtComboQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'supplierName', label: '进院供应商名称', type: 'text' }, { key: 'supplierName', label: '销售商(自定义)名称', type: 'text' },
]; ];
export const warnExpdtComboDrawerFields: readonly CenterReportDrawerField[] = [ export const warnExpdtComboDrawerFields: readonly CenterReportDrawerField[] = [
{ key: 'productName', type: 'text', label: '物料名称' }, { key: 'productName', type: 'text', label: '物料名称' },
{ key: 'supplierName', type: 'text', label: '进院供应商名称' }, { key: 'supplierName', type: 'text', label: '销售商(自定义)名称' },
{ key: 'field', type: 'select', label: '近效期' }, { key: 'field', type: 'select', label: '近效期' },
{ key: 'field2', type: 'text', label: '条码' }, { key: 'field2', type: 'text', label: '条码' },
{ key: 'consumableType', type: 'select', label: '耗材类型' }, { key: 'consumableType', type: 'select', label: '耗材类型' },
...@@ -49,7 +49,7 @@ export const warnExpdtComboAssertKeys = ['productName', 'supplierName'] as const ...@@ -49,7 +49,7 @@ export const warnExpdtComboAssertKeys = ['productName', 'supplierName'] as const
export const warnExpdtDomainQuickFields: readonly DeptQuickFieldDef[] = [ export const warnExpdtDomainQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'supplierName', label: '进院供应商名称', type: 'text' }, { key: 'supplierName', label: '销售商(自定义)名称', type: 'text' },
]; ];
export const warnExpdtDomainAssertKeys = ['productName', 'supplierName'] as const; export const warnExpdtDomainAssertKeys = ['productName', 'supplierName'] as const;
...@@ -65,7 +65,7 @@ export const warnExpdtData: CenterReportPageData & { ...@@ -65,7 +65,7 @@ export const warnExpdtData: CenterReportPageData & {
columns: warnExpdtColumns, columns: warnExpdtColumns,
coreTableHeaders: ['条码', '院区', '库房', '库区', '物料编号','物料名称', '规格型号', '耗材类型'], coreTableHeaders: ['条码', '院区', '库房', '库区', '物料编号','物料名称', '规格型号', '耗材类型'],
columnAliases: { columnAliases: {
supplierName: ['进院供应商'], supplierName: ['销售商(自定义)'],
field5: ['采购计划号'], field5: ['采购计划号'],
}, },
......
...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs'; ...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs';
export const warnLowColumns = { export const warnLowColumns = {
productName: '物料名称', productName: '物料名称',
field: '默认供应商', field: '默认销售商',
consumableType: '耗材类型', consumableType: '耗材类型',
campus: '院区名称', campus: '院区名称',
field2: '库房名称', field2: '库房名称',
...@@ -24,7 +24,7 @@ export const warnLowColumns = { ...@@ -24,7 +24,7 @@ export const warnLowColumns = {
export const warnLowComboFullQuickFields: readonly DeptQuickFieldDef[] = [ export const warnLowComboFullQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'field', label: '默认供应商', type: 'text' }, { key: 'field', label: '默认销售商', type: 'text' },
{ key: 'consumableType', label: '耗材类型', type: 'select' }, { key: 'consumableType', label: '耗材类型', type: 'select' },
{ key: 'campus', label: '院区', type: 'select' }, { key: 'campus', label: '院区', type: 'select' },
{ key: 'field2', label: '库房', type: 'select' }, { key: 'field2', label: '库房', type: 'select' },
...@@ -32,13 +32,13 @@ export const warnLowComboFullQuickFields: readonly DeptQuickFieldDef[] = [ ...@@ -32,13 +32,13 @@ export const warnLowComboFullQuickFields: readonly DeptQuickFieldDef[] = [
]; ];
export const warnLowComboQuickFields: readonly DeptQuickFieldDef[] = [ export const warnLowComboQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'field', label: '默认供应商', type: 'text' }, { key: 'field', label: '默认销售商', type: 'text' },
{ key: 'consumableType', label: '耗材类型', type: 'select' }, { key: 'consumableType', label: '耗材类型', type: 'select' },
]; ];
export const warnLowComboDrawerFields: readonly CenterReportDrawerField[] = [ export const warnLowComboDrawerFields: readonly CenterReportDrawerField[] = [
{ key: 'productName', type: 'text', label: '物料名称' }, { key: 'productName', type: 'text', label: '物料名称' },
{ key: 'field', type: 'text', label: '默认供应商' }, { key: 'field', type: 'text', label: '默认销售商' },
{ key: 'consumableType', type: 'select', label: '耗材类型' }, { key: 'consumableType', type: 'select', label: '耗材类型' },
]; ];
...@@ -53,7 +53,7 @@ export const warnLowComboAssertKeys = [ ...@@ -53,7 +53,7 @@ export const warnLowComboAssertKeys = [
export const warnLowDomainQuickFields: readonly DeptQuickFieldDef[] = [ export const warnLowDomainQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'field', label: '默认供应商', type: 'text' }, { key: 'field', label: '默认销售商', type: 'text' },
{ key: 'consumableType', label: '耗材类型', type: 'select' }, { key: 'consumableType', label: '耗材类型', type: 'select' },
]; ];
...@@ -68,7 +68,7 @@ export const warnLowData: CenterReportPageData & { ...@@ -68,7 +68,7 @@ export const warnLowData: CenterReportPageData & {
iframeSrc: 'warning/lowStorage', iframeSrc: 'warning/lowStorage',
productNameSelector: '#form_item_goodsName', productNameSelector: '#form_item_goodsName',
columns: warnLowColumns, columns: warnLowColumns,
coreTableHeaders: ['院区名称', '库房名称', '库区名称', '物料编号','物料名称', '规格型号', '器械注册人-术语配置', '默认供应商'], coreTableHeaders: ['院区名称', '库房名称', '库区名称', '物料编号','物料名称', '规格型号', '器械注册人-术语配置', '默认销售商'],
columnAliases: { columnAliases: {
field5: ['采购计划号'], field5: ['采购计划号'],
}, },
......
...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs'; ...@@ -4,7 +4,7 @@ import type { DeptQuickFieldDef } from './dept-report-field-defs';
export const warnStrandColumns = { export const warnStrandColumns = {
productName: '物料名称', productName: '物料名称',
supplierName: '进院供应商名称', supplierName: '销售商(自定义)名称',
field: '滞销天数', field: '滞销天数',
field2: '条码', field2: '条码',
consumableType: '耗材类型', consumableType: '耗材类型',
...@@ -21,7 +21,7 @@ export const warnStrandColumns = { ...@@ -21,7 +21,7 @@ export const warnStrandColumns = {
field9: '器械注册人-术语配置', field9: '器械注册人-术语配置',
field10: '单位', field10: '单位',
field11: '字典价', field11: '字典价',
supplierName2: '进院供应商', supplierName2: '销售商(自定义)',
field12: '库存数量', field12: '库存数量',
field13: '可用数量', field13: '可用数量',
statDate: '统计日期', statDate: '统计日期',
...@@ -30,16 +30,16 @@ export const warnStrandColumns = { ...@@ -30,16 +30,16 @@ export const warnStrandColumns = {
export const warnStrandComboFullQuickFields: readonly DeptQuickFieldDef[] = [ export const warnStrandComboFullQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'supplierName', label: '进院供应商名称', type: 'text' }, { key: 'supplierName', label: '销售商(自定义)名称', type: 'text' },
]; ];
export const warnStrandComboQuickFields: readonly DeptQuickFieldDef[] = [ export const warnStrandComboQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'supplierName', label: '进院供应商名称', type: 'text' }, { key: 'supplierName', label: '销售商(自定义)名称', type: 'text' },
]; ];
export const warnStrandComboDrawerFields: readonly CenterReportDrawerField[] = [ export const warnStrandComboDrawerFields: readonly CenterReportDrawerField[] = [
{ key: 'productName', type: 'text', label: '物料名称' }, { key: 'productName', type: 'text', label: '物料名称' },
{ key: 'supplierName', type: 'text', label: '进院供应商名称' }, { key: 'supplierName', type: 'text', label: '销售商(自定义)名称' },
{ key: 'field', type: 'select', label: '滞销天数' }, { key: 'field', type: 'select', label: '滞销天数' },
{ key: 'field2', type: 'text', label: '条码' }, { key: 'field2', type: 'text', label: '条码' },
{ key: 'consumableType', type: 'select', label: '耗材类型' }, { key: 'consumableType', type: 'select', label: '耗材类型' },
...@@ -49,7 +49,7 @@ export const warnStrandComboAssertKeys = ['productName', 'supplierName'] as cons ...@@ -49,7 +49,7 @@ export const warnStrandComboAssertKeys = ['productName', 'supplierName'] as cons
export const warnStrandDomainQuickFields: readonly DeptQuickFieldDef[] = [ export const warnStrandDomainQuickFields: readonly DeptQuickFieldDef[] = [
{ key: 'productName', label: '物料名称', type: 'text' }, { key: 'productName', label: '物料名称', type: 'text' },
{ key: 'supplierName', label: '进院供应商名称', type: 'text' }, { key: 'supplierName', label: '销售商(自定义)名称', type: 'text' },
]; ];
export const warnStrandDomainAssertKeys = ['productName', 'supplierName'] as const; export const warnStrandDomainAssertKeys = ['productName', 'supplierName'] as const;
...@@ -65,7 +65,7 @@ export const warnStrandData: CenterReportPageData & { ...@@ -65,7 +65,7 @@ export const warnStrandData: CenterReportPageData & {
columns: warnStrandColumns, columns: warnStrandColumns,
coreTableHeaders: ['条码', '院区', '库房', '库区', '物料编号','物料名称', '产品俗称', '规格型号'], coreTableHeaders: ['条码', '院区', '库房', '库区', '物料编号','物料名称', '产品俗称', '规格型号'],
columnAliases: { columnAliases: {
supplierName: ['进院供应商'], supplierName: ['销售商(自定义)'],
field5: ['采购计划号'], field5: ['采购计划号'],
}, },
......
...@@ -374,9 +374,9 @@ python3 scripts/sync-docs-ui-specs.py --only ADMIT-001,ADMIT-002,ADMIT-003,ADMIT ...@@ -374,9 +374,9 @@ python3 scripts/sync-docs-ui-specs.py --only ADMIT-001,ADMIT-002,ADMIT-003,ADMIT
| 注册证变更初审 | VENDOR-005 | 已扫描 · `vendor-cert-first` · **40** 项 · 测试点 `TP_VENDOR_CF1` · PO/冒烟已就绪 | | 注册证变更初审 | VENDOR-005 | 已扫描 · `vendor-cert-first` · **40** 项 · 测试点 `TP_VENDOR_CF1` · PO/冒烟已就绪 |
| 注册证变更终审 | VENDOR-006 | 已扫描 · `vendor-cert-final` · **40** 项 · 测试点 `TP_VENDOR_CF2` · PO/冒烟已就绪 | | 注册证变更终审 | VENDOR-006 | 已扫描 · `vendor-cert-final` · **40** 项 · 测试点 `TP_VENDOR_CF2` · PO/冒烟已就绪 |
| 注册证差异对比 | VENDOR-007 | 已扫描 · `vendor-cert-diff` · **54** 项 · 含 scjs iframe · 测试点 `TP_VENDOR_CDF` · PO/冒烟已就绪 | | 注册证差异对比 | VENDOR-007 | 已扫描 · `vendor-cert-diff` · **54** 项 · 含 scjs iframe · 测试点 `TP_VENDOR_CDF` · PO/冒烟已就绪 |
| 评价方案维护 | VENDOR-008 | 已扫描 · `vendor-eval-scheme` · **57** 项 · 测试点 `TP_VENDOR_EVS` · PO/冒烟已就绪 | | 评价方案维护 | VENDOR-008 | 已扫描 · `vendor-eval-scheme` · **57** 项 · 测试点 `TP_VENDOR_EVS` · 自动化 **14** 条(含 014 筛选展开/收起) |
| 评价指标维护 | VENDOR-009 | 已扫描 · `vendor-eval-indicator` · **165** 项 · 测试点 `TP_VENDOR_EVI` · PO/冒烟已就绪 | | 评价指标维护 | VENDOR-009 | 已扫描 · `vendor-eval-indicator` · **165** 项 · 测试点 `TP_VENDOR_EVI` · PO/冒烟已就绪 |
| 供应商节假日管理 | VENDOR-010 | 已扫描 · `vendor-holiday` · **80** 项 · 测试点 `TP_VENDOR_HLD` · PO/冒烟已就绪 | | 供应商节假日管理 | VENDOR-010 | 已扫描 · `vendor-holiday` · **80** 项 · 测试点 `TP_VENDOR_HLD` · PO 已就绪 · 自动化 **8** 条(HLD-001~008) |
菜单路径:**基础设置** → **厂商管理** → {页面名}。 菜单路径:**基础设置** → **厂商管理** → {页面名}。
......
...@@ -8,7 +8,7 @@ related_jrn: "" ...@@ -8,7 +8,7 @@ related_jrn: ""
related_tc: "testpoint/基础管理-厂商管理-厂商查询-测试点分析-01.md" related_tc: "testpoint/基础管理-厂商管理-厂商查询-测试点分析-01.md"
related_def: "" related_def: ""
create_time: "2026-09-30" create_time: "2026-09-30"
update_time: "2026-09-30" update_time: "2026-10-27"
author: "" author: ""
--- ---
...@@ -54,18 +54,20 @@ author: "" ...@@ -54,18 +54,20 @@ author: ""
### 列表与工具栏 ### 列表与工具栏
- 搜索、列设置、刷新/导出(以截图图标为准) - 搜索、列设置(`anticon-setting` 齿轮,与 `column-height` 表格密度区分)、刷新/导出(以截图图标为准)
- 列:序号、厂商编号、厂商名称、产地、详细地址、简称、开户银行、银行账号;底部分页 - 列:序号、厂商编号、厂商名称、产地、详细地址、简称、开户银行、银行账号;底部分页
- 底部分页:「共 N 条」、页码与每页条数切换(左右分栏页面对应侧分页) - 底部分页:「共 N 条」、页码与每页条数切换(可选 **20/50/100/200 条/页**,默认常为 50;左右分栏页面对应侧分页)
## 自动化建议 ## 自动化建议
1. 元素扫描已完成(47 项):`data/scan/vendor-query-elements.json`;下一步补充 Page Object 与用例。 1. 元素扫描已完成(47 项):`data/scan/vendor-query-elements.json`;Playwright 见 `tests/spd/vendor-query.spec.ts`、`pages/spd/vendor-query.page.ts`(列设置复用 `pages/spd/helpers/column-settings.helper.ts`)。
2. 菜单导航:`page.getByRole('menuitem', { name: '厂商查询', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分)。 2. 菜单导航:`page.getByRole('menuitem', { name: '厂商查询', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分);进页可用 `open()` 直链 `/spd/basic/mfrs/paltform/mfrsName/factory`(依赖 `auth.setup` 登录态)。
3. 资质多 Tab、变更审批详情、左右分栏(指标树/节假日)需先断言目标面板可见再操作。 3. 全量 CSV 用例 9 条:`VENDOR-QRY-001`~`009`(`testcase/基础管理-厂商管理-厂商查询-UI自动化测试用例-01.csv`);冒烟 `@smoke`:`001`、`004`;运行 `npm run test:vendor-query:all`。
## 测试关注点 ## 测试关注点
1. 筛选 + Tab/状态下拉组合后,列表条数与底部分页「共 N 条」一致。 1. 筛选 + Tab 组合后,列表条数与底部分页「共 N 条」一致;按厂商名称搜索后清空可恢复更宽结果(自动化 `VENDOR-QRY-003`)。
2. 授权/注册证初审与终审详情、状态流转与业务规则一致;写操作前确认勾选/当前行。 2. 器械注册人 / 经销商 Tab 切换后列表数据域正确(`VENDOR-QRY-001`);经销商 Tab 点选首行后需显式写入厂商名称再查询(`VENDOR-QRY-006`)。
3. 注册证差异对比「一致/不一致」与两侧字段抽样一致;导出与当前查询条件一致。 3. 切换每页条数(如 **20 条/页**)后当前页行数 = min(总条数, 所选档位) 且「共 N 条」不变(`VENDOR-QRY-007`);总条数足够时可翻至第 2 页(`VENDOR-QRY-005`)。
4. 列设置面板含「字段设置 / 列展示 / 重置」;取消勾选非核心列(如简称)后表头隐藏,再勾选可恢复(`VENDOR-QRY-008`~`009`)。
5. 无匹配关键字时总数为 0、空态明确(mock:`__NOT_EXIST_MFRS__99999`,`VENDOR-QRY-004`)。
...@@ -71,17 +71,26 @@ author: "" ...@@ -71,17 +71,26 @@ author: ""
### 状态 / 分类 Tab(若有) ### 状态 / 分类 Tab(若有)
- 证件 Tab:证件效期提醒、授权链路效期预警、供应商三证、器械注册人、器械注册证号、授权书、承诺书、法人委托书、二级供应商三证;效期快捷:近三个月到期、近一个月到期、已过期(带计数) - 证件 Tab:证件效期提醒、授权链路效期预警、供应商三证、器械注册人、器械注册证号、授权书、承诺书、法人委托书、二级供应商三证
- 证件效期提醒:列表区效期快捷近三个月到期、近一个月到期、已过期(带计数)
- **授权链路效期预警**:列表区子 Tab **三个月内过期 / 一个月内过期 / 已过期**;筛选 **授权书名称、授权单位、被授权单位**
- **供应商三证**:列表区子 Tab **全部 / 未过期 / 已过期 / 已缺失**;筛选 **销售商(自定义)名称**
- **器械注册人**:列表区子 Tab **全部 / 已维护 / 未维护**;收起区 **器械注册人、状态、全国总代理**;展开后 **类别、销售商(自定义)名称**
- **器械注册证号**:列表区子 Tab **全部 / 未过期 / 已过期**;收起区 **器械注册人、销售商(自定义)名称、状态**;展开后 **注册证号、是否有附件、注册产品名称、是否新证、产品名称**
- **授权书**:列表区子 Tab **全部 / 未过期 / 已过期**;收起区 **器械注册人、销售商(自定义)名称、状态**;点击 **展开** 后 **授权书名称、注册证号、被授权单位**
- **承诺书**:列表区子 Tab **全部 / 未过期 / 已过期**;筛选 **销售商(自定义)名称、承诺类型、状态**
- **法人委托书**:列表区子 Tab **全部 / 未过期 / 已过期**;筛选 **销售商(自定义)名称、业务员、状态**
- **二级供应商三证**:列表区子 Tab **全部 / 未过期 / 已过期**;筛选 **销售商(自定义)名称、供应商名称、数据来源类型**
### 列表与工具栏 ### 列表与工具栏
- **导出** / **导出明细**(视 Tab);列设置 - **导出** / **导出明细**(视 Tab);**每个主 Tab** 列表工具栏均含 **列设置**(字段展示/隐藏)
- 证件效期提醒列含数据来源、进院供应商、有效期至、证件名称/类型、效期提醒、查看;授权链路预警列含授权单位、授权书名称、被授权单位、效期起止、效期提醒、查看 - 证件效期提醒列含数据来源、进院供应商、有效期至、证件名称/类型、效期提醒、查看;授权链路预警列含授权单位、授权书名称、被授权单位、效期起止、效期提醒、查看
- 底部分页:「共 N 条」、页码与每页条数切换(左右分栏页面对应侧分页) - 底部分页:「共 N 条」、页码与每页条数切换(左右分栏页面对应侧分页)
## 自动化建议 ## 自动化建议
1. 元素扫描已完成(99 项):`data/scan/vendor-qual-elements.json`;下一步补充 Page Object 与用例。 1. 元素扫描(99 项):`data/scan/vendor-qual-elements.json`;自动化 **VENDOR-QUL-001~073**(`vendor-qual.spec.ts` / `vendor-qual-sync-tabs.spec.ts` / `vendor-qual-column-settings.spec.ts`),Tab 与子 Tab 配置见 `data/vendor-qual-*.ts`。
2. 菜单导航:`page.getByRole('menuitem', { name: '供应商资质管理', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分)。 2. 菜单导航:`page.getByRole('menuitem', { name: '供应商资质管理', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分)。
3. 资质多 Tab、变更审批详情、左右分栏(指标树/节假日)需先断言目标面板可见再操作。 3. 资质多 Tab、变更审批详情、左右分栏(指标树/节假日)需先断言目标面板可见再操作。
......
...@@ -8,7 +8,7 @@ related_jrn: "" ...@@ -8,7 +8,7 @@ related_jrn: ""
related_tc: "testpoint/基础管理-厂商管理-评价方案维护-测试点分析-01.md" related_tc: "testpoint/基础管理-厂商管理-评价方案维护-测试点分析-01.md"
related_def: "" related_def: ""
create_time: "2026-09-30" create_time: "2026-09-30"
update_time: "2026-09-30" update_time: "2026-10-28"
author: "" author: ""
--- ---
...@@ -57,9 +57,11 @@ author: "" ...@@ -57,9 +57,11 @@ author: ""
## 自动化建议 ## 自动化建议
1. 元素扫描已完成(57 项):`data/scan/vendor-eval-scheme-elements.json`;下一步补充 Page Object 与用例。 1. 元素扫描(57 项):`data/scan/vendor-eval-scheme-elements.json`;PO:`pages/spd/vendor-eval-scheme.page.ts`。
2. 菜单导航:`page.getByRole('menuitem', { name: '评价方案维护', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分)。 2. 已落地 Playwright(`tests/spd/vendor-eval-scheme.spec.ts`):**EVS-001** 组合查询(冒烟);**EVS-014** 筛选区展开/收起;**EVS-002/003** 列设置;**EVS-004~013** 十列排序。
3. 资质多 Tab、变更审批详情、左右分栏(指标树/节假日)需先断言目标面板可见再操作。 3. 菜单导航:`page.getByRole('menuitem', { name: '评价方案维护', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分)。
4. 数据与用例清单:`data/vendor-eval-scheme.data.ts`(排序列、扩展筛选项);CSV 共 **14** 条(`testcase/…评价方案维护-UI自动化测试用例-01.csv`)。
5. 筛选/新增/指标关联等见测试点分析;PO 内未纳入 CSV 的方法仍预留供扩展。
## 测试关注点 ## 测试关注点
......
...@@ -5,10 +5,10 @@ status: 生效 ...@@ -5,10 +5,10 @@ status: 生效
related_br: "" related_br: ""
related_api: "" related_api: ""
related_jrn: "" related_jrn: ""
related_tc: "testpoint/基础管理-厂商管理-供应商节假日管理-测试点分析-01.md" related_tc: "testpoint/基础管理-厂商管理-供应商节假日管理-测试点分析-01.md; testcase/基础管理-厂商管理-供应商节假日管理-UI自动化测试用例-01.csv"
related_def: "" related_def: ""
create_time: "2026-09-30" create_time: "2026-09-30"
update_time: "2026-09-30" update_time: "2026-10-27"
author: "" author: ""
--- ---
...@@ -57,9 +57,23 @@ author: "" ...@@ -57,9 +57,23 @@ author: ""
## 自动化建议 ## 自动化建议
1. 元素扫描已完成(80 项):`data/scan/vendor-holiday-elements.json`;下一步补充 Page Object 与用例。 1. 元素扫描(80 项):`data/scan/vendor-holiday-elements.json`;Page Object:`pages/spd/vendor-holiday.page.ts`;结构化用例 MD:`testcases/基础管理-厂商管理-供应商节假日管理-UI自动化测试用例-01.md`。
2. 菜单导航:`page.getByRole('menuitem', { name: '供应商节假日管理', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分)。 2. 数据驱动 CSV 与 Playwright **8** 条一一对应(`npm run test:vendor-holiday` 跑 smoke;`npm run test:vendor-holiday:all` 跑全量):
3. 资质多 Tab、变更审批详情、左右分栏(指标树/节假日)需先断言目标面板可见再操作。
| 用例 ID | 标题 | Smoke |
|---------|------|-------|
| VENDOR-HLD-001 | 选中左侧节假日展示详情 | 是 |
| VENDOR-HLD-002 | 左侧搜索无匹配空态(mock反例) | 是 |
| VENDOR-HLD-003 | 点击左侧新增弹出新增弹框 | 是 |
| VENDOR-HLD-004 | 选中首行点击编辑弹出编辑弹框 | 是 |
| VENDOR-HLD-005 | 首行名称或年度搜索验证 | 是 |
| VENDOR-HLD-006 | 切换列表行右侧详情名称年度一致 | 是 |
| VENDOR-HLD-007 | 默认假日详情区点击右侧新增弹出弹框 | 是 |
| VENDOR-HLD-008 | 右侧自定义列表打开列设置面板 | 否 |
3. 菜单导航:`page.getByRole('menuitem', { name: '供应商节假日管理', exact: true }).click()`(注意初审/终审、方案/指标等近似菜单区分)。
4. 写操作:左/右侧新增与左侧编辑仅测弹框打开,不提交;日期校验、主数据对照等暂不纳入当前自动化集。
5. 左右分栏页需先断言目标面板可见再操作;右侧列设置齿轮在供应商自定义列表工具栏(`anticon-setting`,非 column-height)。
## 测试关注点 ## 测试关注点
......
...@@ -316,7 +316,7 @@ locators: ...@@ -316,7 +316,7 @@ locators:
playwright: "page.frameLocator('iframe[src*=\"statistics/pro\"]').locator('#table_search_form_branchId')" playwright: "page.frameLocator('iframe[src*=\"statistics/pro\"]').locator('#table_search_form_branchId')"
productNameInput: productNameInput:
description: "产品编号/名称" description: "物料名称"
element_type: text element_type: text
section: "reportTurnoverIframe::main" section: "reportTurnoverIframe::main"
frame: "reportTurnoverIframe" frame: "reportTurnoverIframe"
......
...@@ -49,7 +49,10 @@ export class SurgerySharedLocators { ...@@ -49,7 +49,10 @@ export class SurgerySharedLocators {
this.paginationPrev = page.locator('.ant-pagination-prev').first(); this.paginationPrev = page.locator('.ant-pagination-prev').first();
this.paginationNext = page.locator('.ant-pagination-next').first(); this.paginationNext = page.locator('.ant-pagination-next').first();
this.dialog = page.locator('.ant-modal-content, .ant-modal-wrap .ant-modal, .ant-drawer-open').last(); this.dialog = page
.locator('.ant-modal-wrap:not([style*="display: none"]) .ant-modal-content')
.or(page.locator('.ant-drawer-open .ant-drawer-content'))
.last();
this.formError = page.locator('.ant-form-item-explain-error, .ant-message-error, .ant-notification-notice'); this.formError = page.locator('.ant-form-item-explain-error, .ant-message-error, .ant-notification-notice');
} }
......
...@@ -279,11 +279,11 @@ locators: ...@@ -279,11 +279,11 @@ locators:
element_type: select element_type: select
section: "main::main" section: "main::main"
strategy: label_text strategy: label_text
value: "销售商" value: "销售商(自定义)"
playwright: "page.getByText('销售商', { exact: true })" playwright: "page.getByText('销售商(自定义)', { exact: true })"
supplierId: supplierId:
description: "销售商" description: "销售商(自定义)"
element_type: search element_type: search
section: "main::main" section: "main::main"
strategy: id strategy: id
......
...@@ -325,6 +325,16 @@ locators: ...@@ -325,6 +325,16 @@ locators:
name: "展开" name: "展开"
playwright: "page.getByRole('button', { name: '展开' })" playwright: "page.getByRole('button', { name: '展开' })"
# 展开后文案变为「收起」;EVS-014 自动化见 vendor-eval-scheme.page.ts
collapseFilterBtn:
description: "收起"
element_type: button
section: "main::main"
strategy: role
role: button
name: "收起"
playwright: "page.getByRole('button', { name: '收起' })"
addBtn: addBtn:
description: "新 增" description: "新 增"
element_type: button element_type: button
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
"gate:commit": "node scripts/git-gate.mjs --mode=commit", "gate:commit": "node scripts/git-gate.mjs --mode=commit",
"gate:push": "node scripts/git-gate.mjs --mode=push", "gate:push": "node scripts/git-gate.mjs --mode=push",
"test:ci": "node scripts/run-ci.mjs", "test:ci": "node scripts/run-ci.mjs",
"cleanup:artifacts": "node scripts/cleanup-local-artifacts.mjs",
"test:ci:smoke": "node scripts/run-ci.mjs --suite=smoke", "test:ci:smoke": "node scripts/run-ci.mjs --suite=smoke",
"test:ci:nightly": "node scripts/run-ci.mjs --suite=nightly", "test:ci:nightly": "node scripts/run-ci.mjs --suite=nightly",
"test:ci:nightly:shard": "node scripts/run-ci.mjs --suite=nightly --shards=2", "test:ci:nightly:shard": "node scripts/run-ci.mjs --suite=nightly --shards=2",
...@@ -116,7 +117,7 @@ ...@@ -116,7 +117,7 @@
"test:vendor-query": "playwright test tests/spd/vendor-query.spec.ts --project=chromium --grep @smoke", "test:vendor-query": "playwright test tests/spd/vendor-query.spec.ts --project=chromium --grep @smoke",
"test:vendor-query:all": "playwright test tests/spd/vendor-query.spec.ts --project=chromium --workers=1", "test:vendor-query:all": "playwright test tests/spd/vendor-query.spec.ts --project=chromium --workers=1",
"test:vendor-qual": "playwright test tests/spd/vendor-qual.spec.ts --project=chromium --grep @smoke", "test:vendor-qual": "playwright test tests/spd/vendor-qual.spec.ts --project=chromium --grep @smoke",
"test:vendor-qual:all": "playwright test tests/spd/vendor-qual.spec.ts --project=chromium --workers=1", "test:vendor-qual:all": "playwright test tests/spd/vendor-qual.spec.ts tests/spd/vendor-qual-sync-tabs.spec.ts tests/spd/vendor-qual-column-settings.spec.ts --project=chromium --workers=1",
"test:vendor:smoke": "playwright test tests/spd/vendor-query.spec.ts tests/spd/vendor-qual.spec.ts tests/spd/vendor-audit.spec.ts tests/spd/vendor-cert-diff.spec.ts tests/spd/vendor-eval-scheme.spec.ts tests/spd/vendor-eval-indicator.spec.ts tests/spd/vendor-holiday.spec.ts --project=chromium --grep @smoke --workers=1", "test:vendor:smoke": "playwright test tests/spd/vendor-query.spec.ts tests/spd/vendor-qual.spec.ts tests/spd/vendor-audit.spec.ts tests/spd/vendor-cert-diff.spec.ts tests/spd/vendor-eval-scheme.spec.ts tests/spd/vendor-eval-indicator.spec.ts tests/spd/vendor-holiday.spec.ts --project=chromium --grep @smoke --workers=1",
"test:vendor-audit:smoke": "playwright test tests/spd/vendor-audit.spec.ts --project=chromium --grep @smoke --workers=1", "test:vendor-audit:smoke": "playwright test tests/spd/vendor-audit.spec.ts --project=chromium --grep @smoke --workers=1",
"test:vendor-audit:all": "playwright test tests/spd/vendor-audit.spec.ts --project=chromium --workers=1", "test:vendor-audit:all": "playwright test tests/spd/vendor-audit.spec.ts --project=chromium --workers=1",
...@@ -140,7 +141,7 @@ ...@@ -140,7 +141,7 @@
"test:surgery:smoke": "playwright test tests/spd/surgery-base-pkg.spec.ts tests/spd/surgery-oper-type.spec.ts tests/spd/surgery-std-pkg.spec.ts --project=chromium --grep @smoke --workers=1", "test:surgery:smoke": "playwright test tests/spd/surgery-base-pkg.spec.ts tests/spd/surgery-oper-type.spec.ts tests/spd/surgery-std-pkg.spec.ts --project=chromium --grep @smoke --workers=1",
"test:surgery:all": "playwright test tests/spd/surgery-base-pkg.spec.ts tests/spd/surgery-oper-type.spec.ts tests/spd/surgery-std-pkg.spec.ts --project=chromium --workers=1", "test:surgery:all": "playwright test tests/spd/surgery-base-pkg.spec.ts tests/spd/surgery-oper-type.spec.ts tests/spd/surgery-std-pkg.spec.ts --project=chromium --workers=1",
"assert:surgery-csv-spec": "node scripts/assert-surgery-csv-spec-sync.mjs", "assert:surgery-csv-spec": "node scripts/assert-surgery-csv-spec-sync.mjs",
"test:vendor:all": "playwright test tests/spd/vendor-query.spec.ts tests/spd/vendor-qual.spec.ts tests/spd/vendor-audit.spec.ts tests/spd/vendor-cert-diff.spec.ts tests/spd/vendor-eval-scheme.spec.ts tests/spd/vendor-eval-indicator.spec.ts tests/spd/vendor-holiday.spec.ts --project=chromium --workers=1", "test:vendor:all": "playwright test tests/spd/vendor-query.spec.ts tests/spd/vendor-qual.spec.ts tests/spd/vendor-qual-sync-tabs.spec.ts tests/spd/vendor-qual-column-settings.spec.ts tests/spd/vendor-audit.spec.ts tests/spd/vendor-cert-diff.spec.ts tests/spd/vendor-eval-scheme.spec.ts tests/spd/vendor-eval-indicator.spec.ts tests/spd/vendor-holiday.spec.ts --project=chromium --workers=1",
"discover:yaml-from-json": "node scripts/json-to-locator-yaml.mjs --all-extended", "discover:yaml-from-json": "node scripts/json-to-locator-yaml.mjs --all-extended",
"update:ui-specs-extended": "python3 scripts/update-extended-ui-specs.py", "update:ui-specs-extended": "python3 scripts/update-extended-ui-specs.py",
"update:ui-specs-consume": "python3 scripts/update-consume-ui-specs.py", "update:ui-specs-consume": "python3 scripts/update-consume-ui-specs.py",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment