commit
This commit is contained in:
@@ -0,0 +1,887 @@
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
siteId: GetQueryString('siteId'),
|
||||
row: {},
|
||||
siteLoaded: false,
|
||||
clubOptions: [],
|
||||
timeLimitConfig: {
|
||||
filterHolidays: false,
|
||||
holidayList: [],
|
||||
notApplyTimeList: [],
|
||||
},
|
||||
formData: {
|
||||
reserveType: 'union',
|
||||
applyUnionId: '',
|
||||
applyUnionName: '',
|
||||
clubId: '',
|
||||
clubName: '',
|
||||
applyMobile: '',
|
||||
reserveStartTime: '',
|
||||
reserveEndTime: '',
|
||||
joinCount: 1,
|
||||
applyCause: '',
|
||||
},
|
||||
showReserveTypePicker: false,
|
||||
showClubPicker: false,
|
||||
showTimePicker: false,
|
||||
timePickerField: '',
|
||||
timePickerColumns: [],
|
||||
timePickerParts: {
|
||||
date: '',
|
||||
hour: null,
|
||||
minute: null,
|
||||
},
|
||||
timePickerSyncing: false,
|
||||
pickerFilterCache: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
reserveTypeColumns() {
|
||||
return ['分工会预约', '协会预约']
|
||||
},
|
||||
reserveTypeText() {
|
||||
if (this.formData.reserveType === 'club') {
|
||||
return '协会预约'
|
||||
}
|
||||
if (this.formData.reserveType === 'union') {
|
||||
return '分工会预约'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
clubColumns() {
|
||||
return this.clubOptions.map(item => item.clubName)
|
||||
},
|
||||
timePickerTitle() {
|
||||
return this.timePickerField === 'reserveEndTime' ? '选择预约结束时间' : '选择预约开始时间'
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
clearTimePickerCache() {
|
||||
this.pickerFilterCache = {}
|
||||
},
|
||||
buildDefaultFormData() {
|
||||
const user = this.$store.state.user || {}
|
||||
return {
|
||||
siteId: this.row.id || '',
|
||||
applyUserId: user.id || '',
|
||||
applyUserName: user.username || '',
|
||||
applySex: user.sex || '',
|
||||
applyLoginName: user.loginname || '',
|
||||
applyUnitId: user.unit ? user.unit.id : '',
|
||||
applyUnitName: user.unit ? user.unit.name : '',
|
||||
reserveType: 'union',
|
||||
applyUnionId: user.union ? user.union.id : '',
|
||||
applyUnionName: user.union ? user.union.name : '',
|
||||
clubId: '',
|
||||
clubName: '',
|
||||
applyMobile: user.mobile || '',
|
||||
reserveStartTime: '',
|
||||
reserveEndTime: '',
|
||||
joinCount: 1,
|
||||
applyCause: '',
|
||||
}
|
||||
},
|
||||
getNormalizedMoment(value) {
|
||||
return this.$moment(value).seconds(0).milliseconds(0)
|
||||
},
|
||||
getFieldMinMoment(field) {
|
||||
const now = this.$moment().add(1, 'minute').seconds(0).milliseconds(0)
|
||||
if (field === 'reserveEndTime' && this.formData.reserveStartTime) {
|
||||
const start = this.getNormalizedMoment(this.formData.reserveStartTime).add(1, 'minute')
|
||||
return start.isAfter(now) ? start : now
|
||||
}
|
||||
return now
|
||||
},
|
||||
getFieldLatestMoment(field) {
|
||||
if (field === 'reserveStartTime' && this.formData.reserveEndTime) {
|
||||
return this.getNormalizedMoment(this.formData.reserveEndTime).subtract(1, 'minute')
|
||||
}
|
||||
return null
|
||||
},
|
||||
getFieldMaxMoment(field) {
|
||||
const defaultMax = this.$moment().add(365, 'day').endOf('day').seconds(0).milliseconds(0)
|
||||
const latest = this.getFieldLatestMoment(field)
|
||||
if (latest && latest.isBefore(defaultMax)) {
|
||||
return latest.clone().seconds(0).milliseconds(0)
|
||||
}
|
||||
return defaultMax
|
||||
},
|
||||
getContinuousEndBounds() {
|
||||
if (!this.formData.reserveStartTime) {
|
||||
return null
|
||||
}
|
||||
const minMoment = this.getFieldMinMoment('reserveEndTime')
|
||||
let maxMoment = this.getFieldMaxMoment('reserveEndTime')
|
||||
if (maxMoment.isBefore(minMoment)) {
|
||||
return null
|
||||
}
|
||||
let boundary = null
|
||||
const blockedDayCursor = minMoment.clone().startOf('day').add(1, 'day')
|
||||
while (blockedDayCursor.isSameOrBefore(maxMoment, 'day')) {
|
||||
if (this.isBlockedDay(blockedDayCursor)) {
|
||||
boundary = blockedDayCursor.clone().startOf('day')
|
||||
break
|
||||
}
|
||||
blockedDayCursor.add(1, 'day')
|
||||
}
|
||||
const list = Array.isArray(this.timeLimitConfig.notApplyTimeList) ? this.timeLimitConfig.notApplyTimeList : []
|
||||
list.forEach(item => {
|
||||
if (!item || !item.date || !item.startTime || !item.endTime) {
|
||||
return
|
||||
}
|
||||
const dayStr = this.$moment(item.date).format('YYYY-MM-DD')
|
||||
const rangeStart = this.$moment(dayStr + ' ' + this.normalizeTime(item.startTime))
|
||||
const rangeEnd = this.$moment(dayStr + ' ' + this.normalizeTime(item.endTime))
|
||||
if (rangeEnd.isSameOrBefore(minMoment)) {
|
||||
return
|
||||
}
|
||||
if (rangeStart.isSameOrBefore(minMoment) && rangeEnd.isAfter(minMoment)) {
|
||||
boundary = minMoment.clone()
|
||||
return
|
||||
}
|
||||
if (rangeStart.isAfter(minMoment) && rangeStart.isSameOrBefore(maxMoment)) {
|
||||
if (!boundary || rangeStart.isBefore(boundary)) {
|
||||
boundary = rangeStart.clone()
|
||||
}
|
||||
}
|
||||
})
|
||||
if (boundary && boundary.isSameOrBefore(maxMoment)) {
|
||||
maxMoment = boundary.clone().subtract(1, 'minute')
|
||||
}
|
||||
if (maxMoment.isBefore(minMoment)) {
|
||||
return null
|
||||
}
|
||||
return {
|
||||
minMoment: minMoment,
|
||||
maxMoment: maxMoment,
|
||||
}
|
||||
},
|
||||
getEffectiveFieldMaxMoment(field) {
|
||||
if (field === 'reserveEndTime' && this.formData.reserveStartTime) {
|
||||
const bounds = this.getContinuousEndBounds()
|
||||
return bounds ? bounds.maxMoment.clone() : this.getFieldMinMoment(field).clone().subtract(1, 'minute')
|
||||
}
|
||||
return this.getFieldMaxMoment(field)
|
||||
},
|
||||
buildPickerMoment(parts) {
|
||||
if (parts && parts.date) {
|
||||
return this.$moment(parts.date, 'YYYY-MM-DD')
|
||||
.hour(parts.hour || 0)
|
||||
.minute(parts.minute || 0)
|
||||
.second(0)
|
||||
.millisecond(0)
|
||||
}
|
||||
return this.$moment({
|
||||
year: parts.year,
|
||||
month: parts.month - 1,
|
||||
date: parts.day,
|
||||
hour: parts.hour,
|
||||
minute: parts.minute,
|
||||
second: 0,
|
||||
millisecond: 0,
|
||||
})
|
||||
},
|
||||
extractTimePickerPartsFromMoment(momentValue) {
|
||||
const pickerMoment = this.getNormalizedMoment(momentValue)
|
||||
return {
|
||||
date: pickerMoment.format('YYYY-MM-DD'),
|
||||
hour: pickerMoment.hour(),
|
||||
minute: pickerMoment.minute(),
|
||||
}
|
||||
},
|
||||
getPickerPartValue(item, fallback) {
|
||||
if (item && typeof item === 'object' && item !== null && typeof item.value !== 'undefined') {
|
||||
return item.value
|
||||
}
|
||||
if (item === '' || item === null || typeof item === 'undefined') {
|
||||
return fallback
|
||||
}
|
||||
return item
|
||||
},
|
||||
extractTimePickerParts(values) {
|
||||
const fallback = this.timePickerParts || {}
|
||||
return {
|
||||
date: this.getPickerPartValue(values && values[0], fallback.date),
|
||||
hour: Number(this.getPickerPartValue(values && values[1], fallback.hour)),
|
||||
minute: Number(this.getPickerPartValue(values && values[2], fallback.minute)),
|
||||
}
|
||||
},
|
||||
isValidCalendarMoment(momentValue, month, day) {
|
||||
return momentValue.isValid() && momentValue.month() + 1 === month && momentValue.date() === day
|
||||
},
|
||||
isBlockedDay(momentValue) {
|
||||
if (!momentValue || !momentValue.isValid()) {
|
||||
return true
|
||||
}
|
||||
if (momentValue.day() === 0 || momentValue.day() === 6) {
|
||||
return true
|
||||
}
|
||||
return this.timeLimitConfig.filterHolidays && this.timeLimitConfig.holidayList.includes(momentValue.format('YYYY-MM-DD'))
|
||||
},
|
||||
isRangeSelectable(start, end) {
|
||||
if (!start || !end || !start.isValid() || !end.isValid()) {
|
||||
return false
|
||||
}
|
||||
if (!end.isAfter(start)) {
|
||||
return false
|
||||
}
|
||||
if (this.hasHolidayInRange(start, end)) {
|
||||
return false
|
||||
}
|
||||
if (this.overlapsDisabledRange(start, end)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
isExactTimeSelectable(momentValue, field) {
|
||||
if (!momentValue || !momentValue.isValid()) {
|
||||
return false
|
||||
}
|
||||
const candidate = momentValue.clone().seconds(0).milliseconds(0)
|
||||
const minMoment = this.getFieldMinMoment(field)
|
||||
if (candidate.isBefore(minMoment)) {
|
||||
return false
|
||||
}
|
||||
const latestMoment = this.getFieldLatestMoment(field)
|
||||
if (latestMoment && candidate.isAfter(latestMoment)) {
|
||||
return false
|
||||
}
|
||||
if (field === 'reserveEndTime' && this.formData.reserveStartTime) {
|
||||
const bounds = this.getContinuousEndBounds()
|
||||
if (!bounds) {
|
||||
return false
|
||||
}
|
||||
return candidate.isSameOrAfter(bounds.minMoment) && candidate.isSameOrBefore(bounds.maxMoment)
|
||||
}
|
||||
if (this.isDateTimeBlocked(candidate.format('YYYY-MM-DD HH:mm:ss'))) {
|
||||
return false
|
||||
}
|
||||
if (field === 'reserveStartTime' && this.formData.reserveEndTime) {
|
||||
const end = this.getNormalizedMoment(this.formData.reserveEndTime)
|
||||
if (!candidate.isBefore(end)) {
|
||||
return false
|
||||
}
|
||||
return this.isRangeSelectable(candidate, end)
|
||||
}
|
||||
return true
|
||||
},
|
||||
dayHasAvailableTime(year, month, day, field) {
|
||||
const cacheKey = ['day', field, year, month, day, this.formData.reserveStartTime || '', this.formData.reserveEndTime || ''].join('|')
|
||||
if (cacheKey in this.pickerFilterCache) {
|
||||
return this.pickerFilterCache[cacheKey]
|
||||
}
|
||||
const dayMoment = this.buildPickerMoment({ year: year, month: month, day: day, hour: 0, minute: 0 })
|
||||
if (!this.isValidCalendarMoment(dayMoment, month, day) || this.isBlockedDay(dayMoment)) {
|
||||
this.pickerFilterCache[cacheKey] = false
|
||||
return false
|
||||
}
|
||||
const minMoment = this.getFieldMinMoment(field)
|
||||
const maxMoment = this.getEffectiveFieldMaxMoment(field)
|
||||
const dayStart = dayMoment.clone().startOf('day')
|
||||
const dayEnd = dayMoment.clone().endOf('day')
|
||||
if (dayEnd.isBefore(minMoment) || dayStart.isAfter(maxMoment)) {
|
||||
this.pickerFilterCache[cacheKey] = false
|
||||
return false
|
||||
}
|
||||
if (field === 'reserveEndTime' && this.formData.reserveStartTime) {
|
||||
this.pickerFilterCache[cacheKey] = true
|
||||
return true
|
||||
}
|
||||
for (let hour = 0; hour < 24; hour++) {
|
||||
if (this.hourHasAvailableTime(year, month, day, hour, field)) {
|
||||
this.pickerFilterCache[cacheKey] = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
this.pickerFilterCache[cacheKey] = false
|
||||
return false
|
||||
},
|
||||
hourHasAvailableTime(year, month, day, hour, field) {
|
||||
const cacheKey = ['hour', field, year, month, day, hour, this.formData.reserveStartTime || '', this.formData.reserveEndTime || ''].join('|')
|
||||
if (cacheKey in this.pickerFilterCache) {
|
||||
return this.pickerFilterCache[cacheKey]
|
||||
}
|
||||
const hourMoment = this.buildPickerMoment({ year: year, month: month, day: day, hour: hour, minute: 0 })
|
||||
if (!this.isValidCalendarMoment(hourMoment, month, day)) {
|
||||
this.pickerFilterCache[cacheKey] = false
|
||||
return false
|
||||
}
|
||||
const minMoment = this.getFieldMinMoment(field)
|
||||
const maxMoment = this.getEffectiveFieldMaxMoment(field)
|
||||
const hourStart = hourMoment.clone().startOf('hour')
|
||||
const hourEnd = hourMoment.clone().endOf('hour')
|
||||
if (hourEnd.isBefore(minMoment) || hourStart.isAfter(maxMoment)) {
|
||||
this.pickerFilterCache[cacheKey] = false
|
||||
return false
|
||||
}
|
||||
if (field === 'reserveEndTime' && this.formData.reserveStartTime) {
|
||||
this.pickerFilterCache[cacheKey] = true
|
||||
return true
|
||||
}
|
||||
for (let minute = 0; minute < 60; minute++) {
|
||||
const candidate = this.buildPickerMoment({ year: year, month: month, day: day, hour: hour, minute: minute })
|
||||
if (this.isExactTimeSelectable(candidate, field)) {
|
||||
this.pickerFilterCache[cacheKey] = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
this.pickerFilterCache[cacheKey] = false
|
||||
return false
|
||||
},
|
||||
findFirstSelectableDateTime(field, baseMoment) {
|
||||
let startMoment = this.getNormalizedMoment(baseMoment)
|
||||
const minMoment = this.getFieldMinMoment(field)
|
||||
const maxMoment = this.getEffectiveFieldMaxMoment(field)
|
||||
if (maxMoment.isBefore(minMoment)) {
|
||||
return null
|
||||
}
|
||||
if (startMoment.isBefore(minMoment)) {
|
||||
startMoment = minMoment.clone()
|
||||
}
|
||||
for (let dayOffset = 0; dayOffset <= 366; dayOffset++) {
|
||||
const dayMoment = startMoment.clone().startOf('day').add(dayOffset, 'day')
|
||||
if (dayMoment.isAfter(maxMoment, 'day')) {
|
||||
break
|
||||
}
|
||||
if (this.isBlockedDay(dayMoment)) {
|
||||
continue
|
||||
}
|
||||
const startHour = dayMoment.isSame(startMoment, 'day') ? startMoment.hour() : 0
|
||||
for (let hour = startHour; hour < 24; hour++) {
|
||||
const startMinute = dayMoment.isSame(startMoment, 'day') && hour === startMoment.hour() ? startMoment.minute() : 0
|
||||
for (let minute = startMinute; minute < 60; minute++) {
|
||||
const candidate = dayMoment.clone().hour(hour).minute(minute).second(0).millisecond(0)
|
||||
if (candidate.isAfter(maxMoment)) {
|
||||
return null
|
||||
}
|
||||
if (this.isExactTimeSelectable(candidate, field)) {
|
||||
return candidate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
formatPickerNumber(value) {
|
||||
return value < 10 ? '0' + value : '' + value
|
||||
},
|
||||
getWeekdayText(momentValue) {
|
||||
const weekdayList = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
||||
return weekdayList[momentValue.day()]
|
||||
},
|
||||
createPickerOption(text, value, disabled) {
|
||||
return {
|
||||
text: text,
|
||||
value: value,
|
||||
disabled: !!disabled,
|
||||
}
|
||||
},
|
||||
findNearestEnabledIndex(options, preferredValue) {
|
||||
if (!Array.isArray(options) || !options.length) {
|
||||
return -1
|
||||
}
|
||||
const enabledIndexes = []
|
||||
options.forEach((item, index) => {
|
||||
if (!item.disabled) {
|
||||
enabledIndexes.push(index)
|
||||
}
|
||||
})
|
||||
if (!enabledIndexes.length) {
|
||||
return -1
|
||||
}
|
||||
if (preferredValue === '' || preferredValue === null || typeof preferredValue === 'undefined' || Number.isNaN(preferredValue)) {
|
||||
return enabledIndexes[0]
|
||||
}
|
||||
let targetIndex = enabledIndexes[0]
|
||||
let targetDistance = Math.abs(Number(options[targetIndex].value) - Number(preferredValue))
|
||||
enabledIndexes.forEach(index => {
|
||||
const distance = Math.abs(Number(options[index].value) - Number(preferredValue))
|
||||
if (distance < targetDistance) {
|
||||
targetIndex = index
|
||||
targetDistance = distance
|
||||
}
|
||||
})
|
||||
return targetIndex
|
||||
},
|
||||
buildDateOptions(field) {
|
||||
const minMoment = this.getFieldMinMoment(field).clone().startOf('day')
|
||||
const maxMoment = this.getEffectiveFieldMaxMoment(field).clone().startOf('day')
|
||||
const options = []
|
||||
const cursor = minMoment.clone()
|
||||
while (cursor.isSameOrBefore(maxMoment, 'day')) {
|
||||
const text = cursor.format('MM-DD') + ' ' + this.getWeekdayText(cursor)
|
||||
options.push(this.createPickerOption(text, cursor.format('YYYY-MM-DD'), !this.dayHasAvailableTime(cursor.year(), cursor.month() + 1, cursor.date(), field)))
|
||||
cursor.add(1, 'day')
|
||||
}
|
||||
return options
|
||||
},
|
||||
buildHourOptionsByDate(field, dateValue) {
|
||||
const dateMoment = this.$moment(dateValue, 'YYYY-MM-DD')
|
||||
const year = dateMoment.year()
|
||||
const month = dateMoment.month() + 1
|
||||
const day = dateMoment.date()
|
||||
const options = []
|
||||
for (let hour = 0; hour < 24; hour++) {
|
||||
options.push(this.createPickerOption(this.formatPickerNumber(hour) + '时', hour, !this.hourHasAvailableTime(year, month, day, hour, field)))
|
||||
}
|
||||
return options
|
||||
},
|
||||
buildMinuteOptionsByDateHour(field, dateValue, hour) {
|
||||
const dateMoment = this.$moment(dateValue, 'YYYY-MM-DD')
|
||||
const options = []
|
||||
for (let minute = 0; minute < 60; minute++) {
|
||||
const candidate = this.buildPickerMoment({
|
||||
year: dateMoment.year(),
|
||||
month: dateMoment.month() + 1,
|
||||
day: dateMoment.date(),
|
||||
hour: hour,
|
||||
minute: minute,
|
||||
})
|
||||
options.push(this.createPickerOption(this.formatPickerNumber(minute) + '分', minute, !this.isExactTimeSelectable(candidate, field)))
|
||||
}
|
||||
return options
|
||||
},
|
||||
buildTimePickerColumns(field, preferredParts) {
|
||||
const dateOptions = this.buildDateOptions(field)
|
||||
const enabledDateIndex = dateOptions.findIndex(item => !item.disabled)
|
||||
if (enabledDateIndex < 0) {
|
||||
return null
|
||||
}
|
||||
let dateIndex = enabledDateIndex
|
||||
if (preferredParts && preferredParts.date) {
|
||||
const exactIndex = dateOptions.findIndex(item => item.value === preferredParts.date && !item.disabled)
|
||||
if (exactIndex >= 0) {
|
||||
dateIndex = exactIndex
|
||||
}
|
||||
}
|
||||
const selectedDate = dateOptions[dateIndex].value
|
||||
|
||||
const hourOptions = this.buildHourOptionsByDate(field, selectedDate)
|
||||
const hourIndex = this.findNearestEnabledIndex(hourOptions, preferredParts ? preferredParts.hour : null)
|
||||
if (hourIndex < 0) {
|
||||
return null
|
||||
}
|
||||
const selectedHour = hourOptions[hourIndex].value
|
||||
|
||||
const minuteOptions = this.buildMinuteOptionsByDateHour(field, selectedDate, selectedHour)
|
||||
const minuteIndex = this.findNearestEnabledIndex(minuteOptions, preferredParts ? preferredParts.minute : null)
|
||||
if (minuteIndex < 0) {
|
||||
return null
|
||||
}
|
||||
const selectedMinute = minuteOptions[minuteIndex].value
|
||||
|
||||
return {
|
||||
parts: {
|
||||
date: selectedDate,
|
||||
hour: selectedHour,
|
||||
minute: selectedMinute,
|
||||
},
|
||||
indexes: [dateIndex, hourIndex, minuteIndex],
|
||||
columns: [
|
||||
{ values: dateOptions, defaultIndex: dateIndex },
|
||||
{ values: hourOptions, defaultIndex: hourIndex },
|
||||
{ values: minuteOptions, defaultIndex: minuteIndex },
|
||||
],
|
||||
}
|
||||
},
|
||||
sameTimePickerParts(left, right) {
|
||||
if (!left || !right) {
|
||||
return false
|
||||
}
|
||||
return left.date === right.date
|
||||
&& left.hour === right.hour
|
||||
&& left.minute === right.minute
|
||||
},
|
||||
syncTimePickerColumns(picker, built) {
|
||||
if (!picker || !built) {
|
||||
this.timePickerSyncing = false
|
||||
return
|
||||
}
|
||||
this.timePickerSyncing = true
|
||||
built.columns.forEach((column, index) => {
|
||||
picker.setColumnValues(index, column.values)
|
||||
})
|
||||
picker.setIndexes(built.indexes)
|
||||
this.timePickerParts = built.parts
|
||||
setTimeout(() => {
|
||||
this.timePickerSyncing = false
|
||||
}, 0)
|
||||
},
|
||||
applyTimePickerState(built, picker, syncColumns = true) {
|
||||
if (!built) {
|
||||
return false
|
||||
}
|
||||
const currentPicker = picker || this.$refs.timePickerRef
|
||||
if (syncColumns) {
|
||||
this.timePickerColumns = built.columns
|
||||
this.$nextTick(() => {
|
||||
this.syncTimePickerColumns(currentPicker || this.$refs.timePickerRef, built)
|
||||
})
|
||||
return true
|
||||
}
|
||||
this.syncTimePickerColumns(currentPicker, built)
|
||||
return true
|
||||
},
|
||||
async init() {
|
||||
if (!this.siteId) {
|
||||
this.$toast('未获取到场馆信息')
|
||||
this.historyBack()
|
||||
return
|
||||
}
|
||||
const siteRes = await this.$axios.post('/platform/siteCug/manage/info', { id: this.siteId })
|
||||
if (siteRes.code !== 0 || !siteRes.data) {
|
||||
this.$toast(siteRes.msg || '场馆信息加载失败')
|
||||
this.historyBack()
|
||||
return
|
||||
}
|
||||
this.row = siteRes.data
|
||||
this.formData = this.buildDefaultFormData()
|
||||
await this.queryTimeLimitConfig()
|
||||
this.siteLoaded = true
|
||||
},
|
||||
async queryTimeLimitConfig() {
|
||||
const fallback = {
|
||||
filterHolidays: !!this.row.filterHolidays,
|
||||
holidayList: [],
|
||||
notApplyTimeList: Array.isArray(this.row.notApplyTimeList) ? this.row.notApplyTimeList : [],
|
||||
}
|
||||
try {
|
||||
const res = await this.$axios.post('/platform/siteCug/apply/timeLimitConfig', {
|
||||
siteId: this.row.id,
|
||||
})
|
||||
if (res.code === 0 && res.data) {
|
||||
this.timeLimitConfig = {
|
||||
filterHolidays: !!res.data.filterHolidays,
|
||||
holidayList: Array.isArray(res.data.holidayList) ? res.data.holidayList : [],
|
||||
notApplyTimeList: Array.isArray(res.data.notApplyTimeList) ? res.data.notApplyTimeList : [],
|
||||
}
|
||||
this.clearTimePickerCache()
|
||||
return
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
this.timeLimitConfig = fallback
|
||||
this.clearTimePickerCache()
|
||||
},
|
||||
async reserveTypeChange(value) {
|
||||
const user = this.$store.state.user || {}
|
||||
if (value === 'union') {
|
||||
this.formData.applyUnionId = user.union ? user.union.id : ''
|
||||
this.formData.applyUnionName = user.union ? user.union.name : ''
|
||||
this.formData.clubId = ''
|
||||
this.formData.clubName = ''
|
||||
return
|
||||
}
|
||||
if (value === 'club') {
|
||||
this.formData.applyUnionId = ''
|
||||
this.formData.applyUnionName = ''
|
||||
this.formData.clubId = ''
|
||||
this.formData.clubName = ''
|
||||
await this.loadManagedClubs()
|
||||
}
|
||||
},
|
||||
async loadManagedClubs() {
|
||||
try {
|
||||
const res = await this.$axios.post('/platform/club/examine/apply/getClubsByRole')
|
||||
this.clubOptions = Array.isArray(res.data) ? res.data : []
|
||||
if (!this.clubOptions.length) {
|
||||
this.$toast('您当前没有可预约的协会管理权限')
|
||||
}
|
||||
} catch (e) {
|
||||
this.clubOptions = []
|
||||
this.$toast('协会列表加载失败,请稍后重试')
|
||||
}
|
||||
},
|
||||
onReserveTypeConfirm(value) {
|
||||
this.showReserveTypePicker = false
|
||||
const reserveType = value === '协会预约' ? 'club' : 'union'
|
||||
this.$set(this.formData, 'reserveType', reserveType)
|
||||
this.reserveTypeChange(reserveType)
|
||||
},
|
||||
async openClubPicker() {
|
||||
if (this.formData.reserveType !== 'club') {
|
||||
this.$toast('请先选择协会预约')
|
||||
return
|
||||
}
|
||||
if (!this.clubOptions.length) {
|
||||
await this.loadManagedClubs()
|
||||
}
|
||||
if (!this.clubOptions.length) {
|
||||
return
|
||||
}
|
||||
this.showClubPicker = true
|
||||
},
|
||||
onClubConfirm(value, index) {
|
||||
this.showClubPicker = false
|
||||
const club = this.clubOptions[index]
|
||||
this.formData.clubId = club ? club.id : ''
|
||||
this.formData.clubName = club ? club.clubName : value
|
||||
},
|
||||
openTimePicker(field) {
|
||||
this.timePickerField = field
|
||||
this.timePickerSyncing = false
|
||||
this.clearTimePickerCache()
|
||||
let defaultTime = this.formData[field] ? this.getNormalizedMoment(this.formData[field]) : null
|
||||
if (!defaultTime || !defaultTime.isValid()) {
|
||||
defaultTime = field === 'reserveEndTime' && this.formData.reserveStartTime
|
||||
? this.getNormalizedMoment(this.formData.reserveStartTime).add(1, 'hour')
|
||||
: this.$moment().add(1, 'hour').startOf('hour')
|
||||
}
|
||||
const availableTime = this.findFirstSelectableDateTime(field, defaultTime)
|
||||
if (!availableTime) {
|
||||
this.$toast('当前没有可预约的时间')
|
||||
return
|
||||
}
|
||||
const built = this.buildTimePickerColumns(field, this.extractTimePickerPartsFromMoment(availableTime))
|
||||
if (!built) {
|
||||
this.$toast('当前没有可预约的时间')
|
||||
return
|
||||
}
|
||||
this.showTimePicker = true
|
||||
this.applyTimePickerState(built, null, true)
|
||||
},
|
||||
onTimePickerChange(picker, values) {
|
||||
if (!this.timePickerField || this.timePickerSyncing) {
|
||||
return
|
||||
}
|
||||
const parts = this.extractTimePickerParts(values)
|
||||
const built = this.buildTimePickerColumns(this.timePickerField, parts)
|
||||
if (!built) {
|
||||
return
|
||||
}
|
||||
if (this.sameTimePickerParts(parts, built.parts)) {
|
||||
this.timePickerParts = built.parts
|
||||
return
|
||||
}
|
||||
this.applyTimePickerState(built, picker, false)
|
||||
},
|
||||
onTimeConfirm(values) {
|
||||
const parts = this.extractTimePickerParts(values)
|
||||
const candidate = this.buildPickerMoment(parts)
|
||||
if (!this.isExactTimeSelectable(candidate, this.timePickerField)) {
|
||||
this.$toast('该时间不可预约,请重新选择')
|
||||
const built = this.buildTimePickerColumns(this.timePickerField, parts)
|
||||
this.applyTimePickerState(built, this.$refs.timePickerRef)
|
||||
return
|
||||
}
|
||||
const formatted = candidate.format('YYYY-MM-DD HH:mm:ss')
|
||||
this.timePickerSyncing = false
|
||||
this.showTimePicker = false
|
||||
this.$set(this.formData, this.timePickerField, formatted)
|
||||
this.clearTimePickerCache()
|
||||
this.timeFieldChange(this.timePickerField)
|
||||
},
|
||||
async normalizeReserveTypeData() {
|
||||
const user = this.$store.state.user || {}
|
||||
if (this.formData.reserveType === 'union') {
|
||||
this.formData.applyUnionId = user.union ? user.union.id : ''
|
||||
this.formData.applyUnionName = user.union ? user.union.name : ''
|
||||
this.formData.clubId = ''
|
||||
this.formData.clubName = ''
|
||||
return true
|
||||
}
|
||||
if (this.formData.reserveType === 'club') {
|
||||
if (!this.clubOptions.length) {
|
||||
await this.loadManagedClubs()
|
||||
}
|
||||
const club = this.clubOptions.find(item => item.id === this.formData.clubId)
|
||||
this.formData.clubName = club ? club.clubName : ''
|
||||
this.formData.applyUnionId = ''
|
||||
this.formData.applyUnionName = ''
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
normalizeTime(timeStr) {
|
||||
if (!timeStr) {
|
||||
return '00:00:00'
|
||||
}
|
||||
return timeStr.length === 5 ? timeStr + ':00' : timeStr
|
||||
},
|
||||
getDisabledRangesByDay(dayStr) {
|
||||
const list = Array.isArray(this.timeLimitConfig.notApplyTimeList) ? this.timeLimitConfig.notApplyTimeList : []
|
||||
return list
|
||||
.filter(item => item && item.date && this.$moment(item.date).format('YYYY-MM-DD') === dayStr)
|
||||
.sort((a, b) => this.normalizeTime(a.startTime).localeCompare(this.normalizeTime(b.startTime)))
|
||||
},
|
||||
isDateTimeBlocked(dateTimeStr) {
|
||||
if (!dateTimeStr) {
|
||||
return false
|
||||
}
|
||||
const target = this.$moment(dateTimeStr)
|
||||
const dayStr = target.format('YYYY-MM-DD')
|
||||
if (target.day() === 0 || target.day() === 6) {
|
||||
return true
|
||||
}
|
||||
if (this.timeLimitConfig.filterHolidays && this.timeLimitConfig.holidayList.includes(dayStr)) {
|
||||
return true
|
||||
}
|
||||
const disabledRanges = this.getDisabledRangesByDay(dayStr)
|
||||
return disabledRanges.some(item => {
|
||||
const start = this.$moment(dayStr + ' ' + this.normalizeTime(item.startTime))
|
||||
const end = this.$moment(dayStr + ' ' + this.normalizeTime(item.endTime))
|
||||
return target.isSameOrAfter(start) && target.isBefore(end)
|
||||
})
|
||||
},
|
||||
hasHolidayInRange(start, end) {
|
||||
const current = start.clone().startOf('day')
|
||||
const endDay = end.clone().startOf('day')
|
||||
while (current.isSameOrBefore(endDay)) {
|
||||
if (current.day() === 0 || current.day() === 6) {
|
||||
return true
|
||||
}
|
||||
if (this.timeLimitConfig.filterHolidays && this.timeLimitConfig.holidayList.includes(current.format('YYYY-MM-DD'))) {
|
||||
return true
|
||||
}
|
||||
current.add(1, 'day')
|
||||
}
|
||||
return false
|
||||
},
|
||||
overlapsDisabledRange(start, end) {
|
||||
const list = Array.isArray(this.timeLimitConfig.notApplyTimeList) ? this.timeLimitConfig.notApplyTimeList : []
|
||||
return list.some(item => {
|
||||
if (!item || !item.date || !item.startTime || !item.endTime) {
|
||||
return false
|
||||
}
|
||||
const rangeStart = this.$moment(this.$moment(item.date).format('YYYY-MM-DD') + ' ' + this.normalizeTime(item.startTime))
|
||||
const rangeEnd = this.$moment(this.$moment(item.date).format('YYYY-MM-DD') + ' ' + this.normalizeTime(item.endTime))
|
||||
return start.isBefore(rangeEnd) && end.isAfter(rangeStart)
|
||||
})
|
||||
},
|
||||
showSubmitError(message) {
|
||||
return this.$dialog.alert({
|
||||
title: '提示',
|
||||
message: message || '提交失败',
|
||||
}).catch(() => {})
|
||||
},
|
||||
validateTimeLimit(showMessage = true, useDialog = false) {
|
||||
const reserveStartTime = this.formData.reserveStartTime
|
||||
const reserveEndTime = this.formData.reserveEndTime
|
||||
if (!reserveStartTime || !reserveEndTime) {
|
||||
return true
|
||||
}
|
||||
const start = this.$moment(reserveStartTime)
|
||||
const end = this.$moment(reserveEndTime)
|
||||
const showError = (message) => {
|
||||
if (!showMessage) {
|
||||
return
|
||||
}
|
||||
if (useDialog) {
|
||||
this.showSubmitError(message)
|
||||
return
|
||||
}
|
||||
this.$toast(message)
|
||||
}
|
||||
if (this.isDateTimeBlocked(reserveStartTime) || this.isDateTimeBlocked(reserveEndTime)) {
|
||||
showError('预约时间不能选择周末、节假日或禁用时间')
|
||||
return false
|
||||
}
|
||||
if (this.hasHolidayInRange(start, end)) {
|
||||
showError('预约时间范围内包含周末或节假日,请重新选择')
|
||||
return false
|
||||
}
|
||||
if (this.overlapsDisabledRange(start, end)) {
|
||||
showError('预约时间范围与禁用时间冲突,请重新选择')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
timeFieldChange(field) {
|
||||
const value = this.formData[field]
|
||||
this.clearTimePickerCache()
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
if (this.isDateTimeBlocked(value)) {
|
||||
this.$toast('该时间点不可预约,请重新选择')
|
||||
this.$set(this.formData, field, '')
|
||||
return
|
||||
}
|
||||
if (field === 'reserveStartTime' && this.formData.reserveEndTime) {
|
||||
const start = this.$moment(value)
|
||||
const end = this.$moment(this.formData.reserveEndTime)
|
||||
if (!end.isAfter(start)) {
|
||||
this.$set(this.formData, 'reserveEndTime', '')
|
||||
this.$toast('结束时间需晚于开始时间,请重新选择')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (field === 'reserveEndTime' && this.formData.reserveStartTime) {
|
||||
const start = this.$moment(this.formData.reserveStartTime)
|
||||
const end = this.$moment(value)
|
||||
if (!end.isAfter(start)) {
|
||||
this.$toast('预约结束时间必须晚于开始时间')
|
||||
this.$set(this.formData, field, '')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.reserveEndTime && !this.validateTimeLimit()) {
|
||||
this.$set(this.formData, field, '')
|
||||
}
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs.formRef.validate().then(async () => {
|
||||
if (!this.formData.reserveType) {
|
||||
await this.showSubmitError('请选择预约类型')
|
||||
return
|
||||
}
|
||||
await this.normalizeReserveTypeData()
|
||||
if (this.formData.reserveType === 'union' && !this.formData.applyUnionId) {
|
||||
await this.showSubmitError('当前用户未关联分工会,不能发起分工会预约')
|
||||
return
|
||||
}
|
||||
if (this.formData.reserveType === 'club' && !this.formData.clubId) {
|
||||
await this.showSubmitError('请选择您管理的协会')
|
||||
return
|
||||
}
|
||||
if (!this.formData.reserveStartTime || !this.formData.reserveEndTime) {
|
||||
await this.showSubmitError('请选择预约开始和结束时间')
|
||||
return
|
||||
}
|
||||
const start = this.$moment(this.formData.reserveStartTime)
|
||||
const end = this.$moment(this.formData.reserveEndTime)
|
||||
if (!start.isAfter(this.$moment())) {
|
||||
await this.showSubmitError('预约开始时间必须晚于当前时间')
|
||||
return
|
||||
}
|
||||
if (!end.isAfter(start)) {
|
||||
await this.showSubmitError('预约结束时间必须晚于开始时间')
|
||||
return
|
||||
}
|
||||
if (!this.validateTimeLimit(true, true)) {
|
||||
return
|
||||
}
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
const loading = this.$toast.loading({
|
||||
message: '提交中...',
|
||||
forbidClick: true,
|
||||
overlay: true,
|
||||
duration: 0,
|
||||
})
|
||||
this.$axios.post('/platform/siteCug/apply/submit', {
|
||||
data: JSON.stringify(this.formData),
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg || '提交成功')
|
||||
this.$pjaxReplace('/platform/siteCug/apply/h5')
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.showSubmitError((err && err.msg) || '提交失败')
|
||||
}).finally(() => {
|
||||
loading.close()
|
||||
})
|
||||
}).catch(() => {})
|
||||
}).catch(() => {})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,167 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
.page-container {
|
||||
padding-bottom: 84px;
|
||||
background: #f7f8fa;
|
||||
min-height: calc(100vh - 46px);
|
||||
}
|
||||
|
||||
.footer-actions {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 10px 12px calc(env(safe-area-inset-bottom) + 10px);
|
||||
background: #ffffff;
|
||||
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.footer-actions .van-button {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.disabled-time-item {
|
||||
line-height: 20px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/deep/ .direction-column-cell .van-cell__value {
|
||||
white-space: normal;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="场馆申请" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<div class="page-container" v-if="siteLoaded">
|
||||
<van-cell-group title="场馆信息">
|
||||
<van-cell title="场馆名称" :value="row.name || '-' "></van-cell>
|
||||
<van-cell title="场地地址" class="direction-column-cell">
|
||||
<template #default>
|
||||
{{ row.address || '-' }}
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="联系人" :value="row.contactName || '-' "></van-cell>
|
||||
<van-cell title="联系电话" :value="row.contactPhone || '-' "></van-cell>
|
||||
<van-cell title="场地类型" :value="row.typeName || '-' "></van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="预约须知">
|
||||
<van-cell title="可预约日期" value="仅限工作日"></van-cell>
|
||||
<van-cell title="节假日限制"
|
||||
:value="timeLimitConfig.filterHolidays ? '节假日不可预约' : '不排除节假日'"></van-cell>
|
||||
<van-cell title="禁用时段" class="direction-column-cell">
|
||||
<template #default>
|
||||
<div v-if="timeLimitConfig.notApplyTimeList.length">
|
||||
<div
|
||||
class="disabled-time-item"
|
||||
v-for="(item, index) in timeLimitConfig.notApplyTimeList"
|
||||
:key="item.date + item.startTime + item.endTime + index">
|
||||
{{ item.date }} {{ item.startTime }} - {{ item.endTime }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>暂无禁用时段</div>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-form ref="formRef" class="form-container" :show-error-message="false">
|
||||
<van-cell-group title="申请信息">
|
||||
<van-field v-model="formData.applyUserName" label="预约人" name="applyUserName" readonly
|
||||
:rules="[{ required: true, message: '请确认预约人' }]"></van-field>
|
||||
<van-field v-model="formData.applyLoginName" label="工号" name="applyLoginName" readonly
|
||||
:rules="[{ required: true, message: '请确认工号' }]"></van-field>
|
||||
<van-field v-model="formData.applyUnitName" label="所属单位" name="applyUnitName" readonly
|
||||
:rules="[{ required: true, message: '请确认所属单位' }]"></van-field>
|
||||
<van-field
|
||||
:value="reserveTypeText"
|
||||
label="预约类型"
|
||||
name="reserveType"
|
||||
readonly
|
||||
clickable
|
||||
is-link
|
||||
required
|
||||
placeholder="请选择预约类型"
|
||||
@click="showReserveTypePicker = true"
|
||||
:rules="[{ required: true, message: '请选择预约类型' }]">
|
||||
</van-field>
|
||||
<van-field
|
||||
v-if="formData.reserveType === 'union'"
|
||||
v-model="formData.applyUnionName"
|
||||
label="分工会"
|
||||
name="applyUnionName"
|
||||
readonly
|
||||
placeholder="自动读取当前登录人的分工会">
|
||||
</van-field>
|
||||
<van-field
|
||||
v-if="formData.reserveType === 'club'"
|
||||
v-model="formData.clubName"
|
||||
label="协会"
|
||||
name="clubName"
|
||||
readonly
|
||||
clickable
|
||||
is-link
|
||||
required
|
||||
placeholder="请选择您管理的协会"
|
||||
@click="openClubPicker"
|
||||
:rules="[{ required: true, message: '请选择您管理的协会' }]">
|
||||
</van-field>
|
||||
<van-field v-model="formData.applyMobile" label="联系电话" name="applyMobile" type="tel" maxlength="11"
|
||||
required placeholder="请输入联系电话"
|
||||
:rules="[{ required: true, message: '请输入联系电话' }]"></van-field>
|
||||
<van-field v-model="formData.reserveStartTime" label="开始时间" name="reserveStartTime" readonly
|
||||
clickable is-link required placeholder="请选择预约开始时间"
|
||||
@click="openTimePicker('reserveStartTime')"
|
||||
:rules="[{ required: true, message: '请选择预约开始时间' }]"></van-field>
|
||||
<van-field v-model="formData.reserveEndTime" label="结束时间" name="reserveEndTime" readonly clickable
|
||||
is-link required placeholder="请选择预约结束时间" @click="openTimePicker('reserveEndTime')"
|
||||
:rules="[{ required: true, message: '请选择预约结束时间' }]"></van-field>
|
||||
<van-field v-model="formData.applyCause" label="预约事由" name="applyCause" required rows="4" autosize
|
||||
type="textarea" maxlength="1000" show-word-limit placeholder="请输入预约事由"
|
||||
:rules="[{ required: true, message: '请输入预约事由' }]"></van-field>
|
||||
</van-cell-group>
|
||||
</van-form>
|
||||
</div>
|
||||
|
||||
<div class="footer-actions" v-if="siteLoaded">
|
||||
<van-button plain round type="info" @click="historyBack">取消</van-button>
|
||||
<van-button round type="primary" color="#246fb4" @click="onSubmit">提交预约</van-button>
|
||||
</div>
|
||||
|
||||
<van-popup v-model="showReserveTypePicker" position="bottom" round>
|
||||
<van-picker show-toolbar :columns="reserveTypeColumns" @confirm="onReserveTypeConfirm"
|
||||
@cancel="showReserveTypePicker = false"></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-popup v-model="showClubPicker" position="bottom" round>
|
||||
<van-picker show-toolbar :columns="clubColumns" @confirm="onClubConfirm"
|
||||
@cancel="showClubPicker = false"></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-popup v-model="showTimePicker" position="bottom" round>
|
||||
<van-picker
|
||||
ref="timePickerRef"
|
||||
show-toolbar
|
||||
value-key="text"
|
||||
:title="timePickerTitle"
|
||||
:columns="timePickerColumns"
|
||||
@change="onTimePickerChange"
|
||||
@confirm="onTimeConfirm"
|
||||
@cancel="timePickerSyncing = false; showTimePicker = false">
|
||||
</van-picker>
|
||||
</van-popup>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('apply.js'){}#-->
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,106 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="场馆预约" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入名称或地址搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false" @change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/siteCug/apply/pageData" :page_form.sync="pageForm" ref="tableListRef" title="name" @ready="onReady">
|
||||
<template v-slot="{ row }">
|
||||
<table-column label="场地地址">{{ row.address }}</table-column>
|
||||
<table-column label="联系人">{{ row.contactName }}</table-column>
|
||||
<table-column label="联系方式">{{ row.contactPhone }}</table-column>
|
||||
<table-column label="场地类型">{{ row.typeName }}</table-column>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onApply(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>预约</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<info ref="infoRef"></info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/siteInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
components: {
|
||||
info: siteInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
type: null,
|
||||
},
|
||||
typeOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onApply(row) {
|
||||
this.$pjaxReplace('/platform/siteCug/apply/form/h5?siteId=' + row.id)
|
||||
},
|
||||
async onReady() {
|
||||
const typeList = await this.querySiteType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: '全部类型',
|
||||
value: null,
|
||||
}
|
||||
].concat(typeList.map((item) => ({ text: item.name, value: item.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.type = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
async querySiteType() {
|
||||
const res = await this.$axios.post('/platform/siteCug/function/type/queryFunctionType')
|
||||
return Array.isArray(res.data) ? res.data : []
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,80 @@
|
||||
const siteCugApplyInfoH5 = {
|
||||
template:
|
||||
/*language=HTML*/
|
||||
`
|
||||
<van-action-sheet v-model="visible" :title="sheetTitle">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="预约场地">{{ viewData.siteName }}</van-cell>
|
||||
<van-cell title="预约人">{{ viewData.applyUserName }}</van-cell>
|
||||
<van-cell title="预约人工号">{{ viewData.applyLoginName }}</van-cell>
|
||||
<van-cell title="所属单位">{{ viewData.applyUnitName }}</van-cell>
|
||||
<van-cell title="预约类型">{{ reserveTypeLabel }}</van-cell>
|
||||
<van-cell title="预约主体">{{ reserveTargetName }}</van-cell>
|
||||
<van-cell title="开始时间">{{ viewData.reserveStartTime }}</van-cell>
|
||||
<van-cell title="结束时间">{{ viewData.reserveEndTime }}</van-cell>
|
||||
<van-cell title="联系电话">{{ viewData.applyMobile }}</van-cell>
|
||||
<van-cell title="预约事由" class="direction-column-cell">{{ viewData.applyCause }}</van-cell>
|
||||
</van-cell-group>
|
||||
<template v-for="task in doneTasks">
|
||||
<van-cell-group :title="task.displayName" v-if="task.ext.isFirstTaskNode" :key="task.id + '-first'">
|
||||
<van-cell title="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})</van-cell>
|
||||
<van-cell title="申请时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group :title="task.displayName" v-else :key="task.id + '-done'">
|
||||
<van-cell title="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" class="direction-column-cell">
|
||||
<div v-html="task.taskFormData.opinion || task.taskFormData.tf_opinion || '-' "></div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ['PROCESS_TASK_SUBMIT_TYPE'],
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
reserveTypeLabel() {
|
||||
return this.viewData.reserveType === 'club' ? '协会预约' : '分工会预约'
|
||||
},
|
||||
reserveTargetName() {
|
||||
return this.viewData.reserveType === 'club' ? (this.viewData.clubName || '-') : (this.viewData.applyUnionName || '-')
|
||||
},
|
||||
sheetTitle() {
|
||||
return this.visible && this.$slots.default ? '审核预约' : '预约详情'
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.viewData = row
|
||||
this.getDoneTasks()
|
||||
},
|
||||
onClose() {
|
||||
this.visible = false
|
||||
},
|
||||
getDoneTasks() {
|
||||
this.$axios.post('/flow/common/doneTasks', { bizId: this.row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
const siteInfo = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<van-action-sheet v-model="visible" title="场馆信息">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="创建人" :value="viewData.createUserName || '-' "></van-cell>
|
||||
<van-cell title="场馆名称" :value="viewData.name || '-' "></van-cell>
|
||||
<van-cell title="场地地址" class="direction-column-cell">
|
||||
<template #default>
|
||||
{{ viewData.address || '-' }}
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="联系人" :value="viewData.contactName || '-' "></van-cell>
|
||||
<van-cell title="联系电话" :value="viewData.contactPhone || '-' "></van-cell>
|
||||
<van-cell title="排序编号" :value="viewData.sortNum || '-' "></van-cell>
|
||||
<van-cell title="容纳人数" :value="viewData.maxNum || '-' "></van-cell>
|
||||
<van-cell title="场地类型" :value="viewData.typeName || '-' "></van-cell>
|
||||
<van-cell title="性别限制">
|
||||
<template #default>
|
||||
<span v-if="viewData.sexLimit === 1">男</span>
|
||||
<span v-else-if="viewData.sexLimit === 2">女</span>
|
||||
<span v-else>不限制</span>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="开启状态">
|
||||
<template #default>
|
||||
<span v-if="viewData.state">开启</span>
|
||||
<span v-else>禁用</span>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="排除节假日">
|
||||
<template #default>
|
||||
<span v-if="viewData.filterHolidays">是</span>
|
||||
<span v-else>否</span>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="场地介绍" class="direction-column-cell">
|
||||
<template #default>
|
||||
<div v-if="viewData.introduce" v-html="viewData.introduce"></div>
|
||||
<div v-else>暂无场地介绍</div>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="禁用时间" v-if="viewData.notApplyTimeList && viewData.notApplyTimeList.length > 0">
|
||||
<table class="table-class">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>开始时间</th>
|
||||
<th>结束时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in viewData.notApplyTimeList" :key="item.date + item.startTime + item.endTime + index">
|
||||
<td>{{ item.date }}</td>
|
||||
<td>{{ item.startTime }}</td>
|
||||
<td>{{ item.endTime }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</van-cell-group>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
viewData: {},
|
||||
visible: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.viewData = row
|
||||
this.visible = true
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
/deep/ .direction-column-cell .van-cell__value {
|
||||
white-space: normal;
|
||||
text-align: left;
|
||||
}
|
||||
/deep/ .table-class {
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
line-height: 1.5rem;
|
||||
font-size: 13px;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
/deep/ .table-class th {
|
||||
background-color: #f2f2f2;
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
/deep/ .table-class tr {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
/deep/ .table-class td {
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="我的预约" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item v-model="pageForm.siteType" :options="typeOptions" :multiple="false" @change="doSearch"></van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.siteId" :options="siteOptions" :multiple="false" @change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/siteCug/mine/pageData" :page_form.sync="pageForm" ref="tableListRef" title="siteName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="场地名称">{{row.siteName}}</table-column>
|
||||
<table-column label="预约类型">{{row.reserveType === 'club' ? '协会预约' : '分工会预约'}}</table-column>
|
||||
<table-column label="预约主体">{{row.reserveType === 'club' ? (row.clubName || '-') : (row.applyUnionName || '-')}}</table-column>
|
||||
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
|
||||
<table-column label="开始时间">{{row.reserveStartTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.reserveEndTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName || '-'}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row)" v-if="row.canCancel">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>取消预约</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<info ref="infoRef"></info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/applyInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
components: {
|
||||
info: siteCugApplyInfoH5,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
siteType: null,
|
||||
siteId: null,
|
||||
},
|
||||
typeOptions: [
|
||||
{
|
||||
text: '全部类型',
|
||||
value: null,
|
||||
}
|
||||
],
|
||||
siteOptions: [
|
||||
{
|
||||
text: '全部场地',
|
||||
value: null,
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
async onReady() {
|
||||
await this.querySiteType()
|
||||
await this.querySites()
|
||||
this.doSearch()
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onDelete(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: row.yearlyBatch
|
||||
? ('该记录属于“预约本年”批量预约,确认后将一并删除同批次的 ' + (row.batchDeleteCount || 0) + ' 条预约记录,是否继续?')
|
||||
: '您确定要取消该预约吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/siteCug/mine/delete', { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg || '取消成功')
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$dialog.alert({
|
||||
title: '提示',
|
||||
message: res.msg || '取消失败',
|
||||
}).catch(() => {})
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$dialog.alert({
|
||||
title: '提示',
|
||||
message: (err && err.msg) || '取消失败',
|
||||
}).catch(() => {})
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
querySiteType() {
|
||||
return this.$axios.post('/platform/siteCug/function/type/queryFunctionType').then((res) => {
|
||||
const list = Array.isArray(res.data) ? res.data : []
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: '全部类型',
|
||||
value: null,
|
||||
}
|
||||
].concat(list.map((item) => ({
|
||||
text: item.name,
|
||||
value: item.id,
|
||||
})))
|
||||
})
|
||||
},
|
||||
querySites() {
|
||||
return this.$axios.post('/platform/siteCug/manage/querySites').then((res) => {
|
||||
const list = Array.isArray(res.data) ? res.data : []
|
||||
this.siteOptions = [
|
||||
{
|
||||
text: '全部场地',
|
||||
value: null,
|
||||
}
|
||||
].concat(list.map((item) => ({
|
||||
text: item.name,
|
||||
value: item.id,
|
||||
})))
|
||||
})
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
.action-btn.disabled {
|
||||
opacity: 0.45;
|
||||
pointer-events: none;
|
||||
}
|
||||
.action-btn.loading {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.action-btn .van-loading {
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="校工会审核" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名/工号/场地搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item v-model="pageForm.siteType" :options="typeOptions" :multiple="false" @change="doSearch"></van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.siteId" :options="siteOptions" :multiple="false" @change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
<van-tabs v-model="pageForm.approvalText" @change="onApprovalTabChange">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/siteCug/schoolUnionAudit/pageData" :page_form.sync="pageForm" ref="tableListRef" title="applyUserName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="场地名称">{{row.siteName}}</table-column>
|
||||
<table-column label="预约类型">{{row.reserveType === 'club' ? '协会预约' : '分工会预约'}}</table-column>
|
||||
<table-column label="预约主体">{{row.reserveType === 'club' ? (row.clubName || '-') : (row.applyUnionName || '-')}}</table-column>
|
||||
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
|
||||
<table-column label="开始时间">{{row.reserveStartTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.reserveEndTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName || '-'}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="canRevoke(row)" :class="{ loading: revokeLoading }" @click="onRevoke(row)">
|
||||
<van-loading v-if="revokeLoading" size="14px" color="#fff"></van-loading>
|
||||
<i v-else class="fa fa-reply"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<info ref="infoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
name="tf_opinion"
|
||||
label="审批意见"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
required
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
</van-form>
|
||||
<div style="display:flex;justify-content:space-between;column-gap:10px;padding:10px;">
|
||||
<van-button type="info" block :loading="auditLoading" :disabled="auditLoading" @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button type="danger" block :loading="auditLoading" :disabled="auditLoading" @click="handleTaskAction(2)">不同意</van-button>
|
||||
<van-button type="primary" block :loading="auditLoading" :disabled="auditLoading" @click="handleTaskAction(1)">同意</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/applyInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
components: {
|
||||
info: siteCugApplyInfoH5,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
approvalText: '0',
|
||||
approval: false,
|
||||
siteType: null,
|
||||
siteId: null,
|
||||
},
|
||||
typeOptions: [
|
||||
{
|
||||
text: '全部类型',
|
||||
value: null,
|
||||
}
|
||||
],
|
||||
siteOptions: [
|
||||
{
|
||||
text: '全部场地',
|
||||
value: null,
|
||||
}
|
||||
],
|
||||
formData: {},
|
||||
showApprovalForm: false,
|
||||
auditLoading: false,
|
||||
revokeLoading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
async onReady() {
|
||||
await this.querySiteType()
|
||||
await this.querySites()
|
||||
this.doSearch()
|
||||
},
|
||||
onApprovalTabChange(val) {
|
||||
this.pageForm.approval = val === '1'
|
||||
this.doSearch()
|
||||
},
|
||||
canRevoke(row) {
|
||||
return Number(row.instanceState) === 20
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
processTaskId: row.taskId,
|
||||
applyId: row.id,
|
||||
taskName: row.curTaskName,
|
||||
tf_opinion: '',
|
||||
yearlyBatch: row.yearlyBatch,
|
||||
batchAuditCount: row.batchAuditCount,
|
||||
}
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
async handleTaskAction(submitType) {
|
||||
if (this.auditLoading) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await this.$refs.formRef.validate()
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: this.formData.yearlyBatch
|
||||
? ('该记录属于“预约本年”批量预约,提交后将一并审核同批次的 ' + (this.formData.batchAuditCount || 0) + ' 条预约记录,是否继续?')
|
||||
: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.auditLoading = true
|
||||
this.$axios.post('/platform/siteCug/schoolUnionAudit/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: submitType,
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.infoRef.onClose()
|
||||
this.$toast.success(res.msg || '提交成功')
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$dialog.alert({
|
||||
title: '提示',
|
||||
message: res.msg || '提交失败',
|
||||
}).catch(() => {})
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$dialog.alert({
|
||||
title: '提示',
|
||||
message: (err && err.msg) || '提交失败',
|
||||
}).catch(() => {})
|
||||
}).finally(() => {
|
||||
this.auditLoading = false
|
||||
})
|
||||
}).catch(() => {})
|
||||
} catch (e) {
|
||||
}
|
||||
},
|
||||
onRevoke(row) {
|
||||
if (!this.canRevoke(row) || this.revokeLoading) {
|
||||
return
|
||||
}
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: row.yearlyBatch
|
||||
? ('该记录属于“预约本年”批量预约,撤回后将一并撤回同批次的 ' + (row.batchAuditCount || 0) + ' 条审核任务,是否继续?')
|
||||
: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.revokeLoading = true
|
||||
this.$axios.post('/platform/siteCug/schoolUnionAudit/revokeTask', { taskId: row.taskId, applyId: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg || '撤回成功')
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$dialog.alert({
|
||||
title: '提示',
|
||||
message: res.msg || '撤回失败',
|
||||
}).catch(() => {})
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$dialog.alert({
|
||||
title: '提示',
|
||||
message: (err && err.msg) || '撤回失败',
|
||||
}).catch(() => {})
|
||||
}).finally(() => {
|
||||
this.revokeLoading = false
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
querySiteType() {
|
||||
return this.$axios.post('/platform/siteCug/function/type/queryFunctionType').then((res) => {
|
||||
const list = Array.isArray(res.data) ? res.data : []
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: '全部类型',
|
||||
value: null,
|
||||
}
|
||||
].concat(list.map((item) => ({
|
||||
text: item.name,
|
||||
value: item.id,
|
||||
})))
|
||||
})
|
||||
},
|
||||
querySites() {
|
||||
return this.$axios.post('/platform/siteCug/manage/querySites').then((res) => {
|
||||
const list = Array.isArray(res.data) ? res.data : []
|
||||
this.siteOptions = [
|
||||
{
|
||||
text: '全部场地',
|
||||
value: null,
|
||||
}
|
||||
].concat(list.map((item) => ({
|
||||
text: item.name,
|
||||
value: item.id,
|
||||
})))
|
||||
})
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user