qualityControlChildTabTwo.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. <!--该组件实际差值和实际偏倚有正负值-->
  2. <template>
  3. <div>
  4. <div v-if="show" class="reagentChange">
  5. <el-row type="flex">
  6. <el-col class="button">
  7. <div class="title">{{ configuration[field.name].title }}</div>
  8. <div v-if="readonly" />
  9. <div v-else> </div>
  10. </el-col>
  11. </el-row>
  12. <el-row type="flex">
  13. <el-col>
  14. <el-table
  15. :data="reagentDataFilter"
  16. @selection-change="handleSelectionChange"
  17. >
  18. <!-- <el-table-column type="selection" width="55" /> -->
  19. <el-table-column
  20. v-if="field.name === 'component_1qyrt3i'"
  21. label="凝聚胺法"
  22. prop="fangFa"
  23. width="130"
  24. align="center"
  25. />
  26. <el-table-column
  27. :label="
  28. field.name === 'component_1qyrt3i' ? '供者编号' : '质控编号'
  29. "
  30. prop="bianHao"
  31. width="130"
  32. align="center"
  33. />
  34. <el-table-column
  35. v-for="(item, ind) in columnParent"
  36. :label="item.name"
  37. :key="'parent' + ind"
  38. align="center"
  39. >
  40. <el-table-column
  41. v-for="(it, i) in configuration[field.name].colChild"
  42. :prop="item.val[i]"
  43. :label="it"
  44. :key="'child1' + i"
  45. width="120"
  46. align="center"
  47. >
  48. <template slot-scope="{ row }">
  49. <!-- <el-input
  50. v-if="!disabled"
  51. v-model="row[item.val[i]]"
  52. :min="0"
  53. size="mini"
  54. placeholder="请输入"
  55. type="text"
  56. /> -->
  57. <el-select
  58. v-if="!disabled"
  59. v-model="row[item.val[i]]"
  60. clearable
  61. placeholder="请选择"
  62. >
  63. <el-option
  64. v-for="s in optionsS"
  65. :key="s.value"
  66. :label="s.label"
  67. :value="s.value"
  68. >
  69. </el-option>
  70. </el-select>
  71. <span v-else>{{ row[item.val[i]] || '/' }}</span>
  72. </template>
  73. </el-table-column>
  74. </el-table-column>
  75. <div
  76. slot="append"
  77. :style="{
  78. width: field.name === 'component_1qyrt3i' ? '1940px' : '2650px'
  79. }"
  80. >
  81. <el-row
  82. v-if="field.name === 'component_1orinpd'"
  83. type="flex"
  84. class="lastRow"
  85. >
  86. <el-col>
  87. <el-table
  88. ref="reagent"
  89. :data="reagentDataFilterL"
  90. @selection-change="handleSelectionChange"
  91. >
  92. <!-- <el-table-column type="selection" width="55" /> -->
  93. <el-table-column
  94. label="质控编号"
  95. prop="bianHao"
  96. width="130"
  97. align="center"
  98. />
  99. <el-table-column
  100. v-for="(item, ind) in columnParent"
  101. :key="'parent1' + ind"
  102. label-class-name="heightLabel"
  103. align="center"
  104. >
  105. <el-table-column
  106. v-for="(it, i) in configuration[field.name].colChildL"
  107. :prop="item.val[i]"
  108. :label="it"
  109. :key="'child2' + i"
  110. width="120"
  111. align="center"
  112. >
  113. <template slot-scope="{ row }">
  114. <el-input
  115. v-if="!disabled"
  116. v-model="row[item.val[i]]"
  117. :min="0"
  118. size="mini"
  119. placeholder="请输入"
  120. type="text"
  121. />
  122. <span v-else>{{ row[item.val[i]] || '/' }}</span>
  123. </template>
  124. </el-table-column>
  125. </el-table-column>
  126. </el-table>
  127. </el-col>
  128. </el-row>
  129. <!-- 自定义内容,例如一个按钮 -->
  130. <div v-if="lastShow" class="lastRow">
  131. <div
  132. class="labelSty"
  133. :style="{
  134. width:
  135. field.name === 'component_1qyrt3i' ? '260px' : '130px'
  136. }"
  137. >结果符合预期:</div
  138. >
  139. <div
  140. v-for="(em, x) in personJGLabel"
  141. class="chooseSty"
  142. :style="{
  143. width:
  144. field.name === 'component_1qyrt3i' ? '220px' : '340px'
  145. }"
  146. >
  147. <el-radio-group
  148. v-if="!disabled"
  149. v-model="
  150. reagentData.find(
  151. (m) =>
  152. m.leiXing === field.name &&
  153. m.tianXieLeiXing === 'result'
  154. )[em]
  155. "
  156. >
  157. <el-radio label="Y">Y</el-radio>
  158. <el-radio label="N">N</el-radio>
  159. </el-radio-group>
  160. <span v-else>{{
  161. reagentData.find(
  162. (m) =>
  163. m.leiXing === field.name &&
  164. m.tianXieLeiXing === 'result'
  165. )[em] || '/'
  166. }}</span>
  167. </div>
  168. </div>
  169. <div v-if="lastShow" class="lastRow">
  170. <div
  171. class="labelSty"
  172. :style="{
  173. width:
  174. field.name === 'component_1qyrt3i' ? '260px' : '130px'
  175. }"
  176. >操作人:</div
  177. >
  178. <div
  179. v-for="(em, x) in personJGLabel"
  180. class="chooseSty"
  181. :style="{
  182. width:
  183. field.name === 'component_1qyrt3i' ? '220px' : '340px'
  184. }"
  185. >
  186. <ibps-user-selector
  187. v-model="
  188. reagentData.find(
  189. (m) =>
  190. m.leiXing === field.name &&
  191. m.tianXieLeiXing === 'person'
  192. )[em]
  193. "
  194. type="user"
  195. readonly-text="text"
  196. :disabled="disabled"
  197. :multiple="false"
  198. size="mini"
  199. :filter="filter"
  200. filtrate
  201. style="width: 100%"
  202. @change-link-data="changeGuanLiRen"
  203. />
  204. </div>
  205. </div>
  206. </div>
  207. </el-table>
  208. <!-- <el-pagination
  209. layout="total,sizes,prev, pager, next,jumper"
  210. :current-page="requestPage.pageNo"
  211. :page-size="requestPage.limit"
  212. :page-sizes="[10, 15, 20, 30, 50, 100]"
  213. :total="reagentData.length"
  214. @size-change="handleSizeChange"
  215. @current-change="handleCurrentChange"
  216. /> -->
  217. </el-col>
  218. </el-row>
  219. </div>
  220. </div>
  221. </template>
  222. <script>
  223. import importTable from '@/business/platform/form/formrender/dynamic-form/components/import-table'
  224. import IbpsImport from '@/plugins/import'
  225. import { downloadFile } from '@/business/platform/file/utils'
  226. import { cloneDeep, forIn } from 'lodash'
  227. export default {
  228. components: {
  229. importTable,
  230. IbpsUserSelector: () => ({
  231. component: import('@/business/platform/org/selector'),
  232. delay: 200
  233. })
  234. },
  235. props: {
  236. formData: {
  237. type: Object,
  238. default: () => {}
  239. },
  240. readonly: {
  241. type: Boolean,
  242. default: false
  243. },
  244. params: {
  245. type: Object,
  246. default: () => {}
  247. },
  248. field: {
  249. type: Object,
  250. default: () => {}
  251. }
  252. },
  253. data() {
  254. return {
  255. reagentData: [],
  256. disabled: false,
  257. show: true,
  258. lastShow: false,
  259. requestPage: {
  260. limit: 20,
  261. pageNo: 1
  262. },
  263. multipleSelection: [],
  264. daysArr: [],
  265. filter: [
  266. {
  267. descVal: '1',
  268. includeSub: true,
  269. old: 'position',
  270. partyId: this.$store.getters.userInfo.employee.positions,
  271. partyName: '',
  272. scriptContent: '',
  273. type: 'user',
  274. userType: 'position'
  275. }
  276. ],
  277. columnParent: [
  278. { name: 'Mon', val: ['zhouYi1', 'zhouYi2', 'zhouYi3'] },
  279. { name: 'Tue', val: ['zhouEr1', 'zhouEr2', 'zhouEr3'] },
  280. { name: 'Wed', val: ['zhouSan1', 'zhouSan2', 'zhouSan3'] },
  281. { name: 'Thur', val: ['zhouSi1', 'zhouSi2', 'zhouSi3'] },
  282. { name: 'Fri', val: ['zhouWu1', 'zhouWu2', 'zhouWu3'] },
  283. { name: 'Sat', val: ['zhouLiu1', 'zhouLiu2', 'zhouLiu3'] },
  284. { name: 'Sun', val: ['zhouRi1', 'zhouRi2', 'zhouRi3'] }
  285. ],
  286. configuration: {
  287. component_1orinpd: {
  288. title: '血型鉴定-试管法',
  289. colChild: ['抗-A', '抗-B', '抗-D'],
  290. colChildL: ['Ac', 'Bc', 'Oc']
  291. },
  292. component_136l4wr: {
  293. title: '抗体筛选-手工法',
  294. colChild: ['Ⅰ', 'Ⅱ', 'Ⅲ']
  295. },
  296. component_1qyrt3i: {
  297. title: '交叉配血-凝聚胺法',
  298. colChild: ['主侧', '次侧']
  299. }
  300. },
  301. personJGLabel: [
  302. 'zhouYi1',
  303. 'zhouEr1',
  304. 'zhouSan1',
  305. 'zhouSi1',
  306. 'zhouWu1',
  307. 'zhouLiu1',
  308. 'zhouRi1'
  309. ],
  310. primarySize: '2650px',
  311. optionsS: [
  312. {
  313. value: '0',
  314. label: '0'
  315. },
  316. {
  317. value: '1+',
  318. label: '1+'
  319. },
  320. {
  321. value: '2+',
  322. label: '2+'
  323. },
  324. {
  325. value: '3+',
  326. label: '3+'
  327. },
  328. {
  329. value: '4+',
  330. label: '4+'
  331. }
  332. ]
  333. }
  334. },
  335. computed: {
  336. reagentDataFilter() {
  337. let data = this.reagentData.filter(
  338. (t) =>
  339. t.leiXing === this.field.name && t.tianXieLeiXing === 'information'
  340. )
  341. return data.slice(
  342. (this.requestPage.pageNo - 1) * this.requestPage.limit,
  343. (this.requestPage.pageNo - 1) * this.requestPage.limit +
  344. this.requestPage.limit
  345. )
  346. },
  347. reagentDataFilterL() {
  348. let data = this.reagentData.filter(
  349. (t) =>
  350. t.leiXing === this.field.name + 'L' &&
  351. t.tianXieLeiXing === 'information'
  352. )
  353. return data.slice(
  354. (this.requestPage.pageNo - 1) * this.requestPage.limit,
  355. (this.requestPage.pageNo - 1) * this.requestPage.limit +
  356. this.requestPage.limit
  357. )
  358. }
  359. },
  360. watch: {
  361. 'formData.mrzkezb': {
  362. handler(value, old) {
  363. if (value && value.length > 0) {
  364. this.reagentData = value
  365. this.lastShow = true
  366. } else {
  367. this.reagentData = []
  368. this.lastShow = false
  369. }
  370. },
  371. immediate: true
  372. },
  373. 'formData.kaiShiShiJian': {
  374. handler(value, old) {
  375. if (value && value !== '') {
  376. this.daysArr = this.getNextSevenDays(value)
  377. } else {
  378. this.daysArr = []
  379. }
  380. },
  381. immediate: true
  382. },
  383. reagentData: {
  384. handler(value, old) {
  385. if (value.length > 0) {
  386. this.$emit('change-data', 'mrzkezb', value)
  387. }
  388. },
  389. deep: true
  390. }
  391. },
  392. mounted() {
  393. const { first = '' } = this.$store.getters.level
  394. const { deptList = [] } = this.$store.getters || {}
  395. this.disabled = this.readonly
  396. // if (this.$refs.component_1qyrt3ireagent) {
  397. // console.log(this.$refs.component_1qyrt3ireagent, 'rrrr')
  398. // this.$refs.component_1qyrt3ireagent.$refs.appendWrapper.clientWidth = 1940
  399. // }
  400. },
  401. methods: {
  402. handleSelectionChange(val) {
  403. this.multipleSelection = val
  404. },
  405. // 当前页码改变
  406. handleCurrentChange(val) {
  407. this.requestPage.pageNo = val
  408. },
  409. // 页码选择器改变
  410. handleSizeChange(val) {
  411. this.requestPage.limit = val
  412. this.requestPage.pageNo = 1
  413. },
  414. changeGuanLiRen(key, data) {
  415. // this.form.fuZeRenDianHua = data?.mobile
  416. },
  417. // 去除小数*100精度方法(支持负数)
  418. deleteAccuracy(num) {
  419. // 处理负数
  420. const isNegative = num < 0
  421. const absoluteNum = Math.abs(num)
  422. // 是否带小数点
  423. if (absoluteNum.toString().includes('.')) {
  424. // 保留小数点后面3位
  425. const numArry = absoluteNum.toFixed(3).toString().split('.')
  426. let result
  427. // 整数位是否大于0
  428. if (numArry[0] > 0) {
  429. result =
  430. Number(
  431. numArry[0] +
  432. numArry[1].substring(0, 2) +
  433. '.' +
  434. numArry[1].substring(2, 3)
  435. ) + '%'
  436. } else {
  437. // 小数位第一位是否大于0
  438. if (numArry[1][0] > 0) {
  439. result =
  440. Number(
  441. numArry[1].substring(0, 2) + '.' + numArry[1].substring(2, 3)
  442. ) + '%'
  443. } else {
  444. // 小数位第二位是否大于0
  445. if (numArry[1][1] > 0) {
  446. result =
  447. Number(
  448. numArry[1].substring(1, 2) + '.' + numArry[1].substring(2, 3)
  449. ) + '%'
  450. } else {
  451. result = Number(0 + '.' + numArry[1].substring(2, 3)) + '%'
  452. }
  453. }
  454. }
  455. // 恢复负号
  456. return isNegative ? '-' + result : result
  457. } else {
  458. const result = absoluteNum * 100 + '%'
  459. return isNegative ? '-' + result : result
  460. }
  461. },
  462. /**
  463. * 获取指定日期之后连续7天的日期数组
  464. **/
  465. getNextSevenDays(inputDate) {
  466. // 转换为Date对象
  467. const date = new Date(inputDate)
  468. if (isNaN(date)) {
  469. throw new Error('Invalid date')
  470. }
  471. const result = []
  472. for (let i = 0; i < 7; i++) {
  473. // 基于原始日期增加 i 天,避免修改原对象
  474. const nextDate = new Date(date)
  475. nextDate.setDate(date.getDate() + i)
  476. const day = String(nextDate.getDate()).padStart(2, '0')
  477. result.push(day)
  478. }
  479. return result
  480. }
  481. }
  482. }
  483. </script>
  484. <style lang="scss" scoped>
  485. .reagentChange {
  486. margin-bottom: 20px;
  487. .button {
  488. display: flex;
  489. justify-content: space-between;
  490. padding: 0px 0px 0px 15px;
  491. background: #f0ffff;
  492. .title {
  493. color: #999;
  494. font-size: 12px;
  495. font-weight: bold;
  496. margin-bottom: 0;
  497. }
  498. .el-button {
  499. margin: 0;
  500. }
  501. }
  502. ::v-deep .heightLabel {
  503. height: 0;
  504. line-height: 0;
  505. padding: 0;
  506. border-bottom: 0;
  507. }
  508. ::v-deep .el-table__append-wrapper {
  509. // width: 2650px;
  510. overflow: visible;
  511. .lastRow {
  512. display: flex;
  513. .labelSty {
  514. text-align: center;
  515. }
  516. .chooseSty {
  517. .el-radio__original[aria-hidden='true'] {
  518. display: none !important;
  519. }
  520. padding: 0 10px;
  521. }
  522. .el-table__body-wrapper.is-scrolling-none {
  523. width: 2650px;
  524. }
  525. }
  526. }
  527. }
  528. </style>