华西海圻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.

392 lines
13 KiB

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