first commit

This commit is contained in:
2026-09-09 09:14:28 +08:00
commit 5343198112
5199 changed files with 1052895 additions and 0 deletions
@@ -0,0 +1,602 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<div class="btn-group tool-button mt5">
<el-date-picker v-model="pageForm.year"
type="year" value-format="yyyy" style="width: 200px" placeholder="选择年">
</el-date-picker>
</div>
<div class="btn-group tool-button mt5">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
style="width: 110px;">
<el-option label="场地名称" value="name"></el-option>
<el-option label="场地地址" value="address"></el-option>
</el-select>
</el-input>
</div>
<div class="btn-group tool-button mt5">
<el-select v-model="pageForm.siteType" placeholder="场地类型" clearable
style="width: 200px;">
<el-option v-for="item in activityTypeList" :label="item.text" :value="item.value"></el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-button type="primary" icon="el-icon-search" @click="doSearch"></el-button>
</div>
<div class="pull-right offscreen-right mt5">
<el-button type="primary" icon="el-icon-plus" @click="openAdd">新建场地</el-button>
</div>
</el-card>
<el-card shadow="never" class="mt20">
<el-table :data="tableData" row-key="id" @sort-change="pageOrder"
v-loading="tableLoading">
<el-table-column align="center" header-align="center" label="序号" type="index">
<template scope="scope">
<span>{{scope.$index+(pageForm.pageNumber - 1) * pageForm.pageSize + 1}} </span>
</template>
</el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="场地名称"
prop="name"></el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="排序编号"
prop="sortNum"></el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="场地地址"
prop="address"></el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="联系人"
prop="contact_person"></el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="联系方式"
prop="contact_phone"></el-table-column>
<el-table-column align="center" :show-overflow-tooltip="true" header-align="center" label="开启状态"
prop="state">
<template slot-scope="{row}">
<el-switch disabled v-model="row.state" active-color="#13ce66"
inactive-color="#ff4949"></el-switch>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="250px">
<template slot-scope="{row}">
<el-button type="primary" @click="openEdit(row.id)" size="mini">编辑</el-button>
<el-button type="danger" @click="doDelete(row)" size="mini">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #edit>
<vi-title title="输入场地信息"></vi-title>
<el-form :model="formData" ref="addForm" :rules="formRules" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="name" label="场地名称">
<el-input maxlength="100" placeholder="请输入场地名称" v-model="formData.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="address" label="场地地址">
<el-input maxlength="100" placeholder="请输入场地地址" v-model="formData.address"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="contact_person" label="联系人">
<el-input v-model="formData.contact_person" placeholder="请输入联系人" type="text"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="contact_phone" label="联系方式">
<el-input v-model="formData.contact_phone" placeholder="请输入联系方式" type="text"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="create_username" label="创建人">
<el-input readonly v-model="formData.create_username" type="text"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="create_time" label="创建时间">
<el-input readonly v-model="formData.create_time" type="text"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="typeId" label="场地类型">
<el-select v-model="formData.typeId" style="width: 100%" filterable
placeholder="请选择场地类型">
<el-option v-for="item in activityTypeList" :label="item.meetingTypeName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="容纳人数" prop="maxNum">
<el-input v-model="formData.maxNum" placeholder="请输入容纳人数" type="number"></el-input>
</el-form-item>
</el-col>
<!--<el-col :span="12">
<el-form-item prop="reserveTarget" label="面向对象">
<el-radio-group v-model="formData.reserveTarget" size="medium">
<el-radio-button :label="1">面向分工会</el-radio-button>
<el-radio-button :label="2">面向个人</el-radio-button>
<el-radio-button :label="3">面向集体</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>-->
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="sortNum" label="排序编号">
<el-input v-model="formData.sortNum" placeholder="请输入排序编号" type="number"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="state" label="开启状态">
<el-radio-group v-model="formData.state" size="medium">
<el-radio-button :label="true">开启</el-radio-button>
<el-radio-button :label="false">禁用</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="filterHolidays" label="排除节假日">
<el-radio-group v-model="formData.filterHolidays" size="medium">
<el-radio-button :label="true"></el-radio-button>
<el-radio-button :label="false"></el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="sexLimit" label="性别限制">
<el-radio-group v-model="formData.sexLimit" size="medium">
<el-radio-button :label="0">不限制</el-radio-button>
<el-radio-button :label="1"></el-radio-button>
<el-radio-button :label="2"></el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="12">
<el-form-item label="禁用时间">
<el-button type="primary" @click="openSetUpTime" size="small">点击设置禁用时间</el-button>
<span style="color: #c64120">您已设置{{ formData.notApplyTimeList ? formData.notApplyTimeList.length : 0 }}个禁用时间</span>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="场地介绍">
<text-editor v-model="formData.introduce"></text-editor>
</el-form-item>
</el-form>
<vi-title2 title="添加场次(温馨提醒:如果设置了预约时间单位,那么系统会在开始时间至结束时间范围内,按照设置的单位来拆分成多个时间段,如果未设置或者为0,则表示开始时间至结束时间是一个时间段)">
<template #func>
<el-button type="primary" @click="formData.open_hours.push({})">
添加
</el-button>
</template>
</vi-title2>
<el-table :data="formData.open_hours" border size="mini">
<el-table-column prop="weekNum" label="星期" align="center" header-align="center">
<template slot-scope="{row}">
<el-select style="width: 100%" v-model="row.weekNum" filterable placeholder="请选择星期">
<el-option label="周一" :value="1"></el-option>
<el-option label="周二" :value="2"></el-option>
<el-option label="周三" :value="3"></el-option>
<el-option label="周四" :value="4"></el-option>
<el-option label="周五" :value="5"></el-option>
<el-option label="周六" :value="6"></el-option>
<el-option label="周日" :value="0"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="start_time" label="开始时间" align="center" header-align="center">
<template slot-scope="{row}">
<el-time-select
style="width: 100%"
placeholder="开始时间"
v-model="row.start_time"
:picker-options="{ start: '00:00',step: '00:30',end: '24:00'}">
</el-time-select>
</template>
</el-table-column>
<el-table-column prop="end_time" label="结束时间" align="center" header-align="center">
<template slot-scope="{row}">
<el-time-select
style="width: 100%"
placeholder="结束时间"
v-model="row.end_time"
:picker-options="{start: '00:00',step: '00:30',end: '24:00',minTime: row.start_time }">
</el-time-select>
</template>
</el-table-column>
<el-table-column prop="timeUnit" label="预约时间单位(小时)" align="center" header-align="center">
<template slot-scope="{row}">
<el-input-number style="width: 100%" v-model="row.timeUnit" placeholder="请输入预约时间单位" :step="0.5"></el-input-number>
</template>
</el-table-column>
<el-table-column label="操作" align="center" header-align="center" width="100px">
<template slot-scope="scope">
<el-button type="danger" icon="el-icon-delete" circle
:disabled="formData.open_hours.length==0"
@click="formData.open_hours.splice(scope.$index, 1)"></el-button>
</template>
</el-table-column>
</el-table>
<div style="float: right;margin: 20px 0">
<el-button type="primary" @click="operation">确 定</el-button>
</div>
</template>
<template #view>
</template>
</guava>
<el-dialog :close-on-click-modal="false" :visible.sync="setUpTimeDialog" title="设置时间" top="50px">
<vi-title title="选择日期"></vi-title>
<el-date-picker
@change="setUpDateChange"
placeholder="请选择一个或多个日期"
style="width: 100%"
type="dates"
v-model="formData.setUpDate"
value-format="yyyy-MM-dd">
</el-date-picker>
<vi-title title="设置禁用时间" class="mt20"></vi-title>
<el-row>
<el-time-select
:picker-options="{
start: '08:30',
step: '00:05',
end: '23:30'
}"
placeholder="开始时间"
v-model="timeOneKeySet.startTime">
</el-time-select>
<el-time-select
:picker-options="{
start: '08:30',
step: '00:05',
end: '23:30'
}"
placeholder="结束时间"
v-model="timeOneKeySet.endTime">
</el-time-select>
<el-button @click="oneKeySetStartEndTime" type="primary">一键设置开始/结束时间</el-button>
</el-row>
<el-table :data="formData.notApplyTimeList" class="mt10" max-height="520px" size="mini" @selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column label="日期" width="200">
<template v-slot="{row}">
<i class="el-icon-time"></i>
{{moment(row.date).format('YYYY-MM-DD')}}
</template>
</el-table-column>
<el-table-column label="开始时间">
<template v-slot="{row}">
<el-time-select
size="mini"
:picker-options="pickerOptions"
placeholder="开始时间"
v-model="row.startTime">
</el-time-select>
</template>
</el-table-column>
<el-table-column label="结束时间">
<template v-slot="{row}">
<el-time-select
size="mini"
:picker-options="pickerOptions"
placeholder="结束时间"
v-model="row.endTime">
</el-time-select>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template v-slot="{row, $index}">
<el-button
size="mini"
@click="formData.notApplyTimeList.splice($index,0,{date:row.date,startTime:'',endTime:''})"
type="primary">
新增同天时段
</el-button>
<el-button size="mini" @click="removeSetUpTableRow(row,$index)" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-row class="mt20" justify="end" type="flex">
<el-button @click="setUpTimeDialog = false">取消</el-button>
<el-button @click="doConfirmSetUpCourse" type="primary">确定</el-button>
</el-row>
</el-dialog>
</div>
<script>
<!--# include("/platform/activity/includeJs/activityUtil.js"){} #-->
const activityUtil = new typeUtil()
const vue = new Vue({
el: '#app',
data() {
return {
pickerOptions: {
start: "08:30",
step: "00:05",
end: "23:30"
},
timeOneKeySet: {
startTime: "",
endTime: ""
},
activityTypeList: [],
tabKey: '',
tableLoading: false,
subDis: false,
tableData: [],
formData: {
open_hours: [{}],
sexLimit: 0,
notApplyTimeList: [],
reserveTarget: 2,
filterHolidays: false,
},
pageForm: {
searchName: "name",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: "",
year: ""
},
formRules: {
name: [{required: true, message: '请输入场地名称', trigger: ['blur', 'change']}],
address: [{required: true, message: '请输入场地地址', trigger: ['blur', 'change']}],
contact_person: [{required: true, message: '请输入联系人', trigger: ['blur', 'change']}],
contact_phone: [{required: true, message: '请输入联系方式', trigger: ['blur', 'change']}],
state: [{required: true, message: '请选择开启状态', trigger: ['blur', 'change']}],
typeId: [{required: true, message: '请选择场地类型', trigger: ['blur', 'change']}],
openWeekTime: [{required: true, message: '请选择预约时间', trigger: ['blur', 'change']}],
reserveTarget: [{required: true, message: '请选择面向对象', trigger: ['blur', 'change']}],
maxNum: [{required: true, message: '请输入容纳人数', trigger: ['blur', 'change']}],
},
setUpTimeDialog: false,
multipleSelection: [],
}
},
components: {
'guava': httpVueLoader('/components/plugins/Guava.vue'),
},
methods: {
handleSelectionChange(val) {
this.multipleSelection = val
},
doConfirmSetUpCourse() {
const courseTableData = this.formData.notApplyTimeList
/*if (courseTableData.length === 0) {
this.$message.warning("请选择禁用时间")
return
}*/
if (courseTableData && courseTableData.length > 0) {
const valid = courseTableData.every(v => v.startTime && v.endTime && (v.startTime < v.endTime))
if (!valid) {
this.$message.warning("时间不完整或者有误")
return
}
this.setUpTimeDialog = false
}
},
removeSetUpTableRow(row, index) {
this.formData.notApplyTimeList.splice(index, 1)
const courseDateArray = this.formData.notApplyTimeList.map(v => moment(v.date).format("YYYY-MM-DD"))
const scdList = this.formData.setUpDate
this.formData.setUpDate = scdList.filter(v => {
return courseDateArray.includes(moment(v).format("YYYY-MM-DD"))
})
},
oneKeySetStartEndTime() {
if(this.multipleSelection.length === 0) {
this.$message.warning('请选择需要一键设置的时间')
return
}
const { startTime, endTime } = this.timeOneKeySet
this.formData.notApplyTimeList.forEach(v => {
const o = this.multipleSelection.find(o => o.date === v.date && o.startTime === v.startTime && o.endTime === v.endTime)
if(o) {
this.$set(v, "startTime", startTime)
this.$set(v, "endTime", endTime)
}
})
this.$forceUpdate()
},
setUpDateChange(val) {
if (!val) {
this.formData.notApplyTimeList = []
return
}
if (this.formData.notApplyTimeList === undefined) {
this.$set(this.formData, "notApplyTimeList", [])
}
const ctList = new Set(this.formData.notApplyTimeList.map(v => moment(v.date).format("YYYY-MM-DD")))
val.forEach(v => {
if (!ctList.has(v)) {
this.formData.notApplyTimeList.push({
date: v, time: null
})
}
})
this.formData.notApplyTimeList = this.formData.notApplyTimeList.filter(v => {
return val.includes(moment(v.date).format("YYYY-MM-DD"))
})
this.formData.notApplyTimeList.sort((a, b) => {
return Date.parse(a["date"]) - Date.parse(b["date"])
})
},
openSetUpTime() {
if(this.formData.notApplyTimeList) {
this.$set(this.formData, 'setUpDate', this.formData.notApplyTimeList.map(o => o.date))
}
this.setUpTimeDialog = true
},
doDelete(row) {
this.$confirm('此操作将删除【' + row.name + '】场地的所有信息!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: (a, b) => {
if ("confirm" === a) {
$.post(location.href + "/doDelete", {id: row.id}, (data) => {
if (data.code === 0) {
this.$message.success(data.msg)
this.pageData();
} else {
this.$message.error(data.msg)
}
}, "json");
}
}
});
},
async operation() {
let method = this.formData.id ? "/doEdit" : "/doAdd"
this.subDis = true
this.$refs["addForm"].validate(async (valid) => {
if (valid) {
const loading = this.$loading({
lock: true,
text: '正在提交...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
const {code, data, msg} = await $.post(location.href + method, {data: JSON.stringify(this.formData)})
if (code === 0) {
this.pageData()
this.$message.success(msg);
this.$refs.guava.index()
} else {
this.$message.error(msg);
}
loading.close()
this.subDis = false
}
});
},
async findOneSite(id) {
const {data} = await $.get("/platform/activity/site/mange/findOneSite", {id: id})
return data
},
openView(row) {
this.$refs.guava.view()
},
async openEdit(id) {
this.formData = await this.findOneSite(id)
if(!this.formData.notApplyTimeList) {
this.$set(this.formData, 'notApplyTimeList', [])
}
this.$refs.guava.edit()
},
openAdd() {
this.formData = {
state: true,
open_hours: [{}],
create_username: '${@shiro.getPrincipalProperty("username")}',
create_time: moment().format('YYYY-MM-DD'),
sexLimit: '0',
notApplyTimeList: [],
reserveTarget: 2,
filterHolidays: false,
}
this.$refs.guava.edit()
if (this.$refs['addForm']) {
this.$refs['addForm'].resetFields()
}
},
doSearch() {
this.tabKey = new Date().getTime()
this.pageForm.pageNumber = 1
this.pageData()
},
pageOrder(column) {
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange(val) {
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange(val) {
this.pageForm.pageSize = val;
this.pageData();
},
pageData() {
sublime.showLoadingbar();
this.tableLoading = true
$.post(location.href + "/pageData", this.pageForm, (res) => {
const {code, data, msg} = res
sublime.closeLoadingbar();
this.tableLoading = false
if (code === 0) {
for (let i = 0; i < data.list.length; i++) {
data.list[i].open_hours = site.reverseRankingDate(data.list[i].open_hours)
}
this.tableData = data.list;
this.pageForm.totalCount = data.totalCount;
} else {
this.$message.error(msg);
}
}, "json");
}
},
async created() {
this.pageData();
this.activityTypeList = await activityUtil.getAllType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,198 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<div class="btn-group tool-button">
<el-date-picker
v-model="pageForm.month" clearable value-format="yyyy-MM"
type="month"
placeholder="选择月">
</el-date-picker>
</div>
<div class="btn-group tool-button">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
style="width: 110px;">
<el-option label="场地名称" value="asi.name"></el-option>
<el-option label="预约人" value="asr.reserve_person"></el-option>
</el-select>
</el-input>
</div>
<div class="btn-group tool-button">
<el-select v-model="pageForm.siteType" placeholder="场地类型" clearable
style="width: 200px;">
<el-option v-for="item in activityTypeList" :label="item.text" :value="item.value"></el-option>
</el-select>
</div>
<div class="btn-group tool-button">
<el-button type="primary" icon="el-icon-search" @click="doSearch"></el-button>
</div>
</el-card>
<el-card shadow="never" class="mt20">
<el-table :data="tableData" row-key="id" @sort-change="pageOrder"
v-loading="tableLoading">
<el-table-column align="center" header-align="center" label="序号" type="index">
<template scope="scope">
<span>{{scope.$index+(pageForm.pageNumber - 1) * pageForm.pageSize + 1}} </span>
</template>
</el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center" label="场地名称"
prop="site_name"></el-table-column>
<el-table-column align="center" sortable header-align="center" label="预约人"
prop="reserve_person"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center" label="预约单位"
prop="reserve_person_unit"></el-table-column>
<el-table-column align="center" header-align="center" label="联系方式"
prop="reserve_person_phone"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="预约日期"
prop="concat_day"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="开始时间"
prop="start_time">
<template slot-scope="{row}">
<span>{{row.start_time}}</span>
</template>
</el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="结束时间"
prop="end_time">
<template slot-scope="{row}">
<span>{{row.end_time}}</span>
</template>
</el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="反馈意见"
prop="back_option">
<template slot-scope="{row}">
<span v-if="row.reserve_person_id === userid || role == true">{{row.back_option}}</span>
</template>
</el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="预约事由"
prop="reserve_cause"></el-table-column>
<el-table-column align="center" show-overflow-tooltip="true" header-align="center" sortable
label="预约状态" prop="state_name">
<template slot-scope="{row}">
<!--<span :style="'color:'+row.state_color">{{row.state_name}}</span>-->
<span v-if="[0].includes(row.stateaudittype)"
style="color: #e6a23c">{{row.state_name}}</span>
<span v-if="row.stateaudittype==3" style="color: #67c23a">{{row.state_name}}</span>
<span v-if="row.stateaudittype==1" style="color: #f56c6c">{{row.state_name}}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="250px">
<template slot-scope="{row}">
<el-button type="primary" @click="openView(row.id)" size="mini">查看</el-button>
<el-button type="danger" @click="doDelete(row.id)"
size="mini">删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
</el-card>
</template>
<template #view>
<reserve-info ref="reserve"></reserve-info>
</template>
</guava>
</div>
<script>
<!--# include("/platform/activity/includeJs/activityUtil.js"){} #-->
const activityUtil = new typeUtil()
const vue = new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return {
userid: "${@shiro.getPrincipalProperty('id')}",
role: "${@shiro.hasRole('sysadmin')||@shiro.hasRole('xghng')||@shiro.hasRole('A06')}",
activityTypeList: [],
reserveViewData: {},
tableLoading: false,
tableData: [],
pageForm: {
searchName: "asi.name",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: "",
isAudit: false,
},
}
},
components: {
'reserve-info': httpVueLoader('/components/activity/site/ReserveInfo.vue?v=' + new Date().getTime()),
},
methods: {
openView(id) {
this.$refs.guava.view()
this.$refs.reserve.openView(id)
},
pageData() {
sublime.showLoadingbar();
this.tableLoading = true
let form = clone(this.pageForm)
if (form.isAudit === null) {
delete form.isAudit
}
$.post(location.href + "/pageData", form, (res) => {
const {code, data, msg} = res
sublime.closeLoadingbar();
this.tableLoading = false
if (code == 0) {
this.tableData = data.list;
this.pageForm.totalCount = data.totalCount;
} else {
this.$message.error(msg);
}
}, "json");
},
async doDelete(id) {
const confirm = await this.$confirm("您确定要删除此预约吗?", '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm !== 'confirm') return
const resp = await $.post('/platform/activity/site/reserve/doDelete', {id, op: 1})
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.doSearch()
} else {
this.notifyWarning(resp.msg)
}
}
},
async created() {
this.activityTypeList = await activityUtil.getAllType()
this.pageData();
},
})
</script>
<!--#
}
#-->
@@ -0,0 +1,782 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style xmlns="">
.text {
font-size: 14px;
}
.e-item {
margin-bottom: 10px;
}
.el-divider--horizontal {
margin: 5px 0;
}
.v-tab .el-card__header {
padding: 10px 15px;
font-weight: bold;
}
.reserve_btn {
font-size: 16px;
float: right;
padding: 3px 0
}
.is-selected {
color: #1989FA;
}
.div-Calendar {
box-sizing: border-box;
height: 100%;
}
.el-carousel__button {
background-color: #c0c4cc;
}
.el-carousel__container {
height: 240px;
}
.el-button--mini.is-circle {
padding: 5px;
font-size: 1px;
}
.slider {
position: relative;
}
.cover {
position: absolute;
height: 6px;
background-color: #409EFF;
margin: 16px 0;
z-index: 999;
}
.cover2 {
position: absolute;
height: 6px;
background-color: #E4E7ED;
margin: 16px 0;
z-index: 1000;
}
.el-slider__marks-text {
margin-top: 10px !important;
}
.el-slider__stop {
z-index: 1001;
}
.el-slider__bar {
z-index: 1000;
}
.el-slider__marks-text {
min-width: 40px !important;
}
.el-slider__button-wrapper {
display: none !important;
}
.el-calendar-day:has(.not-allow-day) {
background-color: #F5F5F5;
}
.div-Calendar p {
margin: 0;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<div class="btn-group tool-button">
<el-select v-model="pageForm.siteType" placeholder="场地类型" clearable
style="width: 200px;">
<el-option v-for="item in activityTypeList" :label="item.text" :value="item.value"></el-option>
</el-select>
</div>
<div class="btn-group tool-button">
<el-date-picker
v-model="pageForm.time" placeholder="选择月"
type="month" value-format="yyyy-MM">
</el-date-picker>
</div>
<div class="btn-group tool-button">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
style="width: 105px;">
<el-option label="场地名称" value="asi.name"></el-option>
<el-option label="预约人" value="asr.reserve_person"></el-option>
</el-select>
</el-input>
</div>
<div class="btn-group tool-button">
<el-button type="primary" icon="el-icon-search" @click="doSearch"></el-button>
</div>
</el-card>
<el-row>
<el-carousel :interval="5000" arrow="always" style="margin: 10px auto;">
<el-carousel-item v-for="index in Math.ceil(siteList.length/4)" :key="index">
<el-row :gutter="20">
<el-col v-for="item in siteList.slice((index-1)*4,index*4)" :span="6">
<el-card class="box-card" style="border-radius: 10px">
<div slot="header" class="clearfix" style="font-size: 16px;padding: 5px 0">
<span>{{item.name}}</span>
<el-button @click.stop="onReserve(item)" class="reserve_btn" type="text">预约</el-button>
</div>
<div @click="siteChange(item.id)">
<div class="text e-item">
<span style="color: gray">场地地址:</span>
{{item.address}}
</div>
<div class="text e-item">
<span style="color: gray">&ensp;&ensp;人:</span>
{{(item.unitname ? item.unitname : '') + ' ' + item.contact_person}}
</div>
<div class="text e-item">
<span style="color: gray">联系方式:</span>
{{item.contact_phone}}
</div>
<!--<div class="text e-item">
<span style="color: gray">面向对象:</span>
<span v-if="item.reservetarget == 1">分工会</span>
<span v-if="item.reservetarget == 2">个人</span>
<span v-if="item.reservetarget == 3">集体</span>
</div>-->
<div class="text e-item">
<span style="color: gray">场地介绍:</span>
<el-link @click="viewIntroduce(item)" type="primary" style="position: relative; top: -2px">点击查看</el-link>
</div>
</div>
</el-card>
</el-col>
</el-row>
</el-carousel-item>
</el-carousel>
<el-row class="v-tab">
<el-card class="box-card" shadow="never">
<vi-title2 title="预约列表">
<template #func>
<el-button style="float: right" type="primary" @click="siteChange()" size="mini">全部</el-button>
</template>
</vi-title2>
<el-table :data="tableData" row-key="id"
v-loading="tableLoading">
<el-table-column align="center" header-align="center" label="序号" type="index">
<template scope="scope">
<span>{{scope.$index+(pageForm.pageNumber - 1) * pageForm.pageSize + 1}} </span>
</template>
</el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="场地名称"
prop="site_name"></el-table-column>
<el-table-column align="center" sortable header-align="center" label="预约人"
prop="reserve_person"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="所属单位"
prop="reserve_person_unit"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="预约日期"
prop="concat_day"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="开始时间"
prop="start_time">
<template slot-scope="{row}">
<span>{{row.start_time}}</span>
</template>
</el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="结束时间"
prop="end_time">
<template slot-scope="{row}">
<span>{{row.end_time}}</span>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="联系方式"
prop="reserve_person_phone"></el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="预约事由"
prop="reserve_cause"></el-table-column>
<el-table-column align="center" show-overflow-tooltip="true" header-align="center" sortable
label="预约状态" prop="state_name">
<template slot-scope="{row}">
<!--<span :style="'color:'+row.state_color">{{row.state_name}}</span>-->
<span v-if="[0].includes(row.stateaudittype)" style="color: #e6a23c">{{row.state_name}}</span>
<span v-if="row.stateaudittype==3" style="color: #67c23a">{{row.state_name}}</span>
<span v-if="row.stateaudittype==1" style="color: #f56c6c">{{row.state_name}}</span>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" fixed="right"
width="200px">
<template scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'view',data:scope.row}">
查看
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.reserve_person_id === '${@shiro.getPrincipalProperty('id')}'"
:command="{type:'backOption',data:scope.row}">
反馈意见
</el-dropdown-item>
<!--# if(@shiro.hasRole('sysadmin')){ #-->
<el-dropdown-item
:command="{type:'delete',data:scope.row}">
删除
</el-dropdown-item>
<!--# } #-->
<el-dropdown-item
v-if="scope.row.reserve_person_id === '${@shiro.getPrincipalProperty('id')}'"
:command="{type:'cancel',data:scope.row}">
撤销预约
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
</el-card>
</el-row>
</el-row>
</template>
<template #edit>
<el-row :gutter="20">
<el-col :span="12" :offset="6" style="text-align: center">
<div style="font-size: large;color: #303133">
您正在预约【<span style="color: #409EFF">{{infoViewData.name}}</span>】活动场地
</div>
</el-col>
</el-row>
<el-calendar v-model="reserve_time">
<template slot="dateCell" slot-scope="{date, data}">
<div :class="getDayClass(data)" @click="pushDay(data)">
<p :style="dayArray.includes(data.day) ? 'color: #246fb4' : ''">
{{ data.day.split('-').slice(1).join('-') }} {{ dayArray.includes(data.day) ? '✔️' : ''}}
</p>
<div v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('xghng')||@shiro.hasRole('A06')}"
v-for="item in reserveViewData">
<div v-if="data.day.toString() == item.reserve_day"
:style="{backgroundColor:([0].includes(item.stateaudittype)?'#FAECD9':item.reserve_state==30?'#E0F4D9':'#FEE2E2')}">
<el-row style="line-height: 20px">
<el-col :span="4" style="font-size: 10px">
<span v-if="[0].includes(item.stateaudittype)">待审</span>
<span v-if="item.stateaudittype==3">通过</span>
<span v-if="item.stateaudittype==1">拒绝</span>
</el-col>
<el-col :span="20" style="font-size: 10px">
<span>
<b>{{item.reserve_person}}</b>{{item.start_time}}-{{item.end_time}}
</span>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
</el-calendar>
<div style="text-align: right">
<el-button @click="openAdd" type="primary">下一步</el-button>
</div>
</template>
<template #view>
<reserve-info ref="reserve"></reserve-info>
</template>
</guava>
<el-dialog title="新增场地预约" class="dia" :close-on-click-modal="false" @close="diaClose" top="2%"
:visible.sync="addDialogVisible" custom-class="ViewDialogClass" width="50%">
<vi-title :title="'您已选择的预约日期为:'+ dayArray.toString()" style="margin-left: 48px"></vi-title>
<el-form :model="formData" ref="addForm" :rules="formRules" label-position="right"
label-width="100px">
<el-form-item label="预约人" prop="reserve_person">
<el-select disabled allow-create style="width: 100%" v-model="formData.reserve_person" filterable remote
value-key="id" reserve-keyword placeholder="请输入关键词" @change="userChange"
:remote-method="remoteMethod" :loading="loading">
<el-option v-for="item in restaurants" :key="item.id" :label="item.username"
:value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-input readonly v-model="formData.sex" maxlength="100"
placeholder="请输入性别"></el-input>
</el-form-item>
<el-form-item label="工号" prop="loginname">
<el-input readonly v-model="formData.loginname" maxlength="100"
placeholder="请输入工号"></el-input>
</el-form-item>
<el-form-item label="所属单位" prop="reserve_person_unit">
<el-input readonly v-model="formData.reserve_person_unit" maxlength="100"
placeholder="请输入所属单位"></el-input>
</el-form-item>
<el-form-item label="联系电话" prop="reserve_person_phone">
<el-input maxlength="11" placeholder="请输入联系电话"
v-model="formData.reserve_person_phone"></el-input>
</el-form-item>
<el-form-item label="预约时间" prop="time">
<el-select v-model="formData.time" style="width: 100%" filterable @change="timeChange"
placeholder="请选择预约时间">
<el-option v-for="item in allowTimeList"
:disabled="item.disabled === true"
:value="item.start_time + '-' + item.end_time">
<template #default>
<span v-if="item.disabled === true">
{{ item.start_time + ' - ' + item.end_time + '' + item.tooltip + '' }}
</span>
<span v-else>{{ item.start_time + ' - ' + item.end_time }}</span>
</template>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预约人数" prop="joinCount">
<el-input-number
:disabled="infoViewData.reservetarget === 1 || infoViewData.reservetarget === 3"
v-model="formData.joinCount"
:min="1" :max="9999"
label="请输入预约人数"
style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item label="预约事由" prop="reserve_cause">
<el-input maxlength="1000" placeholder="请输入预约事由" autosize v-model="formData.reserve_cause"
type="textarea" :autosize="{ minRows: 4, maxRows: 6}"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeAdd">取 消</el-button>
<el-button type="primary" :disabled="subDis" @click="doAdd">确 定</el-button>
</span>
</el-dialog>
<el-dialog :visible.sync="drawer" title="场地介绍" width="40%" top="3%">
<div v-html="viewData.introduce"></div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="drawer = false">确定</el-button>
</span>
</el-dialog>
</div>
<script>
<!--# include("/platform/activity/includeJs/activityUtil.js"){} #-->
const activityUtil = new typeUtil()
const vue = new Vue({
el: '#app',
data() {
return {
activityTypeList: [],
drawer: false,
siteList: [],
restaurants: [],
reserve_time: '',
infoViewData: {},
reserveViewData: {},
tableLoading: false,
addDialogVisible: false,
subDis: false,
loading: false,
tableData: [],
formData: {
start_time: '',
end_time: '',
reserve_person_phone: '',
reserve_cause: '',
time: '',
sex: "${@shiro.getPrincipalProperty('sex')}",
loginname: "${@shiro.getPrincipalProperty('loginname')}"
},
pageForm: {
searchName: "asr.reserve_person",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: "",
time: ''
},
userid: '',
formRules: {
reserve_person: [{required: true, message: '请填写预约人', trigger: ['blur', 'change']}],
reserve_person_unit: [{required: true, message: '请填写单位', trigger: ['blur', 'change']}],
reserve_person_phone: [{required: true, message: '请填写联系电话', trigger: ['blur', 'change']}],
start_time: [{required: true, message: '请选择预约时间', trigger: ['blur', 'change']}],
time: [{required: true, message: '请选择预约时间', trigger: ['blur', 'change']}],
joinCount: [{required: true, message: '请输入预约人数', trigger: ['blur', 'change']}],
/*reserve_cause: [{required: true, message: '请选择预约事由', trigger: ['blur', 'change']}],*/
},
dayArray: [],
allowDayList: [],
allowTimeList: [],
viewData: {},
reverseData: {},
}
},
components: {
'guava': httpVueLoader('/components/plugins/Guava.vue'),
'reserve-info': httpVueLoader('/components/activity/site/ReserveInfo.vue?v=' + new Date().getTime()),
},
methods: {
viewIntroduce(item) {
this.viewData = item
this.drawer = true
},
diaClose() {
this.formData.time = ''
this.formData.start_time = ''
this.formData.end_time = ''
},
timeChange(o) {
this.formData.start_time = o.split('-')[0]
this.formData.end_time = o.split('-')[1]
},
dropdownCommand(command) {
const {type, data} = command
if (type === 'view') {
this.userid = data.reserve_person_id;
this.openView(data)
} else if (type === 'delete') {
this.doDelete(data.id, 1)
} else if (type === 'cancel') {
this.doDelete(data.id, 2)
} else if (type === 'backOption') {
this.backOption(data)
}
},
backOption(row) {
this.$prompt('请填写反馈意见', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValidator: (value) => {
if (value === null) {
return '反馈意见不能为空'
}
}
}).then(async ({value}) => {
const res = await $.post('/mobile/activity/site/info/backOption', {
id: row.id,
option: value
})
if (res.code === 0) {
await this.doSearch()
this.$message.success(res.msg)
} else {
this.$message.warning(res.msg)
}
}).catch(() => {
});
},
async siteChange(id) {
this.pageForm.siteId = id
this.pageData()
},
userChange(data) {
this.$set(this.formData, "reserve_person", data.username ? data.username : data)
this.$set(this.formData, "reserve_person_unit", data.unit_name)
this.$set(this.formData, "reserve_person_phone", data.mobile ? data.mobile : '')
},
remoteMethod(keywords) {
$.post(location.href + "/findUser", {keywords: keywords}, (res) => {
const {code, data, msg} = res
if (code === 0) {
this.restaurants = data;
} else {
this.restaurants = [];
this.$message.error(msg);
}
this.loading = false;
})
},
closeAdd() {
this.addDialogVisible = false
this.formData.end_time = ''
},
onReserve(data) {
if(data.reservetarget === 1 && "${@shiro.hasAnyRoles('gh01', 'H04')}" === 'false' && "${@shiro.hasRole('sysadmin')}" === 'false') {
this.$message.warning('该场地只能分工会预约')
return
}
this.reverseData = data
this.dayArray = []
this.getAllowTime()
if (data.sexlimit === 1 || data.sexlimit === 2) {
const sex = data.sexlimit === 1 ? '男' : '女'
if ("${@shiro.getPrincipalProperty('sex')}" === sex) {
this.openReserve(data)
} else {
this.$message.warning('抱歉,该场地仅限' + sex + '性会员预约')
}
} else {
this.openReserve(data)
}
},
getDayClass(data) {
const d = new Date(data.day).getDay()
let classStr = 'div-Calendar'
if(this.allowDayList.length > 0 && !this.allowDayList.includes(data.day)) {
classStr += ' not-allow-day';
}
if(this.infoViewData.openweektime) {
const openWeedTime = JSON.parse(this.infoViewData.openweektime)
if(!openWeedTime.includes(d)) {
classStr += ' not-allow-day';
}
}
if(this.infoViewData.notapplytimelist) {
const notApplyTimeList = JSON.parse(this.infoViewData.notapplytimelist)
if(notApplyTimeList.includes(data.day)) {
classStr += ' not-allow-day';
}
}
if(moment(data.day).isBefore(moment().startOf('day'))) {
classStr += ' not-allow-day';
}
return classStr
},
async pushDay(data) {
this.$nextTick(async () => {
await this.getAllowTime(moment(data.day).year(), moment(data.day).month() + 1)
})
if (this.allowDayList.length > 0 && !this.allowDayList.includes(data.day)) {
this.$message.warning(data.day + "不能预约")
return
}
if (this.infoViewData.notapplytimelist) {
const notApplyTimeList = JSON.parse(this.infoViewData.notapplytimelist)
if (notApplyTimeList.includes(data.day)) {
this.$message.warning(data.day + "不能预约")
return
}
}
if (data.day < moment(new Date()).format('YYYY-MM-DD')) {
this.$message.warning('你选择的日期已过')
return
}
if (this.dayArray.includes(data.day)) {
this.dayArray.splice(this.dayArray.indexOf(data.day), 1)
} else {
this.dayArray = []
this.dayArray.push(data.day)
this.dayArray.sort()
}
},
async openAdd() {
//查询用户点击的这一天已经被预约的时间段
if (this.dayArray && this.dayArray.length === 0) {
this.$message.warning('请选择预约日期')
return
}
this.$set(this.formData, "reserve_person", '${@shiro.getPrincipalProperty("username")}')
this.$set(this.formData, "reserve_person_unit", '${@shiro.getPrincipalProperty("unit").getName()}')
this.$set(this.formData, "reserve_person_phone", '${@shiro.getPrincipalProperty("mobile")}')
if (this.$refs['addForm']) {
this.$refs['addForm'].resetFields()
}
if(this.infoViewData.reservetarget === 1 || this.infoViewData.reservetarget === 3) {
this.$set(this.formData, "joinCount", this.infoViewData.maxnum)
} else {
this.$set(this.formData, "joinCount", 1)
}
this.allowTimeList = await this.getTimesByDay()
this.addDialogVisible = true
},
async doDelete(id, op) {
if (op === 2) {
const res = await $.post(location.href + "/isCanRollBack", {id: id});
if (res === true) {
this.$message.warning('此预约状态下不能进行撤回操作')
return
}
}
let text = op === 1 ? '删除' : '撤销'
this.$confirm("您确定要" + text + "此预约吗?", '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: (a, b) => {
if ("confirm" === a) {
$.post(location.href + "/doDelete", {id, op}, (data) => {
if (data.code === 0) {
this.$message.success(data.msg)
this.pageData();
} else {
this.$message.warning(data.msg)
}
}, "json");
}
}
});
},
async doAdd() {
if (!this.formData.time) {
this.$message.warning('未选择预约时间')
return
}
const s = this.formData.time.split('-')[0]
const e = this.formData.time.split('-')[1]
if (moment().unix() >= moment(this.dayArray[0] + ' ' + e + ':00').unix()) {
this.$message.warning('您预约的时间段已过')
return
}
this.$refs["addForm"].validate(async (valid) => {
if (valid) {
this.subDis = true
const loading = this.$loading({
lock: true,
text: '正在提交...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
const {code, msg} = await $.post(location.href + "/doAdd", {
data: JSON.stringify(this.formData),
days: JSON.stringify(this.dayArray)
})
if (code === 0) {
this.addDialogVisible = false
this.$message.success(msg);
this.pageData()
this.$refs.guava.index()
} else {
this.$message.warning(msg)
}
loading.close()
this.subDis = false
}
});
},
openView(row) {
this.$refs.guava.view()
const role = "${@shiro.hasRole('sysadmin')||@shiro.hasRole('xghng')||@shiro.hasRole('A06')}"
this.$refs.reserve.role = role
const backOptionShow = "${@shiro.getPrincipalProperty('id')}" === this.userid
this.$refs.reserve.backOptionShow = (role || backOptionShow)
this.$refs.reserve.openView(row.id)
},
async openReserve(data) {
this.reserveViewData = await this.findReserveInfo(data.id)
/*this.reserveViewData.forEach(item => {
item.index = 0
})*/
this.formData.site_id = data.id
this.infoViewData = data
this.$refs.guava.edit()
},
async doSearch() {
this.pageForm.pageNumber = 1
this.pageData()
this.siteList = await this.findAllOpenSite()
},
pageOrder(column) {
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange(val) {
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange(val) {
this.pageForm.pageSize = val;
this.pageData();
},
pageData() {
sublime.showLoadingbar();
this.tableLoading = true
$.post(location.href + "/pageData", this.pageForm, (res) => {
const {code, data, msg} = res
sublime.closeLoadingbar();
this.tableLoading = false
if (code === 0) {
this.tableData = data.list;
this.pageForm.totalCount = data.totalCount;
} else {
this.$message.error(msg);
}
}, "json");
},
async findReserveInfo(siteId) {
const {data} = await $.get("/platform/activity/site/reserve/findReserveInfo", {siteId})
return data;
},
async findAllOpenSite(siteId) {
const {data} = await $.get("/platform/activity/site/reserve/findAllOpenSite", {
time: this.pageForm.time,
siteId: siteId,
siteType: this.pageForm.siteType,
})
return data
},
async getAllowTime(year = null, month = null) {
const titleText = $('.el-calendar__title').text().trim().replaceAll(' ', '')
const m = moment(titleText, "YYYY年M月")
const { data } = await $.get("/platform/activity/site/reserve/getAllowTime", {
siteId: this.reverseData.id,
year: year != null ? year : m.year(),
month: month != null ? month : m.month() + 1,
})
this.allowDayList = data
},
async getTimesByDay() {
const { data } = await $.get("/platform/activity/site/reserve/getTimesByDay", {
siteId: this.reverseData.id,
day: moment(this.reserve_time).format('YYYY-MM-DD'),
})
return data
}
},
async created() {
this.activityTypeList = await activityUtil.getAllType()
this.siteList = await this.findAllOpenSite()
await this.getAllowTime()
this.pageData()
this.$nextTick(() => {
// 点击前一个月
let prevBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(1)"
);
prevBtn.addEventListener("click", e => {
this.getAllowTime()
})
//点击下一个月
let nextBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(3)"
);
nextBtn.addEventListener("click", () => {
this.getAllowTime()
});
//点击今天
let todayBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(2)"
);
todayBtn.addEventListener("click", () => {
this.getAllowTime()
});
})
},
})
</script>
<!--#
}
#-->
@@ -0,0 +1,357 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<div class="btn-group tool-button">
<el-date-picker
v-model="pageForm.month" clearable value-format="yyyy-MM"
type="month"
placeholder="选择月">
</el-date-picker>
</div>
<div class="btn-group tool-button">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
style="width: 110px;">
<el-option label="场地名称" value="asi.name"></el-option>
<el-option label="预约人" value="asr.reserve_person"></el-option>
</el-select>
</el-input>
</div>
<div class="btn-group tool-button">
<el-select v-model="pageForm.siteType" placeholder="场地类型" clearable
style="width: 200px;">
<el-option v-for="item in activityTypeList" :label="item.text" :value="item.value"></el-option>
</el-select>
</div>
<div class="btn-group tool-button">
<el-button type="primary" icon="el-icon-search" @click="doSearch"></el-button>
</div>
<div class="pull-right offscreen-right mt5">
<el-radio-group v-model="pageForm.isAudit" @change="doSearch">
<el-radio-button :label="null">全部</el-radio-button>
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</div>
</el-card>
<el-card shadow="never" class="mt20">
<div style="text-align: right" v-if="pageForm.isAudit === false">
<el-button @click="doReview('many', false)" type="danger" size="mini">一键驳回</el-button>
<el-button @click="doReview('many', true)" type="primary" size="mini">一键通过</el-button>
</div>
<el-table :data="tableData" row-key="id" @sort-change="pageOrder"
@selection-change="handleSelectionChange"
v-loading="tableLoading">
<el-table-column v-if="pageForm.isAudit === false" type="selection" width="55"
:reserve-selection="true"></el-table-column>
<el-table-column align="center" header-align="center" label="序号" type="index">
<template scope="scope">
<span>{{scope.$index+(pageForm.pageNumber - 1) * pageForm.pageSize + 1}} </span>
</template>
</el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center" label="场地名称"
prop="site_name"></el-table-column>
<el-table-column align="center" sortable header-align="center" label="预约人"
prop="reserve_person"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center" label="所属单位"
prop="reserve_person_unit"></el-table-column>
<el-table-column align="center" header-align="center" label="联系方式"
prop="reserve_person_phone"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="预约天数"
prop="days"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="预约日期"
prop="concat_day"></el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="开始时间"
prop="start_time">
<template slot-scope="{row}">
<span>{{row.start_time}}</span>
</template>
</el-table-column>
<el-table-column align="center" sortable show-overflow-tooltip header-align="center"
label="结束时间"
prop="end_time">
<template slot-scope="{row}">
<span>{{row.end_time}}</span>
</template>
</el-table-column>
<el-table-column align="center" show-overflow-tooltip header-align="center" label="预约事由"
prop="reserve_cause"></el-table-column>
<el-table-column align="center" show-overflow-tooltip="true" header-align="center"
label="预约状态" prop="state_name">
<template slot-scope="{row}">
<!--<span :style="'color:'+row.state_color">{{row.state_name}}</span>-->
<span v-if="[0].includes(row.stateaudittype)"
style="color: #e6a23c">{{row.state_name}}</span>
<span v-if="row.stateaudittype==3" style="color: #67c23a">{{row.state_name}}</span>
<span v-if="row.stateaudittype==1" style="color: #f56c6c">{{row.state_name}}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="250px">
<template slot-scope="{row}">
<el-button type="primary" @click="userid = row.reserve_person_id; openView(row.id)" size="mini">查看
</el-button>
<el-button v-if="pageForm.isAudit === false" type="primary" @click="openReview2(row)"
size="mini">审核
</el-button>
<!--# if(@shiro.hasRole('sysadmin')||@shiro.hasRole('xgh02')){ #-->
<!--<el-button v-if="pageForm.isAudit === false" type="primary" @click="openReview(row)"
size="mini">
批示
</el-button>-->
<!--# } #-->
</template>
</el-table-column>
</el-table>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
</el-card>
</template>
<template #edit style="padding: 0 10%">
<reserve-info v-if="pageForm.isAudit === false" ref="reserve3" btn>
<template #btn>
<el-row style="margin: 40px 0;text-align: right">
<el-button type="danger" @click="doReview('one', false)">驳回</el-button>
<el-button type="primary" @click="doReview('one', true)">通过</el-button>
</el-row>
</template>
</reserve-info>
<!--<reserve-info v-if="pageForm.isAudit === false" ref="reserve2" label="主席批示" handle>
<template #handle>
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="100px">
<el-form-item label="批示信息&emsp;" label-width="135px" class="view-header">
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item prop="xld_id" label="批示人">
<el-input value="${@shiro.getPrincipalProperty('username')}"
disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="time" label="批示时间">
<el-input v-model="formData.time" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="opinion" label="批示意见">
<el-input type="textarea" v-model="formData.opinion" rows="6" maxlength="500"
placeholder="请填写您的批示意见"></el-input>
</el-form-item>
</el-form>
<el-row style="margin: 40px 0;text-align: right">
<el-button type="primary" @click="doInstructions">确 定</el-button>
</el-row>
</template>
</reserve-info>-->
</template>
<template #view>
<reserve-info ref="reserve"></reserve-info>
</template>
</guava>
</div>
<script>
<!--# include("/platform/activity/includeJs/activityUtil.js"){} #-->
const activityUtil = new typeUtil()
const vue = new Vue({
el: '#app',
data() {
return {
selectTable: [],
activityTypeList: [],
reserveViewData: {},
tableLoading: false,
tableData: [],
formData: {},
pageForm: {
searchName: "asi.name",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: "",
isAudit: false,
},
formRules: {
opinion: [{required: true, message: '请填写批示意见', trigger: ['blur', 'change']}],
},
userid: '',
}
},
components: {
'guava': httpVueLoader('/components/plugins/Guava.vue'),
'reserve-info': httpVueLoader('/components/activity/site/ReserveInfo.vue?v=' + new Date().getTime()),
},
methods: {
openView(id) {
this.$refs.guava.view()
const role = "${@shiro.hasRole('sysadmin')||@shiro.hasRole('xghng')||@shiro.hasRole('A06')}"
this.$refs.reserve.role = role
const backOptionShow = "${@shiro.getPrincipalProperty('id')}" === this.userid
this.$refs.reserve.backOptionShow = (role || backOptionShow)
this.$refs.reserve.openView(id)
},
handleSelectionChange(val) {
this.selectTable = val;
},
openReview(row) {
this.reserveViewData = row
this.formData = {
id: row.id,
state: 30,
time: moment().format('YYYY-MM-DD')
}
if (this.$refs['addForm']) {
this.$refs['addForm'].resetFields()
}
this.$nextTick(() => {
this.$refs.guava.edit()
this.$refs.reserve2.openView(row.id)
})
},
openReview2(row) {
this.reserveViewData = row
this.formData = {
id: row.id,
}
this.$nextTick(() => {
this.$refs.guava.edit()
const role = "${@shiro.hasRole('sysadmin')||@shiro.hasRole('xghng')||@shiro.hasRole('A06')}"
this.$refs.reserve3.role = role
const backOptionShow = "${@shiro.getPrincipalProperty('id')}" === row.reserve_person_id
this.$refs.reserve3.backOptionShow = (role || backOptionShow)
this.$refs.reserve3.openView(row.id)
})
},
doReview(type, state) {
let that = this
if (type === 'many' && this.selectTable.length === 0) {
this.$notify.warning({title: '警告', message: '一键审核请先在多选框中进行选择!'});
return
}
let typeText = type === 'many' ? '一键' : ''
let typeT = type === 'many' ? '这些' : '此'
let text = state ? '通过' : '驳回'
this.$prompt('您确定要' + typeText + text + typeT + '预约吗?', '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPlaceholder: '请在此填写审核意见',
inputType: 'textarea',
inputValidator: (value) => {
if (value === null) {
return '审核意见不能为空'
}
}
}).then(async ({value}) => {
let id = ''
if (type === 'one') {
id = JSON.stringify([that.formData.id])
} else {
id = JSON.stringify(this.selectTable.map(x => x.id))
}
$.post(location.href + "/doReview", {
id: id,
auditOpinion: value,
isPass: state
}, (res) => {
if (res.code === 0) {
that.$message.success(res.msg)
this.selectTable = []
that.pageData();
that.$refs.guava.index()
}
}, "json");
}).catch(() => {
});
},
doInstructions() {
$.post(location.href + "/doReview", this.formData, (res) => {
if (res.code == 0) {
this.$message.success(res.msg)
this.pageData();
this.$refs.guava.index()
}
}, "json");
},
doSearch() {
this.pageForm.pageNumber = 1
this.pageData()
},
pageOrder(column) {
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange(val) {
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange(val) {
this.pageForm.pageSize = val;
this.pageData();
},
pageData() {
sublime.showLoadingbar();
this.tableLoading = true
let form = clone(this.pageForm)
if (form.isAudit === null) {
delete form.isAudit
}
$.post(location.href + "/pageData", form, (res) => {
const {code, data, msg} = res
sublime.closeLoadingbar();
this.tableLoading = false
if (code == 0) {
this.tableData = data.list;
this.pageForm.totalCount = data.totalCount;
} else {
this.$message.error(msg);
}
}, "json");
}
},
async created() {
this.activityTypeList = await activityUtil.getAllType()
this.pageData();
},
})
</script>
<!--#
}
#-->
@@ -0,0 +1,416 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.audit-userids-select .el-select__tags {
flex-wrap: unset;
overflow: auto;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<div class="search">
<div class="search-item">
<div class="search-item-label">类型名称:</div>
<div class="search-item-option">
<el-input placeholder="请输入类型名称" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch" style="width: 100%">
</el-input>
</div>
</div>
<div class="search-query">
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
</div>
</div>
</el-card>
<el-card shadow="never" class="mt20">
<table-tool :app="this" label="类型列表">
<template #func>
<el-button @click="openAdd" size="small" type="primary">新增类型</el-button>
</template>
</table-tool>
<el-table :data="tableData" :size="tableSize"
@sort-change="pageOrder" class="vi-table"
row-key="id" style="width: 100%">
<el-table-column align="center" header-align="center" label="序号" type="index"
width="80px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
align="center"
header-align="center"
min-width="50"
show-overflow-tooltip
v-for="column in tableColumns"
>
</el-table-column>
<el-table-column label="操作">
<template scope="{row}">
<el-button @click="openEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button @click="doDelete(row.id)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<el-form :model="formData" :rules="formRules" label-width="80px" ref="form">
<el-form-item label="类型名称" prop="meetingTypeName">
<el-input v-model="formData.meetingTypeName" placeholder="请输入类型名称"></el-input>
</el-form-item>
<el-form-item label="模块名称" prop="moduleName">
<el-input v-model="formData.moduleName" placeholder="请输入模块名称"></el-input>
</el-form-item>
<el-form-item label="序号" prop="sortNum">
<el-input-number :max="tableData.length + 1" :min="1" :precision="0"
v-model="formData.sortNum"></el-input-number>
</el-form-item>
<el-table :data="formData.auditStateList">
<el-table-column label="节点ID" prop="stateId" width="100px">
<template slot-scope="scope">
<el-input readonly v-model="scope.row.stateId"></el-input>
</template>
</el-table-column>
<el-table-column label="审核节点名称" prop="stateName">
<template slot-scope="scope">
<el-input v-model="scope.row.stateName" placeholder="请输入审核节点名称"></el-input>
</template>
</el-table-column>
<el-table-column label="审核人" prop="selectUserId">
<template slot-scope="scope">
<el-select :remote-method="userRemoteMethod" class="audit-userids-select" filterable
multiple placeholder="请输入姓名或工号查找"
remote style="width: 100%"
v-model="scope.row.selectUserId">
<el-option :key="item.id" :label="item.username + '' + item.loginname + ''"
:value="item.id"
v-for="item in userList"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="筛选审核人" width="100px">
<template scope="scope">
<el-button @click="openUserSelect(scope.$index)" type="text">筛选用户</el-button>
</template>
</el-table-column>
<el-table-column label="通过下个节点" pro="afterPassStateId" width="120px">
<template slot-scope="scope">
<el-select v-model="scope.row.afterPassStateId">
<el-option :label="item"
:value="item"
v-for="item in stateIdList"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="拒绝下个节点" pro="afterRejectStateId" width="120px">
<template slot-scope="scope">
<el-select v-model="scope.row.afterRejectStateId">
<el-option :label="item"
:value="item"
v-for="item in stateIdList"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="审核类型" prop="stateAuditType" width="150px">
<template slot-scope="scope">
<el-select v-model="scope.row.stateAuditType">
<el-option :label="item.desc"
:value="item.value"
v-for="item in stateAuditTypeList"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column width="100px">
<template scope="scope" slot="header">
<el-button @click="addState"
icon="el-icon-circle-plus-outline"
size="mini"
type="primary"></el-button>
</template>
<template scope="scope">
<el-button @click="formData.auditStateList.splice(scope.$index, 1)"
icon="el-icon-delete"
size="mini"
type="danger"></el-button>
</template>
</el-table-column>
</el-table>
</el-form>
<el-row class="mt10" justify="end" type="flex">
<el-button @click="$refs.guava.index()">取消</el-button>
<el-button @click="doConfirm" type="primary">确定</el-button>
</el-row>
</template>
</guava>
<condition :fields="fields"
:show_filter_result="true"
@confirm="cndConfirm"
ref="cnd"
v-model="cnd"></condition>
</div>
<script>
<!--# include("/platform/activity/includeJs/activityUtil.js"){} #-->
const activityUtil = new typeUtil()
const vue = new Vue({
el: '#app',
mixins: [initTableMixins],
components: {
'condition': httpVueLoader('/components/plugins/ConditionStructure.vue?v=1.0.0'),
},
data() {
return {
tableColumns: [
{prop: 'meetingTypeName', label: '类型名称'},
{prop: 'moduleName', label: '模块名称'},
{prop: 'sortNum', label: '排序编号'}],
stateAuditTypeList: [],
formData: {
auditStateList: []
},
formRules: {
meetingTypeName: [{required: true, message: '请输入类型名称', trigger: ['blur', 'change']}],
moduleName: [{required: true, message: '请输入模块名称,英文命名', trigger: ['blur', 'change']}],
sortNum: [{required: true, message: '请输入排序编号', trigger: ['blur', 'change']}]
},
userList: [],
maxStateId: 0,
userSelectDialogVisible: false,
cnd: {},
fields: [],
nodeIndex: null
}
},
watch: {
async 'formData.auditStateList'(val) {
const {id} = this.formData
for (let i = 0; i < val.length; i++) {
let item = val[i]
if (id) {
if (item.isAddRow) {
//当前行是新增的第几行
const addIndex = i + 1 - val.filter(v => !v.isAddRow).length
const stateId = val[0].stateId + i * 10
const licitStateCode = await this.checkStateId(stateId, addIndex)
item['stateId'] = licitStateCode
}
} else {
item['stateId'] = this.maxStateId + (i + 1) * 10
}
}
// this.$set(this.formData,'auditStateList',val)
}
},
computed: {
dialogTitle() {
if (this.formData.id) {
return '编辑'
}
return '新增'
},
stateIdList() {
return this.formData.auditStateList.map(v => v.stateId)
}
},
methods: {
async checkStateId(stateId, stateIndex) {
const resp = await $.get(loc() + '/checkStateId', {stateId, stateIndex})
if (resp.code === 0) {
return resp.data
} else {
this.notifyError(resp.msg)
}
},
addState() {
this.formData.auditStateList.push({
stateId: this.maxStateId,
stateName: null,
selectUserId: [],
auditStateUserList: [],
afterPassStateId: null,
afterRejectStateId: null,
isAddRow: true
})
},
async pageData() {
const res = await $.post(loc() + '/pageData', this.pageForm)
if (res.code === 0) {
res.data.list.forEach(v => {
v.auditStateList.forEach(x => {
if (x.matchCnd) x.matchCnd = JSON.parse(x.matchCnd)
})
})
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount;
}
},
openAdd() {
this.formData = {
meetingName: null,
sortNum: this.tableData.length + 1,
auditStateList: [{}]
}
this.$refs.guava.edit()
},
async doConfirm() {
try {
const valid = await this.$refs['form'].validate()
if (valid) {
this.formData.auditStateList.forEach(v => {
v['auditStateUserList'] = v.selectUserId.map(x => {
return {userId: x}
})
v['matchCnd'] = JSON.stringify(v['matchCnd'])
})
const resp = await $.post(loc() + '/doHandle', {data: JSON.stringify(this.formData)})
if (resp.code === 0) {
this.$refs.guava.index()
this.notifySuccess(resp.msg)
await this.pageData()
} else {
this.notifyError(resp.msg)
}
}
} catch (e) {
}
},
async openEdit(row) {
const d = clone(row)
let u = []
d.auditStateList.forEach(v => {
v['selectUserId'] = v.auditStateUserList.map(x => x.userId)
u = u.concat(v['selectUserId'])
})
this.userList = await queryUserByIds(u)
this.formData = d
this.$refs.guava.edit()
},
async doDelete(id) {
try {
const confirm = await this.$confirm('您确定要删除吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm === 'confirm') {
const resp = await $.post(loc() + '/delete/' + id)
if (resp.code === 0) {
this.notifySuccess(resp.msg)
await this.pageData()
} else {
this.notifyWarning(resp.msg)
}
}
} catch (e) {
console.log(e)
}
},
async userRemoteMethod(query) {
if (query) {
this.userList = await searchUser(query)
}
},
openUserSelect(node_index) {
this.nodeIndex = node_index
const node = this.formData.auditStateList[node_index]
if (node.matchCnd) {
this.cnd = node.matchCnd
console.log('......')
} else {
this.cnd = {method: "AND", conditions: [{}]}
}
this.$refs.cnd.open(false)
},
async initCndFields() {
this.cnd = {
method: "AND",
conditions: [{}],
}
/*const meet_data = await getOpenMeeting()
const meet_options = meet_data.map(v => {
return {"label": v.jdhallname, "value": v.id}
})
this.fields.push(
{label: '教代会', value: 'jdhid', type: "select", options: meet_options}
)*/
const {data: role_data} = await $.get('/platform/sys/role/getAllRoles')
const role_options = role_data.map(v => {
return {"label": v.name, "value": v.id}
})
this.fields.push(
{label: '角色', value: 'roleId', type: "select", options: role_options}
)
this.fields.push(
{label: '姓名', value: 'username', options: null}
)
},
async cndConfirm(val) {
if (val) {
const matchCnd = clone(val)
if (matchCnd.conditions && matchCnd.conditions.length > 0) {
this.formData.auditStateList[this.nodeIndex].matchCnd = matchCnd
const resp = await $.post('/platform/userFilter/findUserByCnd', {cnd: JSON.stringify(matchCnd)})
if (resp.code === 0) {
if (resp.data) {
const d = this.formData.auditStateList[this.nodeIndex]
d.matchCnd = matchCnd
d.selectUserId = [...new Set(d.selectUserId.concat(resp.data.map(v => v.id)))]
this.$set(this.formData.auditStateList, this.nodeIndex, d)
let u = []
this.formData.auditStateList.forEach(v => {
u = u.concat(v.selectUserId.map(x => x))
})
this.userList = await queryUserByIds([...new Set(u)])
}
}
console.log(resp)
}
}
}
},
async created() {
this.pageData()
this.initCndFields()
this.maxStateId = await activityUtil.findMaxStateId()
this.stateAuditTypeList = await getEnumOptions('AuditTypeEnum')
}
})
</script>
<!--#
}
#-->