File size: 9,068 Bytes
f4cac62 | 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 | /**
* @license
* SPDX-License-Identifier: Apache-2.0
*/
import React, { useState } from 'react';
import { AccountabilityCase, CaseCategory, CreateCaseInput } from '../types';
import { FilePlus2, X, Plus, AlertCircle } from 'lucide-react';
interface CreateCaseFormProps {
onClose: () => void;
onSubmit: (newCase: CreateCaseInput) => void;
}
export default function CreateCaseForm({ onClose, onSubmit }: CreateCaseFormProps) {
const [title, setTitle] = useState('');
const [category, setCategory] = useState<CaseCategory>('asset');
const [accusedName, setAccusedName] = useState('');
const [accusedDept, setAccusedDept] = useState('');
const [accusedPost, setAccusedPost] = useState('');
const [incidentAmount, setIncidentAmount] = useState<number>(0);
const [description, setDescription] = useState('');
const [investigationTeamInput, setInvestigationTeamInput] = useState('');
const [error, setError] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!title.trim()) return setError('请输入案件名称');
if (!accusedName.trim()) return setError('请输入被问责人姓名');
if (!accusedDept.trim()) return setError('请输入被问责人部门');
if (!accusedPost.trim()) return setError('请输入被问责人职务');
if (!description.trim()) return setError('请输入违规事实描述');
const team = investigationTeamInput.split(/[,,\s]+/).filter(Boolean);
if (team.length === 0) {
team.push('王严明', '陈调查'); // 默认调查人
}
onSubmit({
title,
category,
accusedName,
accusedDept,
accusedPost,
incidentAmount,
description,
investigationTeam: team,
});
};
return (
<div className="fixed inset-0 bg-slate-950/60 backdrop-blur-xs flex items-center justify-center p-4 z-50 animate-fade-in" id="create-case-modal">
<div className="bg-white rounded-xl shadow-xl border border-slate-200 w-full max-w-xl overflow-hidden flex flex-col max-h-[90vh]">
{/* 头部 */}
<div className="bg-slate-900 text-white p-4 flex justify-between items-center">
<div className="flex items-center gap-2">
<FilePlus2 className="w-5 h-5 text-blue-400" />
<h3 className="text-sm font-bold">发起银行内部问责立案</h3>
</div>
<button onClick={onClose} className="text-slate-400 hover:text-white transition-colors cursor-pointer">
<X className="w-5 h-5" />
</button>
</div>
{/* 表单体 */}
<form onSubmit={handleSubmit} className="p-6 space-y-4 overflow-y-auto flex-1 text-slate-700 text-xs">
{error && (
<div className="bg-red-50 border border-red-200 text-red-700 p-2.5 rounded-lg flex items-center gap-2">
<AlertCircle className="w-4 h-4 text-red-500 shrink-0" />
<span>{error}</span>
</div>
)}
{/* 案件基本信息 */}
<div className="space-y-3">
<div>
<label className="block text-[11px] font-bold text-slate-600 mb-1">案件/违规事由名称 *</label>
<input
type="text"
placeholder="例如:关于某分行违规发放流贷造成损失责任问责案"
value={title}
onChange={(e) => setTitle(e.target.value)}
className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500"
/>
</div>
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-[11px] font-bold text-slate-600 mb-1">案件分类 *</label>
<select
value={category}
onChange={(e) => setCategory(e.target.value as CaseCategory)}
className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg bg-white focus:outline-none focus:border-blue-500"
>
<option value="asset">问题资产问责案 (时限90天)</option>
<option value="non-asset">非问题资产问责案 (时限30工作日)</option>
</select>
</div>
<div>
<label className="block text-[11px] font-bold text-slate-600 mb-1">涉案/事件涉及金额 (万元)</label>
<input
type="number"
placeholder="例如:1200"
value={incidentAmount || ''}
onChange={(e) => setIncidentAmount(Number(e.target.value))}
className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500"
/>
</div>
</div>
</div>
{/* 被问责人信息 */}
<div className="bg-slate-50 p-3 rounded-lg border border-slate-100 space-y-3">
<h4 className="font-bold text-slate-800 border-b border-slate-200 pb-1 flex items-center gap-1">
被问责人(责任人)档案信息
</h4>
<div className="grid grid-cols-3 gap-2">
<div>
<label className="block text-[10px] text-slate-500 mb-1">姓名 *</label>
<input
type="text"
placeholder="张建国"
value={accusedName}
onChange={(e) => setAccusedName(e.target.value)}
className="w-full text-xs px-2.5 py-1.5 border border-slate-200 bg-white rounded-md focus:outline-none focus:border-blue-500"
/>
</div>
<div>
<label className="block text-[10px] text-slate-500 mb-1">部门 *</label>
<input
type="text"
placeholder="普惠金融部"
value={accusedDept}
onChange={(e) => setAccusedDept(e.target.value)}
className="w-full text-xs px-2.5 py-1.5 border border-slate-200 bg-white rounded-md focus:outline-none focus:border-blue-500"
/>
</div>
<div>
<label className="block text-[10px] text-slate-500 mb-1">职务 *</label>
<input
type="text"
placeholder="高级客户经理"
value={accusedPost}
onChange={(e) => setAccusedPost(e.target.value)}
className="w-full text-xs px-2.5 py-1.5 border border-slate-200 bg-white rounded-md focus:outline-none focus:border-blue-500"
/>
</div>
</div>
</div>
{/* 调查组指定 */}
<div>
<label className="block text-[11px] font-bold text-slate-600 mb-1">指定问责调查组成员</label>
<input
type="text"
placeholder="请输入调查人名字,用逗号或空格分隔,例如:王严明, 陈调查"
value={investigationTeamInput}
onChange={(e) => setInvestigationTeamInput(e.target.value)}
className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500"
/>
<p className="text-[10px] text-slate-400 mt-1">
留空将自动指定系统合规调查处的资深调查专家:【王严明】、【陈调查】。
</p>
</div>
{/* 违规事实描述 */}
<div>
<label className="block text-[11px] font-bold text-slate-600 mb-1">违规基本事实与立案审查意见 *</label>
<textarea
rows={4}
placeholder="请详尽输入经审计/风险条线核查出的员工违规操作基本事实。这将被归档入原始立案证据并在后续事实见面、申辩、审理中作为基础依据..."
value={description}
onChange={(e) => setDescription(e.target.value)}
className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500 font-sans"
/>
</div>
{/* 底栏按钮 */}
<div className="flex justify-end gap-2 pt-4 border-t border-slate-100">
<button
type="button"
onClick={onClose}
className="px-4 py-2 border border-slate-200 hover:bg-slate-50 text-slate-700 rounded-lg font-semibold cursor-pointer"
>
取消
</button>
<button
type="submit"
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-semibold shadow-sm flex items-center gap-1.5 cursor-pointer"
>
<Plus className="w-4 h-4" />
确认立案并成立调查组
</button>
</div>
</form>
</div>
</div>
);
}
|