No Description

CreateClasses.vue 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <script lang="ts" setup>
  2. import type { FormInstance } from 'element-plus';
  3. import { onMounted, reactive, ref, watch } from 'vue';
  4. import { selectAllSysStation } from '#/api/system/infoEntry/stationInfo/stationInfo';
  5. const props = defineProps({
  6. isdrawer: {
  7. type: Boolean,
  8. default: false,
  9. },
  10. isdrawerloading: {
  11. type: Boolean,
  12. default: false,
  13. },
  14. editdata: {
  15. type: Object,
  16. default: () => {},
  17. },
  18. isdrawertitle: {
  19. type: String,
  20. default: '',
  21. },
  22. });
  23. const emit = defineEmits(['update:modelValue', 'submit']);
  24. const handleClose = () => {
  25. emit('update:modelValue', false);
  26. console.log('关闭了');
  27. // 重置表单数据
  28. if (ruleFormRef.value) {
  29. ruleFormRef.value.resetFields();
  30. }
  31. // 重置表单对象
  32. Object.assign(ruleForm.value, {
  33. id: '',
  34. name: '',
  35. firstWorkTime: '',
  36. lastWorkTime: '',
  37. firstWorkDuration: '',
  38. secondWorkTime: '',
  39. secondLastWorkTime: '',
  40. secondWorkDuration: '',
  41. common: '0',
  42. stationIds: [],
  43. });
  44. };
  45. // 将小时的小数形式(如7.59)转换为"X小时Y分钟"格式
  46. const convertDecimalToDuration = (decimalHours: number | string): string => {
  47. if (!decimalHours) return '';
  48. const hours = Number(decimalHours);
  49. const integerHours = Math.floor(hours);
  50. const minutes = Math.round((hours - integerHours) * 60);
  51. return `${integerHours}小时${minutes}分钟`;
  52. };
  53. const ruleFormRef = ref();
  54. const options = ref([]) as any;
  55. onMounted(async () => {
  56. try {
  57. // @ts-ignore
  58. options.value = (
  59. await selectAllSysStation({
  60. isAll: 1,
  61. pageSize: 10_000,
  62. })
  63. ).map((item) => ({
  64. value: item?.id,
  65. label: item?.stationName,
  66. }));
  67. } catch (error) {
  68. console.log(error);
  69. }
  70. });
  71. // 监听editdata变化,实现数据回显
  72. watch(
  73. () => props.editdata,
  74. (newEditData) => {
  75. if (newEditData && Object.keys(newEditData).length > 0) {
  76. // 保存ID用于编辑时的标识
  77. ruleForm.value.id = newEditData.id || '';
  78. // 填充基本字段
  79. ruleForm.value.name = newEditData.shiftName || newEditData.name || '';
  80. ruleForm.value.common = newEditData.isCommon?.toString() || '0';
  81. // 处理时间字段(确保转换为Date对象或组件可接受的格式)
  82. if (newEditData.firstStartTime) {
  83. ruleForm.value.firstWorkTime = new Date(newEditData.firstStartTime);
  84. }
  85. if (newEditData.firstEndTime) {
  86. ruleForm.value.lastWorkTime = new Date(newEditData.firstEndTime);
  87. }
  88. if (newEditData.secondStartTime) {
  89. ruleForm.value.secondWorkTime = new Date(newEditData.secondStartTime);
  90. }
  91. if (newEditData.secondEndTime) {
  92. ruleForm.value.secondLastWorkTime = new Date(newEditData.secondEndTime);
  93. }
  94. // 处理工作时长(将小数转换为"X小时Y分钟"格式)
  95. if (newEditData.firstDuration) {
  96. ruleForm.value.firstWorkDuration = convertDecimalToDuration(
  97. newEditData.firstDuration,
  98. );
  99. }
  100. if (newEditData.secondDuration) {
  101. ruleForm.value.secondWorkDuration = convertDecimalToDuration(
  102. newEditData.secondDuration,
  103. );
  104. }
  105. // 处理场站ID列表
  106. if (newEditData.applicableStations) {
  107. ruleForm.value.stationIds = newEditData.applicableStations
  108. .split(',')
  109. .map(Number);
  110. }
  111. }
  112. },
  113. { deep: true, immediate: true },
  114. );
  115. const ruleForm = ref({
  116. id: '',
  117. name: '',
  118. firstWorkTime: '',
  119. lastWorkTime: '',
  120. firstWorkDuration: '',
  121. secondWorkTime: '',
  122. secondLastWorkTime: '',
  123. secondWorkDuration: '',
  124. common: '0',
  125. stationIds: [],
  126. }) as any;
  127. const rules = reactive({
  128. name: [{ required: true, message: '请输入班次名称', trigger: 'blur' }],
  129. firstWorkTime: [
  130. { required: true, message: '请选择第一次上班时间', trigger: 'change' },
  131. ],
  132. lastWorkTime: [
  133. { required: true, message: '请选择第一次下班时间', trigger: 'change' },
  134. ],
  135. secondWorkTime: [
  136. { required: true, message: '请选择第二次上班时间', trigger: 'change' },
  137. ],
  138. secondLastWorkTime: [
  139. { required: true, message: '请选择第二次下班时间', trigger: 'change' },
  140. ],
  141. common: [{ required: true, message: '请选择常用', trigger: 'change' }],
  142. stationIds: [
  143. { required: true, message: '请选择适用场站', trigger: 'change' },
  144. ],
  145. });
  146. const SelectAll = async () => {
  147. try {
  148. // @ts-ignore
  149. ruleForm.value.stationIds = (
  150. await selectAllSysStation({
  151. isAll: 1,
  152. pageSize: 10_000,
  153. })
  154. ).map((item: any) => item?.id);
  155. } catch (error) {
  156. console.log(error);
  157. }
  158. };
  159. const submitForm = async (formEl: FormInstance | undefined) => {
  160. if (!formEl) return;
  161. await formEl.validate((valid, fields) => {
  162. if (valid) {
  163. emit('submit', ruleForm.value);
  164. } else {
  165. console.log('error submit!', fields);
  166. }
  167. });
  168. };
  169. // 计算工作时长
  170. const calculateWorkDuration = (
  171. startTime: Date | string,
  172. endTime: Date | string,
  173. ): string => {
  174. if (!startTime || !endTime) return '';
  175. const start = new Date(startTime);
  176. const end = new Date(endTime);
  177. // 计算毫秒差值
  178. const diffMs = end.getTime() - start.getTime();
  179. // 转换为小时和分钟
  180. const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
  181. const diffMinutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));
  182. // 格式化显示
  183. return `${diffHours}小时${diffMinutes}分钟`;
  184. };
  185. // 计算第一次上班时长
  186. const calculateFirstWorkDuration = () => {
  187. ruleForm.value.firstWorkDuration = calculateWorkDuration(
  188. ruleForm.value.firstWorkTime,
  189. ruleForm.value.lastWorkTime,
  190. );
  191. };
  192. // 计算第二次上班时长
  193. const calculateSecondWorkDuration = () => {
  194. ruleForm.value.secondWorkDuration = calculateWorkDuration(
  195. ruleForm.value.secondWorkTime,
  196. ruleForm.value.secondLastWorkTime,
  197. );
  198. };
  199. // const resetForm = (formEl: FormInstance | undefined) => {
  200. // if (!formEl) return;
  201. // formEl.resetFields();
  202. // };
  203. </script>
  204. <template>
  205. <el-drawer
  206. :model-value="isdrawer"
  207. @update:model-value="emit('update:modelValue', $event)"
  208. :title="isdrawertitle"
  209. direction="rtl"
  210. :close-on-click-modal="false"
  211. @close="handleClose"
  212. >
  213. <div v-loading="isdrawerloading" style="width: 100%; height: 100%">
  214. <el-form
  215. ref="ruleFormRef"
  216. style="max-width: 600px"
  217. :model="ruleForm"
  218. :rules="rules"
  219. label-width="auto"
  220. >
  221. <el-form-item label="班次名称" prop="name">
  222. <el-input v-model="ruleForm.name" placeholder="请输入班次名称" />
  223. </el-form-item>
  224. <div style="display: flex; justify-content: space-between; gap: 20px">
  225. <el-form-item label="第一次上班时间" prop="firstWorkTime">
  226. <el-date-picker
  227. v-model="ruleForm.firstWorkTime"
  228. type="datetime"
  229. placeholder="请选择"
  230. @change="calculateFirstWorkDuration"
  231. />
  232. </el-form-item>
  233. <el-form-item label="第一次下班时间" prop="lastWorkTime">
  234. <el-date-picker
  235. v-model="ruleForm.lastWorkTime"
  236. type="datetime"
  237. placeholder="请选择"
  238. @change="calculateFirstWorkDuration"
  239. />
  240. </el-form-item>
  241. </div>
  242. <el-form-item label="第一次上班时长" prop="firstWorkDuration">
  243. <el-input v-model="ruleForm.firstWorkDuration" disabled />
  244. </el-form-item>
  245. <div style="display: flex; justify-content: space-between; gap: 20px">
  246. <el-form-item label="第二次上班时间" prop="secondWorkTime">
  247. <el-date-picker
  248. v-model="ruleForm.secondWorkTime"
  249. type="datetime"
  250. placeholder="请选择"
  251. @change="calculateSecondWorkDuration"
  252. />
  253. </el-form-item>
  254. <el-form-item label="第二次下班时间" prop="secondLastWorkTime">
  255. <el-date-picker
  256. v-model="ruleForm.secondLastWorkTime"
  257. type="datetime"
  258. placeholder="请选择"
  259. @change="calculateSecondWorkDuration"
  260. />
  261. </el-form-item>
  262. </div>
  263. <el-form-item label="第二次上班时长" prop="secondWorkDuration">
  264. <el-input v-model="ruleForm.secondWorkDuration" disabled />
  265. </el-form-item>
  266. <el-form-item label="常用" prop="common">
  267. <el-radio-group v-model="ruleForm.common">
  268. <el-radio value="1" size="large">是</el-radio>
  269. <el-radio value="0" size="large">否</el-radio>
  270. </el-radio-group>
  271. </el-form-item>
  272. <el-form-item label="适用场站" prop="stationIds">
  273. <div style="display: flex; gap: 20px">
  274. <el-select
  275. v-model="ruleForm.stationIds"
  276. multiple
  277. placeholder="请选择"
  278. style="width: 240px"
  279. >
  280. <el-option
  281. v-for="item in options"
  282. :key="item.value"
  283. :label="item.label"
  284. :value="item.value"
  285. />
  286. </el-select>
  287. <el-button type="primary" @click="SelectAll"> 全选 </el-button>
  288. </div>
  289. </el-form-item>
  290. <el-form-item>
  291. <div
  292. style="
  293. width: 100%;
  294. display: flex;
  295. justify-content: flex-end;
  296. gap: 20px;
  297. "
  298. >
  299. <el-button type="primary" @click="submitForm(ruleFormRef)">
  300. 提交
  301. </el-button>
  302. <el-button @click="handleClose">取消</el-button>
  303. </div>
  304. </el-form-item>
  305. </el-form>
  306. </div>
  307. </el-drawer>
  308. </template>