华西海圻ELN前端工程
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
11 KiB

  1. import moment from 'moment';
  2. import { getLatestSn } from '@/api/template';
  3. export default {
  4. dicts: [
  5. 'business_pztj',
  6. 'business_cctj',
  7. 'business_nddw',
  8. 'business_tjdw',
  9. 'business_yxqdw',
  10. 'business_rqcz',
  11. 'business_sp_jmdyzqdyp', //色谱-编号-准确度与精密度
  12. 'business_sp_nbgzy', //色谱-编号-内标工作液
  13. 'business_sp_zkgzy', //色谱-编号-质控工作液
  14. 'business_sp_bqgzy', //色谱-编号-标曲工作液
  15. 'business_sp_bzqxzkypzbb', //色谱-编号-标准曲线/质控样品制备表
  16. 'business_sp_tqhsl', //色谱-编号-提取回收率
  17. 'business_sp_qxwdx', //色谱-编号-全血稳定性
  18. 'business_sp_cbyhgzywdx', //色谱-编号-储备液和工作液稳定性
  19. 'business_sp_rxjzxy', //色谱-编号-溶血基质效应
  20. 'business_sp_jzxy', //色谱-编号-基质效应
  21. 'business_sp_xzxytyx', //色谱-编号-选择性与特异性
  22. 'business_sp_zdybs', //色谱-编号-最大样本数
  23. 'business_sp_xskkx', //色谱-编号-稀释可靠性
  24. 'business_sp_cbydb' //色谱-编号-储备液对比
  25. ],
  26. props: {
  27. templateData: {
  28. type: Object,
  29. default: () => {}
  30. }
  31. },
  32. watch: {
  33. templateData: {
  34. immediate: true,
  35. deep: true,
  36. handler(v) {
  37. if (v) {
  38. const {
  39. studyMc,
  40. studySn,
  41. templateMc,
  42. templateMcEn,
  43. templateSn,
  44. startDate,
  45. bdmc,
  46. endDate,
  47. id
  48. } = v
  49. if (v.resource) {
  50. //试验试剂信息
  51. this.resource = JSON.parse(v.resource)
  52. }
  53. if (v.bdnr) {
  54. this.formData = {
  55. ...JSON.parse(v.bdnr),
  56. studyMc,
  57. studySn,
  58. templateMc,
  59. templateMcEn,
  60. templateSn,
  61. startDate,
  62. bdmc,
  63. endDate,
  64. id
  65. }
  66. } else {
  67. this.formData = {
  68. studyMc,
  69. studySn,
  70. templateMc,
  71. templateMcEn,
  72. templateSn,
  73. startDate,
  74. bdmc,
  75. endDate,
  76. id
  77. }
  78. }
  79. const { effectivePeriod, effectivePeriodUnit, expireDate } =
  80. this.formData
  81. //实际填报的时候,如果有了开始时间,并且有有效周期,但是没有失效日,就计算失效日为开始时间+有效周期
  82. if (
  83. startDate &&
  84. this.fillType === 'actFill' &&
  85. effectivePeriod &&
  86. effectivePeriodUnit &&
  87. !expireDate
  88. ) {
  89. const start = moment(startDate);
  90. const unit = effectivePeriodUnit === '天' ? 'days' : 'hours';
  91. const end = start
  92. .add(Number(effectivePeriod), unit)
  93. .format('YYYY-MM-DD HH:mm:ss')
  94. this.formData = { ...this.formData, expireDate: end }
  95. }
  96. console.log(this.formData, 'formData from templateData')
  97. this.setTemplateData(v)
  98. }
  99. }
  100. }
  101. },
  102. data() {
  103. return {
  104. formData: {},
  105. templateDetail: {},
  106. resource: [], //试验试剂信息
  107. sysjColumns: [
  108. { label: '试剂名称', prop: 'reagentName' },
  109. { label: '编号', prop: 'reagentCode' },
  110. { label: '批号', prop: 'reagentNo' },
  111. { label: '浓度/含量/纯度', prop: 'concentration' },
  112. { label: '来源', prop: 'source' },
  113. { label: '失效日', prop: 'expireDate' }
  114. ],
  115. yqsColumns: [
  116. { label: '仪器名称', prop: 'instrumentName' },
  117. { label: '仪器型号', prop: 'instrumentModel' },
  118. { label: '仪器编号', prop: 'instrumentCode' },
  119. { label: '下次测试/校准/检定日期', prop: 'nextTestDate' }
  120. ]
  121. }
  122. },
  123. mounted() {},
  124. unmounted() {
  125. this.setTemplateData({})
  126. },
  127. methods: {
  128. async getLatestSn(count = 1){
  129. const res = await getLatestSn({count})
  130. if(res.code === 200){
  131. return res.data;
  132. }
  133. return null
  134. },
  135. getResource() {
  136. return this.resource
  137. },
  138. //根据ref数组获取直接formData
  139. getFilledFormDataByRefs(refArr = []) {
  140. let result = {}
  141. refArr.map((ref) => {
  142. const refData = this.$refs[ref]?.getFilledFormData() || {}
  143. for (const [key, value] of Object.entries(refData)) {
  144. let index = 0;
  145. // 如果当前键是可能重复的字段,且结果对象中已经存在该键,则添加索引后缀
  146. if ((key === 'headerSelectFields' || key === 'stepTableFormData') && result.hasOwnProperty(key)) {
  147. // 为重复字段生成带索引的键名,从1开始(因为第一个组件不需要后缀)
  148. const newKey = `${key}_${++index}`;
  149. result[newKey] = value;
  150. } else {
  151. // 正常合并其他字段
  152. result[key] = value;
  153. }
  154. }
  155. })
  156. return result
  157. },
  158. //统一校验form表单是否填写
  159. async validFormFields(refArr = []) {
  160. let result = {}
  161. const refs = refArr.map((ref) => {
  162. let refData = {}
  163. if (this.$refs[ref][0]) {
  164. refData = this.$refs[ref][0]?.getFormData() || {}
  165. } else {
  166. refData = this.$refs[ref]?.getFormData() || {}
  167. }
  168. return refData
  169. })
  170. const validFormData = await Promise.all(refs).catch((err) => {
  171. // this.$message.error(err);
  172. if (err.errorType && err.errorType === 'step') {
  173. this.$message.error('请添加步骤')
  174. return
  175. }
  176. this.$message.error('表单内容未填完,请填写后再提交')
  177. })
  178. if (validFormData) {
  179. validFormData.forEach((item) => {
  180. for (const [key, value] of Object.entries(item)) {
  181. let index = 0
  182. // 如果当前键是可能重复的字段,且结果对象中已经存在该键,则添加索引后缀
  183. if (
  184. (key === 'headerSelectFields' || key === 'stepTableFormData') &&
  185. result.hasOwnProperty(key)
  186. ) {
  187. // 为重复字段生成带索引的键名,从1开始(因为第一个组件不需要后缀)
  188. const newKey = `${key}_${++index}`
  189. result[newKey] = value
  190. } else {
  191. // 正常合并其他字段
  192. result[key] = value
  193. }
  194. }
  195. })
  196. return result
  197. }
  198. return false
  199. },
  200. //试验配制条件options
  201. getDictOptions(dictType) {
  202. return this.dict.type[dictType] || []
  203. },
  204. setTemplateData(data) {
  205. this.$store.commit('template/SET_TEMPLATE_DATA', data)
  206. },
  207. //统一处理删除行
  208. deleteRow(index) {
  209. this.$refs.stepTableRef.deleteRow(index)
  210. },
  211. //统一处理blur事件,因为有效周期和过期日期是相关的,所以需要在有效周期失焦时更新过期日期
  212. onHandleBlur(fields) {
  213. const {
  214. key,
  215. effectivePeriodUnit,
  216. effectivePeriod,
  217. codeSTD,
  218. targetStartSolution
  219. } = fields
  220. const { startDate } = this.formData
  221. if (key === 'codeSTD') {
  222. //起始编号STD失焦时,更新stepDataSource
  223. const arr = Array.from({ length: codeSTD }, (item, index) => ({
  224. actSolutionVolumePrecision: 3, //小数点精度默认为3
  225. actSolutionConcentrationPrecision: 3, //小数点精度默认为3
  226. targetDiluentVolumePrecision: 3, //小数点精度默认为3
  227. targetStartSolutionVolumePrecision: 3, //小数点精度默认为3
  228. targetSolutionCode: `STD${Number(codeSTD) - index}`
  229. }))
  230. this.$refs.stepTableRef.updateDataSource(arr)
  231. } else if (key === 'targetStartSolution') {
  232. //起始溶液体积失焦时,更新目标溶液预计浓度
  233. const arr = this.$refs.stepTableRef?.getDataSource()
  234. arr.forEach((item, rowIndex) => {
  235. this.updateTargetStartSolutionVolume(
  236. rowIndex,
  237. item,
  238. targetStartSolution
  239. )
  240. })
  241. }
  242. },
  243. //统一处理table失焦事件
  244. onHandleTableBlur(params) {
  245. const { rowIndex, colKey, value, item } = params
  246. if (
  247. colKey === 'targetSolutionVolume' ||
  248. colKey === 'targetSolutionConcentration' ||
  249. colKey === 'targetStartSolutionVolumePrecision' ||
  250. colKey === 'targetDiluentVolumePrecision'
  251. ) {
  252. const volume =
  253. this.$refs.stepFormPackageRef?.getFormDataByKey(
  254. 'targetStartSolution'
  255. ) || 0
  256. if (volume) {
  257. this.updateTargetStartSolutionVolume(item, volume)
  258. }
  259. } else if (
  260. colKey === 'actStartSolutionVolume' ||
  261. colKey === 'actDiluentVolume'
  262. ) {
  263. //实际起始溶液体积和实际目标溶液体积
  264. const targetAcSolution =
  265. this.$refs.stepFormPackageRef?.getFormDataByKey('targetAcSolution') ||
  266. 0 //获取实际起始溶液浓度
  267. if (targetAcSolution) {
  268. this.updateSjmbrynd(item, targetAcSolution)
  269. }
  270. }
  271. },
  272. //计算并更新实际目标溶液浓度 先计算实际目标溶液体积再计算实际目标溶液浓度
  273. updateSjmbrynd(item, targetAcSolution) {
  274. //实际源溶液浓度÷(实际终体积÷源溶液加入体积);
  275. const precision = item.actSolutionConcentrationPrecision || 0
  276. const volPrecision = item.actSolutionVolumePrecision || 0
  277. //实际稀释液体积
  278. const actDiluentVolume = item.actDiluentVolume || 0
  279. const actStartSolutionVolume = item.actStartSolutionVolume || 0
  280. //实际高源溶液加入体积+实际稀释液加入体积
  281. const actVol = (
  282. Number(actStartSolutionVolume) + Number(actDiluentVolume)
  283. ).toFixed(volPrecision)
  284. //实际目标溶液体积
  285. item.actSolutionVolume = actVol
  286. //实际目标溶液浓度
  287. const actNd = (
  288. targetAcSolution /
  289. actStartSolutionVolume /
  290. actVol
  291. ).toFixed(precision)
  292. item.actSolutionConcentration = actNd
  293. },
  294. //更新起始溶液体积时,计算目标溶液预计浓度
  295. updateTargetStartSolutionVolume(item, volume) {
  296. const precision = item.targetStartSolutionVolumePrecision || 0
  297. const concentration = item.targetSolutionConcentration || 0
  298. const targetVolume = item.targetSolutionVolume || 0
  299. //目标溶液预计浓度:(目标溶液预计体积 乘以 起始溶液浓度)除以 起始溶液体积
  300. const result = ((concentration * targetVolume) / volume).toFixed(
  301. precision
  302. )
  303. item.targetStartSolutionVolume = result
  304. // this.$refs.stepTableRef.updateDataSourceByRowIndex(rowIndex, { targetStartSolutionVolume: result });
  305. if (targetVolume) {
  306. //预设稀释液体积:目标溶液预计体积 减去 源溶液预计体积;
  307. const precision1 = item.targetDiluentVolumePrecision || 0
  308. const result1 = (targetVolume - result).toFixed(precision1)
  309. item.targetDiluentVolume = result1
  310. // this.$refs.stepTableRef.updateDataSourceByRowIndex(rowIndex, { targetDiluentVolume: result1 });
  311. }
  312. }
  313. }
  314. }