wangfukang 2 days ago
parent
commit
a75c2d99ad
  1. 8
      src/api/app.js
  2. 13
      src/api/index.js
  3. 235
      src/views/app/business/courier/courier.vue
  4. 57
      src/views/app/business/logistics/logistics.vue
  5. 4
      src/views/app/business/luckey/luckey.vue
  6. 133
      src/views/app/shop/addEdit.vue
  7. 42
      src/views/app/shop/dictManage.vue
  8. 139
      src/views/app/shop/mernage.vue
  9. 13
      src/views/app/shop/shop.vue
  10. 140
      src/views/app/shopArea/shopArea.vue
  11. 244
      src/views/my-components/hiver/map.vue

8
src/api/app.js

@ -469,6 +469,14 @@ export const editShop = (params) => {
return putRequest('/app/shop/edit', params)
}
export const bindShopPrinter = (params) => {
return postRequest('/app/shop/bindPrinter', params)
}
export const getShopPrintConfig = (params) => {
return getRequest('/app/shop/printConfig', params)
}
export const findShopWorkerByMobile = (params) => {
return getRequest('/app/shop/findWorkerByMobile', params)
}

13
src/api/index.js

@ -744,6 +744,11 @@ export const setWorkerFullTime = (id, params) => {
return postRequest(`/worker/admin/fullTime/${id}`, params)
}
// 设置配送员中转接单状态
export const setWorkerTransferOrder = (id, params) => {
return postRequest(`/worker/admin/transferOrder/${id}`, params)
}
// 抢单工上线
export const onLineWorker = (params) => {
return postRequest(`/worker/onLine`, params)
@ -808,6 +813,14 @@ export const orderScheduling = (params) => {
export const orderSchedulingAdmin = (params) => {
return postBodyRequest('/mall/delivery/admin/pagebyworker', params)
}
// 后台分页查询配送员配送单量排名
export const getWorkerDeliveryOrderCountPage = (params) => {
return postBodyRequest('/mall/delivery/countOrdersPage', params)
}
// 后台分页查询中转配送员配送单量排名
export const getWorkerTransferDeliveryOrderCountPage = (params) => {
return postBodyRequest('/mall/delivery/countTransferOrdersPage', params)
}
// 查询区域配送时长
export const getDeliveryTimeSetting = (params) => {
return getRequest('/mall/admin/seckillGroup/deliveryTime/get', params)

235
src/views/app/business/courier/courier.vue

@ -36,6 +36,10 @@
</Form>
</Row>
<Row align="middle" justify="space-between" class="operation">
<div>
<Button type="primary" icon="ios-stats" @click="openOrderCountModal">查看配送单量</Button>
<Button type="warning" icon="ios-git-branch" style="margin-left: 8px" @click="openTransferOrderCountModal">查看中转单量</Button>
</div>
<div class="icons">
<Tooltip content="刷新" placement="top" transfer>
<Icon type="md-refresh" size="18" class="item" @click="getDataList" />
@ -90,6 +94,50 @@
<Button type="text" @click="ruleVisible = false">关闭</Button>
</div>
</Modal>
<Modal :title="orderCountTitle" v-model="orderCountVisible" :mask-closable="false" :width="800">
<Form inline :label-width="80">
<FormItem label="日期范围">
<DatePicker
:options="options"
clearable
v-model="orderCountSelectDate"
type="daterange"
format="yyyy-MM-dd"
placeholder="选择起始时间"
style="width: 240px"
@on-change="selectOrderCountDateRange"
></DatePicker>
</FormItem>
<FormItem>
<Button type="primary" icon="ios-search" @click="handleOrderCountSearch">搜索</Button>
<Button @click="handleOrderCountReset">重置</Button>
</FormItem>
</Form>
<Table
:loading="orderCountLoading"
border
:columns="orderCountColumns"
:data="orderCountData"
:size="tableSize"
></Table>
<Row type="flex" justify="end" class="page" style="margin-top: 12px">
<Page
:current="orderCountForm.pageNum"
:total="orderCountTotal"
:page-size="orderCountForm.pageSize"
@on-change="changeOrderCountPage"
@on-page-size-change="changeOrderCountPageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
<div slot="footer">
<Button type="text" @click="orderCountVisible = false">关闭</Button>
</div>
</Modal>
<withdraw-record-modal ref="withdrawRecordModal" :table-size="tableSize" />
<addEdit :data="form" :type="showType" v-model="showWorker" @on-submit="getDataList" />
</div>
@ -104,7 +152,10 @@
offLineWorker,
onLineWorker,
setWorkerFullTime,
setWorkerTransferOrder,
getWorkerRelaPriceByWorkerId,
getWorkerDeliveryOrderCountPage,
getWorkerTransferDeliveryOrderCountPage,
} from "@/api/index";
import {
shortcuts
@ -148,6 +199,49 @@
loadingExport: true,
ruleVisible: false,
ruleLoading: false,
orderCountVisible: false,
orderCountLoading: false,
orderCountMode: "delivery",
orderCountTitle: "查看配送单量",
orderCountSelectDate: null,
orderCountForm: {
regionId: JSON.parse(this.getStore("user")).departmentId,
startDate: "",
endDate: "",
pageNum: 1,
pageSize: 10,
},
orderCountData: [],
orderCountTotal: 0,
orderCountColumns: [
{
title: "排名",
width: 70,
align: "center",
render: (h, params) => {
const rank =
(this.orderCountForm.pageNum - 1) * this.orderCountForm.pageSize +
params.index +
1;
return h("span", rank);
},
},
{
title: "配送员名称",
key: "workerName",
minWidth: 140,
},
{
title: "手机号",
key: "mobile",
minWidth: 160,
},
{
title: "配送单量",
key: "orderCount",
minWidth: 120,
},
],
exportModalVisible: false,
importModalVisible: false,
drop: false,
@ -210,6 +304,14 @@
marginTop: "4px",
},
}, params.row.isFullTime == 1 ? "全职配送员" : "非全职配送员"),
h("Tag", {
props: {
color: params.row.canTransferOrder == 1 ? "orange" : "default",
},
style: {
marginTop: "4px",
},
}, params.row.canTransferOrder == 1 ? "可接中转" : "不接中转"),
]);
},
},
@ -351,7 +453,7 @@
{
title: "操作",
key: "action",
width: 420,
width: 470,
align: "center",
fixed: "right",
render: (h, params) => {
@ -424,6 +526,17 @@
},
fullTimeText
);
const transferText = params.row.canTransferOrder == 1 ? "取消中转" : "设置中转";
const transferAction = h(
"a", {
on: {
click: () => {
this.changeTransferOrder(params.row);
},
},
},
transferText
);
return h("div", [
/* h(
"a", {
@ -488,6 +601,12 @@
type: "vertical",
},
}),
transferAction,
h("Divider", {
props: {
type: "vertical",
},
}),
h(
"a", {
on: {
@ -619,6 +738,100 @@
openWithdrawRecords(v) {
this.$refs.withdrawRecordModal.open(v, "worker");
},
formatToday() {
const d = new Date();
const m = d.getMonth() + 1;
const day = d.getDate();
return (
d.getFullYear() +
"-" +
(m < 10 ? "0" + m : m) +
"-" +
(day < 10 ? "0" + day : day)
);
},
openOrderCountModal() {
const today = this.formatToday();
this.orderCountMode = "delivery";
this.orderCountTitle = "查看配送单量";
this.orderCountVisible = true;
this.orderCountSelectDate = [today, today];
this.orderCountForm = {
regionId: JSON.parse(this.getStore("user")).departmentId,
startDate: today,
endDate: today,
pageNum: 1,
pageSize: 10,
};
this.getOrderCountList();
},
openTransferOrderCountModal() {
const today = this.formatToday();
this.orderCountMode = "transfer";
this.orderCountTitle = "查看中转单量";
this.orderCountVisible = true;
this.orderCountSelectDate = [today, today];
this.orderCountForm = {
regionId: JSON.parse(this.getStore("user")).departmentId,
startDate: today,
endDate: today,
pageNum: 1,
pageSize: 10,
};
this.getOrderCountList();
},
selectOrderCountDateRange(v) {
if (v && v[0] && v[1]) {
this.orderCountForm.startDate = v[0];
this.orderCountForm.endDate = v[1];
} else {
this.orderCountForm.startDate = "";
this.orderCountForm.endDate = "";
}
},
handleOrderCountSearch() {
this.orderCountForm.pageNum = 1;
this.getOrderCountList();
},
handleOrderCountReset() {
const today = this.formatToday();
this.orderCountSelectDate = [today, today];
this.orderCountForm.startDate = today;
this.orderCountForm.endDate = today;
this.orderCountForm.pageNum = 1;
this.orderCountForm.pageSize = 10;
this.getOrderCountList();
},
changeOrderCountPage(v) {
this.orderCountForm.pageNum = v;
this.getOrderCountList();
},
changeOrderCountPageSize(v) {
this.orderCountForm.pageSize = v;
this.orderCountForm.pageNum = 1;
this.getOrderCountList();
},
getOrderCountList() {
this.orderCountLoading = true;
const request = this.orderCountMode === "transfer"
? getWorkerTransferDeliveryOrderCountPage
: getWorkerDeliveryOrderCountPage;
request(this.orderCountForm)
.then((res) => {
this.orderCountLoading = false;
if (res.success) {
this.orderCountData = res.result.records || [];
this.orderCountTotal = res.result.total || 0;
if (this.orderCountData.length == 0 && this.orderCountForm.pageNum > 1) {
this.orderCountForm.pageNum -= 1;
this.getOrderCountList();
}
}
})
.catch(() => {
this.orderCountLoading = false;
});
},
handleSearch() {
this.searchForm.pageNum = 1;
this.searchForm.pageSize = 10;
@ -831,6 +1044,26 @@
},
});
},
changeTransferOrder(v) {
const canTransferOrder = v.canTransferOrder == 1 ? 0 : 1;
const actionText = canTransferOrder == 1 ? "设置为可接中转单" : "取消接中转单";
this.$Modal.confirm({
title: actionText,
content: "您确认要将配送员 " + v.workerName + " " + actionText + "吗?",
loading: true,
onOk: () => {
setWorkerTransferOrder(v.workerId, {
canTransferOrder
}).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getDataList();
}
});
},
});
},
remove(v) {
this.$Modal.confirm({
title: "确认删除",

57
src/views/app/business/logistics/logistics.vue

@ -65,6 +65,14 @@
word-break: break-all;
}
.transfer-worker-info {
margin-top: 4px;
color: #515a6e;
font-size: 12px;
line-height: 18px;
word-break: break-all;
}
.transfer-worker-disabled-row td {
background-color: #f7f7f7 !important;
color: #c5c8ce;
@ -91,6 +99,8 @@
<Tabs v-else v-model="deliveryTab" :animated="false" @on-click="changeDeliveryTab">
<TabPane :label="'待取货(' + deliveryCounts.daiqu + ')'" name="daiqu"></TabPane>
<TabPane :label="'待送达(' + deliveryCounts.daisong + ')'" name="daisong"></TabPane>
<TabPane label="已完成" name="wancheng"></TabPane>
<TabPane label="已取消" name="quxiao"></TabPane>
</Tabs>
</div>
<div v-else-if="tabName === 'setting'" style="padding: 20px 0;">
@ -280,7 +290,9 @@
};
const DELIVERY_STATUS_MAP = {
daiqu: 1,
daisong: 2
daisong: 2,
wancheng: 3,
quxiao: 4
};
export default {
@ -532,6 +544,9 @@
style: { color: "red", marginTop: "4px", fontWeight: 700 }
}, "商家已出餐:" + this.formatDateTime(params.row.shopMakeTime)) : null,
h("span", { class: "must-finish-time" }, "要求送达:" +this.formatDateTime(params.row.mustFinishTime)),
Number(params.row.status) === 3 && params.row.finishTime ? h("div", {
style: { color: "#2d8cf0", marginTop: "4px", fontWeight: 700 }
}, "实际送达:" + this.formatDateTime(params.row.finishTime)) : null,
this.isNearMustFinishTime(params.row) ? h("div", {
style: { color: "#515a6e", marginTop: "4px", fontWeight: 700 }
}, this.getMustFinishWarningText(params.row)) : null
@ -549,13 +564,13 @@
}, {
title: "配送员",
key: "workerName",
width: 170,
width: 160,
align: "center",
render: (h, params) => this.renderWorkerInfo(h, params.row, clickableWorker)
},{
title: "配送类型",
key: "deliveryType",
width: 140,
width: 150,
align: "center",
render: (h, params) => this.renderDeliveryTags(h, params.row)
}, {
@ -607,7 +622,10 @@
this.deliverySearchForm.pageNum = 1;
this.deliverySearchForm.status = DELIVERY_STATUS_MAP[v];
this.getLogisticsInfo();
this.refreshOrderCounts();
// /
if (v === "daiqu" || v === "daisong") {
this.refreshOrderCounts();
}
},
handleGetAreaChange(v) {
if (this.suppressAreaChange) return;
@ -1227,6 +1245,12 @@
if (row.transferPickupCode) {
tags.push(h("div", { class: "transfer-pickup-code" }, "中转码:" + row.transferPickupCode));
}
if (row.transferWorkerName || row.transferWorkerMobile) {
tags.push(h("div", { class: "transfer-worker-info" }, [
h("div", "中转员:" + (row.transferWorkerName || "-")),
row.transferWorkerMobile ? h("div", "电话:" + row.transferWorkerMobile) : null
]));
}
}
if (row.isBig == 1) {
tags.push(h("Tag", { props: { color: "red" } }, "超大/超重"));
@ -1328,13 +1352,34 @@
return new Date(text.replace(/-/g, "/")).getTime();
},
isNearMustFinishTime(item) {
const mustFinishTime = this.parseDeliveryTime(item && item.mustFinishTime);
if (!item) return false;
const status = Number(item.status);
//
if (status === 4) return false;
const mustFinishTime = this.parseDeliveryTime(item.mustFinishTime);
if (isNaN(mustFinishTime)) return false;
// finishTime
if (status === 3) {
const finishTime = this.parseDeliveryTime(item.finishTime);
if (isNaN(finishTime)) return false;
return finishTime > mustFinishTime;
}
// /
return mustFinishTime - Date.now() <= 10 * 60 * 1000;
},
getMustFinishWarningText(item) {
const mustFinishTime = this.parseDeliveryTime(item && item.mustFinishTime);
if (!isNaN(mustFinishTime) && Date.now() > mustFinishTime) {
if (isNaN(mustFinishTime)) return "";
const status = Number(item && item.status);
if (status === 4) return "";
if (status === 3) {
const finishTime = this.parseDeliveryTime(item.finishTime);
if (!isNaN(finishTime) && finishTime > mustFinishTime) {
return "已超时";
}
return "";
}
if (Date.now() > mustFinishTime) {
return "已超时";
}
return "临近送达";

4
src/views/app/business/luckey/luckey.vue

@ -2,7 +2,7 @@
<div class="luckey">
<Card>
<Row class="region-bar">
<span class="region-tip" style="margin-right:20px;">当前校区<b>{{ regionName || '未识别(请确认账号已绑定校区)' }}</b></span>
<!-- <span class="region-tip" style="margin-right:20px;">当前校区<b>{{ regionName || '未识别(请确认账号已绑定校区)' }}</b></span> -->
<Button type="primary" icon="ios-refresh" @click="reloadActive" :disabled="!regionId">刷新</Button>
</Row>
@ -556,7 +556,7 @@
]
if (!this.isPoolDrawn(params.row)) {
actions.unshift(h('Button', { props: { type: 'text', size: 'small' }, on: { click: () => this.openPool(params.row) } }, '编辑'))
actions.push(h('Button', { props: { type: 'text', size: 'small' }, style: { color: '#ed4014' }, on: { click: () => this.delPool(params.row) } }, '删除'))
/* actions.push(h('Button', { props: { type: 'text', size: 'small' }, style: { color: '#ed4014' }, on: { click: () => this.delPool(params.row) } }, '删除')) */
}
return h('div', actions)
}

