detail.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. <template>
  2. <div class="page_box">
  3. <van-form ref="resumption_form">
  4. <div class="panel">
  5. <NavBar :go="{ type: 'push', path: '/resumption' }" />
  6. <van-panel :title="resumptionData.taskName">
  7. <div class="tts">
  8. <van-row>
  9. <van-col span="12">
  10. <div class="total_panel">
  11. <div class="title">履职项</div>
  12. <div class="content">
  13. <span class="con_num ok">已查 {{ resumptionData.yesPointNums }}</span>
  14. <span class="con_num no">未查 {{ resumptionData.noPointNums }}</span>
  15. </div>
  16. </div>
  17. </van-col>
  18. <van-col span="12">
  19. <div class="total_panel" @click="showDetail(1)">
  20. <div class="title">NFC</div>
  21. <div class="content">
  22. <span class="con_num ok">已扫 {{ yesList.length }}</span>
  23. <span class="con_num no">未扫 {{ noList.length}}</span>
  24. </div>
  25. </div>
  26. </van-col>
  27. </van-row>
  28. </div>
  29. </van-panel>
  30. </div>
  31. <div class="progress">
  32. <van-progress
  33. :percentage="
  34. (
  35. ((resumptionData.yesPointNums + yesList.length) /
  36. (resumptionData.yesPointNums +
  37. resumptionData.noPointNums +
  38. yesList.length +
  39. noList.length)) *
  40. 100
  41. ).toFixed(2)
  42. "
  43. />
  44. </div>
  45. <!-- 检查区域 -->
  46. <div class="card">
  47. <van-panel title="巡检区域">
  48. <div style="padding: 5px">
  49. <van-row>
  50. <van-col span="8" v-for="(va, i) in areas" :key="va.areaId">
  51. <div :class="{ active: i === 0 }" class="check-area" @click="clickArea(va, i)">
  52. <div class="ysj">
  53. <van-icon name="checked" :color="areaColor.complete" v-if="va.areaStatus === '1'" />
  54. <van-icon name="warning" :color="areaColor.loading" v-if="va.areaStatus === '2'" />
  55. <van-icon name="warning" :color="areaColor.noOpen" v-if="va.areaStatus === '0'" />
  56. </div>
  57. {{ va.areaName }}
  58. </div>
  59. </van-col>
  60. </van-row>
  61. </div>
  62. </van-panel>
  63. </div>
  64. <van-action-sheet v-model="total_show">
  65. <div class="content">
  66. <van-tabs>
  67. <van-tab title="未扫描" name="b">
  68. <van-list finished-text="没有更多了" @load="onLoad">
  69. <van-cell v-for="item in sheetNoList" :key="item.nfcCode" :label="areasMap[item.areaId] " :title="item.nfcName">
  70. <!-- <img :src="require('../../../assets/svg/NFC.svg')" class="nfc-icon"/>-->
  71. <span >{{item.pointScan === 1?'必扫':'可选'}}</span>
  72. </van-cell>
  73. </van-list>
  74. </van-tab>
  75. <van-tab title="已扫描" name="a">
  76. <van-list finished-text="没有更多了" @load="onLoad">
  77. <van-cell v-for="item in sheetYesList" :key="item.nfcCode" :label="areasMap[item.areaId]" :title="item.nfcName">
  78. <span style="color: green">已完成</span>
  79. </van-cell>
  80. </van-list>
  81. </van-tab>
  82. </van-tabs>
  83. </div>
  84. </van-action-sheet>
  85. <div class="card">
  86. <van-row>
  87. <van-col span="16">
  88. <van-cell @click="showDetail(0)">
  89. <template #title>
  90. <span>NFC</span>
  91. </template>
  92. <template #extra>
  93. <div>
  94. <span style="display: inline-block; color: #26850c">{{ areaYesList.length }}</span>
  95. <span style="display: inline-block; color: #0e0e0e">/</span>
  96. <span style="display: inline-block; color: #0e0e0e">{{ areaNoList.length + areaYesList.length}}</span>
  97. </div>
  98. <img :src="require('../../../assets/svg/NFC.svg')" class="nfc-icon" />
  99. </template>
  100. </van-cell>
  101. </van-col>
  102. <van-col span="8">
  103. <van-cell>
  104. <div class="okAll">
  105. <van-radio-group v-if="enable" v-model="selectRadio" @change="changeSwitch">
  106. <van-radio name="1" icon-size="20px">一键填充</van-radio>
  107. </van-radio-group>
  108. </div>
  109. </van-cell>
  110. </van-col>
  111. </van-row>
  112. <van-row>
  113. <van-col span="24">
  114. <van-cell v-show="currentImgNFC.length > 0" :border="false">
  115. <div
  116. v-if="v.areaId === areaId && v.img"
  117. class="nfc-img"
  118. v-for="(v, i) in nfcs"
  119. :key="v.img"
  120. @click="preViewNFC(i)"
  121. >
  122. <img :src="imgUrl(v.img)" alt="" />
  123. <span>{{ v.nfcName }}</span>
  124. <div v-if="enable" class="cancel_icon" @click="cancelImg(v)">
  125. <van-icon name="clear" />
  126. </div>
  127. </div>
  128. </van-cell>
  129. </van-col>
  130. </van-row>
  131. <van-collapse v-model="activeNames">
  132. <van-collapse-item
  133. v-show="areaId === item.areaId"
  134. v-for="item in checks"
  135. :title="item.itemName + '(' + item.points.length + ')'"
  136. :name="item.itemName"
  137. :key="item.areaId"
  138. >
  139. <div v-for="(point, index) in item.points">
  140. <van-cell>
  141. <template #title>
  142. <pre>{{ point.pointName }}</pre>
  143. </template>
  144. <template #right-icon>
  145. <van-switch
  146. style="margin-left: 10px"
  147. v-model="point.resValue"
  148. v-show="point.dataStatus === 2"
  149. v-if="enable"
  150. :active-value="1"
  151. :inactive-value="0"
  152. inactive-color="#4fc08d"
  153. active-color="#ee0a24"
  154. size="18"
  155. />
  156. <span v-else>
  157. <van-tag v-if="point.resValue === 1" type="warning">异常</van-tag>
  158. <van-tag v-else type="success">正常</van-tag>
  159. </span>
  160. <van-switch
  161. style="margin-left: 10px"
  162. v-model="point.dataStatus"
  163. v-show="point.dataStatus === 1"
  164. :active-value="2"
  165. :inactive-value="1"
  166. inactive-color="#fcfcfc"
  167. active-color="#ee0a24"
  168. size="18"
  169. @change="changeCurrentSwitch(item.areaId)"
  170. />
  171. </template>
  172. </van-cell>
  173. <van-cell-group v-show="point.resValue">
  174. <div class="upload-box">
  175. <uploader :maxCount="5" v-if="enable" v-model="point.imgs" />
  176. <van-cell v-else>
  177. <div
  178. class="nfc-img van-hairline--surround"
  179. v-for="(v, i) in point.imgs"
  180. :key="v.imgPath"
  181. @click="clickWarnImage(point.imgs, i)"
  182. >
  183. <img :src="imgUrl(v.imgPath)" alt="" />
  184. <span>{{ v.checkName }}</span>
  185. </div>
  186. </van-cell>
  187. </div>
  188. <van-field
  189. :rules="[{ required: enable, message: '请输入情况描述' },{validator, message: '输入长度200字符以内'}]"
  190. :required="enable"
  191. v-model="point.resRemark"
  192. :readonly="!enable"
  193. rows="1"
  194. name="resRemark"
  195. autosize
  196. autofocus="true"
  197. label="情况描述"
  198. type="textarea"
  199. :placeholder="enable ? '请输入情况描述' : ''"
  200. />
  201. <select-cell
  202. :required="enable"
  203. :disabled="!enable"
  204. title="整改期限"
  205. name="rectificationDeadline"
  206. v-model="point.rectificationDeadline"
  207. :data-list="dayList"
  208. />
  209. </van-cell-group>
  210. </div>
  211. </van-collapse-item>
  212. </van-collapse>
  213. </div>
  214. <div class="bottomClass" v-if="enable" v-show="showButton" >
  215. <van-row>
  216. <van-col span="8">
  217. <van-button type="primary" @click="clickNFC">扫描NFC</van-button>
  218. </van-col>
  219. <van-col span="8">
  220. <van-button type="default" @click="resumptionDataSave">保存</van-button>
  221. </van-col>
  222. <van-col span="8">
  223. <van-button type="info" @click="submitResumptionData">提交</van-button>
  224. </van-col>
  225. </van-row>
  226. </div>
  227. <!-- nfc弹窗 -->
  228. <nfc-popup v-if="enable" ref="NfcPopup" @checkNFC="checkNFC" @change="changeNfcImg"></nfc-popup>
  229. </van-form>
  230. </div>
  231. </template>
  232. <script>
  233. import { ImagePreview, Dialog } from 'vant'
  234. import NavBar from '@/components/NavBar/index.vue'
  235. import Uploader from '@/components/upload/gxuploader.vue'
  236. import SelectCell from '@/components/selectCell/index.vue'
  237. import { getDict } from '@/api/toConsult'
  238. import { saveTask, taskDetail } from '@/views/menu/resumption/api'
  239. import NfcPopup from '@/components/nfcPopup/gxmore'
  240. import { imgUrl } from '@/utils'
  241. import dayjs from 'dayjs'
  242. import { mapGetters } from 'vuex'
  243. import { ref } from 'vue'
  244. import {uploadBase64} from "@/api/public";
  245. export default {
  246. components: {
  247. SelectCell,
  248. Uploader,
  249. NavBar,
  250. NfcPopup,
  251. imgUrl,
  252. [Dialog.Component.name]: Dialog.Component
  253. },
  254. data() {
  255. return {
  256. areaColor: {
  257. // 已完成
  258. complete: '#26850c',
  259. // 未开始
  260. noOpen: '#1989fa',
  261. // 进行中
  262. loading: '#ffa500'
  263. },
  264. NFCnums: 0,
  265. yesNFCnums: 0,
  266. currentImgNFC: [],
  267. areaId: null,
  268. resumptionData: {},
  269. areas: [],
  270. areasMap: {},
  271. checks: [],
  272. nfcs: [],
  273. selectRadio: 0,
  274. total_show: false,
  275. enable: false,
  276. activeNames: [],
  277. dayList: [15, 30, 90, 180],
  278. yesList: [],
  279. noList: [],
  280. areaYesList:[],
  281. areaNoList:[],
  282. sheetYesList: [],
  283. sheetNoList: [],
  284. loading: false,
  285. finished: false,
  286. selectArea: null,
  287. showButton:true,
  288. preViewImages: {
  289. images: [],
  290. startPosition: 0
  291. },
  292. timer:null,
  293. }
  294. },
  295. computed: {
  296. ...mapGetters(['id'])
  297. },
  298. mounted() {
  299. this.getResumptionData()
  300. window.openNFCScanCallBack = this.openNFCScanCallBack;
  301. },
  302. created() {
  303. getDict('rectification_deadline').then(res => {
  304. let { data } = res
  305. this.dayList = data
  306. })
  307. },
  308. methods: {
  309. showButtoFun(vel){
  310. if( val === 1){
  311. this.showButton = false;
  312. }
  313. if(val === 2){
  314. this.showButton = true;
  315. }
  316. },
  317. //长度校验
  318. validator(val) {
  319. let len = val.length;
  320. if( len > 200) {
  321. this.$toast.fail('问题情况输入长度不能超过200');
  322. return false
  323. }else {
  324. return true
  325. }
  326. },
  327. checkNFC(){
  328. this.useNFC();
  329. this.$toast.loading({
  330. duration: 0, // 持续展示 toast
  331. position: 'top',
  332. forbidClick: true,
  333. message: '请靠近NFC标签,进行扫描!',
  334. });
  335. let second = 30;
  336. this.timer = setInterval(() => {
  337. second--;
  338. if(!second){
  339. this.$toast.clear();
  340. clearInterval(this.timer);
  341. this.$toast.fail({
  342. message: '未扫描到任何信息!',
  343. });
  344. }
  345. }, 1000);
  346. },
  347. openNFCScanCallBack(nfcStr){
  348. clearInterval(this.timer);
  349. let nfcCode = '';
  350. try{
  351. let nfc = JSON.parse(nfcStr);
  352. nfcCode = nfc.content;
  353. }catch (e) {
  354. nfcCode = nfcStr.content;
  355. }
  356. this.checkNfcFilter(nfcCode);
  357. },
  358. checkNfcFilter(nfcCode){
  359. let areaId = null;
  360. let checkOk = false;
  361. this.nfcs.forEach(v => {
  362. if(v.nfcCode === nfcCode){
  363. areaId = v.areaId;
  364. this.switchArea(areaId);
  365. if(v.status === 1){
  366. this.$toast.fail('NFC点位:' + v.nfcName + '已扫描,请勿重复扫描!');
  367. throw new Error('NFC点位:' + v.nfcName + '已扫描,请勿重复扫描!');
  368. }
  369. v.status = 1
  370. v.scanMethod = 2
  371. v.submitTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
  372. v.submitBy = this.id
  373. this.$toast.success('NFC点位:' + v.nfcName + '扫描成功!');
  374. checkOk = true;
  375. }
  376. });
  377. this.updateNFC(1,nfcCode);
  378. if(!checkOk){
  379. this.$toast.fail(nfcCode + ",不在本次履职范围内!");
  380. }
  381. this.validateArea(areaId)
  382. },
  383. switchArea(areaId){
  384. this.areas.forEach((area, i) => {
  385. if (areaId === area.areaId) {
  386. this.activeArea(area, i)
  387. }
  388. })
  389. },
  390. useNFC(){
  391. let system = this.isAndroidOrIos();
  392. const parms = {
  393. "iOS_SessionType":"0"
  394. };
  395. if(system === 1){
  396. //android
  397. // 判断当前环境是是否存在 js桥 'sap'
  398. const hasSap = window.hasOwnProperty('sap');
  399. if (hasSap) {
  400. // 判断是否存在方法 ?preview
  401. const fun = sap.hasOwnProperty('openNFCScan');
  402. if (fun) {
  403. sap.openNFCScan(JSON.stringify(parms));
  404. }
  405. }
  406. }
  407. if(system === 2){
  408. //ios
  409. // 判断 ios是否存在方法 preview
  410. const fun = window.webkit.messageHandlers.hasOwnProperty('openNFCScan')
  411. if (fun) {
  412. window.webkit.messageHandlers.openNFCScan.postMessage(JSON.stringify(parms))
  413. }
  414. }
  415. },
  416. isAndroidOrIos(){
  417. const urls = navigator.userAgent;
  418. let isAndroid = urls.indexOf('Android') > -1 || urls.indexOf('Linux') > -1;
  419. let isIos = !!urls.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
  420. if(isAndroid){
  421. return 1;
  422. }
  423. if(isIos){
  424. return 2;
  425. }
  426. },
  427. preViewNFC(i) {
  428. this.preViewImages.images = this.currentImgNFC.map(v => imgUrl(v.img))
  429. this.preViewImages.startPosition = i
  430. ImagePreview(this.preViewImages)
  431. },
  432. clickWarnImage(arr, i) {
  433. this.preViewImages.images = arr.map(v => imgUrl(v.imgPath))
  434. this.preViewImages.startPosition = i
  435. ImagePreview(this.preViewImages)
  436. },
  437. getResumptionData() {
  438. let data = {
  439. taskId: this.$route.query.id,
  440. taskDate: this.$route.query.taskDate
  441. }
  442. taskDetail(data).then(res => {
  443. let { taskId, taskName, yesPointNums, noPointNums, yesNFCNums, noNFCNums, status } = res.data
  444. this.resumptionData = {
  445. taskId,
  446. taskName,
  447. yesPointNums,
  448. noPointNums,
  449. yesNFCNums,
  450. noNFCNums,
  451. status
  452. }
  453. this.enable = this.resumptionData.status === 1 || this.resumptionData.status === 2
  454. this.checks = res.data.checks
  455. this.nfcs = res.data.nfcs
  456. this.areas = res.data.areas
  457. let obj = {};
  458. res.data.areas.forEach(function(v,i){
  459. obj[v.areaId] = v.areaName;
  460. });
  461. this.areasMap = obj;
  462. this.activeArea(this.areas[0], 0)
  463. if (!this.enable) {
  464. this.openCollapseItems()
  465. }
  466. this.updateNFC(0);
  467. })
  468. },
  469. openCollapseItems() {
  470. let len = this.checks.length
  471. for (let i = 0; i < len; i++) {
  472. let title = this.checks[i].itemName
  473. this.activeNames.push(title)
  474. }
  475. },
  476. changeSwitch() {
  477. let num = 0
  478. for (let i = 0; i < this.checks.length; i++) {
  479. for (let j = 0; j < this.checks[i].points.length; j++) {
  480. this.checks[i].points[j].dataStatus = 2
  481. num++
  482. }
  483. }
  484. this.resumptionData.yesPointNums = num
  485. this.resumptionData.noPointNums = 0
  486. this.areas.forEach((item, index) => {
  487. this.validateArea(item.areaId)
  488. })
  489. this.openCollapseItems()
  490. },
  491. changeCurrentSwitch(areaId) {
  492. this.resumptionData.yesPointNums = this.resumptionData.yesPointNums + 1
  493. this.resumptionData.noPointNums = this.resumptionData.noPointNums - 1
  494. this.validateArea(areaId)
  495. },
  496. validateArea(areaId) {
  497. let total = 0
  498. let yes = 0
  499. this.checks.forEach(item => {
  500. let pointList = item.points
  501. pointList.forEach(point => {
  502. if (item.areaId === areaId) {
  503. total++
  504. if (point.dataStatus === 2) {
  505. yes++
  506. }
  507. }
  508. })
  509. })
  510. let areaStatus = '0'
  511. if (total === yes && this.areaNoList.length === 0) {
  512. areaStatus = '1'
  513. } else if (yes === 0 && this.areaNoList.length === this.NFCnums) {
  514. areaStatus = '0'
  515. } else {
  516. areaStatus = '2'
  517. }
  518. this.areas.forEach((item, index) => {
  519. if (item.areaId === areaId) {
  520. this.areas[index].areaStatus = areaStatus
  521. }
  522. })
  523. },
  524. clickNFC() {
  525. let arr = this.nfcs.filter(item => {
  526. return item.areaId === this.areaId && item.status === 0
  527. })
  528. if (arr.length > 0) {
  529. let nfcs = []
  530. for (const nfc of arr) {
  531. let pro = {}
  532. pro.checkName = nfc.nfcName
  533. pro.nfccdoe = nfc.nfcCode
  534. nfcs.push(pro)
  535. }
  536. this.$refs.NfcPopup.show(nfcs)
  537. }
  538. },
  539. cancelImg(imgItem) {
  540. this.updateNFC(2,imgItem.nfcCode,imgItem);
  541. this.validateArea(this.areaId)
  542. },
  543. changeNfcImg(imgItem) {
  544. this.updateNFC(1,imgItem.nfcCode,imgItem);
  545. this.validateArea(this.areaId);
  546. },
  547. updateNFC(type,nfcCode,imgItem){
  548. //type 1 表示新增加扫描的数据,2 表示新增未扫描的数量,0 未做任何操作
  549. //nfcCode 代表扫描和减少的nfc数据。
  550. //更新全局nfc已扫描 和未扫描
  551. this.yesList = [];
  552. this.noList = [];
  553. this.areaYesList = [];
  554. this.areaNoList = [];
  555. this.nfcs.forEach(item => {
  556. if(type === 1){
  557. //新增扫描到的标签
  558. if(nfcCode === item.nfcCode){
  559. item.status = 1
  560. item.scanMethod = 1
  561. item.submitTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
  562. item.submitBy = this.id
  563. if(imgItem){
  564. //拍照NFC特殊处理
  565. item.img = imgItem.url
  566. this.currentImgNFC.push(item)
  567. }
  568. }
  569. }
  570. if(type === 2){
  571. //新增未扫描的标签
  572. if(nfcCode === item.nfcCode){
  573. item.status = 0
  574. item.scanMethod = null
  575. item.submitTime = null
  576. item.submitBy = null
  577. if(item.img){
  578. //拍照NFC特殊处理
  579. item.img = null;
  580. this.currentImgNFC = this.currentImgNFC.filter(v => {
  581. return v.nfcCode !== item.nfcCode
  582. })
  583. }
  584. }
  585. }
  586. //扫描到nfc
  587. if(item.status === 1){
  588. this.yesList.push(item);
  589. if(this.areaId === item.areaId){
  590. this.areaYesList.push(item);
  591. }
  592. }else{
  593. this.noList.push(item);
  594. if(this.areaId === item.areaId){
  595. this.areaNoList.push(item);
  596. }
  597. }
  598. });
  599. },
  600. showDetail(data) {
  601. if(data === 1){
  602. this.sheetYesList = this.yesList;
  603. this.sheetNoList = this.noList;
  604. }else{
  605. this.sheetNoList = this.areaNoList;
  606. this.sheetYesList = this.areaYesList;
  607. }
  608. this.total_show = true
  609. },
  610. onLoad() {
  611. },
  612. //点击区域
  613. clickArea(area, index) {
  614. this.activeArea(area, index)
  615. },
  616. //选中区域时数据变更
  617. activeArea(area, index) {
  618. //获取当前选中区域
  619. this.areaId = area.areaId
  620. this.updateNFC(0);
  621. //设置选中样式
  622. this.$nextTick(() => {
  623. let doms = document.getElementsByClassName('check-area')
  624. Array.prototype.forEach.call(doms, item => {
  625. item.classList.remove('active')
  626. })
  627. doms[index].classList.add('active')
  628. })
  629. let nfcs = 0
  630. let current = []
  631. let yesNum = 0;
  632. for (let i = 0; i < this.nfcs.length; i++) {
  633. let nfc = this.nfcs[i]
  634. let areaId = nfc.areaId
  635. if (areaId === area.areaId) {
  636. nfcs++
  637. if (nfc.status === 1) {
  638. yesNum++;
  639. }
  640. if (nfc.img) {
  641. current.push(nfc)
  642. }
  643. }
  644. }
  645. this.currentImgNFC = current
  646. this.yesNFCnums = yesNum;
  647. this.NFCnums = nfcs
  648. this.selectArea = area
  649. },
  650. //保存数据
  651. resumptionDataSave() {
  652. //组装数据
  653. let data = {}
  654. data.taskId = this.resumptionData.taskId
  655. data.checks = this.checks
  656. data.nfcs = this.nfcs
  657. data.subType = 1
  658. saveTask(data).then(res => {
  659. this.$toast('保存成功')
  660. this.$router.go(-1)
  661. })
  662. },
  663. submitResumptionData() {
  664. //备份数据
  665. let bakNfcs = this.nfcs;
  666. let bakChecks = this.checks;
  667. try{
  668. //验证数据
  669. let subNFCS = [];
  670. let noNfc = this.nfcs.filter((item, index) => {
  671. if(item.status === 1){
  672. subNFCS.push(item);
  673. }
  674. if(item.status === 0 && item.pointScan === 1){
  675. return true;
  676. }
  677. })
  678. if (noNfc.length > 0) {
  679. Dialog.alert({
  680. message: 'NFC标签还未扫描完成,请完成后提交!'
  681. })
  682. throw new Error('NFC标签还未扫描完成,请完成后提交!')
  683. return
  684. }
  685. for (let i = 0; i < this.checks.length; i++) {
  686. for (let j = 0; j < this.checks[i].points.length; j++) {
  687. let point = this.checks[i].points[j];
  688. if (point.dataStatus === 1) {
  689. if( point.required === 0){
  690. //如果不是必填内容
  691. this.checks[i].points[j].dataStatus = 2
  692. this.checks[i].points[j].resValue = 0
  693. }else{
  694. Dialog.alert({
  695. message: '存在未编辑完成履职项,无法提交!'
  696. })
  697. throw new Error('还有未完成的内容,请先完成再提交')
  698. }
  699. } else {
  700. if (point.resValue === 1) {
  701. if (!point.rectificationDeadline || !point.resRemark) {
  702. this.changeSwitch()
  703. this.areas.forEach((area, i) => {
  704. if (area.areaId === item.areaId) {
  705. this.activeArea(area, i)
  706. //切换后验证表单
  707. this.$refs.resumption_form.validate()
  708. this.$toast.fail({
  709. message: '请完成异常情况的信息填写!',
  710. position: 'top'
  711. })
  712. }
  713. })
  714. throw new Error('存在未编辑完成履职项,无法提交')
  715. }
  716. if(point.imgs.length < 1){
  717. this.$toast.fail({
  718. message: '请拍照上传异常图片!',
  719. position: 'top'
  720. })
  721. throw new Error('请上传异常图片!');
  722. }
  723. }
  724. }
  725. }
  726. }
  727. let data = {}
  728. data.taskId = this.resumptionData.taskId
  729. data.checks = this.checks
  730. data.nfcs = subNFCS
  731. data.subType = 2
  732. saveTask(data).then(res => {
  733. this.$toast('提交成功')
  734. this.$router.go(-1)
  735. })
  736. }catch(e){
  737. this.nfcs = bakNfcs;
  738. this.checks = bakChecks;
  739. }
  740. }
  741. }
  742. }
  743. </script>
  744. <style lang="scss" scoped>
  745. .van-progress {
  746. z-index: 999;
  747. width: 98%;
  748. left: 6px;
  749. right: 6px;
  750. }
  751. .page_box {
  752. height: calc(100vh - 60px);
  753. overflow: scroll;
  754. }
  755. .content {
  756. padding: 16px 16px 10px;
  757. }
  758. .panel {
  759. background-color: white;
  760. border-radius: 10px;
  761. border: 1px solid #ffffff;
  762. display: flex;
  763. flex-direction: column;
  764. box-shadow: 0 8px 12px #ebedf0;
  765. margin-bottom: 10px;
  766. .van-cell__title {
  767. font-weight: bold;
  768. }
  769. }
  770. .total_panel {
  771. text-align: center;
  772. .title {
  773. padding-top: 10px;
  774. }
  775. .content {
  776. padding-top: 10px;
  777. padding-bottom: 10px;
  778. .con_num {
  779. padding: 15px;
  780. }
  781. .ok {
  782. color: #26850c;
  783. }
  784. .no {
  785. color: #98632d;
  786. }
  787. }
  788. }
  789. .card {
  790. box-shadow: 0 10px 10px #eaeaea;
  791. }
  792. .van-popup {
  793. height: 50%;
  794. }
  795. .check-area {
  796. //background-color: #f1f1f1;
  797. text-align: center;
  798. margin: 10px;
  799. padding: 20px;
  800. //color: #aaa;
  801. border-radius: 6px;
  802. justify-content: space-between;
  803. align-items: center;
  804. box-shadow: 0 2px 6px #ddd;
  805. position: relative;
  806. .ysj {
  807. position: absolute;
  808. right: 5px;
  809. top: 5px;
  810. }
  811. }
  812. .active {
  813. background-color: #bdbdbd;
  814. color: #333;
  815. }
  816. .complete {
  817. color: #fff;
  818. background-color: #1989fa;
  819. }
  820. .nfc-icon {
  821. width: 50px;
  822. height: 50px;
  823. margin-left: 20px;
  824. }
  825. .bottomClass {
  826. position: fixed;
  827. width: 100%;
  828. bottom: 0;
  829. z-index: 999;
  830. background: #ebedf0;
  831. text-align: center;
  832. .van-button {
  833. width: 95%;
  834. margin-top: 10px;
  835. }
  836. }
  837. .okAll {
  838. background-color: #fff;
  839. display: flex;
  840. justify-content: center;
  841. align-items: center;
  842. height: 50px;
  843. }
  844. .nfc-img {
  845. display: inline-block;
  846. width: 160px;
  847. height: 160px;
  848. margin: 0 10px;
  849. position: relative;
  850. > img {
  851. width: 100%;
  852. height: 100%;
  853. border: none;
  854. }
  855. > span {
  856. position: absolute;
  857. padding: 0 10px;
  858. bottom: 0;
  859. left: 0;
  860. display: block;
  861. width: 100%;
  862. background-color: rgba(0, 0, 0, 0.2);
  863. color: #eaeaea;
  864. font-size: 5px;
  865. overflow: hidden;
  866. text-overflow: ellipsis;
  867. line-height: 30px;
  868. white-space: break-spaces;
  869. height: 30px;
  870. }
  871. .cancel_icon {
  872. position: absolute;
  873. font-size: 30px;
  874. right: 5px;
  875. top: 2px;
  876. }
  877. }
  878. </style>