店铺编辑时增加腾讯地图座标的获取

This commit is contained in:
zhl 2021-04-21 15:42:54 +08:00
parent 8db7b22fd8
commit fd39ea8b2f
7 changed files with 217 additions and 190 deletions

View File

@ -9,3 +9,13 @@ export async function queryArea(str: string, region: string) {
}) })
} }
export async function addressToLoc(address: string) {
let data = { address }
return request({
url: '/area/geocoder',
method: 'post',
data
})
}

View File

@ -5,6 +5,7 @@ export const defaultShopData: IShopData = {
name: '', name: '',
_id: '', _id: '',
address: '', address: '',
logo: ''
} }
export const getShops = (params: any) => export const getShops = (params: any) =>

8
src/api/types.d.ts vendored
View File

@ -47,5 +47,11 @@ export interface IShopData {
createdAt?: Date, createdAt?: Date,
areaCode?: number, areaCode?: number,
areaStr?: string, areaStr?: string,
address: string address: string,
logo?: string,
lng?: number,
lat?: number,
showName?: string,
extData?: string,
category?: string
} }

View File

@ -2,32 +2,33 @@
<div class="upload-container"> <div class="upload-container">
<el-upload <el-upload
:data="dataObj" :data="dataObj"
:multiple="false" name="image-file"
:multiple="true"
:show-file-list="false" :show-file-list="false"
:on-success="handleImageSuccess" :on-success="handleImageSuccess"
class="image-uploader" class="image-uploader"
drag drag
action="https://httpbin.org/post" :action="uploadUrl"
> >
<i class="el-icon-upload" /> <i class="el-icon-upload" />
<div class="el-upload__text"> <div class="el-upload__text">
将文件拖到此处<em>点击上传</em> 将文件拖到此处<em>点击上传</em>
</div> </div>
</el-upload> </el-upload>
<div class="image-preview image-app-preview"> <!-- <div class="image-preview image-app-preview">-->
<div <!-- <div-->
v-show="imageUrl.length>1" <!-- v-show="imageUrl.length>1"-->
class="image-preview-wrapper" <!-- class="image-preview-wrapper"-->
> <!-- >-->
<img :src="imageUrl"> <!-- <img :src="imageUrl">-->
<div class="image-preview-action"> <!-- <div class="image-preview-action">-->
<i <!-- <i-->
class="el-icon-delete" <!-- class="el-icon-delete"-->
@click="rmImage" <!-- @click="rmImage"-->
/> <!-- />-->
</div> <!-- </div>-->
</div> <!-- </div>-->
</div> <!-- </div>-->
<div class="image-preview"> <div class="image-preview">
<div <div
v-show="imageUrl.length>1" v-show="imageUrl.length>1"
@ -54,8 +55,11 @@ import { Component, Prop, Vue } from 'vue-property-decorator'
export default class extends Vue { export default class extends Vue {
@Prop({ default: '' }) private value!: string @Prop({ default: '' }) private value!: string
private uploadUrl = 'https://opm.kingsome.cn/api/upload'
// private uploadUrl = 'http://127.0.0.1:4000/api/upload'
private tempUrl = '' private tempUrl = ''
private dataObj = { token: '', key: '' } private dataObj = { sub_path: 'game', type: 'image' }
get imageUrl() { get imageUrl() {
return this.value return this.value
@ -70,7 +74,8 @@ export default class extends Vue {
} }
private handleImageSuccess(res: any) { private handleImageSuccess(res: any) {
this.emitInput(res.files.file) console.log(res)
this.emitInput(res.url_cdn)
} }
} }
</script> </script>
@ -88,7 +93,6 @@ export default class extends Vue {
.image-preview { .image-preview {
width: 200px; width: 200px;
height: 200px;
position: relative; position: relative;
border: 1px dashed #d9d9d9; border: 1px dashed #d9d9d9;
float: left; float: left;
@ -97,18 +101,15 @@ export default class extends Vue {
.image-preview-wrapper { .image-preview-wrapper {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%;
img { img {
width: 100%; width: 100%;
height: 100%;
} }
} }
.image-preview-action { .image-preview-action {
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%;
left: 0; left: 0;
top: 0; top: 0;
cursor: default; cursor: default;

View File

@ -30,16 +30,16 @@ const marketingRoutes: RouteConfig = {
icon: 'promo' icon: 'promo'
} }
}, },
// { {
// path: 'points', path: 'points',
// component: () => import('@/views/marketing/points.vue'), component: () => import('@/views/marketing/points.vue'),
// name: 'PointsSetting', name: 'PointsSetting',
// meta: { meta: {
// title: 'marketing_points', title: 'marketing_points',
// permissions: ['points:read'], permissions: ['points:read'],
// icon: 'points' icon: 'points'
// } }
// } }
] ]
} }

