Ddtails.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <template>
  2. <ele-modal
  3. :before-close="cancel"
  4. :close-on-click-modal="false"
  5. :maxable="true"
  6. :title="title"
  7. :visible.sync="detailsVisible"
  8. append-to-body
  9. custom-class="ele-dialog-form"
  10. width="75vw"
  11. >
  12. <el-form
  13. ref="form"
  14. :model="form"
  15. :rules="rules"
  16. label-position="right"
  17. label-width="110px"
  18. >
  19. <el-row>
  20. <headerTitle style="margin-top: 15px" title="报工信息"></headerTitle>
  21. <el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
  22. <el-form-item
  23. :rules="{
  24. required: true,
  25. message: '请选择实际开始时间',
  26. trigger: 'change'
  27. }"
  28. label="实际开始时间"
  29. prop="realStartTime"
  30. >
  31. <el-date-picker
  32. v-model="form.realStartTime"
  33. :disabled="inputDis"
  34. class="time_select"
  35. placeholder="选择实际开始时间"
  36. type="datetime"
  37. value-format="yyyy-MM-dd HH:mm:ss"
  38. @change="handleTimeChange"
  39. ></el-date-picker>
  40. </el-form-item>
  41. </el-col>
  42. <el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
  43. <el-form-item
  44. :rules="{
  45. required: true,
  46. message: '请选择实际结束时间',
  47. trigger: 'change'
  48. }"
  49. label="实际结束时间"
  50. prop="realEndTime"
  51. >
  52. <el-date-picker
  53. v-model="form.realEndTime"
  54. :disabled="inputDis"
  55. class="time_select"
  56. placeholder="选择实际结束时间"
  57. type="datetime"
  58. value-format="yyyy-MM-dd HH:mm:ss"
  59. @change="handleTimeChange"
  60. ></el-date-picker>
  61. </el-form-item>
  62. </el-col>
  63. <el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
  64. <el-form-item label="合格数量" prop="qualifiedQuantity">
  65. <el-input
  66. v-model.number="form.qualifiedQuantity"
  67. :disabled="inputDis"
  68. placeholder="请输入"
  69. type="number"
  70. @input="(e) => handleQuantityInput(e, 'qualifiedQuantity')"
  71. ></el-input>
  72. </el-form-item>
  73. </el-col>
  74. <el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
  75. <el-form-item label="不合格数量" prop="unqualifiedQuantity">
  76. <el-input
  77. v-model.number="form.unqualifiedQuantity"
  78. :disabled="inputDis"
  79. placeholder="请输入"
  80. type="number"
  81. @input="(e) => handleQuantityInput(e, 'unqualifiedQuantity')"
  82. ></el-input>
  83. </el-form-item>
  84. </el-col>
  85. <el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
  86. <el-form-item label="合格重量" prop="qualifiedWeight">
  87. <el-input
  88. v-model.number="form.qualifiedWeight"
  89. :disabled="inputDis"
  90. placeholder="请输入"
  91. type="number"
  92. @input="(e) => handleWeightInput(e, 'qualifiedWeight')"
  93. ></el-input>
  94. </el-form-item>
  95. </el-col>
  96. <el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
  97. <el-form-item label="不合格重量" prop="unqualifiedWeight">
  98. <el-input
  99. v-model.number="form.unqualifiedWeight"
  100. :disabled="inputDis"
  101. placeholder="请输入"
  102. type="number"
  103. @input="(e) => handleWeightInput(e, 'unqualifiedWeight')"
  104. ></el-input>
  105. </el-form-item>
  106. </el-col>
  107. <el-col :span="24">
  108. <el-form-item label="备注信息">
  109. <el-input
  110. v-model="form.remark"
  111. :disabled="inputDis"
  112. :rows="2"
  113. placeholder="请输入"
  114. type="textarea"
  115. ></el-input>
  116. </el-form-item>
  117. </el-col>
  118. </el-row>
  119. <el-row class="tool_btn">
  120. <el-button
  121. type="primary"
  122. size="medium"
  123. @click="submitAdd"
  124. :loading="loadingBtn"
  125. >报工</el-button
  126. >
  127. </el-row>
  128. <headerTitle style="margin-top: 15px" title="工单信息"></headerTitle>
  129. <el-row :gutter="10" class="basic">
  130. <el-col
  131. v-for="item in fieldMap.orderList"
  132. :key="item.prop"
  133. :lg="8"
  134. :md="12"
  135. :sm="12"
  136. :xl="8"
  137. :xs="12"
  138. >
  139. <el-form-item :label="item.label" class="form80">
  140. <el-input v-model="current[item.prop]" disabled>
  141. <template slot="append" v-if="item.label == '要求生产数量:'">
  142. {{ current['measuringUnit'] }}
  143. </template>
  144. <template slot="append" v-if="item.label == '要求生产重量:'">
  145. {{ current['newWeightUnit'] }}
  146. </template>
  147. </el-input>
  148. </el-form-item>
  149. </el-col>
  150. </el-row>
  151. <headerTitle style="margin-top: 15px" title="任务信息"></headerTitle>
  152. <el-row :gutter="10" class="basic">
  153. <el-col
  154. v-for="item in fieldMap.taskList"
  155. :key="item.prop"
  156. :lg="8"
  157. :md="12"
  158. :sm="12"
  159. :xl="8"
  160. :xs="12"
  161. >
  162. <el-form-item :label="item.label" class="form80">
  163. <el-input v-model="current[item.prop]" disabled>
  164. <template slot="append" v-if="item.label == '任务数量:'">
  165. {{ current['measuringUnit'] }}
  166. </template>
  167. <template slot="append" v-if="item.label == '任务重量:'">
  168. {{ current['newWeightUnit'] }}
  169. </template>
  170. </el-input>
  171. </el-form-item>
  172. </el-col>
  173. </el-row>
  174. <el-row v-if="title === '详情'">
  175. <headerTitle style="margin-top: 15px" title="报工记录"></headerTitle>
  176. <ModifyRecord ref="ModifyRecordRef" :list="list" />
  177. </el-row>
  178. <div slot="footer" class="tool_btn">
  179. <el-button @click="cancel">关闭</el-button>
  180. </div>
  181. </el-form>
  182. </ele-modal>
  183. </template>
  184. <script>
  185. import {
  186. listWorkCenter,
  187. batchUpdateRealTime,
  188. listUpdateRealTimeRecord
  189. } from '@/api/workOrderList';
  190. import ModifyRecord from '@/views/taskList/components/ModifyRecord.vue';
  191. export default {
  192. components: {
  193. ModifyRecord
  194. },
  195. props: {
  196. currentRow: {
  197. type: Object,
  198. default: () => ({})
  199. }
  200. },
  201. data() {
  202. return {
  203. title: '详情',
  204. form: {
  205. realEndTime: '',
  206. realStartTime: '',
  207. unqualifiedWeight: '',
  208. unqualifiedQuantity: '',
  209. qualifiedWeight: '',
  210. qualifiedQuantity: '',
  211. remark: ''
  212. },
  213. rules: {
  214. qualifiedQuantity: [
  215. {
  216. required: true,
  217. message: '请输入合格数量',
  218. trigger: 'blur'
  219. }
  220. ],
  221. // qualifiedWeight: [
  222. // {
  223. // required: true,
  224. // message: '请输入合格重量',
  225. // trigger: 'blur'
  226. // }
  227. // ],
  228. unqualifiedQuantity: [
  229. {
  230. required: true,
  231. message: '请输入不合格数量',
  232. trigger: 'blur'
  233. }
  234. ]
  235. // unqualifiedWeight: [
  236. // {
  237. // required: true,
  238. // message: '请输入不合格重量',
  239. // trigger: 'blur'
  240. // }
  241. // ]
  242. },
  243. current: {},
  244. detailsVisible: false,
  245. fieldMap: {
  246. orderList: [
  247. { label: '计划批次号:', prop: 'batchNo' },
  248. { label: '工单编码:', prop: 'mesWorkOrderCode' },
  249. { label: '编码', prop: 'productCode' },
  250. { label: '名称', prop: 'productName' },
  251. { label: '规格', prop: 'specification' },
  252. { label: '生产订单编码:', prop: 'workOrderCode' },
  253. { label: '计划编号:', prop: 'productionPlanCode' },
  254. { label: '工艺路线:', prop: 'produceRoutingName' },
  255. { label: '要求生产数量:', prop: 'formingNum' },
  256. { label: '要求生产重量:', prop: 'formingWeight' },
  257. { label: '所属工厂:', prop: 'factoryName' },
  258. { label: '所属班组:', prop: 'assignTeamName' },
  259. { label: '计划开始时间:', prop: 'planStartTime' },
  260. { label: '计划结束时间:', prop: 'planCompleteTime' }
  261. ],
  262. taskList: [
  263. { label: '任务编码:', prop: 'assignCode' },
  264. { label: '工序名称:', prop: 'taskName' },
  265. { label: '执行类型:', prop: 'assigneeType' },
  266. { label: '执行对象名称:', prop: 'assigneeName' },
  267. { label: '工时:', prop: 'durationText' },
  268. { label: '任务开始时间:', prop: 'startTime' },
  269. { label: '任务结束时间:', prop: 'endTime' },
  270. { label: '任务数量:', prop: 'quantity' },
  271. { label: '任务重量:', prop: 'weight' }
  272. ]
  273. },
  274. loadingBtn: false,
  275. list: []
  276. };
  277. },
  278. computed: {
  279. inputDis() {
  280. return this.title === '详情';
  281. }
  282. },
  283. methods: {
  284. open(type, row, form) {
  285. this.title = type === 'report' ? '报工' : '详情';
  286. this.detailsVisible = true;
  287. this.current = { ...row };
  288. if (form.realEndTime) {
  289. this.$nextTick(() => {
  290. this.form = { ...form };
  291. });
  292. if (type !== 'report') {
  293. listUpdateRealTimeRecord(row.apsAssigneeId)
  294. .then((res) => {
  295. if (res) {
  296. this.list = res;
  297. }
  298. })
  299. .catch((err) => {
  300. this.$message.error(err.message);
  301. });
  302. }
  303. }
  304. this.getData();
  305. },
  306. cancel() {
  307. this.form = {
  308. realEndTime: '',
  309. realStartTime: '',
  310. unqualifiedWeight: '',
  311. unqualifiedQuantity: '',
  312. qualifiedWeight: '',
  313. qualifiedQuantity: '',
  314. remark: ''
  315. };
  316. this.$refs.form.resetFields();
  317. this.detailsVisible = false;
  318. },
  319. async getData() {
  320. try {
  321. const res = await listWorkCenter(this.current.firstTaskId);
  322. this.$set(this.current, 'factoryName', res[0].factoryName);
  323. } catch (err) {
  324. this.$message.warning(err.message);
  325. }
  326. },
  327. // 时间选择
  328. handleTimeChange() {
  329. // 如果结束时间早于开始时间,清空结束时间
  330. if (this.form.realStartTime && this.current.startTime) {
  331. const realStartTime = new Date(this.form.realStartTime).getTime();
  332. const realEndTime = new Date(this.current.startTime).getTime();
  333. if (realStartTime < realEndTime) {
  334. this.form.realStartTime = '';
  335. this.$message.warning('实际开始时间不能早于任务开始时间');
  336. }
  337. }
  338. if (this.form.realStartTime && this.form.realEndTime) {
  339. const realStartTime = new Date(this.form.realStartTime).getTime();
  340. const realEndTime = new Date(this.form.realEndTime).getTime();
  341. if (realStartTime > realEndTime) {
  342. this.form.realEndTime = '';
  343. this.$message.warning('结束时间不能早于开始时间');
  344. }
  345. }
  346. },
  347. // 重量正则判断
  348. handleWeightInput(e, type) {
  349. // 过滤非数字和非小数点字符(包括负号)
  350. let value = e.replace(/[^\d.]/g, '');
  351. // 限制只能有一个小数点
  352. const dotCount = (value.match(/\./g) || []).length;
  353. if (dotCount > 1) {
  354. value = value.slice(0, value.lastIndexOf('.'));
  355. }
  356. // 限制不能以小数点开头
  357. if (value.startsWith('.')) {
  358. value = '0' + value;
  359. }
  360. // 更新绑定值
  361. this.form[type] = value;
  362. // this.calculateWeight(type);
  363. },
  364. //计算重量
  365. calculateWeight(type) {
  366. let total =
  367. this.form.qualifiedWeight - 0 + (this.form.unqualifiedWeight - 0);
  368. if (total > this.current.weight) {
  369. this.form[type] = 0;
  370. this.$message.warning('合格重量加不合格重量不能大于任务重量');
  371. }
  372. },
  373. // 计算数量
  374. calculateQuantity(type) {
  375. let total =
  376. this.form.qualifiedQuantity - 0 + (this.form.unqualifiedQuantity - 0);
  377. if (total > this.current.quantity) {
  378. this.form[type] = 0;
  379. this.$message.warning('合格数量加不合格数量不能大于任务数量');
  380. }
  381. },
  382. // 数量正则 quantity
  383. handleQuantityInput(e, type) {
  384. // 过滤非数字字符(包括负号)
  385. let value = e.replace(/[^\d]/g, '');
  386. // 限制不能以 0 开头(除非是 0 本身)
  387. if (value.startsWith('0') && value.length > 1) {
  388. value = value.slice(1);
  389. }
  390. // 更新绑定值
  391. this.form[type] = value;
  392. this.calculateQuantity(type);
  393. },
  394. submitAdd() {
  395. this.$refs.form.validate((valid) => {
  396. if (!valid) return;
  397. // if (
  398. // this.form.qualifiedQuantity -
  399. // 0 +
  400. // (this.form.unqualifiedQuantity - 0) !==
  401. // this.current.quantity
  402. // ) {
  403. // return this.$message.warning(
  404. // `合格数量加不合格数量要等于任务数量${this.current.quantity}`
  405. // );
  406. // }
  407. // if (
  408. // this.form.qualifiedWeight -
  409. // 0 +
  410. // (this.form.unqualifiedWeight - 0) !==
  411. // this.current.weight
  412. // ) {
  413. // return this.$message.warning(
  414. // `合格重量加不合格重量要等于任务重量${this.current.weight}`
  415. // );
  416. // }
  417. let data = {
  418. ...this.form,
  419. apsAssigneeId: this.current.apsAssigneeId
  420. };
  421. this.loadingBtn = true;
  422. batchUpdateRealTime([data])
  423. .then((res) => {
  424. this.loadingBtn = false;
  425. if (res) {
  426. this.$message.success('操作成功');
  427. this.cancel();
  428. this.$emit('success');
  429. }
  430. })
  431. .catch((err) => {
  432. this.loadingBtn = false;
  433. this.$message.error(err.message);
  434. });
  435. });
  436. }
  437. }
  438. };
  439. </script>
  440. <style scoped lang="scss">
  441. ::v-deep .time_select {
  442. width: 100%;
  443. }
  444. ::v-deep .tool_btn {
  445. text-align: right;
  446. .el-button {
  447. padding: 10px 18px !important;
  448. font-size: 15px !important;
  449. }
  450. }
  451. </style>