detail.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  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 }}</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 nfc = JSON.parse(nfcStr);
  340. let nfcCode = nfc.content;
  341. this.checkNfcFilter(nfcCode);
  342. },
  343. checkNfcFilter(nfcCode){
  344. let areaId = null;
  345. let checkOk = false;
  346. this.nfcs.forEach(v => {
  347. if(v.nfcCode === nfcCode){
  348. areaId = v.areaId;
  349. this.switchArea(areaId);
  350. if(v.status === 1){
  351. this.$toast.fail('NFC点位:' + v.nfcName + '已扫描,请勿重复扫描!');
  352. throw new Error('NFC点位:' + v.nfcName + '已扫描,请勿重复扫描!');
  353. }
  354. v.status = 1
  355. v.scanMethod = 2
  356. v.submitTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
  357. v.submitBy = this.id
  358. this.$toast.success('NFC点位:' + v.nfcName + '扫描成功!');
  359. checkOk = true;
  360. }
  361. });
  362. this.updateNFC(1,nfcCode);
  363. if(!checkOk){
  364. this.$toast.fail(nfcCode + ",不在本次履职范围内!");
  365. }
  366. this.validateArea(areaId)
  367. },
  368. switchArea(areaId){
  369. this.areas.forEach((area, i) => {
  370. if (areaId === area.areaId) {
  371. this.activeArea(area, i)
  372. }
  373. })
  374. },
  375. useNFC(){
  376. let system = this.isAndroidOrIos();
  377. const parms = {
  378. "iOS_SessionType":"0"
  379. };
  380. if(system === 1){
  381. //android
  382. // 判断当前环境是是否存在 js桥 'sap'
  383. const hasSap = window.hasOwnProperty('sap');
  384. if (hasSap) {
  385. // 判断是否存在方法 ?preview
  386. const fun = sap.hasOwnProperty('openNFCScan');
  387. if (fun) {
  388. sap.openNFCScan(JSON.stringify(parms));
  389. }
  390. }
  391. }
  392. if(system === 2){
  393. //ios
  394. // 判断 ios是否存在方法 preview
  395. const fun = window.webkit.messageHandlers.hasOwnProperty('openNFCScan')
  396. if (fun) {
  397. window.webkit.messageHandlers.openNFCScan.postMessage(JSON.stringify(parms))
  398. }
  399. }
  400. },
  401. isAndroidOrIos(){
  402. const urls = navigator.userAgent;
  403. let isAndroid = urls.indexOf('Android') > -1 || urls.indexOf('Linux') > -1;
  404. let isIos = !!urls.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
  405. if(isAndroid){
  406. return 1;
  407. }
  408. if(isIos){
  409. return 2;
  410. }
  411. },
  412. preViewNFC(i) {
  413. this.preViewImages.images = this.currentImgNFC.map(v => imgUrl(v.img))
  414. this.preViewImages.startPosition = i
  415. ImagePreview(this.preViewImages)
  416. },
  417. clickWarnImage(arr, i) {
  418. this.preViewImages.images = arr.map(v => imgUrl(v.imgPath))
  419. this.preViewImages.startPosition = i
  420. ImagePreview(this.preViewImages)
  421. },
  422. getResumptionData() {
  423. let data = {
  424. taskId: this.$route.query.id,
  425. taskDate: this.$route.query.taskDate
  426. }
  427. taskDetail(data).then(res => {
  428. let { taskId, taskName, yesPointNums, noPointNums, yesNFCNums, noNFCNums, status } = res.data
  429. this.resumptionData = {
  430. taskId,
  431. taskName,
  432. yesPointNums,
  433. noPointNums,
  434. yesNFCNums,
  435. noNFCNums,
  436. status
  437. }
  438. this.enable = this.resumptionData.status === 1 || this.resumptionData.status === 2
  439. this.checks = res.data.checks
  440. this.nfcs = res.data.nfcs
  441. this.areas = res.data.areas
  442. let obj = {};
  443. res.data.areas.forEach(function(v,i){
  444. obj[v.areaId] = v.areaName;
  445. });
  446. this.areasMap = obj;
  447. this.activeArea(this.areas[0], 0)
  448. if (!this.enable) {
  449. this.openCollapseItems()
  450. }
  451. this.updateNFC(0);
  452. })
  453. },
  454. openCollapseItems() {
  455. let len = this.checks.length
  456. for (let i = 0; i < len; i++) {
  457. let title = this.checks[i].itemName
  458. this.activeNames.push(title)
  459. }
  460. },
  461. changeSwitch() {
  462. let num = 0
  463. for (let i = 0; i < this.checks.length; i++) {
  464. for (let j = 0; j < this.checks[i].points.length; j++) {
  465. this.checks[i].points[j].dataStatus = 2
  466. num++
  467. }
  468. }
  469. this.resumptionData.yesPointNums = num
  470. this.resumptionData.noPointNums = 0
  471. this.areas.forEach((item, index) => {
  472. this.validateArea(item.areaId)
  473. })
  474. this.openCollapseItems()
  475. },
  476. changeCurrentSwitch(areaId) {
  477. this.resumptionData.yesPointNums = this.resumptionData.yesPointNums + 1
  478. this.resumptionData.noPointNums = this.resumptionData.noPointNums - 1
  479. this.validateArea(areaId)
  480. },
  481. validateArea(areaId) {
  482. let total = 0
  483. let yes = 0
  484. this.checks.forEach(item => {
  485. let pointList = item.points
  486. pointList.forEach(point => {
  487. if (item.areaId === areaId) {
  488. total++
  489. if (point.dataStatus === 2) {
  490. yes++
  491. }
  492. }
  493. })
  494. })
  495. let areaStatus = '0'
  496. if (total === yes && this.areaNoList.length === 0) {
  497. areaStatus = '1'
  498. } else if (yes === 0 && this.areaNoList.length === this.NFCnums) {
  499. areaStatus = '0'
  500. } else {
  501. areaStatus = '2'
  502. }
  503. this.areas.forEach((item, index) => {
  504. if (item.areaId === areaId) {
  505. this.areas[index].areaStatus = areaStatus
  506. }
  507. })
  508. },
  509. clickNFC() {
  510. let arr = this.nfcs.filter(item => {
  511. return item.areaId === this.areaId && item.status === 0
  512. })
  513. if (arr.length > 0) {
  514. let nfcs = []
  515. for (const nfc of arr) {
  516. let pro = {}
  517. pro.checkName = nfc.nfcName
  518. pro.nfccdoe = nfc.nfcCode
  519. nfcs.push(pro)
  520. }
  521. this.$refs.NfcPopup.show(nfcs)
  522. }
  523. },
  524. cancelImg(imgItem) {
  525. this.updateNFC(2,imgItem.nfcCode,imgItem);
  526. this.validateArea(this.areaId)
  527. },
  528. changeNfcImg(imgItem) {
  529. this.updateNFC(1,imgItem.nfcCode,imgItem);
  530. this.validateArea(this.areaId);
  531. },
  532. updateNFC(type,nfcCode,imgItem){
  533. //type 1 表示新增加扫描的数据,2 表示新增未扫描的数量,0 未做任何操作
  534. //nfcCode 代表扫描和减少的nfc数据。
  535. //更新全局nfc已扫描 和未扫描
  536. this.yesList = [];
  537. this.noList = [];
  538. this.areaYesList = [];
  539. this.areaNoList = [];
  540. this.nfcs.forEach(item => {
  541. if(type === 1){
  542. //新增扫描到的标签
  543. if(nfcCode === item.nfcCode){
  544. item.status = 1
  545. item.scanMethod = 1
  546. item.submitTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
  547. item.submitBy = this.id
  548. if(imgItem){
  549. //拍照NFC特殊处理
  550. item.img = imgItem.url
  551. this.currentImgNFC.push(item)
  552. }
  553. }
  554. }
  555. if(type === 2){
  556. //新增未扫描的标签
  557. if(nfcCode === item.nfcCode){
  558. item.status = 0
  559. item.scanMethod = null
  560. item.submitTime = null
  561. item.submitBy = null
  562. if(item.img){
  563. //拍照NFC特殊处理
  564. item.img = null;
  565. this.currentImgNFC = this.currentImgNFC.filter(v => {
  566. return v.nfcCode !== item.nfcCode
  567. })
  568. }
  569. }
  570. }
  571. //扫描到nfc
  572. if(item.status === 1){
  573. this.yesList.push(item);
  574. if(this.areaId === item.areaId){
  575. this.areaYesList.push(item);
  576. }
  577. }else{
  578. this.noList.push(item);
  579. if(this.areaId === item.areaId){
  580. this.areaNoList.push(item);
  581. }
  582. }
  583. });
  584. },
  585. showDetail(data) {
  586. if(data === 1){
  587. this.sheetYesList = this.yesList;
  588. this.sheetNoList = this.noList;
  589. }else{
  590. this.sheetNoList = this.areaNoList;
  591. this.sheetYesList = this.areaYesList;
  592. }
  593. this.total_show = true
  594. },
  595. onLoad() {
  596. },
  597. //点击区域
  598. clickArea(area, index) {
  599. this.activeArea(area, index)
  600. },
  601. //选中区域时数据变更
  602. activeArea(area, index) {
  603. //获取当前选中区域
  604. this.areaId = area.areaId
  605. this.updateNFC(0);
  606. //设置选中样式
  607. this.$nextTick(() => {
  608. let doms = document.getElementsByClassName('check-area')
  609. Array.prototype.forEach.call(doms, item => {
  610. item.classList.remove('active')
  611. })
  612. doms[index].classList.add('active')
  613. })
  614. let nfcs = 0
  615. let current = []
  616. let yesNum = 0;
  617. for (let i = 0; i < this.nfcs.length; i++) {
  618. let nfc = this.nfcs[i]
  619. let areaId = nfc.areaId
  620. if (areaId === area.areaId) {
  621. nfcs++
  622. if (nfc.status === 1) {
  623. yesNum++;
  624. }
  625. if (nfc.img) {
  626. current.push(nfc)
  627. }
  628. }
  629. }
  630. this.currentImgNFC = current
  631. this.yesNFCnums = yesNum;
  632. this.NFCnums = nfcs
  633. this.selectArea = area
  634. },
  635. //保存数据
  636. resumptionDataSave() {
  637. //组装数据
  638. let data = {}
  639. data.taskId = this.resumptionData.taskId
  640. data.checks = this.checks
  641. data.nfcs = this.nfcs
  642. data.subType = 1
  643. saveTask(data).then(res => {
  644. this.$toast('保存成功')
  645. this.$router.go(-1)
  646. })
  647. },
  648. submitResumptionData() {
  649. //备份数据
  650. let bakNfcs = this.nfcs;
  651. let bakChecks = this.checks;
  652. try{
  653. //验证数据
  654. let subNFCS = [];
  655. let noNfc = this.nfcs.filter((item, index) => {
  656. if(item.status === 1){
  657. subNFCS.push(item);
  658. }
  659. if(item.status === 0 && item.pointScan === 1){
  660. return true;
  661. }
  662. })
  663. if (noNfc.length > 0) {
  664. Dialog.alert({
  665. message: 'NFC标签还未扫描完成,请完成后提交!'
  666. })
  667. throw new Error('NFC标签还未扫描完成,请完成后提交!')
  668. return
  669. }
  670. for (let i = 0; i < this.checks.length; i++) {
  671. for (let j = 0; j < this.checks[i].points.length; j++) {
  672. let point = this.checks[i].points[j];
  673. if (point.dataStatus === 1) {
  674. if( point.required === 0){
  675. //如果不是必填内容
  676. this.checks[i].points[j].dataStatus = 2
  677. this.checks[i].points[j].resValue = 0
  678. }else{
  679. Dialog.alert({
  680. message: '存在未编辑完成履职项,无法提交!'
  681. })
  682. throw new Error('还有未完成的内容,请先完成再提交')
  683. }
  684. } else {
  685. if (point.resValue === 1) {
  686. if (!point.rectificationDeadline || !point.resRemark) {
  687. this.changeSwitch()
  688. this.areas.forEach((area, i) => {
  689. if (area.areaId === item.areaId) {
  690. this.activeArea(area, i)
  691. //切换后验证表单
  692. this.$refs.resumption_form.validate()
  693. this.$toast.fail({
  694. message: '请完成异常情况的信息填写!',
  695. position: 'top'
  696. })
  697. }
  698. })
  699. throw new Error('存在未编辑完成履职项,无法提交')
  700. }
  701. if(point.imgs.length < 1){
  702. this.$toast.fail({
  703. message: '请拍照上传异常图片!',
  704. position: 'top'
  705. })
  706. throw new Error('请上传异常图片!');
  707. }
  708. }
  709. }
  710. }
  711. }
  712. let data = {}
  713. data.taskId = this.resumptionData.taskId
  714. data.checks = this.checks
  715. data.nfcs = subNFCS
  716. data.subType = 2
  717. saveTask(data).then(res => {
  718. this.$toast('提交成功')
  719. this.$router.go(-1)
  720. })
  721. }catch(e){
  722. this.nfcs = bakNfcs;
  723. this.checks = bakChecks;
  724. }
  725. }
  726. }
  727. }
  728. </script>
  729. <style lang="scss" scoped>
  730. .van-progress {
  731. z-index: 999;
  732. width: 98%;
  733. left: 6px;
  734. right: 6px;
  735. }
  736. .page_box {
  737. height: calc(100vh - 60px);
  738. overflow: scroll;
  739. }
  740. .content {
  741. padding: 16px 16px 10px;
  742. }
  743. .panel {
  744. background-color: white;
  745. border-radius: 10px;
  746. border: 1px solid #ffffff;
  747. display: flex;
  748. flex-direction: column;
  749. box-shadow: 0 8px 12px #ebedf0;
  750. margin-bottom: 10px;
  751. .van-cell__title {
  752. font-weight: bold;
  753. }
  754. }
  755. .total_panel {
  756. text-align: center;
  757. .title {
  758. padding-top: 10px;
  759. }
  760. .content {
  761. padding-top: 10px;
  762. padding-bottom: 10px;
  763. .con_num {
  764. padding: 15px;
  765. }
  766. .ok {
  767. color: #26850c;
  768. }
  769. .no {
  770. color: #98632d;
  771. }
  772. }
  773. }
  774. .card {
  775. box-shadow: 0 10px 10px #eaeaea;
  776. height: 50px;
  777. }
  778. .van-popup {
  779. height: 50%;
  780. }
  781. .check-area {
  782. //background-color: #f1f1f1;
  783. text-align: center;
  784. margin: 10px;
  785. padding: 20px;
  786. //color: #aaa;
  787. border-radius: 6px;
  788. justify-content: space-between;
  789. align-items: center;
  790. box-shadow: 0 2px 6px #ddd;
  791. position: relative;
  792. .ysj {
  793. position: absolute;
  794. right: 5px;
  795. top: 5px;
  796. }
  797. }
  798. .active {
  799. background-color: #bdbdbd;
  800. color: #333;
  801. }
  802. .complete {
  803. color: #fff;
  804. background-color: #1989fa;
  805. }
  806. .nfc-icon {
  807. width: 50px;
  808. height: 50px;
  809. margin-left: 20px;
  810. }
  811. .bottomClass {
  812. position: fixed;
  813. width: 100%;
  814. bottom: 0;
  815. z-index: 999;
  816. background: #ebedf0;
  817. text-align: center;
  818. .van-button {
  819. width: 95%;
  820. margin-top: 10px;
  821. }
  822. }
  823. .okAll {
  824. background-color: #fff;
  825. display: flex;
  826. justify-content: center;
  827. align-items: center;
  828. height: 50px;
  829. }
  830. .nfc-img {
  831. display: inline-block;
  832. width: 160px;
  833. height: 160px;
  834. margin: 0 10px;
  835. position: relative;
  836. > img {
  837. width: 100%;
  838. height: 100%;
  839. border: none;
  840. }
  841. > span {
  842. position: absolute;
  843. padding: 0 10px;
  844. bottom: 0;
  845. left: 0;
  846. display: block;
  847. width: 100%;
  848. background-color: rgba(0, 0, 0, 0.2);
  849. color: #eaeaea;
  850. font-size: 5px;
  851. overflow: hidden;
  852. text-overflow: ellipsis;
  853. line-height: 30px;
  854. white-space: break-spaces;
  855. height: 30px;
  856. }
  857. .cancel_icon {
  858. position: absolute;
  859. font-size: 30px;
  860. right: 5px;
  861. top: 2px;
  862. }
  863. }
  864. </style>