index.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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-row
  24. v-for="(per, index) in persons"
  25. :key="per.userName"
  26. :gutter="20"
  27. style="width: 100%"
  28. >
  29. <el-col :span="10">
  30. <el-form-item label="" prop="userName">
  31. <el-select
  32. v-model="per.userName"
  33. filterable
  34. placeholder="请选择人员"
  35. value-key="id"
  36. >
  37. <el-option
  38. v-for="item in dictStroe.allUsers"
  39. :key="item.id"
  40. :label="item.userName"
  41. :value="item.userName"
  42. />
  43. </el-select>
  44. </el-form-item>
  45. </el-col>
  46. <el-col :span="10">
  47. <el-form-item label="" prop="workingHoursRate">
  48. <el-select
  49. v-model="per.workingHoursRate"
  50. placeholder="请选择工时比例"
  51. value-key="value"
  52. >
  53. <el-option
  54. v-for="item in rateArray"
  55. :key="item.value"
  56. :label="item.label"
  57. :value="item.value"
  58. />
  59. </el-select>
  60. </el-form-item>
  61. </el-col>
  62. <el-col :span="4">
  63. <div v-if="!formDisabled" class="right-btns">
  64. <CirclePlus
  65. class="icon-btn"
  66. @click="
  67. persons.push({
  68. userName: null,
  69. workingHoursRate: null,
  70. })
  71. "
  72. />
  73. <Remove
  74. v-if="index !== 0"
  75. class="icon-btn"
  76. @click="persons.splice(index, 1)"
  77. />
  78. </div>
  79. </el-col>
  80. </el-row>
  81. </el-form>
  82. </div>
  83. </el-scrollbar>
  84. </template>
  85. <template #footer>
  86. <div class="bottom-btns">
  87. <el-button class="cancelBtn" @click="cancelClick">取消</el-button>
  88. <el-button
  89. v-if="!formDisabled"
  90. class="sureBtn"
  91. type="primary"
  92. @click="confirmClick"
  93. >报工
  94. </el-button>
  95. </div>
  96. </template>
  97. </el-drawer>
  98. </template>
  99. <script lang="ts" setup>
  100. import { useProcessStore } from "@/store/modules/processView";
  101. import { useDictionaryStore } from "@/store/modules/dictionary";
  102. import { getProcessInfo } from "@/api/prosteps";
  103. import { CirclePlus, Remove } from "@element-plus/icons-vue";
  104. import { useUserStore } from "@/store/modules/user";
  105. import { reportWork } from "@/api/process/reportBreak";
  106. const processStore = useProcessStore();
  107. const dictStroe = useDictionaryStore();
  108. const userStore = useUserStore();
  109. const router = useRouter();
  110. const drawerVisible = ref(false);
  111. const formDisabled = ref(true);
  112. const formRef = ref<InstanceType<typeof ElForm>>();
  113. const persons = ref<
  114. {
  115. userName: string | null;
  116. workingHoursRate: number | null;
  117. }[]
  118. >([{ userName: userStore.user.username ?? "", workingHoursRate: 100 }]);
  119. const openReportWorkDrawer = () => {
  120. getProcessInfo(processStore.scanInfo.id).then((res) => {
  121. processStore.scanInfo.currentState = res.data.currentState;
  122. if (res.data.currentState !== "start") {
  123. ElMessage.warning("当前工单状态不允许报工");
  124. formDisabled.value = true;
  125. // reportWorkList(processStore.scanInfo.id).then((res) => {
  126. // persons.value = res.data || [];
  127. // });
  128. } else {
  129. drawerVisible.value = true;
  130. formDisabled.value = false;
  131. }
  132. });
  133. };
  134. const cancelClick = () => {
  135. drawerVisible.value = false;
  136. };
  137. const confirmClick = () => {
  138. let total = 0;
  139. persons.value.forEach((item) => {
  140. total += item.workingHoursRate ?? 0;
  141. });
  142. if (total > 100) {
  143. ElMessage.error("总占比不能超过100%");
  144. return;
  145. }
  146. let params = {
  147. processId: processStore.scanInfo.id,
  148. processUserReportList: persons.value,
  149. };
  150. reportWork(params).then((res: any) => {
  151. if (res.code === "200") {
  152. ElMessage.success("报工成功");
  153. router.replace("/process");
  154. drawerVisible.value = false;
  155. } else {
  156. ElMessage.error("报工失败");
  157. }
  158. });
  159. };
  160. defineExpose({
  161. openReportWorkDrawer,
  162. });
  163. const rateArray: { label: string; value: number }[] = [
  164. { label: "10%", value: 10 },
  165. { label: "20%", value: 20 },
  166. { label: "30%", value: 30 },
  167. { label: "40%", value: 40 },
  168. { label: "50%", value: 50 },
  169. { label: "60%", value: 60 },
  170. { label: "70%", value: 70 },
  171. { label: "80%", value: 80 },
  172. { label: "90%", value: 90 },
  173. { label: "100%", value: 100 },
  174. ];
  175. </script>
  176. <style lang="scss" scoped>
  177. #drawContent {
  178. width: 100%;
  179. }
  180. .right-btns {
  181. display: flex;
  182. justify-content: space-evenly;
  183. align-items: center;
  184. padding-top: 7px;
  185. margin-bottom: 15px;
  186. .icon-btn {
  187. width: 30px;
  188. height: 30px;
  189. }
  190. }
  191. .bottom-btns {
  192. display: flex;
  193. justify-content: center;
  194. //margin-top: 20px;
  195. //margin-bottom: 20px;
  196. .button {
  197. margin-right: 20px;
  198. }
  199. .cancelBtn {
  200. width: 292px;
  201. height: 80px;
  202. background: rgba(0, 0, 0, 0.06);
  203. border-radius: 76px 76px 76px 76px;
  204. }
  205. .sureBtn {
  206. width: 292px;
  207. height: 80px;
  208. background: #0a59f7;
  209. border-radius: 76px 76px 76px 76px;
  210. }
  211. }
  212. </style>