index.vue 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875
  1. <template>
  2. <div class="bgcolor deviceWithin">
  3. <div class="navBarTOP">
  4. <!-- 顶部条-->
  5. <van-nav-bar class="navBar" title="计划内">
  6. <template #right>
  7. <span @click="searchFn">筛选<van-icon name="arrow-down" /></span>
  8. </template>
  9. </van-nav-bar>
  10. <div class="searchDiv">
  11. <van-search
  12. v-model="storeName"
  13. left-icon="search"
  14. show-action
  15. placeholder="搜索名称/编号/地址">
  16. <template #action>
  17. <div @click="onSearch">搜索</div>
  18. </template>
  19. </van-search>
  20. </div>
  21. <!-- 隐藏高销额门店入口 -->
  22. <!-- <div style="background-color: #dfebf4; padding: 10px" v-if="mapShows">
  23. <div
  24. style="
  25. font-size: 16px;
  26. text-align: center;
  27. margin: 0 auto;
  28. width: 150px;
  29. text-decoration: underline;
  30. font-weight: bold;
  31. color: #222;
  32. "
  33. @click="goFn(1)">
  34. <img
  35. src="./../../assets/Icon/clcik.png"
  36. style="width: 22px; float: left; display: inline-block" />高销额门店推荐
  37. </div>
  38. <van-button
  39. round
  40. type="info"
  41. size="small"
  42. style="position: absolute; top: 108px; right: 10px; height: 28px"
  43. @click="goFn(1)"
  44. >去查看<van-icon name="arrow"
  45. /></van-button>
  46. </div> -->
  47. <div class="monthNow" v-show="calendarIsshow == false">
  48. <span class="month" @click="show = true">{{ timeData }}</span>
  49. <van-icon class="CalendarIcon" :name="timeico" @click="show = true" />
  50. </div>
  51. </div>
  52. <!-- 主体内容-->
  53. <div class="container content" style="margin-top: 145px" @touchmove="handleTouch">
  54. <div class="cellcontent" v-for="(item, index) in list" :key="index">
  55. <van-cell>
  56. <div class="card">
  57. <div class="title">
  58. <template v-if="item.storeLabels">
  59. <!-- 金牌店ABC -->
  60. <img
  61. class="JPABC"
  62. :src="require('@/assets/Icon/storeA.png')"
  63. v-if="item.storeLabels.storeA" />
  64. <img
  65. class="JPABC"
  66. :src="require('@/assets/Icon/storeB.png')"
  67. v-if="item.storeLabels.storeB" />
  68. <img
  69. class="JPABC"
  70. :src="require('@/assets/Icon/storeC.png')"
  71. v-if="item.storeLabels.storeC" />
  72. <img
  73. class="JPABC"
  74. :src="require('@/assets/Icon/storeD.png')"
  75. v-if="item.storeLabels.storeD" />
  76. <img
  77. class="JPABC"
  78. :src="require('@/assets/Icon/storeE.png')"
  79. v-if="item.storeLabels.storeE" />
  80. </template>
  81. <span @click="goOtherSystem(item)" :style="setStroeNameStyle(item)">
  82. <span>{{ item.storeName }}</span>
  83. (<span>{{ item.storeCode }}</span
  84. >)
  85. </span>
  86. <span class="btn" :data-clipboard-text="item.storeCode">
  87. <van-icon
  88. :name="paste"
  89. color="#ee0a24"
  90. size="20"
  91. style="top: 6px; margin-left: 4px" />
  92. </span>
  93. <!-- "approvalStatus": 1:已结案;0:未结案, -->
  94. <!-- "processApprovalStatus": 审批状态(0=未提交,1=已提交待审核,2=审批通过,3=审批拒绝) -->
  95. <template v-if="item.approvalStatus == 0">
  96. <span class="statusIcon submit" v-if="item.processApprovalStatus == 1">已提交</span>
  97. <span class="statusIcon noSubmit" v-if="item.processApprovalStatus == 0"
  98. >未提交</span
  99. >
  100. </template>
  101. </div>
  102. <div class="info">
  103. 类型:{{ item.storeCategory }} &nbsp;
  104. <!-- <el-popover popper-class="zpover zpover6" placement="bottom-start" trigger="click">
  105. <div>
  106. <p>
  107. 本店经营品项指导:
  108. <a @click="linkimg(item)" style="text-decoration: underline">点击查看</a>
  109. </p>
  110. </div>
  111. <van-icon name="question-o" size="18" slot="reference" />
  112. </el-popover> -->
  113. </div>
  114. <div class="info" style="position: relative">
  115. 联系人:{{ item.contactName }}
  116. <div style="position: absolute; bottom: 0; right: 14px">
  117. <!-- 是否终端客户 -->
  118. <el-popover
  119. popper-class="zpover"
  120. placement="bottom"
  121. width="120"
  122. trigger="click"
  123. disabled>
  124. <div
  125. v-if="item.storeLabels.terminalCustomer"
  126. class="visitStoreIco"
  127. style="background-color: #fff"
  128. slot="reference">
  129. <van-icon :name="require('@/assets/Icon/zhongduankehu.png')" size="26" />
  130. </div>
  131. </el-popover>
  132. <!-- 是否双包客户 -->
  133. <el-popover
  134. popper-class="zpover poperWidthAuto"
  135. placement="bottom"
  136. width="120"
  137. trigger="click"
  138. :content="item.storeLabels.doubleCustomer">
  139. <div
  140. v-if="item.storeLabels.doubleCustomer"
  141. class="visitStoreIco"
  142. style="background-color: #fff"
  143. slot="reference">
  144. <van-icon :name="require('@/assets/Icon/shuangbaokehu.png')" size="26" />
  145. </div>
  146. </el-popover>
  147. <!-- 工企标签 -->
  148. <el-popover
  149. popper-class="zpover poperWidthAuto"
  150. placement="bottom"
  151. width="120"
  152. trigger="click"
  153. :content="item.storeLabels.industrialEnterprises">
  154. <div
  155. v-if="item.storeLabels.industrialEnterprises"
  156. class="visitStoreIco"
  157. style="background-color: #fff"
  158. slot="reference">
  159. <van-icon :name="require('@/assets/Icon/qiye.png')" size="26" />
  160. </div>
  161. </el-popover>
  162. <!-- 商住标签 -->
  163. <el-popover
  164. popper-class="zpover poperWidthAuto"
  165. placement="bottom"
  166. width="120"
  167. trigger="click"
  168. :content="item.storeLabels.commercialResidential">
  169. <div
  170. v-if="item.storeLabels.commercialResidential"
  171. class="visitStoreIco"
  172. style="background-color: #fff"
  173. slot="reference">
  174. <van-icon :name="require('@/assets/Icon/shangye.png')" size="26" />
  175. </div>
  176. </el-popover>
  177. <!-- 市政工程标签 -->
  178. <el-popover
  179. popper-class="zpover poperWidthAuto"
  180. placement="bottom"
  181. width="120"
  182. trigger="click"
  183. :content="item.storeLabels.municipalEngineering">
  184. <div
  185. v-if="item.storeLabels.municipalEngineering"
  186. class="visitStoreIco"
  187. style="background-color: #fff"
  188. slot="reference">
  189. <van-icon :name="require('@/assets/Icon/shizheng.png')" size="26" />
  190. </div>
  191. </el-popover>
  192. <el-popover
  193. popper-class="zpover"
  194. placement="bottom"
  195. width="120"
  196. trigger="click"
  197. content="该客户为凤凰客户">
  198. <div
  199. v-if="item.storeLabels.fhCustomer"
  200. class="visitStoreIco"
  201. style="background-color: #fff"
  202. slot="reference">
  203. <van-icon :name="require('@/assets/Icon/fenghuangjihua.png')" size="26" />
  204. </div>
  205. </el-popover>
  206. <el-popover popper-class="zpover zpover6" placement="bottom-start" trigger="click">
  207. <div>
  208. <p>
  209. 本店{{ timeData1 }}下单SKU数:<a
  210. @click="linkList(item)"
  211. style="text-decoration: underline"
  212. >点击查看详情</a
  213. >
  214. </p>
  215. </div>
  216. <div
  217. class="visitStoreIco"
  218. v-if="item.storeLabels.zysslNums !== false"
  219. style="background-color: #fff; position: relative"
  220. slot="reference">
  221. <p
  222. style="
  223. width: 100%;
  224. position: absolute;
  225. z-index: 1;
  226. top: 0.2px;
  227. width: 22px;
  228. margin: 0;
  229. margin-left: 3.6px;
  230. text-align: center;
  231. font-size: 12px;
  232. ">
  233. {{ item.storeLabels.zysslNums }}
  234. </p>
  235. <van-icon :name="ord" size="26" />
  236. </div>
  237. </el-popover>
  238. <el-popover popper-class="zpover" placement="bottom" width="200" trigger="click">
  239. <div v-if="item.storeLabels">
  240. <p>已参加:</p>
  241. <p v-for="tt in (item.storeLabels.targetOne + '').split(';')">
  242. {{ tt }}
  243. </p>
  244. </div>
  245. <div
  246. class="visitStoreIco"
  247. v-if="item.storeLabels.targetOne"
  248. style="background-color: #fff"
  249. slot="reference">
  250. <van-icon :name="targetOne" size="26" />
  251. </div>
  252. </el-popover>
  253. <el-popover
  254. popper-class="zpover"
  255. placement="bottom"
  256. width="120"
  257. trigger="click"
  258. content="调色机7天未调色">
  259. <div
  260. v-if="item.storeLabels.stopColorMixerSeven"
  261. class="visitStoreIco"
  262. style="background-color: #fff"
  263. slot="reference">
  264. <van-icon :name="Network" size="26" />
  265. </div>
  266. </el-popover>
  267. <el-popover
  268. popper-class="zpover"
  269. placement="bottom"
  270. width="120"
  271. trigger="click"
  272. content="调色机当月未调色">
  273. <div
  274. v-if="item.storeLabels.stopColorMixerMonth"
  275. class="visitStoreIco"
  276. style="background-color: #fff"
  277. slot="reference">
  278. <van-icon :name="WiFi" size="26" />
  279. </div>
  280. </el-popover>
  281. <el-popover
  282. popper-class="zpover"
  283. placement="bottom"
  284. width="200"
  285. trigger="click"
  286. content="同城店近60天未下单">
  287. <div
  288. v-if="item.storeLabels.fxNoOrder"
  289. class="visitStoreIco"
  290. style="background-color: #fff"
  291. slot="reference">
  292. <van-icon :name="order60" size="26" />
  293. </div>
  294. </el-popover>
  295. <el-popover
  296. popper-class="zpover"
  297. placement="bottom"
  298. width="200"
  299. trigger="click"
  300. content="金牌店近30天未下单">
  301. <div
  302. v-if="item.storeLabels.noOrder"
  303. class="visitStoreIco"
  304. style="background-color: #fff"
  305. slot="reference">
  306. <van-icon :name="order" size="26" />
  307. </div>
  308. </el-popover>
  309. <el-popover
  310. popper-class="zpover"
  311. placement="bottom"
  312. width="200"
  313. trigger="click"
  314. content="本店本月进过专业时时丽">
  315. <div
  316. v-if="item.storeLabels.zyssl"
  317. class="visitStoreIco"
  318. style="background-color: #ed5c68"
  319. slot="reference">
  320. </div>
  321. </el-popover>
  322. <el-popover
  323. popper-class="zpover zpover1"
  324. placement="bottom"
  325. width="200"
  326. trigger="click"
  327. content="本店本月进过超好贴">
  328. <div
  329. v-if="item.storeLabels.chtczj"
  330. class="visitStoreIco"
  331. style="background-color: #0057ba"
  332. slot="reference">
  333. </div>
  334. </el-popover>
  335. <el-popover
  336. placement="bottom"
  337. popper-class="zpover zpover1 zpover1sb"
  338. trigger="click"
  339. :disabled="!item.userVisitTimesMap"
  340. :content="'本店本月已拜访过' + item.storeLabels.visitTimes + '次'">
  341. <div
  342. v-if="item.storeLabels.visitTimes && item.storeLabels.visitTimes > 0"
  343. class="visitStoreIco"
  344. slot="reference"
  345. style="background-color: #fff; position: relative">
  346. <p
  347. style="
  348. width: 100%;
  349. position: absolute;
  350. z-index: 10;
  351. top: -2px;
  352. margin: 0;
  353. text-align: center;
  354. font-size: 12px;
  355. ">
  356. {{ item.storeLabels.visitTimes }}
  357. </p>
  358. <!-- A级金牌店拜访次数少于2 -->
  359. <van-icon
  360. :name="require('@/assets/ordernumRed.png')"
  361. size="26"
  362. v-if="
  363. item.storeLabels.storeA &&
  364. item.needVisitNum &&
  365. item.storeLabels.visitTimes < item.needVisitNum
  366. " />
  367. <van-icon :name="require('@/assets/ordernum.png')" size="26" v-else />
  368. </div>
  369. <p style="text-align: center; background: #fff; color: #000; padding: 5px 0">
  370. 本店本月已拜访过{{ item.storeLabels.visitTimes }}次
  371. </p>
  372. <p
  373. v-if="item.storeLabels.storeA && item.needVisitNum"
  374. style="text-align: center; background: #fff; color: red; padding: 5px 0">
  375. A级金牌店拜访标准:1月{{ item.needVisitNum }}次
  376. </p>
  377. <el-table :data="item.userVisitTimesMap" border max-height="180px">
  378. <el-table-column label="业务员" prop="userName" />
  379. <el-table-column label="拜访次数" prop="visitTimes" width="110px" />
  380. </el-table>
  381. </el-popover>
  382. </div>
  383. </div>
  384. <div class="info" v-if="item.telephone" @click="buryingPointFn(item)">
  385. 联系电话:<a
  386. style="color: #0057ba; font-weight: bold; text-decoration: underline"
  387. :href="'tel:' + item.telephone"
  388. >{{ item.telephone }}<van-icon name="phone"
  389. /></a>
  390. </div>
  391. <div class="info" v-if="item.addressLine">
  392. 地址:{{ item.addressLine
  393. }}<img
  394. v-if="item.storeLonExist"
  395. style="width: 36px"
  396. :src="sbpmdh"
  397. @click="linkapp(item)" />
  398. </div>
  399. <!-- 潜在店不显示经销商 -->
  400. <template v-if="item.sfaStoreType.type != 'qzd'">
  401. <!-- 分销店 -->
  402. <template
  403. v-if="
  404. item.sfaStoreType &&
  405. item.sfaStoreType.type == 'fxd' &&
  406. item.sfaStoreChainsContactList
  407. ">
  408. <div class="info" v-if="typeShow">
  409. 经销商:
  410. <div class="TCFXListItem" v-for="(item, index) in item.sfaStoreChainsContactList">
  411. <el-popover
  412. popper-class="zpover zpoverStoreztype"
  413. placement="bottom-start"
  414. trigger="click">
  415. <div>
  416. <div>{{ item.chainCode }}</div>
  417. <div>{{ item.chainName }}</div>
  418. </div>
  419. <div slot="reference" :key="index">
  420. {{ item.categoryDescribe }}
  421. </div>
  422. </el-popover>
  423. </div>
  424. </div>
  425. </template>
  426. <template v-else>
  427. <div class="info" v-if="typeShow">经销商:{{ item.chainName }}</div>
  428. </template>
  429. </template>
  430. <!-- storeLonExist 门店是否存在经纬度 字段false=不显示导航和距离,true=显示 -->
  431. <div class="info" v-if="item.storeLonExist">距离:{{ Micrometer(item.distance) }}m</div>
  432. <div class="info" v-if="item.cntOrderAmtYear">
  433. 门店销额(全年累计):{{ Micrometer(item.cntOrderAmtYear) }}元
  434. </div>
  435. </div>
  436. <div
  437. class="statstext"
  438. v-if="item.stateString == '未拜访'"
  439. style="background-color: #ed5c68">
  440. 未拜访
  441. </div>
  442. <div
  443. class="statstext"
  444. v-if="item.stateString == '拜访中'"
  445. style="background-color: white">
  446. <van-icon :name="times" color="#ee0a24" size="32" />
  447. </div>
  448. <div class="statstext" v-if="item.stateString == '已拜访'">已拜访</div>
  449. <div class="btnbox">
  450. <van-row>
  451. <van-col
  452. span="4"
  453. v-if="item.stateString != '已拜访' && item.visitAble && customerVisits"
  454. @click="storeVisit(item)">
  455. <img :src="call" style="margin: 0 auto; height: 15px; display: block" />
  456. <p style="text-align: center; margin: 0; font-size: 11px">进入拜访</p>
  457. </van-col>
  458. <van-col
  459. span="4"
  460. v-if="item.storeCategory == '公装经销商'"
  461. @click="projectOutVisit(item)">
  462. <img :src="xmgj" style="margin: 0 auto; height: 15px; display: block" />
  463. <p style="text-align: center; margin: 0; font-size: 11px">项目跟进</p>
  464. </van-col>
  465. <van-col
  466. span="4"
  467. v-if="
  468. item.stateString != '已拜访' &&
  469. item.visitAble &&
  470. item.storeCategory != '公装经销商' &&
  471. customerVisits
  472. "
  473. @click="abnormalVisit(item)">
  474. <img :src="yichang" style="margin: 0 auto; height: 15px; display: block" />
  475. <p style="text-align: center; margin: 0; margin-top: 1px; font-size: 11px">
  476. 异常拜访
  477. </p>
  478. </van-col>
  479. <van-col span="4" v-if="item.storeLabels.zysslNums !== false" @click="linkList(item)">
  480. <img
  481. :src="require('@/assets/recommendicon.png')"
  482. style="margin: 0 auto; height: 15px; display: block" />
  483. <p style="text-align: center; margin: 0; margin-top: 1px; font-size: 11px">
  484. 推荐下单
  485. </p>
  486. </van-col>
  487. <van-col span="4" v-else-if="item.showOrderButton" @click="orderFn(item)">
  488. <img :src="xiadan" style="margin: 0 auto; height: 15px; display: block" />
  489. <p style="text-align: center; margin: 0; margin-top: 1px; font-size: 11px">
  490. 去下单
  491. </p>
  492. </van-col>
  493. <van-col span="4" v-if="item.stateString == '已拜访'" @click="Visit(item)">
  494. <img :src="bfxx" style="margin: 0 auto; height: 15px; display: block" />
  495. <p style="text-align: center; margin: 0; margin-top: 1px; font-size: 11px">
  496. 拜访信息
  497. </p>
  498. </van-col>
  499. <van-col span="4" @click="visitFn(item)">
  500. <img :src="kehuxinxi" style="margin: 0 auto; height: 15px; display: block" />
  501. <p style="text-align: center; margin: 0; margin-top: 1px; font-size: 11px">
  502. 客户信息
  503. </p>
  504. </van-col>
  505. </van-row>
  506. </div>
  507. </van-cell>
  508. <div class="lineGrey"></div>
  509. </div>
  510. <p style="text-align: center; color: #888a8e" v-if="list.length > 0">--已经到底了--</p>
  511. <br />
  512. <van-empty description="暂无数据" v-if="list.length == 0" />
  513. </div>
  514. <van-popup v-model="show" position="bottom" :style="{ height: '50%' }">
  515. <van-datetime-picker
  516. v-model="currentDate"
  517. type="date"
  518. title="计划日期"
  519. :min-date="minDate"
  520. :max-date="maxDate"
  521. @confirm="dateeconfirm"
  522. @cancel="show = false" />
  523. </van-popup>
  524. <!-- 筛选模块 -->
  525. <filtrate v-show="showFilter" :showFilter="showFilter" @closePopup="closePopup"></filtrate>
  526. <tab-bar tabBarActive="deviceWithin"></tab-bar>
  527. </div>
  528. </template>
  529. <script>
  530. import Network from '@/assets/Network.png';
  531. import WiFi from '@/assets/WiFi.png';
  532. import tabBar from '@/components/tabBar';
  533. import times from '@/assets/Icon/times.png';
  534. import order60 from '@/assets/order60.png';
  535. import targetOne from '@/assets/targetOne.png';
  536. import visitTimes from '@/assets/visitTimes.png';
  537. import ord from '@/assets/ord.png';
  538. import timeico from '@/assets/Icon/datatims.png';
  539. import sbpmdh from '@/assets/sbpmdh.png';
  540. import {
  541. getUserInPlanList,
  542. checkVisit,
  543. addVisitsPosition,
  544. mobileReposition,
  545. buryingPoint,
  546. ProductItemImge,
  547. } from '@/api/index';
  548. import axios from 'axios';
  549. import paste from '@/assets/paste.png';
  550. import order from '@/assets/order.png';
  551. import call from '@/assets/call.png';
  552. import jiarujihua from '@/assets/jiarujihua.png';
  553. import kehuxinxi from '@/assets/kehuxinxi-2.png';
  554. import xiadan from '@/assets/xiadan.png';
  555. import yichang from '@/assets/yichang.png';
  556. import bfxx from '@/assets/bfxx.png';
  557. import xmgj from '@/assets/xmgj.png';
  558. import { getOrderUrlByStoreId } from '@/api/inventory';
  559. import { checkStoreAddressByStoreCode } from '@/api/visitstore';
  560. import { getPosition, getTicketFun } from '@/utils/TXApiFun';
  561. import filtrate from '@/components/filtrate';
  562. export default {
  563. name: 'deviceWithin',
  564. components: { tabBar, filtrate },
  565. data() {
  566. return {
  567. Network: Network,
  568. WiFi: WiFi,
  569. xmgj: xmgj,
  570. bfxx: bfxx,
  571. yichang: yichang,
  572. xiadan: xiadan,
  573. kehuxinxi: kehuxinxi,
  574. jiarujihua: jiarujihua,
  575. call: call,
  576. times: times,
  577. timeico: timeico,
  578. order60: order60,
  579. sbpmdh: sbpmdh,
  580. ord: ord,
  581. timeData1: '',
  582. targetOne: targetOne,
  583. paste: paste,
  584. visitTimess: visitTimes,
  585. show: false,
  586. cont: 0,
  587. timer: null,
  588. flag: true,
  589. order: order,
  590. defaultDate: new Date(),
  591. minDate: new Date(2020, 0, 1),
  592. // maxDate: new Date(2025, 10, 1),
  593. showPopoverVNUM: [],
  594. showPopoverC: [],
  595. showPopoverZ: [],
  596. currentDate: new Date(),
  597. searchValue: '',
  598. calendarIsshow: false,
  599. tabVal: 'insidePlan',
  600. list: [],
  601. loading: false,
  602. finished: false,
  603. mapShows: false,
  604. typeShow: false,
  605. storeName: '',
  606. timeData: '',
  607. genDate: '',
  608. listActive: null,
  609. query: '',
  610. lat: '',
  611. lon: '',
  612. storeType: '',
  613. endShow: false,
  614. visitEndId: '',
  615. customerVisits: true,
  616. // 筛选模块
  617. showFilter: false,
  618. filterParams: {},
  619. };
  620. },
  621. computed: {
  622. /**
  623. * 计算最大可选日期:当前日期往后推30天
  624. */
  625. maxDate() {
  626. const today = new Date();
  627. const maxYear = today.getFullYear();
  628. const maxMonth = today.getMonth();
  629. const maxDay = today.getDate() + 30;
  630. return new Date(maxYear, maxMonth, maxDay);
  631. },
  632. },
  633. watch: {
  634. $route(to, from) {
  635. if (from.path == '/deviceWithin/index' && to.path == '/storeVisitpage') {
  636. localStorage.setItem('startTime', new Date());
  637. }
  638. },
  639. },
  640. activated() {
  641. this.query = this.$route.query;
  642. this.timeData = this.parseTime(new Date(), '{yy}-{mm}-{dd}');
  643. this.storeName = localStorage.getItem('deviveStoreName');
  644. this.getMonth();
  645. // 授权
  646. getTicketFun().then(() => {
  647. this.getUserInPlanList();
  648. });
  649. },
  650. mounted() {
  651. // 解决iOS 上拉边界下拉出现白色空白
  652. let node = document.getElementsByClassName('deviceWithin')[0];
  653. node.addEventListener(
  654. 'touchmove',
  655. (e) => {
  656. if (e._isScroller) return;
  657. e.preventDefault();
  658. },
  659. {
  660. passive: false,
  661. },
  662. );
  663. },
  664. methods: {
  665. closePopup(flag, filterParams) {
  666. this.showFilter = false;
  667. if (flag) {
  668. this.filterParams = filterParams;
  669. this.onSearch();
  670. }
  671. },
  672. searchFn() {
  673. this.showFilter = true;
  674. },
  675. handleTouch(e) {
  676. e._isScroller = true;
  677. },
  678. linkapp(val) {
  679. var poind = this.gcj02BD(val.lat, val.lon);
  680. let url = window.location.href;
  681. let that = this;
  682. let wx = this.wx;
  683. let qiyeData;
  684. const instance = axios.create();
  685. instance.defaults.headers.common['userId'] = localStorage.getItem('loginName');
  686. instance
  687. .get(process.env.VUE_APP_BASE_API + 'mobile/wx/ticket', {
  688. params: {
  689. url: url,
  690. agent: 1,
  691. },
  692. })
  693. .then((response) => {
  694. if (response.status == 200) {
  695. qiyeData = response.data.data;
  696. wx.agentConfig({
  697. corpid: qiyeData.appId, // 必填,企业微信的corpid,必须与当前登录的企业一致
  698. agentid: qiyeData.agentId, // 必填,企业微信的应用id (e.g. 1000247)
  699. timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
  700. nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
  701. signature: qiyeData.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
  702. jsApiList: ['launchMiniprogram'], //必填,传入需要使用的接口名称
  703. success: function (res) {
  704. wx.invoke(
  705. 'launchMiniprogram',
  706. {
  707. appid: 'wx238bbb5f6d958414',
  708. path:
  709. 'pages/relayStation/relayStation?latitude=' +
  710. poind.lat +
  711. '&longitude=' +
  712. poind.lon +
  713. '&name=' +
  714. val.addressLine,
  715. },
  716. function (res) {
  717. if (res.err_msg == 'launchMiniprogram:ok') {
  718. } else {
  719. }
  720. },
  721. );
  722. },
  723. fail: function (res) {
  724. if (res.errMsg.indexOf('function not exist') > -1) {
  725. alert('版本过低请升级');
  726. }
  727. },
  728. });
  729. }
  730. });
  731. },
  732. orderFn(val) {
  733. buryingPoint({
  734. systemModel: '计划内',
  735. buryingPointType: 1,
  736. buryingPointValue: val.storeName + '(' + val.storeCode + ')',
  737. buryingPointName: '去下单',
  738. buryingPointPosition: '计划内',
  739. });
  740. getOrderUrlByStoreId({
  741. storeId: val.storeId,
  742. from: 'inPlan',
  743. }).then((res) => {
  744. if (res.code == 200 && res.data) {
  745. window.location.href = res.data;
  746. } else {
  747. this.Toast({
  748. message: res.msg,
  749. duration: 5000,
  750. });
  751. }
  752. });
  753. },
  754. linkList(val) {
  755. buryingPoint({
  756. systemModel: '计划内',
  757. buryingPointType: 1,
  758. buryingPointValue: val.storeName + '(' + val.storeCode + ')',
  759. buryingPointName: '推荐下单',
  760. buryingPointPosition: '计划内',
  761. });
  762. this.$router.push({
  763. path: '/pItem',
  764. query: {
  765. id: val.storeId,
  766. detilId: 'a',
  767. from: 'inPlan',
  768. storeCode: val.storeCode,
  769. storeName: val.storeName,
  770. showOrderButton: val.showOrderButton,
  771. },
  772. });
  773. },
  774. linkimg(val) {
  775. ProductItemImge({ storeId: val.storeId }).then((response) => {
  776. if (response.code == 200) {
  777. if (response.data != undefined) {
  778. window.open(response.data);
  779. } else {
  780. this.$toast(response.msg);
  781. }
  782. } else {
  783. this.$dialog.alert({
  784. title: '系统提示',
  785. message: res.msg,
  786. });
  787. }
  788. });
  789. },
  790. getMonth() {
  791. // 获取当前日期
  792. var currentDate = new Date();
  793. // 获取当前月份
  794. var currentMonth = currentDate.getMonth();
  795. // 获取当前年份
  796. // var currentYear = currentDate.getFullYear();
  797. var previousMonthDate1 = new Date();
  798. if (currentDate.getDate() == 1) {
  799. previousMonthDate1.setMonth(currentMonth - 1);
  800. } else {
  801. }
  802. var previousMonth1 = previousMonthDate1.getMonth();
  803. var previousYear1 = previousMonthDate1.getFullYear();
  804. // 计算前三个月的年份和月份
  805. var previousMonthDate = new Date();
  806. if (currentDate.getDate() == 1) {
  807. previousMonthDate.setMonth(currentMonth - 3);
  808. } else {
  809. previousMonthDate.setMonth(currentMonth - 2);
  810. }
  811. 1;
  812. var previousMonth = previousMonthDate.getMonth();
  813. var previousYear = previousMonthDate.getFullYear();
  814. //前三个月
  815. if (previousYear1 == previousYear) {
  816. var formattedPreviousMonth1 = previousYear1 + '-' + (previousMonth1 + 1);
  817. // 格式化年份和月份
  818. var formattedPreviousMonth = previousYear + '-' + (previousMonth + 1);
  819. this.timeData1 =
  820. formattedPreviousMonth.split('-')[1] + '-' + formattedPreviousMonth1.split('-')[1] + '月';
  821. } else {
  822. var formattedPreviousMonth1 = previousYear1 + '年' + (previousMonth1 + 1) + '月';
  823. // .toString().padStart(2, '0');
  824. // 格式化年份和月份
  825. var formattedPreviousMonth = previousYear + '年' + (previousMonth + 1) + '月';
  826. this.timeData1 = formattedPreviousMonth + '-' + formattedPreviousMonth1;
  827. }
  828. },
  829. Visit(val) {
  830. this.$router.push({
  831. path: '/historicalDetails',
  832. query: {
  833. visitId: val.visitId,
  834. storeId: val.storeId,
  835. storeCode: val.storeCode,
  836. },
  837. });
  838. },
  839. dateeconfirm() {
  840. this.show = false;
  841. this.genDate = this.parseTime(this.currentDate, '{yy}-{mm}-{dd}');
  842. this.timeData = this.parseTime(this.currentDate, '{yy}-{mm}-{dd}');
  843. this.getUserInPlanList();
  844. },
  845. dataFn() {
  846. this.genDate = this.parseTime(new Date(), '{yy}-{mm}-{dd}');
  847. this.timeData = this.parseTime(new Date(), '{yy}-{mm}-{dd}');
  848. this.getUserInPlanList();
  849. },
  850. buryingPointFn(val) {
  851. buryingPoint({
  852. systemModel: '计划内',
  853. buryingPointType: 1,
  854. buryingPointValue: val.telephone,
  855. buryingPointName: '点击电话',
  856. buryingPointPosition: val.storeName + '(' + val.storeCode + ')',
  857. });
  858. },
  859. getUserInPlanList() {
  860. localStorage.setItem('outvstoreName', '');
  861. localStorage.setItem('outvchainName', '');
  862. localStorage.removeItem('outvstoreLabelTypes');
  863. localStorage.removeItem('outvstoreCategoryList');
  864. localStorage.setItem('outvchainCode', '');
  865. localStorage.setItem('outvstoreName', '');
  866. localStorage.setItem('outvsortType', '');
  867. localStorage.setItem('outsortParam', '');
  868. localStorage.setItem('lat', '');
  869. localStorage.setItem('lon', '');
  870. this.list = [];
  871. var postType = localStorage.getItem('postType');
  872. this.customerVisits = localStorage.getItem('customerVisits');
  873. if (localStorage.getItem('postType') == 'JZ' || localStorage.getItem('postType') == 'GZ') {
  874. this.mapShows = false;
  875. } else {
  876. this.mapShows = true;
  877. }
  878. if (postType == 'GZ') {
  879. this.typeShow = false;
  880. } else {
  881. this.typeShow = true;
  882. }
  883. this.storeType = localStorage.getItem('storeType');
  884. this.endShow = false;
  885. this.toastLoading(0, '加载中...', true);
  886. localStorage.removeItem('visitId');
  887. getPosition(true, true)
  888. .then((res) => {
  889. let { TXisBD } = res;
  890. this.getUserInPlanListFun(TXisBD);
  891. })
  892. .catch((error) => {
  893. this.getUserInPlanListFun();
  894. // this.$dialog.alert({
  895. // message: error,
  896. // });
  897. });
  898. },
  899. getUserInPlanListFun(TXisBD) {
  900. getUserInPlanList({
  901. storeName: this.storeName.trim(),
  902. genDate: this.genDate,
  903. lat: TXisBD ? TXisBD.lat : '',
  904. lon: TXisBD ? TXisBD.lon : '',
  905. ...this.filterParams,
  906. }).then((res) => {
  907. this.toastLoading().clear();
  908. if (res.code == 200) {
  909. this.list = res.data;
  910. this.list.forEach((item) => {
  911. if (item.stateString.indexOf('拜访中') != -1) {
  912. this.endShow = true;
  913. this.visitEndId = item.visitId;
  914. return;
  915. }
  916. });
  917. } else {
  918. this.$toast.fail(res.msg);
  919. }
  920. });
  921. },
  922. storeVisit(val) {
  923. if (val.visitSource && val.visitSource == 2) {
  924. this.$toast('请先取消异常拜访后再进入正常拜访!');
  925. return;
  926. }
  927. var that = this;
  928. localStorage.removeItem('visitId');
  929. checkVisit({ storeId: val.storeId }).then((res) => {
  930. // buryingPoint({
  931. // systemModel: '计划内',
  932. // buryingPointType: 1,
  933. // buryingPointValue: val.storeName + '(' + val.storeCode + ')',
  934. // buryingPointName: '进店拜访',
  935. // buryingPointPosition: '计划内',
  936. // });
  937. if (res.code == 200 || val.stateString.indexOf('拜访中') != -1) {
  938. if (localStorage.getItem('loginType') == 'cs') {
  939. var lat = '';
  940. var lon = '';
  941. if (val.lat == '' || val.lat == null) {
  942. lat = '31.2517820000';
  943. lon = '120.5593090000';
  944. } else {
  945. lat = val.lat;
  946. lon = val.lon;
  947. }
  948. this.$router.push({
  949. path: '/storeVisitpage',
  950. query: {
  951. storeId: val.storeId,
  952. rdId: val.rdId,
  953. lat: lat,
  954. lon: lon,
  955. visitId: val.visitId,
  956. pageType: 'out',
  957. addressLine: val.addressLine,
  958. storeCategory: val.storeCategory,
  959. storeName: val.storeName,
  960. hisTime: val.hisTime,
  961. contactName: val.contactName,
  962. storeCode: val.storeCode,
  963. tabVal: this.tabVal,
  964. visitModel: '1',
  965. latNew: '31.2517820000',
  966. lonNew: '120.5593090000',
  967. PointSum: 0,
  968. marklat: lat,
  969. marklon: lon,
  970. from: 'inPlan',
  971. },
  972. });
  973. localStorage.setItem('startTime', new Date());
  974. localStorage.setItem('ORGName', val.deptName);
  975. localStorage.setItem('chainNameR', val.storeName);
  976. } else {
  977. if (that.flag) {
  978. that.flag = false;
  979. that.timer = null;
  980. that.timer = setTimeout(() => {
  981. that.flag = true;
  982. }, 2000);
  983. if (val.stateString.indexOf('拜访中') != -1) {
  984. that.$router.push({
  985. path: '/storeVisitpage',
  986. query: {
  987. storeId: val.storeId,
  988. rdId: val.rdId,
  989. lat: val.lat,
  990. lon: val.lon,
  991. visitId: val.visitId,
  992. addressLine: val.addressLine,
  993. storeCategory: val.storeCategory,
  994. storeName: val.storeName,
  995. contactName: val.contactName,
  996. genDate: val.hisTime,
  997. storeCode: val.storeCode,
  998. visitModel: '1',
  999. latNew: val.lat,
  1000. lonNew: val.lon,
  1001. PointSum: '0',
  1002. marklat: val.lat,
  1003. marklon: val.lon,
  1004. from: 'inPlan',
  1005. },
  1006. });
  1007. localStorage.setItem('startTime', new Date());
  1008. localStorage.setItem('ORGName', val.deptName);
  1009. localStorage.setItem('chainNameR', val.storeName);
  1010. } else {
  1011. getPosition()
  1012. .then((res) => {
  1013. let { TXisBD, resData } = res;
  1014. this.lat = TXisBD.lat;
  1015. this.lon = TXisBD.lon;
  1016. localStorage.setItem('lat', this.lat);
  1017. localStorage.setItem('lon', this.lon);
  1018. this.checkStoreAddressByStoreCodeFun(val, TXisBD, resData);
  1019. })
  1020. .catch((error) => {
  1021. this.$dialog.alert({
  1022. message: error,
  1023. });
  1024. });
  1025. }
  1026. }
  1027. }
  1028. } else {
  1029. this.$dialog.alert({
  1030. title: '系统提示',
  1031. message: res.msg,
  1032. });
  1033. }
  1034. });
  1035. },
  1036. checkStoreAddressByStoreCodeFun(val, location, res) {
  1037. checkStoreAddressByStoreCode({
  1038. storeCode: val.storeCode,
  1039. lon: location.lon,
  1040. lat: location.lat,
  1041. }).then((response) => {
  1042. // loading1.clear();
  1043. if (val.lat == '' || val.lat == null) {
  1044. this.lat = location.lat;
  1045. this.lon = location.lon;
  1046. }
  1047. // let PointSum = this.twoPointSum(this.lat, this.lon, location.lat, location.lon).toFixed(2);
  1048. let PointSumval = this.twoPointSum(
  1049. location.lat,
  1050. location.lon,
  1051. location.lat,
  1052. location.lon,
  1053. ).toFixed(2);
  1054. // GZ:工装店铺 直接进入拜访
  1055. if (localStorage.getItem('postType') == 'GZ' || /^FSQ/.test(val.storeCode)) {
  1056. localStorage.setItem('startTime', new Date());
  1057. localStorage.setItem('ORGName', val.deptName);
  1058. localStorage.setItem('chainNameR', val.storeName);
  1059. this.toSuishenbangOutstoreVisit(res, val, location, PointSumval);
  1060. return;
  1061. }
  1062. // 门店校验 地址不通过
  1063. if (response.code != 200) {
  1064. // updateAddress : ,1:同城AB+金牌,去修改地址;2:非金牌店铺,非同城店铺偏差过大不允许拜访,可以重置定位;0非金牌店铺,非同城店铺 位置信息不存在 可以继续拜访
  1065. if (response.data.updateAddress == 0) {
  1066. // 非金牌店铺,非同城店铺 位置信息不存在 可以继续拜访
  1067. this.$dialog
  1068. .confirm({
  1069. confirmButtonText: '确定拜访',
  1070. cancelButtonText: '取消拜访',
  1071. title: '系统提示',
  1072. message:
  1073. '该客户没有经纬度,此次拜访会保存定位点作为客户经纬度,下次拜访时判断是否偏差过大。',
  1074. closeOnClickOverlay: true,
  1075. })
  1076. .then(() => {
  1077. this.toSuishenbangOutstoreVisit(res, val, location, PointSumval);
  1078. });
  1079. } else if (response.data.updateAddress == 1) {
  1080. // 同城AB+金牌,去修改地址
  1081. // addressUpdateTimesOver: true=已经达到最大次数,不让修改; false=没有达到可以修改
  1082. if (!response.data.addressUpdateTimesOver) {
  1083. this.$dialog
  1084. .confirm({
  1085. title: '系统提示',
  1086. message: response.msg + '请立即修改后再拜访',
  1087. messageAlign: 'left',
  1088. confirmButtonText: '立即修改',
  1089. cancelButtonText: '取消',
  1090. })
  1091. .then(() => {
  1092. this.$router.push({
  1093. path: '/storeDetail',
  1094. query: {
  1095. id: val.storeId,
  1096. type: 'address',
  1097. storeAddressId: val.storeAddressId,
  1098. },
  1099. });
  1100. });
  1101. } else {
  1102. this.$dialog.confirm({
  1103. title: '系统提示',
  1104. message: '已经达到最大修改次数',
  1105. messageAlign: 'left',
  1106. confirmButtonText: '确定',
  1107. });
  1108. }
  1109. } else if (response.data.updateAddress == 2) {
  1110. // 1.非金牌店铺,非同城店铺 位置偏差过大 重置经纬度
  1111. this.resetCoord(res, val, location, PointSumval);
  1112. return;
  1113. }
  1114. } else {
  1115. // 门店编码校验门店地址通过 进入拜访
  1116. this.toSuishenbangOutstoreVisit(res, val, location, PointSumval);
  1117. }
  1118. });
  1119. },
  1120. // 重置经纬度
  1121. resetCoord(res, val, location, PointSumval) {
  1122. this.$dialog
  1123. .confirm({
  1124. confirmButtonText: '初始化定位',
  1125. cancelButtonText: '取消拜访',
  1126. title: '系统提示',
  1127. message: '偏差过大,不允许拜访。可修改本店定位.',
  1128. closeOnClickOverlay: true,
  1129. })
  1130. .then(() => {
  1131. mobileReposition({
  1132. storeId: val.storeId,
  1133. lat: location.lat,
  1134. lon: location.lon,
  1135. }).then((response) => {
  1136. if (response.code == 200) {
  1137. this.$dialog
  1138. .alert({
  1139. title: '系统提示',
  1140. message: '本信息定位已更新成功!',
  1141. })
  1142. .then(() => {
  1143. this.toSuishenbangOutstoreVisit(res, val, location, PointSumval);
  1144. });
  1145. localStorage.setItem('startTime', new Date());
  1146. localStorage.setItem('ORGName', val.deptName);
  1147. localStorage.setItem('chainNameR', val.storeName);
  1148. } else {
  1149. this.$toast(response.msg);
  1150. }
  1151. });
  1152. })
  1153. .catch(() => {});
  1154. },
  1155. // 进入拜访 router.push
  1156. toSuishenbangOutstoreVisit(res, val, location, PointSumval) {
  1157. addVisitsPosition({
  1158. storeId: val.storeId,
  1159. visitsId: '',
  1160. lon: res.longitude,
  1161. lat: res.latitude,
  1162. sourceLon: location.lon,
  1163. sourceLat: location.lat,
  1164. positionDesc: '',
  1165. accuracy: res.accuracy,
  1166. }).then(() => {
  1167. this.$router.push({
  1168. path: '/storeVisitpage',
  1169. query: {
  1170. storeId: val.storeId,
  1171. rdId: val.rdId,
  1172. lat: location.lat,
  1173. lon: location.lon,
  1174. visitId: val.visitId,
  1175. addressLine: val.addressLine,
  1176. storeCategory: val.storeCategory,
  1177. storeName: val.storeName,
  1178. contactName: val.contactName,
  1179. genDate: val.hisTime,
  1180. storeCode: val.storeCode,
  1181. visitModel: '1',
  1182. latNew: location.lat,
  1183. lonNew: location.lon,
  1184. PointSum: PointSumval,
  1185. marklat: res.latitude,
  1186. marklon: res.longitude,
  1187. from: 'inPlan',
  1188. },
  1189. });
  1190. });
  1191. },
  1192. projectOutVisit(val) {
  1193. localStorage.setItem('tabVal', this.tabVal);
  1194. localStorage.removeItem('visitId');
  1195. // checkVisit({storeId:val.storeId}).then(res=>{
  1196. // if(res.code==200||val.stateString.indexOf("拜访中")!=-1){
  1197. if (localStorage.getItem('loginType') == 'cs') {
  1198. var lat = '';
  1199. var lon = '';
  1200. if (val.lat == '' || val.lat == null) {
  1201. lat = '31.2517820000';
  1202. lon = '120.5593090000';
  1203. } else {
  1204. lat = val.lat;
  1205. lon = val.lon;
  1206. }
  1207. this.$router.push({
  1208. path: '/storeGroup',
  1209. query: {
  1210. storeId: val.storeId,
  1211. rdId: val.rdId,
  1212. lat: lat,
  1213. lon: lon,
  1214. visitId: val.visitId,
  1215. pageType: 'out',
  1216. addressLine: val.addressLine,
  1217. storeCategory: val.storeCategory,
  1218. storeName: val.storeName,
  1219. hisTime: val.hisTime,
  1220. contactName: val.contactName,
  1221. storeCode: val.storeCode,
  1222. tabVal: this.tabVal,
  1223. visitModel: '1',
  1224. latNew: '31.2517820000',
  1225. lonNew: '120.5593090000',
  1226. PointSum: 0,
  1227. marklat: lat,
  1228. marklon: lon,
  1229. },
  1230. });
  1231. localStorage.setItem('startTime', new Date());
  1232. localStorage.setItem('ORGName', val.deptName);
  1233. localStorage.setItem('chainNameR', val.storeName);
  1234. } else {
  1235. if (this.flag) {
  1236. this.flag = false;
  1237. this.timer = null;
  1238. let that = this;
  1239. this.timer = setTimeout(() => {
  1240. this.flag = true;
  1241. }, 2000);
  1242. if (val.stateString.indexOf('拜访中') != -1) {
  1243. localStorage.setItem('startTime', new Date());
  1244. localStorage.setItem('ORGName', val.deptName);
  1245. localStorage.setItem('chainNameR', val.storeName);
  1246. that.$router.push({
  1247. path: '/storeGroup',
  1248. query: {
  1249. storeId: val.storeId,
  1250. rdId: val.rdId,
  1251. lat: val.lat,
  1252. lon: val.lon,
  1253. visitId: val.visitId,
  1254. pageType: 'out',
  1255. addressLine: val.addressLine,
  1256. storeCategory: val.storeCategory,
  1257. storeName: val.storeName,
  1258. hisTime: val.hisTime,
  1259. contactName: val.contactName,
  1260. storeCode: val.storeCode,
  1261. tabVal: that.tabVal,
  1262. visitModel: '1',
  1263. latNew: val.lat,
  1264. lonNew: val.lon,
  1265. PointSum: '0',
  1266. marklat: val.lat,
  1267. marklon: val.lon,
  1268. },
  1269. });
  1270. } else {
  1271. let loading1 = this.$toast.loading({
  1272. duration: 0,
  1273. message: '加载中...',
  1274. forbidClick: true,
  1275. });
  1276. let url = window.location.href;
  1277. let wx = this.wx;
  1278. let qiyeData;
  1279. const instance = axios.create();
  1280. instance.defaults.headers.common['userId'] = localStorage.getItem('loginName');
  1281. instance
  1282. .get(process.env.VUE_APP_BASE_API + 'mobile/wx/ticket', {
  1283. params: {
  1284. url: url,
  1285. },
  1286. })
  1287. .then((response) => {
  1288. if (response.status == 200) {
  1289. this.cont = 3;
  1290. var flat = true;
  1291. var times = setInterval(() => {
  1292. this.cont--;
  1293. if (this.cont == '0') {
  1294. if (flat) {
  1295. loading1.clear();
  1296. clearInterval(times);
  1297. that.$dialog
  1298. .alert({
  1299. message: '定位失败,请开启企微定位权限',
  1300. })
  1301. .then(() => {});
  1302. } else {
  1303. clearInterval(times);
  1304. }
  1305. }
  1306. }, 1000);
  1307. qiyeData = response.data.data;
  1308. wx.config({
  1309. beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
  1310. debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  1311. appId: qiyeData.appId, // 必填,企业微信的corpID
  1312. timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
  1313. nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
  1314. signature: qiyeData.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
  1315. jsApiList: ['ready', 'getLocation'], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
  1316. });
  1317. wx.ready(function () {
  1318. wx.getLocation({
  1319. type: 'gcj02',
  1320. success: function (res) {
  1321. flat = false;
  1322. loading1.clear();
  1323. var location = that.CJ02BD(res.latitude, res.longitude);
  1324. if (val.lat == '' || val.lat == null) {
  1325. that.lat = location.lat;
  1326. that.lon = location.lon;
  1327. }
  1328. let PointSum = that
  1329. .twoPointSum(that.lat, that.lon, location.lat, location.lon)
  1330. .toFixed(2);
  1331. if (val.lat == '' || val.lat == null) {
  1332. if (
  1333. localStorage.getItem('postType') == 'GZ' ||
  1334. /^FSQ/.test(val.storeCode)
  1335. ) {
  1336. that.$router.push({
  1337. path: '/storeGroup',
  1338. query: {
  1339. storeId: val.storeId,
  1340. rdId: val.rdId,
  1341. lat: that.lat,
  1342. lon: that.lon,
  1343. visitId: val.visitId,
  1344. pageType: 'out',
  1345. addressLine: val.addressLine,
  1346. storeCategory: val.storeCategory,
  1347. storeName: val.storeName,
  1348. contactName: val.contactName,
  1349. hisTime: val.hisTime,
  1350. storeCode: val.storeCode,
  1351. tabVal: that.tabVal,
  1352. visitModel: '1',
  1353. latNew: location.lat,
  1354. lonNew: location.lon,
  1355. PointSum: PointSum,
  1356. marklat: res.latitude,
  1357. marklon: res.longitude,
  1358. },
  1359. });
  1360. } else {
  1361. that.$dialog
  1362. .confirm({
  1363. confirmButtonText: '确定拜访',
  1364. cancelButtonText: '取消拜访',
  1365. title: '系统提示',
  1366. message:
  1367. '该信息没有经纬度,此次拜访会保存定位点作为信息经纬度,下次拜访时判断是否偏差过大。',
  1368. closeOnClickOverlay: true,
  1369. })
  1370. .then(() => {
  1371. that.$router.push({
  1372. path: '/storeGroup',
  1373. query: {
  1374. storeId: val.storeId,
  1375. rdId: val.rdId,
  1376. lat: that.lat,
  1377. lon: that.lon,
  1378. visitId: val.visitId,
  1379. pageType: 'out',
  1380. addressLine: val.addressLine,
  1381. storeCategory: val.storeCategory,
  1382. storeName: val.storeName,
  1383. contactName: val.contactName,
  1384. hisTime: val.hisTime,
  1385. storeCode: val.storeCode,
  1386. tabVal: that.tabVal,
  1387. visitModel: '1',
  1388. latNew: location.lat,
  1389. lonNew: location.lon,
  1390. PointSum: PointSum,
  1391. marklat: res.latitude,
  1392. marklon: res.longitude,
  1393. },
  1394. });
  1395. });
  1396. }
  1397. } else {
  1398. that.$router.push({
  1399. path: '/storeGroup',
  1400. query: {
  1401. storeId: val.storeId,
  1402. rdId: val.rdId,
  1403. lat: that.lat,
  1404. lon: that.lon,
  1405. visitId: val.visitId,
  1406. pageType: 'out',
  1407. addressLine: val.addressLine,
  1408. storeCategory: val.storeCategory,
  1409. storeName: val.storeName,
  1410. contactName: val.contactName,
  1411. hisTime: val.hisTime,
  1412. storeCode: val.storeCode,
  1413. tabVal: that.tabVal,
  1414. visitModel: '1',
  1415. latNew: location.lat,
  1416. lonNew: location.lon,
  1417. PointSum: PointSum,
  1418. marklat: res.latitude,
  1419. marklon: res.longitude,
  1420. },
  1421. });
  1422. }
  1423. localStorage.setItem('startTime', new Date());
  1424. localStorage.setItem('ORGName', val.deptName);
  1425. localStorage.setItem('chainNameR', val.storeName);
  1426. addVisitsPosition({
  1427. storeId: val.storeId,
  1428. visitsId: '',
  1429. lon: res.longitude,
  1430. lat: res.latitude,
  1431. sourceLon: location.lon,
  1432. sourceLat: location.lat,
  1433. positionDesc: '',
  1434. accuracy: res.accuracy,
  1435. });
  1436. },
  1437. fail: function () {
  1438. loading1.clear();
  1439. that.$dialog.alert({
  1440. message: 'GPS未开启',
  1441. });
  1442. },
  1443. });
  1444. });
  1445. wx.error(function (res) {
  1446. loading1.clear();
  1447. that.$dialog
  1448. .alert({
  1449. message: '定位失败,请开启企微定位权限',
  1450. })
  1451. .then(() => {});
  1452. });
  1453. }
  1454. });
  1455. }
  1456. }
  1457. }
  1458. // }
  1459. // })
  1460. },
  1461. abnormalVisit(val) {
  1462. localStorage.removeItem('visitId');
  1463. checkVisit({ storeId: val.storeId }).then((res) => {
  1464. buryingPoint({
  1465. systemModel: '计划内',
  1466. buryingPointType: 1,
  1467. buryingPointValue: val.storeName + '(' + val.storeCode + ')',
  1468. buryingPointName: '异常拜访',
  1469. buryingPointPosition: '计划内',
  1470. });
  1471. if (res.code == 200 || val.stateString.indexOf('拜访中') != -1) {
  1472. if (localStorage.getItem('loginType') == 'cs') {
  1473. var lat = '';
  1474. var lon = '';
  1475. if (val.lat == '' || val.lat == null) {
  1476. lat = '31.2517820000';
  1477. lon = '120.5593090000';
  1478. } else {
  1479. lat = val.lat;
  1480. lon = val.lon;
  1481. }
  1482. this.$router.push({
  1483. path: '/abnormalVisit',
  1484. query: {
  1485. storeId: val.storeId,
  1486. rdId: val.rdId,
  1487. lat: lat,
  1488. lon: lon,
  1489. visitId: val.visitId,
  1490. pageType: 'out',
  1491. addressLine: val.addressLine,
  1492. storeCategory: val.storeCategory,
  1493. storeName: val.storeName,
  1494. hisTime: val.hisTime,
  1495. contactName: val.contactName,
  1496. storeCode: val.storeCode,
  1497. tabVal: this.tabVal,
  1498. visitModel: '3',
  1499. latNew: '31.2517820000',
  1500. lonNew: '120.5593090000',
  1501. PointSum: 0,
  1502. marklat: lat,
  1503. marklon: lon,
  1504. },
  1505. });
  1506. localStorage.setItem('startTime', new Date());
  1507. localStorage.setItem('ORGName', val.deptName);
  1508. localStorage.setItem('chainNameR', val.storeName);
  1509. } else {
  1510. getPosition()
  1511. .then((res) => {
  1512. let { TXisBD, resData } = res;
  1513. this.lat = TXisBD.lat;
  1514. this.lon = TXisBD.lon;
  1515. localStorage.setItem('lat', this.lat);
  1516. localStorage.setItem('lon', this.lon);
  1517. console.log('异常拜访=' + this.lat);
  1518. console.log('异常拜访=' + this.lon);
  1519. let PointSum = this.twoPointSum(
  1520. TXisBD.lat,
  1521. TXisBD.lon,
  1522. TXisBD.lat,
  1523. TXisBD.lon,
  1524. ).toFixed(2);
  1525. this.$router.push({
  1526. path: '/abnormalVisit',
  1527. query: {
  1528. storeId: val.storeId,
  1529. rdId: val.rdId,
  1530. lat: this.lat,
  1531. lon: this.lon,
  1532. visitModel: localStorage.getItem('postType') != 'GZ' ? '5' : '3',
  1533. visitId: val.visitId,
  1534. genDate: val.genDate,
  1535. storeCode: val.storeCode,
  1536. latNew: location.lat,
  1537. lonNew: location.lon,
  1538. PointSum: PointSum,
  1539. marklat: resData.latitude,
  1540. marklon: resData.longitude,
  1541. },
  1542. });
  1543. localStorage.setItem('startTime', new Date());
  1544. localStorage.setItem('ORGName', val.deptName);
  1545. localStorage.setItem('chainNameR', val.storeName);
  1546. addVisitsPosition({
  1547. storeId: val.storeId,
  1548. visitsId: '',
  1549. lon: resData.longitude,
  1550. lat: resData.latitude,
  1551. sourceLon: location.lon,
  1552. sourceLat: location.lat,
  1553. positionDesc: '',
  1554. accuracy: resData.accuracy,
  1555. });
  1556. })
  1557. .catch((error) => {
  1558. this.$dialog.alert({
  1559. message: error,
  1560. });
  1561. });
  1562. }
  1563. } else {
  1564. this.$dialog.alert({
  1565. title: '系统提示',
  1566. message: res.msg,
  1567. });
  1568. }
  1569. });
  1570. },
  1571. compareDate(dateTime1) {
  1572. var formatDate1 = Date.parse(dateTime1);
  1573. var formatDate2 = Date.parse(this.parseTime(new Date(), '{yy}-{mm}-{dd}'));
  1574. if (formatDate1 == formatDate2) {
  1575. return true;
  1576. } else {
  1577. return false;
  1578. }
  1579. },
  1580. visitFn(val) {
  1581. buryingPoint({
  1582. systemModel: '计划内',
  1583. buryingPointType: 1,
  1584. buryingPointValue: val.storeName + '(' + val.storeCode + ')',
  1585. buryingPointName: '客户信息',
  1586. buryingPointPosition: '计划内',
  1587. });
  1588. if (val.sfaStoreType.type == 'qzd') {
  1589. // 竞品店/潜在店
  1590. this.$router.push({
  1591. path: '/competingStoresDetail',
  1592. query: { id: val.storeId },
  1593. });
  1594. } else if (/^FSQ/.test(val.storeCode)) {
  1595. // FSQ 仿石漆服务商
  1596. this.$router.push({
  1597. path: '/FSQStoreDetail',
  1598. query: { id: val.storeId },
  1599. });
  1600. return;
  1601. } else if (val.designerStore) {
  1602. // designerStore 是否为设计师招募门店,true-是,false-否
  1603. this.$router.push({
  1604. path: '/addDesignerDetail',
  1605. query: { id: val.storeId },
  1606. });
  1607. return;
  1608. } else {
  1609. this.$router.push({
  1610. path: '/storeDetail',
  1611. query: { id: val.storeId, detilId: 'a' },
  1612. });
  1613. }
  1614. },
  1615. goFn() {
  1616. this.$router.push({
  1617. path: '/topStore',
  1618. });
  1619. },
  1620. formLink() {
  1621. this.$router.push('/storeVisit/questions');
  1622. },
  1623. onClickLeft() {
  1624. this.$router.go(-1);
  1625. },
  1626. onSearch() {
  1627. localStorage.setItem('deviveStoreName', this.storeName);
  1628. this.getUserInPlanList();
  1629. },
  1630. handelChange(date) {
  1631. var dateF = this.parseTime(date.$d, '{yy}-{mm}-{dd}');
  1632. this.timeData = dateF;
  1633. this.genDate = dateF;
  1634. this.getUserInPlanList();
  1635. },
  1636. onLoad() {
  1637. this.getUserInPlanList();
  1638. },
  1639. listClick(val) {
  1640. this.listActive = val;
  1641. },
  1642. setStroeNameStyle(item) {
  1643. // 家装或工装 approvalStatus:是否结案 0:未结案,1:已结案
  1644. if (
  1645. (item.sfaStoreType && (item.sfaStoreType.jz || item.sfaStoreType.gz)) ||
  1646. item.approvalStatus == null ||
  1647. item.approvalStatus == 0
  1648. ) {
  1649. return {};
  1650. } else {
  1651. return { color: '#0057ba', 'text-decoration': 'underline' };
  1652. }
  1653. },
  1654. // 跳转好帮手门店详情
  1655. goOtherSystem(item) {
  1656. // 家装或工装 approvalStatus:是否结案 0:未结案,1:已结案
  1657. if (
  1658. (item.sfaStoreType && (item.sfaStoreType.jz || item.sfaStoreType.gz)) ||
  1659. item.approvalStatus == null ||
  1660. item.approvalStatus == 0
  1661. ) {
  1662. return false;
  1663. }
  1664. if (item.storeCode) {
  1665. window.location.href =
  1666. process.env.VUE_APP_SSB_LINK + '/order/storeDetail/index?shopCode=' + item.storeCode;
  1667. } else {
  1668. this.$dialog.alert({
  1669. message: '缺少门店code',
  1670. });
  1671. }
  1672. },
  1673. },
  1674. };
  1675. </script>
  1676. <style lang="scss">
  1677. .van-dialog__confirm,
  1678. .van-dialog__confirm:active {
  1679. color: #0057ba;
  1680. }
  1681. .searchDiv {
  1682. .van-search {
  1683. background: #fff;
  1684. }
  1685. .van-search__action {
  1686. font-size: 14px;
  1687. color: #0057ba;
  1688. font-weight: bold;
  1689. background: #f1f1f1;
  1690. border-bottom-right-radius: 60px;
  1691. border-top-right-radius: 60px;
  1692. border: 1px solid #c1c1c1;
  1693. padding: 0 20px;
  1694. }
  1695. .van-search--show-action {
  1696. padding-right: 12px;
  1697. }
  1698. .van-search__content {
  1699. border: 1px solid #c1c1c1;
  1700. border-bottom-left-radius: 60px;
  1701. border-top-left-radius: 60px;
  1702. background: #f1f1f1;
  1703. border-right: 0;
  1704. }
  1705. }
  1706. </style>
  1707. <style lang="scss" scoped>
  1708. .bgcolor {
  1709. background-color: #f5f5f5;
  1710. }
  1711. .container {
  1712. padding-bottom: 50px;
  1713. }
  1714. .monthNow {
  1715. height: 48px;
  1716. line-height: 48px;
  1717. text-align: center;
  1718. font-weight: bold;
  1719. padding: 0 15px;
  1720. box-sizing: border-box;
  1721. background-color: #f5f5f5;
  1722. font-size: 16px;
  1723. .CalendarIcon {
  1724. font-size: 24px;
  1725. color: #0057ba;
  1726. position: relative;
  1727. top: 6px;
  1728. margin-left: 10px;
  1729. }
  1730. }
  1731. .card {
  1732. padding: 10px 16px;
  1733. box-sizing: border-box;
  1734. .title {
  1735. font-size: 15px;
  1736. font-weight: bold;
  1737. color: #333;
  1738. line-height: 22px;
  1739. padding-right: 52px;
  1740. /*word-break: break-all;*/
  1741. .JPABC {
  1742. width: 20px;
  1743. position: relative;
  1744. top: 4px;
  1745. margin-right: 3px;
  1746. }
  1747. .statusIcon {
  1748. padding: 3px;
  1749. font-size: 12px;
  1750. margin: 0 3px;
  1751. color: #fff;
  1752. display: inline-block;
  1753. height: 20px;
  1754. line-height: 16px;
  1755. vertical-align: -1px;
  1756. }
  1757. .submit {
  1758. background: #ffba13;
  1759. }
  1760. .noSubmit {
  1761. background: #f11818;
  1762. }
  1763. }
  1764. .info {
  1765. font-size: 14px;
  1766. color: #909090;
  1767. line-height: 26px;
  1768. }
  1769. }
  1770. .navBarTOP {
  1771. position: fixed;
  1772. width: 100%;
  1773. z-index: 2;
  1774. top: 0;
  1775. }
  1776. .cellcontent .centerBtn {
  1777. margin: 0 auto 10px;
  1778. display: block;
  1779. width: 92%;
  1780. border-radius: 5px;
  1781. color: #0057ba;
  1782. border: 1px solid #0057ba;
  1783. }
  1784. .cellcontent .centerBtn1 {
  1785. background-color: #0057ba;
  1786. color: #fff;
  1787. }
  1788. .btnbox {
  1789. padding-top: 14px;
  1790. border-top: 1px solid #eee;
  1791. margin: 0 10px;
  1792. }
  1793. .cellcontent .centerBtn2 {
  1794. margin: 0 auto 10px;
  1795. display: block;
  1796. width: 92%;
  1797. color: #0057ba;
  1798. border-radius: 5px;
  1799. padding: 0;
  1800. }
  1801. .statstext {
  1802. background-color: #0057ba;
  1803. position: absolute;
  1804. right: 0;
  1805. top: 6px;
  1806. padding: 2px 6px 2px 12px;
  1807. border-bottom-left-radius: 60px;
  1808. border-top-left-radius: 60px;
  1809. color: #fff;
  1810. }
  1811. .lineGrey {
  1812. height: 10px;
  1813. width: 100%;
  1814. background: #f1f1f1;
  1815. }
  1816. .cellcontent .van-cell {
  1817. padding: 10px 0;
  1818. }
  1819. .statstext .van-icon__image {
  1820. height: 0.7em;
  1821. }
  1822. .visitStoreIco {
  1823. float: left;
  1824. float: left;
  1825. width: 26px;
  1826. text-align: center;
  1827. background-color: #ffba13;
  1828. color: #fff;
  1829. border-radius: 100%;
  1830. margin-left: 14px;
  1831. line-height: 26px;
  1832. height: 26px;
  1833. }
  1834. .tipsTitle {
  1835. padding: 5px 0;
  1836. text-align: center;
  1837. font-size: 16px;
  1838. font-weight: 600;
  1839. }
  1840. .deviceWithin {
  1841. height: 100%;
  1842. width: 100%;
  1843. display: flex;
  1844. flex-direction: column;
  1845. overflow: hidden;
  1846. .content {
  1847. flex: 1;
  1848. overflow-y: auto;
  1849. }
  1850. .tabBar {
  1851. height: 50px;
  1852. }
  1853. .JPVisitNum {
  1854. position: relative;
  1855. top: -26px;
  1856. font-size: 10px;
  1857. }
  1858. .TCFXListItem {
  1859. display: inline-block;
  1860. border: 1px solid #ccc;
  1861. padding: 3px 5px;
  1862. margin: 0 5px;
  1863. border-radius: 6px;
  1864. }
  1865. }
  1866. </style>