info.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  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:'#227EFF'}}/>;
  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. riskExposureSuper:node.key,
  81. riskExposureSuperName:node.title,
  82. riskExposureIsmini:'',
  83. riskExposureWeight:'',
  84. riskExposureState:'',
  85. riskExposureStageId:'',
  86. defaultOut:'',
  87. riskExposureIndex:''
  88. });
  89. setFormData([]);
  90. leaf.current = '1';
  91. levelcode.current = levelcode.current + 1;
  92. }
  93. // 废除节点
  94. const deleteNode = (node: DictTree) => {
  95. const funccode = node.key;
  96. if (node.children) {
  97. baseFun.warning('请先作废所有下级节点');
  98. return;
  99. }
  100. if (treeData?.length === 1 && !treeData[0].children) {
  101. baseFun.warning('不能作废根节点');
  102. return;
  103. }
  104. baseFun.confirm("请确认是否继续操作", ()=>{ deleteFunc(funccode).then(()=>{
  105. baseFun.info("作废成功");
  106. refreshTree();
  107. });
  108. });
  109. }
  110. // 菜单增加
  111. const handleSave =async(record:riskExposureDefinitionModel)=>{
  112. if (editType == 'create') {
  113. await createRiskData(record).then(()=>{
  114. baseFun.info("执行成功");
  115. });
  116. refreshTree();
  117. closeAndRefresh();
  118. } else if (editType == 'update') {
  119. await updateRiskData(record).then(()=>{
  120. baseFun.info("执行成功");
  121. refreshTree();
  122. closeAndRefresh();
  123. });
  124. }
  125. }
  126. // 风险暴漏规则新增或删除
  127. const handleRiskRuleSave =async(record:any)=>{
  128. if (backEditType == 'update' ) {
  129. if (currentRow?.ruleNo) {
  130. updateRiskRuleExistData(record,currentRow?.ruleNo);
  131. closeAndRefresh();
  132. }
  133. } else if (backEditType == 'create' ) {
  134. createRiskRuleData(record,key);
  135. closeAndRefresh();
  136. }
  137. }
  138. //关闭窗口刷新父页面
  139. const closeAndRefresh = ()=>{
  140. actionRef.current?.reloadAndRest?.();
  141. }
  142. // 选中树节点数据查询
  143. const handleSelect =async(record:any)=>{
  144. const selectKey = record[0];
  145. setKey(selectKey);
  146. const data = await getSelectTreeData(selectKey);
  147. // 页面联动值初始化
  148. if (data.riskExposureIsmini == '1') {
  149. setRiskFlag(true);
  150. closeAndRefresh();
  151. } else {
  152. setRiskFlag(false);
  153. }
  154. if (data.riskExposureIsmini == '1') {
  155. setRiskWeightFlag(true);
  156. } else {
  157. setRiskWeightFlag(false);
  158. }
  159. formRef.current?.setFieldsValue(data);
  160. setEditType('update');
  161. }
  162. // 风险暴漏分类规则删除
  163. const delRiskRule = async (record:any) => {
  164. baseFun.confirm('请确认是否继续操作',async() =>{
  165. await delRiskRuleData(record);
  166. closeAndRefresh();
  167. })
  168. }
  169. // 风险暴漏分类规则当前行查询
  170. const selectRiskRowData = async (record:any) => {
  171. const formDataList = await getRiskDataList(record,key);
  172. backformRef.current?.setFieldsValue(formDataList[0]);
  173. }
  174. // 编辑规则编号
  175. const setRuleNoAdd = () => {
  176. let lastEditRuleNo ="";
  177. if (formData !== null || formData !== undefined) {
  178. if (formData?.length == 0) {
  179. lastEditRuleNo = "FXBL" + key + 1;
  180. } else {
  181. let lastNo = formData?.filter((item)=>{
  182. return item.ruleNo == formData[formData.length-1].ruleNo;
  183. })[0].ruleNo;
  184. let numberNo = lastNo?.substring(lastNo.length-3,lastNo.length);
  185. let castnumber = toNumber(numberNo);
  186. castnumber = castnumber+1;
  187. lastEditRuleNo = "FXBL" + key + castnumber;
  188. }
  189. } else {
  190. lastEditRuleNo = "FXBL" + key + 1;
  191. }
  192. setEditRuleNo(lastEditRuleNo);
  193. }
  194. // 页面展示元素
  195. const columns: ProColumns<riskExposureClassRuleModel>[] = [
  196. {
  197. title: '计算实例号',
  198. dataIndex: 'calcindex',
  199. search: false,
  200. hideInTable: true,
  201. },
  202. {
  203. title: '起始数据日期',
  204. dataIndex: 'startDate',
  205. search: false,
  206. hideInTable: true,
  207. },
  208. {
  209. title: '截止数据日期',
  210. dataIndex: 'endDate',
  211. search: false,
  212. hideInTable: true,
  213. },
  214. {
  215. title: '规则编号',
  216. dataIndex: 'ruleNo',
  217. search: false,
  218. hideInTable: false,
  219. },
  220. {
  221. title: '规则说明',
  222. dataIndex: 'ruleName',
  223. search: false,
  224. hideInTable: false,
  225. },
  226. {
  227. title: '产品名称',
  228. dataIndex: 'ruleProductNo',
  229. search: false,
  230. hideInTable: false,
  231. valueType: 'treeSelect',
  232. request: () => fetchDict('CUST_TYPE_LV02'),
  233. fieldProps: {
  234. treeDefaultExpandAll: true,
  235. treeCheckable:true,
  236. },
  237. },
  238. {
  239. title: '权重(%)',
  240. dataIndex: 'riskExposureWeight',
  241. search: false,
  242. hideInTable: false,
  243. },
  244. {
  245. title: '输入数据源',
  246. dataIndex: 'ruleIn',
  247. search: false,
  248. hideInTable: false,
  249. valueType: 'treeSelect',
  250. request: () => fetchDict('CUST_TYPE_LV02'),
  251. fieldProps: {
  252. treeDefaultExpandAll: true,
  253. treeCheckable:true,
  254. },
  255. },
  256. {
  257. title: '输出数据源',
  258. dataIndex: 'ruleOut',
  259. search: false,
  260. hideInTable: false,
  261. valueType: 'treeSelect',
  262. request: () => fetchDict('CUST_TYPE_LV02'),
  263. fieldProps: {
  264. treeDefaultExpandAll: true,
  265. treeCheckable:true,
  266. },
  267. },
  268. {
  269. title: '执行序号',
  270. dataIndex: 'ruleIndex',
  271. search: false,
  272. hideInTable: false,
  273. },
  274. {
  275. title: '风险暴露分类认定规则',
  276. dataIndex: 'ruleGetdata',
  277. search: false,
  278. hideInTable: false,
  279. },
  280. {
  281. title: '操作',
  282. dataIndex: 'operate',
  283. valueType: 'option',
  284. render: (_, record) => [
  285. <SDOperate
  286. key="roleCfg"
  287. icon={<WomanOutlined />}
  288. successMessage=""
  289. onClick={
  290. ()=>{
  291. selectRiskRowData(record);
  292. setBackEditType('update');
  293. setDetailVisible(true);
  294. setCurrentRow(record);
  295. }}
  296. >
  297. 修改
  298. </SDOperate>,
  299. <SDOperate
  300. key="roleCfg"
  301. icon={<WomanOutlined />}
  302. successMessage=""
  303. onClick={()=>{
  304. delRiskRule(record);
  305. } }
  306. >
  307. 删除
  308. </SDOperate>,
  309. ],
  310. },
  311. ];
  312. // 右键菜单
  313. const items: any[] = [
  314. {
  315. label: <a>新建</a>,
  316. key: 'create',
  317. },
  318. {
  319. label: <a>作废</a>,
  320. key: 'delete',
  321. },
  322. {
  323. type: 'divider',
  324. },
  325. ];
  326. return(
  327. <SDPage footer={[<SDSubmitButton successMessage='' editType={editType} formRef={formRef} doSubmit={handleSave} >保存</SDSubmitButton>]}>
  328. <SDLayout subLayout='horizontal' >
  329. <SDLayout
  330. title='菜单列表'
  331. colSpan='25%'
  332. fixHeight
  333. >
  334. <DirectoryTree treeData={treeData} onSelect={handleSelect} showLine={true} autoExpandParent={true}
  335. titleRender={(nodeData) => {
  336. return (
  337. <Dropdown menu={{ items, onClick: (e) => {
  338. console.log(e.key,nodeData)
  339. if (e.key == 'create') {
  340. createNode(nodeData);
  341. e.domEvent.stopPropagation();
  342. } else if (e.key == 'delete') {
  343. deleteNode(nodeData);
  344. e.domEvent.stopPropagation();
  345. }
  346. }}} trigger={['contextMenu']}
  347. >
  348. <span>{nodeData.title}</span>
  349. </Dropdown>
  350. )
  351. }}
  352. onRightClick={({event, node}: any) => {
  353. event.preventDefault();
  354. }}
  355. />
  356. </SDLayout>
  357. <SDLayout
  358. title='风险暴露分类信息维护'
  359. colSpan='75%'
  360. fixHeight
  361. >
  362. <SDForm
  363. editType={editType}
  364. //doSubmit={handleSave}
  365. formRef={formRef}
  366. onValuesChange={
  367. (changedValues, values)=>{
  368. if (changedValues.riskExposureIsmini == '1'){
  369. setRiskFlag(true);
  370. setRiskWeightFlag(true);
  371. } else if (values.riskExposureIsmini == '0' || values.riskExposureIsmini== null) {
  372. setRiskFlag(false);
  373. setRiskWeightFlag(false);
  374. formRef.current?.setFieldValue('riskExposureWeight',null);
  375. }
  376. }
  377. }
  378. >
  379. <SDFormText name="riskExposureNo" required={true}
  380. bgValidater={(riskExposureNo: string) => isNotExist({
  381. riskExposureNo: riskExposureNo,
  382. calcIndex: '',
  383. startDate: '',
  384. endDate: '',
  385. term: '',
  386. dataDate: '',
  387. riskExposureName: '',
  388. riskExposureStageId: '',
  389. defaultOut: '',
  390. riskExposureIndex: '',
  391. riskExposureSuper: '',
  392. riskExposureSuperName: '',
  393. riskExposureIsmini: '',
  394. riskExposureWeight: '',
  395. riskExposureState: ''
  396. })}
  397. readonlyCond='update' label="项目代码"/>
  398. <SDFormText name="riskExposureName" readonlyCond='update' required={true} label="项目名称" rules={[{max:50,message:'不可超过50个字'},]}/>
  399. <SDFormText name="riskExposureSuper" label="上级项目代码"/>
  400. <SDFormText name="riskExposureSuperName" label="上级项目名称"/>
  401. <SDFormDict name="riskExposureIsmini" dictKey="YESORNO" label="是否最细一级"/>
  402. {riskWeightFlag && <SDFormText name="riskExposureWeight" required={true} label="默认权重(%)"/>}
  403. <SDFormDict name="defaultOut" dictKey='CUST_TYPE_LV02' label="默认输出数据源"/>
  404. <SDFormDict name="riskExposureStageId" dictKey='CUST_TYPE_LV02' label="所属阶段"/>
  405. <SDFormText name="riskExposureIndex" label="认定顺序号"/>
  406. <SDFormText name="riskExposureState" readonlyCond='both' label="状态"/>
  407. </SDForm>
  408. { riskFlag &&
  409. <ProTable
  410. search={false}
  411. rowKey="ruleNo"
  412. columns={columns}
  413. dataSource={formData}
  414. toolBarRender={(_, { selectedRows }) => [
  415. <SDButton
  416. key="create"
  417. icon={<PlusSquareTwoTone />}
  418. successMessage=''
  419. onClick={() => {
  420. setDetailVisible(true);
  421. setBackEditType('create');
  422. setRuleNoAdd();
  423. }}
  424. >
  425. 新建
  426. </SDButton>,
  427. ]}
  428. request={ async(record:riskExposureClassRuleModel)=>{
  429. const formDataList = await getRiskDataList(record,key);
  430. setFormData(formDataList);
  431. return {data:formDataList}
  432. }}
  433. actionRef={actionRef}
  434. formRef={proformRef}
  435. />}
  436. {detailVisible && (
  437. <SDModalForm
  438. title={'详细信息'}
  439. editType={backEditType}
  440. visible={detailVisible}
  441. initialValues={{ruleNo:editRuleNo}}
  442. onVisibleChange={() => {setDetailVisible(false)}}
  443. footer={[
  444. <SDSubmitButton editType={backEditType} formRef={backformRef} doSubmit={handleRiskRuleSave} >保存</SDSubmitButton>,
  445. <SDButton
  446. key="closeUpdate"
  447. successMessage=''
  448. onClick={() => {setDetailVisible(false);}}>关闭</SDButton>
  449. ]}
  450. formRef={backformRef}
  451. >
  452. <SDAreaTtile title='风险暴露分类认定规则信息'/>
  453. <SDFormText name="ruleNo" readonlyCond='both' label="规则编号"/>
  454. <SDFormText name="ruleName" required={true} label="规则说明"/>
  455. <SDFormDict name="ruleProductNo" dictKey='CUST_TYPE_LV02' rules={[{required:true}]} label="产品名称"/>
  456. <SDFormText name="riskExposureWeight" label="权重(%)"/>
  457. <SDFormDict name="ruleIn" dictKey='CUST_TYPE_LV02' rules={[{required:true}]} label="输入数据源"/>
  458. <SDFormDict name="ruleOut" dictKey='CUST_TYPE_LV02' rules={[{required:true}]} label="输出数据源" />
  459. <SDFormText name="ruleIndex" required={true} label="执行序号" />
  460. <SDFormText name="ruleGetdata" required={true} type="textarea" label="风险暴露分类认定规则"/>
  461. </SDModalForm>
  462. )}
  463. </SDLayout>
  464. </SDLayout>
  465. </SDPage>
  466. )
  467. }
  468. export default info;