noVisit.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <template>
  2. <div class="noVisit">
  3. <div class="header">
  4. <van-nav-bar class="navBar" title="未拜访门店" left-arrow @click-left="onClickLeft" />
  5. </div>
  6. <div class="content">
  7. <van-collapse v-model="activeName" accordion @change="collapseCange">
  8. <van-collapse-item v-for="(val, ind) in list" :key="ind" :name="val.targetName">
  9. <template #title>
  10. <div class="title">{{ val.targetName }}</div>
  11. <div class="num">{{ val.num }}家</div>
  12. </template>
  13. <div class="itemContent">
  14. <template v-if="val.chainList && val.chainList.length">
  15. <div class="item" v-for="(item, index) in val.chainList" :key="index">
  16. <div class="itemLeft">
  17. <div class="storeName">
  18. {{ item.chainName }}
  19. <span>({{ item.chainCode }})</span>
  20. </div>
  21. <!-- <div class="address">
  22. <van-icon name="location-o" />
  23. {{ item.addressLine }}
  24. </div> -->
  25. <!-- <div class="distance" v-if="item.storeLonExist">
  26. (距离{{ Micrometer(item.distance) }}m)
  27. </div> -->
  28. <div class="bottomBtnBox">
  29. <div class="toVisit" @click="storeVisit(item)">
  30. 进入拜访 <van-icon name="arrow" />
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. </template>
  36. <van-empty description="暂无数据" v-else />
  37. </div>
  38. </van-collapse-item>
  39. </van-collapse>
  40. </div>
  41. </div>
  42. </template>
  43. <script>
  44. import { addVisitsPosition, mobileReposition } from '@/api/index';
  45. import { chainNoVisitList } from '@/api/visitapi';
  46. import { checkChainsAddressByChainCode } from '@/api/agentList';
  47. import { getPosition, getTicketFun } from '@/utils/TXApiFun';
  48. import { mapState } from 'vuex';
  49. import store from '@/store';
  50. export default {
  51. name: 'noVisit',
  52. computed: {
  53. ...mapState({
  54. activaTypeStore: (state) => state.user.activaTypeStore,
  55. }),
  56. },
  57. data() {
  58. return {
  59. activeName: '',
  60. list: {},
  61. TXPiont: {}, //腾讯定位数据
  62. TXisBD: {}, // 腾讯定位数据转百度
  63. activatStoreVal: {}, //当前点击门店数据
  64. clickIsFlage: true,
  65. };
  66. },
  67. created() {
  68. // 授权
  69. getTicketFun().then(() => {
  70. // 获取定位
  71. getPosition()
  72. .then((res) => {
  73. let { TXisBD } = res;
  74. this.getList(TXisBD);
  75. })
  76. .catch((error) => {
  77. this.$dialog.alert({
  78. message: error,
  79. });
  80. });
  81. });
  82. this.activeName = this.activaTypeStore || '';
  83. },
  84. methods: {
  85. collapseCange(value) {
  86. store.dispatch('setActivaTypeStore', value);
  87. },
  88. getList(TXisBD) {
  89. this.toastLoading(0, '加载中...', true);
  90. chainNoVisitList({
  91. lat: TXisBD.lat,
  92. lon: TXisBD.lon,
  93. }).then((res) => {
  94. this.toastLoading().clear();
  95. this.list = res.data;
  96. console.log(this.list);
  97. });
  98. },
  99. tabChange(val) {},
  100. // 进入拜访
  101. storeVisit(val) {
  102. if (!this.clickIsFlage) return;
  103. this.clickIsFlage = false;
  104. this.toastLoading(0, '加载中...', true);
  105. this.activatStoreVal = val;
  106. // 拜访时重新获取定位
  107. getPosition()
  108. .then((res) => {
  109. let { TXisBD, resData } = res;
  110. this.TXisBD = TXisBD;
  111. this.TXPiont = resData;
  112. localStorage.setItem('lat', TXisBD.lat);
  113. localStorage.setItem('lon', TXisBD.lon);
  114. this.checkStoreAddressByStoreCodeFun();
  115. })
  116. .catch((error) => {
  117. this.clickIsFlage = true;
  118. this.$dialog.alert({
  119. message: error,
  120. });
  121. });
  122. },
  123. checkStoreAddressByStoreCodeFun() {
  124. this.toastLoading(0, '加载中...', true);
  125. let PointSumval = this.twoPointSum(
  126. this.TXisBD.lat,
  127. this.TXisBD.lon,
  128. this.TXisBD.lat,
  129. this.TXisBD.lon
  130. ).toFixed(2);
  131. checkChainsAddressByChainCode({
  132. chainId: this.activatStoreVal.chainId,
  133. lon: this.TXisBD.lon,
  134. lat: this.TXisBD.lat,
  135. })
  136. .then((response) => {
  137. this.clickIsFlage = true;
  138. // 门店校验 地址不通过
  139. if (response.code != 200) {
  140. this.toastLoading().clear();
  141. // updateAddress : ,1:同城AB+金牌,去修改地址;2:非金牌店铺,非同城店铺偏差过大不允许拜访,可以重置定位;0非金牌店铺,非同城店铺 位置信息不存在 可以继续拜访
  142. if (response.data) {
  143. if (response.data.updateAddress == 0) {
  144. // 非金牌店铺,非同城店铺 位置信息不存在 可以继续拜访
  145. this.$dialog
  146. .confirm({
  147. confirmButtonText: '确定拜访',
  148. cancelButtonText: '取消拜访',
  149. title: '系统提示',
  150. message:
  151. '该客户没有经纬度,此次拜访会保存定位点作为客户经纬度,下次拜访时判断是否偏差过大。',
  152. closeOnClickOverlay: true,
  153. })
  154. .then(() => {
  155. this.toSuishenbangOutstoreVisit(PointSumval);
  156. });
  157. } else if (response.data.updateAddress == 1) {
  158. // 同城AB+金牌,去修改地址
  159. // addressUpdateTimesOver: true=已经达到最大次数,不让修改; false=没有达到可以修改
  160. if (!response.data.addressUpdateTimesOver) {
  161. this.$dialog
  162. .confirm({
  163. title: '系统提示',
  164. message: response.msg + '请立即修改后再拜访',
  165. messageAlign: 'left',
  166. confirmButtonText: '立即修改',
  167. cancelButtonText: '取消',
  168. })
  169. .then(() => {
  170. this.$router.push({
  171. path: '/storeDetail',
  172. query: {
  173. id: this.activatStoreVal.storeId,
  174. type: 'address',
  175. storeAddressId: this.activatStoreVal.storeAddressId,
  176. },
  177. });
  178. });
  179. } else {
  180. this.$dialog.confirm({
  181. title: '系统提示',
  182. message: '已经达到最大修改次数',
  183. messageAlign: 'left',
  184. confirmButtonText: '确定',
  185. });
  186. }
  187. } else if (response.data.updateAddress == 2) {
  188. // 1.非金牌店铺,非同城店铺 位置偏差过大 重置经纬度
  189. this.resetCoord(PointSumval);
  190. return;
  191. }
  192. } else {
  193. this.$dialog.confirm({
  194. title: '系统提示',
  195. message: response.msg,
  196. showCancelButton: false,
  197. confirmButtonText: '确定',
  198. });
  199. }
  200. } else {
  201. // 门店编码校验门店地址通过 进入拜访
  202. this.toSuishenbangOutstoreVisit(PointSumval);
  203. }
  204. })
  205. .catch((error) => {
  206. this.clickIsFlage = true;
  207. });
  208. },
  209. // 进入拜访
  210. toSuishenbangOutstoreVisit(PointSumval) {
  211. addVisitsPosition({
  212. chainId: this.activatStoreVal.chainId,
  213. visitsId: '',
  214. lon: this.TXPiont.longitude,
  215. lat: this.TXPiont.latitude,
  216. sourceLon: this.TXisBD.lon,
  217. sourceLat: this.TXisBD.lat,
  218. positionDesc: '',
  219. accuracy: this.TXPiont.accuracy,
  220. });
  221. this.clickIsFlage = true;
  222. this.toastLoading().clear();
  223. this.$router.push({
  224. path: '/visitPage',
  225. query: {
  226. typeName2: this.activatStoreVal.typeName2,
  227. chainId: this.activatStoreVal.chainId,
  228. rdId: this.activatStoreVal.rdId,
  229. lat: this.TXisBD.lat,
  230. lon: this.TXisBD.lon,
  231. visitId: this.activatStoreVal.visitId,
  232. pageType: 'out',
  233. addressLine: this.activatStoreVal.addressLine,
  234. storeCategory: this.activatStoreVal.storeCategoryName,
  235. chainName: this.activatStoreVal.chainName,
  236. hisTime: this.activatStoreVal.hisTime,
  237. contactName: this.activatStoreVal.contactName,
  238. chainCode: this.activatStoreVal.chainCode,
  239. visitModel: '1',
  240. latNew: this.TXisBD.lat,
  241. lonNew: this.TXisBD.lon,
  242. PointSum: PointSumval,
  243. marklat: this.TXPiont.latitude,
  244. marklon: this.TXPiont.longitude,
  245. from: 'outPlan',
  246. },
  247. });
  248. },
  249. // 重置经纬度
  250. resetCoord(PointSumval) {
  251. this.$dialog
  252. .confirm({
  253. confirmButtonText: '初始化定位',
  254. cancelButtonText: '取消拜访',
  255. title: '系统提示',
  256. message: '偏差过大,不允许拜访。可修改本店定位.',
  257. closeOnClickOverlay: true,
  258. })
  259. .then(() => {
  260. mobileReposition({
  261. chainId: this.activatStoreVal.chainId,
  262. lat: this.TXisBD.lat,
  263. lon: this.TXisBD.lon,
  264. }).then((response) => {
  265. if (response.code == 200) {
  266. this.$dialog
  267. .alert({
  268. title: '系统提示',
  269. message: '本信息定位已更新成功!',
  270. })
  271. .then(() => {
  272. this.toSuishenbangOutstoreVisit(PointSumval);
  273. });
  274. localStorage.setItem('startTime', new Date());
  275. localStorage.setItem('ORGName', this.activatStoreVal.deptName);
  276. localStorage.setItem('chainNameR', this.activatStoreVal.storeName);
  277. } else {
  278. this.$toast(response.msg);
  279. }
  280. });
  281. });
  282. },
  283. onClickLeft() {
  284. this.$router.go(-1);
  285. },
  286. },
  287. };
  288. </script>
  289. <style lang="scss" scoped>
  290. .noVisit {
  291. height: 100%;
  292. width: 100%;
  293. /* overflow-y: auto; */
  294. .content {
  295. padding: 8px 10px;
  296. .item {
  297. background: #deedff;
  298. padding: 8px;
  299. margin: 10px 0;
  300. border-radius: 5px;
  301. display: flex;
  302. position: relative;
  303. .storeName {
  304. font-size: 15px;
  305. font-weight: bold;
  306. color: #333;
  307. padding: 3px 0;
  308. width: 80%;
  309. }
  310. .address,
  311. .distance {
  312. font-size: 14px;
  313. color: #909090;
  314. padding: 3px 0;
  315. }
  316. .distance {
  317. // padding-left: 12px;
  318. }
  319. .itemLeft {
  320. flex: 1;
  321. .bottomBtnBox {
  322. display: flex;
  323. justify-content: flex-end;
  324. align-items: center;
  325. .toVisit {
  326. height: 32px;
  327. font-size: 15px;
  328. color: #1989fa;
  329. display: flex;
  330. align-items: center;
  331. white-space: nowrap;
  332. }
  333. .joinVisit {
  334. span {
  335. display: inline-block;
  336. border-radius: 20px;
  337. padding: 5px 10px;
  338. background: #1989fa;
  339. color: #fff;
  340. }
  341. }
  342. }
  343. }
  344. .itemRight {
  345. position: absolute;
  346. right: 0;
  347. .statstext {
  348. background-color: #0057ba;
  349. padding: 2px 6px 2px 12px;
  350. border-bottom-left-radius: 60px;
  351. border-top-left-radius: 60px;
  352. color: #fff;
  353. width: 60px;
  354. // margin-right: -8px;
  355. /* overflow: hidden; */
  356. white-space: nowrap;
  357. .van-icon__image {
  358. height: 0.7em;
  359. }
  360. }
  361. }
  362. }
  363. }
  364. .van-collapse-item {
  365. border-bottom: 1px solid #dcdcdc;
  366. }
  367. }
  368. </style>
  369. <style lang="scss">
  370. .noVisit {
  371. .van-cell__title {
  372. font-size: 15px;
  373. font-weight: bold;
  374. color: #333;
  375. display: flex;
  376. justify-content: space-between;
  377. .num {
  378. color: #909090;
  379. margin-right: 5px;
  380. }
  381. }
  382. .van-collapse-item__wrapper {
  383. border-top: 1px solid #dcdcdc;
  384. }
  385. .van-collapse-item__title--expanded {
  386. position: sticky;
  387. top: 0px;
  388. z-index: 10;
  389. }
  390. }
  391. </style>