import React, { useState, useEffect } from 'react';
|
import { Button, Modal, Drawer } from 'dingtalk-design-mobile';
|
import { useHistory, useLocation } from 'react-router-dom';
|
import { caseDesPicture, caseDesVoice, riskMask, guide } from '../../../../assets/img';
|
import useCharacterCounter from '../CharacterCounter';
|
import CustomFormView from '../../../../components/CustomFormView';
|
import * as $$ from '../../../../utils/utility';
|
import './index.less';
|
|
const BasicInfoForm = ({ onGuideClick }) => {
|
const history = useHistory();
|
const location = useLocation();
|
const MAX_LENGTH = 100; // 事项概况最大字符数
|
const APP_MAX_LENGTH = 2000; // 事项申请最大字符数
|
const [caseLevel, setCaseLevel] = useState({ level1: false, level2: false, level3: false });
|
const [caseTypeFirstName, setCaseTypeFirstName] = useState('');
|
const [disputeTypeName, setDisputeTypeName] = useState('');
|
const [disputeLocationText, setDisputeLocationText] = useState('');
|
const [selectedLocation, setSelectedLocation] = useState([]);
|
const [disputeLocation, setDisputeLocation] = useState([]);
|
const [peopleNum, setPeopleNum] = useState('');
|
const [amount, setAmount] = useState('');
|
const [textValue, setTextValue] = useState('');
|
const [appTextValue, setAppTextValue] = useState('');
|
const [majorStatus, setMajorStatus] = useState({ yes: false, no: false });
|
const [applicationFiles, setApplicationFiles] = useState([]);
|
const [evidenceFiles, setEvidenceFiles] = useState([]);
|
const [pictureModalVisible, setPictureModalVisible] = useState(false);
|
const [guideVisible, setGuideVisible] = useState(false);
|
const [currentPictureType, setCurrentPictureType] = useState();
|
const [formData, setFormData] = useState({ caseLevel: '3', occurTime: new Date(), majorStatus: 0 });
|
|
// 使用字符计数器
|
const { charCount, isExceeded: overviewCounter } = useCharacterCounter(textValue, 100);
|
const { charCount: appCharCount, isExceeded: applicationCounter } = useCharacterCounter(appTextValue, 2000);
|
|
useEffect(() => {
|
const data = $$.getSessionStorage('selectedLocation');
|
if (data) {
|
// 处理时间数据
|
const formattedData = {
|
...data,
|
occurTime: data.occurTime ? new Date(data.occurTime) : new Date(),
|
};
|
setFormData({ ...formData, ...formattedData });
|
$$.clearSessionStorage('selectedLocation');
|
}
|
}, [$$.getSessionStorage('selectedLocation')]);
|
|
// 自动设置当前时间为纠纷发生时间
|
useEffect(() => {
|
// 获取当前时间
|
const currentDateTime = new Date();
|
setFormData({ ...formData, occurTime: currentDateTime });
|
}, []); // 只在组件挂载时执行一次
|
|
// 保存数据到缓存
|
const saveToCache = (data) => {
|
localStorage.setItem('basicInfoFormData', JSON.stringify(data));
|
};
|
|
// 处理事项等级变化
|
const handleCaseLevelChange = (value) => {
|
const newCaseLevel = {
|
level1: value === 'level1',
|
level2: value === 'level2',
|
level3: value === 'level3',
|
};
|
setCaseLevel(newCaseLevel);
|
saveToCache({ ...getFormData(), caseLevel: newCaseLevel });
|
};
|
|
// 处理纠纷类型选择
|
const handleDisputeTypeSelect = (value) => {
|
if (value && value.length > 0) {
|
const [firstLevel, secondLevel] = value;
|
setCaseTypeFirstName(firstLevel);
|
setDisputeTypeName(secondLevel);
|
saveToCache({
|
...getFormData(),
|
caseTypeFirstName: firstLevel,
|
disputeTypeName: secondLevel,
|
});
|
}
|
};
|
|
// 转换纠纷类型数据格式
|
const transformCaseTypeData = (data) => {
|
return data.map((item) => ({
|
label: item.label,
|
value: item.value,
|
children: item.children
|
? item.children.map((child) => ({
|
label: child.label,
|
value: child.value,
|
}))
|
: [],
|
}));
|
};
|
|
// 处理纠纷发生地点选择
|
const handleDisputeLocationSelect = () => {
|
// 导航到地点选择器页面
|
$$.setSessionStorage('selectedLocationData', JSON.stringify(formData));
|
history.push('/gzdyh/locationPicker');
|
};
|
|
// 处理问题属地选择
|
const handleJurisdictionLocationSelect = (value) => {};
|
|
// 处理涉及人数变化
|
const handlePeopleNumChange = (value) => {
|
setPeopleNum(value);
|
saveToCache({ ...getFormData(), peopleNum: value });
|
};
|
|
// 处理涉及金额变化
|
const handleAmountChange = (value) => {
|
setAmount(value);
|
saveToCache({ ...getFormData(), amount: value });
|
};
|
|
// 处理文本变化
|
const handleTextChange = (value) => {
|
setTextValue(value);
|
saveToCache({ ...getFormData(), textValue: value });
|
};
|
|
// 处理申请文本变化
|
const handleAppTextChange = (value) => {
|
setAppTextValue(value);
|
saveToCache({ ...getFormData(), appTextValue: value });
|
};
|
|
// 处理重大矛盾纠纷状态变化
|
const handleMajorStatusChange = (status) => {
|
const newMajorStatus = { ...majorStatus, [status]: !majorStatus[status] };
|
setMajorStatus(newMajorStatus);
|
saveToCache({ ...getFormData(), majorStatus: newMajorStatus });
|
};
|
|
// 处理申请材料上传
|
const handleApplicationUpload = (file) => {
|
const newFiles = [...applicationFiles, file];
|
setApplicationFiles(newFiles);
|
saveToCache({ ...getFormData(), applicationFiles: newFiles });
|
};
|
|
// 处理证据材料上传
|
const handleEvidenceUpload = (file) => {
|
const newFiles = [...evidenceFiles, file];
|
setEvidenceFiles(newFiles);
|
saveToCache({ ...getFormData(), evidenceFiles: newFiles });
|
};
|
|
// 确保日期格式正确
|
const formatDate = (date) => {
|
if (!date) return null;
|
try {
|
// 如果是字符串,尝试转换为日期对象
|
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
// 验证日期是否有效
|
if (isNaN(dateObj.getTime())) {
|
return new Date(); // 如果无效,返回当前日期
|
}
|
return dateObj;
|
} catch (e) {
|
console.error('日期格式化错误:', e);
|
return new Date();
|
}
|
};
|
|
// 获取表单数据
|
const getFormData = () => {
|
return {
|
caseLevel,
|
caseTypeFirstName,
|
disputeTypeName,
|
disputeLocationText,
|
disputeLocation,
|
selectedLocation,
|
peopleNum,
|
amount,
|
textValue,
|
appTextValue,
|
majorStatus,
|
applicationFiles,
|
evidenceFiles,
|
// occurTime,
|
};
|
};
|
|
// 指引弹窗处理函数
|
const handleGuideClick = () => {
|
setGuideVisible(true);
|
};
|
|
// 关闭指引弹窗
|
const handleGuideClose = () => {
|
setGuideVisible(false);
|
};
|
|
// 跳转到语音识别页面 - 通用方法
|
const handleVoiceRecognition = (title, callback) => {
|
// 使用URL查询参数而非state传递数据
|
// 存储回调函数类型到sessionStorage
|
const callbackType = title === '事项概况' ? 'overview' : 'application';
|
sessionStorage.setItem('voiceCallbackType', callbackType);
|
|
// 构建带查询参数的URL
|
history.push(`/gzdyh/voiceRecognition?title=${encodeURIComponent(title)}`);
|
};
|
|
// 获取地区标签
|
const getAreaLabels = (areaValues) => {
|
const areaLabels = [];
|
if (Array.isArray(areaValues)) {
|
// 递归查找多级区域的名称
|
let currentList = $$.threelocationSelectList.threelocationSelect || [];
|
areaValues.forEach((areaCode) => {
|
const found = currentList.find((item) => item.value === areaCode);
|
if (found) {
|
areaLabels.push(found.label);
|
currentList = found.children || [];
|
}
|
});
|
}
|
return areaLabels;
|
};
|
|
// 获取纠纷类型标签
|
const getCaseTypeLabels = (caseTypeValues) => {
|
const typeLabels = [];
|
if (Array.isArray(caseTypeValues)) {
|
// 递归查找多级类型的名称
|
let currentList = transformCaseTypeData($$.caseTypeList.caseTypeSelect) || [];
|
caseTypeValues.forEach((typeCode) => {
|
const found = currentList.find((item) => item.value === typeCode);
|
if (found) {
|
typeLabels.push(found.label);
|
currentList = found.children || [];
|
}
|
});
|
}
|
return typeLabels;
|
};
|
|
// 打开图片识别弹窗
|
const handlePictureButtonClick = (type) => {
|
setCurrentPictureType(type);
|
setPictureModalVisible(true);
|
};
|
|
// 关闭图片识别弹窗
|
const handlePictureModalClose = () => {
|
setPictureModalVisible(false);
|
};
|
|
// 处理图片识别来源选择
|
const handlePictureSourceSelect = (source) => {
|
// 这里实现实际的图片识别逻辑
|
console.log(`选择了${source}方式进行图片识别,当前文本区域:${currentPictureType}`);
|
setPictureModalVisible(false);
|
};
|
|
// 表单配置
|
const formConfig = [
|
{
|
list: [
|
{
|
type: 'radio',
|
label: (
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
<span>事项等级</span>
|
<img
|
src={guide}
|
alt="指引"
|
style={{
|
width: '15px',
|
height: '15px',
|
marginLeft: '5px',
|
cursor: 'pointer',
|
}}
|
onClick={handleGuideClick}
|
/>
|
</div>
|
),
|
name: 'caseLevel',
|
list: $$.selectOption.caseLevelList,
|
},
|
{
|
type: 'cascader',
|
name: 'myCaseType',
|
label: '纠纷类型',
|
placeholder: '选择',
|
require: true,
|
list: transformCaseTypeData($$.caseTypeList.caseTypeSelect),
|
},
|
{
|
type: 'date',
|
name: 'occurTime',
|
label: '纠纷发生时间',
|
placeholder: '选择',
|
require: true,
|
format: 'YYYY-MM-DD HH:mm',
|
},
|
{
|
type: 'navigation',
|
name: 'addr',
|
label: '纠纷发生地点',
|
placeholder: '选择',
|
require: true,
|
onClick: handleDisputeLocationSelect,
|
},
|
{
|
type: 'cascader',
|
name: 'que',
|
label: '问题属地',
|
placeholder: '选择',
|
require: true,
|
cols: 2,
|
list: $$.threelocationSelectList.threelocationSelect,
|
},
|
{
|
type: 'text',
|
name: 'peopleNum',
|
label: '涉及人数(人)',
|
placeholder: '请填写',
|
},
|
{
|
type: 'text',
|
name: 'amount',
|
label: '涉及金额(元)',
|
placeholder: '请填写',
|
},
|
],
|
},
|
{
|
list: [
|
{
|
type: 'textarea',
|
name: 'caseDes',
|
label: '事项概况',
|
placeholder: '请完整描述事项概况,应具备5要素:发生时间+发生地点+人物情况+事项起因+事项经过',
|
require: true,
|
tabs: 5,
|
customActions: (
|
<div className="overview-button-area">
|
<div className="word-count">
|
<div className="count-wrapper">
|
<span className="current-count" style={{ color: overviewCounter.isExceeded ? '#F53F3F' : 'inherit' }}>
|
{charCount}
|
</span>
|
<span className="total-count" style={{ color: overviewCounter.isExceeded ? '#F53F3F' : 'inherit' }}>
|
/{MAX_LENGTH} 字
|
</span>
|
</div>
|
</div>
|
<div className="overview-actions">
|
<Button className="action-button picture-button" onClick={() => handlePictureButtonClick('overview')}>
|
<div className="action-icon">
|
<img src={caseDesPicture} alt="图片识别" />
|
</div>
|
<div className="action-text">图片识别</div>
|
</Button>
|
<div className="action-button-split">|</div>
|
<Button className="action-button voice-button" onClick={() => handleVoiceRecognition('事项概况', handleTextChange)}>
|
<div className="action-icon">
|
<img src={caseDesVoice} alt="语音识别" />
|
</div>
|
<div className="action-text">语音识别</div>
|
</Button>
|
</div>
|
</div>
|
),
|
},
|
],
|
},
|
{
|
list: [
|
{
|
type: 'textarea',
|
name: 'caseClaim',
|
label: '事项申请',
|
placeholder: '希望相关部门如何处理,建议分条描述,如请求1,请求2...',
|
require: true,
|
value: appTextValue,
|
tabs: 5,
|
customActions: (
|
<div className="overview-button-area">
|
<div className="word-count">
|
<div className="count-wrapper">
|
<span className="current-count" style={{ color: applicationCounter.isExceeded ? '#F53F3F' : 'inherit' }}>
|
{appCharCount}
|
</span>
|
<span className="total-count" style={{ color: applicationCounter.isExceeded ? '#F53F3F' : 'inherit' }}>
|
/{APP_MAX_LENGTH} 字
|
</span>
|
</div>
|
</div>
|
<div className="overview-actions">
|
<Button className="action-button picture-button" onClick={() => handlePictureButtonClick('application')}>
|
<div className="action-icon">
|
<img src={caseDesPicture} alt="图片识别" />
|
</div>
|
<div className="action-text">图片识别</div>
|
</Button>
|
<div className="action-button-split">|</div>
|
<Button className="action-button voice-button" onClick={() => handleVoiceRecognition('事项申请', handleAppTextChange)}>
|
<div className="action-icon">
|
<img src={caseDesVoice} alt="语音识别" />
|
</div>
|
<div className="action-text">语音识别</div>
|
</Button>
|
</div>
|
</div>
|
),
|
},
|
],
|
},
|
{
|
list: [
|
{
|
type: 'radio',
|
name: 'majorStatus',
|
label: (
|
<div className="major-dispute-label">
|
<img src={riskMask} alt="风险标识" className="risk-icon" />
|
<span className="major-dispute-text">是否重大矛盾纠纷</span>
|
</div>
|
),
|
list: [
|
{ value: 0, label: '否' },
|
{ value: 1, label: '是' },
|
],
|
},
|
],
|
},
|
];
|
|
// 处理表单值变化
|
const handleFormChange = (values, name) => {
|
console.log('表单值变化:', values, name);
|
// 处理时间数据
|
let formattedValues = {
|
...values,
|
occurTime: values.occurTime ? new Date(values.occurTime) : formData.occurTime,
|
};
|
|
// 在这里处理问题属地信息
|
if (values?.que && values.que.length >= 2) {
|
const areaLabels = getAreaLabels(values.que);
|
formattedValues = {
|
...formattedValues,
|
queArea: values.que[0],
|
queAreaName: areaLabels[0],
|
queRoad: values.que[1],
|
queRoadName: areaLabels[1],
|
};
|
}
|
|
// 处理纠纷类型
|
if (values?.myCaseType && values.myCaseType.length >= 2) {
|
const typeLabels = getCaseTypeLabels(values.myCaseType);
|
formattedValues = {
|
...formattedValues,
|
caseType: values.myCaseType[1], // 二级类型值作为caseType
|
caseTypeFirst: values.myCaseType[0], // 一级类型值
|
caseTypeName: typeLabels[1] || '', // 二级类型名称
|
caseTypeFirstName: typeLabels[0] || '', // 一级类型名称
|
};
|
}
|
|
onGuideClick(formattedValues, name);
|
setFormData({ ...formData, ...formattedValues });
|
};
|
|
return (
|
<>
|
<CustomFormView formConfig={formConfig} formData={formData} onChange={handleFormChange} />
|
|
<div className="audit-section">
|
{/* <DingUpload
|
title="附件材料"
|
subtitle="可添加上报申请相关附件"
|
fileList={applicationFiles}
|
mainId={caseId}
|
ownerId={reportForm?.id || ''}
|
ownerType="22_00018-512"
|
multiple={true}
|
maxCount={9}
|
/> */}
|
</div>
|
|
{/* 图片识别弹窗 */}
|
<Modal visible={pictureModalVisible} onClose={handlePictureModalClose} className="picture-recognition-modal" maskClosable={true}>
|
<div className="picture-modal-content">
|
<div className="picture-modal-intro">
|
<div className="picture-modal-title">识别图片</div>
|
<div className="picture-modal-desc">仅支持图片,请选择图片来源</div>
|
</div>
|
<div className="picture-modal-options">
|
<div className="picture-modal-option" onClick={() => handlePictureSourceSelect('相册')}>
|
手机相册
|
</div>
|
<div className="picture-modal-option" onClick={() => handlePictureSourceSelect('拍照')}>
|
拍照上传
|
</div>
|
</div>
|
<div className="picture-modal-cancel" onClick={handlePictureModalClose}>
|
取消操作
|
</div>
|
</div>
|
</Modal>
|
|
{/* 事项等级指引弹窗 */}
|
<Drawer
|
visible={guideVisible}
|
onClose={handleGuideClose}
|
className="guide-drawer"
|
placement="bottom"
|
height="auto"
|
contentStyle={{ padding: '0' }}
|
header={null}
|
>
|
<div className="guide-content" style={{ textAlign: 'left', padding: '16px' }}>
|
<div style={{ fontSize: '16px', fontWeight: 500, marginBottom: '16px' }}>
|
事项等级<span style={{ color: '#1A6FB8' }}>-指引</span>
|
</div>
|
<span style={{ display: 'block', marginBottom: '12px', fontSize: '16px', fontWeight: 500 }}>一级重点事件</span>
|
<p style={{ marginBottom: '8px', fontSize: '14px', lineHeight: '1.5' }}>
|
1、5人(含5人)以上到非接待场所聚集、滞留、静坐、游行或准备上访;
|
</p>
|
<p style={{ marginBottom: '8px', fontSize: '14px', lineHeight: '1.5' }}>
|
2、拉横幅、穿着"状衣"、呼喊口号、呼喊标语、堵塞交通非法占据公共场所、扰乱公共秩序、向他人散发传单等上访材料;
|
</p>
|
<p style={{ marginBottom: '8px', fontSize: '14px', lineHeight: '1.5' }}>3、拖欠工资、劳资纠纷涉及人数5人以上;</p>
|
<p style={{ marginBottom: '8px', fontSize: '14px', lineHeight: '1.5' }}>4、拖欠工资总金额5万元以上,经济合同外涉金额20万元以上;</p>
|
<p style={{ marginBottom: '8px', fontSize: '14px', lineHeight: '1.5' }}>5、扬言到市赴省进京越级上访;</p>
|
</div>
|
</Drawer>
|
</>
|
);
|
};
|
|
export default BasicInfoForm;
|