uploadVNormal.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. <template>
  2. <div class="questionNamep">
  3. <div class="cameraDiv" @click="uploadImg">
  4. <van-icon
  5. v-if="updateImgMode == 'album'"
  6. class="photo photos"
  7. name="photo-o"
  8. size="22px"
  9. color="#969696" />
  10. <van-icon v-else class="photo photos" name="photograph" size="22px" color="#969696" />
  11. </div>
  12. <div id="allmap"></div>
  13. <div class="mask" v-if="progressFlag">
  14. <el-progress
  15. type="circle"
  16. :percentage="percentage"
  17. :show-text="true"
  18. :width="110"
  19. :format="format"></el-progress>
  20. <div class="progressClose" @click="progressClose">取消</div>
  21. </div>
  22. <imageAIVerifyErr
  23. v-if="imageAIVerifyFlag"
  24. :imageAIVerifyFlag="imageAIVerifyFlag"
  25. :imageAIVerifyData="imageAIVerifyData"
  26. @confirmUpload="confirmUpload"
  27. @uploadImgFun="uploadImg"
  28. :source="'visit'"
  29. @normalFlow="normalFlow"
  30. @close="close"></imageAIVerifyErr>
  31. </div>
  32. </template>
  33. <script>
  34. import { addstorePhoto, addVisitsPosition, addPhotoToDB } from '@/api/index';
  35. import imageAIVerifyErr from './imageAIVerifyErr';
  36. import axios from 'axios';
  37. export default {
  38. name: 'uploadImg',
  39. components: { imageAIVerifyErr },
  40. props: {
  41. uploadid: {
  42. type: String,
  43. default: '',
  44. },
  45. storeGroupId: {
  46. type: String,
  47. default: '',
  48. },
  49. parentCollectionId: {
  50. type: String,
  51. default: '',
  52. },
  53. secondCollectionId: {
  54. type: [String, Number],
  55. default: '',
  56. },
  57. firstCollectionId: {
  58. type: String,
  59. default: '',
  60. },
  61. fourthCollectionId: {
  62. type: String,
  63. default: '',
  64. },
  65. thirdCollectionId: {
  66. type: String,
  67. default: '',
  68. },
  69. visitsId: {
  70. type: String,
  71. default: '',
  72. },
  73. taskId: {
  74. type: String,
  75. default: '',
  76. },
  77. collectionId: {
  78. type: String,
  79. default: '',
  80. },
  81. objectType: {
  82. type: String,
  83. default: '',
  84. },
  85. type: {
  86. type: Number,
  87. default: 1,
  88. },
  89. imgArr: {
  90. type: Array,
  91. default() {
  92. return [];
  93. },
  94. },
  95. visitModel: {
  96. type: String,
  97. default: '1',
  98. },
  99. deviceCode: {
  100. type: String,
  101. default: '',
  102. },
  103. putInCode: {
  104. type: String,
  105. default: '',
  106. },
  107. photoIdentifyType: {
  108. // 图匠识别目的(1:店招内容识别,2:门店代码识别,3:调色机识别,4:更换店招)
  109. type: String,
  110. default: '',
  111. },
  112. updateImgMode: {
  113. // 上传图片方式,album:相册选择;camera:相机拍照
  114. type: String,
  115. default: 'camera',
  116. },
  117. },
  118. data() {
  119. return {
  120. shows: false,
  121. url: '',
  122. progressFlag: false,
  123. percentage: 0,
  124. timeFlag: null,
  125. imageAIVerifyFlag: false,
  126. imageAIVerifyData: null, //图匠校验返回的数据
  127. meidaId: '', //当前上传图片id
  128. addressesRemark: '', //当前位置信息
  129. controller: null, //取消请求状态
  130. };
  131. },
  132. methods: {
  133. uploadImg() {
  134. var map = new TMap.Map('allmap', {
  135. zoom: 14,
  136. center: new TMap.LatLng(39.986785, 116.301012),
  137. });
  138. var geocoder = new TMap.service.Geocoder(); // 新建一个正逆地址解析类
  139. var markers = new TMap.MultiMarker({
  140. map: map,
  141. geometries: [],
  142. });
  143. markers.setGeometries([]);
  144. if (this.objectType == '' || this.objectType == null) {
  145. this.$toast('请选择类型!');
  146. return;
  147. }
  148. let url = window.location.href;
  149. let that = this;
  150. let wx = this.wx;
  151. let qiyeData;
  152. let addressesRemark = '';
  153. const instance = axios.create();
  154. instance.defaults.headers.common['userId'] = localStorage.getItem('loginName');
  155. instance
  156. .get(process.env.VUE_APP_BASE_API + 'mobile/wx/ticket', {
  157. params: {
  158. url: url,
  159. },
  160. })
  161. .then((response) => {
  162. if (response.status == 200) {
  163. qiyeData = response.data.data;
  164. wx.config({
  165. beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
  166. debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  167. appId: qiyeData.appId, // 必填,企业微信的corpID
  168. timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
  169. nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
  170. signature: qiyeData.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
  171. jsApiList: ['ready', 'chooseImage', 'uploadImage', 'getLocation'], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
  172. });
  173. wx.ready(function () {
  174. wx.getLocation({
  175. type: 'gcj02',
  176. success: function (res) {
  177. var location = new TMap.LatLng(res.latitude, res.longitude);
  178. map.setCenter(location);
  179. markers.updateGeometries([
  180. {
  181. id: 'main', // 点标注数据数组
  182. position: location,
  183. },
  184. ]);
  185. geocoder.getAddress({ location: location }).then(
  186. function (result) {
  187. var addresses = result.result.formatted_addresses;
  188. addressesRemark = addresses.recommend;
  189. },
  190. function (err) {
  191. addressesRemark = '';
  192. }
  193. );
  194. },
  195. fail: function () {
  196. that.$dialog.alert({
  197. message: 'GPS未开启',
  198. });
  199. },
  200. });
  201. wx.chooseImage({
  202. count: 1,
  203. sizeType: ['original'], // 可以指定是原图还是压缩图,默认二者都有
  204. sourceType: [updateImgMode], // 可以指定来源是相册还是相机,默认二者都有
  205. defaultCameraMode: 'normal', //表示进入拍照界面的默认模式,目前有normal与batch两种选择,normal表示普通单拍模式,batch表示连拍模式,不传该参数则为normal模式。从3.0.26版本开始支持front和batch_front两种值,其中front表示默认为前置摄像头单拍模式,batch_front表示默认为前置摄像头连拍模式。(注:用户进入拍照界面仍然可自由切换两种模式)
  206. isSaveToAlbum: 0, //整型值,0表示拍照时不保存到系统相册,1表示自动保存,默认值是1
  207. success: function (res) {
  208. var localIds = '';
  209. if (res.localIds != undefined) {
  210. localIds = res.localIds[0];
  211. } else {
  212. localIds = res.localId;
  213. }
  214. wx.uploadImage({
  215. localId: localIds, // 需要上传的图片的本地ID,由chooseImage接口获得
  216. isShowProgressTips: 1, // 默认为1,显示进度提示
  217. success: function (res) {
  218. that.uploadImagev(res.serverId, addressesRemark);
  219. },
  220. });
  221. },
  222. });
  223. });
  224. }
  225. });
  226. },
  227. uploadImagev(meidaId, addressesRemark) {
  228. // 初始化重置 图匠校验
  229. this.resetProgress();
  230. this.close();
  231. var that = this;
  232. var parentCollectionId = null;
  233. if (that.parentCollectionId != null && that.parentCollectionId != 'null') {
  234. parentCollectionId = that.parentCollectionId;
  235. }
  236. var secondCollectionId = null;
  237. if (that.secondCollectionId != null && that.secondCollectionId != 'null') {
  238. secondCollectionId = that.secondCollectionId;
  239. }
  240. var firstCollectionId = null;
  241. if (that.firstCollectionId != null && that.firstCollectionId != 'null') {
  242. firstCollectionId = that.firstCollectionId;
  243. }
  244. var fourthCollectionId = null;
  245. if (that.fourthCollectionId != null && that.fourthCollectionId != 'null') {
  246. fourthCollectionId = that.fourthCollectionId;
  247. }
  248. var thirdCollectionId = null;
  249. if (that.thirdCollectionId != null && that.thirdCollectionId != 'null') {
  250. thirdCollectionId = that.thirdCollectionId;
  251. }
  252. this.meidaId = meidaId;
  253. this.addressesRemark = addressesRemark;
  254. var form = {
  255. mediaId: meidaId,
  256. collectionItemId: that.collectionId,
  257. objectType: that.objectType,
  258. storeGroupId: that.storeGroupId,
  259. taskId: that.taskId,
  260. visitsId: localStorage.getItem('visitId'),
  261. visitModel: that.visitModel,
  262. visitSource: '1',
  263. locationRemark: addressesRemark,
  264. parentCollectionId: parentCollectionId,
  265. secondCollectionId: secondCollectionId,
  266. firstCollectionId: firstCollectionId,
  267. fourthCollectionId: fourthCollectionId,
  268. thirdCollectionId: thirdCollectionId,
  269. deviceCode: that.deviceCode, //设备编号
  270. putInCode: that.putInCode, //投放编号
  271. };
  272. this.controller = null;
  273. // 需要图匠校验的添加参数和loading
  274. if (this.photoIdentifyType) {
  275. form.photoIdentifyType = this.photoIdentifyType;
  276. this.progress();
  277. this.controller = new AbortController(); //取消请求
  278. } else {
  279. this.toastLoading(0, '上传中...', true);
  280. }
  281. addstorePhoto(form, this.controller ? this.controller.signal : null)
  282. .then((res) => {
  283. this.toastLoading().clear();
  284. if (res.code == -1) {
  285. // 图匠图片校验接口超时
  286. this.requestTimeOut(res);
  287. } else if (res.code == 200) {
  288. // 图匠校验结果返回
  289. if (this.photoIdentifyType) {
  290. // 重置loaidng状态
  291. this.resetProgress();
  292. this.imageAIVerifyFlag = true;
  293. this.imageAIVerifyData = res.data;
  294. } else {
  295. // 正常流程
  296. this.normalFlow(res);
  297. }
  298. } else {
  299. this.resetProgress();
  300. that.$toast('上传失败!');
  301. }
  302. })
  303. .catch((error) => {
  304. if (error.message === 'canceled') {
  305. this.$toast('取消上传');
  306. console.log('请求被取消:', error.message);
  307. }
  308. this.resetProgress();
  309. });
  310. },
  311. // 正常流程
  312. normalFlow(res) {
  313. this.$toast('上传成功!');
  314. this.$emit('newimgarr', {
  315. fileUrl: res.data.url,
  316. id: res.data.fileId,
  317. type: 2,
  318. photoIdentifyType: this.photoIdentifyType,
  319. });
  320. },
  321. progress() {
  322. // 后端接口20000ms后失效,每1000m progress加10,到90停止;
  323. this.progressFlag = true;
  324. this.percentage = 10;
  325. this.timeFlag = setInterval(() => {
  326. this.percentage = this.percentage + 10;
  327. if (this.percentage == 90) clearInterval(this.timeFlag);
  328. }, 1000);
  329. },
  330. format(percentage) {
  331. return `${percentage} %\n图像识别中`;
  332. },
  333. // 重置loaidng状态
  334. resetProgress() {
  335. this.percentage = 100;
  336. clearInterval(this.timeFlag);
  337. this.progressFlag = false;
  338. this.percentage = 0;
  339. },
  340. // 照片是否入库,1.照片识别三次不通过仍要上传,2.照片识别通过
  341. // isUpdate:是否更新店招照片,只有门店店招需要更新
  342. confirmUpload(res) {
  343. if (this.photoIdentifyType) {
  344. var form = {
  345. mediaId: this.meidaId, // string 图片素材id
  346. visitSource: '1', // Long 拜访模式
  347. storeGroupId: this.storeGroupId, // string 门店任务组,多个用逗号隔开
  348. visitsId: localStorage.getItem('visitId'), // string 拜访id
  349. taskId: this.taskId, // string 任务id
  350. objectType: this.objectType, // string 照片类型,取任务上的照片类型,如果没有则取手动选择的照片类型
  351. locationRemark: this.addressesRemark, // String 当前地址信息
  352. firstCollectionId: this.firstCollectionId, // Long 第一级采集项id,取当前采集项的字段就行
  353. secondCollectionId: this.secondCollectionId, // Long 第二级采集项id,取当前采集项的字段就行
  354. putInCode: this.putInCode, // String 当前任务对应的投放编号
  355. deviceCode: this.deviceCode, // String 当前任务对应的设备编号
  356. collectionItemId: this.collectionId,
  357. url: res.data.url, // String 当前拍摄图片的url
  358. businessId: res.data.businessId, // 当前拍摄图片id
  359. };
  360. if (res.isUpdate) {
  361. form.isUpdate = 'true';
  362. form.feedbackMessage = res.feedbackMessage;
  363. }
  364. addPhotoToDB(form).then((resData) => {
  365. if (resData.code == 200) {
  366. console.log(resData);
  367. res.data.fileId = resData.data.fileId;
  368. this.normalFlow(res);
  369. }
  370. });
  371. }
  372. },
  373. close() {
  374. this.imageAIVerifyFlag = false;
  375. },
  376. requestTimeOut(res) {
  377. this.resetProgress();
  378. this.close();
  379. this.$dialog
  380. .confirm({
  381. title: '系统提示',
  382. message: res.msg,
  383. showCancelButton: false,
  384. })
  385. .then(() => {
  386. this.confirmUpload(res);
  387. });
  388. },
  389. // 取消图片上传
  390. progressClose() {
  391. this.controller.abort();
  392. },
  393. },
  394. };
  395. </script>
  396. <style lang="scss" scoped>
  397. .questionNamep {
  398. font-size: 16px;
  399. color: #484848;
  400. line-height: 40px;
  401. padding: 0 15px;
  402. box-sizing: border-box;
  403. position: relative;
  404. .cameraDivp {
  405. flex: 1;
  406. display: flex;
  407. align-items: center;
  408. justify-content: center;
  409. .photo {
  410. /*margin-top: 9px;*/
  411. float: right;
  412. }
  413. .camera {
  414. width: 60px;
  415. height: 100%;
  416. position: absolute;
  417. right: 0;
  418. top: 0;
  419. opacity: 0;
  420. z-index: 89;
  421. }
  422. }
  423. .mask {
  424. position: fixed;
  425. top: 0;
  426. left: 0;
  427. right: 0;
  428. bottom: 0;
  429. width: 100%;
  430. height: 100%;
  431. background: rgba(255, 255, 255, 1);
  432. display: flex;
  433. justify-content: center;
  434. align-items: center;
  435. z-index: 99999999;
  436. display: flex;
  437. flex-direction: column;
  438. .progressClose {
  439. width: 70px;
  440. text-align: center;
  441. background: #67c23a;
  442. color: #fff;
  443. height: 30px;
  444. line-height: 30px;
  445. border-radius: 5px;
  446. margin-top: 5px;
  447. font-size: 12px;
  448. }
  449. }
  450. }
  451. #allmap {
  452. width: 10px;
  453. height: 10px;
  454. left: -1000px;
  455. position: relative;
  456. }
  457. </style>
  458. <style lang="scss">
  459. .mask {
  460. .el-progress__text {
  461. white-space: pre-wrap;
  462. }
  463. }
  464. </style>