detail.vue 26 KB

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