gaoluyang
2026-06-24 712aa51536236d43e87273e4ce45ac5691dffad8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<script lang="ts" setup>
import type { MallDeliveryPickUpStoreApi } from '#/api/mall/trade/delivery/pickUpStore';
 
import { computed, ref } from 'vue';
 
import { useVbenModal } from '..\..\..\..\..\..\packages\effects\common-ui\src';
 
import { Button, message } from 'ant-design-vue';
import dayjs from 'dayjs';
 
import { useVbenForm } from '#/adapter/form';
import { getTradeConfig } from '#/api/mall/trade/config';
import {
  createDeliveryPickUpStore,
  getDeliveryPickUpStore,
  updateDeliveryPickUpStore,
} from '#/api/mall/trade/delivery/pickUpStore';
import { $t } from '#/locales';
 
import { useFormSchema } from '../data';
 
const emit = defineEmits(['success']);
const formData = ref<MallDeliveryPickUpStoreApi.DeliveryPickUpStore>();
const getTitle = computed(() => {
  return formData.value?.id
    ? $t('ui.actionTitle.edit', ['门店'])
    : $t('ui.actionTitle.create', ['门店']);
});
 
const mapVisible = ref(false); // 是否显示地图弹窗
const tencentLbsUrl = ref(''); // 腾讯位置服务 url
 
/** 获取经纬度相关方法 */
function selectAddress(loc: any) {
  if (loc.latlng?.lat) {
    formApi.setFieldValue('latitude', loc.latlng.lat);
  }
  if (loc.latlng?.lng) {
    formApi.setFieldValue('longitude', loc.latlng.lng);
  }
  mapVisible.value = false;
}
 
/** 初始化腾讯地图 */
async function initTencentLbsMap() {
  // 从配置中获取腾讯地图的 key
  const data = await getTradeConfig();
  const key = data.tencentLbsKey;
  if (!key) {
    message.warning('请先配置腾讯位置服务的 key');
    return;
  }
 
  // 设置 url
  if (!window) {
    return;
  }
  (window as any).selectAddress = selectAddress;
  window.addEventListener(
    'message',
    (event) => {
      // 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息
      const loc = event.data;
      if (loc && loc.module === 'locationPicker') {
        // 防止其他应用也会向该页面 post 信息,需判断 module 是否为 'locationPicker'
        (window.parent as any).selectAddress(loc);
      }
    },
    false,
  );
  tencentLbsUrl.value = `https://apis.map.qq.com/tools/locpicker?type=1&key=${key}&referer=myapp`;
}
 
const [Form, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
    labelWidth: 120,
  },
  fieldMappingTime: [['rangeTime', ['openingTime', 'closingTime'], 'HH:mm']],
  wrapperClass: 'grid-cols-2',
  layout: 'horizontal',
  schema: useFormSchema(),
  showDefaultActions: false,
});
 
const [Modal, modalApi] = useVbenModal({
  async onConfirm() {
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    modalApi.lock();
    // 提交表单
    const data =
      (await formApi.getValues()) as MallDeliveryPickUpStoreApi.DeliveryPickUpStore;
    try {
      await (formData.value?.id
        ? updateDeliveryPickUpStore(data)
        : createDeliveryPickUpStore(data));
      // 关闭并提示
      await modalApi.close();
      emit('success');
      message.success($t('ui.actionMessage.operationSuccess'));
    } finally {
      modalApi.unlock();
    }
  },
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      formData.value = undefined;
      return;
    }
    // 加载数据
    const data =
      modalApi.getData<MallDeliveryPickUpStoreApi.DeliveryPickUpStore>();
    if (!data || !data.id) {
      // 初始化地图
      await initTencentLbsMap();
      return;
    }
    modalApi.lock();
    try {
      formData.value = await getDeliveryPickUpStore(data.id);
      formData.value.rangeTime = [
        dayjs(formData.value.openingTime, 'HH:mm'),
        dayjs(formData.value.closingTime, 'HH:mm'),
      ];
      // 设置到 values
      await formApi.setValues(formData.value);
    } finally {
      modalApi.unlock();
      // 初始化地图
      await initTencentLbsMap();
    }
  },
});
</script>
 
<template>
  <Modal :title="getTitle" class="w-2/5">
    <Form class="mx-4" />
    <template #prepend-footer>
      <Button @click="mapVisible = true"> 获取经纬度 </Button>
    </template>
  </Modal>
 
  <!-- 地图弹窗 -->
  <a-modal
    v-model:open="mapVisible"
    title="获取经纬度"
    :width="800"
    :footer="null"
  >
    <iframe
      v-if="mapVisible && tencentLbsUrl"
      :src="tencentLbsUrl"
      class="h-[600px] w-full border-0"
    ></iframe>
  </a-modal>
</template>