index.tsx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. /*
  2. * @Author: your name
  3. * @Date: 2022-03-08 10:41:15
  4. * @LastEditTime: 2022-03-09 18:14:12
  5. * @LastEditors: Please set LastEditors
  6. * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  7. * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/components/articleDetailModule/index.tsx
  8. */
  9. import MccsEditableTable from '@/components/MccsEditableTable';
  10. import MccsLightTable from '@/components/MccsLightTable';
  11. import { getScoreColor } from '@/constant';
  12. import TextArea from 'antd/lib/input/TextArea';
  13. import React, { useRef, useEffect, useState } from 'react'
  14. import { useModel } from 'umi';
  15. import { ActType } from '../..';
  16. import { getCurrentLevelTable, getTaizhangDirectoryTable } from '../../server';
  17. import { Input, Switch, Select } from 'antd'
  18. import './style.less';
  19. import SetDrawer from './drawer';
  20. const { Option } = Select;
  21. const myEvent = new Event('resize');
  22. const MccsLightTableColumns = [
  23. {
  24. key: 'gradeLevel',
  25. title: '档次',
  26. width: 10
  27. },
  28. {
  29. key: 'directory',
  30. title: '名称',
  31. width: 60
  32. },
  33. {
  34. key: 'accountType',
  35. title: '类型',
  36. },
  37. {
  38. key: 'accountStatus',
  39. title: '需要台账',
  40. render: (record: any) => {
  41. return record.accountStatus == 0 ? '否' : '是'
  42. }
  43. },
  44. ]
  45. const ArticleDetail = ({ isModeTwo = false }) => {
  46. const { articleManagement } = useModel('allModels');
  47. const {
  48. isLeaf,
  49. treeData,
  50. getTableData,
  51. currentActivedTree,
  52. setCurrentActivedTree,
  53. scoreList,
  54. getDepartmentRequest,
  55. departmentManagers,
  56. getDepartment,//获取责任单位
  57. currentSelectedActObj,
  58. ...restModelData
  59. } = articleManagement;
  60. // console.log({isModeTwo});
  61. const [scrollAreaH, setScrollAreaH] = useState(100);
  62. const leafContentRef = useRef<HTMLDivElement>(null);
  63. const scrollContentRef = useRef<HTMLDivElement>(null);
  64. const [ifCollapse, setifCollapse] = useState(false);
  65. const mccsEditableTableColumns = [
  66. {
  67. title: '名称',
  68. dataIndex: 'directory',
  69. width: '50%',
  70. align: 'center',
  71. formItemProps: () => {
  72. return {
  73. rules: [{ required: true, message: '此项为必填项' }],
  74. };
  75. },
  76. },
  77. {
  78. title: '档次',
  79. dataIndex: 'grade',
  80. width: '15%',
  81. align: 'center',
  82. formItemProps: () => {
  83. return {
  84. rules: [{ required: true, message: '此项为必填项' }],
  85. };
  86. },
  87. renderFormItem: (_: any, config: any, form: any) => {
  88. const { isEditable } = config;
  89. return isEditable ? (
  90. <Select
  91. mode='multiple'
  92. placeholder='请选择'
  93. >
  94. {
  95. restModelData.gradeOptions.map((item, index) => (
  96. <Option value={item.value} key={index}>{item.label}</Option>
  97. ))
  98. }
  99. </Select>
  100. ) : <Input />;
  101. },
  102. render: (_: any, row: any) => {
  103. return typeof _ == 'object' ? _.join(',') : _;
  104. },
  105. },
  106. {
  107. title: '类型',
  108. dataIndex: 'accountType',
  109. align: 'center',
  110. width: '15%',
  111. formItemProps: () => {
  112. return {
  113. rules: [{ required: true, message: '此项为必填项' }],
  114. };
  115. },
  116. renderFormItem: (_: any, { isEditable }: { isEditable: boolean }, form: any) => {
  117. return isEditable ? (
  118. <Select
  119. placeholder='请选择'
  120. >
  121. {
  122. restModelData.accountTypeOptions.map((item, index) => (
  123. <Option value={item.value} key={index}>{item.label}</Option>
  124. ))
  125. }
  126. </Select>
  127. ) : <Input />;
  128. },
  129. },
  130. {
  131. title: '台账上传',
  132. align: 'center',
  133. dataIndex: 'accountStatus',
  134. width: '10%',
  135. valueType: 'switch',
  136. render: (_: any, row: any) => {
  137. return (
  138. <Switch size='small' disabled checked={row.accountStatus} />
  139. )
  140. },
  141. },
  142. ]
  143. const onTextAreaChange = (e: React.ChangeEvent<HTMLTextAreaElement>, level: string) => {
  144. //更改执行情况说明数据
  145. //首先找出要更新的项,再进行整体替换
  146. if (restModelData.selectedSelfEvolution) {
  147. const editTargetLevel = restModelData.selectedSelfEvolution.label; //目标等级
  148. //找出目标等级下正在更新的level
  149. const editImplementationDataItemIndex = restModelData.implementationData[editTargetLevel].findIndex(item => item.level == level);
  150. //拷贝旧的目标等级数据
  151. let _cpOldImplemetationItem = restModelData.implementationData[editTargetLevel];
  152. //将新的编辑内容赋值给正在编辑的目标下的level
  153. _cpOldImplemetationItem[editImplementationDataItemIndex].note = e.target.value;
  154. if (editImplementationDataItemIndex != -1) {
  155. restModelData.setImplementationData({
  156. ...restModelData.implementationData,
  157. //插入更新
  158. [editTargetLevel]: _cpOldImplemetationItem
  159. }
  160. )
  161. }
  162. }
  163. }
  164. const taizhangDataDerectoryEditHandle = (data: any, actType: ActType) => {
  165. //台账资料目录编辑回调
  166. const version = restModelData.leafData?.reviewArticle.version;
  167. let prevData = restModelData.taizhangDataDirectoryCommitList;
  168. const numStr = restModelData.leafData?.reviewArticle.numStr;
  169. if (actType == ActType.DEL && (typeof data.id == 'string')) {
  170. //如果是删除操作且删除的不是数据库已有数据时,剔除之前暂时保留数据
  171. prevData = prevData.filter(item => item.directory != data.directory);
  172. restModelData.setTaizhangDataDirectoryCommitList([...prevData]);
  173. return;
  174. }
  175. const replaceData = (item: any, index: number) => {
  176. prevData[index] = {
  177. ...item, dataStatus: actType, version: version ? version : '',
  178. grade: data.grade.join(','), numStr: numStr, accountStatus: data.accountStatus ? '1' : '0'
  179. };
  180. restModelData.setTaizhangDataDirectoryCommitList([...prevData]);
  181. }
  182. const findeIndex = prevData.findIndex(item => item.id == data.id);
  183. if (findeIndex != -1) {
  184. //之前已有操作记录的,替换为最新状态
  185. replaceData(data, findeIndex);
  186. return;
  187. }
  188. restModelData.setTaizhangDataDirectoryCommitList(
  189. [...prevData, {
  190. ...data, dataStatus: actType, version: version ? version : '',
  191. grade: data.grade.join(','), numStr: numStr, accountStatus: data.accountStatus ? '1' : '0'
  192. }]
  193. )
  194. }
  195. const followWindowResize = (num?: number, leafContentHeight?: number) => {
  196. const _num = num ? num : 0;
  197. if (leafContentRef.current) {
  198. const leafContentH = leafContentHeight ? leafContentHeight : (leafContentRef.current.clientHeight); //className为leafContent的div
  199. const headerH = 48 + 16;
  200. const scoreH = isModeTwo ? (60 + 32) : 0;
  201. const h = window.innerHeight - (leafContentH + headerH + scoreH);
  202. // console.log({leafContentH,headerH,scoreH,h});
  203. setScrollAreaH(h - _num);
  204. }
  205. }
  206. const telescopicBtnHandle = (e: React.MouseEvent) => {
  207. //展开/收起
  208. e.preventDefault();
  209. setifCollapse(!ifCollapse);
  210. if (!ifCollapse) {
  211. followWindowResize(0, 55);
  212. } else {
  213. followWindowResize(0);
  214. }
  215. // window.dispatchEvent(myEvent);
  216. if (scrollContentRef.current) {
  217. scrollContentRef.current.scrollTop = 0
  218. }
  219. }
  220. const articleSetBtnHandle = () => {
  221. //条文设置
  222. // console.log({ articleSettingFormInit });
  223. restModelData.setDrawerFormType('ARTICLE_SET');
  224. restModelData.setDrawerVisible(true);
  225. }
  226. const setEditPageStatus = () => {
  227. //更改页面的编辑状态
  228. restModelData.setEditMode(!restModelData.editMode);
  229. }
  230. useEffect(() => {
  231. if (restModelData.editMode) {
  232. followWindowResize(40);
  233. } else {
  234. followWindowResize(0);
  235. }
  236. }, [restModelData.editMode]);
  237. useEffect(() => {
  238. // followWindowResize();
  239. if (isLeaf) {
  240. setTimeout(() => {
  241. //首次加载叶子节点内容触发一次
  242. window.dispatchEvent(myEvent);
  243. document.body.style.overflowY = 'hidden'; //叶子节点下锁住页面滚动
  244. }, 500);
  245. //获取单位列表
  246. }
  247. if (!isLeaf) {
  248. document.body.style.overflowY = 'auto'; //非叶子节点放开
  249. }
  250. }, [isLeaf]);
  251. useEffect(() => {
  252. window.addEventListener("resize", () => followWindowResize());
  253. return () => {
  254. window.removeEventListener("resize", () => followWindowResize());
  255. }
  256. }, []);
  257. return (
  258. <div className='articleDetailContainer' >
  259. {
  260. //抽屉
  261. }
  262. <SetDrawer />
  263. {
  264. isLeaf && (
  265. <div className={ifCollapse ? 'leafContent collapse' : 'leafContent'} ref={leafContentRef}>
  266. <div className='leafContentTitle'>{currentActivedTree ? currentActivedTree.title : ''}</div>
  267. <div className='peopleGroup'>
  268. <span>条文组别:</span>
  269. <span>{restModelData.leafData?.reviewArticle?.accountType}</span>
  270. <span>负责单位:</span>
  271. <span>{restModelData.leafData?.reviewArticle?.responsibilityDepartmentName}</span>
  272. <span>负责人:</span>
  273. <span>{restModelData.leafData?.reviewArticle?.responsibilityUserName}</span>
  274. </div>
  275. {/* <MccsScoreBanner list={scoreList} /> */}
  276. <div className='scoreRow'>
  277. <div className='scoreInfo'>
  278. {
  279. scoreList.map((item, index) => {
  280. return (
  281. <div key={index} className='scoreBlock'>
  282. {item.label}
  283. {item.value && item.value != '-' ? (<span style={{ color: getScoreColor(item.value) }}>{item.value}</span>) : ' -'}
  284. </div>
  285. )
  286. })
  287. }
  288. </div>
  289. {
  290. //条文页面
  291. !restModelData.moduleMode && <div className='ruleSettingBtn' onClick={articleSetBtnHandle}>条文设置</div>
  292. }
  293. {
  294. //台账上传页面且非编辑状态下
  295. (restModelData.moduleMode && !restModelData.editMode && restModelData.hasEditAuthority) && <div className='editPageBtn' onClick={() => setEditPageStatus()}>{restModelData.editMode ? '取消编辑' : '开启编辑'}</div>
  296. }
  297. </div>
  298. <div className='scoreGradeDetail'>
  299. {
  300. restModelData.leafData?.pfmViewRuleDetailDataVoList.map((item, index) => (
  301. <div className='scoreGradeDetailList' key={index}>
  302. <div className='head'>{item.evaluation}</div>
  303. <div className='detail'>
  304. {
  305. item.viewRuleAndLevelVos && item.viewRuleAndLevelVos.map((v, k) => (
  306. <div className='textLine' key={k}>{`${v.grade} ${v.detail}`}</div>
  307. ))
  308. }
  309. </div>
  310. </div>
  311. ))
  312. }
  313. </div>
  314. <div className={ifCollapse ? 'telescopicBtn collapse' : 'telescopicBtn'} onClick={e => telescopicBtnHandle(e)}></div>
  315. </div>
  316. )
  317. }
  318. {
  319. isLeaf && isModeTwo && (
  320. <div className='selfEvaluationWrap'>
  321. <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', width: '100%', }}>
  322. <div className='selfEvaluation'>
  323. 自评等级
  324. {!restModelData.editMode && (
  325. <span style={{ color: getScoreColor(restModelData.leafData ? restModelData.leafData.reviewArticle.selfEvaluation : '') }}>{restModelData.leafData?.reviewArticle.selfEvaluation ? restModelData.leafData?.reviewArticle.selfEvaluation : '-'}</span>
  326. )}
  327. </div>
  328. {
  329. restModelData.editMode && (
  330. <div className='wrap' style={{ width: '60%', display: 'flex', flexDirection: 'row', justifyContent: 'flex-end' }}>
  331. {
  332. (restModelData.targetScores).map((item, index) => (
  333. <div className={restModelData.selectedSelfEvolution?.label == item.label ? 'tab on' : 'tab'} key={index} onClick={() => restModelData.onSelfEvolutionTabChange(item)}>{item.label}</div>
  334. ))
  335. }
  336. </div>
  337. )
  338. }
  339. </div>
  340. </div>
  341. )
  342. }
  343. {
  344. isLeaf && restModelData.leafData && (
  345. //台账上传页面时,背景色统一白色,cardWrap提供容器实现上下滑动
  346. <div className={isModeTwo ? 'cardWrap isModeTwo' : 'cardWrap'} style={{ marginTop: '16px', height: `${scrollAreaH - 16}px` }} ref={scrollContentRef}>
  347. <div>
  348. {
  349. //渲染执行情况说明
  350. /**
  351. * 满足条件:
  352. * 1.存在自评等级从接口获取或手动点击选择
  353. * 2.implementationData里有当前等级的数据
  354. */
  355. (restModelData.selectedSelfEvolution && restModelData.implementationData[restModelData.selectedSelfEvolution.label])
  356. && restModelData.implementationData[restModelData.selectedSelfEvolution.label].map((item, index) => {
  357. return (
  358. <div className='card' key={index} style={{ marginBottom: isModeTwo ? 0 : '16px', paddingBottom: isModeTwo ? 0 : '16px', paddingTop: isModeTwo ? 0 : '16px' }}>
  359. <div className='cardTitle' style={{ marginBottom: isModeTwo ? '8px' : '16px' }}>{`执行情况说明(等级${item.level})`}</div>
  360. <TextArea allowClear showCount maxLength={2000}
  361. autoSize={{
  362. minRows: 5,
  363. maxRows: 20
  364. }}
  365. disabled={!restModelData.editMode} value={item.note}
  366. onChange={e => onTextAreaChange(e, item.level)}
  367. style={{ marginBottom: 20 }} />
  368. {
  369. !isModeTwo && (
  370. <MccsLightTable
  371. columns={MccsLightTableColumns}
  372. request={(current, pageSize) => getCurrentLevelTable({
  373. level: item.level,
  374. numStr: currentSelectedActObj ? (currentSelectedActObj.numStr?currentSelectedActObj.numStr:currentSelectedActObj.code) : 'null',
  375. version: restModelData.leafData ? (restModelData.leafData.reviewArticle.version) : 'null',
  376. current,
  377. pageSize
  378. })}
  379. />
  380. )
  381. }
  382. </div>
  383. )
  384. })
  385. }
  386. </div>
  387. <div>
  388. {
  389. //台帐下展示
  390. (isModeTwo && restModelData.leafData) && (
  391. <MccsEditableTable
  392. bordered={true}
  393. controlled={false}
  394. edit={restModelData.editMode}
  395. reload={!restModelData.editMode}
  396. pagination={true}
  397. addHandle={
  398. (data: any) => taizhangDataDerectoryEditHandle(data, ActType.ADD)
  399. }
  400. editHandle={
  401. (data: any) => taizhangDataDerectoryEditHandle(data, ActType.EDIT)
  402. }
  403. delHandle={
  404. (data: any) => taizhangDataDerectoryEditHandle(data, ActType.DEL)
  405. }
  406. request={async (current, pageSize) => {
  407. if (restModelData.leafData) {
  408. const { numStr, version } = restModelData.leafData.reviewArticle;
  409. const resp = await getTaizhangDirectoryTable({ numStr, version, current, pageSize });
  410. const { list = [] } = resp;
  411. return {
  412. data: list.map(item => ({ ...item, grade: item.grade ? item.grade.split(',') : [], accountStatus: item.accountStatus == '0' ? false : true })), //多选下拉需传数组值
  413. total: resp.totalCount,
  414. current: resp.current,
  415. success: true
  416. };
  417. }
  418. return {
  419. data: [],
  420. total: 0,
  421. success: false
  422. }
  423. }}
  424. columns={mccsEditableTableColumns}
  425. />
  426. )
  427. }
  428. </div>
  429. </div>
  430. )
  431. }
  432. </div>
  433. )
  434. }
  435. export default ArticleDetail;