detailDialog.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <template>
  2. <div style="margin-top: 10px; padding: 0 20px">
  3. <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
  4. <header-title title="基本信息" />
  5. <el-row :gutter="10">
  6. <el-col :span="8">
  7. <el-form-item label="放行单编码">
  8. <el-input v-model="form.code" disabled placeholder="系统自动生成" />
  9. </el-form-item>
  10. </el-col>
  11. <el-col :span="8">
  12. <el-form-item label="放行单名称" prop="name">
  13. <el-input v-model="form.name" disabled placeholder="请输入" />
  14. </el-form-item>
  15. </el-col>
  16. </el-row>
  17. <header-title title="物品清单" />
  18. <ele-pro-table
  19. ref="table"
  20. row-key="userId"
  21. :columns="ordersColumns"
  22. :datasource="form.orders"
  23. />
  24. <header-title title="生产放行规则" />
  25. <ele-pro-table
  26. row-key="id"
  27. :columns="detailsColumns"
  28. :datasource="scDetails"
  29. >
  30. <template #isPass="{ row }">
  31. <el-radio-group v-model="row.isPass" :disabled="isScDisabled">
  32. <el-radio :label="1">是</el-radio>
  33. <el-radio :label="0">否</el-radio>
  34. </el-radio-group>
  35. </template>
  36. <template #remark="{ row }">
  37. <el-input
  38. v-model="row.remark"
  39. type="textarea"
  40. :rows="1"
  41. :disabled="isScDisabled"
  42. placeholder="请输入备注"
  43. />
  44. </template>
  45. </ele-pro-table>
  46. <header-title title="质检放行规则" />
  47. <ele-pro-table
  48. row-key="id"
  49. :columns="detailsColumns"
  50. :datasource="zjDetails"
  51. >
  52. <template #isPass="{ row }">
  53. <el-radio-group v-model="row.isPass" :disabled="isZjDisabled">
  54. <el-radio :label="1">是</el-radio>
  55. <el-radio :label="0">否</el-radio>
  56. </el-radio-group>
  57. </template>
  58. <template #remark="{ row }">
  59. <el-input
  60. v-model="row.remark"
  61. type="textarea"
  62. :rows="1"
  63. :disabled="isZjDisabled"
  64. placeholder="请输入备注"
  65. />
  66. </template>
  67. </ele-pro-table>
  68. </el-form>
  69. </div>
  70. </template>
  71. <script>
  72. import dictMixins from '@/mixins/dictMixins';
  73. import { checklistrecordGetById } from '@/api/checklistrecord/index';
  74. /** 常量 */
  75. const CHECK_TYPE = {
  76. SC: 1, // 生产
  77. ZJ: 2 // 质检
  78. };
  79. export default {
  80. mixins: [dictMixins],
  81. props: {
  82. businessId: { default: '' },
  83. tasks: { type: Array, default: () => [] }
  84. },
  85. data() {
  86. const formBaseData = {
  87. id: null,
  88. approvalStatus: null,
  89. checklistType: 0,
  90. code: '',
  91. name: '',
  92. orders: [],
  93. details: [],
  94. workConclution: null,
  95. qualityConclution: null
  96. };
  97. return {
  98. loading: false,
  99. nodeType: '',
  100. formBaseData,
  101. form: JSON.parse(JSON.stringify(formBaseData)),
  102. rules: {}
  103. };
  104. },
  105. mounted() {
  106. const currentTask = this.tasks.find((v) => v.result === 1);
  107. this.nodeType = currentTask?.definitionKey || '';
  108. this.getCheckDetails(this.businessId);
  109. },
  110. watch: {
  111. 'form.details': {
  112. deep: true,
  113. handler(details) {
  114. this.updateConclution(details);
  115. }
  116. }
  117. },
  118. computed: {
  119. /** 表格 columns 不再重复创建 */
  120. ordersColumns() {
  121. return [
  122. { type: 'index', width: 55, label: '序号', align: 'center' },
  123. { prop: 'batchNo', label: '批次号', align: 'center' },
  124. { prop: 'productCode', label: '产品编码', align: 'center' },
  125. { prop: 'productName', label: '产品名称', align: 'center' },
  126. { prop: 'workOrderCode', label: '生产工单号', align: 'center' },
  127. { prop: 'formingNum', label: '数量', align: 'center' },
  128. { prop: 'specification', label: '规格', align: 'center' },
  129. { prop: 'productModel', label: '型号', align: 'center' }
  130. ];
  131. },
  132. detailsColumns() {
  133. return [
  134. { type: 'index', width: 55, label: '序号', align: 'center' },
  135. { prop: 'mainIndicatorName', label: '指标名称', align: 'center' },
  136. { prop: 'isPass', label: '审核结果', slot: 'isPass' },
  137. { prop: 'remark', label: '备注', slot: 'remark' }
  138. ];
  139. },
  140. scDetails() {
  141. return this.form.details.filter((v) => v.checkType === CHECK_TYPE.SC);
  142. },
  143. zjDetails() {
  144. return this.form.details.filter((v) => v.checkType === CHECK_TYPE.ZJ);
  145. },
  146. isScDisabled() {
  147. return ['qualityApproval', 'leaderApproval'].includes(this.nodeType);
  148. },
  149. isZjDisabled() {
  150. return ['workOrderApproval', 'leaderApproval'].includes(this.nodeType);
  151. }
  152. },
  153. methods: {
  154. /** 获取详情 */
  155. async getCheckDetails(id) {
  156. this.loading = true;
  157. try {
  158. const data = await checklistrecordGetById(id);
  159. this.$util.assignObject(this.form, data);
  160. this.form.details.forEach((d) => (d._originIsPass = d.isPass));
  161. } finally {
  162. this.loading = false;
  163. }
  164. },
  165. /** 统一结论计算 */
  166. updateConclution(details) {
  167. const calc = (type) => {
  168. const list = details.filter((v) => v.checkType === type);
  169. if (!list.length) return null;
  170. return list.every((v) => v.isPass === 1) ? 1 : 0;
  171. };
  172. this.form.workConclution = calc(CHECK_TYPE.SC);
  173. this.form.qualityConclution = calc(CHECK_TYPE.ZJ);
  174. },
  175. /** 提交校验 */
  176. async getTableValue() {
  177. const typeMap = {
  178. workOrderApproval: CHECK_TYPE.SC,
  179. qualityApproval: CHECK_TYPE.ZJ
  180. };
  181. const needCheckType = typeMap[this.nodeType];
  182. if (needCheckType) {
  183. const invalid = this.form.details.find(
  184. (v) => v.checkType === needCheckType && ![0, 1].includes(v.isPass)
  185. );
  186. if (invalid) {
  187. this.$message.warning('请先完成所有放行规则的审核结果选择');
  188. return false;
  189. }
  190. }
  191. const changeList = this.form.details
  192. .filter((v) => v.isPass !== v._originIsPass)
  193. .map((v) => ({
  194. id: v.id,
  195. isPass: v.isPass,
  196. remark: v.remark
  197. }));
  198. if (changeList.some((v) => !v.remark?.trim())) {
  199. this.$message.warning('请填写备注');
  200. return false;
  201. }
  202. return {
  203. formData: this.form,
  204. changeList
  205. };
  206. }
  207. }
  208. };
  209. </script>
  210. <style scoped lang="scss">
  211. .detail-table {
  212. border: 1px solid #ebeef5;
  213. // 实线边框
  214. border-collapse: collapse;
  215. td {
  216. border: none;
  217. padding: 10px 15px;
  218. border: 1px solid #ebeef5;
  219. &:first-child {
  220. font-weight: 600;
  221. background: #f5f7fa;
  222. width: 130px;
  223. text-align: center;
  224. }
  225. }
  226. }
  227. .mask-box {
  228. position: relative;
  229. &::after {
  230. content: '';
  231. width: 100%;
  232. height: 100%;
  233. position: absolute;
  234. top: 0;
  235. left: 0;
  236. background: rgba(0, 0, 0, 0);
  237. cursor: pointer;
  238. }
  239. }
  240. </style>