Ver código fonte

feat 店铺新增、编辑

Funny 3 anos atrás
pai
commit
1560c3742d

+ 7 - 0
src/api/index.ts

@@ -63,6 +63,13 @@ export const deleteShop = (params: any) => {
   return post('app/shop/delete', params)
 }
 
+export const shopAdd = (params: any) => {
+  return post('app/shop/add', params)
+}
+export const shopEdit = (params: any) => {
+  return post('app/shop/modify', params)
+}
+
 // 获取订单列表
 export const orderList = (params: any) => {
   return get('app/order/list', params)

+ 122 - 18
src/components/MapContainer.vue

@@ -1,55 +1,159 @@
 <script setup lang='ts'>
 import { onMounted, ref } from 'vue'
-import { shallowRef } from '@vue/reactivity'
+import { reactive, ShallowRef, shallowRef } from '@vue/reactivity'
 import AMapLoader from '@amap/amap-jsapi-loader';
+import axios from 'axios';
 let map = shallowRef(null);
 const emit = defineEmits(["getMapData"]);
+let centerPoint = reactive({ arr: [120.67012, 31.266833] })
+let city = ref('苏州市')
+let addressInfo = ref('')
 const initMap = () => {
   AMapLoader.load({
     key: "21132ea36aed6ab1884085a836f12ca9",             // 申请好的Web端开发者Key,首次调用 load 时必填
     version: "2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
-    plugins: ['AMap.ToolBar', 'AMap.Driving'],
     AMapUI: {
       version: "1.1",
-      plugins: ['misc/PositionPicker'],
-
+      plugins: ['misc/PositionPicker', 'misc/PoiPicker'],
     },
     Loca: {
       version: "2.0.0"
     }
   }).then((AMap) => {
-    AMapUI.loadUI(['misc/PositionPicker'], (PositionPicker: new (arg0: { mode: string; map: any; }) => any) => {
-      map = new AMap.Map("container", {  //设置地图容器id
-        viewMode: "3D",    //是否为3D地图模式
-        zoom: 16,           //初始化地图级别
-        center: [120.67012, 31.266833], //初始化地图中心点位置
+    map = new AMap.Map("container", {  //设置地图容器id
+      viewMode: "3D",    //是否为3D地图模式
+      zoom: 16,           //初始化地图级别
+      center: centerPoint.arr, //初始化地图中心点位置
+    });
+    let marker = new AMap.Marker();
+    let infoWindow = new AMap.InfoWindow({
+      offset: new AMap.Pixel(0, -20)
+    });
+    AMapUI.loadUI(['misc/PositionPicker', 'misc/PoiPicker'], (PositionPicker: new (arg0: { mode: string; map: ShallowRef<null>; }) => any, PoiPicker: new (arg0: { input: string; }) => any) => {
+      let poiPicker = new PoiPicker({
+        input: 'pickerInput'
       });
+      const poiPickerReady = (poiPicker: { on: (arg0: string, arg1: (poiResult: any) => void) => void; onCityReady: (arg0: () => void) => void; suggest: (arg0: string) => void; }, AMap: { Marker: new () => any; InfoWindow: new (arg0: { offset: any; }) => any; Pixel: new (arg0: number, arg1: number) => any; }) => {
+        window.poiPicker = poiPicker;
+        //选取了某个POI
+        poiPicker.on('poiPicked', (poiResult: { source: any; item: any; }) => {
+          console.log('选取点:', poiResult);
+          let poi = poiResult.item
+          marker.setMap(map);
+          marker.setPosition(poi.location);
+          map.setCenter(marker.getPosition());
+        });
+      }
+      //初始化poiPicker
+      poiPickerReady(poiPicker, AMap);
       let positionPicker = new PositionPicker({
-        mode: 'dragMarker',
+        mode: 'dragMap',
         map: map
       });
       positionPicker.on('success', (positionResult: any) => {
         console.log('positionResult:', positionResult);
-        emit('getMapData',JSON.stringify(positionResult))
+        let poi = positionResult.regeocode.pois[0]
+
+        // poiPicker.suggest(positionResult.address);
+        // marker.setMap(map);
+        // marker.setPosition(poi.location);
+        // map.setCenter(marker.getPosition());
+        infoWindow.setMap(map);
+        infoWindow.setPosition(poi.location);
+        let html = `<div style="font-size:16px;">${poi.name}</div><div style="font-size:14px;margin-top:5px;color: #999999;">${poi.address}</div>`
+        infoWindow.setContent(html);
+        addressInfo.value = JSON.stringify(positionResult)
+
       });
       positionPicker.start();
+
     })
   }).catch((e: String) => {
     console.log(e);
   })
 }
-onMounted(() => {
+
+const ipLocation = async () => {
+  return new Promise((res, rej) => {
+    axios.get('https://restapi.amap.com/v3/ip', {
+      params: {
+        key: '5ae8644771ef9abf9cfb3ea23b1df6ca'
+      }
+    })
+      .then((response) => {
+        console.log('ip-response', response);
+        res(response.data)
+      })
+      .catch((error) => {
+        console.log(error);
+        rej(error)
+      });
+  })
+
+}
+const cityLocation = async () => {
+  return new Promise((res, rej) => {
+    axios.get('https://restapi.amap.com/v3/place/text', {
+      params: {
+        key: '5ae8644771ef9abf9cfb3ea23b1df6ca',
+        keywords: city.value
+      }
+    })
+      .then((response) => {
+        console.log('ip-response', response);
+        res(response.data)
+      })
+      .catch((error) => {
+        console.log(error);
+        rej(error)
+      });
+  })
+}
+const confirm = () => {
+  emit('getMapData', addressInfo.value)
+}
+onMounted(async () => {
+  const ip: any = await ipLocation()
+  if (ip.status === '1') {
+    city.value = ip.city
+  }
+  const cityInfo: any = await cityLocation()
+  console.log('cityInfo', cityInfo);
+  if (cityInfo.status === '1') {
+    let poi = cityInfo.pois[0]
+    let location = poi.location.split(',')
+    centerPoint.arr = [location[0], location[1]]
+  }
   initMap()
 })
 </script>
 <template>
-  <div id="container"></div>
+  <div class="map">
+    <input id="pickerInput" placeholder="输入关键字选取地点" />
+    <div id="container"></div>
+    <div class="w-full flex justify-end mt-20px">
+      <a-button type="primary" @click="confirm">确认</a-button>
+    </div>
+  </div>
 </template>
 <style lang='scss' scoped>
-#container {
-  padding: 0px;
-  margin: 0px;
-  width: 100%;
-  height: 80vh;
+.map {
+  position: relative;
+
+  #pickerInput {
+    position: absolute;
+    top: 20px;
+    left: 20px;
+    width: 300px;
+    padding: 5px 5px;
+    z-index: 99999;
+  }
+
+  #container {
+    padding: 0px;
+    margin: 0px;
+    width: 100%;
+    height: 80vh;
+  }
 }
 </style>

+ 54 - 13
src/views/management/shop/shop.vue

@@ -1,11 +1,12 @@
 <script setup lang='ts'>
-import { onMounted, reactive, ref } from 'vue'
-import { shopList, deleteShop, getShopDetail, getProductList } from '@/api'
+import { computed, onMounted, reactive, ref } from 'vue';
+import { shopList, deleteShop, getShopDetail, getProductList, shopAdd, shopEdit } from '@/api';
 import { message } from 'ant-design-vue';
 import MapContainer from "@/components/MapContainer.vue";
+import util from '@/util/index';
 
 let visible = ref<Boolean>(false)
-let showMap = ref<Boolean>(true)
+let showMap = ref<Boolean>(false)
 let title = ref<String>('新增门店')
 let deliveries = reactive({
   arr: [{
@@ -37,9 +38,8 @@ interface formType {
   id?: Number;
   name: String;
   categoryId?: Number;
-  username: String;
   contactName: String;
-  mobile: String;
+  mobile?: String;
   address: String;
   poiAddress: String;
   street: String;
@@ -52,7 +52,6 @@ interface formType {
 }
 let form = reactive<formType>({
   name: '',
-  username: '',
   contactName: '',
   mobile: '',
   address: '',
@@ -146,7 +145,6 @@ const addShop = () => {
   let obj = {
     id: '',
     name: '',
-    username: '',
     contactName: '',
     mobile: '',
     address: '',
@@ -199,6 +197,40 @@ const showStatus = (bindStatus: Number, authMsg: String) => {
 }
 const confirm = () => {
 
+  if (!form.name.trim()) {
+    return message.error('请填写门店名称!')
+  }
+  if (!form.categoryId) {
+    return message.error('请选择主营类别!')
+  }
+  if (!form.contactName.trim()) {
+    return message.error('请填写联系人!')
+  }
+  if (!util.mobile(form.mobile)) {
+    return message.error('请填写正确格式的联系电话!')
+  }
+  if (!form.address.trim()) {
+    return message.error('请点击选择详细地址!')
+  }
+  if (form.id) {
+    shopEdit(form).then((res: any) => {
+      if (res.code === 200) {
+        message.success('编辑成功')
+        handleShopList()
+      } else {
+        message.error(res.msg)
+      }
+    })
+  } else {
+    shopAdd(form).then((res: any) => {
+      if (res.code === 200) {
+        message.success('新增成功')
+        handleShopList()
+      } else {
+        message.error(res.msg)
+      }
+    })
+  }
 }
 const getMapData = (v: string) => {
   let mapData = JSON.parse(v)
@@ -213,7 +245,11 @@ const getMapData = (v: string) => {
   form.districtName = regeocode.addressComponent.district
   form.lng = poi.location[0]
   form.lat = poi.location[1]
+  showMap.value = false
 }
+const address: any = computed(() => {
+  return `${form.poiAddress}${form.address}`
+})
 onMounted(() => {
 
 })
@@ -229,7 +265,7 @@ onMounted(() => {
       <a-input v-model:value="formState.shopName" placeholder="请输入要查询的店铺名称" allowClear>
       </a-input>
     </a-form-item>
-    <a-form-item label="联系电话" name="mobile">
+    <a-form-item label="联系电话" name="mobile">
       <a-input v-model:value="formState.mobile" placeholder="请输入要查询的联系人电话" allowClear>
       </a-input>
     </a-form-item>
@@ -273,13 +309,13 @@ onMounted(() => {
         <a-input v-model:value="form.contactName" placeholder="请输入联系人" allowClear />
       </a-form-item>
       <a-form-item label="联系电话" name="mobile">
-        <a-input v-model:value="form.mobile" placeholder="请输入联系电话" allowClear />
+        <a-input v-model:value="form.mobile" type="text" placeholder="请输入联系电话" allowClear />
       </a-form-item>
       <a-form-item label="详细地址" name="address">
-        <!-- <a-input v-model:value="form.address" /> -->
         <a-input-group compact>
-          <a-input v-model:value="address" style="width: calc(100% - 32px)" placeholder="请点击右侧图标选择详细地址" />
-          <img src="@/assets/images/23.png" class="cursor-pointer w-32px h-32px" alt="">
+          <a-input :disabled="true" v-model:value="address" style="width: calc(100% - 32px)"
+            placeholder="请点击右侧图标选择详细地址" />
+          <img src="@/assets/images/23.png" class="cursor-pointer w-32px h-32px" alt="" @click="showMap = true">
         </a-input-group>
       </a-form-item>
       <a-form-item label="门牌号" name="street">
@@ -310,11 +346,16 @@ onMounted(() => {
       </a-form-item>
     </a-form>
   </a-modal>
-  <a-modal v-model:visible="showMap" title="选择地址" :footer="null" width="1000px" style="top:20px;">
+  <a-modal bodyStyle="{padding: 0 !important;}" v-model:visible="showMap" title="选择地址" :footer="null" width="1400px"
+    style="top:20px;">
     <MapContainer @getMapData="getMapData"></MapContainer>
   </a-modal>
 </template>
 <style lang='scss' scoped>
+.map-container {
+  padding: 0 !important;
+}
+
 .category_box {
   display: flex;
   flex-wrap: wrap;

+ 19 - 19
src/views/register/index.vue

@@ -41,29 +41,29 @@ let checked = ref<boolean>(false)
 let showAgreement = ref<boolean>(false)
 
 interface FormState {
-  provinceName: string,
-  cityName: string,
-  cityCode: string,
+  provinceName: string;
+  cityName: string;
+  cityCode: string;
   districtName: string,
   userAccount: string;
   password: string;
   passwordAgain: string;
-  code?: number
-  licenseType: number,
-  merchantType: number,
-  categoryId: number,
-  address: string,
-  street: string,
-  merchantName: string,
-  bizLicenseNo: string,
-  bizLicense: string
-  legalPerson: string,
-  idcardType: number,
-  idcardNo: string,
-  idcardFront: string,
-  idcardBack: string,
-  bizLicenseIdcard: string,
-  contactName: string,
+  code?: number;
+  licenseType: number;
+  merchantType: number;
+  categoryId: number;
+  address: string;
+  street: string;
+  merchantName: string;
+  bizLicenseNo: string;
+  bizLicense: string;
+  legalPerson: string;
+  idcardType: number;
+  idcardNo: string;
+  idcardFront: string;
+  idcardBack: string;
+  bizLicenseIdcard: string;
+  contactName: string;
   mobile: string
 }
 const formState: UnwrapRef<FormState> = reactive({