detail.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. <template>
  2. <div class="repair-detail-box">
  3. <div :class="[
  4. 'repair-content',
  5. detailStatus === 'unAcceptance' ? 'fixed-page-content' : 'page-content',
  6. ]">
  7. <div class="white-box page-1">
  8. <div class="cell-item">
  9. <p class="label">当前企业</p>
  10. <p class="tit">{{ detail.companyName }}</p>
  11. </div>
  12. <!-- <div class="cell-item">
  13. <p class="label">您是想</p>
  14. <div class="tit">{{ detail.type === "1" ? "报事" : "咨询" }}</div>
  15. </div> -->
  16. <div class="cell-item">
  17. <p class="label">快捷选择</p>
  18. <div class="tit">{{ detail.serviceType }}</div>
  19. </div>
  20. <div class="block-cell-item">
  21. <p class="label">工单描述</p>
  22. <div class="tit">
  23. <div class="textarea">
  24. {{ !detail.description ? "暂无" : detail.description }}
  25. </div>
  26. </div>
  27. </div>
  28. </div>
  29. <div class="white-box page-2">
  30. <!-- <div class="cell-item">
  31. <p class="label">位置</p>
  32. <div class="tit">{{ detail.position === "1" ? "室内" : "公区" }}</div>
  33. </div> -->
  34. <div class="block-cell-item">
  35. <p class="label">补充说明</p>
  36. <div class="tit">
  37. <!-- <ul class="annex-list-box">-->
  38. <!-- <li class="annex-item" v-for="(item, index) in explainAnnexList" :key="index">-->
  39. <!--&lt;!&ndash; {{ item }}&ndash;&gt;-->
  40. <!-- <img :src="item" alt="" />-->
  41. <!-- </li>-->
  42. <van-uploader :max-count="6" :file-list="explainAnnexList" :show-upload="false" />
  43. <!-- </ul>-->
  44. </div>
  45. </div>
  46. <div class="cell-item flex-item">
  47. <p class="label">联系方式</p>
  48. <p class="tit tel-box">
  49. <span>{{ detail.contact }}</span>
  50. <!-- {{ detail.phone }} -->
  51. <TelNum :num="detail.contact" :showTel="false" v-if="detail.contact && detail.contact.length > 0" />
  52. </p>
  53. </div>
  54. <div class="cell-item flex-item">
  55. <p class="label">报事人</p>
  56. <p class="tit tel-box">
  57. <span>{{ detail.reporter }}</span>
  58. <!-- {{ detail.phone }} -->
  59. <!-- <TelNum :num="detail.phone" :showTel="false" /> -->
  60. </p>
  61. </div>
  62. <div class="cell-item">
  63. <p class="label">报事时间</p>
  64. <p class="tit">{{ detail.createdAt }}</p>
  65. </div>
  66. </div>
  67. <div class="white-box page-3 form-part" style="padding-bottom: 120px">
  68. <div class="custom-item-tit">
  69. <div class="tit">
  70. <div style="padding-left: 15rpx;">
  71. 处理情况
  72. </div>
  73. </div>
  74. </div>
  75. <div class="block-cell-item">
  76. <div class="label" style=" display: flex;
  77. justify-content: space-between;
  78. align-items: center;">
  79. <p>处理进展
  80. <!-- {{stepActive}}-->
  81. </p>
  82. <van-button type="warning" size="mini" @click="orderOut()" v-if="detail.status==1">处理退回</van-button>
  83. </div>
  84. <div>
  85. <van-steps :active="stepActive" :active-color="'#6600FF'" :steps="processSteps">
  86. </van-steps>
  87. </div>
  88. </div>
  89. <div class="cell-item">
  90. <p class="label">派单人</p>
  91. <p class="tit">{{ detail.dispatchUserName }}</p>
  92. </div>
  93. <div class="cell-item">
  94. <p class="label">派单时间</p>
  95. <p class="tit">{{ detail.dispatchTime }}</p>
  96. </div>
  97. <div class="block-cell-item">
  98. <p class="label">派单备注</p>
  99. <div class="tit">
  100. <div class="textarea">
  101. {{ detail.dispatchRemark == "null" || !detail.dispatchRemark || detail.dispatchRemark == "undefind" ? "暂无" :
  102. detail.dispatchRemark }}
  103. </div>
  104. </div>
  105. </div>
  106. <div class="block-cell-item">
  107. <p class="label">
  108. 处理后拍照<span class="tips">(支持图片上传限20M内,最多6张)</span>
  109. </p>
  110. <div class="tit">
  111. <van-uploader @delete="deleteRYXXZP" :file-list="handleUrlList" :max-count="6" @after-read="afterRead"
  112. :show-upload="true">
  113. </van-uploader>
  114. </div>
  115. </div>
  116. <div class="custom-item-tit">
  117. <div class="tit">
  118. <div style="margin-left: 15rpx;">
  119. 处理说明
  120. </div>
  121. </div>
  122. </div>
  123. <div class="custom-textarea-box">
  124. <uni-easyinput :disabled="detail.status !== '1' && detail.status != 2 && detail.status != 5&&detail.status != '3'&& detail.status != '4'" type="textarea"
  125. class="bgcF9F9F9 height218rpx" v-model="params.handleExplain" autoHeight placeholder="请填写" show-word-limit>
  126. </uni-easyinput>
  127. </div>
  128. <div class="cell-item">
  129. <p class="label">结案人</p>
  130. <p class="tit">{{ handleUserId2 }}</p>
  131. </div>
  132. <div class="cell-item">
  133. <p class="label">结案时间</p>
  134. <p class="tit">{{ detail.handleTime ? detail.handleTime : "" }}</p>
  135. </div>
  136. </div>
  137. </div>
  138. <div class="repair-bottom bottom-button" v-if="detail.status == '1' || detail.status == '2'|| detail.status == '3'|| detail.status == '4' || detail.status == '5'">
  139. <button class="btn" @click="onConfirm">{{ detail.status == 2 ||detail.status == 3 ? '编辑' : '提交' }}</button>
  140. </div>
  141. </div>
  142. </template>
  143. <script>
  144. import TelNum from "../../subPackages/components/tel-number";
  145. import vanRate from "../../../wxcomponents/weapp/dist/rate";
  146. import {
  147. editRepair,
  148. getHandleInfoById,
  149. getByCodes,
  150. getUserLocalStorageInfo,
  151. handleReportBack
  152. } from "@/js_sdk/http";
  153. import { editReportInfo } from "../../../js_sdk/http";
  154. // import Base from '@/pages/base/base'
  155. // import { editRepair } from '@/service/api_repair'
  156. // import { Toast } from 'vant'
  157. // import auth from '@/service/auth'
  158. // import axios from 'axios'
  159. export default {
  160. components: {
  161. TelNum,
  162. vanRate,
  163. },
  164. data() {
  165. return {
  166. handleUserId2: "",
  167. userId2: "",
  168. dispatchUserId2: "",
  169. dic_key: ["QUICK_SELECTION", "REPAIR_STATUS"],
  170. dic_SelectList: {},
  171. detailId: "", // 详情id
  172. handleUrlList: [],
  173. fileUrls: [],
  174. handleUrls: [],
  175. detailStatus: "1", // 1 待派单 2已派单
  176. explainAnnexList: [], // 说明附件 type image、图片 video、视频
  177. processedAnnexList: [], // 附件 type image、图片 video、视频
  178. stepActive: 0, // 当前处理到哪一步
  179. processSteps: [
  180. {
  181. id: 1,
  182. status: 1,
  183. text: "上报",
  184. },
  185. {
  186. id: 2,
  187. status: 1,
  188. text: "已受理",
  189. },
  190. {
  191. id: 3,
  192. status: 1,
  193. text: "已处理",
  194. },
  195. {
  196. id: 4,
  197. status: 0,
  198. text: "已确认",
  199. },
  200. ], // 处理流程
  201. evaluateVal: 0, // 评分
  202. id: "",
  203. detail: {},
  204. fileUrlList: [],
  205. params: {
  206. id: "",
  207. handleUrl: "",
  208. handleTime: "",
  209. status: "processed",
  210. },
  211. };
  212. },
  213. onLoad(option) {
  214. this.id = option.id;
  215. this.getByCodes();
  216. },
  217. methods: {
  218. deleteRYXXZP(e) {
  219. console.log(e.detail.file.id)
  220. let index = this.handleUrlList.findIndex((row) => {
  221. return row.id == e.detail.file.id;
  222. });
  223. console.log('deleteRYXXZP', index)
  224. let handleUrlList = JSON.parse(JSON.stringify(this.handleUrlList));
  225. handleUrlList.splice(index, 1);
  226. this.handleUrlList = handleUrlList
  227. },
  228. async orderOut() {
  229. let _this = this
  230. console.log(_this.detail.reportRepairId)
  231. wx.showModal({
  232. title: '提示',
  233. confirmText: '退回',
  234. content: '是否退回到派单阶段?',
  235. success: async function (e) {
  236. if (e.confirm) {
  237. let outData = {
  238. id: _this.id,
  239. reportRepairId: _this.detail.reportRepairId,
  240. userId: getUserLocalStorageInfo().user.id
  241. }
  242. let data = await handleReportBack(outData)
  243. if (data.code == 200) {
  244. _this.$showToast('退回成功');
  245. uni.navigateBack({});
  246. }
  247. // 用户点击了确定 可以调用删除方法了
  248. } else if (e.cancel) {
  249. console.log('用户点击取消')
  250. }
  251. }
  252. })
  253. },
  254. async getByCodes() {
  255. let data = await getByCodes(JSON.stringify(this.dic_key));
  256. this.dic_SelectList = this.$common.handleDicList(data);
  257. this.getDetailById();
  258. },
  259. onSelect(val) {
  260. this.value = val.text;
  261. this.params.handleUserId = val.value + "-" + val.text;
  262. this.showPicker = false;
  263. },
  264. onConfirm(value) {
  265. let that = this;
  266. uni.showModal({
  267. title: '提示',
  268. content: '是否确认提交',
  269. success: function (res) {
  270. if (res.confirm) {
  271. if (!that.params.handleExplain || that.params.handleExplain.length == 0) {
  272. that.$showToast("请填写处理说明");
  273. return;
  274. }
  275. that.params.id = that.id;
  276. // handleUrlList
  277. that.params.handleTime = that.detail.handleTime;
  278. // this.params.handleUrlList = this.params.handleUrlList.join(",");
  279. let handleUrlList = [];
  280. if (that.handleUrlList && that.handleUrlList.length > 0) {
  281. handleUrlList = that.handleUrlList.map((e) => {
  282. return e.id;
  283. });
  284. }
  285. // console.log(this.handleUrlList);
  286. // console.log(handleUrlList.join(","))
  287. // return;
  288. // that.params.handleExplain = that.detail.handleExplain;
  289. that.params.updatedBy = getUserLocalStorageInfo().user.id;
  290. that.params.handleUrl = handleUrlList.join(",");
  291. that.params.userId = getUserLocalStorageInfo().user.id;
  292. if (that.detail.status == 2 || that.detail.status == 3) {
  293. let params = { ...that.params }
  294. delete params.status;
  295. editReportInfo(params).then((res) => {
  296. that.$showToast("结案成功");
  297. uni.switchTab({
  298. url: "/pages/index/index",
  299. });
  300. // this.$router.push({ path: "/repairprocessing-app" });
  301. });
  302. } else {
  303. let params = { ...that.params }
  304. delete params.status;
  305. editRepair(params).then((res) => {
  306. that.$showToast("结案成功");
  307. uni.switchTab({
  308. url: "/pages/index/index",
  309. });
  310. // this.$router.push({ path: "/repairprocessing-app" });
  311. });
  312. }
  313. } else if (res.cancel) {
  314. console.log('用户点击取消');
  315. }
  316. }
  317. });
  318. },
  319. getDetailById() {
  320. const _this = this;
  321. getHandleInfoById(_this.id).then((res) => {
  322. console.log(res.data);
  323. if (res.data) {
  324. let det = _this.getItemJson(res.data);
  325. this.detail = det;
  326. this.params.handleExplain = !det.handleExplain == 'null' || det.handleExplain == 'null' ? '' : det.handleExplain
  327. // if (det.userId != null && det.userId !== "") {
  328. // const test = det.userId.split("-");
  329. // this.detail.phone = test[2];
  330. // this.userId2 = test[1] + "-" + test[2];
  331. // }
  332. if (det.dispatchUserId != null && det.dispatchUserId !== "") {
  333. const test = det.dispatchUserId.split("-");
  334. console.log(test);
  335. this.dispatchUserId2 = test[1] + "-" + test[2];
  336. }
  337. if (det.handleUserId != null && det.handleUserId !== "") {
  338. // const test = det.handleUserId.split("-");
  339. // console.log(test);
  340. this.handleUserId2 = det.handleUserName;
  341. }
  342. console.log('det.handleUrlList', det.handleUrlList)
  343. this.handleUrlList = det.handleUrlList;
  344. if (det.fileUrl && det.fileUrl.length > 0) {
  345. this.explainAnnexList = det.fileUrl.split(',').map(e => {
  346. return {
  347. url: this.$constant.BASE_URI + "/wx/fileController/download/" + e,
  348. id: e,
  349. isImage: true,
  350. deletable: false,
  351. }
  352. });
  353. console.log("asodmqowndonq", this.explainAnnexList);
  354. }
  355. // this.processedAnnexList = det.handleUrlList;
  356. this.detailStatus = det.status;
  357. this.params.remark = det.remark;
  358. // this.detail.status = this.detail.status ==5 ? 2 : this.detail.status
  359. }
  360. });
  361. },
  362. getItemJson: function (item) {
  363. // const fileUrls = item.fileUrl ? item.fileUrl.split(",") : [];
  364. //
  365. // const fileUrlViews = [];
  366. // if (fileUrls !== null && fileUrls.length > 0) {
  367. // fileUrls.forEach((item) => {
  368. // item =
  369. // this.$constant.BASE_URI + "/wx/fileController/download/" + item;
  370. // fileUrlViews.push(item);
  371. // });
  372. // }
  373. // item.fileUrlViewList = fileUrlViews;
  374. if (!item.handleTime) {
  375. item.handleTime = this.$common.transServDate(new Date());
  376. }
  377. const handleUrl = item.handleUrl ? item.handleUrl.split(",") : [];
  378. const handleUrlViews = [];
  379. if (handleUrl !== null && handleUrl.length > 0) {
  380. handleUrl.forEach((item) => {
  381. handleUrlViews.push({
  382. url:
  383. this.$constant.BASE_URI + "/wx/fileController/download/" + item,
  384. isImage: true,
  385. id: item
  386. });
  387. });
  388. }
  389. item.handleUrlList = handleUrlViews;
  390. console.log(item.handleUrlList);
  391. item.serviceType =
  392. this.dic_SelectList.QUICK_SELECTION[item.serviceType - 1].label;
  393. switch (item.status) {
  394. // console.log(status)
  395. case "0":
  396. this.stepActive = 0;
  397. break;
  398. case "1":
  399. this.stepActive = 1;
  400. break;
  401. case "2":
  402. this.stepActive = 2;
  403. break;
  404. case "3":
  405. this.stepActive = 3;
  406. break;
  407. case "4":
  408. this.stepActive = 0;
  409. break;
  410. case "5":
  411. this.stepActive = 5;
  412. break;
  413. }
  414. return item;
  415. },
  416. afterRead(event) {
  417. let that = this;
  418. const { file } = event.detail;
  419. try {
  420. uni.uploadFile({
  421. url: that.$constant.BASE_URI + "/wx/fileController/upload",
  422. filePath: file.url,
  423. name: "file",
  424. formData: { user: "test" },
  425. success(res) {
  426. // 上传完成需要更新 fileList
  427. let { data } = JSON.parse(res.data);
  428. console.log(data[0]);
  429. that.handleUrlList.push({
  430. id: data[0],
  431. url:
  432. that.$constant.BASE_URI + "/FileController/download/" + data[0],
  433. isImage: true,
  434. });
  435. that.handleUrlList = [...that.handleUrlList];
  436. that.$forceUpdate();
  437. console.log(that.fileUrlList);
  438. },
  439. fail(res) { },
  440. });
  441. } catch (error) { }
  442. },
  443. beforeDelete(file, detail) {
  444. // this.handleImagUrlList = []
  445. const vm = this;
  446. // name.index代表图片的索引
  447. vm.handleUrls.splice(detail.index, 1);
  448. return (file, name) => {
  449. const fileIndex = name.index;
  450. vm.handleUrls[detail.index].splice(fileIndex, 1);
  451. };
  452. },
  453. /**
  454. * 上传图片
  455. */
  456. uploadImg(file) {
  457. const _this = this;
  458. const formParam = new FormData(); // 创建form对象
  459. formParam.append("file", file.file); // 通过append向form对象添加数据
  460. console.log(formParam.get("file")); // FormData私有类对象,访问不到,可以通过get判断值是否传进去
  461. // upload(formParam).then((res) => {
  462. //
  463. // })
  464. const config = {
  465. headers: {
  466. "Content-Type": "multipart/form-data",
  467. "MVVM-Key": String(new Date().getTime()),
  468. xx: "anything",
  469. }, // 这里是重点,需要和后台沟通好请求头,Content-Type不一定是这个值
  470. }; // 添加请求头
  471. return new Promise((resolve, reject) => {
  472. axios
  473. .post(
  474. "/smartParkH5Server/wx/fileController/upload",
  475. formParam,
  476. config
  477. )
  478. .then((response) => {
  479. let files = response.data.data.substring(
  480. 1,
  481. response.data.data.length
  482. );
  483. files = files.substring(0, files.length - 1);
  484. _this.handleUrls.push(_this.$common.castEval(files));
  485. })
  486. .catch((err, x) => {
  487. reject(err, x);
  488. });
  489. });
  490. },
  491. },
  492. };
  493. </script>
  494. <style lang="scss">
  495. .infoUpload {
  496. .van-uploader__upload--disabled {
  497. display: none;
  498. }
  499. }
  500. .bottom-button {
  501. position: fixed;
  502. bottom: 0;
  503. left: 0;
  504. width: 100%;
  505. z-index: 100;
  506. height: 160rpx;
  507. padding: 35rpx 30rpx;
  508. background-color: #fff;
  509. display: flex;
  510. align-items: center;
  511. justify-content: center;
  512. box-sizing: border-box;
  513. .btn {
  514. height: 100%;
  515. line-height: 80rpx;
  516. width: 100%;
  517. color: #fff;
  518. background-color: #6600ff;
  519. font-size: 34rpx;
  520. border-radius: 10rpx;
  521. }
  522. }
  523. .repair-detail-box {
  524. .page-4 {
  525. .evaluate-box {
  526. padding: 20rpx 30rpx;
  527. background: $page-color-base;
  528. border: 1rpx solid #ebedf0;
  529. border-radius: 100rpx;
  530. display: flex;
  531. align-items: center;
  532. justify-content: space-between;
  533. box-sizing: border-box;
  534. }
  535. }
  536. width: 100%;
  537. height: 100%;
  538. .page-1 {
  539. .textarea {
  540. padding: 20rpx;
  541. border-radius: 10rpx;
  542. background: $page-color-base;
  543. box-sizing: border-box;
  544. }
  545. }
  546. .page-3 {
  547. padding-bottom: 100rpx;
  548. .input-item {
  549. padding: 0;
  550. }
  551. .custom-item-tit {
  552. height: 13.333vw;
  553. font-size: 4.267vw;
  554. color: #333;
  555. padding: 2.667vw 0;
  556. position: relative;
  557. display: -webkit-box;
  558. display: -ms-flexbox;
  559. display: flex;
  560. -webkit-box-pack: justify;
  561. -ms-flex-pack: justify;
  562. justify-content: space-between;
  563. -webkit-box-align: center;
  564. -ms-flex-align: center;
  565. align-items: center;
  566. -webkit-box-sizing: border-box;
  567. box-sizing: border-box;
  568. .tit {
  569. &::after {
  570. content: "";
  571. width: 0.8vw;
  572. height: 90%;
  573. background-color: #976dec;
  574. border-radius: 0.4vw;
  575. position: absolute;
  576. left: 0;
  577. top: 50%;
  578. -webkit-transform: translateY(-50%);
  579. transform: translateY(-50%);
  580. }
  581. }
  582. }
  583. .tit {
  584. // padding-left: 2.667vw;
  585. position: relative;
  586. }
  587. }
  588. .page-4 {
  589. .custom-item-tit {
  590. height: 13.333vw;
  591. font-size: 4.267vw;
  592. color: #333;
  593. padding: 2.667vw 0;
  594. position: relative;
  595. display: -webkit-box;
  596. display: -ms-flexbox;
  597. display: flex;
  598. -webkit-box-pack: justify;
  599. -ms-flex-pack: justify;
  600. justify-content: space-between;
  601. -webkit-box-align: center;
  602. -ms-flex-align: center;
  603. align-items: center;
  604. -webkit-box-sizing: border-box;
  605. box-sizing: border-box;
  606. .tit {
  607. &::after {
  608. content: "";
  609. width: 0.8vw;
  610. height: 90%;
  611. background-color: #976dec;
  612. border-radius: 0.4vw;
  613. position: absolute;
  614. left: 0;
  615. top: 50%;
  616. -webkit-transform: translateY(-50%);
  617. transform: translateY(-50%);
  618. }
  619. }
  620. }
  621. .tit {
  622. padding-left: 2.667vw;
  623. position: relative;
  624. }
  625. s .evaluate-box {
  626. padding: 20px 30px;
  627. background: $page-color-base;
  628. border: 1px solid #ebedf0;
  629. border-radius: 100px;
  630. display: flex;
  631. align-items: center;
  632. justify-content: space-between;
  633. box-sizing: border-box;
  634. }
  635. }
  636. .annex-list-box {
  637. display: flex;
  638. flex-wrap: wrap;
  639. justify-content: space-between;
  640. &::after {
  641. display: block;
  642. content: "";
  643. width: 30%;
  644. height: 0px;
  645. }
  646. .annex-item {
  647. width: 30%;
  648. height: 240rpx;
  649. border: 1px solid $text4;
  650. margin-bottom: 20px;
  651. position: relative;
  652. overflow: hidden;
  653. >img {
  654. width: 240rpx;
  655. height: 240rpx;
  656. position: absolute;
  657. top: 0;
  658. left: 0;
  659. right: 0;
  660. bottom: 0;
  661. margin: auto;
  662. display: block;
  663. }
  664. video {
  665. width: 100%;
  666. height: 100%;
  667. }
  668. }
  669. }
  670. .tel-box {
  671. display: flex;
  672. align-items: center;
  673. /deep/ .custom-tel-component {
  674. margin-left: 20px;
  675. }
  676. }
  677. }
  678. </style>
  679. <style lang="scss">
  680. .image-repairDispatch-box {
  681. .van-image-preview__close-icon {
  682. color: #fff;
  683. font-size: 64px;
  684. }
  685. }
  686. </style>s