Browse Source

处理地图

master
1263428893@qq.com 4 months ago
parent
commit
830ebf0bdc
10 changed files with 875 additions and 22019 deletions
  1. +2
    -2
      admin-hanhai-vue/.env.development
  2. +102
    -22016
      admin-hanhai-vue/package-lock.json
  3. +1
    -0
      admin-hanhai-vue/package.json
  4. +1
    -1
      admin-hanhai-vue/public/index.html
  5. +3
    -0
      admin-hanhai-vue/src/main.js
  6. +221
    -0
      admin-hanhai-vue/src/views/travelExperience/TravelExperienceList.vue
  7. +235
    -0
      admin-hanhai-vue/src/views/travelExperience/modules/TencentMapPicker.vue
  8. +166
    -0
      admin-hanhai-vue/src/views/travelExperience/modules/TravelExperienceForm.vue
  9. +84
    -0
      admin-hanhai-vue/src/views/travelExperience/modules/TravelExperienceModal.Style#Drawer.vue
  10. +60
    -0
      admin-hanhai-vue/src/views/travelExperience/modules/TravelExperienceModal.vue

+ 2
- 2
admin-hanhai-vue/.env.development View File

@ -1,6 +1,6 @@
NODE_ENV=development NODE_ENV=development
//VUE_APP_API_BASE_URL=https://traveladmin.augcl.com/travel-api/
VUE_APP_API_BASE_URL=http://localhost:8001/travel-api/
VUE_APP_API_BASE_URL=https://traveladmin.augcl.com/travel-api/
# VUE_APP_API_BASE_URL=http://localhost:8001/travel-api/
VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview


+ 102
- 22016
admin-hanhai-vue/package-lock.json
File diff suppressed because it is too large
View File


+ 1
- 0
admin-hanhai-vue/package.json View File

@ -35,6 +35,7 @@
"vue-area-linkage": "^5.1.0", "vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.5.4", "vue-cropper": "^0.5.4",
"vue-i18n": "^8.7.0", "vue-i18n": "^8.7.0",
"vue-jsonp": "^2.0.0",
"vue-loader": "^15.7.0", "vue-loader": "^15.7.0",
"vue-ls": "^3.2.0", "vue-ls": "^3.2.0",
"vue-photo-preview": "^1.1.3", "vue-photo-preview": "^1.1.3",


+ 1
- 1
admin-hanhai-vue/public/index.html View File

@ -254,7 +254,7 @@
</div> </div>
</div> </div>
</div> </div>
<!-- <script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=SNGBZ-K6AKJ-5X2FI-XYKCM-DEZXZ-FGBA3"></script> -->
</body> </body>
</html> </html>

+ 3
- 0
admin-hanhai-vue/src/main.js View File

@ -8,6 +8,9 @@ import router from './router'
import store from './store/' import store from './store/'
import { VueAxios } from "@/utils/request" import { VueAxios } from "@/utils/request"
import { VueJsonp } from 'vue-jsonp'
Vue.use(VueJsonp)
require('@jeecg/antd-online-mini') require('@jeecg/antd-online-mini')
require('@jeecg/antd-online-mini/dist/OnlineForm.css') require('@jeecg/antd-online-mini/dist/OnlineForm.css')


+ 221
- 0
admin-hanhai-vue/src/views/travelExperience/TravelExperienceList.vue View File

