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

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