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

336 lines
11 KiB

  1. <template>
  2. <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" title="分装(分装后的编号可用于下一步关联选择)" append-to-body :visible.sync="visible" @close="close" width="1100px">
  3. <div class="dialog-content">
  4. <div class="header-container">
  5. <div class="header-item">
  6. <div class="header-title">母液编号</div>
  7. <HandleFormItem :isFieldsRecord="false" :item="inputItem" :error="formErrors.mybh"
  8. v-model="formData.mybh" />
  9. </div>
  10. <div class="header-item">
  11. <div class="header-title">分装数量</div>
  12. <HandleFormItem :isFieldsRecord="false" @blur="onBlurFzsl" :item="integerInputNumberItem"
  13. type = "inputNumber"
  14. :error="formErrors.fzsl" v-model="formData.fzsl" />
  15. </div>
  16. </div>
  17. <div class="content-container">
  18. <div class="content-item">
  19. <span>分装编号</span>
  20. <span class="ml-20">单位</span>
  21. <div class="unit-select">
  22. <HandleFormItem :isFieldsRecord="false" :item="unitItem" type="select" :error="formErrors.dw"
  23. @blur="(e) => onCommonBlur(e, 'dw')" v-model="formData.dw" />
  24. </div>
  25. <span class="ml-20">每份包装量</span>
  26. <div class="unit-select">
  27. <HandleFormItem type="inputNumber" :isFieldsRecord="false" :item="inputNumberItem" v-model="formData.mfbzl" />
  28. </div>
  29. <el-button type="primary" plain @click="onAverage">平均分配</el-button>
  30. <el-button type="primary" plain @click="onReset">重置</el-button>
  31. </div>
  32. <div class="header-container">
  33. <div v-for="(item, index) in fzList" class="list-item" :key="index">
  34. <div class="list-label">{{ formData.mybh }}-set{{ item.subCode }}</div>
  35. <HandleFormItem :isFieldsRecord="false" :item="inputNumberItem" :error="fzListErrors[index]"
  36. type="inputNumber" @blur="onBlurFzNum(index)" v-model="item.num" />
  37. <el-button type="primary" plain @click="onPrint(item)">打印</el-button>
  38. </div>
  39. </div>
  40. </div>
  41. </div>
  42. <template slot="footer" class="dialog-footer">
  43. <el-button @click="close">{{ $t('form.cancel') }}</el-button>
  44. <el-button type="primary" @click="onSubmit">{{ $t('form.saveConfirm') }}</el-button>
  45. </template>
  46. </el-dialog>
  47. </template>
  48. <script>
  49. import HandleFormItem from '@/components/Template/HandleFormItem.vue';
  50. import { compareVolume } from '@/utils/volumeTools.js';
  51. import { EventBus } from '@/utils/eventBus';
  52. import { getLatestSn } from '@/api/template';
  53. export default {
  54. dicts: [
  55. 'business_tjdw',
  56. ],
  57. components: {
  58. HandleFormItem,
  59. },
  60. data() {
  61. return {
  62. visible: false,
  63. inputItem: {
  64. type: "input",
  65. fillType: "actFill",
  66. disabled: true,
  67. },
  68. integerInputNumberItem: {
  69. type: "inputNumber",
  70. fillType: "actFill",
  71. precision: 0,
  72. maxlength: 3
  73. },
  74. inputNumberItem: {
  75. type: "inputNumber",
  76. fillType: "actFill",
  77. },
  78. formData: {
  79. mybh: "",//母液编号
  80. fzsl: "",//分装数量
  81. dw: "",//单位
  82. mfbzl: "",//每份包装量
  83. },
  84. fzList: [],//分装列表
  85. // 错误状态字段
  86. formErrors: {
  87. mybh: false,
  88. fzsl: false,
  89. dw: false,
  90. },
  91. fzListErrors: [], // 分装列表错误状态
  92. uuid:"",//事件id
  93. }
  94. },
  95. computed: {
  96. unitItem() {
  97. return {
  98. type: "select",
  99. fillType: "actFill",
  100. options: this.dict.type.business_tjdw
  101. }
  102. }
  103. },
  104. methods: {
  105. close() {
  106. this.visible = false;
  107. this.fzList = [];
  108. this.formData = {};
  109. this.resetErrors();
  110. },
  111. show(data) {
  112. const cloneData = JSON.parse(JSON.stringify(data));
  113. if(data && data.uuid) {//为了标识eventBus的事件id
  114. this.uuid = data.uuid
  115. }
  116. if (data.fzList) {
  117. this.fzList = JSON.parse(JSON.stringify(cloneData.fzList));
  118. // 初始化分装列表错误状态
  119. this.fzListErrors = new Array(this.fzList.length).fill(false);
  120. delete cloneData.fzList;
  121. }
  122. this.formData = cloneData;
  123. // 重置错误状态
  124. this.resetErrors();
  125. this.visible = true;
  126. },
  127. onSubmit() {
  128. // 验证表单数据
  129. if (!this.validateFormData()) {
  130. this.$message.error('表单内容未填完,请填写后再提交')
  131. return;
  132. } else {
  133. const errMsg = "分装后小份容量之和大于母液容量,是否确认分装?"
  134. const {maxVolume,maxVolumeUnit,dw} = this.formData;
  135. const totalVolume = this.fzList.reduce((acc, cur) => acc + Number(cur.num), 0);
  136. const compareResult = compareVolume(totalVolume,dw,maxVolume, maxVolumeUnit);
  137. console.log(compareResult,totalVolume,dw,maxVolume, maxVolumeUnit,"比较结果");
  138. if(compareResult > 0||!maxVolume){//没有填写实际溶液体积的也需要提示错误信息
  139. this.$modal.confirm(errMsg, '提示', {
  140. confirmButtonText: this.$t('form.saveConfirm'),
  141. cancelButtonText: this.$t('form.cancel'),
  142. type: 'warning'
  143. }).then(() => {
  144. this.submitEmit();
  145. }).catch(() => {
  146. // 取消操作,不执行任何操作
  147. });
  148. return;
  149. }
  150. this.submitEmit();
  151. }
  152. },
  153. submitEmit(){
  154. EventBus.$emit('dialogSubPackageSubmit', {...this.formData, fzList: this.fzList,uuid:this.uuid});
  155. setTimeout(() => {
  156. this.close();
  157. }, 500);
  158. },
  159. validateFormData() {
  160. let isValid = true;
  161. // 验证母液编号
  162. if (!this.formData.mybh) {
  163. this.formErrors.mybh = true;
  164. isValid = false;
  165. }
  166. // 验证分装数量
  167. if (!this.formData.fzsl) {
  168. this.formErrors.fzsl = true;
  169. isValid = false;
  170. }
  171. // 验证单位
  172. if (!this.formData.dw) {
  173. this.formErrors.dw = true;
  174. isValid = false;
  175. }
  176. // 验证分装列表中的数值
  177. if (this.fzList && this.fzList.length > 0) {
  178. for (let i = 0; i < this.fzList.length; i++) {
  179. if (!this.fzList[i].num) {
  180. // 确保fzListErrors数组有足够的元素
  181. if (this.fzListErrors.length <= i) {
  182. this.$set(this.fzListErrors, i, true);
  183. } else {
  184. this.fzListErrors[i] = true;
  185. }
  186. isValid = false;
  187. }
  188. }
  189. }
  190. return isValid;
  191. },
  192. resetErrors() {
  193. // 重置表单错误状态
  194. Object.keys(this.formErrors).forEach(key => {
  195. this.formErrors[key] = false;
  196. });
  197. // 重置分装列表错误状态
  198. this.fzListErrors.forEach((_, index) => {
  199. this.$set(this.fzListErrors, index, false);
  200. });
  201. },
  202. // 分装数量失去焦点时,根据数量生成分装列表
  203. async onBlurFzsl(e) {
  204. console.log(e,"失去焦点时的数量")
  205. // 清除当前字段的错误状态
  206. if (e) {
  207. this.formErrors.fzsl = false;
  208. }
  209. // 清空现有列表
  210. this.fzList = [];
  211. this.fzListErrors = [];
  212. const result = await getLatestSn({
  213. my: this.formData.mybh,
  214. count: e,
  215. })
  216. if(result.code === 200){
  217. const codes = result.data;
  218. // 根据输入的数量生成新列表
  219. for (let i = 0; i < e; i++) {
  220. this.fzList.push({
  221. num: "",
  222. subCode: codes[i],
  223. });
  224. // 同步初始化错误状态数组
  225. this.fzListErrors.push(false);
  226. }
  227. }
  228. },
  229. onAverage() {
  230. const { mfbzl } = this.formData;
  231. this.fzList.forEach((item, index) => {
  232. item.num = mfbzl;
  233. // 同时更新错误状态
  234. if (this.fzListErrors[index] !== undefined) {
  235. this.$set(this.fzListErrors, index, false);
  236. }
  237. })
  238. // 清除相关字段的错误状态
  239. this.formErrors.mfbzl = false;
  240. },
  241. onReset() {
  242. this.fzList.forEach((item, index) => {
  243. item.num = "";
  244. // 同时更新错误状态
  245. if (this.fzListErrors[index] !== undefined) {
  246. this.$set(this.fzListErrors, index, false);
  247. }
  248. })
  249. // 清除相关字段的错误状态
  250. this.formErrors.mfbzl = false;
  251. },
  252. onPrint(item) {
  253. EventBus.$emit('subPackageDialogPrintTag', {...this.formData, printCode: `${this.formData.mybh}-set${item.subCode}`,uuid:this.uuid});
  254. },
  255. onCommonBlur(e, field) {
  256. if (this.formData[field]) {
  257. this.formErrors[field] = false;
  258. }
  259. },
  260. onBlurFzNum(index) {
  261. if (this.fzList[index] && this.fzList[index].num) {
  262. if (this.fzListErrors[index] !== undefined) {
  263. this.$set(this.fzListErrors, index, false);
  264. }
  265. }
  266. },
  267. }
  268. }
  269. </script>
  270. <style lang="scss" scoped>
  271. .dialog-content {
  272. padding: 20px;
  273. }
  274. .unit-select {
  275. width: 100px;
  276. }
  277. .content-item {
  278. display: flex;
  279. align-items: center;
  280. }
  281. .header-container {
  282. display: grid;
  283. grid-template-columns: 1fr 1fr 1fr;
  284. grid-gap: 20px;
  285. margin-top: 20px;
  286. }
  287. .header-item {
  288. box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  289. background: #fff;
  290. border-radius: 4px;
  291. padding: 20px;
  292. }
  293. .header-title {
  294. margin-bottom: 10px;
  295. }
  296. .content-container {
  297. margin-top: 20px;
  298. padding: 20px;
  299. box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  300. max-height: 50vh;
  301. overflow: auto;
  302. }
  303. .ml-20 {
  304. margin-left: 20px;
  305. }
  306. .list-item {
  307. display: flex;
  308. align-items: center;
  309. // margin-top: 20px;
  310. }
  311. .list-label {
  312. margin-right: 5px;
  313. // width: 200px;
  314. }
  315. </style>