import {useTranslation} from '@/i18n.ts' import {Badge, Button, Divider, Form, Popconfirm, Space, Tag, Tooltip} from 'antd' import {useAtom, useAtomValue} from 'jotai' import React, {useEffect, useMemo, useState} from 'react' import Action from '@/components/action/Action.tsx' import {BetaSchemaForm, ProColumns, ProFormColumnsType,} from '@ant-design/pro-components' import ListPageLayout from '@/layout/ListPageLayout.tsx' import {useStyle} from './style.ts' import {FilterOutlined} from '@ant-design/icons' import {getValueCount, unSetColumnRules} from '@/utils' import {Table as ProTable} from '@/components/table' import { deleteTemplateAtom, saveOrUpdateTemplateAtom, templateAtom, templateListAtom, templateSearchAtom } from "@/store/message/template.ts"; import {coverType} from "@/types/message/template.ts"; const i18nPrefix = 'mdwMessage.list' const MdwMessage = () => { const {styles, cx} = useStyle() const {t} = useTranslation() const [form] = Form.useForm() const [filterForm] = Form.useForm() const {mutate: saveOrUpdate, isPending: isSubmitting, isSuccess} = useAtomValue(saveOrUpdateTemplateAtom) const [search, setSearch] = useAtom(templateSearchAtom) const [currentTemplate, setAppPackage] = useAtom(templateAtom) const {data, isFetching, isLoading, refetch} = useAtomValue(templateListAtom) const {mutate: deleteAppPackage, isPending: isDeleting} = useAtomValue(deleteTemplateAtom) const [open, setOpen] = useState(false) const [openFilter, setFilterOpen] = useState(false) const [searchKey, setSearchKey] = useState(search?.title) const [templateField, setTemplateField] = useState([]); const [templateTitle, setTemplateTitle] = useState(''); const [templateContent, setTemplateContent] = useState(''); const [templateType, setTemplateType] = useState('') useEffect(() => { setTemplateType(currentTemplate?.type) if (form.getFieldValue('id') === 0) { setTemplateField(['name']); } else { setTemplateField(currentTemplate?.fields.split(",")); } }, [open]); const handleChange = () => { // 使用正则表达式匹配 ${var} 格式的变量 const regex = /\${\.([a-zA-Z0-9_]+)}/g; const matches = [...(templateTitle + templateContent).matchAll(regex)]; // 提取变量名 const variables = Array.from(new Set(matches.map(match => match[1]))); setTemplateField(variables); }; useEffect(() => { handleChange() }, [templateTitle, templateContent]); const handleContentChange = (e) => { const value = e.target.value; setTemplateContent(value) }; const titheHandleContentChange = (e) => { const value = e.target.value; setTemplateTitle(value) }; const typeHandlerChange = (value) => { if (value !== 'EMAIL') { setTemplateTitle('') form.setFieldsValue({'title': undefined}) } setTemplateType(value) } const drawerColumns = useMemo(() => { return [ { title: 'ID', dataIndex: 'id', hideInTable: true, hideInSearch: true, formItemProps: {hidden: true} }, { title: t(`${i18nPrefix}.columns.name`, '模板名称'), dataIndex: 'name', valueType: 'text', fieldProps: { maxLength: 50, showCount: true, }, formItemProps: { rules: [ { required: true, message: t('message.required', '模板名称必填') } ] } }, { title: t(`${i18nPrefix}.columns.type`, '模板类型'), dataIndex: 'type', valueType: 'select', fieldProps: { options: [ {label: '短信', value: 'SMS'}, {label: '邮件', value: 'EMAIL'}, {label: 'Telegram', value: 'TG'} ], allowClear: false, onChange: typeHandlerChange }, formItemProps: { rules: [ { required: true, } ] } }, { title: t(`${i18nPrefix}.columns.title`, '模板标题'), dataIndex: 'title', valueType: 'text', fieldProps: { maxLength: 100, showCount: true, onChange: titheHandleContentChange, // 监听输入事件 }, formItemProps: { tooltip: '支持邮件类型', hidden: templateType != 'EMAIL', rules: [ { required: templateType == 'EMAIL', message: t('message.required', '模板内容必填') } ] }, }, { title: t(`${i18nPrefix}.columns.content`, '模板内容'), dataIndex: 'content', valueType: 'textarea', fieldProps: { defaultValue: "你好,我叫${.name}", maxLength: 1000, showCount: true, rows: 15, onChange: handleContentChange, // 监听输入事件 }, formItemProps: { rules: [ { required: true, message: t('message.required', '模板内容必填') } ] } }, { title: t(`${i18nPrefix}.columns.fields`, '识别到的变量'), dataIndex: 'fields', renderFormItem: () => { return ( <> { templateField.map((variable, index) => ( {variable} )) } ); } }, ] as ProColumns[] }, [isDeleting, currentTemplate, search, templateField, templateType]) const columns = useMemo(() => { return [ { title: 'ID', dataIndex: 'id', hideInTable: true, hideInSearch: true, formItemProps: {hidden: true} }, { title: t(`${i18nPrefix}.columns.name`, '模板名称'), dataIndex: 'name', }, { title: t(`${i18nPrefix}.columns.type`, '模板类型'), dataIndex: 'type', render: (_, record) => { return
{coverType(record.type)}
} }, { title: t(`${i18nPrefix}.columns.title`, '模板标题'), dataIndex: 'title', }, { title: t(`${i18nPrefix}.columns.content`, '模板内容'), dataIndex: 'content', }, { title: t(`${i18nPrefix}.columns.option`, '操作'), key: 'option', valueType: 'option', fixed: 'right', render: (_, record) => [ { form.setFieldsValue(record) setOpen(true) }}>{t('actions.edit')}, , { deleteAppPackage(record.id) }} title={t('message.deleteConfirm')}> {t('actions.delete', '删除')} , ] } ] as ProColumns[] }, [isDeleting, currentTemplate, search]) useEffect(() => { setSearchKey(search?.title) filterForm.setFieldsValue(search) }, [search]) useEffect(() => { if (isSuccess) { setOpen(false) } }, [isSuccess]) return ( { setSearch(prev => ({ ...prev, title: value })) }, allowClear: true, onChange: (e) => { setSearchKey(e.target?.value) }, value: searchKey, placeholder: t(`${i18nPrefix}.placeholder`, '输入模板名称') }, actions: [ ] }} scroll={{ x: columns.length * 200, y: 'calc(100vh - 290px)' }} search={false} onRow={(record) => { return { className: cx({ // 'ant-table-row-selected': currentAppPackage?.id === record.id }), onClick: () => { setAppPackage(record) } } }} dateFormatter="string" loading={isLoading || isFetching} dataSource={data?.rows ?? []} columns={columns} options={{ reload: () => { refetch() }, }} pagination={{ total: data?.total, pageSize: search.pageSize, current: search.page, onShowSizeChange: (current: number, size: number) => { setSearch({ ...search, pageSize: size, page: current }) }, onChange: (current, pageSize) => { setSearch(prev => { return { ...prev, page: current, pageSize: pageSize, } }) }, }} /> { setOpen(open) }} loading={isSubmitting} onValuesChange={() => { }} onFinish={async (values) => { saveOrUpdate({...values, 'fields': templateField.join()}) }} columns={drawerColumns as ProFormColumnsType[]}/> { setFilterOpen(open) }} layout={'vertical'} scrollToFirstError={true} layoutType={'DrawerForm'} drawerProps={{ maskClosable: false, mask: false, }} submitter={{ searchConfig: { resetText: t(`${i18nPrefix}.filter.reset`, '清空'), submitText: t(`${i18nPrefix}.filter.submit`, '查询'), }, onReset: () => { filterForm.resetFields() }, render: (props,) => { return (
) }, }} onValuesChange={() => { }} onFinish={async (values) => { //处理,变成数组 Object.keys(values).forEach(key => { if (typeof values[key] === 'string' && values[key].includes(',')) { values[key] = values[key].split(',') } }) setSearch(values) }} columns={unSetColumnRules(columns.filter(item => !item.hideInSearch)) as ProFormColumnsType[]}/>
) } export default MdwMessage