@ -0,0 +1,221 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('非遗体验表')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<!-- 高级查询区域 -->
<j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
class="j-table-force-nowrap"
@change="handleTableChange">
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text,record">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="downloadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
<a-menu slot="overlay">
<a-menu-item>
<a @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<travel-experience-modal ref="modalForm" @ok="modalFormOk"></travel-experience-modal>
</a-card>
</template>
<script>
import '@/assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import TravelExperienceModal from './modules/TravelExperienceModal'
export default {
name: 'TravelExperienceList',
mixins:[JeecgListMixin, mixinDevice],
components: {
TravelExperienceModal
},
data () {
return {
description: '非遗体验表管理页面',
//
columns: [
{
title: '#',
dataIndex: '',
key:'rowIndex',
width:60,
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
{
title:'非遗体验标题',
align:"center",
dataIndex: 'experienceTitle'
},
{
title:'非遗体验封面',
align:"center",
dataIndex: 'experienceImage',
scopedSlots: {customRender: 'imgSlot'}
},
{
title:'开放时间',
align:"center",
dataIndex: 'experienceOpentime'
},
{
title:'非遗体验详情',
align:"center",
dataIndex: 'experienceDetail',
scopedSlots: {customRender: 'htmlSlot'}
},
{
title:'开放时间',
align:"center",
dataIndex: 'openTime'
},
{
title:'联系电话',
align:"center",
dataIndex: 'phone'
},
{
title:'经度',
align:"center",
dataIndex: 'experienceLongitude'
},
{
title:'纬度',
align:"center",
dataIndex: 'experienceLatitude'
},
{
title:'价格',
align:"center",
dataIndex: 'experiencePrice'
},
{
title: '操作',
dataIndex: 'action',
align:"center",
fixed:"right",
width:147,
scopedSlots: { customRender: 'action' }
}
],
url: {
list: "/travelExperience/travelExperience/list",
delete: "/travelExperience/travelExperience/delete",
deleteBatch: "/travelExperience/travelExperience/deleteBatch",
exportXlsUrl: "/travelExperience/travelExperience/exportXls",
importExcelUrl: "travelExperience/travelExperience/importExcel",
},
dictOptions:{},
superFieldList:[],
}
},
created() {
this.getSuperFieldList();
},
computed: {
importExcelUrl: function(){
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
},
methods: {
initDictConfig(){
},
getSuperFieldList(){
let fieldList=[];
fieldList.push({type:'string',value:'experienceTitle',text:'非遗体验标题',dictCode:''})
fieldList.push({type:'string',value:'experienceImage',text:'非遗体验封面',dictCode:''})
fieldList.push({type:'string',value:'experienceOpentime',text:'开放时间',dictCode:''})
fieldList.push({type:'Text',value:'experienceDetail',text:'非遗体验详情',dictCode:''})
fieldList.push({type:'string',value:'openTime',text:'开放时间',dictCode:''})
fieldList.push({type:'string',value:'phone',text:'联系电话',dictCode:''})
fieldList.push({type:'BigDecimal',value:'experienceLongitude',text:'经度',dictCode:''})
fieldList.push({type:'BigDecimal',value:'experienceLatitude',text:'纬度',dictCode:''})
fieldList.push({type:'BigDecimal',value:'experiencePrice',text:'价格',dictCode:''})
this.superFieldList = fieldList
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

+ 235
- 0
admin-hanhai-vue/src/views/travelExperience/modules/TencentMapPicker.vue View File

@ -0,0 +1,235 @@
<template>
<div>
<div class="map-box">
<div class="map" ref="map" style="height: 400px" ></div>
<div class="map-search">
<div>
<a-input-search id="place" v-model="searchValue" placeholder="请输入详细地址" enter-button @search="searchAddress(searchValue)" />
</div>
<div>
<ul v-if="kwData.length">
<li v-for="(item, index) in kwData" :key="index" @click="selectKeyword(item)">{{ item.address }}</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TencentMapPicker',
props: {
latitude: {
type: Number|String,
default: 0
},
longitude: {
type: Number|String,
default: 0
}
},
watch: {
latitude(newVal, oldVal) {
console.info(`newVal`,newVal,`oldVal`,oldVal)
if (newVal) {
this.form.latitude = newVal
// this.$nextTick(()=>{
// this.map.setCenter(new window.TMap.LatLng(this.form.latitude, this.form.longitude));
// })
}
},
longitude(newVal, oldVal) {
console.info(`newVal`,newVal,`oldVal`,oldVal)
if (newVal) {
this.form.longitude = newVal
// this.$nextTick(()=>{
// this.map.setCenter(new window.TMap.LatLng(this.form.latitude, this.form.longitude));
// })
}
}
},
data() {
return {
searchValue: '', //
form: {
longitude: 116.397128,
latitude: 39.916527
},
kwData:[]
}
},
mounted() {
let that = this
if (that.script) return;
that.script = document.createElement('script');
that.script.type = 'text/javascript';
that.script.src = `//map.qq.com/api/gljs?v=1.exp&libraries=service&key=SNGBZ-K6AKJ-5X2FI-XYKCM-DEZXZ-FGBA3`;
document.head.appendChild(that.script);
that.script.onload = () => {
window.initMap = that.initMap;
that.$nextTick(() => {
that.initMap();
});
};
},
methods: {
//
initMap() {
//
this.searchEr = new window.TMap.service.Search({ pageSize: 15 });
//
this.map = new window.TMap.Map(this.$refs.map, {
backgroundColor: '#f7f7f7',
mapStyleId: 'style1',
zoom: 14,
mapTypeControlOptions: {
mapTypeIds: [],
},
draggableCursor: 'crosshair',
center: new window.TMap.LatLng(this.form.latitude, this.form.longitude),
});
//
this.markerLayer = new window.TMap.MultiMarker({
map: this.map,
geometries: [],
});
//
this.geocoder = new window.TMap.service.Geocoder();
const setMarker = () => {
const latlng = new window.TMap.LatLng(this.form.latitude, this.form.longitude);
this.markerLayer.setGeometries([]);
let geometries = this.markerLayer.getGeometries();
geometries.push({
id: '-1',
position: latlng,
});
this.markerLayer.updateGeometries(geometries);
};
this.map.on('click', (e) => {
this.form.longitude = e.latLng.getLng(); //
this.form.latitude = e.latLng.getLat(); //
setMarker();
this.getAddressFormat();
});
if (this.form.longitude) {
this.map.setCenter(new window.TMap.LatLng(this.form.latitude, this.form.longitude));
setMarker();
}
},
selectKeyword(event){
this.map.setCenter(new window.TMap.LatLng(event.location.lat, event.location.lng));
this.kwData = []
},
//
searchAddress(keyword = '') {
if (!keyword) return;
this.$jsonp('https://apis.map.qq.com/ws/place/v1/suggestion', {
key: 'SNGBZ-K6AKJ-5X2FI-XYKCM-DEZXZ-FGBA3',
output: 'jsonp',
keyword: keyword,
}).then((res) => {
console.log(`res`,res)
if (res.status === 0) {
this.kwData = res.data
} else {
this.kwData = []
}
}).catch((e) => {
console.log(e)
})
this.markerLayer.setGeometries([]);
this.searchEr.searchRectangle({
keyword,
bounds: this.map.getBounds(),
})
.then((result) => {
console.info(`result`,result)
const { location = {} } = result.data[0] || {};
const { lat = 39.916527, lng = 116.397128 } = location;
this.map.setCenter(new window.TMap.LatLng(lat, lng));
result.data.forEach((item, index) => {
let geometries = this.markerLayer.getGeometries();
//
geometries.push({
id: String(index),
position: item.location,
});
//
this.markerLayer.updateGeometries(geometries);
});
});
},
getAddressFormat() {
const { longitude, latitude } = this.form;
this.geocoder
.getAddress({
location: new window.TMap.LatLng(latitude, longitude),
})
.then((res) => {
const {
formatted_addresses: { recommend = '' },
} = res.result || {};
this.searchValue = recommend
this.form.hotelDetailAddress = recommend;
this.$emit('onLocationSelected', this.form);
console.log(this.form);
});
},
}
}
</script>
<style>
.map-box {
position: relative;
}
.map-search {
z-index: 1000;
display: flex;
flex-direction: column;
position: absolute;
top: 20px;
left: 20px;
width: 300px;
}
button {
border-radius: 0;
}
.icons {
display: flex;
align-items: center;
justify-content: space-between;
}
.time {
margin-top: 15px;
width: 100%;
font-size: 12px;
flex-wrap: wrap;
height: 70%;
}
ul{
background: white;
list-style-type: none;
padding-left: 0px;
height: 280px;
overflow: scroll;
}
li{
padding-left: 6px;
font-size: 10px;
text-align: left;
height: 40px;
line-height: 15px;
display: flex;
align-items: center;
}
li:hover{
cursor: pointer;
background: #f5f5f5;
}
</style>

+ 166
- 0
admin-hanhai-vue/src/views/travelExperience/modules/TravelExperienceForm.vue View File

@ -0,0 +1,166 @@
<template>
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
<a-row>
<a-col :span="24">
<a-form-model-item label="非遗体验标题" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="experienceTitle">
<a-input v-model="model.experienceTitle" placeholder="请输入非遗体验标题" ></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="非遗体验封面" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="experienceImage">
<j-image-upload isMultiple v-model="model.experienceImage" ></j-image-upload>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="开放时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="experienceOpentime">
<a-input v-model="model.experienceOpentime" placeholder="请输入开放时间" ></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="非遗体验详情" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="experienceDetail">
<j-editor v-model="model.experienceDetail" />
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="开放时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="openTime">
<a-input v-model="model.openTime" placeholder="请输入开放时间" ></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="联系电话" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="phone">
<a-input v-model="model.phone" placeholder="请输入联系电话" ></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="纬度" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="experienceLatitude">
<a-input v-model="model.experienceLatitude" placeholder="请输入纬度" style="width: 100%" />
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="经度" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="experienceLongitude">
<a-input v-model="model.experienceLongitude" placeholder="请输入经度" style="width: 100%" />
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="地图选择位置" :labelCol="labelCol" :wrapperCol="wrapperCol">
<TencentMapPicker
:latitude="model.experienceLatitude"
:longitude="model.experienceLongitude"
@onLocationSelected="handleLocationSelected"
/>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="价格" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="experiencePrice">
<a-input-number v-model="model.experiencePrice" placeholder="请输入价格" style="width: 100%" />
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
</j-form-container>
</a-spin>
</template>
<!-- <script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=SNGBZ-K6AKJ-5X2FI-XYKCM-DEZXZ-FGBA3"></script> -->
<script>
import { httpAction, getAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
import TencentMapPicker from './TencentMapPicker.vue';
export default {
name: 'TravelExperienceForm',
components: {
TencentMapPicker
},
props: {
//:XMBBZ-BCPCV-SXPPQ-5Y7MY-PHZXK-YFFVU
//
disabled: {
type: Boolean,
default: false,
required: false
}
},
data () {
return {
model:{
experienceLongitude:null,
experienceLatitude:null,
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
validatorRules: {
},
url: {
add: "/travelExperience/travelExperience/add",
edit: "/travelExperience/travelExperience/edit",
queryById: "/travelExperience/travelExperience/queryById"
}
}
},
computed: {
formDisabled(){
return this.disabled
},
},
created () {
//model
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods: {
handleLocationSelected({latitude, longitude}) {
console.log('event',latitude, longitude)
this.model.experienceLatitude = latitude;
this.model.experienceLongitude = longitude;
},
add () {
this.edit(this.modelDefault);
},
edit (record) {
this.model = Object.assign({}, record);
this.visible = true;
},
submitForm () {
const that = this;
//
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
}
})
},
}
}
</script>

+ 84
- 0
admin-hanhai-vue/src/views/travelExperience/modules/TravelExperienceModal.Style#Drawer.vue View File

@ -0,0 +1,84 @@
<template>
<a-drawer
:title="title"
:width="width"
placement="right"
:closable="false"
@close="close"
destroyOnClose
:visible="visible">
<travel-experience-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></travel-experience-form>
<div class="drawer-footer">
<a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
<a-button v-if="!disableSubmit" @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
</div>
</a-drawer>
</template>
<script>
import TravelExperienceForm from './TravelExperienceForm'
export default {
name: 'TravelExperienceModal',
components: {
TravelExperienceForm
},
data () {
return {
title:"操作",
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
});
},
close () {
this.$emit('close');
this.visible = false;
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
handleCancel () {
this.close()
}
}
}
</script>
<style lang="less" scoped>
/** Button按钮间距 */
.ant-btn {
margin-left: 30px;
margin-bottom: 30px;
float: right;
}
.drawer-footer{
position: absolute;
bottom: -8px;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

+ 60
- 0
admin-hanhai-vue/src/views/travelExperience/modules/TravelExperienceModal.vue View File

@ -0,0 +1,60 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
switchFullscreen
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
@cancel="handleCancel"
cancelText="关闭">
<travel-experience-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></travel-experience-form>
</j-modal>
</template>
<script>
import TravelExperienceForm from './TravelExperienceForm'
export default {
name: 'TravelExperienceModal',
components: {
TravelExperienceForm
},
data () {
return {
title:'',
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
}
}
</script>

Loading…
Cancel
Save