newNegativeReagent.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  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">平行实验/留样再测</div>
  8. <div v-if="nodeId === 'Activity_0xkc1ji' || readonly" />
  9. <div v-else>
  10. <span style="color: red; margin-right: 20px; font-size: 16px"
  11. >注意:手动计算与导入不可混用</span
  12. >
  13. <el-button
  14. type="primary"
  15. size="mini"
  16. icon="ibps-icon-add"
  17. @click="handleAdd"
  18. >
  19. 添加</el-button
  20. >
  21. <el-button
  22. type="primary"
  23. size="mini"
  24. icon="ibps-icon-copy"
  25. @click="handleCopy"
  26. >
  27. 复制</el-button
  28. >
  29. <el-button
  30. type="danger"
  31. size="mini"
  32. icon="ibps-icon-remove"
  33. @click="handleDelete"
  34. >
  35. 删除</el-button
  36. >
  37. <el-button
  38. type="warning"
  39. size="mini"
  40. icon="ibps-icon-calculator"
  41. @click="computedResult"
  42. >计算</el-button
  43. >
  44. <el-button
  45. type="primary"
  46. size="mini"
  47. icon="ibps-icon-download"
  48. @click="handleDownload"
  49. >模版下载</el-button
  50. >
  51. <el-button
  52. type="primary"
  53. size="mini"
  54. icon="ibps-icon-import"
  55. @click="handleImport"
  56. >导入</el-button
  57. >
  58. </div>
  59. </el-col>
  60. </el-row>
  61. <el-row type="flex">
  62. <el-col>
  63. <el-table
  64. ref="reagent"
  65. :data="reagentDataFilter"
  66. :span-method="spanMethod"
  67. @selection-change="handleSelectionChange"
  68. >
  69. <el-table-column type="selection" width="55" />
  70. <el-table-column label="检验项目" prop="jianCeXiangMu" />
  71. <el-table-column label="浓度" prop="nongDu" width="100">
  72. <template slot-scope="{ row }">
  73. <el-input
  74. v-if="!disabled"
  75. v-model="row.nongDu"
  76. size="mini"
  77. placeholder="请输入"
  78. />
  79. <span v-else>{{ row.nongDu || '/' }}</span>
  80. </template>
  81. </el-table-column>
  82. <el-table-column label="样品编号" prop="biaoBenHao" width="100">
  83. <template slot-scope="{ row }">
  84. <el-input
  85. v-if="!disabled"
  86. v-model="row.biaoBenHao"
  87. size="mini"
  88. placeholder="请输入"
  89. />
  90. <span v-else>{{ row.biaoBenHao || '/' }}</span>
  91. </template>
  92. </el-table-column>
  93. <el-table-column
  94. label="旧试剂测得结果"
  95. prop="jiuJieGuo"
  96. width="130"
  97. >
  98. <template slot-scope="{ row }">
  99. <el-input
  100. v-if="!disabled"
  101. v-model="row.jiuJieGuo"
  102. :min="0"
  103. size="mini"
  104. placeholder="请输入"
  105. :type="isCb ? 'text' : 'number'"
  106. />
  107. <span v-else>{{ row.jiuJieGuo || '/' }}</span>
  108. </template>
  109. </el-table-column>
  110. <el-table-column
  111. label="新试剂测得结果"
  112. prop="xinJieGuo"
  113. width="130"
  114. >
  115. <template slot-scope="{ row }">
  116. <el-input
  117. v-if="!disabled"
  118. v-model="row.xinJieGuo"
  119. :min="0"
  120. size="mini"
  121. placeholder="请输入"
  122. :type="isCb ? 'text' : 'number'"
  123. />
  124. <span v-else>{{ row.xinJieGuo || '/' }}</span>
  125. </template>
  126. </el-table-column>
  127. <el-table-column label="计算方式" prop="jiSuanFangShi" width="140">
  128. <template slot-scope="{ row }">
  129. <el-select
  130. v-if="!disabled"
  131. v-model="row.jiSuanFangShi"
  132. size="mini"
  133. placeholder="请选择"
  134. >
  135. <el-option label="Y-X" value="Y-X" />
  136. <el-option label="(Y-X)/X(%)" value="(Y-X)/X(%)" />
  137. </el-select>
  138. <span v-else>{{ row.jiSuanFangShi || '/' }}</span>
  139. </template>
  140. </el-table-column>
  141. <el-table-column label="实际差值" prop="shiJiChaZhi" />
  142. <el-table-column label="实际偏倚" prop="jieGuo" />
  143. <el-table-column
  144. :label="isHz ? '允许差值' : '限定范围'"
  145. prop="zuiXiaoFanWei"
  146. width="110"
  147. >
  148. <template slot-scope="{ row }">
  149. <el-input
  150. v-if="!disabled"
  151. v-model="row.zuiXiaoFanWei"
  152. size="mini"
  153. placeholder="请输入"
  154. type="number"
  155. />
  156. <span v-else>{{ row.zuiXiaoFanWei || '/' }}</span>
  157. </template>
  158. </el-table-column>
  159. <el-table-column label="允许偏倚" prop="yunXuPianYi" width="100">
  160. <template slot-scope="{ row }">
  161. <el-input
  162. v-if="!disabled"
  163. v-model="row.yunXuPianYi"
  164. size="mini"
  165. placeholder="请输入"
  166. />
  167. <span v-else>{{ row.yunXuPianYi || '/' }}</span>
  168. </template>
  169. </el-table-column>
  170. <el-table-column label="是否相符" prop="xiangFu" width="80" />
  171. <el-table-column label="符合率" prop="biaoZhun" />
  172. <el-table-column
  173. label="符合率可接受标准"
  174. prop="xiangMuFuHeLv"
  175. width="140"
  176. >
  177. <template slot-scope="{ row }">
  178. <el-select
  179. v-if="!disabled"
  180. v-model="row.xiangMuFuHeLv"
  181. size="mini"
  182. placeholder="请选择"
  183. @change="handelChange($event, row.jianCeXiangMu)"
  184. >
  185. <el-option label="≥80%" value="≥80%" />
  186. <el-option label="=100%" value="=100%" />
  187. </el-select>
  188. <span v-else>{{ row.xiangMuFuHeLv || '/' }}</span>
  189. </template>
  190. </el-table-column>
  191. <el-table-column label="结论" prop="jieLun" />
  192. </el-table>
  193. <el-pagination
  194. layout="total,sizes,prev, pager, next,jumper"
  195. :current-page="requestPage.pageNo"
  196. :page-size="requestPage.limit"
  197. :page-sizes="[10, 15, 20, 30, 50, 100]"
  198. :total="reagentData.length"
  199. @size-change="handleSizeChange"
  200. @current-change="handleCurrentChange"
  201. />
  202. </el-col>
  203. </el-row>
  204. </div>
  205. <import-table
  206. :visible="importTableDialogVisible"
  207. title="导入"
  208. @close="(visible) => (importTableDialogVisible = visible)"
  209. @action-event="handleImportTableActionEvent"
  210. />
  211. </div>
  212. </template>
  213. <script>
  214. import importTable from '@/business/platform/form/formrender/dynamic-form/components/import-table'
  215. import IbpsImport from '@/plugins/import'
  216. import { downloadFile } from '@/business/platform/file/utils'
  217. import { cloneDeep } from 'lodash'
  218. export default {
  219. components: {
  220. importTable
  221. },
  222. props: {
  223. formData: {
  224. type: Object,
  225. default: () => {}
  226. },
  227. readonly: {
  228. type: Boolean,
  229. default: false
  230. },
  231. params: {
  232. type: Object,
  233. default: () => {}
  234. }
  235. },
  236. data() {
  237. return {
  238. reagentData: [],
  239. copyDialogData: [],
  240. disabled: false,
  241. ypData: [],
  242. nodeId: '',
  243. show: true,
  244. requestPage: {
  245. limit: 20,
  246. pageNo: 1
  247. },
  248. importTableDialogVisible: false,
  249. multipleSelection: [],
  250. isHz: false,
  251. isCb: false
  252. }
  253. },
  254. computed: {
  255. reagentDataFilter() {
  256. return this.reagentData.slice(
  257. (this.requestPage.pageNo - 1) * this.requestPage.limit,
  258. (this.requestPage.pageNo - 1) * this.requestPage.limit +
  259. this.requestPage.limit
  260. )
  261. }
  262. },
  263. watch: {
  264. 'formData.sjghyzjlbbbzb': {
  265. handler(value, old) {
  266. if (value && value.length) {
  267. this.reagentData = value
  268. }
  269. },
  270. immediate: true
  271. },
  272. reagentData: {
  273. handler(value, old) {
  274. this.$emit('change-data', 'sjghyzjlbbbzb', value)
  275. },
  276. deep: true
  277. },
  278. 'formData.fangAn': {
  279. handler(val) {
  280. this.showAndHide(val)
  281. },
  282. immediate: true
  283. },
  284. 'formData.yunXuPianYi': {
  285. handler(val) {
  286. this.reagentData.forEach((item) => {
  287. const { jianYanXiangMu } = this.formData
  288. if (item.jianCeXiangMu === jianYanXiangMu) {
  289. item.yunXuPianYi = val
  290. }
  291. })
  292. },
  293. immediate: true
  294. },
  295. 'formData.xianDingFanWei': {
  296. handler(val) {
  297. this.reagentData.forEach((item) => {
  298. const { jianYanXiangMu } = this.formData
  299. if (item.jianCeXiangMu === jianYanXiangMu) {
  300. item.zuiXiaoFanWei = val
  301. }
  302. })
  303. }
  304. }
  305. },
  306. mounted() {
  307. const { first = '' } = this.$store.getters.level
  308. const { deptList = [] } = this.$store.getters || {}
  309. const t1 = deptList.find((i) => i.positionId === first) || {}
  310. this.isHz = t1.positionName === '惠州市第三人民医院'
  311. this.isCb = t1.positionName === '川北医学院附属医院'
  312. // console.log(t1.positionName)
  313. this.nodeId = this.params ? this.params.nodeId : ''
  314. this.disabled = this.readonly || this.nodeId === 'Activity_0xkc1ji'
  315. this.showAndHide(this.formData.fangAn)
  316. },
  317. methods: {
  318. handelChange(event, jianCeXiangMu) {
  319. this.reagentData.forEach((item) => {
  320. if (item.jianCeXiangMu == jianCeXiangMu) {
  321. item.xiangMuFuHeLv = event
  322. }
  323. })
  324. },
  325. // 新增
  326. handleAdd() {
  327. if (
  328. !this.reagentData ||
  329. (this.reagentData && this.reagentData.length === 0)
  330. ) {
  331. this.disabled = false
  332. }
  333. const { jianYanXiangMu, yunXuPianYi, xianDingFanWei } = this.formData
  334. if (this.disabled && this.reagentData?.length > 0) {
  335. return this.$message.warning('导入与手动添加功能不可混用!')
  336. }
  337. if (!this.formData.jianYanXiangMu) {
  338. return this.$message.warning('请选择检验项目')
  339. }
  340. this.reagentData.push({
  341. jianCeXiangMu: jianYanXiangMu,
  342. nongDu: '',
  343. biaoBenHao: '',
  344. jiuJieGuo: '',
  345. xinJieGuo: '',
  346. jiSuanFangShi: '(Y-X)/X(%)',
  347. shiJiChaZhi: '',
  348. jieGuo: '',
  349. zuiXiaoFanWei: xianDingFanWei,
  350. yunXuPianYi: yunXuPianYi,
  351. xiangFu: '',
  352. biaoZhun: '',
  353. xiangMuFuHeLv: '≥80%',
  354. jieLun: ''
  355. })
  356. const grouped = this.reagentData.reduce((acc, item) => {
  357. const key = item.jianCeXiangMu
  358. if (!acc[key]) acc[key] = []
  359. acc[key].push(item)
  360. return acc
  361. }, {})
  362. // 先清空数组,再填充新数据(确保 Vue 检测到变化)
  363. this.reagentData.splice(
  364. 0,
  365. this.reagentData.length,
  366. ...Object.values(grouped).flat()
  367. )
  368. console.log(this.reagentData)
  369. },
  370. // 复制
  371. handleCopy() {
  372. if (this.multipleSelection.length > 0) {
  373. this.reagentData = this.reagentData.concat(
  374. cloneDeep(this.multipleSelection)
  375. )
  376. const grouped = this.reagentData.reduce((acc, item) => {
  377. const key = item.jianCeXiangMu
  378. if (!acc[key]) acc[key] = []
  379. acc[key].push(item)
  380. return acc
  381. }, {})
  382. // 先清空数组,再填充新数据(确保 Vue 检测到变化)
  383. this.reagentData.splice(
  384. 0,
  385. this.reagentData.length,
  386. ...Object.values(grouped).flat()
  387. )
  388. } else {
  389. this.$message.warning('请选择数据')
  390. }
  391. },
  392. // 删除
  393. handleDelete() {
  394. this.$confirm('确定删除当前选中数据?', '提示', {
  395. confirmButtonText: '确定',
  396. cancelButtonText: '取消',
  397. type: 'warning'
  398. }).then(() => {
  399. if (this.multipleSelection.length > 0) {
  400. this.reagentData = this.reagentData.filter(
  401. (row) => !this.multipleSelection.includes(row)
  402. )
  403. } else {
  404. this.$message.warning('请选择数据')
  405. }
  406. })
  407. },
  408. handleSelectionChange(val) {
  409. this.multipleSelection = val
  410. },
  411. handleImport() {
  412. this.importTableDialogVisible = true
  413. },
  414. handleDownload() {
  415. downloadFile({
  416. id: 'download_sjghdl',
  417. fileName: '试剂更换验证定量模板',
  418. ext: 'xlsx'
  419. })
  420. },
  421. getColumns() {
  422. return [
  423. {
  424. field_name: 'xiangFu',
  425. label: '是否相符',
  426. name: 'xiangFu'
  427. },
  428. {
  429. field_name: 'jianCeXiangMu',
  430. label: '检验项目',
  431. name: 'jianCeXiangMu'
  432. },
  433. {
  434. field_name: 'nongDu',
  435. label: '浓度',
  436. name: 'nongDu'
  437. },
  438. {
  439. field_name: 'biaoBenHao',
  440. label: '样品编号',
  441. name: 'biaoBenHao'
  442. },
  443. {
  444. field_name: 'jiuJieGuo',
  445. label: '旧试剂测得结果',
  446. name: 'jiuJieGuo'
  447. },
  448. {
  449. field_name: 'xinJieGuo',
  450. label: '新试剂测得结果',
  451. name: 'xinJieGuo'
  452. },
  453. {
  454. field_name: 'shiJiChaZhi',
  455. label: '实际差值',
  456. name: 'shiJiChaZhi'
  457. },
  458. {
  459. field_name: 'jieGuo',
  460. label: '实际偏倚',
  461. name: 'jieGuo'
  462. },
  463. {
  464. field_name: 'zuiXiaoFanWei',
  465. label: this.isHz ? '允许差值' : '限定范围',
  466. name: 'zuiXiaoFanWei'
  467. },
  468. {
  469. field_name: 'yunXuPianYi',
  470. label: '允许偏倚',
  471. name: 'yunXuPianYi'
  472. },
  473. {
  474. field_name: 'biaoZhun',
  475. label: '符合率',
  476. name: 'biaoZhun'
  477. },
  478. {
  479. field_name: 'jieLun',
  480. label: '结论',
  481. name: 'jieLun'
  482. },
  483. {
  484. field_name: 'xiangMuFuHeLv',
  485. label: '符合率可接受标准',
  486. name: 'xiangMuFuHeLv'
  487. }
  488. ]
  489. },
  490. getKeys(data) {
  491. return Array.isArray(data)
  492. ? data.reduce((acc, item) => ({ ...acc, [item.label]: item.name }), {})
  493. : {}
  494. },
  495. handleImportTableActionEvent(file, options) {
  496. IbpsImport.xlsx(file, options).then(({ header, results }) => {
  497. const list = []
  498. const keys = this.getKeys(this.getColumns())
  499. results.forEach((item) => {
  500. const obj = {}
  501. Object.keys(item).forEach((key) => {
  502. if (keys[key]) {
  503. obj[keys[key]] = item[key]
  504. }
  505. })
  506. list.push(obj)
  507. })
  508. const filteredArray = list
  509. .map((item) => {
  510. if (item.jianCeXiangMu && item.biaoZhun && item.jieLun) {
  511. return item
  512. }
  513. return null
  514. })
  515. .filter((item) => item !== null)
  516. filteredArray.forEach((item) => {
  517. list.forEach((el) => {
  518. if (el.jianCeXiangMu === item.jianCeXiangMu) {
  519. el.biaoZhun = item.biaoZhun
  520. el.jieLun = item.jieLun
  521. el.xiangMuFuHeLv = item.xiangMuFuHeLv
  522. }
  523. /*
  524. if (el.shiJiChaZhi) {
  525. el.shiJiChaZhi = (el.shiJiChaZhi + '').replace('-', '')
  526. }
  527. if (el.jieGuo) {
  528. el.jieGuo = (el.jieGuo + '').replace('-', '')
  529. }*/
  530. })
  531. })
  532. this.reagentData = list
  533. this.disabled = true
  534. this.importTableDialogVisible = false
  535. })
  536. },
  537. // 当前页码改变
  538. handleCurrentChange(val) {
  539. this.requestPage.pageNo = val
  540. },
  541. // 页码选择器改变
  542. handleSizeChange(val) {
  543. this.requestPage.limit = val
  544. this.requestPage.pageNo = 1
  545. },
  546. showAndHide(data) {
  547. if (
  548. data.includes('平行试验') ||
  549. data.includes('留样再测') ||
  550. data.includes('比对方案')
  551. ) {
  552. this.show = true
  553. } else {
  554. this.show = false
  555. }
  556. },
  557. // 计算结果
  558. computedResult() {
  559. if (this.disabled) {
  560. this.$message.warning('导入数据请勿使用计算功能!')
  561. return
  562. }
  563. const hasInvalidData = this.reagentData.some(
  564. (item) =>
  565. !item.jiuJieGuo ||
  566. item.jiuJieGuo <= 0 ||
  567. !item.xinJieGuo ||
  568. item.xinJieGuo <= 0
  569. )
  570. if (hasInvalidData || this.reagentData.length === 0) {
  571. this.$message.warning('新、旧试剂测得结果必须大于0且不能为空!')
  572. return
  573. }
  574. const hasPyOrCz = this.reagentData.some(
  575. (item) =>
  576. (item.jiSuanFangShi === '(Y-X)/X(%)' && !item.yunXuPianYi) ||
  577. (item.jiSuanFangShi === 'Y-X' && !item.zuiXiaoFanWei)
  578. )
  579. if (hasPyOrCz) {
  580. this.$message.warning(
  581. `计算方式为 (Y-X)/X(%) 请填写允许偏倚,计算方式为 Y-X 请填写${
  582. this.isHz ? '允许差值' : '限定范围'
  583. }`
  584. )
  585. return
  586. }
  587. // 预处理函数:统一处理百分比数值
  588. const normalizePercent = (val) =>
  589. Number(String(val).replace('%', '')) || 0
  590. // 使用 Map 存储统计信息
  591. const projectStats = new Map()
  592. this.reagentData.forEach((item) => {
  593. const {
  594. jiSuanFangShi,
  595. xinJieGuo,
  596. jiuJieGuo,
  597. zuiXiaoFanWei,
  598. jianCeXiangMu
  599. } = item
  600. // 计算差值/偏倚
  601. if (jiSuanFangShi === 'Y-X') {
  602. //item.shiJiChaZhi = Math.abs((xinJieGuo * 100000 - jiuJieGuo * 100000) / 100000)
  603. item.shiJiChaZhi = ((xinJieGuo * 100000 - jiuJieGuo * 100000) / 100000) .toFixed(3)
  604. item.xiangFu =
  605. Math.abs(normalizePercent(item.shiJiChaZhi)) <=
  606. Math.abs(normalizePercent(zuiXiaoFanWei))
  607. ? '相符'
  608. : '不相符'
  609. item.jieGuo = ''
  610. } else {
  611. //item.jieGuo = this.deleteAccuracy(Math.abs(xinJieGuo - jiuJieGuo) / jiuJieGuo)
  612. item.jieGuo = this.deleteAccuracy((xinJieGuo - jiuJieGuo) / jiuJieGuo)
  613. item.xiangFu =
  614. Math.abs(normalizePercent(item.jieGuo)) <= Math.abs(normalizePercent(item.yunXuPianYi))
  615. ? '相符'
  616. : '不相符'
  617. item.shiJiChaZhi = ''
  618. }
  619. // 统计符合率
  620. const stats = projectStats.get(jianCeXiangMu) || { total: 0, yes: 0 }
  621. stats.total++
  622. if (item.xiangFu === '相符') stats.yes++
  623. projectStats.set(jianCeXiangMu, stats)
  624. })
  625. // 填充符合率标准,保留小数点后两位
  626. this.reagentData.forEach((item) => {
  627. const stats = projectStats.get(item.jianCeXiangMu)
  628. item.biaoZhun = this.deleteAccuracy(stats.yes / stats.total)
  629. console.log(parseFloat(item.biaoZhun), item.xiangMuFuHeLv)
  630. item.jieLun =
  631. parseFloat(item.biaoZhun) >=
  632. parseFloat(item.xiangMuFuHeLv.replace(/[≥=%]/g, ''))
  633. ? '可接受'
  634. : '不可接受'
  635. })
  636. },
  637. spanMethod({ row, column, rowIndex, columnIndex }) {
  638. if (
  639. columnIndex === 1 ||
  640. columnIndex === 12 ||
  641. columnIndex === 13 ||
  642. columnIndex === 14
  643. ) {
  644. const currentValue = row[column.property]
  645. const preRow = this.reagentData[rowIndex - 1]
  646. // 上一行这一列的数据
  647. const preValue = preRow ? preRow[column.property] : null
  648. // 如果当前值和上一行的值相同,则将当前单元格隐藏
  649. // 给第0,10,11,12列对数值相同且是同一个'jianCeXiangMu'进行表格合并
  650. if (
  651. currentValue === preValue &&
  652. row['jianCeXiangMu'] === preRow['jianCeXiangMu']
  653. ) {
  654. return { rowspan: 0, colspan: 0 }
  655. } else {
  656. let rowspan = 1
  657. // 计算应该合并的行数
  658. for (let i = rowIndex + 1; i < this.reagentData.length; i++) {
  659. const nextRow = this.reagentData[i]
  660. const nextValue = nextRow[column.property]
  661. if (
  662. nextValue === currentValue &&
  663. nextRow['jianCeXiangMu'] === row['jianCeXiangMu']
  664. ) {
  665. rowspan++
  666. } else {
  667. break
  668. }
  669. }
  670. return { rowspan, colspan: 1 }
  671. }
  672. // if (rowIndex % rowspan === 0) {
  673. // return {
  674. // rowspan,
  675. // colspan: 1
  676. // }
  677. // } else {
  678. // return {
  679. // rowspan: 0,
  680. // colspan: 0
  681. // }
  682. // }
  683. }
  684. },
  685. // 去除小数*100精度方法(支持负数)
  686. deleteAccuracy(num) {
  687. // 处理负数
  688. const isNegative = num < 0
  689. const absoluteNum = Math.abs(num)
  690. // 是否带小数点
  691. if (absoluteNum.toString().includes('.')) {
  692. // 保留小数点后面3位
  693. const numArry = absoluteNum.toFixed(3).toString().split('.')
  694. let result
  695. // 整数位是否大于0
  696. if (numArry[0] > 0) {
  697. result = Number(
  698. numArry[0] +
  699. numArry[1].substring(0, 2) +
  700. '.' +
  701. numArry[1].substring(2, 3)
  702. ) + '%'
  703. } else {
  704. // 小数位第一位是否大于0
  705. if (numArry[1][0] > 0) {
  706. result = Number(
  707. numArry[1].substring(0, 2) + '.' + numArry[1].substring(2, 3)
  708. ) + '%'
  709. } else {
  710. // 小数位第二位是否大于0
  711. if (numArry[1][1] > 0) {
  712. result = Number(
  713. numArry[1].substring(1, 2) + '.' + numArry[1].substring(2, 3)
  714. ) + '%'
  715. } else {
  716. result = Number(0 + '.' + numArry[1].substring(2, 3)) + '%'
  717. }
  718. }
  719. }
  720. // 恢复负号
  721. return isNegative ? '-' + result : result
  722. } else {
  723. const result = absoluteNum * 100 + '%'
  724. return isNegative ? '-' + result : result
  725. }
  726. }
  727. }
  728. }
  729. </script>
  730. <style lang="scss" scoped>
  731. .reagentChange {
  732. margin-bottom: 20px;
  733. .button {
  734. display: flex;
  735. justify-content: space-between;
  736. padding: 0px 0px 0px 15px;
  737. background: #f0ffff;
  738. .title {
  739. color: #999;
  740. font-size: 12px;
  741. font-weight: bold;
  742. margin-bottom: 0;
  743. }
  744. .el-button {
  745. margin: 0;
  746. }
  747. }
  748. }
  749. </style>