index.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /*
  2. * @Author: code4eat awesomedema@gmail.com
  3. * @Date: 2023-03-03 11:30:33
  4. * @LastEditors: code4eat awesomedema@gmail.com
  5. * @LastEditTime: 2024-06-11 10:44:27
  6. * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/index.tsx
  7. * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  8. */
  9. import { createFromIconfontCN } from '@ant-design/icons';
  10. import { ModalForm, ProFormDatePicker } from '@ant-design/pro-form';
  11. import FormItem from 'antd/es/form/FormItem';
  12. import { DatePicker, Input, message, Modal, Dropdown } from 'antd';
  13. import { useEffect, useRef, useState } from 'react';
  14. import type { MenuProps } from 'antd';
  15. import { getData, downloadTemplateReq, importDataPost, getIncomeCostDataImportErrList, cancelIncomeCostDataImport, rebackIncomeCostDataImport } from './service';
  16. import './style.less';
  17. import moment from 'moment';
  18. import 'moment/locale/zh-cn';
  19. import locale from 'antd/es/date-picker/locale/zh_CN';
  20. import KCIMPagecontainer from '@/components/KCIMPageContainer';
  21. import { KCIMTable } from '@/components/KCIMTable';
  22. import KCIMUpload from '@/components/KCIMUpload';
  23. import { TableDataResponse } from 'typings';
  24. import { ActionType, ProColumns, ProFormSelect } from '@ant-design/pro-components';
  25. import { importEmpCostDataPost } from '../empCostDataImport/service';
  26. import { importPatientInfoDataPost } from '../patientInfoImport/service';
  27. import { importPatientChargeItemDataPost } from '../patientChargeItemsImport/service';
  28. const IconFont = createFromIconfontCN({
  29. scriptUrl: '',
  30. });
  31. const { host } = location;
  32. const currentData = `${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`
  33. let currentImportkey: any = undefined;
  34. const items: MenuProps['items'] = [
  35. {
  36. key: '1',
  37. label: (
  38. <a target="_blank" rel="noopener noreferrer" onClick={() => { downloadTemplateReq('/gateway/costAccount/excel/getShareParamTemplate'); currentImportkey = 1 }}>
  39. 成本分摊参数模板
  40. </a>
  41. ),
  42. },
  43. {
  44. key: '2',
  45. label: (
  46. <a target="_blank" rel="noopener noreferrer" onClick={() => { downloadTemplateReq('/gateway/costAccount/excel/getImportIncomeProductAccountTemplate'); currentImportkey = 2 }} >
  47. 收入数据模板
  48. </a>
  49. ),
  50. },
  51. {
  52. key: '3',
  53. label: (
  54. <a target="_blank" rel="noopener noreferrer" onClick={() => { downloadTemplateReq('/gateway/costAccount/excel/getImportCostProductAccountTemplate'); currentImportkey = 3 }}>
  55. 成本数据模板
  56. </a>
  57. ),
  58. },
  59. {
  60. key: '4',
  61. label: (
  62. <a target="_blank" rel="noopener noreferrer" onClick={() => { downloadTemplateReq('/gateway/costAccount/computeImport/exportEmpCostList'); currentImportkey = 4 }}>
  63. 人事成本数据
  64. </a>
  65. ),
  66. },
  67. {
  68. key: '5',
  69. label: (
  70. <a target="_blank" rel="noopener noreferrer" onClick={() => { downloadTemplateReq('/gateway/costAccount/computeImport/exportPatientInfo'); currentImportkey = 5 }}>
  71. 患者信息
  72. </a>
  73. ),
  74. },
  75. {
  76. key: '6',
  77. label: (
  78. <a target="_blank" rel="noopener noreferrer" onClick={() => { downloadTemplateReq('/gateway/costAccount/computeImport/exportPatientItem'); currentImportkey = 6 }}>
  79. 患者收费项目
  80. </a>
  81. ),
  82. },
  83. ];
  84. let _computeDate: string | undefined = undefined;
  85. export default function IncomeCostDataImport({ date, btnPerm }: { date: string, btnPerm: string }) {
  86. const [computeDate, set_computeDate] = useState(date);
  87. const [tableDataFilterParams, set_tableDataFilterParams] = useState<any>({ computeDate: currentData });
  88. const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState('');
  89. const tableRef = useRef<ActionType>();
  90. const [currentEditRow, set_currentEditRow] = useState<undefined | any>(undefined);
  91. const [ifShowGetBtn, set_ifShowGetBtn] = useState(false);
  92. const [ifShowCancelBtn, set_ifShowCancelBtn] = useState(false);
  93. const columns: ProColumns[] = [
  94. {
  95. title: '文件编号',
  96. dataIndex: 'id',
  97. width: '15%',
  98. },
  99. {
  100. title: '文件名称',
  101. width:'40%',
  102. dataIndex: 'fileName',
  103. renderText(text, record, index, action) {
  104. const {fileUrl} = record;
  105. const userData = localStorage.getItem('userData');
  106. const { token } = JSON.parse(userData as string);
  107. return <a key='download' href={`${fileUrl}?token=${token}`} target="_blank">{text}</a>
  108. },
  109. },
  110. {
  111. title: '导入类型',
  112. width: '15%',
  113. dataIndex: 'fileType',
  114. },
  115. {
  116. title: '导入人员',
  117. width: '15%',
  118. dataIndex: 'userName',
  119. },
  120. {
  121. title: '导入时间',
  122. width: '15%',
  123. dataIndex: 'dateTime',
  124. },
  125. {
  126. title: '操作',
  127. width: '10%',
  128. dataIndex: 'option',
  129. renderText(text, record) {
  130. const { errStatus, rollbackStatus } = record;
  131. return [
  132. <span key='act' style={{ color: '#3377FF', cursor: 'pointer' }}
  133. onClick={() => {
  134. optionBtnGrouphandle(errStatus, record)
  135. }}>{errStatus == 1 ? '错误详情' :rollbackStatus == 1?'复原导入':'撤销导入'}</span>
  136. ]
  137. },
  138. }
  139. ];
  140. const getTableData = async (params: any): Promise<TableDataResponse | any[]> => {
  141. const resp = await getData({ ...params, ...tableDataFilterParams });
  142. if (resp) {
  143. const { list, totalCount, pageSize, current, totalPage } = resp;
  144. if (totalCount == 0 && current != 1) {
  145. return getTableData({ ...params, current: current - 1 });
  146. } else {
  147. return {
  148. data: list,
  149. success: true,
  150. total: totalCount,
  151. pageSize: pageSize,
  152. totalPage: totalPage,
  153. };
  154. }
  155. }
  156. return [];
  157. };
  158. const tableDataSearchHandle = (paramName: string) => {
  159. set_tableDataFilterParams({
  160. ...tableDataFilterParams,
  161. [`${paramName}`]: tableDataSearchKeywords
  162. })
  163. }
  164. const getErrorInfo = async (id: number) => {
  165. const resp = await getIncomeCostDataImportErrList({ id });
  166. if (resp) {
  167. return {
  168. data: resp,
  169. success: true,
  170. };
  171. } else {
  172. return []
  173. }
  174. }
  175. const optionBtnGrouphandle = async (errStatus: number, record: any) => {
  176. set_currentEditRow(record);
  177. const { id,rollbackStatus } = record;
  178. if (errStatus != 1) {
  179. let resp = undefined
  180. if(rollbackStatus != 1){
  181. //撤销
  182. resp = await cancelIncomeCostDataImport(id,date);
  183. }
  184. if(rollbackStatus == 1){
  185. //复原
  186. resp = await rebackIncomeCostDataImport(id,date);
  187. }
  188. if (resp){
  189. message.success(rollbackStatus == 1?'还原成功!':'撤销成功!');
  190. tableRef.current?.reload();
  191. }
  192. } else {
  193. Modal.info({
  194. title: '错误详情',
  195. icon: '',
  196. content: (
  197. <>
  198. <KCIMTable
  199. rowKey='id'
  200. columns={[
  201. {
  202. title: '行数',
  203. width: 50,
  204. dataIndex: 'total',
  205. },
  206. {
  207. title: '错误信息',
  208. dataIndex: 'errMessage',
  209. ellipsis: true
  210. }
  211. ]}
  212. request={() => getErrorInfo(id)}
  213. />
  214. </>
  215. )
  216. })
  217. }
  218. }
  219. const importData = () => {
  220. return (
  221. <ModalForm
  222. width={360}
  223. title={`导入数据`}
  224. trigger={
  225. <a className="import" key="3">
  226. 导入
  227. </a>
  228. }
  229. initialValues={{dateTime:date}}
  230. submitter={{
  231. render: (props, defaultDoms) => {
  232. const needBtn = defaultDoms.filter((b) => {
  233. return b.key != 'rest';
  234. });
  235. return [
  236. // <Button
  237. // key="ok"
  238. // onClick={auditType == '0' ? () => downloadTemplate(index) : () => { }}
  239. // >
  240. // 下载模板
  241. // </Button>,
  242. ...needBtn,
  243. ];
  244. },
  245. }}
  246. onFinish={async (values) => {
  247. try {
  248. const {
  249. importFile: { fileList },
  250. fileType
  251. } = values;
  252. if (fileType <= 3) {
  253. let formData = new FormData();
  254. formData.append('file', fileList[0].originFileObj);
  255. formData.append('dateTime', date);
  256. formData.append('fileType', fileType);
  257. const resp = await importDataPost(formData);
  258. if (resp) {
  259. tableRef.current?.reload();
  260. return true;
  261. }
  262. } else {
  263. if (fileType == 4) {
  264. //人事成本
  265. let formData = new FormData();
  266. formData.append('file', fileList[0].originFileObj);
  267. formData.append('computeDate', date);
  268. const resp = await importEmpCostDataPost(formData);
  269. if (resp) {
  270. tableRef.current?.reload();
  271. return true;
  272. }
  273. }
  274. if (fileType == 5) {
  275. //患者信息
  276. let formData = new FormData();
  277. formData.append('file', fileList[0].originFileObj);
  278. formData.append('computeDate', date);
  279. const resp = await importPatientInfoDataPost(formData);
  280. if (resp) {
  281. tableRef.current?.reload();
  282. return true;
  283. }
  284. }
  285. if (fileType == 6) {
  286. //患者收费项目
  287. let formData = new FormData();
  288. formData.append('file', fileList[0].originFileObj);
  289. formData.append('computeDate', date);
  290. const resp = await importPatientChargeItemDataPost(formData);
  291. if (resp) {
  292. tableRef.current?.reload();
  293. return true;
  294. }
  295. }
  296. }
  297. } catch (err) {
  298. console.log({ err });
  299. }
  300. }}
  301. >
  302. {/* <ProFormDatePicker label='数据所属年月:' name='dateTime'
  303. width={328}
  304. fieldProps={{
  305. picker: 'month',
  306. locale: locale,
  307. format: 'YYYY-MM'
  308. }}
  309. disabled
  310. placeholder="选择年月"
  311. rules={[
  312. {
  313. required: true,
  314. message: '请选择年月',
  315. },
  316. ]}
  317. /> */}
  318. <ProFormSelect
  319. rules={[
  320. {
  321. required: true,
  322. message: '请选择数据类型',
  323. },
  324. ]}
  325. options={[
  326. {
  327. value: 1,
  328. label: '成本分摊参数值',
  329. },
  330. {
  331. value: 2,
  332. label: '收入数据',
  333. },
  334. {
  335. value: 3,
  336. label: '成本数据',
  337. },
  338. {
  339. value: 4,
  340. label: '人事成本数据',
  341. },
  342. {
  343. value: 5,
  344. label: '患者信息',
  345. },
  346. {
  347. value: 6,
  348. label: '患者收费项目',
  349. },
  350. ]}
  351. name="fileType"
  352. label="选择数据类型"
  353. />
  354. <FormItem name={'importFile'}>
  355. <KCIMUpload ifShowTemplateDownload={false} ifShowTip={false} />
  356. </FormItem>
  357. </ModalForm>
  358. );
  359. };
  360. useEffect(() => {
  361. if (date) {
  362. set_tableDataFilterParams({
  363. ...tableDataFilterParams,
  364. computeDate: date,
  365. });
  366. _computeDate = date
  367. }
  368. }, [date]);
  369. useEffect(() => {
  370. if (btnPerm) {
  371. const [a, b] = btnPerm.split('|');
  372. set_ifShowCancelBtn(b == '1');
  373. set_ifShowGetBtn(a == '1')
  374. }
  375. }, [btnPerm])
  376. useEffect(() => { }, []);
  377. return (
  378. <div className="IncomeCostDataImport" >
  379. <div className="toolBar">
  380. <div className="filter">
  381. {/* <div className="filterItem">
  382. {
  383. <div className="search">
  384. <span>核算年月:</span>
  385. <DatePicker
  386. onChange={(data, dateString) => {
  387. set_computeDate(dateString);
  388. set_tableDataFilterParams({
  389. ...tableDataFilterParams,
  390. computeDate: dateString,
  391. });
  392. }}
  393. picker="month"
  394. locale={locale}
  395. defaultValue={moment(`${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`, 'YYYY-MM')}
  396. format="YYYY-MM"
  397. placeholder="选择年月"
  398. />
  399. </div>
  400. }
  401. </div> */}
  402. <div className='filterItem' style={{ width: 205 }}>
  403. <span className='label' style={{ whiteSpace: 'nowrap' }}> 检索:</span>
  404. <Input placeholder={'文件名称'} allowClear
  405. suffix={
  406. <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('fileName')} />
  407. }
  408. onChange={(e) => {
  409. set_tableDataSearchKeywords(e.target.value);
  410. if (e.target.value.length == 0) {
  411. set_tableDataFilterParams({
  412. ...tableDataFilterParams,
  413. fileName: ''
  414. });
  415. }
  416. }}
  417. onPressEnter={(e) => {
  418. set_tableDataFilterParams({
  419. ...tableDataFilterParams,
  420. fileName: ((e.target) as HTMLInputElement).value
  421. });
  422. }}
  423. />
  424. </div>
  425. </div>
  426. <div className="btnGroup">
  427. <>
  428. <Dropdown menu={{ items }} placement="bottomLeft">
  429. <span className='normal'>模板下载</span>
  430. </Dropdown>
  431. {importData()}
  432. </>
  433. </div>
  434. </div>
  435. <div style={{ marginTop: 16 }}>
  436. <KCIMTable
  437. columns={columns}
  438. actionRef={tableRef}
  439. rowKey="id"
  440. scroll={{y:`calc(100vh - 259px)`}}
  441. params={tableDataFilterParams}
  442. request={(params) => getTableData(params)}
  443. />
  444. </div>
  445. </div>
  446. );
  447. }