View File

@ -1,187 +1,135 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- filter --> <el-form
<el-form ref="filterForm" :inline="true" :model="filterForm" class="filter"> ref="form"
<el-form-item label="关键字" prop="key"> :model="form"
<el-input v-model="filterForm.key" placeholder="关键字"/> label-width="120px"
</el-form-item> >
<el-form-item label="店铺"> <el-form-item label="Activity name">
<el-select <el-input v-model="form.name" />
v-model="filterForm.department" </el-form-item>
placeholder="所有" <el-form-item label="Activity zone">
class="w100" <el-select
v-model="form.region"
placeholder="please select your zone"
> >
<el-option value="">所有</el-option>
<el-option <el-option
v-for="item in allDepts" label="Zone one"
:key="item._id" value="shanghai"
:label="item.name" />
:value="item._id" <el-option
label="Zone two"
value="beijing"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker
v-model="form.date1"
type="date"
placeholder="Pick a date"
style="width: 100%;"
/>
</el-col>
<el-col
:span="2"
class="line"
>
-
</el-col>
<el-col :span="11">
<el-time-picker
v-model="form.date2"
type="fixed-time"
placeholder="Pick a time"
style="width: 100%;"
/>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery" />
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox
label="Online activities"
name="type"
/>
<el-checkbox
label="Promotion activities"
name="type"
/>
<el-checkbox
label="Offline activities"
name="type"
/>
<el-checkbox
label="Simple brand exposure"
name="type"
/>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor" />
<el-radio label="Venue" />
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input
v-model="form.desc"
type="textarea"
/>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="search">查询</el-button> <el-button
<el-button @click="resetFilterForm">重置</el-button> type="primary"
@click="onSubmit"
>
Create
</el-button>
<el-button @click="onCancel">
Cancel
</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<router-link to="/system/create">
<el-button
type="primary"
icon="el-icon-edit"
>
添加
</el-button>
</router-link>
<el-table
v-loading="listLoading"
:data="list"
border
fit
highlight-current-row
style="width: 100%;margin-top:30px;"
>
<el-table-column
width="180px"
align="center"
label="添加时间"
>
<template slot-scope="{row}">
<span>{{ row.createdAt | parseTime }}</span>
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
>
<template slot-scope="scope">
<router-link :to="'/system/edit/'+scope.row._id">
<el-button
type="primary"
size="small"
icon="el-icon-edit"
>
编辑
</el-button>
</router-link>
<el-button
type="danger"
size="small"
style="margin-left: 10px"
@click="handleDelete(scope)"
>
{{ $t('permission.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
@pagination="getList"
/>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator' import { Component, Vue } from 'vue-property-decorator'
import { IShopData } from '@/api/types'
import Pagination from '@/components/Pagination/index.vue'
import { deleteShop, getShops } from '@/api/shop'
import { parseTime } from '@/utils'
import { Form } from 'element-ui'
@Component({ @Component({
name: 'PointsList', name: 'PointsView'
components: {
Pagination
},
filters: {
parseTime: (timestamp: string) => {
return parseTime(timestamp)
}
}
}) })
export default class extends Vue { export default class extends Vue {
private total = 0 private form = {
private list: IShopData[] = [] name: '',
private listLoading = true region: '',
private allDepts = [] date1: '',
private listQuery = { date2: '',
page: 1, delivery: false,
limit: 20, type: [],
key: '' resource: '',
} desc: ''
private filterForm = { };
key: ''
private onSubmit() {
this.$message('submit!')
} }
created() { private onCancel() {
this.getList() this.$message({
this.getRemoteDeptList() message: 'cancel!',
}
private async getList() {
this.listLoading = true
const { data } = await getShops(this.listQuery)
this.listLoading = false
this.list = data.records
this.total = data.total
}
private async handleDelete(scope: any) {
const { $index, row } = scope
await this.$confirm('确认删除该店铺?', 'Warning', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning' type: 'warning'
}) })
await deleteShop(row._id)
this.list.splice($index, 1)
this.$message({
type: 'success',
message: '删除成功!'
})
} }
private search() {
this.filterData()
}
private filterData() {
this.listQuery.key = this.filterForm.key
this.listQuery.page = 1
this.getList()
}
private resetFilterForm() {
const ref = <Form>this.$refs.filterForm
ref.resetFields()
}
private async getRemoteDeptList(name: string) {
const { data } = await getShops({ key: name })
if (!data.records) return
this.allDepts = data.records
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.edit-input { .line {
padding-right: 100px; text-align: center;
} }
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style> </style>

View File

@ -8,7 +8,6 @@
class="form-container" class="form-container"
> >
<el-form-item <el-form-item
label="店铺名" label="店铺名"
> >
<el-select <el-select
@ -30,6 +29,27 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item
label="显示名"
prop="showName"
>
<el-input
v-model="postForm.showName"
name="showName"
style="width: 50%"
required
/>
</el-form-item>
<el-form-item
label="类别"
prop="category"
>
<el-input
v-model="postForm.category"
name="category"
style="width: 50%"
/>
</el-form-item>
<el-form-item <el-form-item
label="区域" label="区域"
> >
@ -49,6 +69,25 @@
required required
/> />
</el-form-item> </el-form-item>
<el-form-item
label="座标点"
prop="lng"
>
{{postForm.lat}} - {{postForm.lng}}
<el-button
type="success"
v-loading="querying"
@click="updateLoc"
>
更新座标
</el-button>
</el-form-item>
<el-form-item
prop="imageURL"
label="logo"
>
<upload-image v-model="postForm.logo" />
</el-form-item>
<el-form-item> <el-form-item>
<el-button <el-button
type="primary" type="primary"
@ -74,7 +113,7 @@ import UploadImage from '@/components/UploadImage/index.vue'
import RegionPicker from '@/components/RegionPicker/index.vue' import RegionPicker from '@/components/RegionPicker/index.vue'
import { Form } from 'element-ui' import { Form } from 'element-ui'
import { defaultShopData, getShop, saveShop } from '@/api/shop' import { defaultShopData, getShop, saveShop } from '@/api/shop'
import { queryArea } from '@/api/map' import { addressToLoc, queryArea } from '@/api/map'
@Component({ @Component({
name: 'ShopEditor', name: 'ShopEditor',
@ -109,6 +148,7 @@ export default class extends Vue {
private postForm = Object.assign({}, defaultShopData) private postForm = Object.assign({}, defaultShopData)
private loading = false private loading = false
private querying = false
private rules = { private rules = {
name: [{ validator: this.validateRequire }], name: [{ validator: this.validateRequire }],
} }
@ -230,7 +270,28 @@ export default class extends Vue {
console.log(result) console.log(result)
if (result) { if (result) {
this.postForm.address = result.address this.postForm.address = result.address
this.postForm.showName = this.postForm.name
this.postForm.areaCode = result.adcode this.postForm.areaCode = result.adcode
this.postForm.areaStr = `${result.province}-${result.city}-${result.district}`
this.postForm.extData = result.id
this.postForm.category = result.category
if (result.location) {
this.postForm.lat = result.location.lat
this.postForm.lng = result.location.lng
}
}
}
private async updateLoc() {
if (!this.postForm.address) {
return
}
this.querying = true
let {data} = await addressToLoc(this.postForm.address)
console.log(data)
this.querying = false
if (data.location) {
this.postForm.lat = data.location.lat
this.postForm.lng = data.location.lng
} }
} }