index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. <template>
  2. <div>
  3. <van-nav-bar
  4. title="工单新增"
  5. left-text="返回"
  6. left-arrow
  7. @click-left="onClickLeft"
  8. />
  9. <div class="listcontent" :style="`height:${bodyheight}px`">
  10. <van-form @submit="onSubmit">
  11. <van-cell-group inset>
  12. <van-field
  13. v-model="taskinfo.taskCode"
  14. name="系统工单"
  15. label="系统工单"
  16. placeholder="工单号"
  17. />
  18. <van-field
  19. v-model="taskinfo.taskOtherId"
  20. name="来件工单号"
  21. label="来件工单号"
  22. placeholder="来件工单号"
  23. />
  24. <van-field
  25. v-model="taskdfrom"
  26. name="事件来源"
  27. label="事件来源"
  28. placeholder="点击选择事件来源"
  29. is-link
  30. readonly
  31. @click="showPicker3 = true"
  32. />
  33. <van-popup v-model:show="showPicker3" position="bottom">
  34. <van-picker
  35. v-model="taskdfrom"
  36. title="选择事件来源"
  37. :columns="allfrom"
  38. @confirm="onConfirm3"
  39. @cancel="showPicker3 = false"
  40. />
  41. </van-popup>
  42. <van-field
  43. v-model="taskdarea"
  44. name="行政区"
  45. label="行政区"
  46. placeholder="点击选择行政区"
  47. is-link
  48. readonly
  49. @click="showPicker2 = true"
  50. />
  51. <van-popup v-model:show="showPicker2" position="bottom">
  52. <van-picker
  53. v-model="taskdarea"
  54. title="选择行政区"
  55. :columns="allarea"
  56. @confirm="onConfirm2"
  57. @cancel="showPicker2 = false"
  58. />
  59. </van-popup>
  60. <van-field
  61. v-model="taskinfo.taskAddrRoad"
  62. name="道路名"
  63. label="道路名"
  64. placeholder="道路名"
  65. />
  66. <van-field
  67. v-model="taskinfo.taskComplainConnect"
  68. name="投诉人电话"
  69. label="投诉人电话"
  70. placeholder="投诉人电话"
  71. />
  72. <van-field label="班组区域" name="班组区域">
  73. <template #input>
  74. <el-tree-select
  75. v-model="taskinfo.taskDeptRange"
  76. multiple
  77. :data="treedept"
  78. check-strictly="true"
  79. />
  80. </template>
  81. </van-field>
  82. <!-- <van-field-->
  83. <!-- v-model="taskinfo.taskTime"-->
  84. <!-- is-link-->
  85. <!-- readonly-->
  86. <!-- name="picker"-->
  87. <!-- label="来件时间"-->
  88. <!-- placeholder="点击选择时间"-->
  89. <!-- @click="showPicker = true"-->
  90. <!-- />-->
  91. <!-- <van-popup v-model:show="showPicker" position="bottom">-->
  92. <!-- <van-datetime-picker-->
  93. <!-- v-model="taskdate"-->
  94. <!-- type="datetime"-->
  95. <!-- title="选择完整时间"-->
  96. <!-- @confirm="onConfirm"-->
  97. <!-- @cancel="showPicker = false"-->
  98. <!-- />-->
  99. <!-- </van-popup>-->
  100. <van-field
  101. v-model="taskinfo.taskReqCompleteTime"
  102. is-link
  103. readonly
  104. name="picker1"
  105. label="要求完成时间"
  106. placeholder="点击选择时间"
  107. @click="showPicker4 = true"
  108. />
  109. <van-popup v-model:show="showPicker4" position="bottom">
  110. <van-datetime-picker
  111. v-model="taskdate1"
  112. type="datetime"
  113. title="选择完整时间"
  114. @confirm="onConfirm4"
  115. @cancel="showPicker4 = false"
  116. />
  117. </van-popup>
  118. <van-field
  119. v-model="taskinfo.taskTime"
  120. name="处理时限"
  121. label="处理时限"
  122. placeholder="处理时限"
  123. readonly
  124. />
  125. <van-field
  126. v-model="taskdtype"
  127. name="事件类型"
  128. label="事件类型"
  129. is-link
  130. readonly
  131. placeholder="点击选择事件类型"
  132. @click="showPicker1 = true"
  133. />
  134. <van-popup v-model:show="showPicker1" position="bottom">
  135. <van-picker
  136. v-model="taskdtype"
  137. title="选择事件类型"
  138. :columns="alltype"
  139. @confirm="onConfirm1"
  140. @cancel="showPicker1 = false"
  141. />
  142. </van-popup>
  143. <van-field
  144. v-model="taskdcategory"
  145. name="事件分类"
  146. label="事件分类"
  147. is-link
  148. readonly
  149. placeholder="点击选择事件分类"
  150. @click="showPicker5 = true"
  151. />
  152. <van-popup v-model:show="showPicker5" position="bottom">
  153. <van-picker
  154. v-model="taskdcategory"
  155. title="选择事件类型"
  156. :columns="allcategory"
  157. @confirm="onConfirm5"
  158. @cancel="showPicker5 = false"
  159. />
  160. </van-popup>
  161. <van-field
  162. name="任务内容"
  163. label="任务内容"
  164. v-model="taskinfo.taskContent"
  165. rows="2"
  166. autosize
  167. type="textarea"
  168. placeholder="请输入任务内容"
  169. />
  170. <!-- <van-field-->
  171. <!-- v-model="taskdisconfirm"-->
  172. <!-- name="是否需要确认"-->
  173. <!-- label="是否需要确认"-->
  174. <!-- is-link-->
  175. <!-- readonly-->
  176. <!-- placeholder="点击选择"-->
  177. <!-- @click="showPicker6 = true"-->
  178. <!-- />-->
  179. <!-- <van-popup v-model:show="showPicker6" position="bottom">-->
  180. <!-- <van-picker-->
  181. <!-- v-model="taskdisconfirm"-->
  182. <!-- title="是否需要确认"-->
  183. <!-- :columns="allconfirm"-->
  184. <!-- @confirm="onConfirm6"-->
  185. <!-- @cancel="showPicker6 = false"-->
  186. <!-- />-->
  187. <!-- </van-popup>-->
  188. <van-field name="接单人员" label="接单人员">
  189. <template #input>
  190. <el-select
  191. v-model="taskinfo.taskReporter"
  192. filterable
  193. default-first-option
  194. :reserve-keyword="false"
  195. placeholder="请选择人员"
  196. >
  197. <el-option
  198. v-for="item in allusers"
  199. :key="item.userId"
  200. :label="item.nickName"
  201. :value="item.userId+''"
  202. />
  203. </el-select>
  204. </template>
  205. </van-field>
  206. <van-field
  207. v-model="taskinfo.taskFromRemark"
  208. name="来件备注"
  209. label="来件备注"
  210. rows="2"
  211. autosize
  212. type="textarea"
  213. placeholder="来件备注"
  214. />
  215. <van-field
  216. v-model="taskinfo.taskAddr"
  217. name="详细地址"
  218. label="详细地址"
  219. placeholder="详细地址"
  220. >
  221. <template #button>
  222. <van-button
  223. size="small"
  224. type="primary"
  225. icon="search"
  226. @click="searchaddr"
  227. ></van-button>
  228. </template>
  229. </van-field>
  230. <div style="padding-top: 10px">
  231. <MapSelect ref="mapSelect" v-model:formv="formlocation"></MapSelect>
  232. </div>
  233. <van-field name="照片附件" label="照片附件">
  234. <template #input>
  235. <ImageUpload v-model="fileList"></ImageUpload>
  236. </template>
  237. </van-field>
  238. </van-cell-group>
  239. <div style="margin: 16px">
  240. <van-button round block type="primary" native-type="submit">
  241. 提交
  242. </van-button>
  243. </div>
  244. </van-form>
  245. </div>
  246. </div>
  247. </template>
  248. <script setup>
  249. import { defineComponent, ref, onMounted, watch } from "vue";
  250. import { cloneDeep } from "lodash";
  251. import { listDept, getDept } from "@/api/system/dept";
  252. import ImagePreview from "@/components/ImagePreview";
  253. import ImageUpload from "@/components/ImageUpload";
  254. import { useDict } from "@/utils/dict";
  255. import { useRoute } from "vue-router";
  256. import MapSelect from "@/components/MapSelect";
  257. import moment from "moment";
  258. import {
  259. listTask,
  260. getTask,
  261. delTask,
  262. addTask,
  263. updateTask,
  264. distributedTask,
  265. closeTask,
  266. czTask,
  267. gzTask,
  268. hcTask,
  269. } from "@/api/system/task";
  270. import {
  271. changeUserStatus,
  272. listUser,
  273. resetUserPwd,
  274. delUser,
  275. getUser,
  276. updateUser,
  277. addUser,
  278. } from "@/api/system/user";
  279. import { Toast } from "vant";
  280. import { treeselect as deptTreeselect } from "@/api/system/dept";
  281. import router from "../../../../router";
  282. const {
  283. task_status,
  284. task_event_category,
  285. task_event_type,
  286. sys_area,
  287. task_type,
  288. } = useDict(
  289. "task_status",
  290. "task_event_category",
  291. "task_event_type",
  292. "sys_area",
  293. "task_type"
  294. );
  295. const bodyheight = ref(0);
  296. const showPicker = ref(false);
  297. const showPicker1 = ref(false);
  298. const showPicker2 = ref(false);
  299. const showPicker3 = ref(false);
  300. const showPicker4 = ref(false);
  301. const showPicker5 = ref(false);
  302. const showPicker6 = ref(false);
  303. const taskdate = ref(new Date());
  304. const taskdate1 = ref(new Date());
  305. const taskdate2 = ref(new Date());
  306. const taskdate3 = ref(new Date());
  307. const taskdate4 = ref(new Date());
  308. const fileList = ref([]);
  309. const taskdtype = ref("");
  310. const taskdarea = ref("");
  311. const taskdfrom = ref("");
  312. const taskdcategory = ref("");
  313. const taskdisconfirm = ref("");
  314. const alltype = ref([]);
  315. const allarea = ref([]);
  316. const allfrom = ref([]);
  317. const allcategory = ref([]);
  318. const allconfirm = ref(["是", "否"]);
  319. bodyheight.value = document.body.clientHeight - 48;
  320. const onConfirm = () => {
  321. showPicker.value = false;
  322. taskinfo.value.taskTime = moment(taskdate.value).format(
  323. "YYYY-MM-DD HH:mm:ss"
  324. );
  325. };
  326. const onConfirm1 = (value) => {
  327. showPicker1.value = false;
  328. taskdtype.value = value;
  329. taskinfo.value.taskEventType =
  330. task_event_type.value.filter(
  331. (i) => i.label.toString() === (taskdtype.value ?? "").toString()
  332. )[0]?.value ?? null;
  333. };
  334. const onConfirm2 = (value) => {
  335. showPicker2.value = false;
  336. taskdarea.value = value;
  337. taskinfo.value.taskArea =
  338. sys_area.value.filter(
  339. (i) => i.label.toString() === (taskdarea.value ?? "").toString()
  340. )[0]?.value ?? null;
  341. };
  342. const onConfirm3 = (value) => {
  343. showPicker3.value = false;
  344. taskdfrom.value = value;
  345. taskinfo.value.taskType =
  346. task_type.value.filter(
  347. (i) => i.label.toString() === (taskdfrom.value ?? "").toString()
  348. )[0]?.value ?? null;
  349. };
  350. const onConfirm4 = () => {
  351. showPicker4.value = false;
  352. taskinfo.value.taskReqCompleteTime = moment(taskdate1.value==undefined?0: taskdate1.value).format(
  353. "YYYY-MM-DD HH:mm:ss"
  354. );
  355. };
  356. const onConfirm5 = (value) => {
  357. showPicker5.value = false;
  358. taskdcategory.value = value;
  359. taskinfo.value.taskEventCategory =
  360. task_event_category.value.filter(
  361. (i) => i.label.toString() === (taskdcategory.value ?? "").toString()
  362. )[0]?.value ?? null;
  363. };
  364. const onConfirm6 = (value) => {
  365. showPicker6.value = false;
  366. taskdisconfirm.value = value;
  367. taskinfo.value.remark = value === "是" ? "1" : "0";
  368. };
  369. const searchaddr = () => {
  370. if (taskinfo.value.taskAddr) {
  371. mapSelect.value.searchaddr(taskinfo.value.taskAddr);
  372. } else {
  373. Toast("请输入地址");
  374. }
  375. };
  376. const alldept = ref([]);
  377. listDept().then((response) => {
  378. alldept.value = cloneDeep(response.data);
  379. });
  380. const allusers = ref([]);
  381. listUser({ pageSize: 1000 }).then((res) => {
  382. allusers.value = res.rows;
  383. });
  384. const taskinfo = ref({
  385. taskName: null,
  386. taskContent: null,
  387. taskAddr: null,
  388. taskLocation: null,
  389. taskCode: null,
  390. taskType: null,
  391. taskEventType: null,
  392. taskEventCategory: null,
  393. taskFromRemark: null,
  394. taskAddrRoad: null,
  395. taskOtherId: null,
  396. taskTime: null,
  397. taskArea: "1",
  398. taskReqCompleteTime: "",
  399. status: 1,
  400. taskId: null,
  401. remark: "",
  402. taskCreater: null,
  403. taskReporter: null,
  404. taskPics: null,
  405. taskVideos: null,
  406. taskComplainConnect: null,
  407. taskDeptRange: "",
  408. taskFacilitieCode: "",
  409. remark: "",
  410. });
  411. listTask({ taskCode: moment().year() + "" }).then((res) => {
  412. taskinfo.value.taskCode =
  413. moment().format("yyyyMMDD") + (Array(4).join(0) + (res.total + 1)).slice(-4);
  414. });
  415. const mapSelect = ref(null);
  416. const formlocation = ref({ addr: "", locations: "" });
  417. watch(
  418. () => formlocation.value.addr,
  419. () => {
  420. taskinfo.value.taskAddr = formlocation.value.addr;
  421. }
  422. );
  423. watch(
  424. () => formlocation.value.locations,
  425. () => {
  426. taskinfo.value.taskLocation = formlocation.value.locations;
  427. if (formlocation.value.locations != "") {
  428. mapSelect.value.getlocationaddr(formlocation.value.locations, (data) => {
  429. var qu = data.regeocode.addressComponent.district;
  430. if (qu) {
  431. for (var i in sys_area.value) {
  432. if (sys_area.value[i].label == qu) {
  433. taskinfo.value.taskArea = sys_area.value[i].value;
  434. taskdarea.value = sys_area.value[i].label;
  435. }
  436. }
  437. }
  438. });
  439. }
  440. }
  441. );
  442. watch(
  443. () => fileList.value,
  444. () => {
  445. taskinfo.value.taskPics = fileList.value;
  446. }
  447. );
  448. watch(
  449. () => task_event_type.value,
  450. () => {
  451. alltype.value = task_event_type.value.map((i) => i.label);
  452. }
  453. );
  454. watch(
  455. () => sys_area.value,
  456. () => {
  457. allarea.value = sys_area.value.map((i) => i.label);
  458. }
  459. );
  460. watch(
  461. () => task_type.value,
  462. () => {
  463. allfrom.value = task_type.value.map((i) => i.label);
  464. }
  465. );
  466. watch(
  467. () => task_event_category.value,
  468. () => {
  469. allcategory.value = task_event_category.value.map((i) => i.label);
  470. }
  471. );
  472. watch(()=>taskinfo.value.taskType,()=>{
  473. if(task_type.value && task_type.value.length>0){
  474. for (const index in task_type.value) {
  475. var typec = task_type.value[index];
  476. if((typec.value+"") === (taskinfo.value.taskType+"")){
  477. taskinfo.value.taskTime = moment().add(typec.remark,'hours').format('YYYY-MM-DD HH:mm:ss')
  478. }
  479. }
  480. }
  481. })
  482. const store = useStore();
  483. const getters = computed(() => store.getters);
  484. taskinfo.value.taskReporter = getters.value.userId.toString();
  485. function setdatakey(dept) {
  486. if (dept.children) {
  487. dept.children = dept.children.map((i) => {
  488. return setdatakey(i);
  489. });
  490. }
  491. dept["value"] = dept.id;
  492. return dept;
  493. }
  494. const treedept = ref([
  495. {
  496. value: "1",
  497. label: "ss",
  498. },
  499. {
  500. value: "2",
  501. label: "ss1",
  502. },
  503. ]);
  504. deptTreeselect().then((res) => {
  505. treedept.value = [setdatakey(res.data[0])];
  506. });
  507. const onSubmit = async () => {
  508. if (
  509. taskinfo.taskName === null ||
  510. taskinfo.taskName === "" ||
  511. taskinfo.taskCode === null ||
  512. taskinfo.taskCode === ""
  513. ) {
  514. Toast.fail("请填写完整");
  515. return;
  516. }
  517. await addTask(taskinfo.value);
  518. Toast.success("添加成功");
  519. router.back();
  520. };
  521. const onClickLeft = () => {
  522. router.back();
  523. };
  524. </script>
  525. <style lang="scss">
  526. body {
  527. position: fixed;
  528. width: 100%;
  529. top: -1px;
  530. }
  531. .listcontent {
  532. overflow-y: auto;
  533. padding: 10px;
  534. }
  535. </style>