index.tsx 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  1. /*
  2. * @Author: code4eat awesomedema@gmail.com
  3. * @Date: 2022-12-16 09:42:52
  4. * @LastEditors: code4eat awesomedema@gmail.com
  5. * @LastEditTime: 2023-05-30 16:30:41
  6. * @FilePath: /BudgetManaSystem/src/pages/budgetMana/monthlySet/index.tsx
  7. * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  8. */
  9. import BMSPagecontainer from '@/components/BMSPageContainer';
  10. import { Fragment, Key, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
  11. import './style.less';
  12. import { Tree, TreeProps, Tabs, Input, Modal, Transfer, Popconfirm, message, Popover, Select } from 'antd';
  13. import { DataNode } from 'antd/es/tree';
  14. import expandedIcon from '../../../../../static/treenode_open.png';
  15. import closeIcon from '../../../../../static/treenode_collapse.png';
  16. import { BMSTable } from '@/components/BMSTable';
  17. import { ActionType, ModalForm, ProColumns, ProColumnType, ProFormDigit, ProFormSelect } from '@ant-design/pro-components';
  18. import { createFromIconfontCN } from '@ant-design/icons';
  19. import { delRequest, getIndicTableData, getBillingItemTableData, getTreeDataRespType, getTreeData, getAllCheckUnit, saveCopyRequest, getAllCheckUnitProjectData, addBillingItemData, editBillingItemData, addIndicItemData, editIndicItemData, getNonCheckTableData, addNonCheckItemData } from './service';
  20. import { TransferItem, TransferProps } from 'antd/es/transfer';
  21. import { getComputeDate } from '@/pages/Home/service';
  22. import 'dayjs/locale/zh-cn';
  23. import React from 'react';
  24. import DirectoryTree from 'antd/es/tree/DirectoryTree';
  25. import { getDeepestTreeData } from '@/utils/tooljs';
  26. import { ColumnsType, TableRowSelection } from 'antd/es/table/interface';
  27. import { difference } from 'lodash';
  28. import { getBillProjectData } from '../bilingProjectMana/service';
  29. import { getIndicProjectTableData } from '../indicProjectMana/service';
  30. import { getNonCheckProjectTableData } from '../nonAssessmentProjectMana/service';
  31. import '../../../../utils/zhongtaiB';
  32. const IconFont = createFromIconfontCN({
  33. scriptUrl: '',
  34. });
  35. const SearchIcon = createFromIconfontCN({
  36. scriptUrl: '',
  37. });
  38. export type TableListItem = {
  39. key: number;
  40. name: string;
  41. };
  42. const CheckUnitProjectSet: React.FC = () => {
  43. const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
  44. const [tableColumn, set_tableColumn] = useState<ProColumns[]>([]);
  45. const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>();
  46. const [currentSelectedTabKey, set_currentSelectedTabKey] = useState<string>('1');
  47. const [currentComputeDate, set_currentComputeDate] = useState<string | undefined>();
  48. const [currentEditRow, set_currentEditRow] = useState<any>(undefined);
  49. const [searchKeywords, set_searchKeywords] = useState('');
  50. const [searchParams, set_searchParams] = useState<any>({});
  51. const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  52. const [searchValue, setSearchValue] = useState('');
  53. const [autoExpandParent, setAutoExpandParent] = useState(true);
  54. const [ifEdit, set_ifEdit] = useState(false);
  55. const [ifShowModal, set_ifShowModal] = useState(false);
  56. const ref = React.createRef<{ save: any; getSelectedKeys: any }>();
  57. const [currentEditCoreFlag,set_currentEditCoreFlag] = useState(0);
  58. const tableRef = useRef<ActionType>();
  59. const billingTableColumn: ProColumns[] = [
  60. {
  61. title: '项目代码',
  62. dataIndex: 'itemPointCode',
  63. renderText(text, record, index, action) {
  64. return <span style={{ display: 'inline-block', height: '26px', lineHeight: '26px' }}>{text}</span>
  65. },
  66. ellipsis:true
  67. },
  68. {
  69. title: '项目名称',
  70. dataIndex: 'itemName',
  71. ellipsis:true
  72. },
  73. {
  74. title: '项目类别',
  75. dataIndex: 'itemType',
  76. ellipsis:true
  77. },
  78. {
  79. title: '点值',
  80. width: 120,
  81. ellipsis:true,
  82. dataIndex: 'orderPointValue',
  83. renderText:(text, record, index, action)=>{
  84. if (ifEdit && currentEditRow?.id == record.id) {
  85. return <ProFormDigit noStyle fieldProps={{
  86. defaultValue: text, onChange(value) {
  87. // console.log({value,currentEditRow});
  88. if (value && currentEditRow) {
  89. set_currentEditRow({ ...currentEditRow, orderPointValue: value })
  90. }
  91. },
  92. }} width={80} />
  93. } else {
  94. return <span style={{ display: 'inline-block', width: 80 }}>{text}</span>
  95. }
  96. },
  97. },
  98. {
  99. title: '类型',
  100. width: 120,
  101. ellipsis:true,
  102. dataIndex: 'coreFlagName',
  103. renderText:(text, record, index, action)=>{
  104. if (ifEdit && currentEditRow && currentEditRow?.id == record.id) {
  105. return <Select defaultValue={record.coreFlag} style={{width:'100%'}} options={
  106. [
  107. { label: '核心', value: 1 }, { label: '非核心', value: 0 },{ label: '不计', value:2 }
  108. ]
  109. } onChange={(a, b) => { set_currentEditCoreFlag(a)}} />
  110. } else {
  111. return <span style={{ display: 'inline-block', width:120}}>{text}</span>
  112. }
  113. },
  114. }
  115. ];
  116. const indicTableColumn: ProColumns[] = [
  117. {
  118. title: '项目代码',
  119. dataIndex: 'indicatorCode',
  120. ellipsis:true,
  121. renderText(text, record, index, action) {
  122. return <span style={{ display: 'inline-block', height: '26px', lineHeight: '26px' }}>{text}</span>
  123. },
  124. },
  125. {
  126. title: '项目名称',
  127. ellipsis:true,
  128. dataIndex: 'indicatorName',
  129. },
  130. {
  131. title: '类型',
  132. ellipsis:true,
  133. dataIndex: 'indicatorTypeName',
  134. },
  135. {
  136. title: '定义',
  137. ellipsis:true,
  138. dataIndex: 'indicatorDefinition',
  139. },
  140. {
  141. title: '点值',
  142. width: 120,
  143. ellipsis:true,
  144. dataIndex: 'orderPointValue',
  145. renderText(text, record, index, action) {
  146. if (ifEdit && currentEditRow?.id == record.id) {
  147. return <ProFormDigit noStyle fieldProps={{
  148. defaultValue: text, onChange(value) {
  149. console.log({ value, currentEditRow });
  150. if (value && currentEditRow) {
  151. set_currentEditRow({ ...currentEditRow, orderPointValue: value })
  152. }
  153. },
  154. }} width={80} />
  155. } else {
  156. return <span style={{ display: 'inline-block', width: 80 }}>{text}</span>
  157. }
  158. },
  159. }
  160. ];
  161. const nonCheckTableColumn: ProColumns[] = [
  162. {
  163. title: '项目名称',
  164. ellipsis:true,
  165. dataIndex: 'nonAssessmentName',
  166. renderText(text, record, index, action) {
  167. return <span style={{ display: 'inline-block', height: '26px', lineHeight: '26px' }}>{text}</span>
  168. },
  169. },
  170. {
  171. title: '分配方式',
  172. ellipsis:true,
  173. dataIndex: 'distributionTypeName',
  174. },
  175. {
  176. title: '分配对象',
  177. ellipsis:true,
  178. dataIndex: 'distributionTargetName',
  179. },
  180. {
  181. title: '上限值',
  182. ellipsis:true,
  183. dataIndex: 'ceiling',
  184. },
  185. {
  186. title: '评分项',
  187. width: 260,
  188. dataIndex: 'orderPointValue',
  189. ellipsis:true,
  190. renderText(text, record) {
  191. return record.secondItem?record.secondItem.reduce((prev: any,cur: any)=>`${prev.length>0?prev+'|':prev}${cur.secondItemName}`,''):''
  192. },
  193. }
  194. ];
  195. const delHandle = async (record: any) => {
  196. const { id } = record;
  197. const resp = await delRequest({id: id},currentSelectedTabKey);
  198. if (resp) {
  199. message.success('操作成功');
  200. tableRef.current?.reload();
  201. }
  202. }
  203. const onSelect: TreeProps['onSelect'] = (selectedKeys, info:any) => {
  204. // console.log('selected', selectedKeys, info);
  205. const { node} = info;
  206. if(!node.child)set_currentSelectedTreeNode(node);
  207. };
  208. const getCurrentComputeDate = async () => {
  209. const resp = await getComputeDate();
  210. set_currentComputeDate(resp);
  211. }
  212. const onTabChange = (activeKey: string) => {
  213. set_currentSelectedTabKey(activeKey);
  214. }
  215. const getTableData = async (type: 'BILL' | 'INDIC' | 'NONCHECK', params: any, sort: any, filter: any) => {
  216. // console.log({ currentSelectedTreeNode });
  217. // console.log({ params, sort, filter });
  218. if (currentSelectedTreeNode && currentComputeDate) {
  219. if (type == 'BILL') {
  220. const resp = await getBillingItemTableData({
  221. unitCode: currentSelectedTreeNode.code,
  222. ...params,
  223. });
  224. if (resp) {
  225. return {
  226. data: resp.list,
  227. success: true,
  228. total: resp.totalCount,
  229. pageSize: resp.pageSize,
  230. totalPage: resp.totalPage,
  231. }
  232. }
  233. return {
  234. data: [],
  235. success: true
  236. }
  237. }
  238. if (type == 'INDIC') {
  239. const resp = await getIndicTableData({
  240. unitCode: currentSelectedTreeNode.code,
  241. ...params
  242. });
  243. if (resp) {
  244. return {
  245. data: resp.list,
  246. success: true,
  247. total: resp.totalCount,
  248. pageSize: resp.pageSize,
  249. totalPage: resp.totalPage,
  250. }
  251. }
  252. return {
  253. data: [],
  254. success: true
  255. }
  256. }
  257. if (type == 'NONCHECK') {
  258. const resp = await getNonCheckTableData({
  259. unitCode: currentSelectedTreeNode.code,
  260. ...params
  261. });
  262. if (resp) {
  263. return {
  264. data: resp.list,
  265. success: true,
  266. total: resp.totalCount,
  267. pageSize: resp.pageSize,
  268. totalPage: resp.totalPage,
  269. }
  270. }
  271. return {
  272. data: [],
  273. success: true
  274. }
  275. }
  276. }
  277. return []
  278. }
  279. interface TableTransferProps extends TransferProps<TransferItem> {
  280. leftColumns: ColumnsType<any>;
  281. rightColumns: ColumnsType<any>;
  282. }
  283. const transferTableColumn = [
  284. {
  285. title: '项目名称',
  286. dataIndex: 'itemName',
  287. ellipsis: true,
  288. width: 220
  289. },
  290. {
  291. title: '类型',
  292. dataIndex: 'itemType',
  293. },
  294. ];
  295. const tableSelecterColumn = [
  296. {
  297. title: '核算单元名称',
  298. dataIndex: 'unitName',
  299. },
  300. {
  301. title: '职类',
  302. dataIndex: 'unitTypeName',
  303. },
  304. ]
  305. const openCopyHandleModal = () => {
  306. set_ifShowModal(true);
  307. }
  308. const openTransfer = () => {
  309. const ref = React.createRef<{ save: any }>();
  310. Modal.confirm({
  311. title: '添加',
  312. icon: <></>,
  313. width: 800,
  314. centered:true,
  315. okText: '确定',
  316. cancelText: '取消',
  317. content: <TableTransfer
  318. ref={ref}
  319. leftColumns={transferTableColumn}
  320. rightColumns={transferTableColumn}
  321. ></TableTransfer>,
  322. onOk: () => {
  323. return ref.current && ref.current.save();
  324. }
  325. })
  326. }
  327. interface TableSelecterProps extends TransferProps<TransferItem> {
  328. tableSelecterColumn: any[];
  329. record: any
  330. }
  331. const TableSelecter = React.forwardRef(({ tableSelecterColumn, record }: TableSelecterProps, ref) => {
  332. const [datasource, set_datasource] = useState<any[]>([]);
  333. const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
  334. const [showList, set_showList] = useState<any[]>([]);
  335. //获取表格数据
  336. const getFuncList = async () => {
  337. const resp = await getAllCheckUnit();
  338. if (resp) {
  339. const filteredData = resp.filter((a:any)=>a.code != currentSelectedTreeNode.code);
  340. set_datasource(filteredData);
  341. set_showList(filteredData);
  342. }
  343. }
  344. const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
  345. setSelectedKeys([...newSelectedRowKeys]);
  346. };
  347. const save = async () => {
  348. const result = {
  349. unitCodeList: selectedKeys,
  350. unitCode: currentSelectedTreeNode.code
  351. };
  352. const resp = await saveCopyRequest(result, currentSelectedTabKey);
  353. if (resp) {
  354. message.success('复制成功!');
  355. set_ifShowModal(false);
  356. tableRef.current?.reload();
  357. }
  358. }
  359. useEffect(() => {
  360. getFuncList();
  361. }, [])
  362. return (
  363. <div className='TableSelecter'>
  364. <Input placeholder={'请输入'} allowClear
  365. suffix={
  366. <IconFont type="iconsousuo" />
  367. }
  368. style={{ marginBottom: 8 }}
  369. onChange={(e) => {
  370. if (e.target.value.length != 0) {
  371. const result = datasource.filter(item => item.unitName.indexOf(e.target.value) != -1);
  372. set_showList(result);
  373. } else {
  374. set_showList(datasource);
  375. }
  376. }}
  377. />
  378. <BMSTable columns={tableSelecterColumn}
  379. options={{
  380. density: true,
  381. setting: {
  382. listsHeight: 100,
  383. },
  384. }}
  385. rowKey='code'
  386. tableAlertRender={false}
  387. rowSelection={{
  388. // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
  389. // 注释该行则默认不显示下拉选项
  390. onChange: onSelectChange,
  391. }}
  392. pagination={{ showSizeChanger: false, pageSize: 10, simple: true, showTitle: false }}
  393. dataSource={showList}
  394. />
  395. <div className='footer'>
  396. <span className='cancel' onClick={() => set_ifShowModal(false)}>取消</span>
  397. <span className='ok' onClick={() => save()}>{`确认(${selectedKeys.length > 0 && selectedKeys.length})`}</span>
  398. </div>
  399. </div>
  400. )
  401. });
  402. const TableTransfer = React.forwardRef(({ leftColumns, rightColumns, ...restProps }: TableTransferProps, ref) => {
  403. const [_data, _set_data] = useState<any>();
  404. const [targetKeys, setTargetKeys] = useState<string[]>([]);
  405. const [datasource, set_datasource] = useState<any[]>([]);
  406. const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
  407. const [targetData,set_targetData] = useState<any[]>([]);
  408. const [loading,set_loading] = useState(true);
  409. //获取单元
  410. const getFuncList = async () => {
  411. if (currentSelectedTabKey == '1') {
  412. const resp = await getAllCheckUnitProjectData();
  413. if (resp) {
  414. const resp1 = await getBillingItemTableData({
  415. unitCode: currentSelectedTreeNode.code,
  416. pageSize: 500, current: 1
  417. });
  418. if (resp1) {
  419. let allData = resp;
  420. set_targetData(resp1.list);
  421. const defaultSelctedkeys = (resp1.list).map((a:any) => a.itemPointCode);
  422. set_datasource(allData);
  423. setTargetKeys(defaultSelctedkeys);
  424. }
  425. }
  426. }
  427. if (currentSelectedTabKey == '2') {
  428. const resp = await getIndicProjectTableData({ pageSize: 500, current: 1 });
  429. if (resp) {
  430. const resp1 = await getIndicTableData({
  431. unitCode: currentSelectedTreeNode.code,
  432. pageSize: 500, current: 1
  433. });
  434. if (resp1) {
  435. set_targetData(resp1.list);
  436. set_datasource(resp.list.map((a: any) => ({ ...a, itemName: a.indicatorName, itemType: a.indicatorTypeName })));
  437. const defaultSelctedkeys = (resp1.list).map((a: any) => a.indicatorCode);
  438. setTargetKeys(defaultSelctedkeys);
  439. }
  440. }
  441. }
  442. if (currentSelectedTabKey == '3') {
  443. const resp = await getNonCheckProjectTableData({ pageSize: 500, current: 1 });
  444. if (resp) {
  445. const resp1 = await getNonCheckTableData({
  446. unitCode: currentSelectedTreeNode.code,
  447. pageSize: 1000000, current: 1
  448. });
  449. if (resp1) {
  450. set_targetData(resp1.list);
  451. set_datasource(resp.list.map((a: any) => ({ ...a, itemName: a.name, itemType: a.distributionTypeName })));
  452. const defaultSelctedkeys = (resp1.list).map((a: any) => a.nonAssessmentCode);
  453. setTargetKeys(defaultSelctedkeys);
  454. }
  455. }
  456. }
  457. set_loading(false);
  458. }
  459. const onChange = (nextTargetKeys: string[]) => {
  460. setTargetKeys(nextTargetKeys);
  461. };
  462. const onSelectChange = (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => {
  463. console.log('sourceSelectedKeys:', sourceSelectedKeys,'targetSelectedKeys:',targetSelectedKeys);
  464. setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
  465. };
  466. useImperativeHandle(ref, () => ({
  467. save: async () => {
  468. let flag = false;
  469. if (currentSelectedTabKey == '1') {
  470. const items = datasource.filter(a => targetKeys.includes(a.code));
  471. //拿到当前的表格数据覆盖全量表格数据
  472. console.log({items,targetKeys});
  473. const uodatedData = items.map(a=>{
  474. if(targetData.length>0){
  475. const result = targetData.filter(b=>b.itemPointCode == a.code);
  476. if(result.length>0){
  477. return {
  478. ...a,
  479. orderPointValue:result[0].orderPointValue,
  480. coreFlag:result[0].coreFlag,
  481. }
  482. }else{
  483. return a
  484. }
  485. }else{
  486. return a
  487. }
  488. })
  489. const result = {
  490. unitCode: currentSelectedTreeNode.code,
  491. item: uodatedData.map(a=>({
  492. itemPointCode:a.itemCode,
  493. itemName:a.itemName,
  494. orderPointValue:a.orderPointValue,
  495. coreFlag:a.coreFlag
  496. }))
  497. }
  498. const resp = await addBillingItemData(result);
  499. if (resp) {
  500. flag = true
  501. }
  502. }
  503. if (currentSelectedTabKey == '2') {
  504. const items = datasource.filter(a => targetKeys.includes(a.code));
  505. //拿到当前的表格数据覆盖全量表格数据
  506. const uodatedData = items.map(a=>{
  507. if(targetData.length>0){
  508. const result = targetData.filter(b=>b.indicatorCode == a.code);
  509. if(result.length>0){
  510. return {
  511. ...a,
  512. orderPointValue:result[0].orderPointValue
  513. }
  514. }else{
  515. return a
  516. }
  517. }else{
  518. return a
  519. }
  520. })
  521. const commitData = uodatedData.map((a:any) => ({
  522. indicatorCode: a.code,
  523. indicatorName: a.indicatorName,
  524. orderPointValue: a.orderPointValue,
  525. executePointValue: a.executePointValue
  526. }))
  527. const result = {
  528. unitCode: currentSelectedTreeNode.code,
  529. indicatorValues: commitData
  530. }
  531. const resp = await addIndicItemData(result);
  532. if (resp) {
  533. flag = true
  534. }
  535. }
  536. if (currentSelectedTabKey == '3') {
  537. const items = datasource.filter(a => targetKeys.includes(a.code));
  538. const commitData = items.map(a => ({
  539. code:a.code,
  540. name:a.name
  541. }))
  542. const result = {
  543. unitCode: currentSelectedTreeNode.code,
  544. assessments: commitData
  545. }
  546. const resp = await addNonCheckItemData(result);
  547. if (resp) {
  548. flag = true
  549. }
  550. }
  551. if (flag) {
  552. message.success('操作成功!');
  553. tableRef.current?.reload();
  554. }
  555. }
  556. }));
  557. useEffect(() => {
  558. getFuncList();
  559. }, [])
  560. return (
  561. <Transfer className='TableTransfer' showSearch
  562. titles={['待选项', '已选项']}
  563. locale={{
  564. itemUnit: '项',
  565. itemsUnit: '项',
  566. searchPlaceholder: '请输入',
  567. }}
  568. // oneWay={true}
  569. onChange={onChange}
  570. onSelectChange={onSelectChange}
  571. dataSource={datasource}
  572. rowKey={record => record.code}
  573. targetKeys={targetKeys}
  574. selectedKeys={selectedKeys}
  575. filterOption={(inputValue, item) => {
  576. if(item.itemName!.indexOf(inputValue) !== -1){
  577. console.log({item});
  578. }
  579. return item.itemName!.indexOf(inputValue) !== -1
  580. }}
  581. >
  582. {({
  583. direction,
  584. filteredItems,
  585. onItemSelectAll,
  586. onItemSelect,
  587. selectedKeys: listSelectedKeys,
  588. disabled: listDisabled,
  589. }) => {
  590. //console.log({ filteredItems, listSelectedKeys, direction });
  591. const columns = direction === 'left' ? leftColumns : rightColumns;
  592. const rowSelection: TableRowSelection<TransferItem> = {
  593. getCheckboxProps: (item) => ({ disabled: listDisabled || item.disabled }),
  594. onSelectAll(selected, selectedRows) {
  595. const treeSelectedKeys = selectedRows.map(({ code }) => code);
  596. const diffKeys = selected
  597. ? difference(treeSelectedKeys, listSelectedKeys)
  598. : difference(listSelectedKeys, treeSelectedKeys);
  599. onItemSelectAll(diffKeys as string[], selected);
  600. },
  601. onSelect({ code }, selected) {
  602. console.log({code,selected})
  603. onItemSelect(code as string, selected);
  604. },
  605. selectedRowKeys: listSelectedKeys,
  606. };
  607. return (
  608. <BMSTable
  609. rowSelection={rowSelection}
  610. columns={columns as TransferItem[]}
  611. dataSource={filteredItems}
  612. size="small"
  613. loading={loading}
  614. bordered={false}
  615. rowKey={'code'}
  616. pagination={{ showTitle: false, pageSize: 10, showLessItems: false, simple: true }}
  617. tableAlertRender={false}
  618. style={{ pointerEvents: listDisabled ? 'none' : undefined }}
  619. onRow={({ code, disabled: itemDisabled }) => ({
  620. onClick: () => {
  621. if (itemDisabled || listDisabled) return;
  622. onItemSelect(code as string, !listSelectedKeys.includes(code as string));
  623. },
  624. })}
  625. />
  626. );
  627. }}
  628. </Transfer>
  629. )
  630. })
  631. const tableSearchHandle = () => {
  632. set_searchParams({
  633. name: searchKeywords
  634. })
  635. }
  636. //编辑按钮操作
  637. const editBtnHandle = async () => {
  638. let flag = false;
  639. if (ifEdit) {
  640. //保存操作
  641. if (currentSelectedTabKey == '1' && currentEditRow) {
  642. //收费项目
  643. console.log({currentEditRow});
  644. const result = {
  645. id: currentEditRow.id,
  646. unitCode: currentSelectedTreeNode.code,
  647. orderPointValue: `${currentEditRow.orderPointValue}`,
  648. coreFlag:currentEditCoreFlag
  649. }
  650. const resp = await editBillingItemData(result);
  651. if (resp) flag = true;
  652. }
  653. if (currentSelectedTabKey == '2' && currentEditRow) {
  654. //收费项目
  655. const result = {
  656. id: currentEditRow.id,
  657. unitCode: currentSelectedTreeNode.code,
  658. indicatorCode: currentEditRow.indicatorCode,
  659. indicatorName: currentEditRow.indicatorName,
  660. orderPointValue: currentEditRow.orderPointValue,
  661. executePointValue: currentEditRow.executePointValue
  662. }
  663. const resp = await editIndicItemData(result);
  664. if (resp) flag = true;
  665. }
  666. } else {
  667. //开启编辑模式
  668. set_ifEdit(true);
  669. }
  670. if (flag) {
  671. set_ifEdit(false);
  672. message.success('操作成功!');
  673. tableRef.current?.reload();
  674. }
  675. }
  676. const dataList: any[] = [];
  677. const getParentKey = (key: React.Key, tree: any[]): React.Key => {
  678. let parentKey: React.Key;
  679. for (let i = 0; i < tree.length; i++) {
  680. const node = tree[i];
  681. if (node.child) {
  682. if (node.child.some((item: { code: React.Key; }) => item.code === key)) {
  683. parentKey = node.code;
  684. } else if (getParentKey(key, node.child)) {
  685. parentKey = getParentKey(key, node.child);
  686. }
  687. }
  688. }
  689. return parentKey!;
  690. };
  691. const onTreeSearchKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  692. const { value } = e.target;
  693. const newExpandedKeys = dataList
  694. .map((item) => {
  695. if (item.name.indexOf(value) > -1) {
  696. return getParentKey(item.code, treeData);
  697. }
  698. return null;
  699. });
  700. const b = newExpandedKeys.filter((item, i, self) => item && self.indexOf(item) === i);
  701. setExpandedKeys(newExpandedKeys as React.Key[]);
  702. setSearchValue(value);
  703. setAutoExpandParent(true);
  704. }
  705. const onExpand = (newExpandedKeys: React.Key[]) => {
  706. setExpandedKeys(newExpandedKeys);
  707. setAutoExpandParent(false);
  708. };
  709. const generateList = (data: getTreeDataRespType[]) => {
  710. for (let i = 0; i < data.length; i++) {
  711. const node = data[i];
  712. const { code, name } = node;
  713. dataList.push({ code: code, name: name });
  714. if (node.child) {
  715. generateList(node.child);
  716. }
  717. }
  718. };
  719. generateList(treeData as any);
  720. const getTreeReqFunc = async (computeDate: string) => {
  721. const resp = await getTreeData(computeDate);
  722. set_treeData(resp);
  723. }
  724. const setTableColumn = () => {
  725. if (currentSelectedTabKey == '1') {
  726. set_tableColumn(billingTableColumn);
  727. }
  728. if (currentSelectedTabKey == '2') {
  729. set_tableColumn(indicTableColumn);
  730. }
  731. if (currentSelectedTabKey == '3') {
  732. set_tableColumn(nonCheckTableColumn);
  733. }
  734. }
  735. useEffect(() => {
  736. if (currentComputeDate) {
  737. getTreeReqFunc(currentComputeDate);
  738. }
  739. }, [currentComputeDate]);
  740. useEffect(() => {
  741. setTableColumn();
  742. }, [ifEdit]);
  743. useEffect(() => {
  744. tableRef.current?.reload();
  745. }, [currentSelectedTreeNode]);
  746. useEffect(() => {
  747. setTableColumn();
  748. }, [currentSelectedTabKey]);
  749. useEffect(() => {
  750. //初始化左侧树结构数据后
  751. if (treeData?.length > 0) {
  752. if (treeData[0].child && treeData[0].child.length > 0) {
  753. const [node, nodeParent] = getDeepestTreeData(treeData[0], 'child');
  754. set_currentSelectedTreeNode(node);
  755. setExpandedKeys([nodeParent.code]);
  756. }
  757. }
  758. }, [treeData]);
  759. useEffect(() => {
  760. set_tableColumn(billingTableColumn as ProColumns[]);
  761. getCurrentComputeDate();
  762. }, []);
  763. return (
  764. <div className='CheckUnitProjectSet'>
  765. <ModalForm title={`复制(${currentSelectedTreeNode?currentSelectedTreeNode.name:''})`} width={400} submitter={{
  766. render: (props, defaultDoms) => []
  767. }} open={ifShowModal} modalProps={{
  768. closable: false,
  769. }}>
  770. <TableSelecter
  771. ref={ref}
  772. record={undefined}
  773. tableSelecterColumn={tableSelecterColumn}
  774. ></TableSelecter>
  775. </ModalForm>
  776. <div className='leftTree'>
  777. <div className='search'>
  778. <Input
  779. className='searchInput'
  780. placeholder="请输入类目名称"
  781. size='small'
  782. allowClear
  783. style={{ marginBottom: 16 }}
  784. onChange={onTreeSearchKeyChange}
  785. suffix={
  786. <SearchIcon type='iconsousuo' />
  787. }
  788. />
  789. </div>
  790. {
  791. treeData && treeData.length > 0 && currentSelectedTreeNode && (
  792. <DirectoryTree
  793. fieldNames={{ title: 'name', key: 'code', children: 'child' }}
  794. rootStyle={{ height: '100%', paddingBottom: 50, overflowY: 'scroll', overflowX: 'hidden' }}
  795. onSelect={onSelect}
  796. onExpand={onExpand}
  797. expandedKeys={expandedKeys}
  798. autoExpandParent={autoExpandParent}
  799. selectedKeys={[currentSelectedTreeNode.code]}
  800. blockNode={true}
  801. icon={() => null}
  802. titleRender={
  803. (nodeData: any) => {
  804. const strTitle = nodeData.name as string;
  805. const index = strTitle.indexOf(searchValue);
  806. const beforeStr = strTitle.substring(0, index);
  807. const afterStr = strTitle.slice(index + searchValue.length);
  808. const title =
  809. index > -1 ? (
  810. <span>
  811. {beforeStr}
  812. <span className="site-tree-search-value" style={{ color: 'red', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{searchValue}</span>
  813. {afterStr}
  814. </span>
  815. ) : (
  816. <span className='strTitle'>{strTitle}</span>
  817. );
  818. return <div style={{
  819. display: 'flex', flexDirection: 'row',
  820. width: '100%',
  821. justifyContent: 'flex-start', alignItems: 'center', height: 32,
  822. borderRadius: '4px',
  823. overflow: 'hidden',
  824. color: '#17181A',
  825. textOverflow: 'ellipsis',
  826. whiteSpace: 'nowrap'
  827. }}>{title}</div>
  828. }
  829. }
  830. defaultSelectedKeys={[treeData[0].child[0].code]}
  831. treeData={treeData as unknown as DataNode[]}
  832. // treeData={treeDataNew}
  833. switcherIcon={(props: any) => {
  834. const { expanded } = props;
  835. return !expanded ? <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={expandedIcon} /> : <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={closeIcon} />
  836. }}
  837. />
  838. )
  839. }
  840. </div>
  841. {/* <div style={{width:16,height:'92vh',background:'#F5F7FA'}}></div> */}
  842. <div className='rightContent'>
  843. <BMSPagecontainer title={false} ghost>
  844. <div></div>
  845. <Tabs
  846. defaultActiveKey="1"
  847. onChange={onTabChange}
  848. items={[
  849. {
  850. label: `收费项目`,
  851. key: '1',
  852. },
  853. {
  854. label: `指标项目`,
  855. key: '2',
  856. },
  857. {
  858. label: `非考核项目`,
  859. key: '3',
  860. },
  861. ]}
  862. />
  863. {
  864. currentSelectedTabKey == '1' && (
  865. <div className='tabContent'>
  866. <div className='tableToolbar'>
  867. <div className='search'>
  868. <span>检索:</span><Input className='searchInput' allowClear onChange={(e) => {
  869. set_searchKeywords(e.target.value)
  870. if (e.target.value.length == 0) {
  871. set_searchParams({
  872. ...searchParams,
  873. name: e.target.value
  874. })
  875. }
  876. }} placeholder="请输入项目名称" suffix={
  877. <IconFont type="iconsousuo" onClick={() => tableSearchHandle()} />
  878. } />
  879. </div>
  880. <div className={'btnGroup'}>
  881. <span key="2" onClick={() => openCopyHandleModal()}>复制</span>
  882. <span key="3" onClick={() => openTransfer()}>添加</span>
  883. </div>
  884. </div>
  885. {currentSelectedTreeNode && <BMSTable params={searchParams} actionRef={tableRef} rowKey='id' columns={[...tableColumn, {
  886. title: '操作',
  887. key: 'option',
  888. width: 140,
  889. valueType: 'option',
  890. render: (text, record: any) => [
  891. <a key={'edit'} onClick={() => {
  892. if (!ifEdit) {
  893. set_ifEdit(true);
  894. set_currentEditRow(record)
  895. }
  896. if (ifEdit) {
  897. editBtnHandle();
  898. }
  899. }}>{(ifEdit&&currentEditRow?.id == record.id )? '保存' : '编辑'}</a>,
  900. <Fragment key={'cancel'}>{(ifEdit&&currentEditRow?.id == record.id ) && <a onClick={() => set_ifEdit(false)}>取消</a>}</Fragment>,
  901. <Popconfirm key="popconfirm" title={`确认删除吗?`} okText="是" cancelText="否" onConfirm={() => delHandle(record)}>
  902. {(currentEditRow?.id != record.id || !ifEdit) && <a key={'del'}>删除</a>}
  903. </Popconfirm>
  904. ],
  905. }]} request={(params, sort, filter) => getTableData('BILL', params, sort, filter)} />}
  906. </div>
  907. )
  908. }
  909. {
  910. currentSelectedTabKey == '2' && (
  911. <div className='tabContent'>
  912. <div className='tableToolbar'>
  913. <div className='search'>
  914. <span>检索:</span><Input className='searchInput' allowClear placeholder="请输入项目名称" onChange={(e) => {
  915. set_searchKeywords(e.target.value);
  916. if (e.target.value.length == 0) {
  917. set_searchParams({
  918. ...searchParams,
  919. name: ''
  920. });
  921. }
  922. }} suffix={
  923. <IconFont type="iconsousuo" onClick={() => tableSearchHandle()} />
  924. } />
  925. </div>
  926. <div className={'btnGroup'}>
  927. <span key="2" onClick={() => openCopyHandleModal()}>复制</span>
  928. <span key="3" onClick={() => openTransfer()}>添加</span>
  929. </div>
  930. </div>
  931. {currentSelectedTreeNode && <BMSTable actionRef={tableRef} params={searchParams} rowKey='id' columns={[...tableColumn, {
  932. title: '操作',
  933. key: 'option',
  934. width: 140,
  935. valueType: 'option',
  936. render: (text, record: any) => [
  937. <a key={'edit'} onClick={() => {
  938. if (!ifEdit) {
  939. set_ifEdit(true);
  940. set_currentEditRow(record)
  941. }
  942. if (ifEdit) {
  943. editBtnHandle();
  944. }
  945. }}>{(ifEdit&&currentEditRow?.id == record.id ) ? '保存' : '编辑'}</a>,
  946. <Fragment key={'cancel'}>{(ifEdit&&currentEditRow?.id == record.id ) && <a onClick={() => set_ifEdit(false)}>取消</a>}</Fragment>,
  947. <Popconfirm key="popconfirm" title={`确认删除吗?`} okText="是" cancelText="否" onConfirm={() => delHandle(record)}>
  948. {(currentEditRow?.id != record.id || !ifEdit) && <a key={'del'}>删除</a>}
  949. </Popconfirm>
  950. ],
  951. }]} request={(params, sort, filter) => getTableData('INDIC', params, sort, filter)} />}
  952. </div>
  953. )
  954. }
  955. {
  956. currentSelectedTabKey == '3' && (
  957. <div className='tabContent'>
  958. <div className='tableToolbar'>
  959. <div className='search'>
  960. <span>检索:</span><Input className='searchInput' allowClear placeholder="请输入项目名称" onChange={(e) => {
  961. set_searchKeywords(e.target.value);
  962. if (e.target.value.length == 0) {
  963. set_searchParams({
  964. ...searchParams,
  965. name: ''
  966. });
  967. }
  968. }} suffix={
  969. <IconFont type="iconsousuo" onClick={() => tableSearchHandle()} />
  970. } />
  971. </div>
  972. <div className={'btnGroup'}>
  973. <span key="2" onClick={() => openCopyHandleModal()}>复制</span>
  974. <span key="3" onClick={() => openTransfer()}>添加</span>
  975. </div>
  976. </div>
  977. {currentSelectedTreeNode && <BMSTable actionRef={tableRef} params={searchParams} rowKey='id' columns={[...tableColumn,{
  978. title: '操作',
  979. key: 'option',
  980. valueType: 'option',
  981. render: (text, record: any) => [
  982. <Popconfirm key="popconfirm" title={`确认删除吗?`} okText="是" cancelText="否" onConfirm={() => delHandle(record)}>
  983. { <a key={'del'}>删除</a>}
  984. </Popconfirm>
  985. ],
  986. }]} request={(params, sort, filter) => getTableData('NONCHECK', params, sort, filter)} />}
  987. </div>
  988. )
  989. }
  990. </BMSPagecontainer>
  991. </div>
  992. </div>
  993. );
  994. };
  995. export default CheckUnitProjectSet;