问题分类取字典
This commit is contained in:
@ -9,6 +9,7 @@ import {
|
||||
} from '@ant-design/icons';
|
||||
import { getDownloadList, updateDownloadStatus, batchDeleteDownload } from '@/servers/api/download';
|
||||
import DownloadManageForm from './DownloadManageForm';
|
||||
import uiconfig from '@/uiconfig';
|
||||
import {
|
||||
DownloadStatus,
|
||||
DownloadIsTop,
|
||||
@ -499,7 +500,7 @@ const DownloadManage: React.FC = () => {
|
||||
}
|
||||
open={modalVisible}
|
||||
onCancel={handleModalCancel}
|
||||
width={600}
|
||||
width={uiconfig.Modal.width}
|
||||
maskClosable={false}
|
||||
destroyOnClose
|
||||
footer={null}
|
||||
|
@ -5,6 +5,8 @@ import WangEditor from '@/components/WangEidtor/WangEidtor';
|
||||
import { TopStatus, EnglishSetting, categoryOptions } from '@/dicts/helpManageDict';
|
||||
import { addHelp, updateHelp, getHelpDetail } from '@/servers/api/help';
|
||||
import styles from './helpManage.less';
|
||||
import { getDictList } from '@/servers/api/dicts';
|
||||
import type { DictItem } from '@/servers/api/dicts';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
const { Option } = Select;
|
||||
@ -20,9 +22,15 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
const [activeTabKey, setActiveTabKey] = useState<string>('zh');
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const intl = useIntl();
|
||||
const [typeList, setTypeList] = useState<DictItem[]>([]);
|
||||
|
||||
// 获取详情数据
|
||||
useEffect(() => {
|
||||
getDictList('help_center').then((res) => {
|
||||
if (res.code === 200 && res.success) {
|
||||
setTypeList(res.data);
|
||||
}
|
||||
});
|
||||
const fetchHelpDetail = async (helpId: string) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
@ -40,7 +48,9 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
answerContentEn: detail.answerContentNe,
|
||||
});
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'helpManage.fetchDetailFailed' }));
|
||||
message.error(
|
||||
response.message || intl.formatMessage({ id: 'helpManage.fetchDetailFailed' }),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取帮助详情失败:', error);
|
||||
@ -76,9 +86,17 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
const fieldName = firstError.name[0];
|
||||
|
||||
// 根据字段名判断应该切换到哪个Tab
|
||||
if (fieldName === 'titleZh' || fieldName === 'contentZh' || fieldName === 'answerContentZh') {
|
||||
if (
|
||||
fieldName === 'titleZh' ||
|
||||
fieldName === 'contentZh' ||
|
||||
fieldName === 'answerContentZh'
|
||||
) {
|
||||
setActiveTabKey('zh');
|
||||
} else if (fieldName === 'titleEn' || fieldName === 'contentEn' || fieldName === 'answerContentEn') {
|
||||
} else if (
|
||||
fieldName === 'titleEn' ||
|
||||
fieldName === 'contentEn' ||
|
||||
fieldName === 'answerContentEn'
|
||||
) {
|
||||
setActiveTabKey('en');
|
||||
}
|
||||
}
|
||||
@ -110,14 +128,19 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
}
|
||||
|
||||
if (response && response.success) {
|
||||
message.success(isEdit
|
||||
? intl.formatMessage({ id: 'helpManage.updateSuccess' })
|
||||
: intl.formatMessage({ id: 'helpManage.addSuccess' }));
|
||||
message.success(
|
||||
isEdit
|
||||
? intl.formatMessage({ id: 'helpManage.updateSuccess' })
|
||||
: intl.formatMessage({ id: 'helpManage.addSuccess' }),
|
||||
);
|
||||
onSuccess(); // 回调父组件
|
||||
} else {
|
||||
message.error(response.message || (isEdit
|
||||
? intl.formatMessage({ id: 'helpManage.updateFailed' })
|
||||
: intl.formatMessage({ id: 'helpManage.addFailed' })));
|
||||
message.error(
|
||||
response.message ||
|
||||
(isEdit
|
||||
? intl.formatMessage({ id: 'helpManage.updateFailed' })
|
||||
: intl.formatMessage({ id: 'helpManage.addFailed' })),
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('表单验证或提交失败:', error);
|
||||
@ -130,38 +153,63 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
return (
|
||||
<div className={styles.helpForm}>
|
||||
<Form form={form} layout="vertical" name="helpForm" preserve={false}>
|
||||
<Form.Item name="isTop" label={intl.formatMessage({ id: 'helpManage.form.isTop' })} valuePropName="checked">
|
||||
<Form.Item
|
||||
name="isTop"
|
||||
label={intl.formatMessage({ id: 'helpManage.form.isTop' })}
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="type"
|
||||
label={intl.formatMessage({ id: 'helpManage.form.category' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'helpManage.form.categoryRequired' }) }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'helpManage.form.categoryRequired' }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select placeholder={intl.formatMessage({ id: 'helpManage.form.categoryPlaceholder' })}>
|
||||
{categoryOptions.map(option => (
|
||||
<Option key={option.value} value={option.value}>
|
||||
{typeof option.label === 'function' ? option.label() : option.label}
|
||||
{typeList.map((option) => (
|
||||
<Option key={option.code} value={option.code}>
|
||||
{option.dicName}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Tabs activeKey={activeTabKey} onChange={handleTabChange}>
|
||||
<TabPane tab={intl.formatMessage({ id: 'helpManage.form.chineseTab' })} key="zh" forceRender={true}>
|
||||
<TabPane
|
||||
tab={intl.formatMessage({ id: 'helpManage.form.chineseTab' })}
|
||||
key="zh"
|
||||
forceRender={true}
|
||||
>
|
||||
<Form.Item
|
||||
name="titleZh"
|
||||
label={intl.formatMessage({ id: 'helpManage.form.titleZh' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'helpManage.form.titleZhRequired' }) }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'helpManage.form.titleZhRequired' }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'helpManage.form.titleZhPlaceholder' })} />
|
||||
<Input
|
||||
placeholder={intl.formatMessage({ id: 'helpManage.form.titleZhPlaceholder' })}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="contentZh"
|
||||
label={intl.formatMessage({ id: 'helpManage.form.contentZh' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'helpManage.form.contentZhRequired' }) }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'helpManage.form.contentZhRequired' }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<WangEditor
|
||||
language="zh-CN"
|
||||
@ -177,23 +225,41 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
<WangEditor
|
||||
language="zh-CN"
|
||||
height="200px"
|
||||
placeholder={intl.formatMessage({ id: 'helpManage.form.answerContentZhPlaceholder' })}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'helpManage.form.answerContentZhPlaceholder',
|
||||
})}
|
||||
/>
|
||||
</Form.Item>
|
||||
</TabPane>
|
||||
<TabPane tab={intl.formatMessage({ id: 'helpManage.form.englishTab' })} key="en" forceRender={true}>
|
||||
<TabPane
|
||||
tab={intl.formatMessage({ id: 'helpManage.form.englishTab' })}
|
||||
key="en"
|
||||
forceRender={true}
|
||||
>
|
||||
<Form.Item
|
||||
name="titleEn"
|
||||
label={intl.formatMessage({ id: 'helpManage.form.titleEn' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'helpManage.form.titleEnRequired' }) }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'helpManage.form.titleEnRequired' }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'helpManage.form.titleEnPlaceholder' })} />
|
||||
<Input
|
||||
placeholder={intl.formatMessage({ id: 'helpManage.form.titleEnPlaceholder' })}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="contentEn"
|
||||
label={intl.formatMessage({ id: 'helpManage.form.contentEn' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'helpManage.form.contentEnRequired' }) }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'helpManage.form.contentEnRequired' }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<WangEditor
|
||||
language="en"
|
||||
@ -209,7 +275,9 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
<WangEditor
|
||||
language="en"
|
||||
height="200px"
|
||||
placeholder={intl.formatMessage({ id: 'helpManage.form.answerContentEnPlaceholder' })}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'helpManage.form.answerContentEnPlaceholder',
|
||||
})}
|
||||
/>
|
||||
</Form.Item>
|
||||
</TabPane>
|
||||
@ -219,11 +287,7 @@ const HelpManageForm: React.FC<HelpManageFormProps> = ({ id, isEdit, onSuccess }
|
||||
<Button onClick={() => onSuccess()}>
|
||||
{intl.formatMessage({ id: 'helpManage.cancel' })}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
loading={loading}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
<Button type="primary" loading={loading} onClick={handleSubmit}>
|
||||
{intl.formatMessage({ id: 'helpManage.submit' })}
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -1,22 +1,27 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Descriptions, Divider, Card, Tag } from 'antd';
|
||||
import { useIntl } from 'umi';
|
||||
import { HelpStatus, HelpStatusText, HelpStatusColor } from '@/dicts/helpManageDict';
|
||||
import styles from './helpManage.less';
|
||||
import { getDictList } from '@/servers/api/dicts';
|
||||
import type { DictItem } from '@/servers/api/dicts';
|
||||
|
||||
interface HelpManageInfoProps {
|
||||
data: API.HelpRecord | null;
|
||||
typeList: DictItem[];
|
||||
}
|
||||
|
||||
const HelpManageInfo: React.FC<HelpManageInfoProps> = ({ data }) => {
|
||||
const HelpManageInfo: React.FC<HelpManageInfoProps> = ({ data, typeList }) => {
|
||||
const intl = useIntl();
|
||||
|
||||
// 获取状态标签
|
||||
const getStatusTag = (status: string) => {
|
||||
const statusKey = status as keyof typeof HelpStatusText;
|
||||
const color = HelpStatusColor[statusKey] || 'default';
|
||||
const getText = HelpStatusText[statusKey];
|
||||
const text = typeof getText === 'function' ? getText() : intl.formatMessage({ id: 'helpManage.status.unknown' });
|
||||
const text =
|
||||
typeof getText === 'function'
|
||||
? getText()
|
||||
: intl.formatMessage({ id: 'helpManage.status.unknown' });
|
||||
return <Tag color={color}>{text}</Tag>;
|
||||
};
|
||||
|
||||
@ -29,12 +34,15 @@ const HelpManageInfo: React.FC<HelpManageInfoProps> = ({ data }) => {
|
||||
{data.title}
|
||||
</Descriptions.Item>
|
||||
{data.titleEn && (
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'helpManage.detail.titleEn' })} span={2}>
|
||||
<Descriptions.Item
|
||||
label={intl.formatMessage({ id: 'helpManage.detail.titleEn' })}
|
||||
span={2}
|
||||
>
|
||||
{data.titleEn}
|
||||
</Descriptions.Item>
|
||||
)}
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'helpManage.detail.category' })}>
|
||||
{data.type}
|
||||
{typeList.find((item) => item.code == data.type) ? typeList.find((item) => item.code == data.type).dicName : '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'helpManage.detail.isTop' })}>
|
||||
{data.isTop === '1'
|
||||
@ -51,40 +59,60 @@ const HelpManageInfo: React.FC<HelpManageInfoProps> = ({ data }) => {
|
||||
{data.createTime}
|
||||
</Descriptions.Item>
|
||||
{data.updateTime && (
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'helpManage.detail.updateTime' })} span={2}>
|
||||
<Descriptions.Item
|
||||
label={intl.formatMessage({ id: 'helpManage.detail.updateTime' })}
|
||||
span={2}
|
||||
>
|
||||
{data.updateTime}
|
||||
</Descriptions.Item>
|
||||
)}
|
||||
</Descriptions>
|
||||
|
||||
<Divider orientation="left">{intl.formatMessage({ id: 'helpManage.detail.contentZh' })}</Divider>
|
||||
<Divider orientation="left">
|
||||
{intl.formatMessage({ id: 'helpManage.detail.contentZh' })}
|
||||
</Divider>
|
||||
<Card size="small" bordered={false} className={styles.contentCard}>
|
||||
<div className={styles.helpContent} dangerouslySetInnerHTML={{ __html: data.content }} />
|
||||
</Card>
|
||||
|
||||
{data.contentEn && (
|
||||
<>
|
||||
<Divider orientation="left">{intl.formatMessage({ id: 'helpManage.detail.contentEn' })}</Divider>
|
||||
<Divider orientation="left">
|
||||
{intl.formatMessage({ id: 'helpManage.detail.contentEn' })}
|
||||
</Divider>
|
||||
<Card size="small" bordered={false} className={styles.contentCard}>
|
||||
<div className={styles.helpContent} dangerouslySetInnerHTML={{ __html: data.contentEn }} />
|
||||
<div
|
||||
className={styles.helpContent}
|
||||
dangerouslySetInnerHTML={{ __html: data.contentEn }}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
|
||||
{data.answerContent && (
|
||||
<>
|
||||
<Divider orientation="left">{intl.formatMessage({ id: 'helpManage.detail.answerContentZh' })}</Divider>
|
||||
<Divider orientation="left">
|
||||
{intl.formatMessage({ id: 'helpManage.detail.answerContentZh' })}
|
||||
</Divider>
|
||||
<Card size="small" bordered={false} className={styles.contentCard}>
|
||||
<div className={styles.helpContent} dangerouslySetInnerHTML={{ __html: data.answerContent }} />
|
||||
<div
|
||||
className={styles.helpContent}
|
||||
dangerouslySetInnerHTML={{ __html: data.answerContent }}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
|
||||
{data.answerContentNe && (
|
||||
<>
|
||||
<Divider orientation="left">{intl.formatMessage({ id: 'helpManage.detail.answerContentEn' })}</Divider>
|
||||
<Divider orientation="left">
|
||||
{intl.formatMessage({ id: 'helpManage.detail.answerContentEn' })}
|
||||
</Divider>
|
||||
<Card size="small" bordered={false} className={styles.contentCard}>
|
||||
<div className={styles.helpContent} dangerouslySetInnerHTML={{ __html: data.answerContentNe }} />
|
||||
<div
|
||||
className={styles.helpContent}
|
||||
dangerouslySetInnerHTML={{ __html: data.answerContentNe }}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
|
@ -63,7 +63,7 @@ const HelpManage: React.FC = () => {
|
||||
showTotal: (total: number) => `共 ${total} 条记录`,
|
||||
});
|
||||
const [searchParams, setSearchParams] = useState<SearchParams>({});
|
||||
const [typeList, setTypeList] = useState<DictItem[]>([]);
|
||||
const [typeList, setTypeList] = useState<DictItem[]>([]);
|
||||
|
||||
// 获取帮助中心列表数据
|
||||
const fetchHelpList = (
|
||||
@ -111,11 +111,11 @@ const HelpManage: React.FC = () => {
|
||||
|
||||
// 首次加载时获取数据
|
||||
useEffect(() => {
|
||||
getDictList('download_section').then((res) => {
|
||||
if (res.code === 200 && res.success) {
|
||||
setTypeList(res.data);
|
||||
}
|
||||
});
|
||||
getDictList('help_center').then((res) => {
|
||||
if (res.code === 200 && res.success) {
|
||||
setTypeList(res.data);
|
||||
}
|
||||
});
|
||||
fetchHelpList(1, pagination.pageSize, {});
|
||||
}, []);
|
||||
|
||||
@ -358,6 +358,10 @@ const HelpManage: React.FC = () => {
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
align: 'center' as const,
|
||||
render: (type: string) => {
|
||||
const dictItem = typeList.find((item) => item.code === type);
|
||||
return dictItem ? dictItem.dicName : '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'helpManage.date' }),
|
||||
@ -434,9 +438,9 @@ const HelpManage: React.FC = () => {
|
||||
allowClear
|
||||
style={{ width: 150 }}
|
||||
>
|
||||
{categoryOptions.map((option) => (
|
||||
<Option key={option.value} value={option.value}>
|
||||
{typeof option.label === 'function' ? option.label() : option.label}
|
||||
{typeList.map((option) => (
|
||||
<Option key={option.code} value={option.code}>
|
||||
{option.dicName}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
@ -526,7 +530,7 @@ const HelpManage: React.FC = () => {
|
||||
maskClosable={false}
|
||||
>
|
||||
{isViewMode ? (
|
||||
<HelpManageInfo data={viewData} />
|
||||
<HelpManageInfo data={viewData} typeList={typeList} />
|
||||
) : (
|
||||
<HelpManageForm id={currentId} isEdit={isEdit} onSuccess={handleModalCancel} />
|
||||
)}
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
updateNoticeTopStatus,
|
||||
getNoticeDetail,
|
||||
} from '@/servers/api/notice';
|
||||
import styles from './noticeManage.less';
|
||||
import uiconfig from '@/uiconfig';
|
||||
import {
|
||||
NoticeStatus,
|
||||
NoticeStatusText,
|
||||
@ -587,7 +587,7 @@ const NoticeManage: React.FC = () => {
|
||||
}
|
||||
open={modalVisible}
|
||||
onCancel={handleModalCancel}
|
||||
width={900}
|
||||
width={uiconfig.Modal.width}
|
||||
maskClosable={false}
|
||||
destroyOnClose
|
||||
footer={
|
||||
|
@ -142,6 +142,7 @@ const PolicyManageForm: React.FC<PolicyManageFormProps> = ({ id, isEdit, onSucce
|
||||
|
||||
<Form.Item
|
||||
name="contentZh"
|
||||
valuePropName="value"
|
||||
label={intl.formatMessage({ id: 'policyManage.form.contentZh' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'policyManage.form.contentZhRequired' }) }]}
|
||||
>
|
||||
@ -163,6 +164,7 @@ const PolicyManageForm: React.FC<PolicyManageFormProps> = ({ id, isEdit, onSucce
|
||||
|
||||
<Form.Item
|
||||
name="contentEn"
|
||||
valuePropName="value"
|
||||
label={intl.formatMessage({ id: 'policyManage.form.contentEn' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'policyManage.form.contentEnRequired' }) }]}
|
||||
>
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
TablePaginationConfig,
|
||||
Tabs,
|
||||
} from 'antd';
|
||||
import uiconfig from '@/uiconfig';
|
||||
import {
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
@ -476,7 +477,7 @@ const PolicyManage: React.FC = () => {
|
||||
: intl.formatMessage({ id: 'policyManage.form.add' })}
|
||||
open={modalVisible}
|
||||
onCancel={handleModalCancel}
|
||||
width={900}
|
||||
width={uiconfig.Modal.width}
|
||||
maskClosable={false}
|
||||
destroyOnClose
|
||||
footer={
|
||||
|
@ -16,26 +16,29 @@ import {
|
||||
TopStatusText,
|
||||
TopStatusColor
|
||||
} from '@/dicts/userQuestionDict';
|
||||
import type { DictItem } from '@/servers/api/dicts';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
interface QuestionModalProps {
|
||||
visible: boolean;
|
||||
open: boolean;
|
||||
onCancel: () => void;
|
||||
question: any;
|
||||
mode: 'view' | 'answer' | 'edit';
|
||||
onSuccess: () => void;
|
||||
typeList: DictItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 问题模态框组件 - 整合了查看详情、回答问题和编辑回答功能
|
||||
*/
|
||||
const QuestionModal: React.FC<QuestionModalProps> = ({
|
||||
visible,
|
||||
open,
|
||||
onCancel,
|
||||
question,
|
||||
mode,
|
||||
onSuccess
|
||||
onSuccess,
|
||||
typeList
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm();
|
||||
@ -170,7 +173,7 @@ const QuestionModal: React.FC<QuestionModalProps> = ({
|
||||
{question.title}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.category' })}>
|
||||
{question.type}
|
||||
{typeList.find((item) => item.code === question.type)?.dicName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.askTime' })}>
|
||||
{question.askTime}
|
||||
@ -252,7 +255,7 @@ const QuestionModal: React.FC<QuestionModalProps> = ({
|
||||
{question.title}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.category' })}>
|
||||
{question.type}
|
||||
{typeList.find((item) => item.code === question.type)?.dicName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.askTime' })}>
|
||||
{question.askTime}
|
||||
@ -357,7 +360,7 @@ const QuestionModal: React.FC<QuestionModalProps> = ({
|
||||
return (
|
||||
<Modal
|
||||
title={getModalTitle()}
|
||||
open={visible}
|
||||
open={open}
|
||||
onCancel={onCancel}
|
||||
width={800}
|
||||
footer={renderFooter()}
|
||||
|
@ -1,108 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Descriptions, Divider, Card, Tag } from 'antd';
|
||||
import { useIntl, FormattedMessage } from 'umi';
|
||||
import styles from './userQuestionManage.less';
|
||||
import {
|
||||
PublishStatus,
|
||||
PublishStatusText,
|
||||
PublishStatusColor,
|
||||
TopStatus,
|
||||
TopStatusText,
|
||||
TopStatusColor
|
||||
} from '@/dicts/userQuestionDict';
|
||||
|
||||
interface QuestionDetailProps {
|
||||
question: any; // 可以改为具体的类型
|
||||
}
|
||||
|
||||
/**
|
||||
* 问题详情查看组件
|
||||
*/
|
||||
const QuestionViewDetail: React.FC<QuestionDetailProps> = ({ question }) => {
|
||||
const intl = useIntl();
|
||||
|
||||
if (!question) return null;
|
||||
|
||||
// 获取发布状态标签
|
||||
const getPublishTag = (isPublished: number) => {
|
||||
return isPublished === 1 ?
|
||||
<Tag color="green">{PublishStatusText[PublishStatus.YES]()}</Tag> :
|
||||
<Tag color="orange">{PublishStatusText[PublishStatus.NO]()}</Tag>;
|
||||
};
|
||||
|
||||
// 获取置顶状态标签
|
||||
const getTopTag = (isTop: number) => {
|
||||
return isTop === 1 ?
|
||||
<Tag color="red">{TopStatusText[TopStatus.YES]()}</Tag> :
|
||||
<Tag color="default">{TopStatusText[TopStatus.NO]()}</Tag>;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.questionDetailView}>
|
||||
<Descriptions bordered column={2} size="small">
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.title' })} span={2}>
|
||||
{question.title}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.category' })}>
|
||||
{question.type}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.askTime' })}>
|
||||
{question.askTime}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.asker' })}>
|
||||
{question.userName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.company' })}>
|
||||
{question.companyName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.account' })}>
|
||||
{question.fullName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.contact' })}>
|
||||
{question.contactDetails}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.email' })}>
|
||||
{question.email}
|
||||
</Descriptions.Item>
|
||||
|
||||
{/* 只有已回答的问题才会显示以下字段 */}
|
||||
{question.isAnswer === '1' && (
|
||||
<>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.publishStatus' })}>
|
||||
{getPublishTag(question.isPublished)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.topStatus' })}>
|
||||
{getTopTag(question.isTop)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.answerTime' })}>
|
||||
{question.answerTime}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={intl.formatMessage({ id: 'questionDetail.respondent' })}>
|
||||
{question.answerBy || '-'}
|
||||
</Descriptions.Item>
|
||||
</>
|
||||
)}
|
||||
</Descriptions>
|
||||
|
||||
<Divider orientation="left">{intl.formatMessage({ id: 'questionDetail.questionContent' })}</Divider>
|
||||
<Card size="small" bordered={false} className={styles.contentCard}>
|
||||
<div className={styles.questionContent}>
|
||||
{question.content}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{question.answerContent && (
|
||||
<>
|
||||
<Divider orientation="left">{intl.formatMessage({ id: 'questionDetail.answerContent' })}</Divider>
|
||||
<Card size="small" bordered={false} className={styles.contentCard}>
|
||||
<div className={styles.answerContent}>
|
||||
{question.answerContent}
|
||||
</div>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default QuestionViewDetail;
|
@ -1,12 +1,23 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useIntl, FormattedMessage } from 'umi';
|
||||
import { Button, Table, Modal, message, Input, Form, Tooltip, Tag, Space, Switch, TablePaginationConfig, Select } from 'antd';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
SearchOutlined
|
||||
} from '@ant-design/icons';
|
||||
Button,
|
||||
Table,
|
||||
Modal,
|
||||
message,
|
||||
Input,
|
||||
Form,
|
||||
Tooltip,
|
||||
Tag,
|
||||
Space,
|
||||
Switch,
|
||||
TablePaginationConfig,
|
||||
Select,
|
||||
} from 'antd';
|
||||
import { DeleteOutlined, ExclamationCircleOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import styles from './userQuestionManage.less';
|
||||
import { getDictList } from '@/servers/api/dicts';
|
||||
import type { DictItem } from '@/servers/api/dicts';
|
||||
// 引入封装的组件
|
||||
import QuestionModal from './QuestionModal';
|
||||
// 引入API
|
||||
@ -14,15 +25,16 @@ import {
|
||||
getQuestionPage,
|
||||
getQuestionDetail,
|
||||
deleteQuestion,
|
||||
batchDeleteQuestion
|
||||
batchDeleteQuestion,
|
||||
} from '@/servers/api/userQuestion';
|
||||
// 引入字典
|
||||
import {
|
||||
QuestionCategoryOptions,
|
||||
AnswerStatus,
|
||||
AnswerStatusText,
|
||||
AnswerStatusColor
|
||||
AnswerStatusColor,
|
||||
} from '@/dicts/userQuestionDict';
|
||||
import { render } from 'react-dom';
|
||||
|
||||
const { confirm } = Modal;
|
||||
const { Option } = Select;
|
||||
@ -49,6 +61,7 @@ const ReadQuestionManage: React.FC = () => {
|
||||
const [modalVisible, setModalVisible] = useState<boolean>(false);
|
||||
const [currentQuestion, setCurrentQuestion] = useState<QuestionItemType | null>(null);
|
||||
const [modalMode, setModalMode] = useState<'view' | 'edit'>('view');
|
||||
const [typeList, setTypeList] = useState<DictItem[]>([]);
|
||||
const [pagination, setPagination] = useState<TablePaginationConfig>({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@ -58,7 +71,7 @@ const ReadQuestionManage: React.FC = () => {
|
||||
showTotal: (total: number) => `共 ${total} 条记录`,
|
||||
});
|
||||
const [searchParams, setSearchParams] = useState<SearchParams>({
|
||||
isAnswer: 1 // 默认已回答
|
||||
isAnswer: 1, // 默认已回答
|
||||
});
|
||||
|
||||
// 获取已回答的用户提问列表数据
|
||||
@ -115,6 +128,11 @@ const ReadQuestionManage: React.FC = () => {
|
||||
// 首次加载时获取数据
|
||||
useEffect(() => {
|
||||
fetchQuestionList(pagination.current, pagination.pageSize);
|
||||
getDictList('help_center').then((res) => {
|
||||
if (res.code === 200 && res.success) {
|
||||
setTypeList(res.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
// 处理搜索
|
||||
@ -123,7 +141,7 @@ const ReadQuestionManage: React.FC = () => {
|
||||
...values,
|
||||
isAnswer: 1,
|
||||
// 如果设置了answerStatus为已回答,则需要特殊处理
|
||||
...values.answerStatus === AnswerStatus.ANSWERED ? { hasAnswerContent: 1 } : {}
|
||||
...(values.answerStatus === AnswerStatus.ANSWERED ? { hasAnswerContent: 1 } : {}),
|
||||
};
|
||||
fetchQuestionList(1, pagination.pageSize, params);
|
||||
};
|
||||
@ -136,7 +154,7 @@ const ReadQuestionManage: React.FC = () => {
|
||||
const detailData = response.data;
|
||||
const formattedDetail = {
|
||||
...detailData,
|
||||
key: detailData.id
|
||||
key: detailData.id,
|
||||
};
|
||||
|
||||
setCurrentQuestion(formattedDetail);
|
||||
@ -178,7 +196,9 @@ const ReadQuestionManage: React.FC = () => {
|
||||
message.success(intl.formatMessage({ id: 'readQuestion.deleteSuccess' }));
|
||||
fetchQuestionList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'readQuestion.deleteFailed' }));
|
||||
message.error(
|
||||
response.message || intl.formatMessage({ id: 'readQuestion.deleteFailed' }),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除问题失败:', error);
|
||||
@ -216,7 +236,9 @@ const ReadQuestionManage: React.FC = () => {
|
||||
message.success(intl.formatMessage({ id: 'readQuestion.batchDeleteSuccess' }));
|
||||
fetchQuestionList(pagination.current, pagination.pageSize, searchParams);
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'readQuestion.batchDeleteFailed' }));
|
||||
message.error(
|
||||
response.message || intl.formatMessage({ id: 'readQuestion.batchDeleteFailed' }),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('批量删除失败:', error);
|
||||
@ -241,17 +263,25 @@ const ReadQuestionManage: React.FC = () => {
|
||||
// 获取回答状态标签
|
||||
const getAnswerTag = (record: QuestionItemType) => {
|
||||
if (record.answerContent && record.answerContent.trim() !== '') {
|
||||
return <Tag color={AnswerStatusColor[AnswerStatus.ANSWERED]}>{AnswerStatusText[AnswerStatus.ANSWERED]()}</Tag>;
|
||||
return (
|
||||
<Tag color={AnswerStatusColor[AnswerStatus.ANSWERED]}>
|
||||
{AnswerStatusText[AnswerStatus.ANSWERED]()}
|
||||
</Tag>
|
||||
);
|
||||
} else {
|
||||
return <Tag color={AnswerStatusColor[AnswerStatus.READ]}>{AnswerStatusText[AnswerStatus.READ]()}</Tag>;
|
||||
return (
|
||||
<Tag color={AnswerStatusColor[AnswerStatus.READ]}>
|
||||
{AnswerStatusText[AnswerStatus.READ]()}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取置顶状态标签
|
||||
const getTopTag = (isTop: number) => {
|
||||
return isTop === 1 ?
|
||||
<Tag color="red">{intl.formatMessage({ id: 'userQuestion.top' })}</Tag> :
|
||||
null;
|
||||
return isTop === 1 ? (
|
||||
<Tag color="red">{intl.formatMessage({ id: 'userQuestion.top' })}</Tag>
|
||||
) : null;
|
||||
};
|
||||
|
||||
// 表格列定义
|
||||
@ -283,6 +313,10 @@ const ReadQuestionManage: React.FC = () => {
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
align: 'center' as const,
|
||||
render: (type: string) => {
|
||||
const dictItem = typeList.find((item) => item.code === type);
|
||||
return dictItem ? dictItem.dicName : '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'readQuestion.asker' }),
|
||||
@ -353,7 +387,9 @@ const ReadQuestionManage: React.FC = () => {
|
||||
render: (_: unknown, record: QuestionItemType) => (
|
||||
<Space>
|
||||
{getAnswerTag(record)}
|
||||
{record.isPublished === 1 && <Tag color="green">{intl.formatMessage({ id: 'userQuestion.published' })}</Tag>}
|
||||
{record.isPublished === 1 && (
|
||||
<Tag color="green">{intl.formatMessage({ id: 'userQuestion.published' })}</Tag>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
@ -380,9 +416,9 @@ const ReadQuestionManage: React.FC = () => {
|
||||
|
||||
// 获取分类选项,处理为下拉框选项
|
||||
const getCategoryOptions = () => {
|
||||
return QuestionCategoryOptions.map(option => (
|
||||
<Option key={option.value} value={option.value}>
|
||||
{typeof option.label === 'function' ? option.label() : option.label}
|
||||
return typeList.map((option) => (
|
||||
<Option key={option.code} value={option.code}>
|
||||
{option.dicName}
|
||||
</Option>
|
||||
));
|
||||
};
|
||||
@ -398,17 +434,33 @@ const ReadQuestionManage: React.FC = () => {
|
||||
className="filter-form"
|
||||
>
|
||||
<Form.Item name="title" label={intl.formatMessage({ id: 'readQuestion.questionTitle' })}>
|
||||
<Input placeholder={intl.formatMessage({ id: 'readQuestion.questionPlaceholder' })} allowClear />
|
||||
<Input
|
||||
placeholder={intl.formatMessage({ id: 'readQuestion.questionPlaceholder' })}
|
||||
allowClear
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="type" label={intl.formatMessage({ id: 'readQuestion.category' })}>
|
||||
<Select placeholder={intl.formatMessage({ id: 'readQuestion.selectCategory' })} allowClear style={{ width: 150 }}>
|
||||
<Select
|
||||
placeholder={intl.formatMessage({ id: 'readQuestion.selectCategory' })}
|
||||
allowClear
|
||||
style={{ width: 150 }}
|
||||
>
|
||||
{getCategoryOptions()}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item name="answerStatus" label={intl.formatMessage({ id: 'readQuestion.answerStatus' })}>
|
||||
<Select placeholder={intl.formatMessage({ id: 'readQuestion.selectAnswerStatus' })} allowClear style={{ width: 120 }}>
|
||||
<Form.Item
|
||||
name="answerStatus"
|
||||
label={intl.formatMessage({ id: 'readQuestion.answerStatus' })}
|
||||
>
|
||||
<Select
|
||||
placeholder={intl.formatMessage({ id: 'readQuestion.selectAnswerStatus' })}
|
||||
allowClear
|
||||
style={{ width: 120 }}
|
||||
>
|
||||
<Option value={AnswerStatus.READ}>{AnswerStatusText[AnswerStatus.READ]()}</Option>
|
||||
<Option value={AnswerStatus.ANSWERED}>{AnswerStatusText[AnswerStatus.ANSWERED]()}</Option>
|
||||
<Option value={AnswerStatus.ANSWERED}>
|
||||
{AnswerStatusText[AnswerStatus.ANSWERED]()}
|
||||
</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item className="filter-btns">
|
||||
@ -430,17 +482,15 @@ const ReadQuestionManage: React.FC = () => {
|
||||
</Form>
|
||||
|
||||
<div className="right-buttons">
|
||||
<Button
|
||||
danger
|
||||
onClick={handleBatchDelete}
|
||||
disabled={!hasSelected}
|
||||
loading={loading}
|
||||
>
|
||||
<Button danger onClick={handleBatchDelete} disabled={!hasSelected} loading={loading}>
|
||||
{intl.formatMessage({ id: 'readQuestion.batchDelete' })}
|
||||
</Button>
|
||||
{hasSelected && (
|
||||
<span className="selected-count">
|
||||
{intl.formatMessage({ id: 'readQuestion.selectedCount' }, { count: selectedRowKeys.length })}
|
||||
{intl.formatMessage(
|
||||
{ id: 'readQuestion.selectedCount' },
|
||||
{ count: selectedRowKeys.length },
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -464,6 +514,7 @@ const ReadQuestionManage: React.FC = () => {
|
||||
onCancel={() => setModalVisible(false)}
|
||||
question={currentQuestion}
|
||||
mode={modalMode}
|
||||
typeList={typeList}
|
||||
onSuccess={() => fetchQuestionList(pagination.current, pagination.pageSize, searchParams)}
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,14 +1,23 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useIntl, FormattedMessage } from 'umi';
|
||||
import { Button, Table, Modal, message, Input, Form, Tooltip, Tag, Space, TablePaginationConfig } from 'antd';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
SearchOutlined
|
||||
} from '@ant-design/icons';
|
||||
Button,
|
||||
Table,
|
||||
Modal,
|
||||
message,
|
||||
Input,
|
||||
Form,
|
||||
Tooltip,
|
||||
Tag,
|
||||
Space,
|
||||
TablePaginationConfig,
|
||||
} from 'antd';
|
||||
import { DeleteOutlined, ExclamationCircleOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import styles from './userQuestionManage.less';
|
||||
// 引入封装的组件
|
||||
import QuestionModal from './QuestionModal';
|
||||
import { getDictList } from '@/servers/api/dicts';
|
||||
import type { DictItem } from '@/servers/api/dicts';
|
||||
// 引入API
|
||||
import {
|
||||
getQuestionPage,
|
||||
@ -16,7 +25,7 @@ import {
|
||||
markQuestionSeen,
|
||||
markQuestionSeeEdit,
|
||||
deleteQuestion,
|
||||
batchDeleteQuestion
|
||||
batchDeleteQuestion,
|
||||
} from '@/servers/api/userQuestion';
|
||||
// 引入字典
|
||||
import { QuestionCategoryOptions } from '@/dicts/userQuestionDict';
|
||||
@ -43,6 +52,7 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [answerModalVisible, setAnswerModalVisible] = useState<boolean>(false);
|
||||
const [currentQuestion, setCurrentQuestion] = useState<QuestionItemType | null>(null);
|
||||
const [typeList, setTypeList] = useState<DictItem[]>([]);
|
||||
const [pagination, setPagination] = useState<TablePaginationConfig>({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@ -52,7 +62,7 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
showTotal: (total: number) => `共 ${total} 条记录`,
|
||||
});
|
||||
const [searchParams, setSearchParams] = useState<SearchParams>({
|
||||
isAnswer: 0 // 默认未回答
|
||||
isAnswer: 0, // 默认未回答
|
||||
});
|
||||
|
||||
// 获取未回答的用户提问列表数据
|
||||
@ -89,8 +99,8 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
}));
|
||||
|
||||
setQuestionData(formattedData);
|
||||
setPagination({
|
||||
...pagination,
|
||||
setPagination({
|
||||
...pagination,
|
||||
current: currentPage,
|
||||
pageSize: size,
|
||||
total,
|
||||
@ -102,12 +112,17 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
console.error('获取问题列表失败:', error);
|
||||
message.error(intl.formatMessage({ id: 'unreadQuestion.fetchFailed' }));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 首次加载时获取数据
|
||||
useEffect(() => {
|
||||
getDictList('help_center').then((res) => {
|
||||
if (res.code === 200 && res.success) {
|
||||
setTypeList(res.data);
|
||||
}
|
||||
});
|
||||
fetchQuestionList(pagination.current, pagination.pageSize);
|
||||
}, []);
|
||||
|
||||
@ -124,8 +139,8 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
const response = await markQuestionSeeEdit(record.id);
|
||||
if (!response || !response.success) {
|
||||
message.error(response?.message || intl.formatMessage({ id: 'userQuestion.replyFailed' }));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取问题详情
|
||||
const detailResponse = await getQuestionDetail(record.id);
|
||||
@ -133,13 +148,15 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
const detailData = detailResponse.data;
|
||||
const formattedDetail = {
|
||||
...detailData,
|
||||
key: detailData.id
|
||||
key: detailData.id,
|
||||
};
|
||||
|
||||
setCurrentQuestion(formattedDetail);
|
||||
setAnswerModalVisible(true);
|
||||
} else {
|
||||
message.error(detailResponse.message || intl.formatMessage({ id: 'userQuestion.replyFailed' }));
|
||||
message.error(
|
||||
detailResponse.message || intl.formatMessage({ id: 'userQuestion.replyFailed' }),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('处理问题失败:', error);
|
||||
@ -164,7 +181,9 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
message.success(intl.formatMessage({ id: 'userQuestion.deleteSuccess' }));
|
||||
fetchQuestionList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'userQuestion.deleteFailed' }));
|
||||
message.error(
|
||||
response.message || intl.formatMessage({ id: 'userQuestion.deleteFailed' }),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除问题失败:', error);
|
||||
@ -202,7 +221,9 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
message.success(intl.formatMessage({ id: 'unreadQuestion.batchDeleteSuccess' }));
|
||||
fetchQuestionList(pagination.current, pagination.pageSize, searchParams);
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'unreadQuestion.batchDeleteFailed' }));
|
||||
message.error(
|
||||
response.message || intl.formatMessage({ id: 'unreadQuestion.batchDeleteFailed' }),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('批量删除失败:', error);
|
||||
@ -226,9 +247,9 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
|
||||
// 获取分类选项,处理为下拉框选项
|
||||
const getCategoryOptions = () => {
|
||||
return QuestionCategoryOptions.map(option => (
|
||||
<option key={option.value} value={option.value}>
|
||||
{typeof option.label === 'function' ? option.label() : option.label}
|
||||
return typeList.map((option) => (
|
||||
<option key={option.code} value={option.code}>
|
||||
{option.dicName}
|
||||
</option>
|
||||
));
|
||||
};
|
||||
@ -260,6 +281,10 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
key: 'type',
|
||||
width: 120,
|
||||
align: 'center' as const,
|
||||
render: (type: string) => {
|
||||
const dictItem = typeList.find((item) => item.code === type);
|
||||
return dictItem ? dictItem.dicName : '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'unreadQuestion.asker' }),
|
||||
@ -327,7 +352,7 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
<Space>
|
||||
<Button type="link" onClick={() => handleAnswer(record)}>
|
||||
{intl.formatMessage({ id: 'unreadQuestion.reply' })}
|
||||
</Button>
|
||||
</Button>
|
||||
<Button type="link" onClick={() => showDeleteConfirm(record)}>
|
||||
{intl.formatMessage({ id: 'unreadQuestion.delete' })}
|
||||
</Button>
|
||||
@ -346,12 +371,20 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
layout="inline"
|
||||
className="filter-form"
|
||||
>
|
||||
<Form.Item name="title" label={intl.formatMessage({ id: 'unreadQuestion.questionTitle' })}>
|
||||
<Input placeholder={intl.formatMessage({ id: 'unreadQuestion.questionPlaceholder' })} allowClear />
|
||||
<Form.Item
|
||||
name="title"
|
||||
label={intl.formatMessage({ id: 'unreadQuestion.questionTitle' })}
|
||||
>
|
||||
<Input
|
||||
placeholder={intl.formatMessage({ id: 'unreadQuestion.questionPlaceholder' })}
|
||||
allowClear
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="type" label={intl.formatMessage({ id: 'unreadQuestion.category' })}>
|
||||
<select className="ant-select" style={{ width: 150, height: 32, borderRadius: 2 }}>
|
||||
<option value="">{intl.formatMessage({ id: 'unreadQuestion.selectCategory' })}</option>
|
||||
<option value="">
|
||||
{intl.formatMessage({ id: 'unreadQuestion.selectCategory' })}
|
||||
</option>
|
||||
{getCategoryOptions()}
|
||||
</select>
|
||||
</Form.Item>
|
||||
@ -374,17 +407,15 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
</Form>
|
||||
|
||||
<div className="right-buttons">
|
||||
<Button
|
||||
danger
|
||||
onClick={handleBatchDelete}
|
||||
disabled={!hasSelected}
|
||||
loading={loading}
|
||||
>
|
||||
<Button danger onClick={handleBatchDelete} disabled={!hasSelected} loading={loading}>
|
||||
{intl.formatMessage({ id: 'unreadQuestion.batchDelete' })}
|
||||
</Button>
|
||||
{hasSelected && (
|
||||
<span className="selected-count">
|
||||
{intl.formatMessage({ id: 'unreadQuestion.selectedCount' }, { count: selectedRowKeys.length })}
|
||||
{intl.formatMessage(
|
||||
{ id: 'unreadQuestion.selectedCount' },
|
||||
{ count: selectedRowKeys.length },
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -408,6 +439,7 @@ const UnreadQuestionManage: React.FC = () => {
|
||||
open={answerModalVisible}
|
||||
onCancel={() => setAnswerModalVisible(false)}
|
||||
question={currentQuestion}
|
||||
typeList={typeList}
|
||||
mode="answer"
|
||||
onSuccess={() => fetchQuestionList(pagination.current, pagination.pageSize, searchParams)}
|
||||
/>
|
||||
|
6
src/uiconfig.ts
Normal file
6
src/uiconfig.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// 配置ui
|
||||
export default {
|
||||
Modal: {
|
||||
width: 1000
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user