This commit is contained in:
2023-03-20 17:28:07 +08:00
parent a7606b1f20
commit bff5199726
42 changed files with 5202 additions and 467 deletions

491
src/views/sch/classType.vue Normal file
View File

@@ -0,0 +1,491 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6">
<div class="head-container">
<el-input v-model="searchName" placeholder="请输入驾校名称" clearable prefix-icon="el-icon-search" style="margin-bottom: 20px" />
</div>
<div class="head-container" style="max-height: 700px;overflow-y: auto">
<el-tree ref="tree" :data="schoolOption.filter(item => item.label.includes(searchName))" accordion node-key="id" :default-expanded-keys="selectNodes.map(item => item.id)" @node-click="handleNodeClick" />
</div>
</el-col>
<el-col :span="18">
<el-row :gutter="20">
<el-form ref="queryForm" :model="queryParams" :inline="true">
<el-form-item>
<el-input v-model="queryParams.typeName" placeholder="请输入班型名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-select v-model="queryParams.licenseType" clearable placeholder="选择驾照类型">
<el-option v-for="item in licenseTypeOption" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="queryParams.status" placeholder="班型状态" clearable>
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" icon="el-icon-plus" @click="handleAdd" v-hasPermi="['sch:classType:add']">新增</el-button>
<el-button type="danger" icon="el-icon-delete" @click="handleDelete" :disabled="multiple" v-hasPermi="['sch:classType:remove']">删除</el-button>
<el-button type="primary" icon="el-icon-copy" @click="handleClone" :disabled="multiple" v-hasPermi="['sch:classType:clone']">克隆</el-button>
</el-form-item>
</el-form>
</el-row>
<el-table v-loading="loading.tableLoading" :data="tableDataList" stripe border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column type="index" width="50" />
<el-table-column label="驾校" prop="schoolName" />
<el-table-column label="场地" prop="placeName" />
<el-table-column label="班型名称" prop="typeName" />
<el-table-column label="驾照类型" prop="licenseType" :formatter="licenseTypeFormat" width="80" />
<!-- <el-table-column label="原价" prop="originalPrice" /> -->
<el-table-column label="报价" prop="currentPrice" width="60" />
<el-table-column label="底价" prop="minPrice" width="60" />
<el-table-column label="描述" prop="description" />
<el-table-column label="状态" prop="status" :formatter="statusFormat" width="80" />
<el-table-column label="创建时间" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="130">
<template slot-scope="scope">
<el-button v-hasPermi="['sch:classType:edit']" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button v-hasPermi="['sch:classType:remove']" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getPageList" />
</el-col>
</el-row>
<el-dialog title="班型设置" :visible.sync="modalVisible" width="500px" append-to-body :close-on-click-modal="false">
<el-form ref="modalForm" :model="modalForm" :rules="modalRules" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="驾校">
<el-input v-model="modalForm.schoolName" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="场地">
<el-input v-model="modalForm.placeName" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="班型名称" prop="typeName">
<el-input v-model="modalForm.typeName" placeholder="请输入班型名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="驾照类型" prop="licenseType">
<el-select v-model="modalForm.licenseType" placeholder="选择驾照类型">
<el-option v-for="item in licenseTypeOption" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="报价" prop="currentPrice">
<el-input v-model="modalForm.currentPrice" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="底价" prop="minPrice">
<el-input v-model="modalForm.minPrice" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="甩单低价" prop="orderMinPrice">
<el-input v-model="modalForm.orderMinPrice" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入账低价" prop="enterMinPrice">
<el-input v-model="modalForm.enterMinPrice" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="公司低价" prop="companyMinPrice">
<el-input v-model="modalForm.companyMinPrice" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="员工低价" prop="employeeMinPrice">
<el-input v-model="modalForm.employeeMinPrice" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="排序" prop="orderNum">
<el-input v-model="modalForm.orderNum" placeholder="请输入排序" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" prop="currentPrice">
<el-radio-group v-model="modalForm.status">
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>
<el-col :span="24">
<el-form-item label="是否克隆到场地" prop="currentPrice">
<el-radio-group v-model="modalForm.clone">
<el-radio :label="true">是</el-radio>
<el-radio :label="false">否</el-radio>
</el-radio-group>
</el-form-item>
<span>克隆到场地,该班型则不统一管理</span>
</el-col>
</el-row> -->
<el-row>
<el-form-item label="描述" prop="description">
<el-input v-model="modalForm.description" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入描述" />
</el-form-item>
</el-row>
</el-form>
<span slot="footer">
<el-button @click="modalVisible = false">取 消</el-button>
<el-button v-loading="loading.modalSaveLoading" type="primary" @click="handleSave">确 定</el-button>
</span>
</el-dialog>
<el-dialog title="克隆班型" :visible.sync="cloneOpen" width="780px" append-to-body :v-loading="loading.cloneLoading">
<el-form ref="clonForm" :model="clonForm" :rules="modalRules" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="场地" prop="placeIdList">
<el-select v-model="clonForm.placeIds" placeholder="请选择" size="small" multiple filterable clearable>
<el-option v-for="dict in placeOption" :key="dict.placeId" :label="dict.name" :value="dict.placeId" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer" style="padding-top:20px">
<el-button type="primary" @click="cloneSave">确 定</el-button>
<el-button @click="cloneOpen = false">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getClassTypeTableList,
updateClassType,
insertClassType,
deleteClassType,
cloneClassType
} from '@/api/sch/classType'
import { validateMoney } from '@/utils/validate'
import { getMapData } from '@/api/sch/place'
export default {
name: 'Classtype',
data() {
return {
searchName: '',
queryParams: {
pageNum: 1,
pageSize: 10,
typeName: undefined,
status: undefined,
schoolId: this.$store.getters.schoolId,
licenseType: undefined,
},
loading: {
tableLoading: false,
modalSaveLoading: false,
cloneLoading: false
},
tableDataList: [],
total: 0,
statusOptions: [],
licenseTypeOption: [],
modalVisible: false,
modalForm: {},
modalRules: {
typeName: {
required: true,
message: '班型名称不为空',
trigger: 'blur',
},
originalPrice: {
required: true,
validator: validateMoney,
trigger: 'blur',
},
currentPrice: {
required: true,
validator: validateMoney,
trigger: 'blur',
},
minPrice: { required: true, validator: validateMoney, trigger: 'blur' },
placeIds: {
required: true,
message: '场地不为空',
trigger: 'change',
},
},
schoolOption: [],
placeOption: [],
selectNodes: [],
multiple: true,
single: true,
cloneOpen: false,
clonForm: {}
}
},
created() {
this.getDicts('sys_normal_disable').then((response) => {
this.statusOptions = response.data
})
this.getDicts('license_type').then((response) => {
this.licenseTypeOption = response.data
})
this._getSchoolTree()
this.getPageList()
this.deptId = this.$store.getters.schoolId
},
methods: {
// 搜索
handleQuery() {
this.queryParams.page = 1
this.getPageList()
},
getPageList() {
this.loading.tableLoading = true
const params = {
...this.queryParams,
schoolId:
this.selectNodes.length > 0 ? this.selectNodes[0].id : undefined,
placeId:
this.selectNodes.length == 2 ? this.selectNodes[1].id : undefined,
}
this.tableDataList = []
getClassTypeTableList(params).then(
(response) => {
this.tableDataList = response.rows
this.total = response.total
this.loading.tableLoading = false
}
)
},
// 重置搜索
resetQuery() {
this.queryParams.typeName = ''
this.queryParams.status = undefined
this.queryParams.schoolId = undefined
this.queryParams.placeId = undefined
this.queryParams.licenseType = undefined
this.handleQuery()
},
// 查询驾校
_getSchoolTree() {
getMapData().then((resp) => {
if (resp.code == 200) {
let sList = resp.data.schoolList.filter((item) => item.showInMap)
const pList = resp.data.placeList.filter((item) => item.showInMap)
sList = sList.map((item) => ({
id: item.schoolId,
label: item.schoolName,
level: 1,
children: pList
.filter((place) => item.schoolId === place.schoolId)
.map((place) => ({
id: place.placeId,
label: place.name,
level: 2,
})),
}))
this.schoolOption = sList
this.placeOption = resp.data.placeList
}
})
},
// 新增
handleAdd() {
if (this.selectNodes.length < 1) {
this.msgError('请选择左侧驾校或场地')
return
}
this.resetForm('modalForm')
this.modalVisible = true
this.modalForm = {
typeName: '',
status: '0',
originalPrice: undefined,
licenseType: 'C1',
description: '',
currentPrice: undefined,
typeId: undefined,
schoolId: this.selectNodes[0].id,
schoolName: this.selectNodes[0].name,
clone: false,
orderMinPrice: undefined,
enterMinPrice: undefined,
companyMinPrice: undefined,
employeeMinPrice: undefined
}
if (this.selectNodes.length > 1) {
this.$set(this.modalForm, "placeId", this.selectNodes[1].id);
this.$set(this.modalForm, "placeName", this.selectNodes[1].name);
}
},
// 编辑
handleUpdate(listItem) {
this.resetForm('modalForm')
this.modalForm = {
...listItem
}
if (listItem.placeId) {
this.$set(
this.modalForm,
"placeName",
this.placeOption.find(item => item.placeId == listItem.placeId).name
);
}
this.modalVisible = true
},
// 模态框保存
handleSave() {
this.$refs.modalForm.validate((valid) => {
if (valid) {
this.loading.modalSaveLoading = true
if (this.modalForm.typeId) {
updateClassType(this.modalForm).then((resp) => {
if (resp.code === 200) {
this.$message.success('修改成功')
this.modalVisible = false
this.loading.modalSaveLoading = false
this.getPageList()
} else {
this.$message.error('修改失败:' + resp.message)
this.loading.modalSaveLoading = false
}
})
} else {
if (!this.modalForm.schoolId) {
this.$set(this.modalForm, 'schoolId', this.$store.getters.schoolId)
}
insertClassType(this.modalForm).then((resp) => {
if (resp.code === 200) {
this.$message.success('新增成功')
this.modalVisible = false
this.loading.modalSaveLoading = false
this.getPageList()
} else {
this.$message.error('新增失败:' + resp.message)
this.loading.modalSaveLoading = false
}
})
}
}
})
},
// 字典状态字典翻译
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status)
},
// 字典状态字典翻译
placeFormat(row, column) {
if (row.placeId) {
return this.placeOption.length > 0
? this.placeOption.find((item) => item.placeId == row.placeId).name
: ''
}
},
// 字典状态字典翻译
licenseTypeFormat(row, column) {
return this.selectDictLabel(this.licenseTypeOption, row.licenseType)
},
handleNodeClick(data, node) {
if (data.level === 1) {
this.selectNodes = [{ id: data.id, name: data.label }]
} else {
this.selectNodes = [
{ id: node.parent.data.id, name: node.parent.data.label },
{ id: data.id, name: data.label },
]
}
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.typeId);
this.nos = selection.map(item => item.productNo);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 删除按钮操作 */
handleDelete(item) {
const typeId = item.typeId || this.ids;
this.$confirm(
'是否确认删除?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then((res) => {
deleteClassType(typeId).then((resp) => {
if (resp.code === 200) {
this.$message.success('删除成功')
this.getPageList()
}
})
})
.catch(function () { })
},
handleClone() {
this.cloneOpen = true;
this.clonForm = {
typeIds: this.ids,
placeIds: undefined
}
},
cloneSave() {
this.$refs.clonForm.validate((valid) => {
if (valid) {
this.loading.cloneLoading = true
cloneClassType(this.clonForm).then((resp) => {
if (resp.code === 200) {
this.$message.success('克隆成功')
this.cloneOpen = false
this.getPageList()
}
this.loading.cloneLoading = false
})
}
})
}
},
}
</script>

