imageAIVerifyErr.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <template>
  2. <div class="imageAIVerifyErr">
  3. <el-dialog
  4. title="图像识别结果"
  5. :visible.sync="vanPopup"
  6. width="80%"
  7. :append-to-body="true"
  8. :close-on-click-modal="false"
  9. @close="close"
  10. custom-class="AIVerifyErrdialog">
  11. <div class="AIVerifyErrMask" v-if="npkpiData">
  12. <!-- shopSignChange 与历史照片是否一致(是否要更换照片) 0一致(要更换),1不一致(不要更换) -->
  13. <template v-if="shopSignChange == 0">
  14. <div class="errorImg">
  15. <img v-if="url" :src="url" height="200px" @click="previewsImg(url)" />
  16. <img v-else :src="imageEmpty" width="100%" height="200px" />
  17. </div>
  18. <div class="AIVerify">
  19. <span style="color: red">{{ contentMessage }}</span>
  20. </div>
  21. <template v-if="shotsNum >= 3">
  22. <div class="feedbackMessage">
  23. <div class="label">若图像识别不正确,可在下表反馈:</div>
  24. <div class="value">
  25. <van-field
  26. v-model="feedbackMessage"
  27. rows="1"
  28. autosize
  29. type="textarea"
  30. placeholder="请输入反馈意见" />
  31. </div>
  32. </div>
  33. </template>
  34. <div class="uploadBtnAIVerify">
  35. <div class="confirmUploadAIVerify" @click="uploadImg(false)">重新拍照</div>
  36. <div v-if="shotsNum >= 3" class="stillUploadAIVerify" @click="confirmUpload">
  37. 仍要上传
  38. </div>
  39. </div>
  40. <template v-if="shotsNum >= 3">
  41. <div class="tipsAIVerify" v-if="npkpiData.recognizeType == 1">
  42. <van-icon name="question-o" />上传后作为本店标准店招,未来每次拜访时校验。
  43. </div>
  44. </template>
  45. </template>
  46. <template v-if="shopSignChange == 1">
  47. <div class="historyImageAIVerify">
  48. <!-- 有门店身份证时 只显示门店身份证和本地拜访照 -->
  49. <template v-if="storeIDCardUrl">
  50. <div class="storeIDCardUrl imageItemAIVerify">
  51. <img
  52. :src="storeIDCardUrl"
  53. width="100px"
  54. height="100px"
  55. @click="previewsImg(storeIDCardUrl)" />
  56. <span>门店标准店招</span>
  57. </div>
  58. </template>
  59. <template v-else>
  60. <div class="initImage imageItemAIVerify">
  61. <img
  62. v-if="createStoreUrl"
  63. :src="createStoreUrl"
  64. width="100px"
  65. height="100px"
  66. @click="previewsImg(createStoreUrl)" />
  67. <img v-else :src="imageEmpty" width="100px" height="100px" />
  68. <span>建店时门店照</span>
  69. </div>
  70. <div class="newestImage imageItemAIVerify">
  71. <img
  72. v-if="lastVisitUrl"
  73. :src="lastVisitUrl"
  74. width="100px"
  75. height="100px"
  76. @click="previewsImg(lastVisitUrl)" />
  77. <img v-else :src="imageEmpty" width="100px" height="100px" />
  78. <span>上次拜访店招</span>
  79. </div>
  80. </template>
  81. <div class="presentImage imageItemAIVerify">
  82. <img v-if="url" :src="url" width="100px" height="100px" @click="previewsImg(url)" />
  83. <img v-else :src="imageEmpty" width="100px" height="100px" />
  84. <span>本次拜访店招</span>
  85. </div>
  86. </div>
  87. <div class="AIVerify">
  88. <span style="color: red">{{ contentMessage }}</span>
  89. </div>
  90. <div class="feedbackMessage">
  91. <div class="label">若图像识别不正确,可在下表反馈:</div>
  92. <div class="value">
  93. <van-field
  94. v-model="feedbackMessage"
  95. rows="2"
  96. autosize
  97. type="textarea"
  98. placeholder="请输入反馈意见" />
  99. </div>
  100. </div>
  101. <div class="uploadBtnAIVerify">
  102. <div class="confirmUploadAIVerify" @click="uploadImg(true)">重新拍照</div>
  103. <div class="changeImageAIVerify" @click="confirmUpDataImage()">更新门店照</div>
  104. </div>
  105. <div class="tipsRemarkAIVerify">
  106. <div>若历史照片拍摄不规范,请选择<span style="color: #81b337">更新门店照</span></div>
  107. <div>本次拜访店招会作为本店标准店招,未来每次拜访时校验</div>
  108. </div>
  109. </template>
  110. </div>
  111. </el-dialog>
  112. </div>
  113. </template>
  114. <script>
  115. import { ImagePreview } from 'vant';
  116. import store from '@/store';
  117. import { mapState } from 'vuex';
  118. import imageEmpty from '@/assets/imageEmpty.png';
  119. export default {
  120. props: {
  121. imageAIVerifyFlag: {
  122. type: Boolean,
  123. default: false,
  124. },
  125. imageAIVerifyData: {
  126. type: [Array, Object],
  127. },
  128. source: {
  129. // 新建店还是门店拜访 visit/newCreated
  130. type: String,
  131. },
  132. },
  133. computed: {
  134. ...mapState({
  135. shotsNum: (state) => state.otheStore.shotsNum,
  136. }),
  137. },
  138. watch: {
  139. imageAIVerifyFlag: {
  140. handler(val) {
  141. console.log('imageAIVerifyFlag=' + val);
  142. if (val) this.initData();
  143. },
  144. immediate: true,
  145. },
  146. },
  147. data() {
  148. return {
  149. imageEmpty: imageEmpty,
  150. contentMessage: '', //提示内容
  151. vanPopup: true,
  152. shopSignChange: 0,
  153. npkpiData: null,
  154. feedbackMessage: '', //反馈图像识别不正确原因
  155. url: '', // 本次图片路径
  156. createStoreUrl: '', // 建店时店招
  157. lastVisitUrl: '', // 上次拜访时店招
  158. storeIDCardUrl: '', // 门店身份证
  159. };
  160. },
  161. methods: {
  162. initData() {
  163. // 图匠识别目的(1:店招内容识别,2:门店代码识别,3:调色机识别,4:更换店招)
  164. // shopSignChange 是否更换店招(0:未更换,1:更换) 1不一致,0一致
  165. // checkInfo 图片检查结果
  166. // cheatState 是否作弊(0:未作弊,1:作弊)
  167. // cheatType 作弊类型
  168. // qualifiedState 是否合格(0:不合格,1:合格)
  169. // unqualifiedReason 不合格原因
  170. this.feedbackMessage = '';
  171. this.shopSignChange = 0;
  172. this.npkpiData =
  173. this.source == 'visit'
  174. ? this.imageAIVerifyData.npkpiData
  175. : this.imageAIVerifyData[0].npkpiData;
  176. let imageAIVerifyData =
  177. this.source == 'visit' ? this.imageAIVerifyData : this.imageAIVerifyData[0];
  178. this.shopSignMatchList = this.npkpiData.shopSignMatchList;
  179. this.url = imageAIVerifyData.url || ''; // 图片路径
  180. this.createStoreUrl = imageAIVerifyData.createStoreUrl || ''; // 建店时店招
  181. this.lastVisitUrl = imageAIVerifyData.lastVisitUrl || ''; // 上次拜访时店招
  182. this.storeIDCardUrl = imageAIVerifyData.storeIDCardUrl || ''; // 门店身份证
  183. // 先判断照片作弊情况,然后是否合格,然后是否和历史照片一致
  184. // 作弊和不合格记录识别次数,超过两次弹框提醒
  185. if (this.npkpiData.checkInfo) {
  186. // 作弊
  187. if (this.npkpiData.checkInfo.cheatState == 1) {
  188. // 增加识别次数
  189. store.dispatch('setShotsNum', this.shotsNum + 1);
  190. // 作弊原因
  191. this.contentMessage = this.contentMessage + this.npkpiData.checkInfo.cheatType;
  192. return;
  193. }
  194. // 不合格
  195. if (this.npkpiData.checkInfo.qualifiedState == 0) {
  196. // 增加识别次数
  197. store.dispatch('setShotsNum', this.shotsNum + 1);
  198. // 不合格原因
  199. this.contentMessage = this.contentMessage + this.npkpiData.checkInfo.unqualifiedReason;
  200. return;
  201. }
  202. // recognizeType 识别目的(1:店招内容识别,2:门店代码识别,3:调色机识别)
  203. if (this.npkpiData.recognizeType == 1) {
  204. this.comparisonImage();
  205. } else {
  206. this.confirmUpload();
  207. }
  208. }
  209. },
  210. // 照片和历史照片是否一致
  211. comparisonImage() {
  212. this.shopSignChange = this.npkpiData.shopSignChange;
  213. if (this.npkpiData.shopSignChange == 1) {
  214. this.contentMessage = '与历史照片不一致,请确认店招是否更换?';
  215. return false;
  216. } else {
  217. this.confirmUpDataImage();
  218. }
  219. },
  220. // 重新拍照
  221. uploadImg(flag) {
  222. // flag: true,识别与历史照片不一致状态下,点击重新拍照,照片识别次数需要加1
  223. if (flag) {
  224. // 增加识别次数
  225. store.dispatch('setShotsNum', this.shotsNum + 1);
  226. }
  227. this.$emit('close');
  228. this.$emit('uploadImgFun');
  229. },
  230. // 照片是否入库,1.照片识别三次不通过仍要上传,2.照片识别通过
  231. // isUpdate:是否更新店招照片,只有门店店招需要更新
  232. confirmUpload() {
  233. // 拜访店招 不合格或作弊三次先提示是否仍要上传,确认后在判断是否与历史照片一致
  234. if (this.npkpiData.recognizeType == 1 && this.shotsNum >= 3) {
  235. this.comparisonImage();
  236. } else {
  237. this.$emit('close');
  238. this.$emit('confirmUpload', {
  239. data: this.imageAIVerifyData,
  240. feedbackMessage: this.feedbackMessage,
  241. });
  242. }
  243. },
  244. confirmUpDataImage() {
  245. this.$emit('close');
  246. this.$emit('confirmUpload', {
  247. data: this.imageAIVerifyData,
  248. isUpdate: 'true',
  249. feedbackMessage: this.feedbackMessage,
  250. });
  251. },
  252. close() {
  253. this.$emit('close');
  254. },
  255. openTips() {
  256. this.$dialog
  257. .confirm({
  258. title: '提示',
  259. message: '不规范的照片上传后会更换本店标准店招,未来每次拜访时校验。',
  260. showCancelButton: false,
  261. className: 'openTips',
  262. overlayClass: 'openTipsMask',
  263. })
  264. .then(() => {});
  265. },
  266. previewsImg(url) {
  267. ImagePreview({
  268. images: [url],
  269. className: 'AIImageItem',
  270. getContainer: 'el-dialog__wrapper',
  271. });
  272. },
  273. },
  274. };
  275. </script>
  276. <style lang="scss">
  277. .el-dialog__wrapper {
  278. z-index: 3333 !important;
  279. display: flex;
  280. justify-content: center;
  281. align-items: center;
  282. background: rgba(0, 0, 0, 0.5) !important;
  283. .el-dialog__body {
  284. padding: 6px !important;
  285. }
  286. .el-dialog__header {
  287. text-align: center;
  288. }
  289. .AIVerifyErrdialog {
  290. width: 95% !important;
  291. margin-top: 1vh !important;
  292. border-radius: 8px !important;
  293. }
  294. .AIVerifyErrMask {
  295. width: 100%;
  296. padding: 8px;
  297. overflow: hidden;
  298. /* min-height: 180px; */
  299. .errorImg {
  300. width: 100%;
  301. display: flex;
  302. align-items: center;
  303. justify-content: center;
  304. }
  305. .AIVerify {
  306. padding: 6px 0;
  307. font-size: 16px;
  308. /* color: red; */
  309. text-align: center;
  310. /* border-top: 1px solid #cfcfcf; */
  311. }
  312. }
  313. .van-popup {
  314. width: 90%;
  315. padding: 8px;
  316. border-radius: 8px;
  317. overflow: hidden;
  318. }
  319. .van-f-red-AIVerify {
  320. color: red;
  321. width: 8px;
  322. display: inline-block;
  323. line-height: 26px;
  324. }
  325. .photoAIVerify {
  326. /*margin-top: 9px;*/
  327. float: right;
  328. }
  329. .title {
  330. font-size: 16px;
  331. font-weight: 600;
  332. text-align: center;
  333. padding: 5px;
  334. }
  335. .contentAIVerify {
  336. .uploadImgAIVerify {
  337. display: flex;
  338. align-items: center;
  339. justify-content: space-between;
  340. padding: 8px 0;
  341. border-top: 1px solid #cfcfcf;
  342. .labelAIVerify {
  343. font-size: 14px;
  344. }
  345. }
  346. }
  347. .tipsAIVerify {
  348. /* border-top: 1px solid #cfcfcf; */
  349. padding: 5px 0;
  350. font-size: 14px;
  351. color: red;
  352. /* white-space: nowrap; */
  353. }
  354. .uploadBtnAIVerify {
  355. /* border-top: 1px solid #cfcfcf; */
  356. display: flex;
  357. align-items: center;
  358. justify-content: center;
  359. padding: 8px 0;
  360. div {
  361. /* width: 40%; */
  362. display: flex;
  363. justify-content: center;
  364. align-items: center;
  365. font-size: 14px;
  366. color: #fff;
  367. border-radius: 10px;
  368. margin: 0 6px;
  369. flex: 1;
  370. }
  371. .confirmUploadAIVerify {
  372. background-color: #0057ba;
  373. padding: 8px 0;
  374. }
  375. .changeImageAIVerify {
  376. background-color: #81b337;
  377. padding: 8px 0;
  378. }
  379. .stillUploadAIVerify {
  380. border: 1px solid #0057ba;
  381. color: #0057ba;
  382. padding: 8px 0;
  383. }
  384. }
  385. .historyImageAIVerify {
  386. display: flex;
  387. justify-content: space-around;
  388. padding: 5px 0;
  389. .imageItemAIVerify {
  390. width: 30%;
  391. display: flex;
  392. flex-direction: column;
  393. align-items: center;
  394. justify-content: center;
  395. span {
  396. font-size: 12px;
  397. padding-top: 3px;
  398. }
  399. }
  400. }
  401. .tipsRemarkAIVerify {
  402. border-top: 1px solid #cfcfcf;
  403. padding: 3px 0;
  404. div {
  405. font-size: 12px;
  406. padding: 3px 0;
  407. }
  408. }
  409. .feedbackMessage {
  410. border-top: 1px solid #cfcfcf;
  411. padding: 5px 0;
  412. /* width: 100%; */
  413. .van-field__body {
  414. border: 1px solid #ccc;
  415. padding-left: 10px;
  416. }
  417. }
  418. }
  419. .openTipsMask,
  420. .openTips {
  421. z-index: 3334 !important;
  422. }
  423. .van-overlay {
  424. /* z-index: 3334 !important; */
  425. }
  426. .van-image-preview {
  427. z-index: 3335 !important;
  428. background: rgba(0, 0, 0, 0.8) !important;
  429. }
  430. </style>