After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 357 B |
After Width: | Height: | Size: 353 B |
After Width: | Height: | Size: 350 B |
After Width: | Height: | Size: 355 B |
After Width: | Height: | Size: 903 B |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 950 B |
After Width: | Height: | Size: 970 B |
@ -0,0 +1,98 @@ |
|||||||
|
<template> |
||||||
|
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" style="height: 90vh"> |
||||||
|
<el-form |
||||||
|
ref="formRef" |
||||||
|
v-loading="formLoading" |
||||||
|
:model="formData" |
||||||
|
:rules="formRules" |
||||||
|
label-width="80px" |
||||||
|
> |
||||||
|
<el-form-item label="问题" prop="question"> |
||||||
|
<el-input v-model="formData.question" placeholder="请输入问题" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="关键词" prop="keyword"> |
||||||
|
<el-input v-model="formData.keyword" placeholder="请输入关键词" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="答案" prop="answer"> |
||||||
|
<Editor v-model:modelValue="formData.answer" /> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<template #footer> |
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> |
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button> |
||||||
|
</template> |
||||||
|
</el-dialog> |
||||||
|
</template> |
||||||
|
<script name="DialogSkill" setup> |
||||||
|
const { t } = useI18n() // 国际化 |
||||||
|
const message = useMessage() // 消息弹窗 |
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示 |
||||||
|
const dialogTitle = ref('') // 弹窗的标题 |
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 |
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改 |
||||||
|
const formData = ref({ |
||||||
|
question: '', |
||||||
|
keyword: [], |
||||||
|
answer: '' |
||||||
|
}) |
||||||
|
const formRules = reactive({ |
||||||
|
question: [{ required: true, message: '问题不能为空', trigger: 'blur' }], |
||||||
|
answer: [{ required: true, message: '答案不能为空', trigger: 'blur,change' }] |
||||||
|
}) |
||||||
|
const formRef = ref() // 表单 Ref |
||||||
|
|
||||||
|
/** 打开弹窗 */ |
||||||
|
const open = async (type, id) => { |
||||||
|
dialogVisible.value = true |
||||||
|
dialogTitle.value = type == 'create' ? '新增话术' : '修改话术' |
||||||
|
formType.value = type |
||||||
|
resetForm() |
||||||
|
// 修改时,设置数据 |
||||||
|
if (id) { |
||||||
|
formLoading.value = true |
||||||
|
try { |
||||||
|
// formData.value = await UserApi.getUser(id) |
||||||
|
} finally { |
||||||
|
formLoading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗 |
||||||
|
|
||||||
|
/** 提交表单 */ |
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 |
||||||
|
const submitForm = async () => { |
||||||
|
// 校验表单 |
||||||
|
if (!formRef.value) return |
||||||
|
const valid = await formRef.value.validate() |
||||||
|
if (!valid) return |
||||||
|
// 提交请求 |
||||||
|
formLoading.value = true |
||||||
|
try { |
||||||
|
// const data = formData.value as unknown as UserApi.UserVO |
||||||
|
if (formType.value === 'create') { |
||||||
|
// await UserApi.createUser(data) |
||||||
|
message.success(t('common.createSuccess')) |
||||||
|
} else { |
||||||
|
// await UserApi.updateUser(data) |
||||||
|
message.success(t('common.updateSuccess')) |
||||||
|
} |
||||||
|
dialogVisible.value = false |
||||||
|
// 发送操作成功的事件 |
||||||
|
emit('success') |
||||||
|
} finally { |
||||||
|
formLoading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** 重置表单 */ |
||||||
|
const resetForm = () => { |
||||||
|
formData.value = { |
||||||
|
question: '', |
||||||
|
keyword: [], |
||||||
|
answer: '' |
||||||
|
} |
||||||
|
formRef.value?.resetFields() |
||||||
|
} |
||||||
|
</script> |
@ -1,7 +1,102 @@ |
|||||||
<template> |
<template> |
||||||
<div> 关键话术 </div> |
<div> |
||||||
|
<el-form :model="searchForm" inline label-width="0"> |
||||||
|
<el-form-item> |
||||||
|
<el-input |
||||||
|
v-model="searchForm.question" |
||||||
|
placeholder="请输入问题" |
||||||
|
clearable |
||||||
|
style="width: 200px" |
||||||
|
@keyup.enter="handleQuery" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button type="primary" @click="handleQuery">搜索</el-button> |
||||||
|
<el-button @click="resetQuery">重置</el-button> |
||||||
|
<el-button type="primary" plain @click="handleAdd">新增</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<el-table :data="tableList"> |
||||||
|
<el-table-column type="index" width="55" align="center" /> |
||||||
|
<el-table-column label="问题" align="center" prop="question" /> |
||||||
|
<el-table-column label="答案" align="center" prop="content"> |
||||||
|
<template #default="scope"> |
||||||
|
<p v-dompurify-html="scope.row.content"></p> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="关键词" align="center" prop="skillKey" /> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template #default="scope"> |
||||||
|
<el-button type="primary" text @click="handleUpdate(scope.row)">修改</el-button> |
||||||
|
<el-button type="primary" text @click="handleDelete(scope.row)">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<Pagination |
||||||
|
v-model:limit="searchForm.pageSize" |
||||||
|
v-model:page="searchForm.pageNum" |
||||||
|
:total="total" |
||||||
|
@pagination="handleQuery" |
||||||
|
/> |
||||||
|
<DialogSkill ref="skillDialog" @success="handleQuery" /> |
||||||
|
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<script setup></script> |
<script setup name="ClueSkill"> |
||||||
|
import DialogSkill from './Comp/DialogSkill.vue' |
||||||
|
|
||||||
|
const skillDialog = ref() |
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗 |
||||||
|
|
||||||
|
const searchForm = ref({ |
||||||
|
question: '', |
||||||
|
pageSize: 20, |
||||||
|
pageNum: 1 |
||||||
|
}) |
||||||
|
|
||||||
|
const total = ref(0) |
||||||
|
|
||||||
|
const tableList = ref([]) |
||||||
|
|
||||||
|
function resetQuery() { |
||||||
|
searchForm.value = { |
||||||
|
question: '', |
||||||
|
pageSize: 20, |
||||||
|
pageNum: 1 |
||||||
|
} |
||||||
|
getList() |
||||||
|
} |
||||||
|
|
||||||
|
function handleQuery() { |
||||||
|
searchForm.value.pageNum = 1 |
||||||
|
getList() |
||||||
|
} |
||||||
|
|
||||||
|
function getList() { |
||||||
|
tableList.value = [{ question: '测试' }] |
||||||
|
} |
||||||
|
|
||||||
|
function handleAdd() { |
||||||
|
skillDialog.value.open('create', null) |
||||||
|
} |
||||||
|
|
||||||
|
function handleUpdate(row) { |
||||||
|
skillDialog.value.open('update', row) |
||||||
|
} |
||||||
|
|
||||||
|
async function handleDelete(row) { |
||||||
|
try { |
||||||
|
console.log(row) |
||||||
|
// 删除的二次确认 |
||||||
|
await message.delConfirm() |
||||||
|
// 发起删除 |
||||||
|
// await UserApi.deleteUser(row.id) |
||||||
|
message.success(t('common.delSuccess')) |
||||||
|
// 刷新列表 |
||||||
|
await getList() |
||||||
|
} catch {} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
<style lang="scss" scoped></style> |
<style lang="scss" scoped></style> |
||||||
|
@ -1,7 +1,196 @@ |
|||||||
<template> |
<template> |
||||||
<div> 班型管理 </div> |
<div> |
||||||
|
<el-form :model="searchForm" ref="searchRef" inline label-width="0"> |
||||||
|
<el-form-item> |
||||||
|
<el-input |
||||||
|
v-model="searchForm.schoolName" |
||||||
|
placeholder="请输入驾校名称" |
||||||
|
@keyup.enter="handleQuery" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-input |
||||||
|
v-model="searchForm.placeName" |
||||||
|
placeholder="请输入场地名称" |
||||||
|
@keyup.enter="handleQuery" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-input |
||||||
|
v-model="searchForm.className" |
||||||
|
placeholder="请输入班型名称" |
||||||
|
@keyup.enter="handleQuery" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-select |
||||||
|
v-model="searchForm.cartypeId" |
||||||
|
placeholder="请选择驾照类型" |
||||||
|
clearable |
||||||
|
filterable |
||||||
|
@change="handleQuery" |
||||||
|
> |
||||||
|
<el-option |
||||||
|
v-for="item in cartypeOptions" |
||||||
|
:key="item.value" |
||||||
|
:label="item.label" |
||||||
|
:value="item.value" |
||||||
|
/> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button plain @click="handleQuery">查询</el-button> |
||||||
|
<el-button plain @click="handleReset">重置</el-button> |
||||||
|
<el-button type="primary" plain @click="handleOpenDialog('create')">新增</el-button> |
||||||
|
<el-button type="danger" @click="handleBatchDelete">批量删除</el-button> |
||||||
|
<el-button type="warning" @click="handleBatchStatus">批量启/停用</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="tableList" |
||||||
|
v-loading="loading" |
||||||
|
border |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column type="selection" width="50" /> |
||||||
|
<el-table-column type="index" label="序号" width="60" /> |
||||||
|
<el-table-column |
||||||
|
v-for="col in columns" |
||||||
|
:prop="col.props" |
||||||
|
:key="col.props" |
||||||
|
:label="col.label" |
||||||
|
:width="col.width" |
||||||
|
show-overflow-tooltip |
||||||
|
/> |
||||||
|
<el-table-column label="状态" width="80"> |
||||||
|
<template #default="{ row }"> |
||||||
|
<el-switch |
||||||
|
v-model="row.status" |
||||||
|
:active-value="1" |
||||||
|
:inactive-value="0" |
||||||
|
@change="handleChangeStatus(row)" |
||||||
|
/> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" width="200px"> |
||||||
|
<template #default="{ row }"> |
||||||
|
<el-button type="primary" text @click="handleOpenDialog('update', row)">修改</el-button> |
||||||
|
<el-button type="danger" text @click="handleRemove(row)">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<!-- 分页 --> |
||||||
|
<Pagination |
||||||
|
v-model:limit="searchForm.pageSize" |
||||||
|
v-model:page="searchForm.pageNum" |
||||||
|
:total="total" |
||||||
|
@pagination="getList" |
||||||
|
/> |
||||||
|
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<script setup></script> |
<script setup name="Class"> |
||||||
|
const message = useMessage() // 消息弹窗 |
||||||
|
|
||||||
|
const loading = ref(false) |
||||||
|
const total = ref(0) |
||||||
|
|
||||||
|
const tableList = ref([]) |
||||||
|
// const schoolDialog = ref() |
||||||
|
|
||||||
|
const searchForm = ref({ |
||||||
|
schoolName: undefined, |
||||||
|
placeName: undefined, |
||||||
|
className: undefined, |
||||||
|
cartypeId: undefined, |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 20 |
||||||
|
}) |
||||||
|
|
||||||
|
const cartypeOptions = ref([]) |
||||||
|
|
||||||
|
const columns = [ |
||||||
|
{ props: 'schoolName', label: '驾校', width: '100px' }, |
||||||
|
{ props: 'placeName', label: '场地' }, |
||||||
|
{ props: 'className', label: '班型名称' }, |
||||||
|
{ props: 'cartypeName', label: '驾照类型', width: '100px' }, |
||||||
|
{ props: '', label: '最新报价', width: '100px' }, |
||||||
|
{ props: '', label: '最新底价', width: '100px' }, |
||||||
|
{ props: 'remark', label: '备注', width: '100px' } |
||||||
|
] |
||||||
|
|
||||||
|
function handleQuery() { |
||||||
|
searchForm.value.pageNum = 1 |
||||||
|
getList() |
||||||
|
} |
||||||
|
|
||||||
|
function getList() { |
||||||
|
tableList.value = [ |
||||||
|
{ schoolName: '测试驾校', placeName: '测试场地', className: '测试', status: 1 } |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
const ClassDialog = ref() |
||||||
|
function handleOpenDialog(type, row = null) { |
||||||
|
ClassDialog.value.open(type, row) |
||||||
|
} |
||||||
|
|
||||||
|
function handleReset() { |
||||||
|
searchForm.value = { |
||||||
|
schoolName: undefined, |
||||||
|
placeName: undefined, |
||||||
|
className: undefined, |
||||||
|
cartypeId: undefined, |
||||||
|
pageSize: 20, |
||||||
|
pageNum: 1 |
||||||
|
} |
||||||
|
getList() |
||||||
|
} |
||||||
|
|
||||||
|
async function handleBatchDelete(arr = []) { |
||||||
|
if (!arr.length || !selectRows.value.length) { |
||||||
|
message.info('请选择表格行!') |
||||||
|
} |
||||||
|
try { |
||||||
|
console.log(arr) |
||||||
|
// 删除的二次确认 |
||||||
|
await message.delConfirm() |
||||||
|
// 发起删除 |
||||||
|
// await UserApi.deleteUser(row.id) |
||||||
|
message.success(t('common.delSuccess')) |
||||||
|
// 刷新列表 |
||||||
|
await getList() |
||||||
|
} catch {} |
||||||
|
} |
||||||
|
|
||||||
|
const selectRows = ref([]) |
||||||
|
function handleSelectionChange(selection) { |
||||||
|
selectRows.value = selection.map((item) => item.classId) |
||||||
|
} |
||||||
|
|
||||||
|
function handleRemove(row) { |
||||||
|
handleBatchDelete([row]) |
||||||
|
} |
||||||
|
|
||||||
|
async function handleChangeStatus(row) { |
||||||
|
try { |
||||||
|
console.log(row) |
||||||
|
// 删除的二次确认 |
||||||
|
await message.confirm('是否确认修改状态') |
||||||
|
// 发起删除 |
||||||
|
// await UserApi.deleteUser(row.id) |
||||||
|
message.success('修改成功') |
||||||
|
// 刷新列表 |
||||||
|
await getList() |
||||||
|
} catch {} |
||||||
|
} |
||||||
|
|
||||||
|
function handleBatchStatus() { |
||||||
|
if (!selectRows.value.length) { |
||||||
|
message.info('请选择表格行!') |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
<style lang="scss" scoped></style> |
<style lang="scss" scoped></style> |
||||||
|
@ -1,7 +1,727 @@ |
|||||||
<template> |
<template> |
||||||
<div> 驾校管理 </div> |
<div class="absolute top-0 left-0 h-full w-full" style="height: calc(100vh - 85px)"> |
||||||
|
<div id="dialogMap" style="height: 100%"></div> |
||||||
|
<!-- 右侧驾校列表 --> |
||||||
|
<div class="asider" :class="showSchool ? '' : 'hidden-school'"> |
||||||
|
<el-card class="box-card" :body-style="{ flex: 1, 'overflow-y': 'scroll', padding: 0 }"> |
||||||
|
<div style="margin: 10px"> |
||||||
|
<el-input v-model="searchValue" placeholder="请输入驾校名" /> |
||||||
|
</div> |
||||||
|
<template #header> |
||||||
|
<div class="clearfix"> |
||||||
|
<div class="map-card-title">驾校列表</div> |
||||||
|
<el-switch |
||||||
|
v-model="showAllSchool" |
||||||
|
:active-value="true" |
||||||
|
:inactive-value="false" |
||||||
|
active-text="隐藏所有" |
||||||
|
inactive-text="展示所有" |
||||||
|
@change="showAllSchoolChange" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<div |
||||||
|
v-for="school in schoolList.filter( |
||||||
|
(item) => searchValue == undefined || item.schoolName.includes(searchValue) |
||||||
|
)" |
||||||
|
:key="school.schoolId" |
||||||
|
style="margin: 10px" |
||||||
|
:class="currentdeptId == school.schoolId ? 'actived-school' : ''" |
||||||
|
> |
||||||
|
<el-card :body-style="{ padding: '10px' }"> |
||||||
|
<template #header> |
||||||
|
<div 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)" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<el-button @click="handleClickSchool(school)">{{ |
||||||
|
`数据管理(${getCount(school.schoolId)})` |
||||||
|
}}</el-button> |
||||||
|
<el-tooltip content="新增场地" placement="left" effect="dark"> |
||||||
|
<el-button class="add-place-btn" @click="handleInsertPlace(school.schoolId)"> |
||||||
|
<Icon icon="ep:plus" /> |
||||||
|
</el-button> |
||||||
|
</el-tooltip> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
<div class="asider-sub"> |
||||||
|
<el-tooltip |
||||||
|
:content="`${showSchool ? '折叠' : '展开'}驾校列表`" |
||||||
|
placement="left" |
||||||
|
effect="dark" |
||||||
|
> |
||||||
|
<el-button class="is-circle" @click="toggleSchool"> |
||||||
|
<Icon class="text-12px" :icon="`ep:d-arrow-${showSchool ? 'right' : 'left'}`" /> |
||||||
|
</el-button> |
||||||
|
</el-tooltip> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 左侧场地弹框 --> |
||||||
|
<el-card v-if="placeDialogShow" class="place-dialog" :body-style="{ padding: '10px' }"> |
||||||
|
<template #header> |
||||||
|
<div class="clearfix"> |
||||||
|
<div class="map-card-title">场地设置</div> |
||||||
|
<el-tooltip content="取点" placement="right" effect="dark"> |
||||||
|
<el-button class="add-icon" @click="isPointing = !isPointing"> |
||||||
|
<Icon icon="ep:location" /> |
||||||
|
</el-button> |
||||||
|
</el-tooltip> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<el-form ref="FormPlace" :model="placeForm" label-width="70px"> |
||||||
|
<el-form-item label="所属驾校" prop="schoolId"> |
||||||
|
<el-select v-model="placeForm.schoolId" placeholder="请选择" clearable class="w-full"> |
||||||
|
<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="flagMap[item]" style="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 class="w-full"> |
||||||
|
<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">保存</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)' }" |
||||||
|
> |
||||||
|
<template #header> |
||||||
|
<div 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 class="add-icon" @click="fullScreenPlaceList = !fullScreenPlaceList"> |
||||||
|
<Icon icon="ep:full-screen" /> |
||||||
|
</el-button> |
||||||
|
</el-tooltip> |
||||||
|
<el-tooltip content="关闭" placement="top" effect="dark"> |
||||||
|
<el-button class="add-icon" @click="closePlaceList"> |
||||||
|
<Icon icon="ep:close" /> |
||||||
|
</el-button> |
||||||
|
</el-tooltip> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<el-table |
||||||
|
:data="placeTableData" |
||||||
|
border |
||||||
|
stripe |
||||||
|
class="place-table-list" |
||||||
|
size="small" |
||||||
|
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 #default="scope"> |
||||||
|
<el-switch v-model="scope.row.showInMap" @change="changePlaceStatus(scope.row)" /> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" width="100"> |
||||||
|
<template #default="scope"> |
||||||
|
<el-tooltip content="编辑" placement="top" effect="dark"> |
||||||
|
<el-button |
||||||
|
type="primary" |
||||||
|
style="padding: 4px 8px" |
||||||
|
@click="handleEditPlace(scope.row)" |
||||||
|
> |
||||||
|
<Icon icon="ep:edit" /> |
||||||
|
</el-button> |
||||||
|
</el-tooltip> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<div |
||||||
|
v-if="isPointing" |
||||||
|
class="map-tip" |
||||||
|
:style="{ |
||||||
|
transform: 'translate3D(' + (tipPostion.x + 15) + 'px,' + (tipPostion.y - 10) + 'px, 0)' |
||||||
|
}" |
||||||
|
>{{ mapHelpText }}</div |
||||||
|
> |
||||||
|
<Icon |
||||||
|
v-if="isPointing" |
||||||
|
icon="ep:s-flag" |
||||||
|
class="circle" |
||||||
|
:style="{ transform: 'translate3D(' + tipPostion.x + 'px,' + tipPostion.y + 'px, 0)' }" |
||||||
|
/> |
||||||
|
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<script setup></script> |
<script setup name="Place"> |
||||||
|
import FlagRed from '@/assets/imgs/flag/flag_red.png' |
||||||
|
import FlagYellow from '@/assets/imgs/flag/flag_yellow.png' |
||||||
|
import FlagPurple from '@/assets/imgs/flag/flag_purple.png' |
||||||
|
import FlagGreen from '@/assets/imgs/flag/flag_green.png' |
||||||
|
import FlagBlue from '@/assets/imgs/flag/flag_blue.png' |
||||||
|
import FlagBlack from '@/assets/imgs/flag/flag_black.png' |
||||||
|
import AMapLoader from '@amap/amap-jsapi-loader' |
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗 |
||||||
|
|
||||||
|
// 地图相关 |
||||||
|
const dialogMap = ref(null) |
||||||
|
const aMap = ref(null) |
||||||
|
const geoCoder = ref(null) |
||||||
|
const locationMarker = ref(null) |
||||||
|
|
||||||
|
const flagMap = { |
||||||
|
red: FlagRed, |
||||||
|
yellow: FlagYellow, |
||||||
|
purple: FlagPurple, |
||||||
|
green: FlagGreen, |
||||||
|
blue: FlagBlue, |
||||||
|
black: FlagBlack |
||||||
|
} |
||||||
|
const colorOptions = ['red', 'yellow', 'blue', 'green', 'purple', 'black'] |
||||||
|
const areaOptions = ref([]) |
||||||
|
const mapHelpText = ref('') |
||||||
|
const tipPostion = ref({}) |
||||||
|
|
||||||
|
function initMap() { |
||||||
|
AMapLoader.load({ |
||||||
|
key: '2ffb0e2ea90b1df0b8be48ed66e18fc8', //设置您的key |
||||||
|
version: '2.0', |
||||||
|
plugins: ['AMap.Geocoder'] |
||||||
|
}).then((AMap) => { |
||||||
|
aMap.value = AMap |
||||||
|
geoCoder.value = new AMap.Geocoder() |
||||||
|
dialogMap.value = new AMap.Map('dialogMap', { |
||||||
|
zoom: 12, |
||||||
|
zooms: [2, 22], |
||||||
|
center: [117.283042, 31.86119] |
||||||
|
}) |
||||||
|
locationMarker.value = new AMap.Marker({ |
||||||
|
icon: FlagRed |
||||||
|
}) |
||||||
|
getPageData() |
||||||
|
dialogMap.value.on('click', (ev) => { |
||||||
|
if (isPointing.value) { |
||||||
|
placeForm.value.lat = ev.lnglat.lat |
||||||
|
placeForm.value.lng = ev.lnglat.lng |
||||||
|
regeoCode() |
||||||
|
locationMarker.value.setPosition([placeForm.value.lng, placeForm.value.lat]) |
||||||
|
dialogMap.value.add(locationMarker.value) |
||||||
|
isPointing.value = false |
||||||
|
} |
||||||
|
}) |
||||||
|
dialogMap.value.on('mousemove', (ev) => { |
||||||
|
// if (isRanging.value) { |
||||||
|
// mapHelpText.value = |
||||||
|
// '左键单击选点,双击/右键单击完成选点,再次点击测距按钮可退出测距模式,并清除测距结果' |
||||||
|
// tipPostion.value = { |
||||||
|
// x: ev.pixel.x, |
||||||
|
// y: ev.pixel.y |
||||||
|
// } |
||||||
|
// } else if (isPointing.value) { |
||||||
|
mapHelpText.value = '点击地图添加标注' |
||||||
|
tipPostion.value = { |
||||||
|
x: ev.pixel.x, |
||||||
|
y: ev.pixel.y |
||||||
|
} |
||||||
|
// } |
||||||
|
}) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function regeoCode() { |
||||||
|
geoCoder.value.getAddress([placeForm.value.lng, placeForm.value.lat], (status, result) => { |
||||||
|
if (status === 'complete' && result.regeocode) { |
||||||
|
placeForm.value.address = result.regeocode.formattedAddress |
||||||
|
} else { |
||||||
|
message.error('根据经纬度查询地址失败') |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function getPageData() { |
||||||
|
// getMapData().then((resp) => { |
||||||
|
// if (resp.code == 200) { |
||||||
|
schoolList.value = [{ schoolName: '测试', showInMap: true, schoolId: '0001' }] |
||||||
|
tableData.value = [ |
||||||
|
{ |
||||||
|
schoolName: '测试', |
||||||
|
showInMap: true, |
||||||
|
schoolId: '0001', |
||||||
|
name: '训练场1', |
||||||
|
lat: 31.86119, |
||||||
|
lng: 117.283042, |
||||||
|
schoolShow: true, |
||||||
|
placeId: 'p0001' |
||||||
|
}, |
||||||
|
{ |
||||||
|
schoolName: '测试', |
||||||
|
showInMap: false, |
||||||
|
schoolId: '0001', |
||||||
|
name: '训练场2', |
||||||
|
lat: 31.86219, |
||||||
|
lng: 117.281042, |
||||||
|
schoolShow: true, |
||||||
|
placeId: 'p0002' |
||||||
|
} |
||||||
|
] |
||||||
|
currentdeptId.value = schoolList.value[0].schoolId |
||||||
|
createMarkersInMap() |
||||||
|
// } |
||||||
|
// }); |
||||||
|
} |
||||||
|
|
||||||
|
const searchValue = ref('') |
||||||
|
const schoolList = ref([]) |
||||||
|
const placeListDialogShow = ref(false) |
||||||
|
|
||||||
|
const currentdeptId = ref('') |
||||||
|
|
||||||
|
function changeSchoolStatus(school) { |
||||||
|
tableData.value.forEach((item) => { |
||||||
|
if (school.schoolId == item.schoolId) { |
||||||
|
item.schoolShow = school.showInMap |
||||||
|
} |
||||||
|
}) |
||||||
|
resetMarkers() |
||||||
|
} |
||||||
|
|
||||||
|
function handleClickSchool(item) { |
||||||
|
placeListDialogShow.value = true |
||||||
|
placeListDialogTitle.value = `数据管理 [${item.schoolName}]` |
||||||
|
currentdeptId.value = item.schoolId |
||||||
|
} |
||||||
|
|
||||||
|
// 生成markers |
||||||
|
function createMarkersInMap() { |
||||||
|
for (let i = 0; i < tableData.value.length; i++) { |
||||||
|
const element = tableData.value[i] |
||||||
|
if (!element.schoolShow || !element.showInMap) { |
||||||
|
continue |
||||||
|
} |
||||||
|
const markerIcon = flagMap[element.flagColor || 'red'] |
||||||
|
const tmpMarker = new aMap.value.Marker({ |
||||||
|
map: dialogMap.value, |
||||||
|
position: [element.lng, element.lat], |
||||||
|
icon: markerIcon, |
||||||
|
label: { |
||||||
|
content: element.name, |
||||||
|
direction: 'right' |
||||||
|
}, |
||||||
|
extData: element |
||||||
|
}) |
||||||
|
tmpMarker.on('click', handleClickMarker) |
||||||
|
placeMarkerList.value.push(tmpMarker) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function handleInsertPlace(schoolId) { |
||||||
|
placeDialogShow.value = true |
||||||
|
dialogMap.value.setDefaultCursor('default') |
||||||
|
// isRanging.value = false |
||||||
|
placeForm.value = { |
||||||
|
lat: undefined, |
||||||
|
lng: undefined, |
||||||
|
name: undefined, |
||||||
|
address: undefined, |
||||||
|
remark: undefined, |
||||||
|
phone: undefined, |
||||||
|
schoolId: schoolId, |
||||||
|
showInMap: true, |
||||||
|
flagColor: 'red' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 关闭场地弹窗 |
||||||
|
function closePlaceDialog() { |
||||||
|
placeDialogShow.value = false |
||||||
|
isPointing.value = false |
||||||
|
dialogMap.value.remove(locationMarker.value) |
||||||
|
} |
||||||
|
|
||||||
|
const isPointing = ref(false) |
||||||
|
|
||||||
|
function checkPlaceFormValidate() { |
||||||
|
const valid = [] |
||||||
|
if (!placeForm.value.name) { |
||||||
|
valid.push('名称') |
||||||
|
} |
||||||
|
if (!placeForm.value.address) { |
||||||
|
valid.push('地址') |
||||||
|
} |
||||||
|
if (!placeForm.value.lng) { |
||||||
|
valid.push('经度') |
||||||
|
} |
||||||
|
if (!placeForm.value.lat) { |
||||||
|
valid.push('纬度') |
||||||
|
} |
||||||
|
if (!placeForm.value.phone) { |
||||||
|
valid.push('电话') |
||||||
|
} |
||||||
|
if (valid.length == 0) { |
||||||
|
return true |
||||||
|
} else { |
||||||
|
message.error(`请将以下填写完整: ${valid.join(',')}`) |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function handleClickMarker(ev) { |
||||||
|
placeForm.value = ev.target.getExtData() |
||||||
|
placeDialogShow.value = true |
||||||
|
} |
||||||
|
|
||||||
|
async function onSubmit() { |
||||||
|
// 保存接口 |
||||||
|
if (checkPlaceFormValidate()) { |
||||||
|
// 先访问接口,返回id插入placeForm |
||||||
|
// const resp = savePlace(placeForm.value); |
||||||
|
const resp = { code: 200, data: 'p00001' } |
||||||
|
if (resp.code != 200) { |
||||||
|
return |
||||||
|
} else { |
||||||
|
message.success('操作成功') |
||||||
|
} |
||||||
|
if (!placeForm.value.placeId && resp.data) { |
||||||
|
placeForm.value.placeId = resp.data |
||||||
|
} |
||||||
|
// 移除选点用 的标记 |
||||||
|
dialogMap.value.remove(locationMarker.value) |
||||||
|
// 根据form创建新marker 并添加到地图上 |
||||||
|
const tmpMarker = new aMap.value.Marker({ |
||||||
|
map: dialogMap.value, |
||||||
|
position: [placeForm.value.lng, placeForm.value.lat], |
||||||
|
icon: flagMap[placeForm.value.flagColor], |
||||||
|
label: { |
||||||
|
content: placeForm.value.name, |
||||||
|
direction: 'right' |
||||||
|
}, |
||||||
|
extData: placeForm.value |
||||||
|
}) |
||||||
|
// 新marker事件 |
||||||
|
tmpMarker.on('click', handleClickMarker) |
||||||
|
// 如果当前选择的marker点存在(编辑) |
||||||
|
// if (selectMarker.value) { |
||||||
|
// // 地图上 移除选择的点 |
||||||
|
// dialogMap.value.remove(selectMarker.value) |
||||||
|
// selectMarker.value = null |
||||||
|
// } |
||||||
|
// 关闭场地弹窗 |
||||||
|
placeDialogShow.value = false |
||||||
|
isPointing.value = false |
||||||
|
|
||||||
|
// 场地列表 移除原列表中操作的场地数据 |
||||||
|
const tmpArr = tableData.value.filter((item) => item.placeId !== placeForm.value.placeId) |
||||||
|
// 新增新的场地 |
||||||
|
tmpArr.push(placeForm.value) |
||||||
|
// 重置场地数组 |
||||||
|
tableData.value = tmpArr |
||||||
|
// 地图marker列表 移除操作的原marker 添加新marker进数组 |
||||||
|
const tmpArr1 = placeMarkerList.value.filter( |
||||||
|
(item) => item.getExtData().placeId !== placeForm.value.placeId |
||||||
|
) |
||||||
|
tmpArr1.push(tmpMarker) |
||||||
|
placeMarkerList.value = tmpArr1 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function getCount(schoolId) { |
||||||
|
return tableData.value.filter((item) => item.schoolId === schoolId).length |
||||||
|
} |
||||||
|
|
||||||
|
const showSchool = ref(true) |
||||||
|
const showAllSchool = ref(false) |
||||||
|
const fullScreenPlaceList = ref(false) |
||||||
|
const placeListDialogTitle = ref('') |
||||||
|
const tableSearch = ref('') |
||||||
|
const tableData = ref([]) |
||||||
|
|
||||||
|
const placeTableData = computed(() => { |
||||||
|
if (tableSearch.value) { |
||||||
|
return tableData.value.filter( |
||||||
|
(dataNews) => |
||||||
|
dataNews.schoolId === currentdeptId.value && dataNews.name.includes(tableSearch.value) |
||||||
|
) |
||||||
|
} |
||||||
|
return tableData.value.filter((dataNews) => dataNews.schoolId === currentdeptId.value) |
||||||
|
}) |
||||||
|
|
||||||
|
function showAllSchoolChange() { |
||||||
|
schoolList.value.forEach((item) => (item.showInMap = !showAllSchool.value)) |
||||||
|
tableData.value.forEach((item) => (item.schoolShow = !showAllSchool.value)) |
||||||
|
resetMarkers() |
||||||
|
} |
||||||
|
|
||||||
|
function toggleSchool() { |
||||||
|
showSchool.value = !showSchool.value |
||||||
|
} |
||||||
|
|
||||||
|
function closePlaceList() { |
||||||
|
placeListDialogShow.value = false |
||||||
|
fullScreenPlaceList.value = false |
||||||
|
} |
||||||
|
|
||||||
|
async function changePlaceStatus() { |
||||||
|
// const resp = await updatePlace(item); |
||||||
|
// if (resp.code == 200) { |
||||||
|
resetMarkers() |
||||||
|
// } |
||||||
|
} |
||||||
|
|
||||||
|
// const isRanging = ref(false) |
||||||
|
const placeForm = ref({ |
||||||
|
lat: undefined, |
||||||
|
lng: undefined, |
||||||
|
name: undefined, |
||||||
|
address: undefined, |
||||||
|
remark: undefined, |
||||||
|
phone: undefined, |
||||||
|
flagColor: 'red' |
||||||
|
}) |
||||||
|
// const selectMarker = ref(null) |
||||||
|
const placeMarkerList = ref([]) |
||||||
|
|
||||||
|
// 编辑场地 |
||||||
|
function handleEditPlace(item) { |
||||||
|
placeDialogShow.value = true |
||||||
|
dialogMap.value.setDefaultCursor('default') |
||||||
|
// 方法已废弃 |
||||||
|
// if (selectMarker.value) { |
||||||
|
// selectMarker.value.setAnimation('AMAP_ANIMATION_NONE') |
||||||
|
// } |
||||||
|
// isRanging.value = false |
||||||
|
placeForm.value = Object.assign({}, item) |
||||||
|
// selectMarker.value = placeMarkerList.value.find( |
||||||
|
// (marker) => marker.getExtData().placeId === item.placeId |
||||||
|
// ) |
||||||
|
// 方法已废弃 |
||||||
|
// selectMarker.value && selectMarker.value.setAnimation('AMAP_ANIMATION_BOUNCE') |
||||||
|
dialogMap.value.setCenter([item.lng, item.lat]) |
||||||
|
} |
||||||
|
|
||||||
|
const placeDialogShow = ref(false) |
||||||
|
|
||||||
|
// 重置markers |
||||||
|
function resetMarkers() { |
||||||
|
dialogMap.value.clearMap() |
||||||
|
createMarkersInMap() |
||||||
|
} |
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
initMap() |
||||||
|
}) |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.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%; |
||||||
|
} |
||||||
|
|
||||||
|
::v-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; |
||||||
|
} |
||||||
|
|
||||||
|
::v-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; |
||||||
|
} |
||||||
|
|
||||||
|
.add-place-btn { |
||||||
|
float: right; |
||||||
|
border: none; |
||||||
|
font-size: 16px; |
||||||
|
color: #409eff; |
||||||
|
} |
||||||
|
|
||||||
|
.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; |
||||||
|
} |
||||||
|
|
||||||
<style lang="scss" scoped></style> |
::v-deep(.el-radio__label) { |
||||||
|
vertical-align: middle; |
||||||
|
} |
||||||
|
</style> |
||||||
|
@ -0,0 +1,124 @@ |
|||||||
|
<template> |
||||||
|
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" style="height: 90vh"> |
||||||
|
<el-form |
||||||
|
ref="formRef" |
||||||
|
v-loading="formLoading" |
||||||
|
:model="formData" |
||||||
|
:rules="formRules" |
||||||
|
label-width="80px" |
||||||
|
> |
||||||
|
<el-row :gutter="20"> |
||||||
|
<el-col :span="12" :offset="0"> |
||||||
|
<el-form-item label="驾校名称" prop="name"> |
||||||
|
<el-input v-model="formData.name" placeholder="请输入驾校名称" /> |
||||||
|
</el-form-item> |
||||||
|
</el-col> |
||||||
|
<el-col :span="12" :offset="0"> |
||||||
|
<el-form-item label="状态" prop="status"> |
||||||
|
<el-radio-group v-model="formData.status"> |
||||||
|
<el-radio :label="1"> 正常 </el-radio> |
||||||
|
<el-radio :label="0"> 停用 </el-radio> |
||||||
|
</el-radio-group> |
||||||
|
</el-form-item> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
<el-row :gutter="20"> |
||||||
|
<el-col :span="12" :offset="0"> |
||||||
|
<el-form-item label="负责人" prop="leader"> |
||||||
|
<el-input v-model="formData.leader" placeholder="请输入负责人" /> |
||||||
|
</el-form-item> |
||||||
|
</el-col> |
||||||
|
<el-col :span="12" :offset="0"> |
||||||
|
<el-form-item label="联系方式" prop="phone"> |
||||||
|
<el-input v-model="formData.phone" placeholder="请输入联系方式" /> |
||||||
|
</el-form-item> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
<el-row :gutter="20"> |
||||||
|
<el-form-item label="备注" prop="remark"> |
||||||
|
<Editor v-model:modelValue="formData.remark" /> |
||||||
|
</el-form-item> |
||||||
|
</el-row> |
||||||
|
</el-form> |
||||||
|
<template #footer> |
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> |
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button> |
||||||
|
</template> |
||||||
|
</el-dialog> |
||||||
|
</template> |
||||||
|
<script name="DialogSchool" setup> |
||||||
|
const { t } = useI18n() // 国际化 |
||||||
|
const message = useMessage() // 消息弹窗 |
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示 |
||||||
|
const dialogTitle = ref('') // 弹窗的标题 |
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 |
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改 |
||||||
|
const formData = ref({ |
||||||
|
name: '', |
||||||
|
leader: '', |
||||||
|
phone: '', |
||||||
|
status: 1, |
||||||
|
remark: '' |
||||||
|
}) |
||||||
|
const formRules = reactive({ |
||||||
|
name: [{ required: true, message: '驾校名称不能为空', trigger: 'blur' }] |
||||||
|
}) |
||||||
|
const formRef = ref() // 表单 Ref |
||||||
|
|
||||||
|
/** 打开弹窗 */ |
||||||
|
const open = async (type, id) => { |
||||||
|
dialogVisible.value = true |
||||||
|
dialogTitle.value = type == 'create' ? '新增驾校' : '修改驾校' |
||||||
|
formType.value = type |
||||||
|
resetForm() |
||||||
|
// 修改时,设置数据 |
||||||
|
if (id) { |
||||||
|
formLoading.value = true |
||||||
|
try { |
||||||
|
// formData.value = await UserApi.getUser(id) |
||||||
|
} finally { |
||||||
|
formLoading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗 |
||||||
|
|
||||||
|
/** 提交表单 */ |
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 |
||||||
|
const submitForm = async () => { |
||||||
|
// 校验表单 |
||||||
|
if (!formRef.value) return |
||||||
|
const valid = await formRef.value.validate() |
||||||
|
if (!valid) return |
||||||
|
// 提交请求 |
||||||
|
formLoading.value = true |
||||||
|
try { |
||||||
|
// const data = formData.value as unknown as UserApi.UserVO |
||||||
|
if (formType.value === 'create') { |
||||||
|
// await UserApi.createUser(data) |
||||||
|
message.success(t('common.createSuccess')) |
||||||
|
} else { |
||||||
|
// await UserApi.updateUser(data) |
||||||
|
message.success(t('common.updateSuccess')) |
||||||
|
} |
||||||
|
dialogVisible.value = false |
||||||
|
// 发送操作成功的事件 |
||||||
|
emit('success') |
||||||
|
} finally { |
||||||
|
formLoading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** 重置表单 */ |
||||||
|
const resetForm = () => { |
||||||
|
formData.value = { |
||||||
|
name: '', |
||||||
|
leader: '', |
||||||
|
phone: '', |
||||||
|
status: 1, |
||||||
|
remark: '' |
||||||
|
} |
||||||
|
formRef.value?.resetFields() |
||||||
|
} |
||||||
|
</script> |
@ -1,7 +1,108 @@ |
|||||||
<template> |
<template> |
||||||
<div> 场地管理 </div> |
<div> |
||||||
|
<el-form :model="searchForm" ref="searchForm" label-width="0" inline> |
||||||
|
<el-form-item> |
||||||
|
<el-input |
||||||
|
v-model="searchForm.name" |
||||||
|
class="!w-240px" |
||||||
|
placeholder="请输入驾校名称" |
||||||
|
@keyup.enter="handleQuery" |
||||||
|
/> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button @click="handleQuery"> 搜索 </el-button> |
||||||
|
<el-button @click="resetQuery"> 重置 </el-button> |
||||||
|
<el-button plain type="primary" @click="openForm('create')"> 新增 </el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<!-- 列表 --> |
||||||
|
<el-table v-loading="loading" :data="tableList"> |
||||||
|
<el-table-column label="驾校名称" prop="name" /> |
||||||
|
<el-table-column label="负责人" prop="" /> |
||||||
|
<el-table-column label="联系方式" prop="" /> |
||||||
|
<el-table-column label="状态"> |
||||||
|
<template #default="{ row }"> |
||||||
|
<el-switch |
||||||
|
v-model="row.status" |
||||||
|
:active-value="true" |
||||||
|
:inactive-value="false" |
||||||
|
@change="changeStatus(row)" |
||||||
|
/> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="创建时间" prop="" /> |
||||||
|
<el-table-column fixed="right" label="操作" width="150"> |
||||||
|
<template #default="{ row }"> |
||||||
|
<el-button link type="primary" @click="openForm(update, row)"> 修改 </el-button> |
||||||
|
<el-button link type="danger" @click="handleDelete(row.id)"> 删除 </el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<!-- 分页 --> |
||||||
|
<Pagination |
||||||
|
v-model:limit="searchForm.pageSize" |
||||||
|
v-model:page="searchForm.pageNum" |
||||||
|
:total="total" |
||||||
|
@pagination="getList" |
||||||
|
/> |
||||||
|
<DialogSchool ref="schoolDialog" @success="handleQuery" /> |
||||||
|
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<script setup></script> |
<script setup name="School"> |
||||||
|
import DialogSchool from './Comp/DialogSchool.vue' |
||||||
|
const message = useMessage() // 消息弹窗 |
||||||
|
|
||||||
|
const searchForm = ref({ |
||||||
|
name: '', |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 20 |
||||||
|
}) |
||||||
|
|
||||||
|
const loading = ref(false) |
||||||
|
const total = ref(0) |
||||||
|
|
||||||
|
const tableList = ref([]) |
||||||
|
const schoolDialog = ref() |
||||||
|
|
||||||
|
function resetQuery() { |
||||||
|
searchForm.value = { |
||||||
|
name: '', |
||||||
|
pageSize: 20, |
||||||
|
pageNum: 1 |
||||||
|
} |
||||||
|
getList() |
||||||
|
} |
||||||
|
|
||||||
|
function handleQuery() { |
||||||
|
searchForm.value.pageNum = 1 |
||||||
|
getList() |
||||||
|
} |
||||||
|
|
||||||
|
function getList() { |
||||||
|
tableList.value = [{ name: '测试' }] |
||||||
|
} |
||||||
|
|
||||||
|
function openForm(type, row = null) { |
||||||
|
schoolDialog.value.open(type, row) |
||||||
|
} |
||||||
|
|
||||||
|
async function handleDelete(row) { |
||||||
|
try { |
||||||
|
console.log(row) |
||||||
|
// 删除的二次确认 |
||||||
|
await message.delConfirm() |
||||||
|
// 发起删除 |
||||||
|
// await UserApi.deleteUser(row.id) |
||||||
|
message.success(t('common.delSuccess')) |
||||||
|
// 刷新列表 |
||||||
|
await getList() |
||||||
|
} catch {} |
||||||
|
} |
||||||
|
|
||||||
|
function changeStatus(row) { |
||||||
|
console.log(row) |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
<style lang="scss" scoped></style> |
<style lang="scss" scoped></style> |
||||||
|