Files
shz-admin/src/components/JobComplaintModal/index.tsx
lapuda ed0ac7c4c2 feat: Enhance Company and Job Portal functionality
- Added company nature selection to ManagementList and JobDetailPage.
- Implemented detailed tags for job benefits and schedules in JobDetailPage and JobListPage.
- Introduced CompanyInfoPage for managing company details, including nature, scale, and contacts.
- Enhanced ManagementList to support salary composition, welfare benefits, and work schedule fields.
- Created utility functions for parsing and serializing comma-separated tags.
- Updated API services to fetch and update current company information.
- Added tests for new utility functions to ensure correct parsing and serialization of tags.
2026-07-20 11:53:43 +08:00

183 lines
4.6 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import {
Modal,
Form,
Select,
Input,
Button,
message,
Spin,
Space,
} from 'antd';
import { getDictValueEnum } from '@/services/system/dict';
import type { DictValueEnumObj } from '@/components/DictTag';
import { getJobPortalUserId, ensureJobPortalLogin } from '@/utils/jobPortalAuth';
import { submitJobComplaint } from '@/services/jobportal/user';
const { TextArea } = Input;
interface JobComplaintModalProps {
open: boolean;
jobId: string | number;
onCancel: () => void;
onSuccess?: () => void;
}
const JobComplaintModal: React.FC<JobComplaintModalProps> = ({
open,
jobId,
onCancel,
onSuccess,
}) => {
const [form] = Form.useForm();
const [complaintTypeEnum, setComplaintTypeEnum] = useState<DictValueEnumObj>({});
const [loadingDict, setLoadingDict] = useState(false);
const [submitting, setSubmitting] = useState(false);
// 加载投诉类型字典
useEffect(() => {
if (open) {
setLoadingDict(true);
getDictValueEnum('complaint_type', false, true)
.then((data) => {
setComplaintTypeEnum(data);
})
.catch(() => {
message.error('加载投诉类型失败');
})
.finally(() => {
setLoadingDict(false);
});
}
}, [open]);
// 打开时重置表单
useEffect(() => {
if (open) {
form.resetFields();
}
}, [open, form]);
const handleSubmit = async () => {
try {
const values = await form.validateFields();
// 检查登录状态
if (!ensureJobPortalLogin('提交投诉')) {
return;
}
const userId = getJobPortalUserId();
if (!userId) {
message.warning('无法获取用户信息,请稍后重试');
return;
}
setSubmitting(true);
const res = await submitJobComplaint({
userId: String(userId),
jobId: String(jobId),
complaintType: values.complaintType,
complaintContent: values.complaintContent,
contactPhone: values.contactPhone,
});
if (res?.code === 200) {
message.success('投诉提交成功');
form.resetFields();
onSuccess?.();
onCancel();
} else {
message.error(res?.msg || '投诉提交失败');
}
} catch (error) {
// 表单校验失败不提示
if (error && typeof error === 'object' && 'errorFields' in error) {
return;
}
console.error('提交投诉失败:', error);
message.error('投诉提交失败,请重试');
} finally {
setSubmitting(false);
}
};
// 手机号校验规则
const phoneRules = [
{ required: true, message: '请输入联系方式' },
{
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的11位手机号码',
},
];
return (
<Modal
title="岗位投诉"
open={open}
onCancel={onCancel}
width={600}
destroyOnHidden
footer={
<Space>
<Button onClick={onCancel}></Button>
<Button type="primary" loading={submitting} onClick={handleSubmit}>
</Button>
</Space>
}
>
<Spin spinning={loadingDict} tip="加载投诉类型...">
<Form
form={form}
layout="vertical"
style={{ marginTop: 16 }}
>
<Form.Item
name="complaintType"
label="投诉类型"
rules={[{ required: true, message: '请选择投诉类型' }]}
>
<Select
placeholder="请选择投诉类型"
options={Object.entries(complaintTypeEnum).map(([key, val]) => ({
value: key,
label: (val as any).label || (val as any).text || key,
}))}
showSearch
optionFilterProp="label"
/>
</Form.Item>
<Form.Item
name="complaintContent"
label="投诉描述"
rules={[{ required: true, message: '请输入投诉描述' }]}
>
<TextArea
rows={6}
placeholder="请详细描述您要投诉的内容..."
maxLength={2000}
showCount
/>
</Form.Item>
<Form.Item
name="contactPhone"
label="联系方式"
rules={phoneRules}
>
<Input
placeholder="请输入您的手机号码"
maxLength={11}
style={{ maxWidth: 300 }}
/>
</Form.Item>
</Form>
</Spin>
</Modal>
);
};
export default JobComplaintModal;