fix(supply-chain): 固化人员信息界面配置
This commit is contained in:
parent
f94286464b
commit
7b5f66dfcf
@ -13,7 +13,7 @@ jest.mock('./supply-chain-tabs', () => ({
|
||||
useSupplyChainTabs: () => ({
|
||||
tabs: [
|
||||
{ path: '/supply-chain/dashboard', title: '工作台', closable: false },
|
||||
{ path: '/supply-chain/management/owner-config', title: '负责人配置', closable: true },
|
||||
{ path: '/supply-chain/management/owner-config', title: '人员信息', closable: true },
|
||||
{ path: '/supply-chain/management/custom-table', title: '限价管理', closable: true },
|
||||
{ path: '/supply-chain/management/blank-pages/blank-page-1', title: '空白页 1', closable: true },
|
||||
],
|
||||
@ -47,7 +47,7 @@ describe('SupplyChainTabBar owner config labels', () => {
|
||||
|
||||
it('keeps the page title read-only when editing is disabled', () => {
|
||||
render(<SupplyChainTabBar />)
|
||||
expect(screen.getByText('负责人配置')).toBeInTheDocument()
|
||||
expect(screen.getByText('人员信息')).toBeInTheDocument()
|
||||
expect(screen.queryByRole('button', { name: '修改页签名称' })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
|
||||
@ -111,7 +111,7 @@ export const SUPPLY_CHAIN_ROUTE_TITLES: Record<string, string> = {
|
||||
'/supply-chain/script-monitor': '脚本监控',
|
||||
'/supply-chain/operation-logs': '操作日志',
|
||||
'/supply-chain/user-permissions': '用户权限',
|
||||
'/supply-chain/management/owner-config': '负责人配置',
|
||||
'/supply-chain/management/owner-config': '人员信息',
|
||||
'/supply-chain/management/custom-table': '限价管理',
|
||||
...Object.fromEntries(MANAGEMENT_BLANK_PAGES.map((page) => [page.route, page.label])),
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ describe('supply chain menu', () => {
|
||||
expect(flattenSupplyChainMenu()).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: '负责人配置',
|
||||
label: '人员信息',
|
||||
module: '经营管理',
|
||||
route: '/supply-chain/management/owner-config',
|
||||
}),
|
||||
|
||||
@ -88,7 +88,7 @@ export const SUPPLY_CHAIN_MENU: SupplyChainMenuModule[] = [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
label: '负责人配置',
|
||||
label: '人员信息',
|
||||
route: '/supply-chain/management/owner-config',
|
||||
targetKey: 'businessManagement',
|
||||
},
|
||||
|
||||
@ -45,27 +45,33 @@ beforeEach(() => {
|
||||
})
|
||||
afterAll(() => { global.fetch = originalFetch })
|
||||
|
||||
describe('负责人配置工作台', () => {
|
||||
describe('人员信息工作台', () => {
|
||||
it('只展示三级负责人字段,只读用户不显示编辑控件', async () => {
|
||||
render(<OwnerConfigView canEdit={false} />)
|
||||
await screen.findByText('运营甲')
|
||||
for (const name of ['运营负责人', '部门', '二级部门', '利润中心', '部门负责人', '总负责人', '在职状态']) {
|
||||
expect(screen.getByRole('columnheader', { name })).toBeInTheDocument()
|
||||
}
|
||||
expect(screen.getAllByRole('columnheader').map((header) => header.textContent)).toEqual([
|
||||
'人员',
|
||||
'部门负责人',
|
||||
'总负责人',
|
||||
'部门',
|
||||
'二级部门',
|
||||
'利润中心',
|
||||
'在职状态',
|
||||
])
|
||||
for (const name of ['SPU', '货号', '商品编码']) {
|
||||
expect(screen.queryByRole('columnheader', { name })).not.toBeInTheDocument()
|
||||
}
|
||||
expect(screen.queryByRole('button', { name: '新增配置' })).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole('button', { name: '编辑负责人配置' })).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole('button', { name: '编辑人员信息' })).not.toBeInTheDocument()
|
||||
expect(screen.getByText('在职')).toHaveClass('employed')
|
||||
})
|
||||
|
||||
it('选择通讯录员工后自动带出部门和总负责人', async () => {
|
||||
render(<OwnerConfigView canEdit />)
|
||||
render(<OwnerConfigView canEdit showManagementActions />)
|
||||
await screen.findByText('运营甲')
|
||||
fireEvent.click(screen.getByRole('button', { name: '新增配置' }))
|
||||
await screen.findByRole('dialog')
|
||||
fireEvent.change(screen.getByRole('combobox', { name: '运营负责人' }), { target: { value: 'employee-2' } })
|
||||
fireEvent.change(screen.getByRole('combobox', { name: '人员' }), { target: { value: 'employee-2' } })
|
||||
expect(screen.getByRole('textbox', { name: '部门' })).toHaveValue('运营二部')
|
||||
expect(screen.getByRole('textbox', { name: '二级部门' })).toHaveValue('运营二组')
|
||||
expect(screen.getByRole('textbox', { name: '利润中心' })).toHaveValue('运营中心B')
|
||||
@ -75,12 +81,12 @@ describe('负责人配置工作台', () => {
|
||||
})
|
||||
|
||||
it('允许开发环境人工修改并保存列标题', async () => {
|
||||
render(<OwnerConfigView canEdit allowLabelEditing />)
|
||||
render(<OwnerConfigView canEdit allowLabelEditing showManagementActions />)
|
||||
await screen.findByText('运营甲')
|
||||
expect(screen.getByRole('button', { name: '修改操作列标题' })).toBeInTheDocument()
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '修改运营负责人列标题' }))
|
||||
const input = screen.getByRole('textbox', { name: '修改运营负责人列标题' })
|
||||
fireEvent.click(screen.getByRole('button', { name: '修改人员列标题' }))
|
||||
const input = screen.getByRole('textbox', { name: '修改人员列标题' })
|
||||
fireEvent.change(input, { target: { value: '成员' } })
|
||||
fireEvent.blur(input)
|
||||
|
||||
@ -106,11 +112,39 @@ describe('负责人配置工作台', () => {
|
||||
render(<OwnerConfigView canEdit={false} />)
|
||||
await screen.findByText('运营甲')
|
||||
const headers = screen.getAllByRole('columnheader').map((header) => header.textContent)
|
||||
expect(screen.getByRole('columnheader', { name: '人员' })).toBeInTheDocument()
|
||||
expect(screen.queryByRole('columnheader', { name: '运营负责人' })).not.toBeInTheDocument()
|
||||
expect(headers.indexOf('二级部门')).toBe(headers.indexOf('部门') + 1)
|
||||
})
|
||||
|
||||
it('把历史人工表头配置补全为当前源码中的完整顺序', async () => {
|
||||
window.localStorage.setItem(OWNER_CONFIG_SETTINGS_STORAGE_KEY, JSON.stringify({
|
||||
pageTitle: '负责人配置',
|
||||
actionsLabel: '操作',
|
||||
fields: [
|
||||
{ id: 'operationOwner', label: '运营负责人', builtinKey: 'operationOwner', visible: true },
|
||||
{ id: 'departmentOwner', label: '部门负责人', builtinKey: 'departmentOwner', visible: true },
|
||||
{ id: 'generalOwner', label: '总负责人', builtinKey: 'generalOwner', visible: true },
|
||||
],
|
||||
}))
|
||||
|
||||
render(<OwnerConfigView canEdit={false} />)
|
||||
await screen.findByText('运营甲')
|
||||
|
||||
expect(screen.getAllByRole('columnheader').map((header) => header.textContent)).toEqual([
|
||||
'人员',
|
||||
'部门负责人',
|
||||
'总负责人',
|
||||
'部门',
|
||||
'二级部门',
|
||||
'利润中心',
|
||||
'在职状态',
|
||||
])
|
||||
expect(screen.getByRole('navigation', { name: '人员信息分页' })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('支持新增自定义字段、填写值并删除字段', async () => {
|
||||
render(<OwnerConfigView canEdit allowLabelEditing />)
|
||||
render(<OwnerConfigView canEdit allowLabelEditing showManagementActions />)
|
||||
await screen.findByText('运营甲')
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '字段配置' }))
|
||||
@ -120,7 +154,7 @@ describe('负责人配置工作台', () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: '完成' }))
|
||||
|
||||
expect(screen.getByRole('columnheader', { name: '备注' })).toBeInTheDocument()
|
||||
fireEvent.click(screen.getByRole('button', { name: '编辑负责人配置' }))
|
||||
fireEvent.click(screen.getByRole('button', { name: '编辑人员信息' }))
|
||||
fireEvent.change(screen.getByRole('textbox', { name: '备注' }), { target: { value: '重点成员' } })
|
||||
mockFetch.mockResolvedValueOnce(reply(row))
|
||||
.mockResolvedValueOnce(reply({ items: [row], pageInfo }))
|
||||
@ -145,9 +179,9 @@ describe('负责人配置工作台', () => {
|
||||
it('保存编辑后重新读取负责人数据', async () => {
|
||||
render(<OwnerConfigView canEdit />)
|
||||
await screen.findByText('运营甲')
|
||||
fireEvent.click(screen.getByRole('button', { name: '编辑负责人配置' }))
|
||||
fireEvent.click(screen.getByRole('button', { name: '编辑人员信息' }))
|
||||
await screen.findByRole('dialog')
|
||||
fireEvent.change(screen.getByRole('combobox', { name: '运营负责人' }), { target: { value: 'employee-2' } })
|
||||
fireEvent.change(screen.getByRole('combobox', { name: '人员' }), { target: { value: 'employee-2' } })
|
||||
fireEvent.change(screen.getByRole('textbox', { name: '部门负责人' }), { target: { value: '人工部门负责人' } })
|
||||
fireEvent.change(screen.getByRole('textbox', { name: '总负责人' }), { target: { value: '人工总负责人' } })
|
||||
mockFetch.mockResolvedValueOnce(reply({ ...row, operationOwner: '运营丁' }))
|
||||
@ -201,6 +235,30 @@ describe('负责人配置工作台', () => {
|
||||
expect(screen.getByRole('button', { name: '导出' })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('在底部分页区域显示总条数,单页时禁用翻页按钮', async () => {
|
||||
render(<OwnerConfigView canEdit={false} />)
|
||||
await screen.findByText('运营甲')
|
||||
|
||||
const pagination = screen.getByRole('navigation', { name: '人员信息分页' })
|
||||
expect(pagination).toHaveTextContent('共 1 条')
|
||||
expect(pagination).toHaveTextContent('1 / 1')
|
||||
expect(screen.getByRole('button', { name: '上一页' })).toBeDisabled()
|
||||
expect(screen.getByRole('button', { name: '下一页' })).toBeDisabled()
|
||||
expect(document.querySelector('.owner-config-tools')).not.toHaveTextContent('共 1 条')
|
||||
})
|
||||
|
||||
it('默认隐藏字段配置、批量删除、新增配置和批量勾选列', async () => {
|
||||
render(<OwnerConfigView canEdit allowLabelEditing />)
|
||||
await screen.findByText('运营甲')
|
||||
|
||||
expect(screen.queryByRole('button', { name: '字段配置' })).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole('button', { name: '批量删除' })).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole('button', { name: '新增配置' })).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole('checkbox', { name: '全选当前页' })).not.toBeInTheDocument()
|
||||
expect(screen.queryByRole('checkbox', { name: '选择运营甲' })).not.toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: '编辑人员信息' })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('支持勾选当前页记录并批量删除', async () => {
|
||||
jest.spyOn(window, 'confirm').mockReturnValue(true)
|
||||
mockFetch.mockImplementation(async (input: RequestInfo | URL, options?: RequestInit) => {
|
||||
@ -210,7 +268,7 @@ describe('负责人配置工作台', () => {
|
||||
return reply({ items: [row], pageInfo })
|
||||
})
|
||||
|
||||
render(<OwnerConfigView canEdit />)
|
||||
render(<OwnerConfigView canEdit showManagementActions />)
|
||||
await screen.findByText('运营甲')
|
||||
|
||||
const bulkDeleteButton = screen.getByRole('button', { name: '批量删除' })
|
||||
@ -224,7 +282,7 @@ describe('负责人配置工作台', () => {
|
||||
&& options?.method === 'POST'
|
||||
&& JSON.parse(options.body as string).ids[0] === 'config-1'
|
||||
))).toBe(true))
|
||||
expect(window.confirm).toHaveBeenCalledWith('确认删除已选择的 1 条负责人配置?')
|
||||
expect(window.confirm).toHaveBeenCalledWith('确认删除已选择的 1 条人员信息?')
|
||||
})
|
||||
|
||||
it('分别筛选五个字段并按当前筛选条件导出全部匹配数据', async () => {
|
||||
@ -243,7 +301,7 @@ describe('负责人配置工作台', () => {
|
||||
render(<OwnerConfigView canEdit={false} canExport />)
|
||||
await screen.findByText('运营甲')
|
||||
for (const [name, value] of [
|
||||
['筛选运营负责人', '运营甲'],
|
||||
['筛选人员', '运营甲'],
|
||||
['筛选部门负责人', '部门乙'],
|
||||
['筛选总负责人', '负责人丙'],
|
||||
['筛选利润中心', '运营中心A'],
|
||||
@ -288,7 +346,7 @@ describe('负责人配置工作台', () => {
|
||||
render(<OwnerConfigView canEdit={false} />)
|
||||
await screen.findByText('运营甲')
|
||||
|
||||
const operationOwnerInput = screen.getByRole('combobox', { name: '筛选运营负责人' })
|
||||
const operationOwnerInput = screen.getByRole('combobox', { name: '筛选人员' })
|
||||
const profitCenterInput = screen.getByRole('combobox', { name: '筛选利润中心' })
|
||||
const departmentInput = screen.getByRole('combobox', { name: '筛选部门' })
|
||||
const statusInput = screen.getByRole('combobox', { name: '筛选在职状态' })
|
||||
|
||||
@ -180,11 +180,13 @@ export function OwnerConfigView({
|
||||
canExport = false,
|
||||
allowLabelEditing = false,
|
||||
autoSyncDirectory = false,
|
||||
showManagementActions = false,
|
||||
}: {
|
||||
canEdit: boolean
|
||||
canExport?: boolean
|
||||
allowLabelEditing?: boolean
|
||||
autoSyncDirectory?: boolean
|
||||
showManagementActions?: boolean
|
||||
}) {
|
||||
const {
|
||||
labels,
|
||||
@ -378,7 +380,7 @@ export function OwnerConfigView({
|
||||
}
|
||||
|
||||
const deleteItem = async (item: OwnerConfig) => {
|
||||
if (!canEdit || deletingId || !window.confirm('确认删除该负责人配置?')) return
|
||||
if (!canEdit || deletingId || !window.confirm('确认删除该人员信息?')) return
|
||||
setDeletingId(item.id)
|
||||
try {
|
||||
await readResponse(await fetch(
|
||||
@ -397,7 +399,7 @@ export function OwnerConfigView({
|
||||
const bulkDeleteItems = async () => {
|
||||
const ids = [...selectedIds]
|
||||
if (!canEdit || bulkDeleting || ids.length === 0) return
|
||||
if (!window.confirm(`确认删除已选择的 ${ids.length} 条负责人配置?`)) return
|
||||
if (!window.confirm(`确认删除已选择的 ${ids.length} 条人员信息?`)) return
|
||||
setBulkDeleting(true)
|
||||
setError(null)
|
||||
try {
|
||||
@ -536,8 +538,9 @@ export function OwnerConfigView({
|
||||
setExporting(false)
|
||||
}
|
||||
}
|
||||
const canBulkSelect = canEdit && showManagementActions
|
||||
const allCurrentPageSelected = items.length > 0 && items.every((item) => selectedIds.has(item.id))
|
||||
const tableColumnCount = Math.max(1, visibleFields.length + (canEdit ? 2 : 0))
|
||||
const tableColumnCount = Math.max(1, visibleFields.length + (canEdit ? 1 : 0) + (canBulkSelect ? 1 : 0))
|
||||
|
||||
return (
|
||||
<div className="owner-config-page">
|
||||
@ -568,7 +571,6 @@ export function OwnerConfigView({
|
||||
</div>
|
||||
</form>
|
||||
<div className="owner-config-tools">
|
||||
<span>共 {pageInfo.total} 条</span>
|
||||
<button type="button" className="icon-button" title="刷新" aria-label="刷新" onClick={() => void load()}>
|
||||
<RefreshCw size={15} />
|
||||
</button>
|
||||
@ -577,17 +579,17 @@ export function OwnerConfigView({
|
||||
<FileDown size={15} />{exporting ? '导出中...' : '导出'}
|
||||
</button>
|
||||
) : null}
|
||||
{allowLabelEditing ? (
|
||||
{allowLabelEditing && showManagementActions ? (
|
||||
<button type="button" className="secondary-button" onClick={() => setFieldSettingsOpen(true)}>
|
||||
<Columns3 size={15} />字段配置
|
||||
</button>
|
||||
) : null}
|
||||
{canEdit ? (
|
||||
{canBulkSelect ? (
|
||||
<button type="button" className="danger-button" disabled={selectedIds.size === 0 || bulkDeleting} onClick={() => void bulkDeleteItems()}>
|
||||
<Trash2 size={15} />{bulkDeleting ? '删除中...' : `批量删除${selectedIds.size > 0 ? `(${selectedIds.size})` : ''}`}
|
||||
</button>
|
||||
) : null}
|
||||
{canEdit ? (
|
||||
{canEdit && showManagementActions ? (
|
||||
<button type="button" className="primary-button" onClick={() => openDraft({ ...EMPTY_DRAFT })}>
|
||||
<Plus size={15} />新增配置
|
||||
</button>
|
||||
@ -602,16 +604,16 @@ export function OwnerConfigView({
|
||||
<table
|
||||
className="owner-config-table"
|
||||
aria-label={labels.pageTitle}
|
||||
style={{ minWidth: Math.max(360, visibleFields.length * 150 + (canEdit ? 92 : 0)) }}
|
||||
style={{ minWidth: Math.max(360, visibleFields.length * 150 + (canEdit ? 92 : 0) + (canBulkSelect ? 34 : 0)) }}
|
||||
>
|
||||
<colgroup>
|
||||
{canEdit ? <col className="selection-column" /> : null}
|
||||
{canBulkSelect ? <col className="selection-column" /> : null}
|
||||
{visibleFields.map((field) => <col key={field.id} className="owner-column" />)}
|
||||
{canEdit ? <col className="action-column" /> : null}
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
{canEdit ? (
|
||||
{canBulkSelect ? (
|
||||
<th className="selection-cell">
|
||||
<input
|
||||
className="owner-config-selection-checkbox"
|
||||
@ -643,12 +645,12 @@ export function OwnerConfigView({
|
||||
) : null}
|
||||
{!loading && !error ? items.map((item) => (
|
||||
<tr key={item.id}>
|
||||
{canEdit ? (
|
||||
{canBulkSelect ? (
|
||||
<td className="selection-cell">
|
||||
<input
|
||||
className="owner-config-selection-checkbox"
|
||||
type="checkbox"
|
||||
aria-label={`选择${item.operationOwner || '负责人配置'}`}
|
||||
aria-label={`选择${item.operationOwner || '人员信息'}`}
|
||||
checked={selectedIds.has(item.id)}
|
||||
disabled={bulkDeleting}
|
||||
onChange={(event) => setSelectedIds((current) => {
|
||||
@ -690,17 +692,16 @@ export function OwnerConfigView({
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{pageInfo.totalPages > 1 ? (
|
||||
<nav className="owner-config-pagination" aria-label={`${labels.pageTitle}分页`}>
|
||||
<button type="button" title="上一页" aria-label="上一页" disabled={loading || page <= 1} onClick={() => setPage((value) => Math.max(1, value - 1))}>
|
||||
<ChevronLeft size={15} />
|
||||
</button>
|
||||
<span>{pageInfo.page} / {pageInfo.totalPages}</span>
|
||||
<button type="button" title="下一页" aria-label="下一页" disabled={loading || page >= pageInfo.totalPages} onClick={() => setPage((value) => Math.min(pageInfo.totalPages, value + 1))}>
|
||||
<ChevronRight size={15} />
|
||||
</button>
|
||||
</nav>
|
||||
) : null}
|
||||
<nav className="owner-config-pagination" aria-label={`${labels.pageTitle}分页`}>
|
||||
<span className="owner-config-total">共 {pageInfo.total} 条</span>
|
||||
<button type="button" title="上一页" aria-label="上一页" disabled={loading || page <= 1} onClick={() => setPage((value) => Math.max(1, value - 1))}>
|
||||
<ChevronLeft size={15} />
|
||||
</button>
|
||||
<span>{pageInfo.page} / {pageInfo.totalPages}</span>
|
||||
<button type="button" title="下一页" aria-label="下一页" disabled={loading || page >= pageInfo.totalPages} onClick={() => setPage((value) => Math.min(pageInfo.totalPages, value + 1))}>
|
||||
<ChevronRight size={15} />
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
{draft ? (
|
||||
<Modal isOpen onClose={closeDraft} title={`${draft.id ? '编辑' : '新增'}${labels.pageTitle}`} size="medium" closeOnOverlayClick={!saving}>
|
||||
@ -822,6 +823,7 @@ export function OwnerConfigView({
|
||||
.owner-config-pagination button{display:inline-flex; width:28px; height:28px; align-items:center; justify-content:center; border:0; border-radius:4px; background:transparent; color:var(--sc-ink); cursor:pointer}
|
||||
.owner-config-pagination button:hover:not(:disabled){background:var(--sc-surface-muted)}
|
||||
.owner-config-pagination button:disabled{opacity:.35; cursor:not-allowed}
|
||||
.owner-config-total{margin-right:4px; padding-right:12px; border-right:1px solid var(--sc-border); white-space:nowrap}
|
||||
.owner-config-fields{display:grid; grid-template-columns:1fr 1fr; gap:14px}
|
||||
.owner-config-fields label{display:flex; min-width:0; flex-direction:column; gap:6px; color:var(--sc-muted); font-size:12px}
|
||||
.owner-config-fields input,.owner-config-fields select{box-sizing:border-box; width:100%; height:36px; border:1px solid var(--sc-border); border-radius:5px; background:var(--sc-surface); padding:0 10px; font-size:13px; outline:0}
|
||||
|
||||
@ -40,30 +40,30 @@ type OwnerConfigViewSettings = {
|
||||
}
|
||||
|
||||
const DEFAULT_FIELDS: OwnerConfigField[] = [
|
||||
{ id: 'operationOwner', label: '运营负责人', builtinKey: 'operationOwner', visible: true },
|
||||
{ id: 'operationOwner', label: '人员', builtinKey: 'operationOwner', visible: true },
|
||||
{ id: 'departmentOwner', label: '部门负责人', builtinKey: 'departmentOwner', visible: true },
|
||||
{ id: 'generalOwner', label: '总负责人', builtinKey: 'generalOwner', visible: true },
|
||||
{ id: 'department', label: '部门', builtinKey: 'department', visible: true },
|
||||
{ id: 'secondaryDepartment', label: '二级部门', builtinKey: 'secondaryDepartment', visible: true },
|
||||
{ id: 'profitCenter', label: '利润中心', builtinKey: 'profitCenter', visible: true },
|
||||
{ id: 'departmentOwner', label: '部门负责人', builtinKey: 'departmentOwner', visible: true },
|
||||
{ id: 'generalOwner', label: '总负责人', builtinKey: 'generalOwner', visible: true },
|
||||
{ id: 'employmentStatus', label: '在职状态', builtinKey: 'employmentStatus', visible: true },
|
||||
]
|
||||
|
||||
const DEFAULT_SETTINGS: OwnerConfigViewSettings = {
|
||||
pageTitle: '负责人配置',
|
||||
pageTitle: '人员信息',
|
||||
actionsLabel: '操作',
|
||||
fields: DEFAULT_FIELDS,
|
||||
}
|
||||
|
||||
export const DEFAULT_OWNER_CONFIG_LABELS: OwnerConfigLabels = {
|
||||
pageTitle: DEFAULT_SETTINGS.pageTitle,
|
||||
operationOwner: DEFAULT_FIELDS[0].label,
|
||||
department: DEFAULT_FIELDS[1].label,
|
||||
secondaryDepartment: DEFAULT_FIELDS[2].label,
|
||||
profitCenter: DEFAULT_FIELDS[3].label,
|
||||
departmentOwner: DEFAULT_FIELDS[4].label,
|
||||
generalOwner: DEFAULT_FIELDS[5].label,
|
||||
employmentStatus: DEFAULT_FIELDS[6].label,
|
||||
operationOwner: DEFAULT_FIELDS.find((field) => field.builtinKey === 'operationOwner')!.label,
|
||||
department: DEFAULT_FIELDS.find((field) => field.builtinKey === 'department')!.label,
|
||||
secondaryDepartment: DEFAULT_FIELDS.find((field) => field.builtinKey === 'secondaryDepartment')!.label,
|
||||
profitCenter: DEFAULT_FIELDS.find((field) => field.builtinKey === 'profitCenter')!.label,
|
||||
departmentOwner: DEFAULT_FIELDS.find((field) => field.builtinKey === 'departmentOwner')!.label,
|
||||
generalOwner: DEFAULT_FIELDS.find((field) => field.builtinKey === 'generalOwner')!.label,
|
||||
employmentStatus: DEFAULT_FIELDS.find((field) => field.builtinKey === 'employmentStatus')!.label,
|
||||
actions: DEFAULT_SETTINGS.actionsLabel,
|
||||
}
|
||||
|
||||
@ -84,12 +84,14 @@ function readLegacyLabels(): OwnerConfigLabels {
|
||||
const value = JSON.parse(window.localStorage.getItem(OWNER_CONFIG_LABELS_STORAGE_KEY) ?? 'null')
|
||||
if (!value || typeof value !== 'object') return DEFAULT_OWNER_CONFIG_LABELS
|
||||
const source = value as Partial<Record<OwnerConfigLabelKey, unknown>>
|
||||
return Object.fromEntries(
|
||||
const labels = Object.fromEntries(
|
||||
Object.entries(DEFAULT_OWNER_CONFIG_LABELS).map(([key, fallback]) => [
|
||||
key,
|
||||
cleanLabel(source[key as OwnerConfigLabelKey], fallback),
|
||||
]),
|
||||
) as OwnerConfigLabels
|
||||
if (labels.operationOwner === '运营负责人') labels.operationOwner = DEFAULT_OWNER_CONFIG_LABELS.operationOwner
|
||||
return labels
|
||||
} catch {
|
||||
return DEFAULT_OWNER_CONFIG_LABELS
|
||||
}
|
||||
@ -144,9 +146,16 @@ function normalizeSettings(value: unknown): OwnerConfigViewSettings {
|
||||
|
||||
function readSettings() {
|
||||
try {
|
||||
return normalizeSettings(JSON.parse(
|
||||
const settings = normalizeSettings(JSON.parse(
|
||||
window.localStorage.getItem(OWNER_CONFIG_SETTINGS_STORAGE_KEY) ?? 'null',
|
||||
))
|
||||
if (settings.pageTitle === '负责人配置') settings.pageTitle = DEFAULT_SETTINGS.pageTitle
|
||||
settings.fields = settings.fields.map((field) => (
|
||||
field.builtinKey === 'operationOwner' && field.label === '运营负责人'
|
||||
? { ...field, label: DEFAULT_OWNER_CONFIG_LABELS.operationOwner }
|
||||
: field
|
||||
))
|
||||
return settings
|
||||
} catch {
|
||||
return normalizeSettings(null)
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { requireSession } from '@/lib/server-session'
|
||||
import { supplyChainPermissionSettingsService } from '@/server/services/supply-chain-permission-settings.service'
|
||||
import { OwnerConfigView } from '../OwnerConfigView'
|
||||
|
||||
export const metadata = { title: '负责人配置 · 供应链中心' }
|
||||
export const metadata = { title: '人员信息 · 供应链中心' }
|
||||
|
||||
export default async function OwnerConfigPage() {
|
||||
const { authUser } = await requireSession('/login')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user