index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. <template>
  2. <div>
  3. <van-nav-bar
  4. :title='isedit?"应急仓库编辑":"应急仓库"'
  5. left-arrow
  6. placeholder
  7. @click-left="goback"
  8. :fixed="true"
  9. @click-right="bjclick"
  10. >
  11. </van-nav-bar>
  12. <div>
  13. <div class="content">
  14. <div>
  15. <van-cell-group>
  16. <van-field
  17. v-model="whdata.value.name"
  18. label="仓库命名"
  19. input-align="right"
  20. :readonly="!isedit"
  21. placeholder="请输入仓库命名"
  22. />
  23. <van-field
  24. v-model="whdata.value.manageUnit"
  25. label="管理单位"
  26. input-align="right"
  27. :readonly="true"
  28. placeholder="请输入管理单位"
  29. />
  30. <van-field
  31. v-model="whdata.value.contactName"
  32. required
  33. :readonly="!isedit"
  34. label="联系人"
  35. input-align="right"
  36. placeholder="请输入联系人"
  37. />
  38. <van-field
  39. v-model="whdata.value.contactPhone"
  40. required
  41. label="联系方式"
  42. :readonly="!isedit"
  43. input-align="right"
  44. placeholder="请输入联系方式"
  45. />
  46. <van-field
  47. v-model="whdata.value.address"
  48. label="地址"
  49. :readonly="!isedit"
  50. input-align="right"
  51. placeholder="请输入地址"
  52. type="search"
  53. @keydown="onsearch"
  54. >
  55. <template #button v-if="isedit">
  56. <van-button
  57. size="small"
  58. type="primary"
  59. color="#f2f4fa"
  60. @click="searchaddr"
  61. ><van-icon name="search"
  62. /></van-button>
  63. </template>
  64. </van-field>
  65. </van-cell-group>
  66. </div>
  67. </div>
  68. <div style="padding: 15px; background: #fff; position: relative">
  69. <Map
  70. v-model:map="state.map"
  71. style="
  72. height: 240px;
  73. borderradius: 2px;
  74. boxshadow: 0px 0px 0px 1px #d9d9d9;
  75. "
  76. />
  77. <div v-if="isshowmove" class="mark">
  78. <img :src="icon_map_location" />
  79. </div>
  80. <div v-if="isedit" class="marklocation" @click="getLocation">
  81. <img src="../../assets/icons/incident/location1.png" />
  82. </div>
  83. <div v-if="isedit" style="position: absolute; right: 21px; top: 21px">
  84. <van-button type="primary" size="mini" @click="selectpoint">{{
  85. isshowmove ? '确定' : '选点'
  86. }}</van-button>
  87. </div>
  88. </div>
  89. <div style="padding: 30px 20px" v-if="isedit">
  90. <van-button
  91. type="primary"
  92. block
  93. style="border-radius: 30px"
  94. @click="dosavedata"
  95. >保存</van-button
  96. >
  97. </div>
  98. </div>
  99. </div>
  100. </template>
  101. <script setup>
  102. import { ref, reactive, onUpdated, onMounted, watch } from 'vue';
  103. import { RouterView, useRoute, useRouter } from 'vue-router';
  104. import icon_map_location from '@/assets/icons/home/icon_map_location@2x.png';
  105. import {
  106. api_getresource,
  107. api_getresourcedetail,
  108. api_putresource,
  109. api_bj,
  110. api_isbj,
  111. } from '@/service/warehouse';
  112. import { api_getusergps } from '@/service/login';
  113. import { Toast, Notify, Dialog } from 'vant';
  114. import { BaseMediaUrl } from '@/utils';
  115. import { upload } from '@/api/common';
  116. import Map from '@/components/MapView';
  117. const state = reactive({
  118. map: null,
  119. _marker: null,
  120. loading: false,
  121. postition: {
  122. longitude: '',
  123. latitude: '',
  124. name: '',
  125. },
  126. });
  127. const whdata = reactive({
  128. value: {
  129. name: '',
  130. manageUnit: '',
  131. contactName: '',
  132. contactPhone: '',
  133. longitude: '',
  134. latitude: '',
  135. },
  136. });
  137. const isedit = ref(false);
  138. const isempt = ref(true);
  139. const onsearch= (e)=>{
  140. if(e.keyCode==13){
  141. searchaddr()
  142. }
  143. }
  144. onMounted(() => {
  145. whdata.value = JSON.parse(localStorage.getItem('cck'));
  146. // isedit.value = true;
  147. isedit.value = localStorage.getItem("cedit")=="true"?true:false;
  148. // debugger
  149. var taskid = route.query.taskid;
  150. if (taskid) {
  151. api_isbj(taskid).then((res) => {
  152. isbj.value = !res.data;
  153. console.log(isbj.value);
  154. });
  155. }
  156. state.postition = {
  157. longitude: whdata.value.longitude,
  158. latitude: whdata.value.latitude,
  159. name: whdata.value.address,
  160. };
  161. if (state.map && state._marker) {
  162. state._marker.remove();
  163. state._marker = null;
  164. }
  165. if (state.map) {
  166. setpoint(
  167. Number(whdata.value.longitude),
  168. Number(whdata.value.latitude),
  169. whdata.value.address,
  170. );
  171. }
  172. });
  173. const isshowmove = ref(false);
  174. let allmark = [];
  175. const selectpoint = () => {
  176. if (isshowmove.value) {
  177. var center = state.map.getCenter();
  178. getlocalname(center.lng.toFixed(6) + ',' + center.lat.toFixed(6));
  179. } else {
  180. isshowmove.value = true;
  181. state._marker.remove();
  182. }
  183. };
  184. const setpoint = (longitude, latitude, name) => {
  185. if (state._marker) {
  186. state._marker.remove();
  187. }
  188. var el = document.createElement('div');
  189. el.id = 'marker';
  190. el.style.backgroundImage = `url(${icon_map_location})`;
  191. el.style.backgroundSize = 'cover';
  192. el.style.width = '24px';
  193. el.style.height = '24px';
  194. el.style.borderRadius = '50%';
  195. const popup = new window.minemap.Popup({
  196. closeOnClick: false,
  197. closeButton: false,
  198. offset: [0, -15],
  199. }).setText(name);
  200. state._marker = new window.minemap.Marker(el, {
  201. offset: [-12, -12],
  202. })
  203. .setLngLat([longitude, latitude])
  204. .setPopup(popup)
  205. .addTo(state.map);
  206. state.map.flyTo({
  207. center: [longitude, latitude],
  208. zoom: 14,
  209. bearing: 0,
  210. pitch: 0,
  211. duration: 2000,
  212. });
  213. state._marker.togglePopup();
  214. whdata.value.address = name;
  215. whdata.value.latitude = latitude;
  216. whdata.value.longitude = longitude;
  217. isshowmove.value = false;
  218. };
  219. const searchaddr = () => {
  220. isshowmove.value = false;
  221. fetch(
  222. `https://minedata.cn/service/lbs/search/v1/keywords?keywords=${whdata.value.address}&city=宿迁&citylimit=true&page_idx=1&page_size=10&key=${window.key}`,
  223. )
  224. .then((res) => res.json())
  225. .then((data) => {
  226. // console.log(data.pois)
  227. var clearallmark = () => {
  228. state._marker.remove();
  229. if (allmark.length > 0) {
  230. allmark.map((item) => {
  231. item.remove();
  232. });
  233. allmark = [];
  234. }
  235. };
  236. clearallmark();
  237. var top = [];
  238. var bottom = [];
  239. data.pois.map((item) => {
  240. if (top.length < 1) {
  241. top = [
  242. Number(item.location.split(',')[0]),
  243. Number(item.location.split(',')[1]),
  244. ];
  245. bottom = [
  246. Number(item.location.split(',')[0]),
  247. Number(item.location.split(',')[1]),
  248. ];
  249. }
  250. var el = document.createElement('div');
  251. el.id = 'marker';
  252. el.style.backgroundImage = `url(${icon_map_location})`;
  253. el.style.backgroundSize = 'cover';
  254. el.style.width = '24px';
  255. el.style.height = '24px';
  256. el.style.borderRadius = '50%';
  257. el.onclick = () => {
  258. clearallmark();
  259. setpoint(
  260. Number(item.location.split(',')[0]),
  261. Number(item.location.split(',')[1]),
  262. item.name,
  263. );
  264. };
  265. const popup = new window.minemap.Popup({
  266. closeOnClick: false,
  267. closeButton: false,
  268. offset: [0, -15],
  269. }).setText(item.name);
  270. var mark = new window.minemap.Marker(el, {
  271. offset: [-12, -12],
  272. })
  273. .setLngLat([
  274. Number(item.location.split(',')[0]),
  275. Number(item.location.split(',')[1]),
  276. ])
  277. .setPopup(popup)
  278. .addTo(state.map);
  279. allmark.push(mark);
  280. mark.togglePopup();
  281. if (top[0] < Number(item.location.split(',')[0])) {
  282. top[0] = Number(item.location.split(',')[0]);
  283. }
  284. if (top[1] > Number(item.location.split(',')[1])) {
  285. top[1] = Number(item.location.split(',')[1]);
  286. }
  287. if (bottom[0] > Number(item.location.split(',')[0])) {
  288. bottom[0] = Number(item.location.split(',')[0]);
  289. }
  290. if (bottom[1] < Number(item.location.split(',')[1])) {
  291. bottom[1] = Number(item.location.split(',')[1]);
  292. }
  293. });
  294. state.map.fitBounds([top, bottom]);
  295. });
  296. };
  297. const getlocalname = (location) => {
  298. fetch(
  299. `https://minedata.cn/service/lbs/reverse/v1/regeo?location=${location}&key=${window.key}`,
  300. )
  301. .then((res) => res.json())
  302. .then((data) => {
  303. setpoint(
  304. Number(location.split(',')[0]),
  305. Number(location.split(',')[1]),
  306. data.regeocodes[0].formatted_address,
  307. );
  308. });
  309. };
  310. const getLocation = () => {
  311. api_getusergps().then((res) => {
  312. var lat = null;
  313. var lon = null;
  314. var iserror = false;
  315. try {
  316. lat = res.result[0].lat;
  317. lon = res.result[0].lon;
  318. if (lat == null || lat == undefined) iserror = true;
  319. } catch (e) {
  320. iserror = true;
  321. }
  322. if (!iserror) {
  323. // debugger
  324. var location = `${lon},${lat}`;
  325. getlocalname(location);
  326. // setpoint(lon,lat,data.regeocodes[0].formatted_address)
  327. } else {
  328. Notify({
  329. type: 'danger',
  330. message: 'App不支持地理定位。',
  331. });
  332. }
  333. });
  334. };
  335. const goback = () => {
  336. try {
  337. uni.navigateBack();
  338. } catch (E) {}
  339. //window.history.back();
  340. };
  341. const dosavedata = () => {
  342. Toast.loading({
  343. message: '加载中...',
  344. duration: 0,
  345. forbidClick: true,
  346. });
  347. var data = whdata.value;
  348. api_putresource(data)
  349. .then((res) => {
  350. Toast.clear();
  351. setTimeout(() => {
  352. Toast('保存成功');
  353. }, 1000);
  354. // Notify({ type: 'success', message: '保存成功'});
  355. getdata();
  356. })
  357. .catch((ee) => {
  358. Toast.clear();
  359. });
  360. };
  361. const isbj = ref(true);
  362. const route = useRoute();
  363. </script>
  364. <style lang="scss">
  365. .content label,
  366. .content span {
  367. font-size: 15px;
  368. font-family: PingFangSC, PingFangSC-Regular;
  369. color: #333333;
  370. }
  371. .bjbtn {
  372. font-size: 14px;
  373. font-weight: 500;
  374. color: #ffffff;
  375. font-size: 13px;
  376. font-weight: 500;
  377. background: #bb0000;
  378. padding: 3px 8px;
  379. border-radius: 2px;
  380. }
  381. .content {
  382. .cell-header {
  383. font-family: PingFangSC, PingFangSC-Regular;
  384. font-weight: 400;
  385. line-height: 42px;
  386. padding: 0px 15px;
  387. span {
  388. font-size: 12px;
  389. }
  390. div {
  391. font-size: 14px;
  392. color: #0b33a8;
  393. }
  394. }
  395. }
  396. .mark {
  397. position: absolute;
  398. top: 50%;
  399. left: 50%;
  400. transform: translate(-50%, -50%);
  401. img {
  402. width: 24px;
  403. height: 24px;
  404. }
  405. }
  406. .marklocation {
  407. img {
  408. width: 24px;
  409. height: 24px;
  410. }
  411. position: absolute;
  412. bottom: 10%;
  413. right: 20px;
  414. }
  415. </style>