广州矛调粤政易端
xusd
7 days ago d27794814b69d18aeb8ee96a46cae91d5613570c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
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;