info.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. import React, { useEffect, useRef, useState } from 'react';
  2. import { Button, Dropdown, Form, FormInstance, Input, Menu, Space, Tooltip, Upload } from 'antd';
  3. import { ActionType, ProColumns, ProFormInstance, ProTable } from '@ant-design/pro-components';
  4. import { baseFun, ContextMenu, DictTree, EditType, SDOperate, SDForm, SDFormDict, SDFormText, SDLayout, SDModalForm, SDPage, SDSubmitButton, SDTable, SDTree, TableData,SDButton,SDAreaTtile } from '@sundata/ui-frame';
  5. import { SysFunButtonInfoModel,riskExposureDefinitionModel,riskExposureClassRuleModel } from '@/services/rwa/rwa_calc_config_001riskexposure/info';
  6. import { getDetail1, getFunTree1,getSelectTreeData,getRiskDataList,createRiskRuleData,updateRiskRuleExistData,delRiskRuleData,createRiskData,updateRiskData,isNotExist,deleteFunc } from '@/services/rwa/rwa_calc_config_001riskexposure/info';
  7. import { DataNode } from 'antd/lib/tree';
  8. import { MenuInfo } from 'rc-menu/lib/interface';
  9. import { SortOrder } from 'antd/es/table/interface';
  10. import { CheckCircleOutlined, CheckSquareOutlined, CloseCircleOutlined, CloseSquareTwoTone, PlusSquareTwoTone, WomanOutlined } from "@ant-design/icons";
  11. import { ProductProps } from '@/sundataImport';
  12. import { useModel } from '@umijs/max';
  13. import { number } from 'echarts';
  14. import { method, toNumber } from 'lodash';
  15. import DirectoryTree from 'antd/es/tree/DirectoryTree';
  16. type widowProp = {
  17. onCancel: () => void;
  18. onChangeVisible(visible: boolean, type: string): unknown;
  19. onChangeVisdible:(visible:boolean,type ?: 'none' | 'raload' )=>void;
  20. }& ProductProps;
  21. const info: React.FC<widowProp> = (prop:widowProp) => {
  22. /** 编辑方式,查看、修改、新增按钮时设置,详细信息表单中使用 */
  23. const [editType, setEditType] = useState<EditType>(prop.editType || 'update');
  24. /** 是否显示详细信息窗口 */
  25. const [detailVisible, setDetailVisible] = useState<boolean>(false);
  26. const [currentRow, setCurrentRow] = useState<riskExposureClassRuleModel>();
  27. /** 表格引用对象,刷新表格使用 */
  28. const actionRef = useRef<ActionType>();
  29. const formRef = useRef<FormInstance<any>>();
  30. const proformRef = useRef<FormInstance>();
  31. const [key, setKey] = useState<any>();
  32. const [editRuleNo, setEditRuleNo] = useState<any>();
  33. /** 编辑方式,查看、修改、新增按钮时设置,详细信息表单中使用 */
  34. const [backEditType, setBackEditType] = useState<EditType>(prop.editType || 'update');
  35. const backformRef = useRef<FormInstance>();
  36. /** 表格引用对象,刷新表格使用 */
  37. const backActionRef = useRef<ActionType>();
  38. const [treeData, setTreeData] = useState<DictTree[]>();
  39. const leaf = useRef('1');
  40. const levelcode = useRef(0);
  41. const [dataSource, setDataSource] = useState<readonly SysFunButtonInfoModel[]>()
  42. let runtimeEditType: EditType;
  43. /** 是否单一权重 显示使用 */
  44. const [riskFlag,setRiskFlag] = useState<boolean>(false);
  45. const[riskWeightFlag,setRiskWeightFlag] = useState<boolean>(false);
  46. // 页面数据
  47. const[formData,setFormData] = useState<riskExposureClassRuleModel[]>();
  48. const { fetchDict } = useModel('dict');
  49. useEffect(() => {
  50. refreshTree();
  51. }, []);
  52. // 获取树结构
  53. const refreshTree = async () => {
  54. const newTree = await getFunTree1();
  55. formatArray(newTree);
  56. setTreeData(newTree);
  57. };
  58. // 树结构图标初始化(新增和废除)
  59. function formatArray (arr:DictTree[]) {
  60. arr.forEach((item) => {
  61. if(Array.isArray(item.children)==false){
  62. if (item.attribute == '0') {
  63. item.icon=<CloseCircleOutlined/>;
  64. } else {
  65. item.icon= <CheckCircleOutlined style={{color:'blue'}}/>;
  66. }
  67. };
  68. Array.isArray(item.children) ? formatArray(item.children) : item;
  69. });
  70. }
  71. // 新建节点
  72. const createNode = (node: DictTree) => {
  73. const offobjectNo = node.key as string;
  74. setEditType('create');
  75. runtimeEditType = 'create';
  76. // 设置新增初始值
  77. formRef.current?.setFieldsValue({
  78. riskExposureNo: '',
  79. riskExposureName: '',
  80. });
  81. setFormData([]);
  82. leaf.current = '1';
  83. levelcode.current = levelcode.current + 1;
  84. }
  85. // 废除节点
  86. const deleteNode = (node: DictTree) => {
  87. const funccode = node.key;
  88. if (node.children) {
  89. baseFun.warning('请先作废所有下级节点');
  90. return;
  91. }
  92. if (treeData?.length === 1 && !treeData[0].children) {
  93. baseFun.warning('不能作废根节点');
  94. return;
  95. }
  96. baseFun.confirm("请确认是否继续操作", ()=>{ deleteFunc(funccode).then(()=>{
  97. baseFun.info("作废成功");
  98. refreshTree();
  99. });
  100. });
  101. }
  102. // 菜单增加
  103. const handleSave =async(record:riskExposureDefinitionModel)=>{
  104. if (editType == 'create') {
  105. await createRiskData(record).then(()=>{
  106. baseFun.info("执行成功");
  107. });
  108. refreshTree();
  109. closeAndRefresh();
  110. } else if (editType == 'update') {
  111. await updateRiskData(record).then(()=>{
  112. baseFun.info("执行成功");
  113. refreshTree();
  114. closeAndRefresh();
  115. });
  116. }
  117. }
  118. // 风险暴漏规则新增或删除
  119. const handleRiskRuleSave =async(record:any)=>{
  120. if (backEditType == 'update' ) {
  121. if (currentRow?.ruleNo) {
  122. updateRiskRuleExistData(record,currentRow?.ruleNo);
  123. closeAndRefresh();
  124. }
  125. } else if (backEditType == 'create' ) {
  126. createRiskRuleData(record,key);
  127. closeAndRefresh();
  128. }
  129. }
  130. //关闭窗口刷新父页面
  131. const closeAndRefresh = ()=>{
  132. actionRef.current?.reloadAndRest?.();
  133. }
  134. // 选中树节点数据查询
  135. const handleSelect =async(record:any)=>{
  136. const selectKey = record[0];
  137. setKey(selectKey);
  138. const data = await getSelectTreeData(selectKey);
  139. // 页面联动值初始化
  140. if (data.riskExposureIsmini == '1') {
  141. setRiskFlag(true);
  142. closeAndRefresh();
  143. } else {
  144. setRiskFlag(false);
  145. }
  146. if (data.riskExposureIsmini == '1') {
  147. setRiskWeightFlag(true);
  148. } else {
  149. setRiskWeightFlag(false);
  150. }
  151. formRef.current?.setFieldsValue(data);
  152. setEditType('update');
  153. }
  154. // 风险暴漏分类规则删除
  155. const delRiskRule = async (record:any) => {
  156. baseFun.confirm('请确认是否继续操作',async() =>{
  157. await delRiskRuleData(record);
  158. closeAndRefresh();
  159. })
  160. }
  161. // 风险暴漏分类规则当前行查询
  162. const selectRiskRowData = async (record:any) => {
  163. const formDataList = await getRiskDataList(record,key);
  164. backformRef.current?.setFieldsValue(formDataList[0]);
  165. }
  166. // 编辑规则编号
  167. const setRuleNoAdd = () => {
  168. let lastEditRuleNo ="";
  169. if (formData !== null || formData !== undefined) {
  170. if (formData?.length == 0) {
  171. lastEditRuleNo = "FXBL" + key + 1;
  172. } else {
  173. let lastNo = formData?.filter((item)=>{
  174. return item.ruleNo == formData[formData.length-1].ruleNo;
  175. })[0].ruleNo;
  176. let numberNo = lastNo?.substring(lastNo.length-3,lastNo.length);
  177. let castnumber = toNumber(numberNo);
  178. castnumber = castnumber+1;
  179. lastEditRuleNo = "FXBL" + key + castnumber;
  180. }
  181. } else {
  182. lastEditRuleNo = "FXBL" + key + 1;
  183. }
  184. setEditRuleNo(lastEditRuleNo);
  185. }
  186. // 页面展示元素
  187. const columns: ProColumns<riskExposureClassRuleModel>[] = [
  188. {
  189. title: '计算实例号',
  190. dataIndex: 'calcindex',
  191. search: false,
  192. hideInTable: true,
  193. },
  194. {
  195. title: '起始数据日期',
  196. dataIndex: 'startDate',
  197. search: false,
  198. hideInTable: true,
  199. },
  200. {
  201. title: '截止数据日期',
  202. dataIndex: 'endDate',
  203. search: false,
  204. hideInTable: true,
  205. },
  206. {
  207. title: '规则编号',
  208. dataIndex: 'ruleNo',
  209. search: false,
  210. hideInTable: false,
  211. },
  212. {
  213. title: '规则说明',
  214. dataIndex: 'ruleName',
  215. search: false,
  216. hideInTable: false,
  217. },
  218. {
  219. title: '产品名称',
  220. dataIndex: 'ruleProductNo',
  221. search: false,
  222. hideInTable: false,
  223. valueType: 'treeSelect',
  224. request: () => fetchDict('CUST_TYPE_LV02'),
  225. fieldProps: {
  226. treeDefaultExpandAll: true,
  227. treeCheckable:true,
  228. },
  229. },
  230. {
  231. title: '权重(%)',
  232. dataIndex: 'riskExposureWeight',
  233. search: false,
  234. hideInTable: false,
  235. },
  236. {
  237. title: '输入数据源',
  238. dataIndex: 'ruleIn',
  239. search: false,
  240. hideInTable: false,
  241. valueType: 'treeSelect',
  242. request: () => fetchDict('CUST_TYPE_LV02'),
  243. fieldProps: {
  244. treeDefaultExpandAll: true,
  245. treeCheckable:true,
  246. },
  247. },
  248. {
  249. title: '输出数据源',
  250. dataIndex: 'ruleOut',
  251. search: false,
  252. hideInTable: false,
  253. valueType: 'treeSelect',
  254. request: () => fetchDict('CUST_TYPE_LV02'),
  255. fieldProps: {
  256. treeDefaultExpandAll: true,
  257. treeCheckable:true,
  258. },
  259. },
  260. {
  261. title: '执行序号',
  262. dataIndex: 'ruleIndex',
  263. search: false,
  264. hideInTable: false,
  265. },
  266. {
  267. title: '风险暴露分类认定规则',
  268. dataIndex: 'ruleGetdata',
  269. search: false,
  270. hideInTable: false,
  271. },
  272. {
  273. title: '操作',
  274. dataIndex: 'operate',
  275. valueType: 'option',
  276. render: (_, record) => [
  277. <SDOperate
  278. key="roleCfg"
  279. icon={<WomanOutlined />}
  280. successMessage=""
  281. onClick={
  282. ()=>{
  283. selectRiskRowData(record);
  284. setBackEditType('update');
  285. setDetailVisible(true);
  286. setCurrentRow(record);
  287. }}
  288. >
  289. 修改
  290. </SDOperate>,
  291. <SDOperate
  292. key="roleCfg"
  293. icon={<WomanOutlined />}
  294. successMessage=""
  295. onClick={()=>{
  296. delRiskRule(record);
  297. } }
  298. >
  299. 删除
  300. </SDOperate>,
  301. ],
  302. },
  303. ];
  304. // 右键菜单
  305. const items: any[] = [
  306. {
  307. label: <a>新建</a>,
  308. key: 'create',
  309. },
  310. {
  311. label: <a>作废</a>,
  312. key: 'delete',
  313. },
  314. {
  315. type: 'divider',
  316. },
  317. ];
  318. return(
  319. <SDPage footer={[<SDSubmitButton successMessage='' editType={editType} formRef={formRef} doSubmit={handleSave} >保存</SDSubmitButton>]}>
  320. <SDLayout subLayout='horizontal' >
  321. <SDLayout
  322. title='菜单列表'
  323. colSpan='25%'
  324. fixHeight
  325. >
  326. <DirectoryTree treeData={treeData} onSelect={handleSelect} showLine={true} autoExpandParent={true}
  327. titleRender={(nodeData) => {
  328. return (
  329. <Dropdown menu={{ items, onClick: (e) => {
  330. console.log(e.key,nodeData)
  331. if (e.key == 'create') {
  332. createNode(nodeData);
  333. e.domEvent.stopPropagation();
  334. } else if (e.key == 'delete') {
  335. deleteNode(nodeData);
  336. e.domEvent.stopPropagation();
  337. }
  338. }}} trigger={['contextMenu']}
  339. >
  340. <span>{nodeData.title}</span>
  341. </Dropdown>
  342. )
  343. }}
  344. onRightClick={({event, node}: any) => {
  345. event.preventDefault();
  346. }}
  347. />
  348. </SDLayout>
  349. <SDLayout
  350. title='风险暴露分类信息维护'
  351. colSpan='75%'
  352. fixHeight
  353. >
  354. <SDForm
  355. editType={editType}
  356. //doSubmit={handleSave}
  357. formRef={formRef}
  358. onValuesChange={
  359. (changedValues, values)=>{
  360. if (changedValues.riskExposureIsmini == '1'){
  361. setRiskFlag(true);
  362. setRiskWeightFlag(true);
  363. } else if (values.riskExposureIsmini == '0' || values.riskExposureIsmini== null) {
  364. setRiskFlag(false);
  365. setRiskWeightFlag(false);
  366. formRef.current?.setFieldValue('riskExposureWeight',null);
  367. }
  368. }
  369. }
  370. >
  371. <SDFormText name="riskExposureNo" required={true}
  372. bgValidater={(riskExposureNo: string) => isNotExist({
  373. riskExposureNo: riskExposureNo,
  374. calcIndex: '',
  375. startDate: '',
  376. endDate: '',
  377. term: '',
  378. dataDate: '',
  379. riskExposureName: '',
  380. riskExposureStageId: '',
  381. defaultOut: '',
  382. riskExposureIndex: '',
  383. riskExposureSuper: '',
  384. riskExposureSuperName: '',
  385. riskExposureIsmini: '',
  386. riskExposureWeight: '',
  387. riskExposureState: ''
  388. })}
  389. readonlyCond='update' label="项目代码"/>
  390. <SDFormText name="riskExposureName" readonlyCond='update' required={true} label="项目名称" rules={[{max:50,message:'不可超过50个字'},]}/>
  391. <SDFormText name="riskExposureSuper" label="上级项目代码"/>
  392. <SDFormText name="riskExposureSuperName" label="上级项目名称"/>
  393. <SDFormDict name="riskExposureIsmini" dictKey="YESORNO" label="是否最细一级"/>
  394. {riskWeightFlag && <SDFormText name="riskExposureWeight" required={true} label="默认权重(%)"/>}
  395. <SDFormDict name="defaultOut" dictKey='CUST_TYPE_LV02' label="默认输出数据源"/>
  396. <SDFormDict name="riskExposureStageId" dictKey='CUST_TYPE_LV02' label="所属阶段"/>
  397. <SDFormText name="riskExposureIndex" label="认定顺序号"/>
  398. <SDFormText name="riskExposureState" readonlyCond='both' label="状态"/>
  399. </SDForm>
  400. { riskFlag &&
  401. <ProTable
  402. search={false}
  403. rowKey="ruleNo"
  404. columns={columns}
  405. dataSource={formData}
  406. toolBarRender={(_, { selectedRows }) => [
  407. <SDButton
  408. key="create"
  409. icon={<PlusSquareTwoTone />}
  410. successMessage=''
  411. onClick={() => {
  412. setDetailVisible(true);
  413. setBackEditType('create');
  414. setRuleNoAdd();
  415. }}
  416. >
  417. 新建
  418. </SDButton>,
  419. ]}
  420. request={ async(record:riskExposureClassRuleModel)=>{
  421. const formDataList = await getRiskDataList(record,key);
  422. setFormData(formDataList);
  423. return {data:formDataList}
  424. }}
  425. actionRef={actionRef}
  426. formRef={proformRef}
  427. />}
  428. {detailVisible && (
  429. <SDModalForm
  430. title={'详细信息'}
  431. editType={backEditType}
  432. visible={detailVisible}
  433. initialValues={{ruleNo:editRuleNo}}
  434. onVisibleChange={() => {setDetailVisible(false)}}
  435. footer={[
  436. <SDSubmitButton editType={backEditType} formRef={backformRef} doSubmit={handleRiskRuleSave} >保存</SDSubmitButton>,
  437. <SDButton
  438. key="closeUpdate"
  439. successMessage=''
  440. onClick={() => {setDetailVisible(false);}}>关闭</SDButton>
  441. ]}
  442. formRef={backformRef}
  443. >
  444. <SDAreaTtile title='风险暴露分类认定规则信息'/>
  445. <SDFormText name="ruleNo" readonlyCond='both' label="规则编号"/>
  446. <SDFormText name="ruleName" required={true} label="规则说明"/>
  447. <SDFormDict name="ruleProductNo" dictKey='CUST_TYPE_LV02' rules={[{required:true}]} label="产品名称"/>
  448. <SDFormText name="riskExposureWeight" label="权重(%)"/>
  449. <SDFormDict name="ruleIn" dictKey='CUST_TYPE_LV02' rules={[{required:true}]} label="输入数据源"/>
  450. <SDFormDict name="ruleOut" dictKey='CUST_TYPE_LV02' rules={[{required:true}]} label="输出数据源" />
  451. <SDFormText name="ruleIndex" required={true} label="执行序号" />
  452. <SDFormText name="ruleGetdata" required={true} type="textarea" label="风险暴露分类认定规则"/>
  453. </SDModalForm>
  454. )}
  455. </SDLayout>
  456. </SDLayout>
  457. </SDPage>
  458. )
  459. }
  460. export default info;