index.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <template>
  2. <el-drawer
  3. v-model="drawerVisible"
  4. :close-on-click-modal="false"
  5. :show-close="false"
  6. destroy-on-close
  7. direction="rtl"
  8. size="972px"
  9. >
  10. <template #header>
  11. <div class="drawerTitle">报工</div>
  12. </template>
  13. <template #default>
  14. <el-scrollbar>
  15. <div id="drawContent">
  16. <el-form
  17. ref="formRef"
  18. :disabled="formDisabled"
  19. label-position="left"
  20. label-width="auto"
  21. size="large"
  22. >
  23. <el-select
  24. v-if="processStore.scanInfo.batchReport == 1"
  25. v-model="selectedProcess"
  26. :filterable="true"
  27. multiple
  28. placeholder="请选择流转卡号,可以输入或者扫码筛选"
  29. style="margin-bottom: 20px"
  30. >
  31. <template #prefix
  32. ><img src="@/assets/icons/shaoma.svg"
  33. /></template>
  34. <el-option
  35. v-for="item in processList"
  36. :key="item"
  37. :label="item"
  38. :value="item"
  39. />
  40. </el-select>
  41. <el-row
  42. v-for="(per, index) in persons"
  43. :key="per.userName"
  44. :gutter="20"
  45. style="width: 100%"
  46. >
  47. <el-col :span="10">
  48. <el-form-item label="" prop="userName">
  49. <el-select
  50. v-model="per.userName"
  51. filterable
  52. placeholder="请选择人员"
  53. value-key="id"
  54. >
  55. <el-option
  56. v-for="item in dictStroe.allUsers"
  57. :key="item.id"
  58. :label="item.userName"
  59. :value="item.userName"
  60. />
  61. </el-select>
  62. </el-form-item>
  63. </el-col>
  64. <el-col :span="10">
  65. <el-form-item label="" prop="workingHoursRate">
  66. <el-select
  67. v-model="per.workingHoursRate"
  68. placeholder="请选择工时比例"
  69. value-key="value"
  70. >
  71. <el-option
  72. v-for="item in rateArray"
  73. :key="item.value"
  74. :label="item.label"
  75. :value="item.value"
  76. />
  77. </el-select>
  78. </el-form-item>
  79. </el-col>
  80. <el-col :span="4">
  81. <div v-if="!formDisabled" class="right-btns">
  82. <CirclePlus
  83. class="icon-btn"
  84. @click="
  85. persons.push({
  86. userName: null,
  87. workingHoursRate: null,
  88. })
  89. "
  90. />
  91. <Remove
  92. v-if="index !== 0"
  93. class="icon-btn"
  94. @click="persons.splice(index, 1)"
  95. />
  96. </div>
  97. </el-col>
  98. </el-row>
  99. </el-form>
  100. </div>
  101. </el-scrollbar>
  102. </template>
  103. <template #footer>
  104. <div
  105. style="display: flex; margin-bottom: 10px"
  106. v-if="processStore.scanInfo.outTime == true"
  107. >
  108. <div style="margin-top:3px;font-size:18px;">超期原因: &nbsp;</div>
  109. <el-select
  110. v-model="outTimeReason"
  111. placeholder="Select"
  112. style="width: 240px"
  113. >
  114. <el-option
  115. v-for="item in dictStroe.dicts.out_time_reason"
  116. :key="item.value"
  117. :label="item.dictLabel"
  118. :value="item.dictValue"
  119. />
  120. </el-select>
  121. </div>
  122. <div class="bottom-btns">
  123. <el-button class="cancelBtn el-button-big" @click="cancelClick"
  124. >取消</el-button
  125. >
  126. <el-button
  127. v-if="!formDisabled"
  128. class="sureBtn el-button-big"
  129. type="primary"
  130. @click="confirmClick"
  131. >报工
  132. </el-button>
  133. </div>
  134. </template>
  135. </el-drawer>
  136. </template>
  137. <script lang="ts" setup>
  138. import { useProcessStore } from "@/store/modules/processView";
  139. import { useDictionaryStore } from "@/store/modules/dictionary";
  140. import { getProcessInfo, getunProcessedList } from "@/api/prosteps";
  141. import { emitter, EventsNames } from "@/utils/common";
  142. import { CirclePlus, Remove } from "@element-plus/icons-vue";
  143. import { useUserStore } from "@/store/modules/user";
  144. import { reportWork } from "@/api/process/reportBreak";
  145. const processStore = useProcessStore();
  146. const dictStroe = useDictionaryStore();
  147. console.log(dictStroe.dicts.out_time_reason, "2");
  148. const userStore = useUserStore();
  149. // ================= 选择工序相关
  150. const selectedProcess = ref<any[]>([]);
  151. const processList = ref<any[]>([]);
  152. const router = useRouter();
  153. const drawerVisible = ref(false);
  154. const formDisabled = ref(true);
  155. const outTimeReason = ref(dictStroe.dicts.out_time_reason[0].dictValue);
  156. const formRef = ref<InstanceType<typeof ElForm>>();
  157. const persons = ref<
  158. {
  159. userName: string | null;
  160. workingHoursRate: number | null;
  161. }[]
  162. >([{ userName: userStore.user.username ?? "", workingHoursRate: 100 }]);
  163. const openReportWorkDrawer = () => {
  164. getProcessInfo(processStore.scanInfo.id).then((res) => {
  165. processStore.scanInfo.currentState = res.data.currentState;
  166. if (res.data.currentState !== "start") {
  167. ElMessage.warning("当前工单状态不允许报工");
  168. formDisabled.value = true;
  169. // reportWorkList(processStore.scanInfo.id).then((res) => {
  170. // persons.value = res.data || [];
  171. // });
  172. } else {
  173. drawerVisible.value = true;
  174. formDisabled.value = false;
  175. }
  176. if (processStore.scanInfo.batchReport === 1) {
  177. getunProcessedList(processStore.scanInfo.id).then((res: any) => {
  178. processList.value = res.data ?? [];
  179. });
  180. }
  181. });
  182. };
  183. const cancelClick = () => {
  184. drawerVisible.value = false;
  185. };
  186. const confirmClick = () => {
  187. let total = 0;
  188. persons.value.forEach((item) => {
  189. total += item.workingHoursRate ?? 0;
  190. });
  191. if (total > 100) {
  192. ElMessage.error("总占比不能超过100%");
  193. return;
  194. }
  195. let params = {
  196. processId: processStore.scanInfo.id,
  197. processUserReportList: persons.value,
  198. seqList: selectedProcess.value,
  199. outTimeReason: outTimeReason.value,
  200. };
  201. reportWork(params).then((res: any) => {
  202. if (res.code === "200") {
  203. ElMessage.success("报工成功");
  204. emitter.emit(EventsNames.PROCESS_REDER);
  205. router.replace("/process");
  206. drawerVisible.value = false;
  207. } else {
  208. ElMessage.error("报工失败");
  209. }
  210. });
  211. };
  212. defineExpose({
  213. openReportWorkDrawer,
  214. });
  215. const rateArray: { label: string; value: number }[] = [
  216. { label: "10%", value: 10 },
  217. { label: "20%", value: 20 },
  218. { label: "30%", value: 30 },
  219. { label: "40%", value: 40 },
  220. { label: "50%", value: 50 },
  221. { label: "60%", value: 60 },
  222. { label: "70%", value: 70 },
  223. { label: "80%", value: 80 },
  224. { label: "90%", value: 90 },
  225. { label: "100%", value: 100 },
  226. ];
  227. </script>
  228. <style lang="scss" scoped>
  229. #drawContent {
  230. width: 100%;
  231. }
  232. .right-btns {
  233. display: flex;
  234. justify-content: space-evenly;
  235. align-items: center;
  236. padding-top: 7px;
  237. margin-bottom: 15px;
  238. .icon-btn {
  239. width: 30px;
  240. height: 30px;
  241. }
  242. }
  243. .bottom-btns {
  244. display: flex;
  245. justify-content: center;
  246. //margin-top: 20px;
  247. //margin-bottom: 20px;
  248. .button {
  249. margin-right: 20px;
  250. }
  251. .cancelBtn {
  252. width: 292px;
  253. height: 80px;
  254. background: rgba(0, 0, 0, 0.06);
  255. border-radius: 76px 76px 76px 76px;
  256. }
  257. .sureBtn {
  258. width: 292px;
  259. height: 80px;
  260. background: #0a59f7;
  261. border-radius: 76px 76px 76px 76px;
  262. }
  263. }
  264. </style>