Browse Source

修改地区选择组件

yuhongzhe
王泽彦 11 months ago
parent
commit
e62f76eab4
  1. 4
      admin/src/app/api/venue.ts
  2. 8
      admin/src/app/lang/zh-cn/venue.venue.json
  3. 583
      admin/src/app/views/venue/components/venue-edit.vue
  4. 5
      admin/src/components/TencentMapPicker.vue
  5. 4
      niucloud/app/adminapi/controller/venue/Venue.php
  6. 2
      niucloud/app/adminapi/route/venue.php
  7. 4
      niucloud/app/validate/venue/Venue.php

4
admin/src/app/api/venue.ts

@ -2,6 +2,10 @@ import request from '@/utils/request'
// USER_CODE_BEGIN -- venue // USER_CODE_BEGIN -- venue
/** /**
* *

8
admin/src/app/lang/zh-cn/venue.venue.json

@ -9,12 +9,8 @@
"availabilityStatusPlaceholder":"请输入场地可用状态", "availabilityStatusPlaceholder":"请输入场地可用状态",
"timeRangeType":"场地可用时间范围类型", "timeRangeType":"场地可用时间范围类型",
"timeRangeTypePlaceholder":"请输入场地可用时间范围类型", "timeRangeTypePlaceholder":"请输入场地可用时间范围类型",
"timeRangeStart":"范围类型的开始时间", "fixedTimeRanges":"时间范围",
"timeRangeStartPlaceholder":"请输入范围类型的开始时间", "fixedTimeRangesPlaceholder":"请输入时间范围",
"timeRangeEnd":"范围类型的结束时间",
"timeRangeEndPlaceholder":"请输入范围类型的结束时间",
"fixedTimeRanges":"固定时间范围类型的可用时间, 存储为JSON数组",
"fixedTimeRangesPlaceholder":"请输入固定时间范围类型的可用时间, 存储为JSON数组",
"createdAt":"创建时间", "createdAt":"创建时间",
"createdAtPlaceholder":"请输入创建时间", "createdAtPlaceholder":"请输入创建时间",
"updatedAt":"修改时间", "updatedAt":"修改时间",

583
admin/src/app/views/venue/components/venue-edit.vue

@ -1,267 +1,316 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateVenue') : t('addVenue')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('campusId')" prop="campus_id"> :title="formData.id ? t('updateVenue') : t('addVenue')"
<el-select class="input-width" v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> width="50%"
<el-option label="请选择" value=""></el-option> class="diy-dialog-wrap"
<el-option :destroy-on-close="true"
v-for="(item, index) in campusIdList" >
:key="index" <el-form
:label="item['campus_name']" :model="formData"
:value="item['id']" label-width="120px"
/> ref="formRef"
</el-select> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('venueName')" prop="venue_name"> >
<el-input v-model="formData.venue_name" clearable :placeholder="t('venueNamePlaceholder')" class="input-width" /> <el-form-item :label="t('campusId')" prop="campus_id">
</el-form-item> <el-select
class="input-width"
<el-form-item :label="t('capacity')" prop="capacity"> v-model="formData.campus_id"
<el-input-number v-model="formData.capacity" clearable :placeholder="t('capacityPlaceholder')" class="input-width" :min = "1" max = "500" /> clearable
</el-form-item> :placeholder="t('campusIdPlaceholder')"
>
<el-form-item :label="t('availabilityStatus')" prop="availability_status"> <el-option label="请选择" value=""></el-option>
<el-radio-group v-model="formData.availability_status" :placeholder="t('availabilityStatusPlaceholder')"> <el-option
<el-radio v-for="(item, index) in campusIdList"
v-for="(item, index) in availability_statusList" :key="index"
:key="index" :label="item.value"> :label="item['campus_name']"
{{ item.name }} :value="item['id']"
</el-radio> />
</el-radio-group> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('timeRangeType')" prop="time_range_type"> <el-form-item :label="t('venueName')" prop="venue_name">
<el-radio-group v-model="formData.time_range_type" :placeholder="t('timeRangeTypePlaceholder')"> <el-input
<el-radio v-model="formData.venue_name"
v-for="(item, index) in time_range_typeList" clearable
:key="index" :label="item.value"> :placeholder="t('venueNamePlaceholder')"
{{ item.name }} class="input-width"
</el-radio> />
</el-radio-group> </el-form-item>
</el-form-item>
<el-form-item :label="t('capacity')" prop="capacity">
<el-form-item :label="t('timeRangeStart')" class="input-width"> <el-input-number
<el-date-picker v-model="formData.capacity"
class="flex-1 !flex" clearable
v-model="formData.time_range_start" :placeholder="t('capacityPlaceholder')"
clearable class="input-width"
type="datetime" :min="1"
value-format="YYYY-MM-DD HH:mm:ss" max="500"
:placeholder="t('timeRangeStartPlaceholder')"> />
</el-date-picker> </el-form-item>
</el-form-item>
<el-form-item :label="t('timeRangeEnd')" class="input-width"> <el-form-item :label="t('availabilityStatus')" prop="availability_status">
<el-date-picker <el-radio-group
class="flex-1 !flex" v-model="formData.availability_status"
v-model="formData.time_range_end" :placeholder="t('availabilityStatusPlaceholder')"
clearable >
type="datetime" <!-- <el-radio-->
value-format="YYYY-MM-DD HH:mm:ss" <!-- v-for="(item, index) in availability_statusList"-->
:placeholder="t('timeRangeEndPlaceholder')"> <!-- :key="index"-->
</el-date-picker> <!-- :label="item.value"-->
</el-form-item> <!-- >-->
<el-form-item :label="t('fixedTimeRanges')" class="input-width"> <!-- {{ item.name }}-->
<el-date-picker <!-- </el-radio>-->
class="flex-1 !flex" <el-radio label="1">可用</el-radio>
v-model="formData.fixed_time_ranges" <el-radio label="2">不可用</el-radio>
clearable </el-radio-group>
type="datetime" </el-form-item>
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('fixedTimeRangesPlaceholder')"> <el-form-item :label="t('timeRangeType')" prop="time_range_type">
</el-date-picker> <el-radio-group
</el-form-item> v-model="formData.time_range_type"
</el-form> :placeholder="t('timeRangeTypePlaceholder')"
>
<template #footer> <el-radio
<span class="dialog-footer"> v-for="(item, index) in time_range_typeList"
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> :key="index"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ :label="item.value"
t('confirm') >
}}</el-button> {{ item.name }}
</span> </el-radio>
</template> </el-radio-group>
</el-dialog> </el-form-item>
</template>
<el-form-item :label="t('fixedTimeRanges')" class="input-width">
<script lang="ts" setup> <el-date-picker
import { ref, reactive, computed, watch } from 'vue' class="flex-1 !flex"
import { useDictionary } from '@/app/api/dict' v-model="formData.fixed_time_ranges"
import { t } from '@/lang' clearable
import type { FormInstance } from 'element-plus' type="datetime"
import { addVenue, editVenue, getVenueInfo, getWithCampusList } from '@/app/api/venue' value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('fixedTimeRangesPlaceholder')"
let showDialog = ref(false) >
const loading = ref(false) </el-date-picker>
</el-form-item>
/** </el-form>
* 表单数据
*/ <template #footer>
const initialFormData = { <span class="dialog-footer">
id: '', <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
campus_id: '', <el-button
venue_name: '', type="primary"
capacity: '', :loading="loading"
availability_status: '', @click="confirm(formRef)"
time_range_type: '', >{{ t('confirm') }}</el-button
time_range_start: '', >
time_range_end: '', </span>
fixed_time_ranges: '', </template>
} </el-dialog>
const formData: Record<string, any> = reactive({ ...initialFormData }) </template>
const formRef = ref<FormInstance>() <script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue'
// import { useDictionary } from '@/app/api/dict'
const formRules = computed(() => { import { t } from '@/lang'
return { import type { FormInstance } from 'element-plus'
campus_id: [ import {
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, addVenue,
editVenue,
] getVenueInfo,
, getWithCampusList,
venue_name: [ } from '@/app/api/venue'
{ required: true, message: t('venueNamePlaceholder'), trigger: 'blur' },
let showDialog = ref(false)
] const loading = ref(false)
,
capacity: [ /**
{ required: true, message: t('capacityPlaceholder'), trigger: 'blur' }, * 表单数据
{ validator: (rule: any, value: string, callback: any) => { if (value && !/^\d{1,500}$/.test(value)) { callback(new Error(t('generateBetween')))} else { callback() }}}, */
] const initialFormData = {
, id: '',
availability_status: [ campus_id: '',
{ required: true, message: t('availabilityStatusPlaceholder'), trigger: 'blur' }, venue_name: '',
capacity: '',
] availability_status: '',
, time_range_type: '',
time_range_type: [ fixed_time_ranges: '',
{ required: true, message: t('timeRangeTypePlaceholder'), trigger: 'blur' }, }
const formData: Record<string, any> = reactive({ ...initialFormData })
]
, const formRef = ref<FormInstance>()
time_range_start: [
{ required: true, message: t('timeRangeStartPlaceholder'), trigger: 'blur' }, //
const formRules = computed(() => {
] return {
, campus_id: [
time_range_end: [ { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
{ required: true, message: t('timeRangeEndPlaceholder'), trigger: 'blur' }, ],
venue_name: [
] { required: true, message: t('venueNamePlaceholder'), trigger: 'blur' },
, ],
fixed_time_ranges: [ capacity: [
{ required: true, message: t('fixedTimeRangesPlaceholder'), trigger: 'blur' }, { required: true, message: t('capacityPlaceholder'), trigger: 'blur' },
{
] validator: (rule: any, value: string, callback: any) => {
, if (value && !/^\d{1,500}$/.test(value)) {
} callback(new Error(t('generateBetween')))
}) } else {
callback()
const emit = defineEmits(['complete']) }
},
/** },
* 确认 ],
* @param formEl availability_status: [
*/ {
const confirm = async (formEl: FormInstance | undefined) => { required: true,
if (loading.value || !formEl) return message: t('availabilityStatusPlaceholder'),
let save = formData.id ? editVenue : addVenue trigger: 'blur',
},
await formEl.validate(async (valid) => { ],
if (valid) { time_range_type: [
loading.value = true {
required: true,
let data = formData message: t('timeRangeTypePlaceholder'),
trigger: 'blur',
save(data).then(res => { },
loading.value = false ],
showDialog.value = false fixed_time_ranges: [
emit('complete') {
}).catch(err => { required: true,
loading.value = false message: t('fixedTimeRangesPlaceholder'),
}) trigger: 'blur',
} },
}) ],
} }
})
//
let availability_statusList = ref([]) const emit = defineEmits(['complete'])
const availability_statusDictList = async () => {
availability_statusList.value = await (await useDictionary('SiteStatus')).data.dictionary /**
} * 确认
availability_statusDictList(); * @param formEl
watch(() => availability_statusList.value, () => { formData.availability_status = availability_statusList.value[0].value }) */
let time_range_typeList = ref([]) const confirm = async (formEl: FormInstance | undefined) => {
const time_range_typeDictList = async () => { if (loading.value || !formEl) return
time_range_typeList.value = await (await useDictionary('ALLOTTED_TIME')).data.dictionary let save = formData.id ? editVenue : addVenue
}
time_range_typeDictList(); await formEl.validate(async (valid) => {
watch(() => time_range_typeList.value, () => { formData.time_range_type = time_range_typeList.value[0].value }) if (valid) {
loading.value = true
const campusIdList = ref([] as any[]) let data = formData
const setCampusIdList = async () => {
campusIdList.value = await (await getWithCampusList({})).data save(data)
} .then((res) => {
setCampusIdList() loading.value = false
const setFormData = async (row: any = null) => { showDialog.value = false
Object.assign(formData, initialFormData) emit('complete')
loading.value = true })
if(row){ .catch((err) => {
const data = await (await getVenueInfo(row.id)).data loading.value = false
if (data) Object.keys(formData).forEach((key: string) => { })
if (data[key] != undefined) formData[key] = data[key] }
}) })
} }
loading.value = false
} //
let availability_statusList = ref([])
// const availability_statusDictList = async () => {
const mobileVerify = (rule: any, value: any, callback: any) => { availability_statusList.value = await (
if (value && !/^1[3-9]\d{9}$/.test(value)) { await useDictionary('SiteStatus')
callback(new Error(t('generateMobile'))) ).data.dictionary
} else { }
callback() availability_statusDictList()
} watch(
} () => availability_statusList.value,
() => {
// formData.availability_status = availability_statusList.value[0].value
const idCardVerify = (rule: any, value: any, callback: any) => { }
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { )
callback(new Error(t('generateIdCard'))) let time_range_typeList = ref([])
} else { const time_range_typeDictList = async () => {
callback() time_range_typeList.value = await (
} await useDictionary('ALLOTTED_TIME')
} ).data.dictionary
}
// time_range_typeDictList()
const emailVerify = (rule: any, value: any, callback: any) => { watch(
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { () => time_range_typeList.value,
callback(new Error(t('generateEmail'))) () => {
} else { formData.time_range_type = time_range_typeList.value[0].value
callback() }
} )
}
const campusIdList = ref([] as any[])
// const setCampusIdList = async () => {
const numberVerify = (rule: any, value: any, callback: any) => { campusIdList.value = await (await getWithCampusList({})).data
if (!Number.isInteger(value)) { }
callback(new Error(t('generateNumber'))) setCampusIdList()
} else { const setFormData = async (row: any = null) => {
callback() Object.assign(formData, initialFormData)
} loading.value = true
} if (row) {
const data = await (await getVenueInfo(row.id)).data
defineExpose({ if (data)
showDialog, Object.keys(formData).forEach((key: string) => {
setFormData if (data[key] != undefined) formData[key] = data[key]
}) })
</script> }
loading.value = false
<style lang="scss" scoped></style> }
<style lang="scss">
.diy-dialog-wrap .el-form-item__label{ //
height: auto !important; const mobileVerify = (rule: any, value: any, callback: any) => {
} if (value && !/^1[3-9]\d{9}$/.test(value)) {
</style> callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

5
admin/src/components/TencentMapPicker.vue

@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="dialogVisible" v-model="dialogVisible"
:title="t('mapPickerTitle')" title="位置选择"
width="800px" width="800px"
:before-close="handleClose" :before-close="handleClose"
:close-on-click-modal="false" :close-on-click-modal="false"
@ -344,7 +344,7 @@ const initMap = () => {
} }
const TMap = (window as any).TMap const TMap = (window as any).TMap
const center = new TMap.LatLng(39.90403, 116.407526) const center = new TMap.LatLng(20.029077, 110.366367)
map = new TMap.Map('container', { map = new TMap.Map('container', {
center, center,
@ -499,5 +499,6 @@ onBeforeUnmount(() => {
.address-search { .address-search {
display: flex; display: flex;
gap: 8px; gap: 8px;
margin-top: 20px;
} }
</style> </style>

4
niucloud/app/adminapi/controller/venue/Venue.php

@ -59,8 +59,6 @@ class Venue extends BaseAdminController
["capacity",0], ["capacity",0],
["availability_status",0], ["availability_status",0],
["time_range_type",""], ["time_range_type",""],
["time_range_start",""],
["time_range_end",""],
["fixed_time_ranges",""], ["fixed_time_ranges",""],
]); ]);
@ -81,8 +79,6 @@ class Venue extends BaseAdminController
["capacity",0], ["capacity",0],
["availability_status",0], ["availability_status",0],
["time_range_type",""], ["time_range_type",""],
["time_range_start",""],
["time_range_end",""],
["fixed_time_ranges",""], ["fixed_time_ranges",""],
]); ]);

2
niucloud/app/adminapi/route/venue.php

@ -15,6 +15,8 @@ use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken; use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog; use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- venue // USER_CODE_BEGIN -- venue
Route::group('venue', function () { Route::group('venue', function () {

4
niucloud/app/validate/venue/Venue.php

@ -37,8 +37,8 @@ class Venue extends BaseValidate
]; ];
protected $scene = [ protected $scene = [
"add" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'time_range_start', 'time_range_end', 'fixed_time_ranges'], "add" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'fixed_time_ranges'],
"edit" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'time_range_start', 'time_range_end', 'fixed_time_ranges'] "edit" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'fixed_time_ranges']
]; ];
} }

Loading…
Cancel
Save