10 changed files with 746 additions and 292 deletions
@ -1,20 +1,20 @@ |
|||||
{ |
{ |
||||
"campusName": "校区名称", |
"campusName":"校区名称", |
||||
"campusNamePlaceholder": "请输入校区名称", |
"campusNamePlaceholder":"请输入校区名称", |
||||
"campusAddress": "校区地址", |
"campusAddress":"校区地址", |
||||
"campusAddressPlaceholder": "请输入校区地址", |
"campusAddressPlaceholder":"请输入校区地址", |
||||
"campusPreviewImage": "校区预览图,存储图片路径", |
"campusPreviewImage":"校区banner", |
||||
"campusPreviewImagePlaceholder": "请输入校区预览图,存储图片路径", |
"campusPreviewImagePlaceholder":"请选择图片", |
||||
"campusCoordinates": "校区坐标,格式为经度,纬度", |
"campusCoordinates":"校区位置", |
||||
"campusCoordinatesPlaceholder": "请输入校区坐标,格式为经度,纬度", |
"campusCoordinatesPlaceholder":"请选择校区位置", |
||||
"campusIntroduction": "校区介绍", |
"campusIntroduction":"校区介绍", |
||||
"campusIntroductionPlaceholder": "请输入校区介绍", |
"campusIntroductionPlaceholder":"请输入校区介绍", |
||||
"campusStatus": "校区状态", |
"campusStatus":"校区状态", |
||||
"campusStatusPlaceholder": "请输入校区状态", |
"campusStatusPlaceholder":"请输入校区状态", |
||||
"createTime": "校区创建时间", |
"createTime":"校区创建时间", |
||||
"addCampus": "添加校区", |
"addCampus":"添加校区", |
||||
"updateCampus": "编辑校区", |
"updateCampus":"编辑校区", |
||||
"campusDeleteTips": "确定要删除该数据吗?", |
"campusDeleteTips":"确定要删除该数据吗?", |
||||
"startDate": "请选择开始时间", |
"startDate":"请选择开始时间", |
||||
"endDate": "请选择结束时间" |
"endDate":"请选择结束时间" |
||||
} |
} |
||||
@ -1,253 +1,193 @@ |
|||||
<template> |
<template> |
||||
<div class="main-container"> |
<div class="main-container"> |
||||
<el-card class="box-card !border-none" shadow="never"> |
<el-card class="box-card !border-none" shadow="never"> |
||||
<div class="flex justify-between items-center"> |
|
||||
<span class="text-lg">{{ pageName }}</span> |
<div class="flex justify-between items-center"> |
||||
<el-button type="primary" @click="addEvent"> |
<span class="text-lg">{{pageName}}</span> |
||||
{{ t('addCampus') }} |
<el-button type="primary" @click="addEvent"> |
||||
</el-button> |
{{ t('addCampus') }} |
||||
</div> |
</el-button> |
||||
|
</div> |
||||
<el-card |
|
||||
class="box-card !border-none my-[10px] table-search-wrap" |
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> |
||||
shadow="never" |
<el-form :inline="true" :model="campusTable.searchParam" ref="searchFormRef"> |
||||
> |
<el-form-item :label="t('campusName')" prop="campus_name"> |
||||
<el-form |
<el-input v-model="campusTable.searchParam.campus_name" :placeholder="t('campusNamePlaceholder')" /> |
||||
:inline="true" |
</el-form-item> |
||||
:model="campusTable.searchParam" |
<el-form-item :label="t('campusAddress')" prop="campus_address"> |
||||
ref="searchFormRef" |
<el-input v-model="campusTable.searchParam.campus_address" :placeholder="t('campusAddressPlaceholder')" /> |
||||
> |
</el-form-item> |
||||
<el-form-item :label="t('campusName')" prop="campus_name"> |
|
||||
<el-input |
<el-form-item :label="t('campusStatus')" prop="campus_status"> |
||||
v-model="campusTable.searchParam.campus_name" |
<el-select class="w-[280px]" v-model="campusTable.searchParam.campus_status" clearable :placeholder="t('campusStatusPlaceholder')"> |
||||
:placeholder="t('campusNamePlaceholder')" |
<el-option label="全部" value=""></el-option> |
||||
/> |
<el-option |
||||
</el-form-item> |
v-for="(item, index) in campus_statusList" |
||||
<el-form-item :label="t('campusAddress')" prop="campus_address"> |
:key="index" |
||||
<el-input |
:label="item.name" |
||||
v-model="campusTable.searchParam.campus_address" |
:value="item.value" |
||||
:placeholder="t('campusAddressPlaceholder')" |
/> |
||||
/> |
</el-select> |
||||
</el-form-item> |
</el-form-item> |
||||
|
|
||||
<el-form-item :label="t('campusStatus')" prop="campus_status"> |
<el-form-item> |
||||
<el-select |
<el-button type="primary" @click="loadCampusList()">{{ t('search') }}</el-button> |
||||
class="w-[280px]" |
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> |
||||
v-model="campusTable.searchParam.campus_status" |
</el-form-item> |
||||
clearable |
</el-form> |
||||
:placeholder="t('campusStatusPlaceholder')" |
</el-card> |
||||
> |
|
||||
<el-option label="全部" value=""></el-option> |
<div class="mt-[10px]"> |
||||
<el-option |
<el-table :data="campusTable.data" size="large" v-loading="campusTable.loading"> |
||||
v-for="(item, index) in campus_statusList" |
<template #empty> |
||||
:key="index" |
<span>{{ !campusTable.loading ? t('emptyData') : '' }}</span> |
||||
:label="item.name" |
</template> |
||||
:value="item.value" |
<el-table-column prop="campus_name" :label="t('campusName')" min-width="120" :show-overflow-tooltip="true"/> |
||||
/> |
|
||||
</el-select> |
<el-table-column prop="campus_address" :label="t('campusAddress')" min-width="120" :show-overflow-tooltip="true"/> |
||||
</el-form-item> |
|
||||
|
<el-table-column :label="t('campusStatus')" min-width="180" align="center" :show-overflow-tooltip="true"> |
||||
<el-form-item> |
<template #default="{ row }"> |
||||
<el-button type="primary" @click="loadCampusList()">{{ |
<div v-for="(item, index) in campus_statusList"> |
||||
t('search') |
<div v-if="item.value == row.campus_status">{{ item.name }}</div> |
||||
}}</el-button> |
</div> |
||||
<el-button @click="resetForm(searchFormRef)">{{ |
</template> |
||||
t('reset') |
</el-table-column> |
||||
}}</el-button> |
|
||||
</el-form-item> |
<el-table-column prop="create_time" :label="t('createTime')" min-width="120" :show-overflow-tooltip="true"/> |
||||
</el-form> |
|
||||
</el-card> |
<el-table-column :label="t('operation')" fixed="right" min-width="120"> |
||||
|
<template #default="{ row }"> |
||||
<div class="mt-[10px]"> |
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> |
||||
<el-table |
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> |
||||
:data="campusTable.data" |
</template> |
||||
size="large" |
</el-table-column> |
||||
v-loading="campusTable.loading" |
|
||||
> |
</el-table> |
||||
<template #empty> |
<div class="mt-[16px] flex justify-end"> |
||||
<span>{{ !campusTable.loading ? t('emptyData') : '' }}</span> |
<el-pagination v-model:current-page="campusTable.page" v-model:page-size="campusTable.limit" |
||||
</template> |
layout="total, sizes, prev, pager, next, jumper" :total="campusTable.total" |
||||
<el-table-column |
@size-change="loadCampusList()" @current-change="loadCampusList" /> |
||||
prop="campus_name" |
</div> |
||||
:label="t('campusName')" |
</div> |
||||
min-width="120" |
|
||||
:show-overflow-tooltip="true" |
<edit ref="editCampusDialog" @complete="loadCampusList" /> |
||||
/> |
</el-card> |
||||
|
</div> |
||||
<el-table-column |
</template> |
||||
prop="campus_address" |
|
||||
:label="t('campusAddress')" |
<script lang="ts" setup> |
||||
min-width="120" |
import { reactive, ref, watch } from 'vue' |
||||
:show-overflow-tooltip="true" |
import { t } from '@/lang' |
||||
/> |
import { useDictionary } from '@/app/api/dict' |
||||
|
import { getCampusList, deleteCampus } from '@/app/api/campus' |
||||
<el-table-column |
import { img } from '@/utils/common' |
||||
:label="t('campusStatus')" |
import { ElMessageBox,FormInstance } from 'element-plus' |
||||
min-width="180" |
import Edit from '@/app/views/campus/components/campus-edit.vue' |
||||
align="center" |
import { useRoute } from 'vue-router' |
||||
:show-overflow-tooltip="true" |
const route = useRoute() |
||||
> |
const pageName = route.meta.title; |
||||
<template #default="{ row }"> |
|
||||
<div v-for="(item, index) in campus_statusList"> |
let campusTable = reactive({ |
||||
<div v-if="item.value == row.campus_status"> |
page: 1, |
||||
{{ item.name }} |
limit: 10, |
||||
</div> |
total: 0, |
||||
</div> |
loading: true, |
||||
</template> |
data: [], |
||||
</el-table-column> |
searchParam:{ |
||||
|
"campus_name":"", |
||||
<el-table-column |
"campus_address":"", |
||||
prop="create_time" |
"campus_status":"" |
||||
:label="t('createTime')" |
} |
||||
min-width="120" |
}) |
||||
:show-overflow-tooltip="true" |
|
||||
/> |
const searchFormRef = ref<FormInstance>() |
||||
|
|
||||
<el-table-column |
// 选中数据 |
||||
:label="t('operation')" |
const selectData = ref<any[]>([]) |
||||
fixed="right" |
|
||||
min-width="120" |
// 字典数据 |
||||
> |
const campus_statusList = ref([] as any[]) |
||||
<template #default="{ row }"> |
const campus_statusDictList = async () => { |
||||
<el-button type="primary" link @click="editEvent(row)">{{ |
campus_statusList.value = await (await useDictionary('campus_status')).data.dictionary |
||||
t('edit') |
} |
||||
}}</el-button> |
campus_statusDictList(); |
||||
<el-button type="primary" link @click="deleteEvent(row.id)">{{ |
|
||||
t('delete') |
/** |
||||
}}</el-button> |
* 获取校区列表 |
||||
</template> |
*/ |
||||
</el-table-column> |
const loadCampusList = (page: number = 1) => { |
||||
</el-table> |
campusTable.loading = true |
||||
<div class="mt-[16px] flex justify-end"> |
campusTable.page = page |
||||
<el-pagination |
|
||||
v-model:current-page="campusTable.page" |
getCampusList({ |
||||
v-model:page-size="campusTable.limit" |
page: campusTable.page, |
||||
layout="total, sizes, prev, pager, next, jumper" |
limit: campusTable.limit, |
||||
:total="campusTable.total" |
...campusTable.searchParam |
||||
@size-change="loadCampusList()" |
}).then(res => { |
||||
@current-change="loadCampusList" |
campusTable.loading = false |
||||
/> |
campusTable.data = res.data.data |
||||
</div> |
campusTable.total = res.data.total |
||||
</div> |
}).catch(() => { |
||||
|
campusTable.loading = false |
||||
<edit ref="editCampusDialog" @complete="loadCampusList" /> |
}) |
||||
</el-card> |
} |
||||
</div> |
loadCampusList() |
||||
</template> |
|
||||
|
const editCampusDialog: Record<string, any> | null = ref(null) |
||||
<script lang="ts" setup> |
|
||||
import { reactive, ref, watch } from 'vue' |
/** |
||||
import { t } from '@/lang' |
* 添加校区 |
||||
import { useDictionary } from '@/app/api/dict' |
*/ |
||||
import { getCampusList, deleteCampus } from '@/app/api/campus' |
const addEvent = () => { |
||||
import { img } from '@/utils/common' |
editCampusDialog.value.setFormData() |
||||
import { ElMessageBox, FormInstance } from 'element-plus' |
editCampusDialog.value.showDialog = true |
||||
import Edit from '@/app/views/campus/components/campus-edit.vue' |
} |
||||
import { useRoute } from 'vue-router' |
|
||||
const route = useRoute() |
/** |
||||
const pageName = route.meta.title |
* 编辑校区 |
||||
|
* @param data |
||||
let campusTable = reactive({ |
*/ |
||||
page: 1, |
const editEvent = (data: any) => { |
||||
limit: 10, |
editCampusDialog.value.setFormData(data) |
||||
total: 0, |
editCampusDialog.value.showDialog = true |
||||
loading: true, |
} |
||||
data: [], |
|
||||
searchParam: { |
/** |
||||
campus_name: '', |
* 删除校区 |
||||
campus_address: '', |
*/ |
||||
campus_status: '', |
const deleteEvent = (id: number) => { |
||||
}, |
ElMessageBox.confirm(t('campusDeleteTips'), t('warning'), |
||||
}) |
{ |
||||
|
confirmButtonText: t('confirm'), |
||||
const searchFormRef = ref<FormInstance>() |
cancelButtonText: t('cancel'), |
||||
|
type: 'warning', |
||||
// 选中数据 |
} |
||||
const selectData = ref<any[]>([]) |
).then(() => { |
||||
|
deleteCampus(id).then(() => { |
||||
// 字典数据 |
loadCampusList() |
||||
const campus_statusList = ref([] as any[]) |
}).catch(() => { |
||||
const campus_statusDictList = async () => { |
}) |
||||
campus_statusList.value = await ( |
}) |
||||
await useDictionary('campus_status') |
} |
||||
).data.dictionary |
|
||||
} |
|
||||
campus_statusDictList() |
|
||||
|
const resetForm = (formEl: FormInstance | undefined) => { |
||||
/** |
if (!formEl) return |
||||
* 获取校区列表 |
formEl.resetFields() |
||||
*/ |
loadCampusList() |
||||
const loadCampusList = (page: number = 1) => { |
} |
||||
campusTable.loading = true |
</script> |
||||
campusTable.page = page |
|
||||
|
<style lang="scss" scoped> |
||||
getCampusList({ |
/* 多行超出隐藏 */ |
||||
page: campusTable.page, |
.multi-hidden { |
||||
limit: campusTable.limit, |
word-break: break-all; |
||||
...campusTable.searchParam, |
text-overflow: ellipsis; |
||||
}) |
overflow: hidden; |
||||
.then((res) => { |
display: -webkit-box; |
||||
campusTable.loading = false |
-webkit-line-clamp: 2; |
||||
campusTable.data = res.data.data |
-webkit-box-orient: vertical; |
||||
campusTable.total = res.data.total |
} |
||||
}) |
</style> |
||||
.catch(() => { |
|
||||
campusTable.loading = false |
|
||||
}) |
|
||||
} |
|
||||
loadCampusList() |
|
||||
|
|
||||
const editCampusDialog: Record<string, any> | null = ref(null) |
|
||||
|
|
||||
/** |
|
||||
* 添加校区 |
|
||||
*/ |
|
||||
const addEvent = () => { |
|
||||
editCampusDialog.value.setFormData() |
|
||||
editCampusDialog.value.showDialog = true |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 编辑校区 |
|
||||
* @param data |
|
||||
*/ |
|
||||
const editEvent = (data: any) => { |
|
||||
editCampusDialog.value.setFormData(data) |
|
||||
editCampusDialog.value.showDialog = true |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除校区 |
|
||||
*/ |
|
||||
const deleteEvent = (id: number) => { |
|
||||
ElMessageBox.confirm(t('campusDeleteTips'), t('warning'), { |
|
||||
confirmButtonText: t('confirm'), |
|
||||
cancelButtonText: t('cancel'), |
|
||||
type: 'warning', |
|
||||
}).then(() => { |
|
||||
deleteCampus(id) |
|
||||
.then(() => { |
|
||||
loadCampusList() |
|
||||
}) |
|
||||
.catch(() => {}) |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
const resetForm = (formEl: FormInstance | undefined) => { |
|
||||
if (!formEl) return |
|
||||
formEl.resetFields() |
|
||||
loadCampusList() |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
/* 多行超出隐藏 */ |
|
||||
.multi-hidden { |
|
||||
word-break: break-all; |
|
||||
text-overflow: ellipsis; |
|
||||
overflow: hidden; |
|
||||
display: -webkit-box; |
|
||||
-webkit-line-clamp: 2; |
|
||||
-webkit-box-orient: vertical; |
|
||||
} |
|
||||
</style> |
|
||||
|
|||||
@ -0,0 +1,248 @@ |
|||||
|
<template> |
||||
|
<el-dialog |
||||
|
v-model="dialogVisible" |
||||
|
:title="t('mapPickerTitle')" |
||||
|
width="800px" |
||||
|
:before-close="handleClose" |
||||
|
> |
||||
|
|
||||
|
<div class="map-container" id="container"></div> |
||||
|
<div class="address-search"> |
||||
|
<el-select |
||||
|
v-model="province" |
||||
|
:placeholder="t('provincePlaceholder')" |
||||
|
@change="handleProvinceChange" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in provinceList" |
||||
|
:key="item.id" |
||||
|
:label="item.name" |
||||
|
:value="item.id" |
||||
|
/> |
||||
|
</el-select> |
||||
|
<el-select |
||||
|
v-model="city" |
||||
|
:placeholder="t('cityPlaceholder')" |
||||
|
@change="handleCityChange" |
||||
|
:disabled="!province" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in cityList" |
||||
|
:key="item.id" |
||||
|
:label="item.name" |
||||
|
:value="item.id" |
||||
|
/> |
||||
|
</el-select> |
||||
|
<el-select |
||||
|
v-model="district" |
||||
|
:placeholder="t('districtPlaceholder')" |
||||
|
@change="handleDistrictChange" |
||||
|
:disabled="!province || !city" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in districtList" |
||||
|
:key="item.id" |
||||
|
:label="item.name" |
||||
|
:value="item.id" |
||||
|
/> |
||||
|
</el-select> |
||||
|
<el-input |
||||
|
v-model="detailAddress" |
||||
|
:placeholder="t('detailAddressPlaceholder')" |
||||
|
/> |
||||
|
<el-button type="primary" @click="handleAddressSearch">{{ t('search') }}</el-button> |
||||
|
</div> |
||||
|
<template #footer> |
||||
|
<span class="dialog-footer"> |
||||
|
<el-button @click="dialogVisible = false">{{ t('cancel') }}</el-button> |
||||
|
<el-button type="primary" @click="handleConfirm"> |
||||
|
{{ t('confirm') }} |
||||
|
</el-button> |
||||
|
</span> |
||||
|
</template> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { ref, onMounted, watch } from 'vue' |
||||
|
import { getAreaListByPid, getAreaByCode } from '@/app/api/sys' |
||||
|
import { createMarker, latLngToAddress, addressToLatLng } from '@/utils/qqmap' |
||||
|
import { t } from '@/lang' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
modelValue: { |
||||
|
type: Object, |
||||
|
default: () => ({ |
||||
|
lat: null, |
||||
|
lng: null, |
||||
|
address: '', |
||||
|
}), |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const emit = defineEmits(['update:modelValue', 'confirm']) |
||||
|
|
||||
|
const dialogVisible = ref(false) |
||||
|
|
||||
|
const handleClose = (done: () => void) => { |
||||
|
done() |
||||
|
} |
||||
|
|
||||
|
const handleConfirm = () => { |
||||
|
emit('confirm', { |
||||
|
lat: props.modelValue.lat, |
||||
|
lng: props.modelValue.lng, |
||||
|
address: detailAddress.value |
||||
|
}) |
||||
|
dialogVisible.value = false |
||||
|
} |
||||
|
|
||||
|
// 地图相关 |
||||
|
let map: any |
||||
|
let marker: any |
||||
|
const mapKey = ref('') |
||||
|
|
||||
|
// 区域选择 |
||||
|
const province = ref('') |
||||
|
const city = ref('') |
||||
|
const district = ref('') |
||||
|
const detailAddress = ref('') |
||||
|
const provinceList = ref<any[]>([]) |
||||
|
const cityList = ref<any[]>([]) |
||||
|
const districtList = ref<any[]>([]) |
||||
|
|
||||
|
// 初始化地图 |
||||
|
onMounted(() => { |
||||
|
const mapScript = document.createElement('script') |
||||
|
mapKey.value = 'IZQBZ-3UHEU-WTCVD-2464U-I5N4V-ZFFU3' |
||||
|
mapScript.type = 'text/javascript' |
||||
|
mapScript.src = |
||||
|
'https://map.qq.com/api/gljs?libraries=tools,service&v=1.exp&key=IZQBZ-3UHEU-WTCVD-2464U-I5N4V-ZFFU3' |
||||
|
document.body.appendChild(mapScript) |
||||
|
mapScript.onload = () => { |
||||
|
setTimeout(() => { |
||||
|
initMap() |
||||
|
}, 500) |
||||
|
} |
||||
|
|
||||
|
// 初始化省份列表 |
||||
|
getAreaListByPid(0).then((res) => { |
||||
|
provinceList.value = res.data |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
const initMap = () => { |
||||
|
const TMap = (window as any).TMap |
||||
|
const center = new TMap.LatLng(39.90403, 116.407526) |
||||
|
map = new TMap.Map('container', { |
||||
|
center, |
||||
|
zoom: 12, |
||||
|
}) |
||||
|
|
||||
|
marker = createMarker(map) |
||||
|
|
||||
|
map.on('click', (evt: any) => { |
||||
|
map.setCenter(evt.latLng) |
||||
|
marker.updateGeometries({ |
||||
|
id: 'center', |
||||
|
position: evt.latLng, |
||||
|
}) |
||||
|
emit('update:modelValue', { |
||||
|
lat: evt.latLng.lat, |
||||
|
lng: evt.latLng.lng, |
||||
|
address: detailAddress.value, |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 区域选择处理 |
||||
|
const handleProvinceChange = (val: string) => { |
||||
|
getAreaListByPid(val).then((res) => { |
||||
|
cityList.value = res.data |
||||
|
city.value = '' |
||||
|
district.value = '' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const handleCityChange = (val: string) => { |
||||
|
getAreaListByPid(val).then((res) => { |
||||
|
districtList.value = res.data |
||||
|
district.value = '' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const handleDistrictChange = (val: string) => { |
||||
|
// TODO: 处理区县选择 |
||||
|
} |
||||
|
|
||||
|
// 地址搜索 |
||||
|
const handleAddressSearch = () => { |
||||
|
const address = [ |
||||
|
province.value |
||||
|
? provinceList.value.find((p) => p.id === province.value)?.name |
||||
|
: '', |
||||
|
city.value ? cityList.value.find((c) => c.id === city.value)?.name : '', |
||||
|
district.value |
||||
|
? districtList.value.find((d) => d.id === district.value)?.name |
||||
|
: '', |
||||
|
detailAddress.value, |
||||
|
].join('') |
||||
|
|
||||
|
addressToLatLng({ mapKey: mapKey.value, address }).then( |
||||
|
({ message, result }) => { |
||||
|
if (message == 'Success' || message == 'query ok') { |
||||
|
const latLng = new (window as any).TMap.LatLng( |
||||
|
result.location.lat, |
||||
|
result.location.lng |
||||
|
) |
||||
|
map.setCenter(latLng) |
||||
|
marker.updateGeometries({ |
||||
|
id: 'center', |
||||
|
position: latLng, |
||||
|
}) |
||||
|
emit('update:modelValue', { |
||||
|
lat: result.location.lat, |
||||
|
lng: result.location.lng, |
||||
|
address: detailAddress.value, |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
// 回显处理 |
||||
|
watch( |
||||
|
() => props.modelValue, |
||||
|
(newVal) => { |
||||
|
if (newVal.lat && newVal.lng) { |
||||
|
const latLng = new (window as any).TMap.LatLng(newVal.lat, newVal.lng) |
||||
|
map?.setCenter(latLng) |
||||
|
marker?.updateGeometries({ |
||||
|
id: 'center', |
||||
|
position: latLng, |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
{ immediate: true } |
||||
|
) |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.map-picker { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 16px; |
||||
|
} |
||||
|
|
||||
|
.map-container { |
||||
|
width: 100%; |
||||
|
height: 400px; |
||||
|
border: 1px solid #dcdfe6; |
||||
|
border-radius: 4px; |
||||
|
} |
||||
|
|
||||
|
.address-search { |
||||
|
display: flex; |
||||
|
gap: 8px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,37 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
use think\facade\Route; |
||||
|
|
||||
|
use app\adminapi\middleware\AdminCheckRole; |
||||
|
use app\adminapi\middleware\AdminCheckToken; |
||||
|
use app\adminapi\middleware\AdminLog; |
||||
|
// USER_CODE_BEGIN -- campus |
||||
|
|
||||
|
Route::group('campus', function () { |
||||
|
|
||||
|
//校区列表 |
||||
|
Route::get('campus', 'campus.Campus/lists'); |
||||
|
//校区详情 |
||||
|
Route::get('campus/:id', 'campus.Campus/info'); |
||||
|
//添加校区 |
||||
|
Route::post('campus', 'campus.Campus/add'); |
||||
|
//编辑校区 |
||||
|
Route::put('campus/:id', 'campus.Campus/edit'); |
||||
|
//删除校区 |
||||
|
Route::delete('campus/:id', 'campus.Campus/del'); |
||||
|
|
||||
|
})->middleware([ |
||||
|
AdminCheckToken::class, |
||||
|
AdminCheckRole::class, |
||||
|
AdminLog::class |
||||
|
]); |
||||
|
// USER_CODE_END -- campus |
||||
@ -0,0 +1,94 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\model\campus; |
||||
|
|
||||
|
use core\base\BaseModel; |
||||
|
use think\model\concern\SoftDelete; |
||||
|
use think\model\relation\HasMany; |
||||
|
use think\model\relation\HasOne; |
||||
|
|
||||
|
/** |
||||
|
* 校区模型 |
||||
|
* Class Campus |
||||
|
* @package app\model\campus |
||||
|
*/ |
||||
|
class Campus extends BaseModel |
||||
|
{ |
||||
|
|
||||
|
use SoftDelete; |
||||
|
|
||||
|
/** |
||||
|
* 数据表主键 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $pk = 'id'; |
||||
|
|
||||
|
/** |
||||
|
* 模型名称 |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $name = 'campus'; |
||||
|
|
||||
|
/** |
||||
|
* 定义软删除标记字段. |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $deleteTime = 'delete_time'; |
||||
|
|
||||
|
/** |
||||
|
* 定义软删除字段的默认值. |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $defaultSoftDelete = 0; |
||||
|
|
||||
|
/** |
||||
|
* 搜索器:校区校区名称 |
||||
|
* @param $value |
||||
|
* @param $data |
||||
|
*/ |
||||
|
public function searchCampusNameAttr($query, $value, $data) |
||||
|
{ |
||||
|
if ($value) { |
||||
|
$query->where("campus_name", "like", "%".$value."%"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 搜索器:校区校区地址 |
||||
|
* @param $value |
||||
|
* @param $data |
||||
|
*/ |
||||
|
public function searchCampusAddressAttr($query, $value, $data) |
||||
|
{ |
||||
|
if ($value) { |
||||
|
$query->where("campus_address", $value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 搜索器:校区校区状态 |
||||
|
* @param $value |
||||
|
* @param $data |
||||
|
*/ |
||||
|
public function searchCampusStatusAttr($query, $value, $data) |
||||
|
{ |
||||
|
if ($value) { |
||||
|
$query->where("campus_status", $value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,100 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\admin\campus; |
||||
|
|
||||
|
use app\model\campus\Campus; |
||||
|
|
||||
|
use core\base\BaseAdminService; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 校区服务层 |
||||
|
* Class CampusService |
||||
|
* @package app\service\admin\campus |
||||
|
*/ |
||||
|
class CampusService extends BaseAdminService |
||||
|
{ |
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
$this->model = new Campus(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取校区列表 |
||||
|
* @param array $where |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getPage(array $where = []) |
||||
|
{ |
||||
|
$field = 'id,campus_name,campus_address,campus_preview_image,campus_coordinates,campus_introduction,campus_status,create_time,update_time,delete_time'; |
||||
|
$order = ''; |
||||
|
|
||||
|
$search_model = $this->model->withSearch(["campus_name","campus_address","campus_status"], $where)->field($field)->order($order); |
||||
|
$list = $this->pageQuery($search_model); |
||||
|
return $list; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取校区信息 |
||||
|
* @param int $id |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getInfo(int $id) |
||||
|
{ |
||||
|
$field = 'id,campus_name,campus_address,campus_preview_image,campus_coordinates,campus_introduction,campus_status,create_time,update_time,delete_time'; |
||||
|
|
||||
|
$info = $this->model->field($field)->where([['id', "=", $id]])->findOrEmpty()->toArray(); |
||||
|
$info['campus_status'] = strval($info['campus_status']); |
||||
|
return $info; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加校区 |
||||
|
* @param array $data |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public function add(array $data) |
||||
|
{ |
||||
|
$res = $this->model->create($data); |
||||
|
return $res->id; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 校区编辑 |
||||
|
* @param int $id |
||||
|
* @param array $data |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function edit(int $id, array $data) |
||||
|
{ |
||||
|
|
||||
|
$this->model->where([['id', '=', $id]])->update($data); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除校区 |
||||
|
* @param int $id |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function del(int $id) |
||||
|
{ |
||||
|
$model = $this->model->where([['id', '=', $id]])->find(); |
||||
|
$res = $model->delete(); |
||||
|
return $res; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\validate\campus; |
||||
|
use core\base\BaseValidate; |
||||
|
/** |
||||
|
* 校区验证器 |
||||
|
* Class Campus |
||||
|
* @package addon\app\validate\campus |
||||
|
*/ |
||||
|
class Campus extends BaseValidate |
||||
|
{ |
||||
|
|
||||
|
protected $rule = [ |
||||
|
'campus_name' => 'require', |
||||
|
]; |
||||
|
|
||||
|
protected $message = [ |
||||
|
'campus_name.require' => ['common_validate.require', ['campus_name']], |
||||
|
]; |
||||
|
|
||||
|
protected $scene = [ |
||||
|
"add" => ['campus_name', 'campus_address', 'campus_preview_image', 'campus_coordinates', 'campus_introduction', 'campus_status'], |
||||
|
"edit" => ['campus_name', 'campus_address', 'campus_preview_image', 'campus_coordinates', 'campus_introduction', 'campus_status'] |
||||
|
]; |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue