高德商户
This commit is contained in:
@@ -150,6 +150,26 @@ export function exportCustomerFlow(params) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高德周边商家检索(地理编码 + place/around)
|
||||||
|
* @param {{ CITY: string, ADDRESS: string, RADIUS: number, MAX_PAGE: number, maxRecordsOfpage: number }} params
|
||||||
|
*/
|
||||||
|
export function searchNearbyMerchants(params) {
|
||||||
|
return request({
|
||||||
|
url: '/customerManagement/searchNearbyMerchants',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
CITY: params.CITY,
|
||||||
|
ADDRESS: params.ADDRESS,
|
||||||
|
RADIUS: params.RADIUS,
|
||||||
|
MAX_PAGE: params.MAX_PAGE,
|
||||||
|
maxRecordsOfpage: params.maxRecordsOfpage
|
||||||
|
},
|
||||||
|
timeout: 120000,
|
||||||
|
skipResponseNormalize: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 沟通记录相关API
|
// 沟通记录相关API
|
||||||
// 分页查询沟通记录
|
// 分页查询沟通记录
|
||||||
export function getCommunicationRecordPage(params) {
|
export function getCommunicationRecordPage(params) {
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ service.interceptors.response.use(
|
|||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 直接返回后端 JSON(如 Spring ResponseEntity<Map>),不走 success/code 包装逻辑 */
|
||||||
|
if (response.config && response.config.skipResponseNormalize === true) {
|
||||||
|
return response.data
|
||||||
|
}
|
||||||
|
|
||||||
const loginHeaderValues = {
|
const loginHeaderValues = {
|
||||||
'X-Role-Name': pickValueFromSources(
|
'X-Role-Name': pickValueFromSources(
|
||||||
[response.headers, response.data?.data, response.data],
|
[response.headers, response.data?.data, response.data],
|
||||||
|
|||||||
@@ -70,23 +70,17 @@
|
|||||||
<!-- 操作按钮区域 -->
|
<!-- 操作按钮区域 -->
|
||||||
<el-card class="action-container" shadow="never">
|
<el-card class="action-container" shadow="never">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">添加客户</el-button>
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">添加客户</el-button>
|
||||||
|
<el-button type="primary" icon="el-icon-upload2" @click="handleExport">导出客流</el-button>
|
||||||
<el-button type="danger" icon="el-icon-delete" :disabled="selectedIds.length === 0" @click="handleBatchDelete">批量删除</el-button>
|
<el-button type="danger" icon="el-icon-delete" :disabled="selectedIds.length === 0" @click="handleBatchDelete">批量删除</el-button>
|
||||||
|
<el-button type="success" plain icon="el-icon-location-outline" @click="openGaodeMerchantDialog">高德商户</el-button>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 视图切换和操作按钮区域 -->
|
<!-- 视图切换和操作按钮区域 -->
|
||||||
<el-card class="view-container" shadow="never">
|
<el-card class="view-container" shadow="never">
|
||||||
<div class="view-tabs">
|
<div class="view-tabs">
|
||||||
<el-tabs v-model="activeView" @tab-click="handleViewChange">
|
<el-tabs v-model="activeView" @tab-click="handleViewChange">
|
||||||
<el-tab-pane label="列表" name="list">
|
<el-tab-pane label="列表" name="list" />
|
||||||
<div class="action-buttons">
|
<el-tab-pane label="卡片" name="card" />
|
||||||
<el-button type="primary" icon="el-icon-upload2" @click="handleExport">导出客流</el-button>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="卡片" name="card">
|
|
||||||
<div class="action-buttons">
|
|
||||||
<el-button type="primary" icon="el-icon-upload2" @click="handleExport">导出客流</el-button>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -548,6 +542,76 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 列表中按类型查看客户照片 -->
|
<!-- 列表中按类型查看客户照片 -->
|
||||||
|
<!-- 高德附近商家检索 -->
|
||||||
|
<el-dialog
|
||||||
|
title="高德商户 · 附近商家检索"
|
||||||
|
:visible.sync="gaodeMerchantDialogVisible"
|
||||||
|
width="720px"
|
||||||
|
append-to-body
|
||||||
|
@close="onGaodeMerchantDialogClose"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="gaodeNearbyFormRef"
|
||||||
|
class="gaode-nearby-form"
|
||||||
|
:model="gaodeNearbyForm"
|
||||||
|
:rules="gaodeNearbyRules"
|
||||||
|
label-width="260px"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<el-form-item label="城市 CITY" prop="CITY">
|
||||||
|
<el-input v-model="gaodeNearbyForm.CITY" placeholder="传给高德地理编码的 city,如 北京、上海" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址 ADDRESS" prop="ADDRESS">
|
||||||
|
<el-input v-model="gaodeNearbyForm.ADDRESS" placeholder="地址或地标,传给高德地理编码 address" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="半径 RADIUS(米)" prop="RADIUS">
|
||||||
|
<el-input-number v-model="gaodeNearbyForm.RADIUS" :min="1" :max="50000" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="最大页数 MAX_PAGE" prop="MAX_PAGE">
|
||||||
|
<el-input-number v-model="gaodeNearbyForm.MAX_PAGE" :min="1" :max="100" :precision="0" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="每页条数 maxRecordsOfpage" prop="maxRecordsOfpage">
|
||||||
|
<el-input-number v-model="gaodeNearbyForm.maxRecordsOfpage" :min="1" :max="50" :precision="0" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div v-if="nearbySearchResult" class="gaode-nearby-result">
|
||||||
|
<el-alert
|
||||||
|
:title="nearbySearchResult.success ? '检索成功' : '检索失败'"
|
||||||
|
:type="nearbySearchResult.success ? 'success' : 'error'"
|
||||||
|
:closable="false"
|
||||||
|
show-icon
|
||||||
|
>
|
||||||
|
<div>{{ nearbySearchResult.message || '—' }}</div>
|
||||||
|
<div v-if="nearbySearchResult.success" class="gaode-nearby-meta">
|
||||||
|
<span v-if="nearbySearchResult.totalCount != null">总数:{{ nearbySearchResult.totalCount }}</span>
|
||||||
|
<span v-if="nearbySearchResult.centerLocation">中心点:{{ formatGaodeCenter(nearbySearchResult.centerLocation) }}</span>
|
||||||
|
</div>
|
||||||
|
</el-alert>
|
||||||
|
<el-table
|
||||||
|
v-if="nearbySearchResult.success && Array.isArray(nearbySearchResult.data) && nearbySearchResult.data.length"
|
||||||
|
:data="nearbySearchResult.data"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
max-height="320"
|
||||||
|
size="small"
|
||||||
|
style="width: 100%; margin-top: 12px"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
v-for="col in nearbyMerchantTableColProps"
|
||||||
|
:key="col"
|
||||||
|
:prop="col"
|
||||||
|
:label="col"
|
||||||
|
min-width="100"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="gaodeMerchantDialogVisible = false">关 闭</el-button>
|
||||||
|
<el-button type="primary" :loading="gaodeNearbyLoading" @click="submitGaodeNearbySearch">检 索</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="photoPreviewTitle"
|
:title="photoPreviewTitle"
|
||||||
:visible.sync="photoPreviewVisible"
|
:visible.sync="photoPreviewVisible"
|
||||||
@@ -582,7 +646,8 @@ import {
|
|||||||
deleteCustomer,
|
deleteCustomer,
|
||||||
batchDeleteCustomer,
|
batchDeleteCustomer,
|
||||||
exportCustomerFlow,
|
exportCustomerFlow,
|
||||||
addCommunicationRecord
|
addCommunicationRecord,
|
||||||
|
searchNearbyMerchants
|
||||||
} from '@/api/customer'
|
} from '@/api/customer'
|
||||||
import { getProjectList } from '@/api/project'
|
import { getProjectList } from '@/api/project'
|
||||||
import { getSalesList } from '@/api/sales'
|
import { getSalesList } from '@/api/sales'
|
||||||
@@ -677,7 +742,33 @@ export default {
|
|||||||
photoPreviewSrc: '',
|
photoPreviewSrc: '',
|
||||||
photoPreviewObjectUrl: '',
|
photoPreviewObjectUrl: '',
|
||||||
photoPreviewLoading: false,
|
photoPreviewLoading: false,
|
||||||
photoPreviewLoadError: false
|
photoPreviewLoadError: false,
|
||||||
|
gaodeMerchantDialogVisible: false,
|
||||||
|
gaodeNearbyLoading: false,
|
||||||
|
gaodeNearbyForm: {
|
||||||
|
CITY: '河北省廊坊市三河市燕郊镇',
|
||||||
|
ADDRESS: '',
|
||||||
|
RADIUS: 2000,
|
||||||
|
MAX_PAGE: 5,
|
||||||
|
maxRecordsOfpage: 20
|
||||||
|
},
|
||||||
|
gaodeNearbyRules: {
|
||||||
|
CITY: [{ required: true, message: '请输入城市', trigger: 'blur' }],
|
||||||
|
ADDRESS: [{ required: true, message: '请输入地址或地标', trigger: 'blur' }],
|
||||||
|
RADIUS: [{ required: true, message: '请填写搜索半径', trigger: 'change' }],
|
||||||
|
MAX_PAGE: [{ required: true, message: '请填写最大页数', trigger: 'change' }],
|
||||||
|
maxRecordsOfpage: [{ required: true, message: '请填写每页条数', trigger: 'change' }]
|
||||||
|
},
|
||||||
|
nearbySearchResult: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
nearbyMerchantTableColProps() {
|
||||||
|
const rows = this.nearbySearchResult && this.nearbySearchResult.data
|
||||||
|
if (!Array.isArray(rows) || !rows.length || typeof rows[0] !== 'object') {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return Object.keys(rows[0]).slice(0, 16)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -688,6 +779,65 @@ export default {
|
|||||||
this.getSalesOptions()
|
this.getSalesOptions()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
openGaodeMerchantDialog() {
|
||||||
|
this.nearbySearchResult = null
|
||||||
|
this.gaodeNearbyForm = {
|
||||||
|
CITY: '河北省廊坊市三河市燕郊镇',
|
||||||
|
ADDRESS: '',
|
||||||
|
RADIUS: 2000,
|
||||||
|
MAX_PAGE: 5,
|
||||||
|
maxRecordsOfpage: 20
|
||||||
|
}
|
||||||
|
this.gaodeMerchantDialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.gaodeNearbyFormRef) {
|
||||||
|
this.$refs.gaodeNearbyFormRef.clearValidate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onGaodeMerchantDialogClose() {
|
||||||
|
this.nearbySearchResult = null
|
||||||
|
this.gaodeNearbyLoading = false
|
||||||
|
},
|
||||||
|
formatGaodeCenter(loc) {
|
||||||
|
if (loc == null) return ''
|
||||||
|
if (typeof loc === 'string') return loc
|
||||||
|
try {
|
||||||
|
return JSON.stringify(loc)
|
||||||
|
} catch (e) {
|
||||||
|
return String(loc)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submitGaodeNearbySearch() {
|
||||||
|
this.$refs.gaodeNearbyFormRef.validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
const { CITY, ADDRESS, RADIUS, MAX_PAGE, maxRecordsOfpage } = this.gaodeNearbyForm
|
||||||
|
this.gaodeNearbyLoading = true
|
||||||
|
searchNearbyMerchants({
|
||||||
|
CITY: String(CITY).trim(),
|
||||||
|
ADDRESS: String(ADDRESS).trim(),
|
||||||
|
RADIUS: Number(RADIUS),
|
||||||
|
MAX_PAGE: Number(MAX_PAGE),
|
||||||
|
maxRecordsOfpage: Number(maxRecordsOfpage)
|
||||||
|
}).then(res => {
|
||||||
|
this.nearbySearchResult = res && typeof res === 'object' ? res : { success: false, message: '响应格式异常' }
|
||||||
|
if (this.nearbySearchResult.success) {
|
||||||
|
this.$message.success(this.nearbySearchResult.message || '检索成功')
|
||||||
|
} else {
|
||||||
|
this.$message.error(this.nearbySearchResult.message || '检索失败')
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
const rd = err && err.response && err.response.data
|
||||||
|
if (rd && typeof rd === 'object' && ('success' in rd || 'message' in rd)) {
|
||||||
|
this.nearbySearchResult = rd
|
||||||
|
} else {
|
||||||
|
this.nearbySearchResult = { success: false, message: (err && err.message) || '请求失败' }
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.gaodeNearbyLoading = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
// 获取列表数据
|
// 获取列表数据
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
@@ -1237,10 +1387,6 @@ export default {
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-buttons {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.customer-cards {
|
.customer-cards {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
@@ -1395,4 +1541,29 @@ export default {
|
|||||||
color: #909399;
|
color: #909399;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gaode-nearby-result {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gaode-nearby-meta {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gaode-nearby-meta span {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 高德商户弹窗:label 单行不换行,控件区宽度为原先的 70% */
|
||||||
|
.gaode-nearby-form ::v-deep .el-form-item__label {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gaode-nearby-form ::v-deep .el-form-item__content > .el-input,
|
||||||
|
.gaode-nearby-form ::v-deep .el-form-item__content > .el-input-number {
|
||||||
|
width: 70%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user