index.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <template>
  2. <div class="container">
  3. <div class="timer">
  4. <van-cell title="日志日期" :value="today" @click="calendarShow = true" />
  5. <!-- <van-calendar
  6. v-model:show="calendarShow"
  7. @confirm="onConfirm"
  8. :min-date="minDate"
  9. :max-date="maxDate"
  10. /> -->
  11. </div>
  12. <div class="title">今日工作</div>
  13. <van-field
  14. v-model="formData.reportContent"
  15. rows="5"
  16. autosize
  17. type="textarea"
  18. placeholder=""
  19. />
  20. <div class="title">
  21. 工作量分配 {{ totalTime ? `(总耗时${totalTime}小时)` : "" }}
  22. </div>
  23. <ProjectList type="daily" :onChange="projectChange" />
  24. <div class="title">接收人</div>
  25. <SelectUser v-model="formData.receiveUserIds" />
  26. <div class="blank-line"></div>
  27. <div class="send-btn-group" v-if="formData.isUpdate">
  28. <van-button type="primary" block @click="onSubmit(false)"
  29. >更新</van-button
  30. >
  31. </div>
  32. <div class="send-btn-group" v-else>
  33. <van-button type="success" block class="send-btn" @click="onSubmit(true)"
  34. >暂存</van-button
  35. >
  36. <van-button type="primary" block class="send-btn" @click="onSubmit(false)"
  37. >发送</van-button
  38. >
  39. </div>
  40. </div>
  41. </template>
  42. <script lang="ts" setup>
  43. /**
  44. * @description 日志
  45. */
  46. import moment from "moment";
  47. import { reactive, watch } from "vue";
  48. import { showSuccessToast, showToast } from "vant";
  49. import SelectUser from "@/components/UserSelect.vue";
  50. import ProjectList from "../components/ProjectList.vue";
  51. import { getUserInfo } from "@/utils/tools";
  52. import { http } from "../http";
  53. import { IReport } from "../interface";
  54. import { onSubmitCheck } from "../service";
  55. import PubsubService from "@/utils/PubsubService";
  56. interface FormData {
  57. reportContent: string; // 内容
  58. weeklyWorkloadList: {
  59. projectId: string;
  60. workTime: number;
  61. }[]; // 工作量分配
  62. receiveUserIds: string[]; // 接收人
  63. reportYear: string | number; // 年
  64. reportMonth: string | number; // 月
  65. reportWeek: string | number; // 周
  66. reportDay: string | number; // 本周第几天
  67. isUpdate?: boolean; // 是否是更新
  68. }
  69. // 页面数据
  70. const today = ref(moment().format("YYYY-MM-DD"));
  71. const formData = reactive<FormData>({
  72. reportContent: "",
  73. weeklyWorkloadList: [],
  74. receiveUserIds: [],
  75. reportYear: moment().format("YYYY"),
  76. reportMonth: moment().format("MM"),
  77. reportWeek: 0,
  78. reportDay: 0,
  79. });
  80. const route = useRoute();
  81. onMounted(async () => {
  82. // 查看有没有传日期进来
  83. const query: any = route.query;
  84. // 查一下有没有传id进来,有的话就是数据回填
  85. if (query.id && query.detail) {
  86. const dailyDetail = JSON.parse(route.query.detail as string);
  87. receiveData(dailyDetail);
  88. return;
  89. }
  90. if (query.date) {
  91. today.value = moment(query.date).format("YYYY-MM-DD");
  92. }
  93. // 检查一下今天是否已经填了
  94. const fillLog = await isFillLog();
  95. if (fillLog) return;
  96. // 回填历史接收人
  97. const receiveUser = await http.getReceiveUser();
  98. formData.receiveUserIds = receiveUser;
  99. // 获取当日详情
  100. await getIsWorkDays();
  101. });
  102. // 在退出前调用一下暂存(做好实时暂存后就不需要退出暂存了)
  103. // onBeforeRouteLeave((ev: any) => {
  104. // // 如果是千万详情,则不做处理
  105. // if (ev.name == "LogsDetail") return;
  106. // // 如果日志内容不为空则触发暂存,否则直接退出
  107. // if (formData.reportContent?.length > 0) {
  108. // onSubmit(true, true);
  109. // }
  110. // });
  111. // 在改动工作量的时候实时暂存
  112. watch(
  113. () => formData.reportContent,
  114. (newData, oldData) => {
  115. // 如果是更新,则不进行实时暂存
  116. if (formData.isUpdate) return;
  117. if (newData?.length > 0 && oldData?.length > 0) {
  118. onSubmit(true, true);
  119. }
  120. }
  121. );
  122. // 回填暂存数据
  123. const receiveData = (dailyDetail: any) => {
  124. formData.reportContent = dailyDetail.reportContent;
  125. formData.reportYear = dailyDetail.reportYear;
  126. formData.reportMonth = dailyDetail.reportMonth;
  127. formData.reportWeek = dailyDetail.reportWeek;
  128. if (dailyDetail.isUpdate) {
  129. formData.isUpdate = dailyDetail.isUpdate;
  130. }
  131. today.value = moment(dailyDetail.reportStartDate).format("YYYY-MM-DD");
  132. // 加个定时器回填接收人和工时
  133. const timer = setTimeout(() => {
  134. formData.receiveUserIds = dailyDetail.receiveIds;
  135. formData.weeklyWorkloadList = dailyDetail.workload.map((work: any) => ({
  136. projectId: work.projectId,
  137. workTime: work.workTime,
  138. }));
  139. PubsubService.publish(
  140. "callback-full-project-select",
  141. formData.weeklyWorkloadList
  142. );
  143. clearTimeout(timer);
  144. }, 1000);
  145. };
  146. // 判断一下今天是否已经填了,如果是填了的就跳转到详情页
  147. const isFillLog = async () => {
  148. const searchList = await http.getMonthLogList(
  149. "daily",
  150. moment(today.value).format("YYYY"),
  151. moment(today.value).format("M")
  152. );
  153. const searchLog = searchList.find(
  154. (item: any) =>
  155. moment(item.reportStartDate).format("YYYY-MM-DD") ==
  156. moment(today.value).format("YYYY-MM-DD")
  157. );
  158. if (searchLog) {
  159. if (searchLog.isTemp) {
  160. receiveData(searchLog);
  161. return true;
  162. } else {
  163. replace({
  164. path: "/logsDetail",
  165. query: {
  166. id: searchLog.id,
  167. detail: JSON.stringify({
  168. ...searchLog,
  169. comments: [], // 就不传那么多东西过去了,反正详情页面也会查询评论
  170. }),
  171. },
  172. });
  173. }
  174. }
  175. return false;
  176. };
  177. // 日历
  178. const calendarShow = ref(false);
  179. // const onConfirm = async (value: any) => {
  180. // today.value = moment(value).format("YYYY-MM-DD");
  181. // calendarShow.value = false;
  182. // // 获取当日详情
  183. // await getIsWorkDays();
  184. // };
  185. // 可选择的最小日期,一个月之前,最大日期:今天
  186. // const minDate = moment().subtract(1, "months").toDate();
  187. // const maxDate = moment().toDate();
  188. // 工作量改变
  189. const projectChange = (data: any) => {
  190. formData.weeklyWorkloadList = data;
  191. getTotalTime();
  192. };
  193. // 提交
  194. const { replace } = useRouter();
  195. const onSubmit = async (isTemp: boolean, isRouteLeave?: boolean) => {
  196. const userInfo = getUserInfo();
  197. const params: IReport = {
  198. ...formData,
  199. reportType: "daily",
  200. userId: userInfo.id ?? "",
  201. deptId: userInfo.deptId ?? "",
  202. reportStartDate: moment(today.value).valueOf(),
  203. reportEndDate: moment(today.value).valueOf(),
  204. isTemp,
  205. };
  206. // 提交前校验
  207. const submitCheck = onSubmitCheck(params);
  208. if (!submitCheck.success && !isRouteLeave) {
  209. showToast({
  210. message: submitCheck.msg,
  211. position: "top",
  212. });
  213. return;
  214. }
  215. const result: any = await http.submitReport(params);
  216. if (isRouteLeave) return; // 如果是退出,则不提示暂存
  217. const type = isTemp ? "暂存" : "发送";
  218. if (result.msg == "success") {
  219. showSuccessToast(`${type}成功`);
  220. if (!isTemp) {
  221. replace({
  222. path: "/logsDetail",
  223. query: {
  224. id: result.data,
  225. },
  226. });
  227. }
  228. } else {
  229. showToast(`${type}失败,请稍后重试`);
  230. }
  231. };
  232. // 获取是否工作日
  233. const getIsWorkDays = async (date?: string) => {
  234. const searchDate = date ?? today.value;
  235. const startDate = moment(searchDate).format("YYYY-MM-DD HH:mm:ss");
  236. const endDate = moment(searchDate).format("YYYY-MM-DD HH:mm:ss");
  237. const workDays = await http.getWorkDayList(startDate, endDate);
  238. if (workDays.length > 0) {
  239. formData.reportYear = workDays[0].year;
  240. formData.reportMonth = workDays[0].month;
  241. formData.reportWeek = workDays[0].week;
  242. formData.reportDay = workDays[0].dayOfWeek;
  243. }
  244. };
  245. // 计算总耗时
  246. const totalTime = ref(0);
  247. const getTotalTime = () => {
  248. let total = 0;
  249. formData.weeklyWorkloadList.forEach((item: any) => {
  250. total += item.workTime;
  251. });
  252. totalTime.value = total;
  253. };
  254. </script>
  255. <style lang="scss" scoped>
  256. @import "../page.scss";
  257. </style>