index.tsx 22 KB

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