添加了预约日期

master
doublekou 1 year ago
commit 7e2670d04f

@ -1,12 +1,33 @@
import httpClient from '@/utils/axios'
import type { ApiResult } from '@/api/types'
import type { shopPageParam } from './types'
import type { shopPageParam, shopDetailVO, queryReservation } from './types'
export function pageQueryAll(pageParams: shopPageParam) {
return httpClient.get<ApiResult>('/store/queryAll', {
export function pageQueryPage(pageParams: shopPageParam) {
return httpClient.get<ApiResult>('/store/queryPage', {
params: pageParams
})
}
export function storeUserQueryAll() {
return httpClient.get<ApiResult>('/storeUser/queryAll', {})
}
export function createUser(data: shopDetailVO) {
return httpClient.post<ApiResult<void>>('/store/add', data)
}
export function updateUser(data: shopDetailVO) {
return httpClient.post<ApiResult<void>>('/store/update', data)
}
// 查询预约详情
export function getReservation(pageParams: queryReservation) {
return httpClient.get<ApiResult>('/store/reservation', {
params: pageParams
})
}
export function deleteShop(id: number) {
return httpClient.delete<ApiResult<void>>(`/store/${id}`)
}
export function exportI18nDataExcel(params: queryReservation) {
return httpClient.get('/store/export', { params, responseType: 'blob' })
}

@ -1,12 +1,13 @@
import type { PageParam } from '@/api/types'
import type { Dayjs } from 'dayjs'
export type shopParam = {
storeName?: string
storeType?: number
storeType?: number | null
province?: string
address?: string[]
city?: string
county?: string
createStartTime?: string
createEndTime?: string
reservationDate?: [Dayjs, Dayjs]
}
export type shopPageParam = shopParam & PageParam
@ -17,3 +18,26 @@ export type shopDTO = shopParam & {
storeType: number
storeStatus: number
}
export interface shopDetailVO {
id?: number | null
storeName: string
storeType: number | string
storeStatus: number
userId: string
detail: string
province: string
nid: string
city: string
county: string
address: string
tradeTime: string[]
tradeStartTime?: string
tradeEndTime?: string
longitude: number
latitude: number
}
export interface queryReservation {
storeId: number
startTime: string
endTime: string
}

@ -9,7 +9,7 @@ import '@/styles/global.less'
import 'ant-design-vue/es/message/style/index.less'
import 'ant-design-vue/es/notification/style/index.less'
import 'ant-design-vue/es/modal/style/index.less'
import './styles/index.less'
import App from './App.vue'
import { enableI18n } from '@/config'

@ -80,3 +80,4 @@ ol {
color: @error-color-hover;
}
}

@ -0,0 +1,32 @@
.mb-5 {
margin-bottom: 5px;
}
.ml-5 {
margin-left: 5px;
}
.u-flex {
display: flex;
align-items: center;
}
// 滚动条
.sim-cont{
max-height: 100%;
overflow: auto;
}
.sim-cont::-webkit-scrollbar { /*滚动条整体样式*/
width: 7px;
height: 3px;
}
.sim-cont::-webkit-scrollbar-thumb { /*滚动条里面小方块样式*/
border-radius: 100px;
-webkit-box-shadow: inset 0 0 5px rgba(151, 151, 151, 0.2);
background:rgba(0,0,0,0.1);;
}
.sim-cont::-webkit-scrollbar-track { /*滚动条里面轨道样式*/
-webkit-box-shadow: inset 0 0 5px rgba(223, 223, 223, 0.2);
border-radius: 100px;
background: rgba(0,0,0,0.1);
}
.flex-1 {
flex: 1;
}

@ -1,6 +1,8 @@
/* 使用源对象,覆盖目标对象的已有属性 */
export function overrideProperties<T>(target: T, source: any, excludes?: string[]): T {
if (!source) return target
console.log('target==', target)
console.log('source==', source)
// @ts-ignore
Object.keys(target).forEach(key => {
const result = target as any
@ -8,5 +10,6 @@ export function overrideProperties<T>(target: T, source: any, excludes?: string[
result[key] = source[key]
}
})
console.log('return---', target)
return target
}

@ -63,7 +63,6 @@ let searchParams: GeopoliticalCustomersPageParam = {}
//
const tableRequest: TableRequest = (params, sorter, filter) => {
console.log('11111111111111111')
const pageParam = mergePageParam(params, sorter, filter)
return pageAccessLogs({ ...pageParam, ...searchParams })
}

@ -0,0 +1,161 @@
<template>
<a-modal
:title="title"
:visible="visible"
:mask-closable="false"
:centered="true"
:body-style="{ paddingBottom: '8px' }"
:confirm-loading="submitLoading"
:width="650"
@cancel="handleClose"
>
<a-row>
<a-col :span="3">
<label class="label">查询时间</label>
</a-col>
<a-col ::span="21">
<div class="u-flex">
<a-range-picker v-model:value="reservationDate" format="YYYY-MM-DD" style="width: 100%" />
<a-button type="primary" class="ml-5" @click="search"></a-button>
<a-button class="ml-5" @click="reset"></a-button>
</div>
</a-col>
</a-row>
<div class="body sim-cont">
<div class="reservation">
<h4>查询结果展示</h4>
<div v-if="reservation.time.length > 0" class="u-flex">
<ul class="flex-1">
<li>时间</li>
<li v-for="(item, index) in reservation.time" :key="index">{{ item }}</li>
</ul>
<ul class="flex-1">
<li>预约人次</li>
<li v-for="(item, index) in reservation.num" :key="index">{{ item }}</li>
</ul>
</div>
<a-empty v-else />
</div>
</div>
<template #footer>
<div>
<a-button type="primary" @click="toExcel">Excel</a-button>
</div>
</template>
</a-modal>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { useModal } from '@/hooks/modal'
import { message } from 'ant-design-vue'
import type { queryReservation, shopDetailVO } from '@/api/shopManage/types'
import { getReservation, exportI18nDataExcel } from '@/api/shopManage/index'
import { doRequest } from '@/utils/axios/request'
import { useFormAction, FormAction } from '@/hooks/form'
import { remoteFileDownload } from '@/utils/file-utils'
//
import 'dayjs/locale/zh-cn'
import dayjs from 'dayjs'
import type { Dayjs } from 'dayjs'
//
const reservationDate = ref<[Dayjs, Dayjs]>()
const id = ref()
const reservation: any = reactive({
time: [],
num: []
})
const submitLoading = ref(false)
const { title, visible, openModal, closeModal } = useModal()
const { formAction } = useFormAction()
// onMounted(() => {})
const handleClose = () => {
closeModal()
}
const toExcel = () => {
exportI18nDataExcel({
storeId: id.value,
startTime: dayjs(reservationDate.value[0]).format('YYYY-MM-DD'),
endTime: dayjs(reservationDate.value[1]).format('YYYY-MM-DD')
}).then(res => {
remoteFileDownload(res)
})
}
const getReservationFun = (data?: queryReservation) => {
submitLoading.value = true
doRequest(getReservation(data!), {
onSuccess: (res: any) => {
reservation.time = []
reservation.num = []
submitLoading.value = false
if (res.data.length > 0) {
reservation.time = res.data.map((item: { time: any }) => item.time)
reservation.num = res.data.map((item: { num: any }) => item.num)
}
}
})
}
const search = () => {
getReservationFun({
storeId: id.value,
startTime: dayjs(reservationDate.value[0]).format('YYYY-MM-DD'),
endTime: dayjs(reservationDate.value[1]).format('YYYY-MM-DD')
})
}
const reset = () => {
reservationDate.value = [dayjs(), dayjs().add(7, 'day')]
getReservationFun({
storeId: id.value,
startTime: dayjs().format('YYYY-MM-DD'),
endTime: dayjs().add(7, 'day').format('YYYY-MM-DD')
})
}
defineExpose({
open(newFormAction: FormAction, record?: shopDetailVO) {
openModal()
id.value = record?.id
title.value = `${record?.storeName}的预约详情`
reservationDate.value = [dayjs(), dayjs().add(7, 'day')]
getReservationFun({
storeId: record?.id as number,
startTime: dayjs(reservationDate.value[0]).format('YYYY-MM-DD'),
endTime: dayjs(reservationDate.value[1]).format('YYYY-MM-DD')
})
formAction.value = newFormAction
}
})
</script>
<style lang="less" scoped>
//
.label {
position: relative;
display: inline-flex;
align-items: center;
max-width: 100%;
height: 32px;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
}
.body {
padding: 15px;
border: 1px solid #d9d9d9;
border-radius: 4px;
margin-top: 15px;
max-height: 60vh;
overflow-y: auto;
h4 {
font-weight: 600;
}
ul {
line-height: 25px;
}
ul li:nth-child(1) {
margin-bottom: 3px;
color: #d9d9d9;
}
}
</style>

@ -9,7 +9,6 @@
<a-card :bordered="false" :body-style="{ paddingBottom: 0 }">
<div class="operationButtonArea">
<a-button class="operationButton" @click="addShop"></a-button>
<a-button class="operationButton" @click="batchAddShop"></a-button>
<!-- 更多操作 -->
</div>
</a-card>
@ -30,31 +29,33 @@
</template>
<template v-else-if="column.key === 'operate'">
<operation-group>
<!-- <a @click="handleView(record)"></a> -->
<a @click="editShop(record)"></a>
<delete-text-button @confirm="deleteShopFun(record)" />
<a @click="selectReservation(record)"></a>
</operation-group>
</template>
</template>
</pro-table>
<!-- 新建/编辑弹窗 -->
<shop-modal ref="shopModalRef" @submit-success="reloadTable" />
<!-- 预约详情 -->
<reservation-modal ref="reservationModalRef"></reservation-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue'
// import { message } from 'ant-design-vue'
// import { doRequest } from '@/utils/axios/request'
import { doRequest } from '@/utils/axios/request'
//
import ProTable from '#/table'
import type { ProTableInstanceExpose, TableRequest, ProColumns } from '#/table'
import { mergePageParam } from '@/utils/page-utils'
import { FormAction } from '@/hooks/form'
import shopModal from './shopModal.vue'
import reservationModal from './reservationModal.vue'
import shopSearch from './shopSearch.vue'
import { pageQueryAll } from '@/api/shopManage'
import type {
shopDTO,
shopParam
} from '@/api/shopManage/types'
import { pageQueryPage, deleteShop } from '@/api/shopManage'
import type { shopDetailVO, shopParam } from '@/api/shopManage/types'
defineOptions({ name: 'GeopoliticalCustomers' })
@ -63,13 +64,14 @@ defineOptions({ name: 'GeopoliticalCustomers' })
const tableRef = ref<ProTableInstanceExpose>()
// add ref
const shopModalRef = ref<InstanceType<typeof shopModal>>()
const reservationModalRef = ref<InstanceType<typeof reservationModal>>()
//
let searchParams: shopParam = {}
//
const tableRequest: TableRequest = (params, sorter, filter) => {
const pageParam = mergePageParam(params, sorter, filter)
return pageQueryAll({ ...pageParam, ...searchParams })
return pageQueryPage({ ...pageParam, ...searchParams })
}
//
@ -84,9 +86,21 @@ const searchTable = (params: shopParam) => {
}
//
const addShop = () => {
console.log('00000', shopModalRef.value)
shopModalRef.value?.open(FormAction.CREATE)
}
const editShop = (record: shopDetailVO) => {
shopModalRef.value?.open(FormAction.UPDATE, record)
}
const selectReservation = (record: shopDetailVO) => {
reservationModalRef.value?.open(FormAction.OTHER, record)
}
//
const deleteShopFun = (record: shopDetailVO) => {
doRequest(deleteShop(record.id as number), {
successMessage: '删除成功!',
onSuccess: () => reloadTable()
})
}
//
const batchAddShop = () => {}
// //
@ -158,7 +172,7 @@ const columns: ProColumns[] = [
key: 'operate',
title: '操作',
align: 'center',
width: 160,
width: 180,
fixed: 'right'
}
]

@ -1,294 +0,0 @@
<template>
<a-modal
:title="title"
:visible="visible"
:mask-closable="false"
:centered="true"
:body-style="{ paddingBottom: '8px' }"
:confirm-loading="submitLoading"
:width="650"
@cancel="handleClose"
>
<a-form
:model="formModel"
:label-col="{ sm: { span: 24 }, md: { span: 8 } }"
:wrapper-col="wrapperCol"
>
<a-row justify="start">
<a-col :span="12">
<a-form-item label="客户称呼">
<a-input v-model:value="formModel.customName" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
<a-row justify="start">
<a-col :span="12">
<a-form-item label="客户联系方式">
<a-input v-model:value="formModel.customNid" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
<a-row justify="start">
<a-col :span="24">
<a-form-item
label="客户地址信息"
:label-col="{ sm: { span: 24 }, md: { span: 4 } }"
:wrapper-col="{ sm: { span: 24 }, md: { span: 20 } }"
>
<a-input v-model:value="formModel.comprehensiveAddress" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
<template v-for="item in formModel.customStoreVOList" :key="item.storeId">
<a-row justify="start">
<a-col xs="24" :sm="24" :md="12">
<a-form-item label="预约门店">
<a-input v-model:value="item.storeName" placeholder="请输入" readonly />
</a-form-item>
</a-col>
<a-col xs="24" :sm="24" :md="12">
<a-form-item label="预约时间">
<a-input v-model:value="item.reservationTime" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
</template>
</a-form>
<template #footer>
<div v-if="title !== '详情'">
<a-button v-if="title !== '审核'" @click="visible = false"></a-button>
<a-button type="primary" html-type="submit" style="margin-left: 10px" @click="toExamine(0)"
>重审</a-button
>
<a-button type="primary" html-type="submit" style="margin-left: 10px" @click="toExamine(1)"
>分发</a-button
>
</div>
</template>
</a-modal>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted, toRefs } from 'vue'
import { useModal } from '@/hooks/modal'
import type { FormRequestMapping } from '@/hooks/form'
import { overrideProperties } from '@/utils/bean-utils'
import { message } from 'ant-design-vue'
import type { CustomerDTO, GeopoliticalCustomersRecord } from '@/api/geopoliticalCustomers/types'
import { updateCustomerAudit } from '@/api/geopoliticalCustomers/index'
import { doRequest } from '@/utils/axios/request'
import { useAdminForm, useFormAction, FormAction, labelCol, wrapperCol } from '@/hooks/form'
//
import 'dayjs/locale/zh-cn'
// import dayjs from 'dayjs'
const emits = defineEmits<{
(e: 'submit-success'): void
}>()
//dom:rules = 'rulesData'
// const rulesData = {
// required: true,
// trigger: 'change'
// }
interface ReservationShop {
customStoreId?: number
storeName: string
reservationTime: string
}
interface SysUserPageVO {
customId: number | undefined
customName: string
customNid: string
comprehensiveAddress?: string
customStoreVOList: ReservationShop[]
}
const formModel = reactive<SysUserPageVO>({
customId: undefined,
customName: '',
customNid: '',
comprehensiveAddress: '',
customStoreVOList: []
})
//
const formRule = ref({})
//
const formRequestMapping: FormRequestMapping<SysUserPageVO> = {}
const { title, visible, openModal, closeModal } = useModal()
const { formAction } = useFormAction()
const { submitLoading, resetFields } = useAdminForm(
formAction,
formRequestMapping,
formModel,
formRule
)
// onMounted(() => {})
const handleClose = () => {
submitLoading.value = false
}
const toExamine = (type: number) => {
updateCustomerAudit(type).then(res => {
message.info(res.message)
if (res.code == 200) {
closeModal()
emits('submit-success')
}
})
}
defineExpose({
open(newFormAction: FormAction, record?: GeopoliticalCustomersRecord) {
console.log(record, 'record')
openModal()
resetFields()
if (newFormAction === FormAction.OTHER) {
title.value = '预约详情'
record!.comprehensiveAddress = `${record?.economize}${record?.market}${record?.distinguish}${record?.detailAddress}`
record!.customStoreVOList = [
{
storeName: '测试',
reservationTime: '2023-9-14 10:12:15'
}
]
overrideProperties(formModel, record)
}
formAction.value = newFormAction
}
})
</script>
<style lang="less" scoped>
//
.weightAllocation {
.ant-form {
display: grid;
// grid-auto-flow: column;
grid-template-columns: 50% 50%;
// grid-template-rows: 50% 50%;
}
}
//
::v-deep .ant-input-number-out-of-range input {
color: #000000;
}
////////////////////////////////////////////////////////////////
.ant-list-item {
width: 330px;
}
.ant-list-item-meta-title {
font-size: 13x !important;
}
::v-deep .ant-list-item-meta-description {
font-size: 12px !important;
}
::v-deep .ant-space-item {
width: 100% !important;
}
.storeForm {
margin-top: 20px;
overflow-y: auto;
height: 100px;
}
.ant-list-item {
// align-items: unset;
width: 225px;
padding-right: 3px;
}
.ant-list-item-action > li {
// position: relative;
display: unset;
}
::v-deep .ant-list-item-action {
margin-left: 5px;
}
::v-deep .ant-list-item-meta-title {
font-size: 12px;
}
::v-deep .ant-list-item-action > li {
padding: 0 5px;
}
.ant-btn-sm {
font-size: 12px;
height: 20px;
padding: 0px 3px;
}
::v-deep .amap-overlay-text-container {
z-index: 999;
white-space: unset;
overflow: unset;
text-overflow: unset;
font-size: 15px !important;
color: rgba(0, 0, 0, 0.85) !important;
}
////
#mapContainer {
width: 100%;
height: 500px;
}
::v-deep .bubble-card {
z-index: 999999999;
position: relative;
// top: -62px;
padding: 15px 10px;
background-color: white;
border-radius: 6px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
font-size: 13px;
width: 180px;
filter: drop-shadow(0px 0px 1px gray);
// height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
.medium-card {
height: 50px;
}
.large-card {
height: 100px;
}
::v-deep .bubble-card::before {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
border-width: 5px;
border-style: solid;
border-color: white transparent transparent;
// transform: rotate(180deg);
// font-family: 'anticon'; /* */
// content: '\e66a'; /* Unicode close-outlined */
// color: red;
// font-size: 16px;
}
::v-deep .spanDom {
position: absolute;
top: 3px;
color: #d9d2d2;
right: 3px;
font-size: 15px;
}
</style>

@ -1,294 +0,0 @@
<template>
<a-modal
:title="title"
:visible="visible"
:mask-closable="false"
:centered="true"
:body-style="{ paddingBottom: '8px' }"
:confirm-loading="submitLoading"
:width="650"
@cancel="handleClose"
>
<a-form
:model="formModel"
:label-col="{ sm: { span: 24 }, md: { span: 8 } }"
:wrapper-col="wrapperCol"
>
<a-row justify="start">
<a-col :span="12">
<a-form-item label="客户称呼">
<a-input v-model:value="formModel.customName" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
<a-row justify="start">
<a-col :span="12">
<a-form-item label="客户联系方式">
<a-input v-model:value="formModel.customNid" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
<a-row justify="start">
<a-col :span="24">
<a-form-item
label="客户地址信息"
:label-col="{ sm: { span: 24 }, md: { span: 4 } }"
:wrapper-col="{ sm: { span: 24 }, md: { span: 20 } }"
>
<a-input v-model:value="formModel.comprehensiveAddress" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
<template v-for="item in formModel.customStoreVOList" :key="item.storeId">
<a-row justify="start">
<a-col xs="24" :sm="24" :md="12">
<a-form-item label="预约门店">
<a-input v-model:value="item.storeName" placeholder="请输入" readonly />
</a-form-item>
</a-col>
<a-col xs="24" :sm="24" :md="12">
<a-form-item label="预约时间">
<a-input v-model:value="item.reservationTime" placeholder="请输入" readonly />
</a-form-item>
</a-col>
</a-row>
</template>
</a-form>
<template #footer>
<div v-if="title !== '详情'">
<a-button v-if="title !== '审核'" @click="visible = false"></a-button>
<a-button type="primary" html-type="submit" style="margin-left: 10px" @click="toExamine(0)"
>重审</a-button
>
<a-button type="primary" html-type="submit" style="margin-left: 10px" @click="toExamine(1)"
>分发</a-button
>
</div>
</template>
</a-modal>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted, toRefs } from 'vue'
import { useModal } from '@/hooks/modal'
import type { FormRequestMapping } from '@/hooks/form'
import { overrideProperties } from '@/utils/bean-utils'
import { message } from 'ant-design-vue'
import type { CustomerDTO, GeopoliticalCustomersRecord } from '@/api/geopoliticalCustomers/types'
import { updateCustomerAudit } from '@/api/geopoliticalCustomers/index'
import { doRequest } from '@/utils/axios/request'
import { useAdminForm, useFormAction, FormAction, labelCol, wrapperCol } from '@/hooks/form'
//
import 'dayjs/locale/zh-cn'
// import dayjs from 'dayjs'
const emits = defineEmits<{
(e: 'submit-success'): void
}>()
//dom:rules = 'rulesData'
// const rulesData = {
// required: true,
// trigger: 'change'
// }
interface ReservationShop {
customStoreId?: number
storeName: string
reservationTime: string
}
interface SysUserPageVO {
customId: number | undefined
customName: string
customNid: string
comprehensiveAddress?: string
customStoreVOList: ReservationShop[]
}
const formModel = reactive<SysUserPageVO>({
customId: undefined,
customName: '',
customNid: '',
comprehensiveAddress: '',
customStoreVOList: []
})
//
const formRule = ref({})
//
const formRequestMapping: FormRequestMapping<SysUserPageVO> = {}
const { title, visible, openModal, closeModal } = useModal()
const { formAction } = useFormAction()
const { submitLoading, resetFields } = useAdminForm(
formAction,
formRequestMapping,
formModel,
formRule
)
// onMounted(() => {})
const handleClose = () => {
submitLoading.value = false
}
const toExamine = (type: number) => {
updateCustomerAudit(type).then(res => {
message.info(res.message)
if (res.code == 200) {
closeModal()
emits('submit-success')
}
})
}
defineExpose({
open(newFormAction: FormAction, record?: GeopoliticalCustomersRecord) {
console.log(record, 'record')
openModal()
resetFields()
if (newFormAction === FormAction.OTHER) {
title.value = '预约详情'
record!.comprehensiveAddress = `${record?.economize}${record?.market}${record?.distinguish}${record?.detailAddress}`
record!.customStoreVOList = [
{
storeName: '测试',
reservationTime: '2023-9-14 10:12:15'
}
]
overrideProperties(formModel, record)
}
formAction.value = newFormAction
}
})
</script>
<style lang="less" scoped>
//
.weightAllocation {
.ant-form {
display: grid;
// grid-auto-flow: column;
grid-template-columns: 50% 50%;
// grid-template-rows: 50% 50%;
}
}
//
::v-deep .ant-input-number-out-of-range input {
color: #000000;
}
////////////////////////////////////////////////////////////////
.ant-list-item {
width: 330px;
}
.ant-list-item-meta-title {
font-size: 13x !important;
}
::v-deep .ant-list-item-meta-description {
font-size: 12px !important;
}
::v-deep .ant-space-item {
width: 100% !important;
}
.storeForm {
margin-top: 20px;
overflow-y: auto;
height: 100px;
}
.ant-list-item {
// align-items: unset;
width: 225px;
padding-right: 3px;
}
.ant-list-item-action > li {
// position: relative;
display: unset;
}
::v-deep .ant-list-item-action {
margin-left: 5px;
}
::v-deep .ant-list-item-meta-title {
font-size: 12px;
}
::v-deep .ant-list-item-action > li {
padding: 0 5px;
}
.ant-btn-sm {
font-size: 12px;
height: 20px;
padding: 0px 3px;
}
::v-deep .amap-overlay-text-container {
z-index: 999;
white-space: unset;
overflow: unset;
text-overflow: unset;
font-size: 15px !important;
color: rgba(0, 0, 0, 0.85) !important;
}
////
#mapContainer {
width: 100%;
height: 500px;
}
::v-deep .bubble-card {
z-index: 999999999;
position: relative;
// top: -62px;
padding: 15px 10px;
background-color: white;
border-radius: 6px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
font-size: 13px;
width: 180px;
filter: drop-shadow(0px 0px 1px gray);
// height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
.medium-card {
height: 50px;
}
.large-card {
height: 100px;
}
::v-deep .bubble-card::before {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
border-width: 5px;
border-style: solid;
border-color: white transparent transparent;
// transform: rotate(180deg);
// font-family: 'anticon'; /* */
// content: '\e66a'; /* Unicode close-outlined */
// color: red;
// font-size: 16px;
}
::v-deep .spanDom {
position: absolute;
top: 3px;
color: #d9d2d2;
right: 3px;
font-size: 15px;
}
</style>

@ -7,9 +7,12 @@
:body-style="{ paddingBottom: '8px' }"
:confirm-loading="submitLoading"
:width="650"
@ok="handleSubmit"
@cancel="handleClose"
>
<div class="model-body sim-cont">
<a-form
ref="formRef"
:model="formModel"
:label-col="{ sm: { span: 24 }, md: { span: 8 } }"
:wrapper-col="wrapperCol"
@ -20,7 +23,8 @@
label="门店名称"
:label-col="{ sm: { span: 24 }, md: { span: 4 } }"
:wrapper-col="{ sm: { span: 24 }, md: { span: 20 } }"
:rules="[{ required: true, message: '请选择输入门店名称', trigger: ['blur'] }]"
:rules="[{ required: true, message: '请输入门店名称', trigger: ['blur'] }]"
name="storeName"
>
<a-input v-model:value="formModel.storeName" placeholder="请输入" />
</a-form-item>
@ -31,6 +35,7 @@
<a-form-item
label="门店类型"
:rules="[{ required: true, message: '请选择门店类型', trigger: ['blur'] }]"
name="storeType"
>
<a-select v-model:value="formModel.storeType">
<a-select-option :value="0">直营店</a-select-option>
@ -44,6 +49,7 @@
<a-form-item
label="门店状态"
:rules="[{ required: true, message: '请选择门店状态', trigger: ['blur'] }]"
name="storeStatus"
>
<a-radio-group v-model:value="formModel.storeStatus">
<a-radio :value="0">正常</a-radio>
@ -57,106 +63,65 @@
<a-form-item
label="营业时间"
:rules="[{ required: true, message: '请选择营业时间', trigger: ['blur'] }]"
name="tradeTime"
>
<a-time-range-picker v-model:value="formModel.tradeTime" />
<a-time-range-picker v-model:value="formModel.tradeTime" value-format="HH:mm:ss" />
</a-form-item>
</a-col>
</a-row>
<!-- <a-row justify="start">
<a-row v-if="title != '编辑门店'" justify="start">
<a-col :span="12">
<a-form-item
label="承接销售"
:rules="[{ required: true, message: '请选择承接销售', trigger: ['blur'] }]"
name="userId"
>
<a-select
v-model:value="formModel.storeType"
v-model:value="formModel.userId"
:field-names="{ label: 'userName', value: 'userId' }"
:options="userList"
placeholder="请选择承接销售"
/>
</a-form-item>
</a-col>
</a-row> -->
<a-row :gutter="16">
<a-col :xl="14" :md="14" :sm="14">
</a-row>
<a-row justify="start">
<a-col :span="12">
<a-form-item
label="门店地址"
:label-col="{ sm: { span: 24 }, md: { span: 7 } }"
:wrapper-col="{ sm: { span: 24 }, md: { span: 17 } }"
:rules="[{ required: true, message: '请选择地址信息', trigger: ['blur', 'change'] }]"
name="address"
label="联系电话"
:rules="[{ required: true, message: '请输入门店联系电话', trigger: ['blur'] }]"
name="nid"
>
<a-cascader
v-model:value="formModel.address"
:options="provincesAndCitiesAndAutonomousOptions"
placeholder="请选择"
:show-search="{ filter }"
style="margin-right: 20px"
:disabled="title === '详情'"
class="readonly-cascader"
/>
<a-input v-model:value="formModel.nid" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :xl="10" :md="10" :sm="10">
</a-row>
<a-row v-if="title != '编辑门店'" justify="start">
<a-col :span="24">
<a-form-item
:rules="[{ required: true, message: '请输入小区名称', trigger: 'change' }]"
name="detailAddress"
label="门店地址"
:label-col="{ sm: { span: 24 }, md: { span: 4 } }"
:wrapper-col="{ sm: { span: 24 }, md: { span: 20 } }"
:rules="[{ required: true, message: '请输入详细地址', trigger: ['blur'] }]"
name="address"
>
<div class="fields">
<a-input
v-model:value="formModel.detail"
id="tipinput"
v-model:value="formModel.address"
allow-clear
placeholder="请输入小区名称"
:readonly="title === '详情'"
placeholder="请输入详细地址"
/>
<a-button type="primary" @click="match"></a-button>
</div>
</a-form-item>
</a-col>
</a-row>
<a-row justify="start">
<a-row v-if="title != '编辑门店'">
<a-col :span="24">
<div class="clueImport-page">
<div class="drawStation">
<div class="input"></div>
<div id="draw-station-container">
<!-- <div
v-if="listData.length > 0"
id="aa"
style="
position: absolute;
left: 0;
top: 0;
background-color: #fff;
width: 235px;
overflow-y: auto;
"
@scroll="scrollClick"
>
<a-list item-layout="horizontal" :data-source="listData">
<template #renderItem="{ item }">
<a-list-item @click="storeItemClick(item)">
<a-list-item-meta :description="item.description">
<template #title>
<a :href="item.href" target="_blank">{{ item.title }}</a>
</template>
</a-list-item-meta>
<template #actions>
<img width="35" height="35" alt="logo" :src="item.href" />
<a-button size="small" :disabled="item.disabled" @click="addStore(item)"
>添加</a-button
>
</template>
</a-list-item>
</template>
</a-list>
</div> -->
</div>
</div>
</div>
<!-- 地图 -->
<div id="shopMap"></div>
</a-col>
</a-row>
</a-form>
</div>
</a-modal>
</template>
@ -165,66 +130,54 @@ import { reactive, ref, onMounted, toRefs } from 'vue'
import { useModal } from '@/hooks/modal'
import type { FormRequestMapping } from '@/hooks/form'
import { overrideProperties } from '@/utils/bean-utils'
import { message } from 'ant-design-vue'
// import type { shopDTO } from '@/api/geopoliticalCustomers/types'
import { storeUserQueryAll } from '@/api/shopManage/index'
import { doRequest } from '@/utils/axios/request'
import { storeUserQueryAll, createUser, updateUser } from '@/api/shopManage/index'
import { provincesAndCitiesAndAutonomousRegions } from '@/utils/geopolitical-customers'
import type { ShowSearchType } from 'ant-design-vue/es/cascader'
import { useAdminForm, useFormAction, FormAction, labelCol, wrapperCol } from '@/hooks/form'
import type { shopDetailVO } from '@/api/shopManage/types'
import type { FormInstance } from 'ant-design-vue/es/form/Form'
//
import 'dayjs/locale/zh-cn'
import { reverse } from 'dns'
import { useUserStore } from '@/stores/user-store'
// import dayjs from 'dayjs'
const emits = defineEmits<{
(e: 'submit-success'): void
}>()
const { userInfo } = useUserStore()
declare const AMap: any
interface ReservationShop {
customStoreId?: number
storeName: string
reservationTime: string
}
interface shopDetailVO {
storeName: string
storeType: number | string
storeStatus: number | string
detail: string
address: string
tradeTime: string[]
tradeStartTime: string
tradeEndTime: string
longitude: number
latitude: number
}
const formModel = reactive<shopDetailVO>({
id: null,
storeName: '',
userId: '',
storeType: '',
storeStatus: '',
storeStatus: 0,
province: '',
nid: '',
city: '',
county: '',
detail: '',
address: '',
tradeTime: [],
tradeStartTime: '',
tradeEndTime: '',
longitude: 0,
latitude: 0
})
const companyOptions = reactive({})
const userList: any = reactive([])
const formRef = ref<FormInstance>()
//
let anchorData: any = reactive({})
const userList: any = ref([])
//
const formRule = ref({})
const provincesAndCitiesAndAutonomousOptions: any = ref([])
//
const formRequestMapping: FormRequestMapping<shopDetailVO> = {}
const formRequestMapping: FormRequestMapping<shopDetailVO> = {
[FormAction.CREATE]: createUser,
[FormAction.UPDATE]: updateUser
}
const { title, visible, openModal, closeModal } = useModal()
const { formAction } = useFormAction()
const { submitLoading, resetFields } = useAdminForm(
const { submitLoading, resetFields, validateAndSubmit } = useAdminForm(
formAction,
formRequestMapping,
formModel,
@ -233,38 +186,23 @@ const { submitLoading, resetFields } = useAdminForm(
onMounted(() => {
provincesAndCitiesAndAutonomousOptions.value = provincesAndCitiesAndAutonomousRegions
// selectUserList()
})
const filter: ShowSearchType['filter'] = (val, path) => {
return path.some(option => option.label.toLowerCase().indexOf(val.toLowerCase()) > -1)
}
//AMap.Autocomplete
const autoComplete = ref()
//POIAMap.PlaceSearch
const placeSearch = ref()
//AMap.Marker
// Marker
const marker = ref<any>({})
//AMap.Map
const map = ref<any>({})
//使geocoder/
// AMap.GeocodergetLocation
// AMap.GeocodergetAddress
const geocoder = ref<any>({})
//
const initMap = () => {
map.value = new AMap.Map('draw-station-container', {
map.value = new AMap.Map(['shopMap'], {
center: [120.1551, 30.2741], //
zoom: 13 //
zoom: 13, //
resizeEnable: true
})
// marker.value = new AMap.Marker({
// position: [116.397428, 39.90923] //
// })
const geolocation = new AMap.Geolocation({
enableHighAccuracy: true, // 使false
timeout: 10000, //
@ -282,45 +220,78 @@ const initMap = () => {
console.log('定位失败:', result.message)
}
})
AMap.plugin('AMap.AutoComplete', function () {
// Autocomplete
const autoOptions = {
//city
input: 'tipinput'
}
autoComplete.value = new AMap.AutoComplete(autoOptions)
// geocoder.value = new AMap.Geocoder({
// city: '010' //
// })
})
// map.value.add(marker.value)
AMap.plugin('AMap.PlaceSearch', function () {
// PlaceSearch
const placeOptions = {
map: map.value
}
placeSearch.value = new AMap.PlaceSearch(placeOptions)
})
autoComplete.value.on('select', (e: any) => {
placeSearch.value.setCity(e.poi.adcode)
placeSearch.value.search(e.poi.name)
})
placeSearch.value.on('markerClick', (e: any) => {
formModel.address = `${e.data.pname}${e.data.cityname}${e.data.adname}${e.data.address}`
anchorData = { ...e.data }
})
map.value.addControl(geolocation)
}
const selectUserList = () => {
storeUserQueryAll().then(res => {
console.log(res)
return new Promise(resolve => {
storeUserQueryAll().then((res: any) => {
userList.value = res.data
resolve(true)
})
})
}
const handleClose = () => {
closeModal()
submitLoading.value = false
}
const match = () => {}
const toExamine = (type: number) => {
// updateCustomerAudit(type).then(res => {
// message.info(res.message)
// if (res.code == 200) {
// closeModal()
// emits('submit-success')
// }
// })
/* 表单提交处理 */
const handleSubmit = () => {
formRef.value?.validate().then(res => {
const addkey: any = {}
if (title.value == '添加门店') {
addkey.province = anchorData.pname
addkey.city = anchorData.cityname
addkey.county = anchorData.adname
addkey.detail = anchorData.address
addkey.longitude = anchorData.location.lng
addkey.latitude = anchorData.location.lat
}
anchorData &&
validateAndSubmit(
{
...formModel,
...addkey,
tradeStartTime: formModel.tradeTime[0],
tradeEndTime: formModel.tradeTime[1]
},
{
onSuccess: () => {
closeModal()
emits('submit-success')
}
}
)
})
}
defineExpose({
open(newFormAction: FormAction, record?: shopDetailVO) {
console.log(record, 'record')
console.log(1111111)
async open(newFormAction: FormAction, record?: shopDetailVO) {
await selectUserList()
openModal()
resetFields()
if (newFormAction === FormAction.CREATE) {
@ -329,17 +300,9 @@ defineExpose({
})
title.value = '添加门店'
} else if (newFormAction === FormAction.UPDATE) {
nextTick(() => {
initMap()
})
title.value = '编辑门店'
// record!.comprehensiveAddress = `${record?.economize}${record?.market}${record?.distinguish}${record?.detailAddress}`
// record!.customStoreVOList = [
// {
// storeName: '',
// reservationTime: '2023-9-14 10:12:15'
// }
// ]
const tradeTime = record?.tradeTime.toString()
record!.tradeTime = tradeTime!.split('-')
overrideProperties(formModel, record)
}
formAction.value = newFormAction
@ -347,15 +310,7 @@ defineExpose({
})
</script>
<style lang="less" scoped>
.fields {
display: flex;
width: 127%;
button {
margin-left: 3px;
}
}
.drawStation {
#draw-station-container {
#shopMap {
padding: 0px;
margin: 0px;
width: 100%;
@ -363,28 +318,6 @@ defineExpose({
max-height: 800px;
// height: calc(100vh - 184px);
}
#aa {
padding: 0px;
margin: 0px;
// width: 100%;
height: calc(100% - 20px);
min-height: 300px;
max-height: 800px;
// height: calc(100vh - 214px);
}
.input {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.el-input {
width: 220px;
margin-right: 20px;
}
}
}
//
.weightAllocation {
.ant-form {
@ -514,4 +447,9 @@ defineExpose({
right: 3px;
font-size: 15px;
}
.model-body {
max-height: 70vh;
overflow-y: auto;
}
</style>

@ -4,38 +4,35 @@
<a-row :gutter="16">
<!-- v-if="userInfoCurrent === 'ROLE_ADMIN'" -->
<a-col :xl="8" :md="12" :sm="24">
<a-form-item label="客户名称">
<a-input v-model:value="formModel.customName" placeholder="请输入" />
<a-form-item label="门店名称">
<a-input v-model:value="formModel.storeName" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :xl="8" :md="12" :sm="24">
<a-form-item label="填写时间">
<a-range-picker
v-model:value="searchTimeValue"
show-time
format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
:ranges="{
Today: [dayjs().startOf('date'), dayjs()]
}"
/>
<a-form-item label="门店类型">
<a-select v-model:value="formModel.storeType">
<a-select-option :value="0">直营店</a-select-option>
<a-select-option :value="1">加盟店</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :xl="8" :md="12" :sm="24">
<a-form-item label="分发门店">
<a-input v-model:value="formModel.customNid" placeholder="请输入" />
<a-form-item label="所在城市">
<a-cascader
v-model:value="formModel.address"
:options="provincesAndCitiesAndAutonomousOptions"
placeholder="请选择"
style="margin-right: 20px"
class="readonly-cascader"
/>
</a-form-item>
</a-col>
<a-col :xl="8" :md="12" :sm="24">
<a-form-item label="分发时间">
<a-form-item label="创建日期">
<a-range-picker
v-model:value="searchTimeValue"
show-time
format="YYYY-MM-DD HH:mm:ss"
v-model:value="formModel.reservationDate"
format="YYYY-MM-DD"
style="width: 100%"
:ranges="{
Today: [dayjs().startOf('date'), dayjs()]
}"
/>
</a-form-item>
</a-col>
@ -46,25 +43,35 @@
</a-form>
</a-card>
</template>
<script setup lang="ts">
import { Form } from 'ant-design-vue'
import type { GeopoliticalCustomersSearch } from '@/api/geopoliticalCustomers/types'
import type { shopPageParam } from '@/api/shopManage/types'
import dayjs from 'dayjs'
import type { Dayjs } from 'dayjs'
import { provincesAndCitiesAndAutonomousRegions } from '@/utils/geopolitical-customers'
//
import { useUserStore } from '@/stores/user-store'
const { userInfo } = useUserStore()
const userInfoCurrent = ref<string | undefined>('')
onMounted(() => {
console.log(userInfo, 'userInfo?.permissions')
// userInfoCurrent = userInfo?.roleCodes
userInfoCurrent.value = userInfo?.roleCodes?.toLocaleString()
if (provincesAndCitiesAndAutonomousRegions) {
const arr: any[] = []
provincesAndCitiesAndAutonomousRegions.forEach(item => {
item.children.forEach((it: any) => {
if (it.children) {
delete it.children
}
})
arr.push(item)
})
provincesAndCitiesAndAutonomousOptions.value = arr
}
})
const useForm = Form.useForm
const provincesAndCitiesAndAutonomousOptions: any = ref([])
// label
const labelCol = { md: { span: 6 } }
@ -79,23 +86,46 @@ const emits = defineEmits<{
(e: 'search', params: Record<string, any>): void
}>()
const searchTimeValue = ref<[Dayjs, Dayjs]>()
const formModel = reactive<GeopoliticalCustomersSearch>({
customName: '',
customNid: '',
enrollStatus: undefined
const formModel = reactive<shopPageParam>({
storeName: '',
storeType: null,
address: [],
reservationDate: undefined
})
watch(
() => formModel.reservationDate,
nval => {
if (nval && nval.length == 2) {
formModel.createStartTime = dayjs(nval[0]).format('YYYY-MM-DD')
formModel.createEndTime = dayjs(nval[1]).format('YYYY-MM-DD')
} else {
formModel.reservationDate = undefined
formModel.createStartTime = undefined
formModel.createEndTime = undefined
}
}
)
watch(
() => formModel.address,
nval => {
if (nval) {
formModel.province = nval![0]
formModel.city = nval![1]
} else {
formModel.province = undefined
formModel.city = undefined
}
}
)
const { resetFields } = useForm(formModel)
const search = () => {
const param = toRaw(formModel)
if (searchTimeValue.value && searchTimeValue.value.length == 2) {
param.startTime = searchTimeValue.value[0].format('YYYY-MM-DD HH:mm:ss')
param.endTime = searchTimeValue.value[1].format('YYYY-MM-DD HH:mm:ss')
} else {
param.startTime = ''
param.endTime = ''
if (param.reservationDate && param.reservationDate.length == 2) {
delete param.reservationDate
}
if (param.address) {
delete param.address
}
emits('search', param)
}
@ -103,8 +133,6 @@ const search = () => {
const reset = () => {
//
resetFields()
//
searchTimeValue.value = undefined
search()
}
</script>

Loading…
Cancel
Save