View File

@@ -0,0 +1,130 @@
<template>
<el-dialog title="驾校信息" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="600px" @close="closeDialog">
<div>
<el-form :model="dialogForm" :rules="dataRule" label-position="top" ref="dialogForm" @keyup.enter.native="dialogFormSubmit()">
<el-form-item label="驾校名称" prop="schoolName">
<el-input v-model="dialogForm.schoolName" maxlength="100" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item label="负责人" prop="leader">
<el-input v-model="dialogForm.leader" maxlength="100" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item label="联系方式" prop="phone">
<el-input v-model="dialogForm.phone" maxlength="11" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="dialogForm.status">
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="dialogForm.remark" maxlength="300" placeholder="请输入" clearable></el-input>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button plain @click="(visible=false)">取消</el-button>
<el-button type="primary" v-jclick :disabled="!canSubmit" @click="dialogFormSubmit()">确定</el-button>
</span>
</el-dialog>
</template>
<script>
import api from '@/api/sch/school';
import { mapGetters } from 'vuex';
export default {
dicts: ['sys_normal_disable'],
props: {
},
computed: {
...mapGetters(['userInfo'])
},
data() {
return {
visible: false,
canSubmit: true,
dialogForm: {
schoolId: undefined,
schoolName: undefined,
leader: undefined,
phone: undefined,
remark: undefined,
status: '0'
},
dataRule: {
schoolName: [{ required: true, message: '驾校名称不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
}
};
},
created() { },
methods: {
init(info = undefined) {
// debugger
this.visible = true;
this.$nextTick(() => {
this.resetDialogForm();
this.$refs['dialogForm'].resetFields();
if (info) {
this.dialogForm = this.deepClone(info);
}
});
},
resetDialogForm() {
this.dialogForm = {
schoolId: undefined,
schoolName: undefined,
leader: undefined,
phone: undefined,
remark: undefined
}
},
closeDialog() {
this.$emit('update:dialogVisible', false);
},
// 表单提交
dialogFormSubmit() {
this.$refs.dialogForm.validate((valid) => {
if (valid) {
this.canSubmit = false;
if (this.dialogForm.schoolId) {
// 校验完成,调接口
api
.update(this.dialogForm)
.then((resp) => {
this.canSubmit = true;
if (resp.code == 200) {
this.$message.success('保存成功');
this.$emit('refreshDataList');
this.visible = false;
}
})
.catch(() => {
this.canSubmit = true;
});
} else {
api
.add(this.dialogForm)
.then((resp) => {
this.canSubmit = true;
if (resp.code == 200) {
this.$message.success('保存成功');
this.$emit('refreshDataList');
this.visible = false;
}
})
.catch(() => {
this.canSubmit = true;
});
}
}
})
},
}
};
</script>

772
src/views/sch/place.vue Normal file
View File

@@ -0,0 +1,772 @@
<template>
<div class="amap-page-container">
<div id="map" class="amap-cavans" />
<el-input id="search" v-model="searchBody" class="search-body" placeholder="请输入..." @keyup.enter.native="submitSearch">
<el-button slot="append" icon="el-icon-search" @click="submitSearch" />
</el-input>
<div class="asider" :class="showSchool ? '':'hidden-school'">
<el-card class="box-card" :body-style="{ flex: 1,'overflow-y': 'scroll', padding: 0 }">
<div slot="header" class="clearfix">
<div class="map-card-title">驾校列表</div>
</div>
<div v-for="school in schoolList" :key="school.schoolId" style="margin:10px;" :class="currentdeptId == school.schoolId?'actived-school':''">
<el-card :body-style="{ padding: '10px' }">
<div slot="header" class="clearfix">
<div class="map-card-title">{{ school.schoolName }}</div>
<el-switch v-model="school.showInMap" class="add-icon" active-text="展示" inactive-text="隐藏" @change="changeSchoolStatus(school)" v-hasPermi="['sch:place:edit']" />
</div>
<el-button @click="handleClickSchool(school)">{{ `数据管理(${getCount(school.schoolId)})` }}</el-button>
<el-tooltip content="新增场地" placement="left" effect="dark" v-hasPermi="['sch:place:add']">
<el-button icon="el-icon-plus" class="add-place-btn" @click="handleInsertPlace(school.schoolId)" />
</el-tooltip>
</el-card>
</div>
</el-card>
<div class="asider-sub">
<el-tooltip content="放大" placement="left" effect="dark">
<el-button icon="el-icon-plus" class="is-circle" :disabled="zomm >= 18" @click="bigger" />
</el-tooltip>
<el-tooltip content="缩小" placement="left" effect="dark">
<el-button icon="el-icon-minus" class="is-circle" :disabled="zomm <= 8" @click="smaller" />
</el-tooltip>
<div class="mt10">
<el-tooltip content="驾校" placement="left" effect="dark">
<el-button icon="el-icon-school" class="is-circle" @click="toggleSchool" />
</el-tooltip>
<el-tooltip content="定位" placement="left" effect="dark">
<el-button icon="el-icon-help" class="is-circle" @click="geolocation" />
</el-tooltip>
<el-tooltip content="测距" placement="left" effect="dark">
<el-button icon="el-icon-thumb" class="is-circle" @click="ranging" />
</el-tooltip>
<el-tooltip content="分享" placement="left" effect="dark">
<el-button icon="el-icon-share" class="is-circle" />
</el-tooltip>
</div>
</div>
</div>
<el-card v-if="placeDialogShow" class="place-dialog" :body-style="{ padding: '10px' }">
<div slot="header" class="clearfix">
<div class="map-card-title">场地设置</div>
<el-tooltip content="取点" placement="right" effect="dark">
<el-button icon="el-icon-location" class="add-icon" @click="getPoint" />
</el-tooltip>
</div>
<el-form ref="placeForm" :model="placeForm" label-width="70px">
<el-form-item label="所属驾校" prop="schoolId">
<el-select v-model="placeForm.schoolId" placeholder="请选择" clearable>
<el-option v-for="dict in schoolList" :key="dict.schoolId" :label="dict.schoolName" :value="dict.schoolId" />
</el-select>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="placeForm.name" placeholder="输入名称" />
</el-form-item>
<el-form-item label="旗子颜色" prop="flagColor">
<el-radio-group v-model="placeForm.flagColor">
<el-radio v-for="(item, index) in colorOptions" :key="index" :label="item">
<img :src="require(`@/assets/images/place/flag_${item}.png`)" width="20px" />
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="placeForm.address" placeholder="输入地址" />
</el-form-item>
<el-form-item label="经度" prop="lng">
<el-input v-model="placeForm.lng" placeholder="输入经度" />
</el-form-item>
<el-form-item label="纬度" prop="lat">
<el-input v-model="placeForm.lat" placeholder="输入纬度" />
</el-form-item>
<el-form-item label="所属区域" prop="area">
<el-select v-model="placeForm.area" placeholder="请选择" clearable size="small">
<el-option v-for="dict in areaOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="placeForm.phone" placeholder="输入电话" />
</el-form-item>
<el-form-item label="负责人" prop="contact">
<el-input v-model="placeForm.contact" placeholder="输入负责人" />
</el-form-item>
<el-form-item label="是否推荐" prop="contact">
<el-radio v-model="placeForm.recommend" :label="true"></el-radio>
<el-radio v-model="placeForm.recommend" :label="false"></el-radio>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="placeForm.remark" placeholder="输入备注" type="textarea" :autosize="{ minRows: 2, maxRows: 4}" />
</el-form-item>
<el-form-item style="text-align:right;">
<el-button type="primary" @click="onSubmit" v-hasPermi="['sch:place:edit']">保存</el-button>
<el-button @click="closePlaceDialog">取消</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card :class="placeListDialogShow ? '':'hidden-place-list'" class="place-list-dialog" :style="{ right: showSchool ? '300px' : '0', top : fullScreenPlaceList?'0px':'420px' }" :body-style="{ padding: '10px', height: 'calc(100% - 52px)' }">
<div slot="header" class="clearfix">
<div class="map-card-title">
{{ placeListDialogTitle }}
<el-input v-model="tableSearch" placeholder="请输入搜索的内容" clearable />
</div>
<el-tooltip content="全屏" placement="top" effect="dark">
<el-button icon="el-icon-full-screen" class="add-icon" @click="fullScreenPlaceList = !fullScreenPlaceList" />
</el-tooltip>
<el-tooltip content="关闭" placement="top" effect="dark">
<el-button icon="el-icon-close" class="add-icon" @click="() => { placeListDialogShow = false;fullScreenPlaceList = false }" />
</el-tooltip>
</div>
<el-table :data="placeTableData" border stripe class="place-table-list" height="100%">
<el-table-column label="序号" type="index" fixed="left" width="50" />
<el-table-column prop="name" label="名称" min-width="100" />
<el-table-column prop="phone" label="电话" width="120" />
<el-table-column prop="contact" label="负责人" width="120" />
<el-table-column prop="address" label="地址" min-width="100" />
<el-table-column prop="lng" label="经度" width="110" />
<el-table-column prop="lat" label="纬度" width="110" />
<el-table-column prop="area" label="所属区域" width="110" />
<el-table-column label="展示" width="100">
<template slot-scope="scope">
<el-switch v-model="scope.row.showInMap" @change="changePlaceStatus(scope.row)" v-hasPermi="['sch:place:edit']" />
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-tooltip content="编辑" placement="top" effect="dark" v-hasPermi="['sch:place:edit']">
<el-button icon="el-icon-edit" type="primary" style="padding: 4px 8px;" @click="handleEditPlace(scope.row)" />
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
<div v-if="isPointing || isRanging" class="map-tip" :style="{ transform: 'translate3D(' + (tipPostion.x + 15) +'px,' + (tipPostion.y - 10) + 'px, 0)' }">{{ mapHelpText }}</div>
<i v-if="isPointing" class="el-icon-s-flag circle" :style="{ transform: 'translate3D(' + tipPostion.x +'px,' + tipPostion.y + 'px, 0)' }" />
</div>
</template>
<script>
import { getMapData, savePlace, updateSchoolStatus } from '@/api/sch/place'
export default {
name: 'Place',
data() {
return {
aMap: null,
zomm: 12,
showSchool: true,
isRanging: false,
aMapLocation: null,
aMouseTool: null,
searchBody: '',
placeSearch: null,
placeDialogShow: false,
isPointing: false,
placeForm: {
lat: undefined,
lng: undefined,
name: undefined,
address: undefined,
remark: undefined,
phone: undefined,
flagColor: 'red',
},
colorOptions: ['red', 'yellow', 'blue', 'green', 'purple', 'black'],
mapHelpText: '',
tipPostion: {
x: 0,
y: 0,
},
geocoder: null,
locationMarker: null,
selectMarker: null,
placeListDialogShow: false,
placeListDialogTitle: '',
fullScreenPlaceList: false,
tableSearch: '',
tableData: [],
schoolList: [],
currentdeptId: undefined,
placeMarkerList: [],
areaOptions: [],
}
},
computed: {
placeTableData: function () {
if (this.tableSearch) {
return this.tableData.filter((dataNews) => {
return (
dataNews.schoolId === this.currentdeptId &&
Object.keys(dataNews).some((key) => {
return (
String(dataNews[key]).toLowerCase().indexOf(this.tableSearch) >
-1
)
})
)
})
}
return this.tableData.filter(
(dataNews) => dataNews.schoolId === this.currentdeptId
)
},
},
mounted() {
this.initMap()
this.getDicts('dm_area').then((response) => {
this.areaOptions = response.data
})
},
methods: {
initMap() {
window.onLoad = () => {
this.aMap = new AMap.Map('map', {
zoom: this.zomm,
zooms: [8, 18],
})
// 监听缩放
this.aMap.on('zoomend', () => {
this.zomm = this.aMap.getZoom()
this.$message('当前缩放等级:' + this.zomm)
})
// 监听点击
this.aMap.on('click', (ev) => {
if (this.isPointing) {
this.placeForm.lat = ev.lnglat.lat
this.placeForm.lng = ev.lnglat.lng
this.regeoCode()
if (this.selectMarker) {
this.selectMarker.setPosition([
this.placeForm.lng,
this.placeForm.lat,
])
} else {
this.locationMarker.setPosition([
this.placeForm.lng,
this.placeForm.lat,
])
this.aMap.add(this.locationMarker)
}
this.isPointing = false
}
})
// 监听移动
this.aMap.on('mousemove', (ev) => {
if (this.isRanging) {
this.mapHelpText =
'左键单击选点,双击/右键单击完成选点,再次点击测距按钮可退出测距模式,并清除测距结果'
this.tipPostion = {
x: ev.pixel.x,
y: ev.pixel.y,
}
} else if (this.isPointing) {
this.mapHelpText = '点击地图添加标注'
this.tipPostion = {
x: ev.pixel.x,
y: ev.pixel.y,
}
}
})
// 添加地图插件
AMap.plugin(
[
'AMap.Scale',
'AMap.Geolocation',
'AMap.MouseTool',
'AMap.PlaceSearch',
'AMap.Autocomplete',
'AMap.Geocoder',
],
() => {
this.aMap.addControl(new AMap.Scale())
const geoLoca = new AMap.Geolocation({
showButton: false,
})
this.aMapLocation = geoLoca
this.aMap.addControl(geoLoca)
this.aMouseTool = new AMap.MouseTool(this.aMap)
const auto = new AMap.Autocomplete({
input: 'search', // 前端搜索框
})
this.placeSearch = new AMap.PlaceSearch({
map: this.aMap,
})
AMap.event.addListener(auto, 'select', this.select)
this.geocoder = new AMap.Geocoder()
this.locationMarker = new AMap.Marker({
icon: require(`@/assets/images/place/flag_red.png`),
})
}
)
this.getPageData()
}
this.importMap()
},
// 导入地图
importMap() {
const url =
'https://webapi.amap.com/maps?v=1.4.15&key=124646b0e6076de9d801400f833ac986&callback=onLoad'
var jsapi = document.createElement('script')
jsapi.charset = 'utf-8'
jsapi.src = url
document.head.appendChild(jsapi)
},
toggleSchool() {
this.showSchool = !this.showSchool
},
// 经纬度 -> 地址
regeoCode() {
this.geocoder.getAddress(
[this.placeForm.lng, this.placeForm.lat],
(status, result) => {
if (status === 'complete' && result.regeocode) {
this.placeForm.address = result.regeocode.formattedAddress
} else {
console.log('根据经纬度查询地址失败')
}
}
)
},
// 定位
geolocation() {
this.aMapLocation.getCurrentPosition()
},
// 测距
ranging() {
this.isPointing = false
this.isRanging = !this.isRanging
if (this.isRanging) {
this.aMap.setDefaultCursor('crosshair')
this.drawLine()
} else {
this.aMap.setDefaultCursor('default')
this.aMouseTool.close(true)
}
},
// 画线
drawLine() {
this.aMouseTool.rule({
startMarkerOptions: {
// 可缺省
icon: new AMap.Icon({
size: new AMap.Size(19, 31), // 图标大小
imageSize: new AMap.Size(19, 31),
image: 'https://webapi.amap.com/theme/v1.3/markers/b/start.png',
}),
},
endMarkerOptions: {
// 可缺省
icon: new AMap.Icon({
size: new AMap.Size(19, 31), // 图标大小
imageSize: new AMap.Size(19, 31),
image: 'https://webapi.amap.com/theme/v1.3/markers/b/end.png',
}),
offset: new AMap.Pixel(-9, -31),
},
midMarkerOptions: {
// 可缺省
icon: new AMap.Icon({
size: new AMap.Size(19, 31), // 图标大小
imageSize: new AMap.Size(19, 31),
image: 'https://webapi.amap.com/theme/v1.3/markers/b/mid.png',
}),
offset: new AMap.Pixel(-9, -31),
},
lineOptions: {
// 可缺省
strokeStyle: 'solid',
strokeColor: '#FF33FF',
strokeOpacity: 1,
strokeWeight: 2,
},
tmpLineOptions: {
strokeStyle: 'dashed',
strokeColor: '#FF33FF',
strokeOpacity: 1,
strokeWeight: 2,
},
})
},
// 选择查询结果
select(e) {
this.placeSearch.setCity(e.poi.adcode)
this.placeSearch.search(e.poi.name) // 关键字查询查询
},
// 查询按钮/回车事件
submitSearch() {
this.placeSearch.search(this.searchBody)
},
// 缩放
bigger() {
this.zomm++
this.aMap.setZoom(this.zomm)
},
smaller() {
this.zomm--
this.aMap.setZoom(this.zomm)
},
// 点击数据管理
handleClickSchool(item) {
this.placeListDialogShow = true
this.placeListDialogTitle = `数据管理 [${item.schoolName}]`
this.currentdeptId = item.schoolId
},
// 新增场地
handleInsertPlace(schoolId) {
if (this.selectMarker) {
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
this.selectMarker = null
}
this.placeDialogShow = true
this.aMap.setDefaultCursor('default')
this.isRanging = false
this.placeForm = {
lat: undefined,
lng: undefined,
name: undefined,
address: undefined,
remark: undefined,
phone: undefined,
schoolId: schoolId,
showInMap: true,
flagColor: 'red',
}
},
// 编辑场地
handleEditPlace(item) {
this.placeDialogShow = true
this.aMap.setDefaultCursor('default')
if (this.selectMarker) {
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
}
this.isRanging = false
this.placeForm = Object.assign({}, item)
this.selectMarker = this.placeMarkerList.filter(
(marker) => marker.getExtData().placeId === item.placeId
)[0]
this.selectMarker &&
this.selectMarker.setAnimation('AMAP_ANIMATION_BOUNCE')
this.aMap.setCenter([item.lng, item.lat])
},
getPoint() {
this.isPointing = !this.isPointing
},
// 保存
async onSubmit() {
// 保存接口
if (this.checkPlaceFormValidate()) {
// 先访问接口返回id插入placeForm
const resp = await savePlace(this.placeForm)
if (resp.code != 200) {
return
} else {
this.$message.success('操作成功');
}
if (!this.placeForm.placeId && resp.data) {
this.$set(this.placeForm, 'placeId', resp.data)
}
// 移除选点用 的标记
this.aMap.remove(this.locationMarker)
// 根据form创建新marker 并添加到地图上
const tmpMarker = new AMap.Marker({
map: this.aMap,
position: [this.placeForm.lng, this.placeForm.lat],
icon: require(`@/assets/images/place/flag_${this.placeForm.flagColor}.png`),
label: {
content: this.placeForm.name,
direction: 'right',
},
extData: this.placeForm,
})
// 新marker事件
tmpMarker.on('click', this.handleClickMarker)
// 如果当前选择的marker点存在编辑
if (this.selectMarker) {
// 地图上 移除选择的点
this.aMap.remove(this.selectMarker)
this.selectMarker = null
}
// 关闭场地弹窗
this.placeDialogShow = false
this.isPointing = false
// 场地列表 移除原列表中操作的场地数据
const tmpArr = this.tableData.filter(
(item) => item.placeId !== this.placeForm.placeId
)
// 新增新的场地
tmpArr.push(this.placeForm)
// 重置场地数组
this.tableData = tmpArr
// 地图marker列表 移除操作的原marker 添加新marker进数组
const tmpArr1 = this.placeMarkerList.filter(
(item) => item.getExtData().placeId !== this.placeForm.placeId
)
tmpArr1.push(tmpMarker)
this.placeMarkerList = tmpArr1
}
},
checkPlaceFormValidate() {
const valid = []
if (!this.placeForm.name) {
valid.push('名称')
}
if (!this.placeForm.address) {
valid.push('地址')
}
if (!this.placeForm.lng) {
valid.push('经度')
}
if (!this.placeForm.lat) {
valid.push('纬度')
}
if (!this.placeForm.phone) {
valid.push('电话')
}
if (valid.length == 0) {
return true
} else {
this.$message.error(`请将以下填写完整: ${valid.join(',')}`)
return false
}
},
// 关闭场地弹窗
closePlaceDialog() {
this.placeDialogShow = false
this.isPointing = false
this.aMap.remove(this.locationMarker)
if (this.selectMarker) {
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
this.selectMarker = null
}
},
handleClickMarker(ev) {
if (this.selectMarker) {
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
}
this.placeForm = ev.target.getExtData()
this.placeDialogShow = true
ev.target.setAnimation('AMAP_ANIMATION_BOUNCE')
this.selectMarker = ev.target
},
getPageData() {
getMapData().then((resp) => {
if (resp.code == 200) {
this.schoolList = resp.data.schoolList
this.tableData = resp.data.placeList
this.currentdeptId = this.schoolList[0].schoolId
this.createMarkersInMap()
}
})
},
getCount(schoolId) {
return this.tableData.filter((item) => item.schoolId === schoolId).length
},
// 重置markers
resetMarkers() {
this.aMap.clearMap()
this.createMarkersInMap()
},
// 生成markers
createMarkersInMap() {
for (let i = 0; i < this.tableData.length; i++) {
const element = this.tableData[i]
const tempSchool = this.schoolList.filter(
(item) => item.schoolId === element.schoolId
)[0]
if (!tempSchool.showInMap || !element.showInMap) {
continue
}
const tmpMarker = new AMap.Marker({
map: this.aMap,
position: [element.lng, element.lat],
icon: require(`@/assets/images/place/flag_${element.flagColor}.png`),
label: {
content: element.name,
direction: 'right',
},
extData: element,
})
tmpMarker.on('click', this.handleClickMarker)
this.placeMarkerList.push(tmpMarker)
}
},
// 修改驾校状态
changeSchoolStatus(item) {
// 访问接口成功后重置markers
updateSchoolStatus(item).then((resp) => {
if (resp.code == 200) {
this.$message.success('操作成功');
// this.aMap.clearMap()
// this.getPageData()
this.resetMarkers()
}
})
},
// 修改场地状态
async changePlaceStatus(item) {
const resp = await savePlace(item)
if (resp.code == 200) {
this.resetMarkers()
}
},
},
}
</script>
<style scoped>
.amap-page-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.amap-cavans {
width: 100%;
height: 100%;
}
.asider {
position: absolute;
right: 0;
top: 0;
width: 300px;
height: 100%;
transition: 0.3s;
z-index: 9;
}
.box-card {
display: flex;
flex-direction: column;
height: 100%;
}
/deep/ .el-card__header {
padding: 10px 15px;
}
.clearfix {
display: flex;
}
.clearfix .map-card-title {
flex: 1;
line-height: 30px;
}
.clearfix .add-icon {
width: auto;
height: 30px;
}
.asider-sub {
position: absolute;
top: 40px;
left: -45px;
padding: 10px 10px 0 0;
z-index: 900;
}
.asider-sub .is-circle {
display: block;
margin: 0;
padding: 10px;
color: #464646;
border-radius: 0;
font-size: 16px;
box-shadow: 2px 2px 2px rgba(80, 80, 80, 0.67);
}
.mt10 {
margin-top: 10px;
}
.hidden-school {
transform: translateX(300px);
}
.search-body {
position: absolute;
top: 20px;
left: 20px;
width: 400px;
}
.add-place-btn {
float: right;
border: none;
font-size: 16px;
color: #409eff;
}
/deep/.place-dialog {
position: absolute;
left: 20px;
top: 60px;
width: 350px;
}
.map-tip {
position: absolute;
left: 0;
top: 0;
max-width: 150px;
padding: 5px;
border-radius: 2px;
background: #000;
color: #fff;
opacity: 0.7;
font-size: 12px;
transition-duration: 1ms;
}
.circle {
position: absolute;
left: -8px;
top: -25px;
font-size: 24px;
color: red;
transition-duration: 1ms;
}
.place-dialog .el-form .el-form-item {
margin-bottom: 8px;
}
.place-list-dialog {
position: absolute;
top: 420px;
left: 0;
bottom: 0;
transition: 0.3s;
z-index: 151;
background: #e2e5ea;
}
.place-list-dialog .add-icon {
font-size: 18px;
border: none;
}
.hidden-place-list {
transform: translateY(100%);
}
.place-list-dialog .clearfix .map-card-title {
font-weight: bold;
}
.place-list-dialog .clearfix .map-card-title .el-input {
margin-left: 20px;
width: 240px;
}
.actived-school {
border: 2px solid #409eff !important;
}
/deep/ .el-radio__label {
vertical-align: middle;
}
</style>

121
src/views/sch/school.vue Normal file
View File

@@ -0,0 +1,121 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-form ref="queryForm" :model="queryParams" :inline="true">
<el-form-item>
<el-input v-model="queryParams.schoolName" placeholder="请输入驾校名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle(undefined)" v-hasPermi="['sch:school:add']">新增</el-button>
<!-- <el-button type="danger" icon="el-icon-delete" @click="handleDelete" :disabled="multiple" v-hasPermi="['sch:school:remove']">删除</el-button> -->
</el-form-item>
</el-form>
</el-row>
<el-table v-loading="loading.tableLoading" :data="tableDataList" stripe>
<!-- <el-table-column type="selection" width="50" align="center" /> -->
<el-table-column label="序号" type="index" width="50" />
<el-table-column label="驾校名称" prop="schoolName" />
<el-table-column label="负责人" prop="leader" />
<el-table-column label="联系方式" prop="phone" />
<el-table-column label="备注" prop="remark" />
<el-table-column label="创建时间" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="130">
<template slot-scope="scope">
<el-button v-hasPermi="['sch:school:edit']" type="text" icon="el-icon-edit" @click="addOrUpdateHandle(scope.row)">修改</el-button>
<el-button v-hasPermi="['sch:school:remove']" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getPageList" />
<!-- 驾校弹框 -->
<school-form v-if="dialogVisible" :dialogVisible="dialogVisible" ref="dialogForm" @refreshDataList="getPageList" />
</div>
</template>
<script>
import schoolForm from './components/schoolForm.vue'
import schoolApi from '@/api/sch/school'
import { appendFile } from 'fs'
export default {
name: 'School',
components: {
schoolForm
},
data() {
return {
total: 0,
queryParams: {
schoolName: undefined,
pageNum: 1,
pageSize: 10
},
tableDataList: [],
loading: {
tableLoading: false
},
dialogVisible: false,
}
},
created() {
//页面初始化加载
this.getPageList()
},
methods: {
//查询列表数据
getPageList() {
schoolApi.pageList(this.queryParams).then(resp => {
if (resp.code == 200) {
this.tableDataList = resp.rows
this.total = resp.total
}
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getPageList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams = {
schoolName: undefined,
pageNum: 1,
pageSize: 10
},
this.handleQuery();
},
//新增和修改操作
addOrUpdateHandle(item) {
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs.dialogForm.init(item);
});
},
//删除操作
handleDelete(item) {
this.$modal.confirm('删除驾校信息,同时会删除该驾校下的场地信息和班型信息,是否确认名称为"' + item.schoolName + '"的数据项?').then(function () {
return schoolApi.delete(item.schoolId);
}).then((resp) => {
if (resp.code == 200) {
this.getPageList();
this.$modal.msgSuccess("删除成功");
}
}).catch(() => { });
},
},
}
</script>