133
src/views/app/shop/addEdit.vue

@ -40,6 +40,21 @@
</Select>
</FormItem>
</Col>
<Col span="12" v-if="form.merchantType == 1">
<FormItem label="起送价格" prop="startingPrice">
<InputNumber v-model="form.startingPrice" :min="0" :step="0.1" style="width: 100%" />
</FormItem>
</Col>
<Col span="12" v-else>
<FormItem label="学生商家" prop="isStudent">
<RadioGroup v-model="form.isStudent">
<Radio :label="1"></Radio>
<Radio :label="0"></Radio>
</RadioGroup>
</FormItem>
</Col>
</Row>
<Row :gutter="32" v-if="form.merchantType == 1">
<Col span="12">
<FormItem label="学生商家" prop="isStudent">
<RadioGroup v-model="form.isStudent">
@ -109,6 +124,34 @@
</FormItem>
</Col>
</Row>
<Divider v-if="type == '1'">云打印机</Divider>
<Alert v-if="type == '1' && form.printerSn" type="success" show-icon>
已绑定{{ form.printerName || form.shopName || "云打印机" }}{{ form.printerSn }}
</Alert>
<Row :gutter="32" v-if="type == '1'">
<Col span="12">
<FormItem label="打印机SN">
<Input v-model="printerForm.sn" autocomplete="off" :maxlength="50" placeholder="请输入打印机编号" />
</FormItem>
</Col>
<Col span="12">
<FormItem label="设备绑定码">
<Input type="password" v-model="printerForm.key" autocomplete="off" :maxlength="255" placeholder="请输入设备绑定码" />
</FormItem>
</Col>
</Row>
<Row :gutter="32" v-if="type == '1'">
<Col span="12">
<FormItem label="设备名称">
<Input v-model="printerForm.name" autocomplete="off" :maxlength="50" placeholder="默认使用店铺名称" />
</FormItem>
</Col>
<Col span="12">
<FormItem label="操作">
<Button type="primary" :loading="printerBindLoading" @click="bindPrinter">绑定打印机</Button>
</FormItem>
</Col>
</Row>
<Divider>商家资质</Divider>
<Row :gutter="32">
<Col span="12">
@ -264,6 +307,8 @@
import {
addShop,
editShop,
bindShopPrinter,
getShopPrintConfig,
findShopWorkerByMobile,
initShopArea,
loadShopArea,
@ -302,12 +347,19 @@
passColor: "",
submitLoading: false,
workerLoading: false,
printerBindLoading: false,
workerMobile: "",
printerForm: {
sn: "",
key: "",
name: "",
},
maxHeight: 510,
form: {
address: [],
merchantType: 1,
isStudent: 0,
startingPrice: 0,
openKitchenVideoUrl: "",
supportDineIn: 0,
qita: [],
@ -477,8 +529,75 @@
}
});
},
bindPrinter() {
if (!this.form.id) {
this.$Message.warning("请先保存店铺后再绑定打印机");
return;
}
const sn = (this.printerForm.sn || "").trim();
const key = (this.printerForm.key || "").trim();
const name = (this.printerForm.name || this.form.shopName || "").trim();
if (!sn) {
this.$Message.warning("请输入打印机SN");
return;
}
if (!key) {
this.$Message.warning("请输入设备绑定码");
return;
}
this.printerBindLoading = true;
bindShopPrinter({
shopId: this.form.id,
sn,
key,
name,
shopName: this.form.shopName || "",
}).then((res) => {
this.printerBindLoading = false;
if (res.success) {
if (res.result) {
this.$set(this.form, "printerSn", res.result.printerSn || sn);
this.$set(this.form, "printerName", res.result.printerName || name);
this.$set(this.printerForm, "name", res.result.printerName || name);
}
this.$Message.success(res.message || "打印机绑定成功");
} else {
this.$Message.error(res.message || "打印机绑定失败");
}
}).catch(() => {
this.printerBindLoading = false;
});
},
loadPrintConfig() {
if (!this.form.id) return;
getShopPrintConfig({
shopId: this.form.id
}).then((res) => {
if (res.success && res.result) {
const printerSn = res.result.printerSn || "";
const printerName = res.result.printerName || this.form.shopName || "";
this.$set(this.form, "printerSn", printerSn);
this.$set(this.form, "printerName", printerName);
this.$set(this.form, "printingMethod", res.result.printingMethod || "bluetooth");
this.printerForm = {
sn: printerSn,
key: "",
name: printerName,
};
}
}).catch(() => {});
},
handleSelectShopAreaTree(v) {
this.form.shopArea = Array.isArray(v) ? (v[0] || "") : v;
if (!this.form.shopArea) {
this.form.shopAreaTitle = "";
return;
}
this.$nextTick(() => {
if (this.$refs.shopAreaTree) {
this.form.shopAreaTitle = this.$refs.shopAreaTree.shopAreaTitle || "";
}
});
},
handleSelectTransferAddress(v) {
const value = Array.isArray(v) ? v[0] : v;
@ -574,6 +693,7 @@
this.form.merchantType = Number(this.form.merchantType);
this.form.isStudent = Number(this.form.isStudent);
this.form.supportDineIn = Number(this.form.supportDineIn);
this.form.startingPrice = this.form.merchantType == 1 ? Number(this.form.startingPrice || 0) : 0;
this.form.openKitchenVideoUrl = this.form.openKitchenVideoUrl || "";
if (!this.form.contactPhone && this.form.mobile) {
this.form.contactPhone = this.form.mobile;
@ -723,6 +843,7 @@
this.form = Object.assign({}, registerData, {
merchantType: registerData.merchantType == null ? 1 : Number(registerData.merchantType),
isStudent: registerData.isStudent == null ? 0 : Number(registerData.isStudent),
startingPrice: registerData.startingPrice == null ? 0 : Number(registerData.startingPrice),
openKitchenVideoUrl: registerData.openKitchenVideoUrl || "",
supportDineIn: registerData.supportDineIn == null ? 0 : Number(registerData.supportDineIn),
contactPhone: registerData.contactPhone || registerData.mobile || "",
@ -742,6 +863,12 @@
transferAddressId: data.transferAddressId || "",
transferAddressName: data.transferAddressName || "",
});
this.printerForm = {
sn: this.form.printerSn || "",
key: "",
name: this.form.printerName || this.form.shopName || "",
};
this.loadPrintConfig();
this.workerMobile = this.form.workerPhone || "";
this.$nextTick(() => {
//
@ -758,6 +885,7 @@
address: [],*/
merchantType: 1,
isStudent: 0,
startingPrice: 0,
openKitchenVideoUrl: "",
supportDineIn: 0,
qita: [],
@ -765,6 +893,11 @@
orderBkge: 0,
supportTransferDelivery: 0,
};
this.printerForm = {
sn: "",
key: "",
name: "",
};
this.workerMobile = "";
this.$nextTick(() => {
this.$refs.shopAreaTree.setData("", "");

42
src/views/app/shop/dictManage.vue

@ -151,7 +151,7 @@
<Form ref="searchForm" :model="searchForm" inline :label-width="70">
<FormItem label="商品名称" prop="title">
<Input type="text" v-model="searchForm.productName" placeholder="请输入" clearable
style="width: 200px" />
style="width: 300px" />
</FormItem>
<FormItem style="margin-left: -35px" class="br">
<Button @click="handleSearch" type="primary" icon="ios-search">搜索</Button>
@ -257,7 +257,7 @@
</Modal>
<Modal :title="attributeValueFormTitle" v-model="attributeValueFormVisible" :mask-closable="false" :width="420">
<Form ref="attributeValueForm" :model="attributeValueForm" :rules="attributeValueFormRules" :label-width="90">
<Form ref="attributeValueForm" :model="attributeValueForm" :rules="attributeValueFormRules" :label-width="100">
<FormItem label="属性值名称" prop="value">
<Input v-model="attributeValueForm.value" placeholder="请输入属性值名称" />
</FormItem>
@ -275,17 +275,17 @@
<upload-pic-input v-model="addGoodsForm.productPicture"></upload-pic-input>
</FormItem>
</Col>
<Col span="6">
<Col span="8">
<FormItem label="名称" prop="productName">
<Input v-model="addGoodsForm.productName" :maxlength="20" show-word-limit placeholder="最多20字" />
<Input v-model="addGoodsForm.productName" :maxlength="20" show-word-limit placeholder="最多20字" style="width: 100%" />
</FormItem>
</Col>
<Col span="6">
<Col span="4">
<FormItem label="排名" prop="orderFiled">
<Input v-model="addGoodsForm.orderFiled" type="number" :min="0" :max="100000" placeholder="0-100000整数" />
</FormItem>
</Col>
<Col span="6">
<Col span="4">
<FormItem label="商品分类" prop="categoryId">
<Select v-model="addGoodsForm.categoryId" filterable placeholder="请选择商品分类" @on-change="selectGoodsCategory">
<Option v-for="item in goodsCategoryOptions" :value="item.id" :key="item.id">{{ item.categoryName || item.title }}</Option>
@ -313,7 +313,7 @@
<div v-for="(item,index) in addGoodsForm.productGroupBuyPrices" style="display: flex;margin-top:5px;">
<Input v-model="item.groupCount" type="number" :min="2" :max="10" style="padding-right: 10px;" @on-blur="validateGroupCount(index)" placeholder="人数2-10整数" />
<Input v-model="item.groupPrice" type="number" :min="0.1" :max="9999" style="padding-right: 10px;" @on-blur="validateGroupPrice(index)" placeholder="价格0.1-9999,最多2位小数"/>
<button @click="delGroup(index)" v-if="addGoodsForm.productGroupBuyPrices.length>1" style="width: 120px;height: 30px;line-height: 30px;color: red;border:none;background: #fff;">删除</button>
<button @click="delGroup(index)" style="width: 120px;height: 30px;line-height: 30px;color: red;border:none;background: #fff;">删除</button>
</div>
<div @click="addGroup()" style="margin-top:5px;width: 80px;height: 30px;text-align: center;line-height: 30px;background: #008ba0;color:#fff;">
新增拼团
@ -618,6 +618,14 @@
key: "productName",
minWidth: 60,
},
{
title: "原价",
key: "specPrice",
width: 100,
render: (h, params) => {
return h("span", this.getOriginalPrice(params.row.attributeListPrice));
},
},
{
title: "排名",
key: "orderFiled",
@ -877,7 +885,7 @@
{
title: "属性值名称",
key: "value",
minWidth: 160,
minWidth: 170,
},
{
title: "操作",
@ -924,6 +932,19 @@
}
},
methods: {
getOriginalPrice(attributeListPrice) {
if (!attributeListPrice) return "";
let list = attributeListPrice;
if (typeof attributeListPrice == "string") {
try {
list = JSON.parse(attributeListPrice);
} catch (e) {
return "";
}
}
if (!Array.isArray(list) || list.length == 0) return "";
return list[0].specPrice || "";
},
isIntegerInRange(value, min, max) {
if (value === "" || value === null || value === undefined) return false;
const text = String(value);
@ -1585,12 +1606,13 @@
},
changePage(v) {
this.searchForm.pageNum = v;
// this.getDataList();
this.getDataList();
this.clearSelectAll();
},
changePageSize(v) {
this.searchForm.pageSize = v;
// this.getDataList();
this.searchForm.pageNum = 1;
this.getDataList();
},
getDataList() {
this.loading = true;

139
src/views/app/shop/mernage.vue

@ -23,20 +23,18 @@
</FormItem>
</Col>
</Row>
<Row :gutter="32">
<Col span="12">
<FormItem label="营业开始时间" prop="businessHourBegin">
<DatePicker v-model="form.businessHourBegin" style="display: block" type="time"
format="HH:mm" transfer></DatePicker>
</FormItem>
</Col>
<Col span="12">
<FormItem label="营业结束时间" prop="businessHourEnd">
<DatePicker v-model="form.businessHourEnd" style="display: block" type="time" format="HH:mm"
transfer></DatePicker>
</FormItem>
</Col>
</Row>
<FormItem label="营业时段">
<div v-for="(item, index) in businessHourPeriods" :key="index" class="business-hour-row">
<DatePicker v-model="item.begin" style="width: 140px" type="time" format="HH:mm"
placeholder="开始" transfer></DatePicker>
<span class="business-hour-sep"></span>
<DatePicker v-model="item.end" style="width: 140px" type="time" format="HH:mm"
placeholder="结束" transfer></DatePicker>
<Button type="text" style="color: #ed4014; margin-left: 8px"
@click="removeBusinessHour(index)" :disabled="businessHourPeriods.length <= 1">删除</Button>
</div>
<Button type="dashed" icon="md-add" long @click="addBusinessHour" style="margin-top: 8px">添加时段</Button>
</FormItem>
<Row :gutter="32">
<Col span="12">
<FormItem label="营业状态" class="form-noheight">
@ -142,6 +140,13 @@
form: {},
takeData: {},
isAdd: true,
shopType: [],
yesorno: [],
status: [],
businessHourPeriods: [{
begin: "",
end: ""
}],
formValidate: {
//
username: [{
@ -193,6 +198,9 @@
},
methods: {
init(data) {
if (!data || !data.id) {
return;
}
this.getRoleList();
getByShopId({
"shopId": data.id
@ -204,9 +212,14 @@
this.form.shopName = data.shopName
this.form.regionId = data.regionId
this.isAdd = true
this.businessHourPeriods = [{
begin: "",
end: ""
}]
} else {
this.isAdd = false
this.form = res.result
this.businessHourPeriods = this.parseBusinessHourPeriods(res.result)
for (let i = 0; i < this.shopType.length; i++) {
if (this.shopType[i].title == this.form.type) {
this.form.type = this.shopType[i].value
@ -222,6 +235,81 @@
});
},
formatTimeValue(value) {
if (!value) return "";
if (typeof value === "string") {
return value.length >= 5 ? value.substring(0, 5) : value;
}
const date = value instanceof Date ? value : new Date(value);
if (isNaN(date.getTime())) return "";
const h = date.getHours();
const m = date.getMinutes();
return (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m);
},
parseBusinessHourPeriods(takeaway) {
if (!takeaway) {
return [{
begin: "",
end: ""
}];
}
let list = takeaway.businessHourList;
if ((!list || !list.length) && takeaway.businessHours) {
try {
list = typeof takeaway.businessHours === "string" ?
JSON.parse(takeaway.businessHours) :
takeaway.businessHours;
} catch (e) {
list = [];
}
}
if (list && list.length) {
return list.map((item) => ({
begin: this.formatTimeValue(item.begin),
end: this.formatTimeValue(item.end),
}));
}
if (takeaway.businessHourBegin || takeaway.businessHourEnd) {
return [{
begin: this.formatTimeValue(takeaway.businessHourBegin),
end: this.formatTimeValue(takeaway.businessHourEnd),
}];
}
return [{
begin: "",
end: ""
}];
},
addBusinessHour() {
this.businessHourPeriods.push({
begin: "",
end: ""
});
},
removeBusinessHour(index) {
if (this.businessHourPeriods.length <= 1) return;
this.businessHourPeriods.splice(index, 1);
},
buildBusinessHoursPayload() {
const periods = [];
for (let i = 0; i < this.businessHourPeriods.length; i++) {
const begin = this.formatTimeValue(this.businessHourPeriods[i].begin);
const end = this.formatTimeValue(this.businessHourPeriods[i].end);
if (!begin || !end) {
this.$Message.warning("请完善第" + (i + 1) + "个营业时段");
return null;
}
periods.push({
begin,
end
});
}
if (!periods.length) {
this.$Message.warning("请至少设置一个营业时段");
return null;
}
return periods;
},
getRoleList() {
getUsersByRoleName("ROLE_OWNER").then((res) => {
if (res.success) {
@ -254,11 +342,17 @@
this.form.passStrength = strength;
},
submit1() {
const periods = this.buildBusinessHoursPayload();
if (!periods) return;
this.form.businessHours = JSON.stringify(periods);
this.form.businessHourBegin = periods[0].begin;
this.form.businessHourEnd = periods[0].end;
// form List businessHours JSON
delete this.form.businessHourList;
this.form.shoprank = 0
//
if (this.form.type != '' && this.form.type != null) {
this.shopType.forEach(item => {
debugger;
if (this.form.type == item.value) {
this.form.type = item.value;
}
@ -323,11 +417,22 @@
},
},
mounted() {
this.init();
this.getRoleList();
},
};
</script>
<style lang="less">
@import "@/styles/drawer-common.less";
</style>
.business-hour-row {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.business-hour-sep {
margin: 0 10px;
color: #808695;
}
</style>

13
src/views/app/shop/shop.vue

@ -31,8 +31,8 @@
<Card>
<Row v-show="openSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70">
<FormItem label="店铺名称" prop="keyWord">
<Input type="text" v-model="searchForm.keyWord" clearable placeholder="请输入店铺名称"
<FormItem label="店铺名称" prop="shopName">
<Input type="text" v-model="searchForm.shopName" clearable placeholder="请输入店铺名称"
style="width: 200px" />
</FormItem>
<FormItem label="商家类型" prop="merchantType">
@ -170,6 +170,7 @@
searchForm: {
id: "",
keyWord: "",
shopName: "",
shopOwnerId: "",
shopMangerId: "",
shopArea: "",
@ -201,9 +202,10 @@
fixed: "left",
},
{
type: "index",
width: 60,
align: "center",
title: "排名",
key: "shoprank",
minWidth: 60,
sortable: true,
fixed: "left",
},
{
@ -470,6 +472,7 @@
this.$refs.searchForm.resetFields();
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.keyWord = "";
this.searchForm.startDate = "";
this.searchForm.endDate = "";
if (this.$refs.dep) {

140
src/views/app/shopArea/shopArea.vue

@ -172,22 +172,15 @@
</RadioGroup>
<div class="geo-tip">社会区域首页展示待成团并隐藏配送入口</div>
</FormItem>
<FormItem v-if="showEditParentAgent" label="区域中心">
<FormItem v-if="showEditParentAgent" label="匹配范围">
<Map
id="shopAreaEditMap"
v-model="form.geoPosition"
text="地图选点"
placeholder="经度, 纬度"
v-model="form.geoPolygon"
mode="polygon"
text="绘制匹配范围"
placeholder="请绘制多边形范围"
/>
<div class="geo-tip">用于小程序定位自动绑定校区请用高德地图选点GCJ-02未设置则不参与自动匹配</div>
</FormItem>
<FormItem v-if="showEditParentAgent" label="匹配半径">
<Input
v-model="form.radiusMeters"
placeholder="请输入匹配半径"
style="width: 200px"
/>
<span style="margin-left: 8px"></span>
<div class="geo-tip">用于小程序定位自动绑定区域请用高德地图绘制多边形范围GCJ-02未绘制则不参与自动匹配</div>
</FormItem>
<FormItem label="排序值" prop="sortOrder">
@ -319,22 +312,15 @@
</RadioGroup>
<div class="geo-tip">社会区域首页展示待成团并隐藏配送入口</div>
</FormItem>
<FormItem v-if="showAddParentAgent" label="区域中心">
<FormItem v-if="showAddParentAgent" label="匹配范围">
<Map
id="shopAreaAddMap"
v-model="formAdd.geoPosition"
text="地图选点"
placeholder="经度, 纬度"
/>
<div class="geo-tip">用于小程序定位自动绑定校区请用高德地图选点GCJ-02未设置则不参与自动匹配</div>
</FormItem>
<FormItem v-if="showAddParentAgent" label="匹配半径">
<Input
v-model="formAdd.radiusMeters"
placeholder="请输入匹配半径"
style="width: 200px"
v-model="formAdd.geoPolygon"
mode="polygon"
text="绘制匹配范围"
placeholder="请绘制多边形范围"
/>
<span style="margin-left: 8px"></span>
<div class="geo-tip">用于小程序定位自动绑定区域请用高德地图绘制多边形范围GCJ-02未绘制则不参与自动匹配</div>
</FormItem>
<FormItem label="排序值" prop="sortOrder">
<Tooltip
@ -499,6 +485,7 @@ export default {
centerLng: null,
centerLat: null,
radiusMeters: "",
geoPolygon: "",
geoPosition: "",
},
formAdd: {},
@ -711,47 +698,63 @@ export default {
this.$set(target, "centerLng", null);
this.$set(target, "centerLat", null);
this.$set(target, "radiusMeters", "");
this.$set(target, "geoPolygon", "");
this.$set(target, "geoPosition", "");
},
buildGeoPosition(lng, lat) {
if (lng === "" || lng == null || lat === "" || lat == null) {
return "";
normalizePolygonValue(value) {
if (!value || !String(value).trim()) return "";
let points;
try {
points = JSON.parse(value);
} catch (e) {
this.$Message.warning("匹配范围格式不合法,请重新绘制");
return null;
}
return `${lng}, ${lat}`;
if (!Array.isArray(points) || points.length < 3) {
this.$Message.warning("匹配范围至少需要 3 个点");
return null;
}
const normalized = [];
for (let i = 0; i < points.length; i++) {
const item = points[i];
const lng = Array.isArray(item) ? Number(item[0]) : Number(item && item.lng);
const lat = Array.isArray(item) ? Number(item[1]) : Number(item && item.lat);
if (
!Number.isFinite(lng) ||
!Number.isFinite(lat) ||
lng < -180 ||
lng > 180 ||
lat < -90 ||
lat > 90
) {
this.$Message.warning("匹配范围坐标不合法,请重新绘制");
return null;
}
normalized.push([
Number(lng.toFixed(6)),
Number(lat.toFixed(6)),
]);
}
return JSON.stringify(normalized);
},
applyGeoPosition(target) {
applyGeoPolygon(target) {
if (!this.isRootArea(target.parentId)) {
this.clearGeoValue(target);
return true;
}
const position = (target.geoPosition || "").trim();
if (!position) {
this.clearGeoValue(target);
return true;
}
const parts = position.split(",");
if (parts.length < 2) {
this.$Message.warning("区域中心坐标格式应为:经度, 纬度");
return false;
}
const lng = Number(parts[0].trim());
const lat = Number(parts[1].trim());
if (!Number.isFinite(lng) || !Number.isFinite(lat)) {
this.$Message.warning("区域中心坐标不合法");
const polygon = this.normalizePolygonValue(target.geoPolygon);
if (polygon === null) {
return false;
}
if (lng < -180 || lng > 180 || lat < -90 || lat > 90) {
this.$Message.warning("区域中心坐标超出范围");
return false;
}
const radius = Number(target.radiusMeters);
if (!Number.isInteger(radius) || radius <= 0) {
this.$Message.warning("请设置有效的匹配半径(米)");
return false;
if (!polygon) {
this.clearGeoValue(target);
return true;
}
this.$set(target, "centerLng", lng);
this.$set(target, "centerLat", lat);
this.$set(target, "radiusMeters", radius);
this.$set(target, "geoPolygon", polygon);
this.$set(target, "centerLng", null);
this.$set(target, "centerLat", null);
this.$set(target, "radiusMeters", "");
this.$set(target, "geoPosition", "");
return true;
},
normalizeParentAgent(target) {
@ -775,20 +778,9 @@ export default {
}
},
syncGeoFromEntity(target) {
this.$set(
target,
"geoPosition",
this.buildGeoPosition(target.centerLng, target.centerLat)
);
if (
target.radiusMeters === "" ||
target.radiusMeters === "null" ||
target.radiusMeters == null
) {
this.$set(target, "radiusMeters", "");
} else {
this.$set(target, "radiusMeters", String(target.radiusMeters));
}
this.$set(target, "geoPolygon", target.geoPolygon || "");
this.$set(target, "geoPosition", "");
this.$set(target, "radiusMeters", "");
},
init() {
this.getParentList();
@ -944,6 +936,7 @@ export default {
centerLng: null,
centerLat: null,
radiusMeters: "",
geoPolygon: "",
geoPosition: "",
};
this.editTitle = "";
@ -984,7 +977,7 @@ export default {
this.$Message.warning("请先点击选择要修改的区域");
return;
}
if (!this.applyGeoPosition(this.form)) {
if (!this.applyGeoPolygon(this.form)) {
return;
}
this.submitLoading = true;
@ -996,6 +989,7 @@ export default {
if (payload.centerLng == null) payload.centerLng = "";
if (payload.centerLat == null) payload.centerLat = "";
if (payload.radiusMeters == null) payload.radiusMeters = "";
if (payload.geoPolygon == null) payload.geoPolygon = "";
editShopArea(payload).then((res) => {
this.submitLoading = false;
if (res.success) {
@ -1012,7 +1006,7 @@ export default {
this.normalizeParentAgent(this.formAdd);
this.$refs.formAdd.validate((valid) => {
if (valid) {
if (!this.applyGeoPosition(this.formAdd)) {
if (!this.applyGeoPolygon(this.formAdd)) {
return;
}
this.submitLoading = true;
@ -1022,6 +1016,7 @@ export default {
if (payload.centerLng == null) payload.centerLng = "";
if (payload.centerLat == null) payload.centerLat = "";
if (payload.radiusMeters == null) payload.radiusMeters = "";
if (payload.geoPolygon == null) payload.geoPolygon = "";
addShopArea(payload).then((res) => {
this.submitLoading = false;
if (res.success) {
@ -1088,6 +1083,7 @@ export default {
centerLng: null,
centerLat: null,
radiusMeters: "",
geoPolygon: "",
geoPosition: "",
};
this.modalVisible = true;

244
src/views/my-components/hiver/map.vue

@ -100,10 +100,14 @@
<div slot="footer">
<Row align="middle" justify="space-between">
<div style="flex: 1; margin-right: 12px">
<Alert show-icon style="margin-bottom: 0"
>当前选点坐标{{ currentValue || "未选择" }}</Alert
<Alert show-icon style="margin-bottom: 0"
>{{ valueSummaryLabel }}{{ valueSummaryText }}</Alert
>
<div class="locate-tip">坐标为高德 GCJ-02可搜索定位或点击地图选点</div>
<div class="locate-tip">{{ locateTip }}</div>
<div v-if="isPolygonMode" class="polygon-actions">
<Button size="small" @click="undoPolygonPoint">撤销上一个点</Button>
<Button size="small" @click="clearPolygonValue">清空范围</Button>
</div>
</div>
<div>
<Button type="text" @click="showModal = false">取消</Button>
@ -193,12 +197,21 @@ export default {
type: Boolean,
default: true,
},
mode: {
type: String,
default: "point",
},
},
data() {
return {
data: this.value,
map: null,
marker: null,
referenceMarker: null,
polygon: null,
polygonLine: null,
polygonEditor: null,
vertexMarkers: [],
placeSearch: null,
currentValue: "",
showModal: false,
@ -210,6 +223,26 @@ export default {
mapReady: false,
};
},
computed: {
isPolygonMode() {
return this.mode === "polygon";
},
valueSummaryLabel() {
return this.isPolygonMode ? "当前匹配范围" : "当前选点坐标";
},
valueSummaryText() {
if (!this.isPolygonMode) {
return this.currentValue || "未选择";
}
const points = this.parsePolygonValue(this.currentValue);
return points.length ? `${points.length} 个点` : "未绘制";
},
locateTip() {
return this.isPolygonMode
? "坐标为高德 GCJ-02;点击地图依次绘制多边形顶点,至少 3 个点;未绘制则不参与自动匹配"
: "坐标为高德 GCJ-02;可搜索、定位或点击地图选点";
},
},
methods: {
getAmapKey() {
return (typeof config !== "undefined" && config.amapKey) || "";
@ -223,6 +256,12 @@ export default {
if (decimal > 14) decimal = 14;
return Number(lng).toFixed(decimal) + ", " + Number(lat).toFixed(decimal);
},
formatPoint(lng, lat) {
let decimal = this.decimal;
if (decimal < 0) decimal = 0;
if (decimal > 14) decimal = 14;
return [Number(Number(lng).toFixed(decimal)), Number(Number(lat).toFixed(decimal))];
},
parsePosition(value) {
if (!value || !String(value).trim()) return null;
const parts = String(value).split(",");
@ -253,11 +292,15 @@ export default {
});
this.map.on("click", (e) => {
if (!e || !e.lnglat) return;
this.placeMarker(e.lnglat.getLng(), e.lnglat.getLat());
if (this.isPolygonMode) {
this.addPolygonPoint(e.lnglat.getLng(), e.lnglat.getLat());
} else {
this.placeMarker(e.lnglat.getLng(), e.lnglat.getLat());
}
});
return new Promise((resolve) => {
AMap.plugin(
["AMap.ToolBar", "AMap.Scale", "AMap.PlaceSearch", "AMap.Geolocation"],
["AMap.ToolBar", "AMap.Scale", "AMap.PlaceSearch", "AMap.Geolocation", "AMap.PolygonEditor"],
() => {
this.map.addControl(
new AMap.ToolBar({
@ -307,10 +350,158 @@ export default {
lat,
]);
},
placeReferenceMarker(lng, lat, zoom, title) {
if (!this.map || typeof window.AMap === "undefined") return;
if (this.referenceMarker) {
this.referenceMarker.setMap(null);
this.referenceMarker = null;
}
this.referenceMarker = new window.AMap.Marker({
position: [lng, lat],
title: title || "当前位置",
icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
});
this.referenceMarker.setMap(this.map);
this.map.setZoomAndCenter(zoom || Math.max(this.map.getZoom(), 17), [
lng,
lat,
]);
},
parsePolygonValue(value) {
if (!value || !String(value).trim()) return [];
try {
const parsed = JSON.parse(value);
if (!Array.isArray(parsed)) return [];
return parsed
.map((item) => {
if (Array.isArray(item) && item.length >= 2) {
return this.formatPoint(item[0], item[1]);
}
if (item && typeof item === "object") {
return this.formatPoint(item.lng, item.lat);
}
return null;
})
.filter((item) => {
if (!item) return false;
const lng = item[0];
const lat = item[1];
return Number.isFinite(lng) && Number.isFinite(lat) && lng >= -180 && lng <= 180 && lat >= -90 && lat <= 90;
});
} catch (e) {
return [];
}
},
formatPolygonValue(points) {
return JSON.stringify((points || []).map((item) => this.formatPoint(item[0], item[1])));
},
getPolygonPathPoints() {
if (!this.polygon || typeof this.polygon.getPath !== "function") {
return this.parsePolygonValue(this.currentValue);
}
return this.polygon.getPath().map((item) => {
const lng = typeof item.getLng === "function" ? item.getLng() : item.lng;
const lat = typeof item.getLat === "function" ? item.getLat() : item.lat;
return this.formatPoint(lng, lat);
});
},
syncPolygonValue(points) {
this.currentValue = points && points.length ? this.formatPolygonValue(points) : "";
this.$emit("on-click", this.currentValue);
},
addPolygonPoint(lng, lat) {
const points = this.parsePolygonValue(this.currentValue);
points.push(this.formatPoint(lng, lat));
this.syncPolygonValue(points);
this.renderPolygon(points, false);
},
clearPolygonOverlays() {
if (this.polygonEditor) {
this.polygonEditor.close();
this.polygonEditor = null;
}
if (this.polygon) {
this.polygon.setMap(null);
this.polygon = null;
}
if (this.polygonLine) {
this.polygonLine.setMap(null);
this.polygonLine = null;
}
this.vertexMarkers.forEach((item) => item.setMap(null));
this.vertexMarkers = [];
},
renderPolygon(points, fitView) {
if (!this.map || typeof window.AMap === "undefined") return;
this.clearPolygonOverlays();
const path = (points || []).map((item) => item.slice(0, 2));
path.forEach((item, index) => {
const marker = new window.AMap.Marker({
position: item,
content: `<div class="amap-vertex-marker">${index + 1}</div>`,
offset: new window.AMap.Pixel(-8, -8),
});
marker.setMap(this.map);
this.vertexMarkers.push(marker);
});
if (path.length >= 3) {
this.polygon = new window.AMap.Polygon({
path,
strokeColor: "#2d8cf0",
strokeWeight: 2,
fillColor: "#2d8cf0",
fillOpacity: 0.18,
});
this.polygon.setMap(this.map);
this.polygonEditor = new window.AMap.PolygonEditor(this.map, this.polygon);
["adjust", "addnode", "removenode", "end"].forEach((eventName) => {
this.polygonEditor.on(eventName, () => {
this.syncPolygonValue(this.getPolygonPathPoints());
});
});
this.polygonEditor.open();
if (fitView) {
this.map.setFitView([this.polygon]);
}
} else if (path.length > 0) {
this.polygonLine = new window.AMap.Polyline({
path,
strokeColor: "#2d8cf0",
strokeWeight: 2,
strokeStyle: "dashed",
});
this.polygonLine.setMap(this.map);
if (fitView) {
this.map.setFitView([...this.vertexMarkers, this.polygonLine]);
}
}
},
syncPolygonFromValue() {
const points = this.parsePolygonValue(this.data);
this.currentValue = points.length ? this.formatPolygonValue(points) : "";
this.renderPolygon(points, true);
if (!points.length && this.map) {
this.map.setZoomAndCenter(this.zoom, this.center);
}
},
undoPolygonPoint() {
const points = this.getPolygonPathPoints();
points.pop();
this.syncPolygonValue(points);
this.renderPolygon(points, false);
},
clearPolygonValue() {
this.syncPolygonValue([]);
this.clearPolygonOverlays();
},
syncMarkerFromValue() {
if (this.isPolygonMode) {
this.syncPolygonFromValue();
return;
}
const pos = this.parsePosition(this.data);
if (pos) {
this.currentValue = this.data;
this.currentValue = this.data;
this.placeMarker(pos.lng, pos.lat, 16);
} else {
this.currentValue = "";
@ -355,7 +546,11 @@ export default {
if (!item || !item.location) return;
const lng = item.location.lng;
const lat = item.location.lat;
this.placeMarker(lng, lat, 17);
if (this.isPolygonMode) {
this.placeReferenceMarker(lng, lat, 17, item.name || "搜索位置");
} else {
this.placeMarker(lng, lat, 17);
}
this.searchResults = [];
this.keyword = item.name || this.keyword;
},
@ -374,7 +569,11 @@ export default {
.then((pos) => {
loading();
this.locating = false;
this.placeMarker(pos.lng, pos.lat, 17);
if (this.isPolygonMode) {
this.placeReferenceMarker(pos.lng, pos.lat, 17, "当前位置");
} else {
this.placeMarker(pos.lng, pos.lat, 17);
}
if (pos.accuracy && pos.accuracy > 1000) {
this.$Message.warning(
`定位成功,精度约 ${Math.round(pos.accuracy)} 米,请核对后确认`
@ -440,6 +639,14 @@ export default {
}
},
handelSubmit() {
if (this.isPolygonMode) {
const points = this.getPolygonPathPoints();
if (points.length > 0 && points.length < 3) {
this.$Message.warning("匹配范围至少需要 3 个点");
return;
}
this.currentValue = points.length ? this.formatPolygonValue(points) : "";
}
this.data = this.currentValue;
this.$emit("input", this.data);
this.$emit("on-change", this.data);
@ -451,7 +658,12 @@ export default {
this.marker.setMap(null);
this.marker = null;
}
if (this.referenceMarker) {
this.referenceMarker.setMap(null);
this.referenceMarker = null;
}
if (this.map) {
this.clearPolygonOverlays();
this.map.destroy();
this.map = null;
}
@ -526,6 +738,22 @@ export default {
font-size: 12px;
line-height: 1.4;
}
.polygon-actions {
margin-top: 8px;
button + button {
margin-left: 8px;
}
}
.amap-vertex-marker {
width: 16px;
height: 16px;
line-height: 16px;
text-align: center;
color: #fff;
background: #2d8cf0;
border-radius: 50%;
font-size: 12px;
}
.modal-fullscreen {
position: absolute;
right: 42px;

Loading…
Cancel
Save