index.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <template>
  2. <flow-form :data="formData" @submit="submitNextActivity">
  3. <card title="基础信息">
  4. <van-form required="auto" ref="form" :readonly="formRead">
  5. <van-cell-group inset>
  6. <van-field
  7. v-model="formData.userNickname"
  8. name="请假人"
  9. label="请假人"
  10. placeholder="请假人"
  11. readonly
  12. :rules="[{ required: true, message: '未获取请假人' }]"
  13. />
  14. <van-field
  15. v-model="formData.deptName"
  16. name="所在部门"
  17. label="所在部门"
  18. placeholder="所在部门"
  19. readonly
  20. :rules="[{ required: true, message: '未获取所在部门' }]"
  21. />
  22. <van-field
  23. v-model="formData.createTime"
  24. name="申请时间"
  25. label="申请时间"
  26. placeholder="申请时间"
  27. readonly
  28. :rules="[{ required: true, message: '请填写申请时间' }]"
  29. />
  30. <van-field
  31. v-model="formData.leaveNo"
  32. name="请假单号"
  33. label="请假单号"
  34. placeholder="请假单号"
  35. readonly
  36. />
  37. <van-field
  38. v-model="formData.leaveTypeText"
  39. is-link
  40. readonly
  41. name="休假类型"
  42. label="休假类型"
  43. placeholder="点击选择休假类型"
  44. :rules="[{ required: true, message: '请选择休假类型' }]"
  45. @click="pickerClick"
  46. />
  47. <van-popup v-model:show="showPicker" position="bottom">
  48. <van-picker
  49. v-model="leaveTypePiker"
  50. :columns="columns"
  51. @confirm="onConfirm"
  52. @change="onConfirm"
  53. @cancel="showPicker = false"
  54. />
  55. </van-popup>
  56. <van-field
  57. v-model="formData.leaveDays"
  58. name="休假天数"
  59. label="休假天数"
  60. placeholder="休假天数"
  61. readonly
  62. :rules="[{ required: true, message: '请填写休假天数' }]"
  63. />
  64. <van-field
  65. v-model="formData.leaveReason"
  66. name="请假原因"
  67. label="请假原因"
  68. placeholder="请假原因"
  69. type="textarea"
  70. rows="3"
  71. autosize
  72. :rules="[{ required: true, message: '请填写休假原因' }]"
  73. />
  74. </van-cell-group>
  75. </van-form>
  76. </card>
  77. <card title="请假时间信息">
  78. <template #right>
  79. <button class="add_btn" @click="popupShow = true" v-if="!formRead">
  80. 新增
  81. </button>
  82. </template>
  83. <template #default>
  84. <div v-for="(item, index) in formData.leaveTimeCreateList" :key="index">
  85. <van-swipe-cell :disabled="formRead">
  86. <card-cell>
  87. <van-cell title="起始时间" :value="item.startTime" />
  88. <van-cell title="截止时间" :value="item.endTime" />
  89. <van-cell title="备注" :value="item.bz1" />
  90. </card-cell>
  91. <template #right>
  92. <van-button
  93. square
  94. type="primary"
  95. text="编辑"
  96. @click="detailView(index, item)"
  97. />
  98. <van-button
  99. square
  100. type="danger"
  101. text="删除"
  102. @click="detailDelte(index)"
  103. />
  104. </template>
  105. </van-swipe-cell>
  106. </div>
  107. </template>
  108. </card>
  109. </flow-form>
  110. <van-popup class="detail-popup" v-model:show="popupShow" position="bottom">
  111. <h4 class="title">新增请假时间</h4>
  112. <van-cell-group inset>
  113. <date-time-range
  114. label="起始时间"
  115. v-model="detailData.startTime"
  116. placeholder="请选择起始时间"
  117. @change="startTimeChange"
  118. />
  119. <date-time-range
  120. label="截止时间"
  121. v-model="detailData.endTime"
  122. placeholder="请选择截止时间"
  123. @change="endTimeChange"
  124. />
  125. <van-field
  126. v-model="detailData.bz1"
  127. name="备注"
  128. label="备注"
  129. placeholder="备注"
  130. type="textarea"
  131. rows="3"
  132. autosize
  133. />
  134. </van-cell-group>
  135. <div class="fixed-btn">
  136. <van-button round block type="primary" @click="saveHandle">
  137. 保存
  138. </van-button>
  139. </div>
  140. </van-popup>
  141. </template>
  142. <script setup lang="ts">
  143. import { useRoute } from "vue-router";
  144. import { FlowDTO, getNextActivity } from "@/service/flow";
  145. import reqest from "@/utils/request";
  146. import DateTimeRange from "@/components/dateTimeRange.vue";
  147. import FlowForm from "@/components/flowForm.vue";
  148. import Card from "@/components/card.vue";
  149. import CardCell from "@/components/cardCell.vue";
  150. import { showSuccessToast, showFailToast } from "vant";
  151. import { getDictOptions, getDictLabel, DICT_TYPE } from "@/utils/dict";
  152. const popupShow = ref<boolean>(false);
  153. const form = ref(null);
  154. const route = useRoute();
  155. interface FormDataType {
  156. instanceId: string;
  157. id: string;
  158. leaveHours: number | null;
  159. userNickname: string;
  160. deptName: string;
  161. createTime: string;
  162. leaveNo: string;
  163. leaveType: number | null;
  164. leaveTypeText: string;
  165. leaveDays: string;
  166. leaveReason: string;
  167. leaveTimeCreateList: {
  168. leaveId: string;
  169. startTime: string;
  170. endTime: string;
  171. bz1: string;
  172. }[];
  173. }
  174. const formData = ref<FormDataType>({
  175. instanceId: "",
  176. id: "",
  177. leaveHours: null,
  178. userNickname: "",
  179. deptName: "",
  180. createTime: "",
  181. leaveNo: "",
  182. leaveType: null,
  183. leaveTypeText: "",
  184. leaveDays: "",
  185. leaveReason: "",
  186. leaveTimeCreateList: [],
  187. });
  188. const detailData = ref({
  189. leaveId: "",
  190. startTime: "",
  191. endTime: "",
  192. bz1: "",
  193. });
  194. const detailEdit = ref(false);
  195. const formRead = ref(false);
  196. const detailIndex = ref<any>(null);
  197. const leaveTypePiker = ref(["11"]);
  198. const showPicker = ref(false);
  199. const columns = getDictOptions(DICT_TYPE.WF_LEAVE_TYPE, {
  200. label: "text",
  201. });
  202. const { activityInstanceId, participant, flowInstanceId, read, _o } =
  203. route.query as {
  204. activityInstanceId: string;
  205. participant: string;
  206. flowInstanceId: string;
  207. read: string;
  208. _o: string;
  209. };
  210. const activityData: FlowDTO = {
  211. activityInstanceId,
  212. participantId: participant,
  213. flowOpinion: "",
  214. };
  215. const onConfirm = ({ selectedOptions }) => {
  216. formData.value.leaveTypeText = selectedOptions[0]?.text;
  217. formData.value.leaveType = selectedOptions[0]?.value;
  218. showPicker.value = false;
  219. };
  220. const submitNextActivity = async (NextActivity: () => Promise<any>) => {
  221. form.value.validate().then(async () => {
  222. formData.value.leaveTimeCreateList.forEach((x: any) => {
  223. x.startTime = Date.parse(x.startTime);
  224. x.endTime = Date.parse(x.endTime);
  225. });
  226. //更新表单业务数据
  227. if (!formRead.value) {
  228. const result = await reqest.post(
  229. "/business/Leave/update",
  230. formData.value
  231. );
  232. if (result.code === 200 || result.code === 0) {
  233. //工作流转件
  234. NextActivity();
  235. }
  236. } else {
  237. //工作流转件
  238. NextActivity();
  239. }
  240. });
  241. };
  242. /** 初始化表单数据 */
  243. const initFormData = async () => {
  244. const result = await reqest.get(
  245. `/business/Leave/mobileAdd?flowInstanceId=${flowInstanceId}`
  246. );
  247. formData.value = result.data;
  248. formData.value.leaveTypeText = getDictLabel(
  249. DICT_TYPE.WF_LEAVE_TYPE,
  250. result.data.leaveType
  251. );
  252. };
  253. /** 细节数据保存 */
  254. const saveHandle = async () => {
  255. detailData.value.leaveId = formData.value.id;
  256. if (detailEdit.value) {
  257. formData.value.leaveTimeCreateList[detailIndex.value] = detailData.value;
  258. } else {
  259. formData.value.leaveTimeCreateList.push(detailData.value);
  260. }
  261. detailData.value = {
  262. leaveId: "",
  263. startTime: "",
  264. endTime: "",
  265. bz1: "",
  266. };
  267. const prarms: Object[] = [];
  268. formData.value.leaveTimeCreateList.forEach((x: any) => {
  269. const startTime = Date.parse(x.startTime);
  270. const endTime = Date.parse(x.endTime);
  271. const obj = new Object({
  272. startTime: startTime,
  273. endTime: endTime,
  274. });
  275. prarms.push(obj);
  276. });
  277. const result = await reqest.post(`/business/Leave/getLeaveDays`, prarms);
  278. if (result.data) {
  279. const totalMin = result.data;
  280. const totalHours = totalMin / 60;
  281. const totalDays = Math.floor(totalHours / 7.5);
  282. const subHours = totalHours % 7.5;
  283. let leaveDaysText = "";
  284. if (totalDays > 0) {
  285. leaveDaysText += totalDays + "天";
  286. }
  287. if (subHours > 0) {
  288. leaveDaysText += subHours + "小时";
  289. }
  290. formData.value.leaveDays = leaveDaysText;
  291. formData.value.leaveHours = totalHours;
  292. }
  293. popupShow.value = false;
  294. detailEdit.value = false;
  295. detailIndex.value = null;
  296. };
  297. /** 细节编辑 */
  298. const detailView = (index: number, item: any) => {
  299. popupShow.value = true;
  300. detailEdit.value = true;
  301. detailIndex.value = index;
  302. detailData.value = item;
  303. };
  304. /** 选择框事件 */
  305. const pickerClick = () => {
  306. if (!formRead.value) {
  307. showPicker.value = true;
  308. }
  309. };
  310. /** 细节删除 */
  311. const detailDelte = (index: number) => {
  312. formData.value.leaveTimeCreateList.splice(index, 1);
  313. };
  314. /** 起始时间变化事件 */
  315. const startTimeChange = (value: string) => {
  316. if (Date.parse(value) > Date.parse(detailData.value.endTime)) {
  317. showFailToast("起始时间不能大于开始时间!");
  318. detailData.value.startTime = "";
  319. }
  320. };
  321. /** 截止时间变化事件 */
  322. const endTimeChange = (value: string) => {
  323. if (Date.parse(value) < Date.parse(detailData.value.startTime)) {
  324. showFailToast("截止时间不能小于开始时间!");
  325. detailData.value.endTime = "";
  326. }
  327. };
  328. /** 初始化 */
  329. onMounted(() => {
  330. initFormData();
  331. if (read === "1" || _o === "v") {
  332. formRead.value = true;
  333. }
  334. });
  335. </script>
  336. <style lang="scss" scoped>
  337. @import "./index.scss";
  338. </style>