feat: inherit channel report requirements
This commit is contained in:
@@ -1,27 +1,29 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { ArrowLeft, Plus, Search } from 'lucide-react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { adminApi, type AdminChannel, type ChannelReportField } from '@/api/adminApi';
|
||||
import { adminApi, type AdminChannel, type ChannelReportField, type DictionaryItem } from '@/api/adminApi';
|
||||
import { Breadcrumb, Button, Input, Modal, Select, Table, Textarea, Tag, type TableColumn } from '@/components/ui';
|
||||
|
||||
export function AdminChannelReportPage() {
|
||||
const navigate = useNavigate();
|
||||
const [channels, setChannels] = useState<AdminChannel[]>([]);
|
||||
const [fields, setFields] = useState<ChannelReportField[]>([]);
|
||||
const [libraryFields, setLibraryFields] = useState<DictionaryItem[]>([]);
|
||||
const [channelId, setChannelId] = useState('');
|
||||
const [keyword, setKeyword] = useState('');
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [code, setCode] = useState('');
|
||||
const [name, setName] = useState('');
|
||||
const [fieldType, setFieldType] = useState('string');
|
||||
const [drainageFieldId, setDrainageFieldId] = useState('');
|
||||
const [reportType, setReportType] = useState<'signature' | 'drainage' | 'both'>('signature');
|
||||
const [required, setRequired] = useState(false);
|
||||
const [description, setDescription] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
|
||||
function loadData(nextChannelId = channelId) {
|
||||
Promise.all([adminApi.listChannels(), adminApi.listChannelReportFields(nextChannelId || undefined)])
|
||||
.then(([channelItems, fieldItems]) => {
|
||||
Promise.all([adminApi.listChannels(), adminApi.listChannelReportFields(nextChannelId || undefined), adminApi.listDrainageFields()])
|
||||
.then(([channelItems, fieldItems, libraryItems]) => {
|
||||
setChannels(channelItems.filter((item) => item.status !== 'deleted'));
|
||||
setFields(fieldItems);
|
||||
setLibraryFields(libraryItems.filter((item) => item.status === 'active'));
|
||||
setError('');
|
||||
})
|
||||
.catch((failure: Error) => setError(failure.message || '通道报备配置加载失败'));
|
||||
@@ -34,12 +36,14 @@ export function AdminChannelReportPage() {
|
||||
const filteredFields = useMemo(() => fields.filter((field) => !keyword || [field.code, field.name, field.fieldType, field.description].join(' ').includes(keyword)), [fields, keyword]);
|
||||
|
||||
function createField() {
|
||||
adminApi.createChannelReportField({ channelId, code, name, fieldType, description, status: 'active' })
|
||||
const selected = libraryFields.find((item) => item.id === drainageFieldId);
|
||||
if (!selected) return;
|
||||
adminApi.createChannelReportField({ channelId, drainageFieldId, reportType, required, description, status: 'active' })
|
||||
.then(() => {
|
||||
setModalOpen(false);
|
||||
setCode('');
|
||||
setName('');
|
||||
setFieldType('string');
|
||||
setDrainageFieldId('');
|
||||
setReportType('signature');
|
||||
setRequired(false);
|
||||
setDescription('');
|
||||
loadData();
|
||||
})
|
||||
@@ -51,6 +55,7 @@ export function AdminChannelReportPage() {
|
||||
{ key: 'code', title: '字段代码', width: '160px', render: (record) => <strong>{record.code}</strong> },
|
||||
{ key: 'name', title: '字段名称', width: '160px', render: (record) => record.name },
|
||||
{ key: 'type', title: '字段类型', width: '120px', render: (record) => record.fieldType },
|
||||
{ key: 'reportType', title: '报备用途', width: '140px', render: (record) => record.reportType === 'signature' ? '签名报备' : record.reportType === 'drainage' ? '引流信息报备' : '签名+引流' },
|
||||
{ key: 'required', title: '必填', width: '90px', render: (record) => <Tag tone={record.required ? 'warning' : 'info'}>{record.required ? '是' : '否'}</Tag> },
|
||||
{ key: 'description', title: '说明', render: (record) => record.description ?? '-' },
|
||||
];
|
||||
@@ -87,26 +92,20 @@ export function AdminChannelReportPage() {
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
footer={<><Button onClick={() => setModalOpen(false)} variant="ghost">取消</Button><Button disabled={!channelId || !code || !name} onClick={createField}>保存</Button></>}
|
||||
footer={<><Button onClick={() => setModalOpen(false)} variant="ghost">取消</Button><Button disabled={!channelId || !drainageFieldId} onClick={createField}>保存</Button></>}
|
||||
onClose={() => setModalOpen(false)}
|
||||
open={modalOpen}
|
||||
title="新增通道报备字段"
|
||||
>
|
||||
<div className="admin-system-modal-form">
|
||||
<Input label="字段代码" onChange={(event) => setCode(event.target.value)} value={code} />
|
||||
<Input label="字段名称" onChange={(event) => setName(event.target.value)} value={name} />
|
||||
<Select
|
||||
label="字段类型"
|
||||
onChange={(event) => setFieldType(event.target.value)}
|
||||
options={[
|
||||
{ label: '字符串', value: 'string' },
|
||||
{ label: '数字', value: 'number' },
|
||||
{ label: '文件', value: 'file' },
|
||||
{ label: '图片', value: 'image' },
|
||||
{ label: '网址', value: 'url' },
|
||||
]}
|
||||
value={fieldType}
|
||||
label="报备字段库字段"
|
||||
onChange={(event) => setDrainageFieldId(event.target.value)}
|
||||
options={[{ label: '请选择字段', value: '' }, ...libraryFields.map((field) => ({ label: `${field.name ?? field.code}(${field.code})`, value: field.id }))]}
|
||||
value={drainageFieldId}
|
||||
/>
|
||||
<Select label="报备用途" onChange={(event) => setReportType(event.target.value as typeof reportType)} options={[{ label: '签名报备', value: 'signature' }, { label: '引流信息报备', value: 'drainage' }, { label: '签名+引流', value: 'both' }]} value={reportType} />
|
||||
<Select label="是否必填" onChange={(event) => setRequired(event.target.value === 'true')} options={[{ label: '选填', value: 'false' }, { label: '必填', value: 'true' }]} value={String(required)} />
|
||||
<Textarea label="说明" onChange={(event) => setDescription(event.target.value)} rows={4} value={description} />
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
Reference in New Issue
Block a user