uploadVNormal.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  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. console.log(that.updateImgMode);
  202. wx.chooseImage({
  203. count: 1,
  204. sizeType: ['original'], // 可以指定是原图还是压缩图,默认二者都有
  205. sourceType: [that.updateImgMode], // 可以指定来源是相册还是相机,默认二者都有
  206. defaultCameraMode: 'normal', //表示进入拍照界面的默认模式,目前有normal与batch两种选择,normal表示普通单拍模式,batch表示连拍模式,不传该参数则为normal模式。从3.0.26版本开始支持front和batch_front两种值,其中front表示默认为前置摄像头单拍模式,batch_front表示默认为前置摄像头连拍模式。(注:用户进入拍照界面仍然可自由切换两种模式)
  207. isSaveToAlbum: 0, //整型值,0表示拍照时不保存到系统相册,1表示自动保存,默认值是1
  208. success: function (res) {
  209. var localIds = '';
  210. if (res.localIds != undefined) {
  211. localIds = res.localIds[0];
  212. } else {
  213. localIds = res.localId;
  214. }
  215. wx.uploadImage({
  216. localId: localIds, // 需要上传的图片的本地ID,由chooseImage接口获得
  217. isShowProgressTips: 1, // 默认为1,显示进度提示
  218. success: function (res) {
  219. that.uploadImagev(res.serverId, addressesRemark);
  220. },
  221. });
  222. },
  223. });
  224. });
  225. }
  226. });
  227. },
  228. uploadImagev(meidaId, addressesRemark) {
  229. // 初始化重置 图匠校验
  230. this.resetProgress();
  231. this.close();
  232. var that = this;
  233. var parentCollectionId = null;
  234. if (that.parentCollectionId != null && that.parentCollectionId != 'null') {
  235. parentCollectionId = that.parentCollectionId;
  236. }
  237. var secondCollectionId = null;
  238. if (that.secondCollectionId != null && that.secondCollectionId != 'null') {
  239. secondCollectionId = that.secondCollectionId;
  240. }
  241. var firstCollectionId = null;
  242. if (that.firstCollectionId != null && that.firstCollectionId != 'null') {
  243. firstCollectionId = that.firstCollectionId;
  244. }
  245. var fourthCollectionId = null;
  246. if (that.fourthCollectionId != null && that.fourthCollectionId != 'null') {
  247. fourthCollectionId = that.fourthCollectionId;
  248. }
  249. var thirdCollectionId = null;
  250. if (that.thirdCollectionId != null && that.thirdCollectionId != 'null') {
  251. thirdCollectionId = that.thirdCollectionId;
  252. }
  253. this.meidaId = meidaId;
  254. this.addressesRemark = addressesRemark;
  255. var form = {
  256. mediaId: meidaId,
  257. collectionItemId: that.collectionId,
  258. objectType: that.objectType,
  259. storeGroupId: that.storeGroupId,
  260. taskId: that.taskId,
  261. visitsId: localStorage.getItem('visitId'),
  262. visitModel: that.visitModel,
  263. visitSource: '1',
  264. locationRemark: addressesRemark,
  265. parentCollectionId: parentCollectionId,
  266. secondCollectionId: secondCollectionId,
  267. firstCollectionId: firstCollectionId,
  268. fourthCollectionId: fourthCollectionId,
  269. thirdCollectionId: thirdCollectionId,
  270. deviceCode: that.deviceCode, //设备编号
  271. putInCode: that.putInCode, //投放编号
  272. };
  273. this.controller = null;
  274. // 需要图匠校验的添加参数和loading
  275. if (this.photoIdentifyType) {
  276. form.photoIdentifyType = this.photoIdentifyType;
  277. this.progress();
  278. this.controller = new AbortController(); //取消请求
  279. } else {
  280. this.toastLoading(0, '上传中...', true);
  281. }
  282. addstorePhoto(form, this.controller ? this.controller.signal : null)
  283. .then((res) => {
  284. this.toastLoading().clear();
  285. if (res.code == -1) {
  286. // 图匠图片校验接口超时
  287. this.requestTimeOut(res);
  288. } else if (res.code == 200) {
  289. // 图匠校验结果返回
  290. if (this.photoIdentifyType) {
  291. // 重置loaidng状态
  292. this.resetProgress();
  293. this.imageAIVerifyFlag = true;
  294. this.imageAIVerifyData = res.data;
  295. } else {
  296. // 正常流程
  297. this.normalFlow(res);
  298. }
  299. } else {
  300. this.resetProgress();
  301. that.$toast('上传失败!');
  302. }
  303. })
  304. .catch((error) => {
  305. if (error.message === 'canceled') {
  306. this.$toast('取消上传');
  307. console.log('请求被取消:', error.message);
  308. }
  309. this.resetProgress();
  310. });
  311. },
  312. // 正常流程
  313. normalFlow(res) {
  314. this.$toast('上传成功!');
  315. this.$emit('newimgarr', {
  316. fileUrl: res.data.url,
  317. id: res.data.fileId,
  318. type: 2,
  319. photoIdentifyType: this.photoIdentifyType,
  320. });
  321. },
  322. progress() {
  323. // 后端接口20000ms后失效,每1000m progress加10,到90停止;
  324. this.progressFlag = true;
  325. this.percentage = 10;
  326. this.timeFlag = setInterval(() => {
  327. this.percentage = this.percentage + 10;
  328. if (this.percentage == 90) clearInterval(this.timeFlag);
  329. }, 1000);
  330. },
  331. format(percentage) {
  332. return `${percentage} %\n图像识别中`;
  333. },
  334. // 重置loaidng状态
  335. resetProgress() {
  336. this.percentage = 100;
  337. clearInterval(this.timeFlag);
  338. this.progressFlag = false;
  339. this.percentage = 0;
  340. },
  341. // 照片是否入库,1.照片识别三次不通过仍要上传,2.照片识别通过
  342. // isUpdate:是否更新店招照片,只有门店店招需要更新
  343. confirmUpload(res) {
  344. if (this.photoIdentifyType) {
  345. var form = {
  346. mediaId: this.meidaId, // string 图片素材id
  347. visitSource: '1', // Long 拜访模式
  348. storeGroupId: this.storeGroupId, // string 门店任务组,多个用逗号隔开
  349. visitsId: localStorage.getItem('visitId'), // string 拜访id
  350. taskId: this.taskId, // string 任务id
  351. objectType: this.objectType, // string 照片类型,取任务上的照片类型,如果没有则取手动选择的照片类型
  352. locationRemark: this.addressesRemark, // String 当前地址信息
  353. firstCollectionId: this.firstCollectionId, // Long 第一级采集项id,取当前采集项的字段就行
  354. secondCollectionId: this.secondCollectionId, // Long 第二级采集项id,取当前采集项的字段就行
  355. putInCode: this.putInCode, // String 当前任务对应的投放编号
  356. deviceCode: this.deviceCode, // String 当前任务对应的设备编号
  357. collectionItemId: this.collectionId,
  358. url: res.data.url, // String 当前拍摄图片的url
  359. businessId: res.data.businessId, // 当前拍摄图片id
  360. };
  361. if (res.isUpdate) {
  362. form.isUpdate = 'true';
  363. form.feedbackMessage = res.feedbackMessage;
  364. }
  365. addPhotoToDB(form).then((resData) => {
  366. if (resData.code == 200) {
  367. console.log(resData);
  368. res.data.fileId = resData.data.fileId;
  369. this.normalFlow(res);
  370. }
  371. });
  372. }
  373. },
  374. close() {
  375. this.imageAIVerifyFlag = false;
  376. },
  377. requestTimeOut(res) {
  378. this.resetProgress();
  379. this.close();
  380. this.$dialog
  381. .confirm({
  382. title: '系统提示',
  383. message: res.msg,
  384. showCancelButton: false,
  385. })
  386. .then(() => {
  387. this.confirmUpload(res);
  388. });
  389. },
  390. // 取消图片上传
  391. progressClose() {
  392. this.controller.abort();
  393. },
  394. },
  395. };
  396. </script>
  397. <style lang="scss" scoped>
  398. .questionNamep {
  399. font-size: 16px;
  400. color: #484848;
  401. line-height: 40px;
  402. padding: 0 15px;
  403. box-sizing: border-box;
  404. position: relative;
  405. .cameraDivp {
  406. flex: 1;
  407. display: flex;
  408. align-items: center;
  409. justify-content: center;
  410. .photo {
  411. /*margin-top: 9px;*/
  412. float: right;
  413. }
  414. .camera {
  415. width: 60px;
  416. height: 100%;
  417. position: absolute;
  418. right: 0;
  419. top: 0;
  420. opacity: 0;
  421. z-index: 89;
  422. }
  423. }
  424. .mask {
  425. position: fixed;
  426. top: 0;
  427. left: 0;
  428. right: 0;
  429. bottom: 0;
  430. width: 100%;
  431. height: 100%;
  432. background: rgba(255, 255, 255, 1);
  433. display: flex;
  434. justify-content: center;
  435. align-items: center;
  436. z-index: 99999999;
  437. display: flex;
  438. flex-direction: column;
  439. .progressClose {
  440. width: 70px;
  441. text-align: center;
  442. background: #67c23a;
  443. color: #fff;
  444. height: 30px;
  445. line-height: 30px;
  446. border-radius: 5px;
  447. margin-top: 5px;
  448. font-size: 12px;
  449. }
  450. }
  451. }
  452. #allmap {
  453. width: 10px;
  454. height: 10px;
  455. left: -1000px;
  456. position: relative;
  457. }
  458. </style>
  459. <style lang="scss">
  460. .mask {
  461. .el-progress__text {
  462. white-space: pre-wrap;
  463. }
  464. }
  465. </style>