This commit is contained in:
@jyuhsin
2025-09-12 10:46:44 +08:00
parent 0777e2f4f7
commit 33e106c019
36 changed files with 2661 additions and 71 deletions
@@ -9,27 +9,25 @@ layout("/layouts/platform.html"){
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
placeholder="选择年度"
type="year"
style="width: 100%"
v-model="pageForm.year"
value-format="yyyy"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="活动状态:" style="width: 340px">
<el-radio-group v-model="pageForm.activityType" @change="doSearch">
<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>
</search-item>
</search>
</el-card>
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
placeholder="选择年度"
type="year"
style="width: 100%"
v-model="pageForm.year"
value-format="yyyy"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="活动状态:" style="width: 340px">
<el-radio-group v-model="pageForm.activityType" @change="doSearch">
<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>
</search-item>
</search>
</el-card>
<el-card class="mt10" shadow="never">
@@ -257,43 +257,43 @@ const info = {
},
style: /*language=CSS*/ `
.glow-box {
::v-deep .glow-box {
min-height: calc(100vh - 56px - 40px - 50px - 80px);
max-height: calc(100vh - 56px - 40px - 50px - 80px);
overflow-y: auto;
background: #F0F2F5;
}
img {
::v-deep img {
width: 100%;
height: 180px;
}
.title {
::v-deep .title {
background: white;
height: 20px;
}
.query-row {
::v-deep .query-row {
display: flex;
align-items: center;
padding: 6px 0;
}
.query-row:not(:last-child) {
::v-deep .query-row:not(:last-child) {
border-bottom: 1px dashed rgb(230, 230, 230);
}
.query-row > .query-title {
::v-deep .query-row > .query-title {
width: 100px;
max-width: 100px;
min-width: 100px;
overflow: hidden;
}
.query-row > .query-content {
::v-deep .query-row > .query-content {
min-width: 200px;
overflow: hidden;
}
.query-row > .query-content > .el-tag {
::v-deep .query-row > .query-content > .el-tag {
margin-bottom: 5px;
margin-top: 5px;
}
@media screen and (max-width: 992px) {
::v-deep @media screen and (max-width: 992px) {
.query-row:nth-child(4) .query-content .el-col:not(:last-child) {
margin-bottom: 5px;
}
@@ -0,0 +1,96 @@
const leaveInfo = {
template: /*language=HTML*/ `
<div>
<div class="process-title">
申请信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div>
<el-descriptions :column="2" border>
<el-descriptions-item label="请假人姓名">{{ viewData.userName }}</el-descriptions-item>
<el-descriptions-item label="请假人工号">{{ viewData.loginName }}</el-descriptions-item>
<el-descriptions-item label="所属单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="会议名称">{{ viewData.periodName }}</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ viewData.startTime }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ viewData.endTime }}</el-descriptions-item>
<el-descriptions-item label="请假事由">{{ viewData.leaveReason }}</el-descriptions-item>
<el-descriptions-item label="所属会议">{{ viewData.meetingName }}</el-descriptions-item>
<el-descriptions-item label="会议类型">{{ viewData.typeName }}</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
}}({{task.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{
task.taskFormData.opinion }}
</el-descriptions-item>
</el-descriptions>
</div>
</template>
<slot></slot>
<snaker-chart ref="snakerChartRef"></snaker-chart>
</div>
`,
store,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
visible: false,
viewData: {},
doneTasks: [],
row: null
}
},
methods: {
onOpen(row) {
row.leaveReason = JSON.parse(row.instanceVariable).f_data.leaveReason || ''
this.row = row
this.visible = true
this.viewData = clone(row)
this.getDoneTasks()
},
// 获取已办任务审批记录
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
// 查看流程图
openChart(){
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId, this.row.instanceId)
}
},
style: /*language=CSS*/ `
.el-descriptions-item__label {
width: 200px;
min-width: 200px;
max-width: 200px;
}
.el-tabs__header {
margin: 0;
}
`
}
@@ -0,0 +1,199 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
@change="doSearch"
style="width: 100%"
></el-date-picker>
</search-item>
<search-item label="名称/地点:">
<el-input placeholder="请输入名称或地点查询" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="会议类型:">
<el-select v-model="pageForm.type" @change="doSearch" style="width: 100%"
placeholder="请选择慰问类型" filterable clearable>
<el-option v-for="item in typeOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'leaveReason'">
{{ JSON.parse(row.instanceVariable).f_data.leaveReason || '' }}
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="onAudit(row)" size="mini" type="primary">审核</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<leave-info ref="leaveInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row>
</div>
</leave-info>
</template>
</guava>
</div>
<script>
<!--#include('../common/leaveInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"leave-info": leaveInfo
},
data() {
return {
pageForm: {
approval: false
},
typeOptions: [],
tableColumns: [
{prop: 'periodName', label: '会议名称'},
{prop: 'startTime', label: '开始时间'},
{prop: 'endTime', label: '结束时间'},
{prop: 'userName', label: '请假人'},
{prop: 'leaveReason', label: '请假事由'},
{prop: 'meetingName', label: '所属会议'},
{prop: 'typeName', label: '会议类型'},
{prop: 'curTaskName', label: '当前节点'},
{prop: 'instanceState', label: '流程状态'},
],
formData: {},
showApprovalForm: false
}
},
methods: {
onView(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = false
this.$refs.leaveInfoRef.onOpen(row)
})
},
onAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.leaveInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
queryMeetingType() {
this.$axios.post('/platform/meeting/type/queryMeetingType')
.then((resp) => {
this.typeOptions = resp.data
})
},
},
async created() {
this.queryMeetingType()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,183 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
@change="doSearch"
style="width: 100%"
></el-date-picker>
</search-item>
<search-item label="名称/地点:">
<el-input placeholder="请输入名称或地点查询" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="会议类型:">
<el-select v-model="pageForm.type" @change="doSearch" style="width: 100%"
placeholder="请选择慰问类型" filterable clearable>
<el-option v-for="item in typeOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表"></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'leaveReason'">
{{ JSON.parse(row.instanceVariable).f_data.leaveReason || '' }}
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button v-if="row.canRevoke" size="mini" type="danger" @click="onRevoke(row)">撤回</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onDelete(row.id)" size="mini" type="danger">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<leave-info ref="leaveInfoRef"></leave-info>
</template>
</guava>
</div>
<script>
<!--#include('../common/leaveInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"leave-info": leaveInfo
},
data() {
return {
typeOptions: [],
tableColumns: [
{prop: 'periodName', label: '会议名称'},
{prop: 'startTime', label: '开始时间'},
{prop: 'endTime', label: '结束时间'},
{prop: 'userName', label: '请假人'},
{prop: 'leaveReason', label: '请假事由'},
{prop: 'meetingName', label: '所属会议'},
{prop: 'typeName', label: '会议类型'},
{prop: 'taskName', label: '当前节点'},
{prop: 'instanceState', label: '流程状态'},
],
}
},
methods: {
onView(row) {
this.$refs.guava.view(()=>{
this.$refs.leaveInfoRef.onOpen(row)
})
},
onEdit(row) {
if(!row.canLeave) {
this.$message.warning('该场次不能请假')
return
}
this.$prompt('请输入请假事由', '温馨提醒', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
inputValidator: (value) => {
if (!value) {
return '请假事由不能为空';
}
return true;
}
}).then(({ value }) => {
this.$axios.post("/platform/meeting/mine/submitAgain", {
id: row.id,
leaveReason: value,
taskId: row.taskId
})
.then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.pageData()
} else {
this.$message.error(resp.msg)
}
})
}).catch(() => {})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/meeting/leave/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
queryMeetingType() {
this.$axios.post('/platform/meeting/type/queryMeetingType')
.then((resp) => {
this.typeOptions = resp.data
})
},
},
created() {
this.queryMeetingType()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,205 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.timePeriod_card {
border-top: 5px solid #106898;
border-left: 1px solid #ebeef5;
border-bottom: 1px solid #ebeef5;
border-right: 1px solid #ebeef5;
}
.timePeriod_card .el-form-item {
margin-bottom: 0 !important;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
@change="doSearch"
style="width: 100%"
></el-date-picker>
</search-item>
<search-item label="名称/地点:">
<el-input placeholder="请输入名称或地点查询" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="会议类型:">
<el-select v-model="pageForm.type" @change="doSearch" style="width: 100%"
placeholder="请选择慰问类型" filterable clearable>
<el-option v-for="item in typeOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt20">
<table-tool label="会议列表"></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize" ref="meetingTable">
<el-table-column type="expand">
<template slot-scope="{ row }">
<el-row :gutter="20" justify="start" style="flex-wrap: wrap" type="flex"
v-if="row.timePeriods && row.timePeriods.length > 0">
<el-col :xl="5" v-for="tp,index in row.timePeriods" :key="index">
<el-card class="mb10 timePeriod_card" shadow="hover">
<el-form label-width="80px">
<el-form-item label="名称">{{tp.periodName}}</el-form-item>
<el-form-item label="会议时间">{{tp.startTime}}</el-form-item>
<el-form-item label="结束时间">{{tp.endTime}}</el-form-item>
</el-form>
<el-row justify="space-around" style="border-top: 1px solid #ebeef5;padding: 10px 0 0 0" type="flex">
<el-button v-if="tp.joinStatus === true" @click="onLeave(tp)" size="medium" type="text">请假</el-button>
<el-button v-if="tp.joinStatus === false" size="medium" type="text" disabled>您已请假</el-button>
<el-button v-if="tp.signStatus === false" @click="onSign(tp)" size="medium" type="text">签到</el-button>
<el-button v-if="tp.signStatus === true" size="medium" type="text" disabled>您已签到</el-button>
</el-row>
</el-card>
</el-col>
</el-row>
<el-row v-else>
<el-empty description="没有时间段"></el-empty>
</el-row>
</template>
</el-table-column>
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'createdAt'">
<span>{{ $moment(row.createdAt).format('YYYY-MM-DD') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="230">
<template v-slot="{ row }">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="toggleRowTimePeriod(row)" size="mini" type="primary">展开</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #view>
<meeting-info ref="infoRef"></meeting-info>
</template>
</guava>
</div>
<script>
<!--#include('../common/meetingInfo.js'){}#-->
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"meeting-info": meetingInfo,
},
data() {
return {
tableColumns: [
{prop: 'name', label: '会议名称'},
{prop: 'typeName', label: '会议类型'},
{prop: 'address', label: '会议地点'},
{prop: 'createdAt', label: '创建时间'},
],
typeOptions: [],
}
},
methods: {
onLeave(row) {
if(!row.canLeave) {
this.$message.warning('该场次不能请假')
return
}
this.$prompt('请输入请假事由', '温馨提醒', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
inputValidator: (value) => {
if (!value) {
return '请假事由不能为空';
}
return true;
}
}).then(({ value }) => {
this.$axios.post("/platform/meeting/mine/leave", { periodId: row.id, leaveReason: value })
.then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.pageData()
} else {
this.$message.error(resp.msg)
}
})
}).catch(() => {})
},
onSign(row) {
this.$confirm('您确定要签到吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
this.$axios.post("/platform/meeting/mine/sign", { periodId: row.id })
.then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.pageData()
} else {
this.$message.error(resp.msg)
}
})
})
},
toggleRowTimePeriod(row) {
this.$refs['meetingTable'].toggleRowExpansion(row)
},
onView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
queryMeetingType() {
this.$axios.post('/platform/meeting/type/queryMeetingType')
.then((resp) => {
this.typeOptions = resp.data
})
},
pageData() {
this.$axios.post(loc() + "/pageData", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
},
async created() {
this.queryMeetingType()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -106,10 +106,10 @@ layout("/layouts/platform.html"){
<table-tool label="会议列表"></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize" ref="meetingTable">
<el-table-column type="expand">
<template slot-scope="scope">
<template slot-scope="{ row }">
<el-row :gutter="20" justify="start" style="flex-wrap: wrap" type="flex"
v-if="scope.row.timePeriods && scope.row.timePeriods.length > 0">
<el-col :xl="5" v-for="tp,index in scope.row.timePeriods" :key="index">
v-if="row.timePeriods && row.timePeriods.length > 0">
<el-col :xl="5" v-for="tp,index in row.timePeriods" :key="index">
<el-card class="mb10 timePeriod_card" shadow="hover">
<el-form label-width="80px">
<el-form-item label="名称">{{tp.periodName}}</el-form-item>
@@ -120,7 +120,7 @@ layout("/layouts/platform.html"){
<el-button @click="exportSignature(tp.id)" size="medium" type="text">
导出签字表
</el-button>
<el-button @click="openOnline(tp.id,scope.row.id)" size="medium" type="text">
<el-button @click="openOnline(tp.id, row.id)" size="medium" type="text">
扫描二维码
</el-button>
</el-row>
@@ -0,0 +1,199 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
@change="doSearch"
style="width: 100%"
></el-date-picker>
</search-item>
<search-item label="名称/地点:">
<el-input placeholder="请输入名称或地点查询" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="会议类型:">
<el-select v-model="pageForm.type" @change="doSearch" style="width: 100%"
placeholder="请选择慰问类型" filterable clearable>
<el-option v-for="item in typeOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'leaveReason'">
{{ JSON.parse(row.instanceVariable).f_data.leaveReason || '' }}
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="onAudit(row)" size="mini" type="primary">审核</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<leave-info ref="leaveInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row>
</div>
</leave-info>
</template>
</guava>
</div>
<script>
<!--#include('../common/leaveInfo.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"leave-info": leaveInfo
},
data() {
return {
pageForm: {
approval: false
},
typeOptions: [],
tableColumns: [
{prop: 'periodName', label: '会议名称'},
{prop: 'startTime', label: '开始时间'},
{prop: 'endTime', label: '结束时间'},
{prop: 'userName', label: '请假人'},
{prop: 'leaveReason', label: '请假事由'},
{prop: 'meetingName', label: '所属会议'},
{prop: 'typeName', label: '会议类型'},
{prop: 'curTaskName', label: '当前节点'},
{prop: 'instanceState', label: '流程状态'},
],
formData: {},
showApprovalForm: false
}
},
methods: {
onView(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = false
this.$refs.leaveInfoRef.onOpen(row)
})
},
onAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.leaveInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
queryMeetingType() {
this.$axios.post('/platform/meeting/type/queryMeetingType')
.then((resp) => {
this.typeOptions = resp.data
})
},
},
async created() {
this.queryMeetingType()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -232,13 +232,8 @@ const apply = {
},
// 查询哪些天是开放的
async queryAllowDay() {
const days = Array.from(document.querySelectorAll('.div-Calendar'))
.map(el => el.getAttribute('data-day'))
.sort()
const {data} = await this.$axios.post("/platform/site/apply/queryAllowDay", {
siteId: this.row.id,
startTime: days[0],
endTime: days[days.length - 1],
siteId: this.row.id
})
this.allowDayList = data
},
@@ -9,10 +9,15 @@ const basicForm = {
</el-form-item>
</el-col>
<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 label="创建时间" prop="createTime">
<el-input disabled type="text" v-model="formData.createTime" maxlength="20" placeholder="请输入创建时间"></el-input>
</el-form-item>
</el-col>
</el-col>-->
</el-row>
<el-row :gutter="20" type="flex">
@@ -43,8 +48,8 @@ const basicForm = {
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item prop="sortNum" label="排序编号">
<el-input v-model="formData.sortNum" placeholder="请输入排序编号" type="number"></el-input>
<el-form-item label="开放天数" prop="openDayNum">
<el-input v-model="formData.openDayNum" placeholder="请输入开放天数" type="number"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -283,6 +288,7 @@ const basicForm = {
createUserId: this.$store.state.user.id,
createTime: this.$moment().format('YYYY-MM-DD'),
openHours: [],
openDayNum: 7,
},
formRules: {
createUserName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
@@ -298,6 +304,7 @@ const basicForm = {
sexLimit: [{required: true, message: '必填', trigger: ['blur', 'change']}],
state: [{required: true, message: '必填', trigger: ['blur', 'change']}],
filterHolidays: [{required: true, message: '必填', trigger: ['blur', 'change']}],
openDayNum: [{required: true, message: '必填', trigger: ['blur', 'change']}],
},
setUpTimeDialog: false,
timeOneKeySet: {
@@ -89,13 +89,13 @@ layout("/layouts/platform_h5.html"){
onEdit(row) {
this.$pjaxReplace("/platform/club/join/apply/h5?taskId=" + (row.startTaskId || "") + "&bizId=" + row.id)
},
onDelete(id) {
onDelete(row) {
this.$dialog.confirm({
title: "提示",
message: "确定要删除此申请吗?"
})
.then(() => {
this.$axios.post("/platform/club/join/mine/delete", { id: id }).then((res) => {
this.$axios.post("/platform/club/join/mine/delete", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()
@@ -0,0 +1,77 @@
const leaveInfo = {
template:
/*language=HTML*/
`
<van-action-sheet v-model="visible" title="查看详情">
<div class="detail-container">
<van-cell-group title="基本信息">
<van-cell title="请假人姓名">{{ viewData.userName }}</van-cell>
<van-cell title="请假人工号">{{ viewData.loginName }}</van-cell>
<van-cell title="所属单位">{{ viewData.unitName }}</van-cell>
<van-cell title="所属工会">{{ viewData.unionName }}</van-cell>
<van-cell title="会议名称">{{ viewData.periodName }}</van-cell>
<van-cell title="开始时间">{{ viewData.startTime }}</van-cell>
<van-cell title="结束时间">{{ viewData.endTime }}</van-cell>
<van-cell title="请假事由" class="direction-column-cell">{{ viewData.leaveReason }}</van-cell>
<van-cell title="所属会议">{{ viewData.meetingName }}</van-cell>
<van-cell title="会议类型">{{ viewData.typeName }}</van-cell>
</van-cell-group>
<template v-for="task in doneTasks">
<van-cell-group :title="task.displayName" v-if="task.ext.isFirstTaskNode">
<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>
<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="办理意见" v-if="!task.ext.isFirstTaskNode" class="direction-column-cell">
<div v-html="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,
}
},
methods: {
onOpen(row) {
row.leaveReason = JSON.parse(row.instanceVariable).f_data.leaveReason || ''
this.row = row
this.visible = true
this.viewData = clone(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
}
})
},
},
style: /*language=CSS*/ `
`
}
@@ -0,0 +1,96 @@
const meetingInfo = {
template: /*language=HTML*/ `
<div>
<van-action-sheet v-model="visible" title="会议信息">
<div class="detail-container">
<van-cell-group title="基本信息">
<van-cell title="会议名称">{{ viewData.name }}</van-cell>
<van-cell title="会议地点">{{ viewData.address }}</van-cell>
<van-cell title="会议类型">{{ viewData.typeName }}</van-cell>
<van-cell title="会议描述" class="direction-column-cell">
<span v-html="viewData.description"></span>
</van-cell>
</van-cell-group>
<van-cell-group title="场次信息" v-if="viewData.timePeriods && viewData.timePeriods.length > 0">
<table class="table-class">
<thead>
<tr>
<th>场次名称</th>
<th>开始时间</th>
<th>结束时间</th>
<th>是否可以请假</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in viewData.timePeriods" :key="index">
<td>{{ item.periodName }}</td>
<td>{{ item.startTime }}</td>
<td>{{ item.endTime }}</td>
<td>{{ item.canLeave ? '是' : '否' }}</td>
</tr>
</tbody>
</table>
</van-cell-group>
<van-cell-group title="会议参与人员" v-if="viewData.users && viewData.users.length > 0">
<table class="table-class">
<thead>
<tr>
<th>工号</th>
<th>姓名</th>
<th>性别</th>
<th>所属单位</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in viewData.users" :key="index">
<td>{{ item.loginName }}</td>
<td>{{ item.userName }}</td>
<td>{{ item.sex }}</td>
<td>{{ item.unitName }}</td>
</tr>
</tbody>
</table>
</van-cell-group>
</div>
</van-action-sheet>
</div>
`,
data() {
return {
viewData: {},
visible: false
}
},
methods: {
onOpen(row) {
this.$axios.post('/platform/meeting/manage/info', {id: row.id}).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
this.visible = true
},
},
style: /*language=CSS*/ `
::v-deep .table-class{
width: 100%;
border-radius: 5px;
overflow: hidden;
line-height: 1.5rem;
font-size: 13px;
table-layout: fixed;
border-collapse: collapse;
}
::v-deep .table-class th {
background-color: #f2f2f2;
border: 1px solid #dddddd;
}
::v-deep .table-class tr {
text-align: center;
border-bottom: 1px solid #dddddd;
}
::v-deep .table-class td {
border: 1px solid #dddddd;
}
`
}
@@ -0,0 +1,190 @@
<!--#
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">
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
@change="doSearch"></van-dropdown-item>
</van-dropdown-menu>
<van-tabs v-model="pageForm.approvalText"
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
<van-tab title="已审核" name="1"></van-tab>
<van-tab title="未审核" name="0"></van-tab>
</van-tabs>
</van-sticky>
<table-list api="/platform/meeting/delegationApproval/pageData" :page_form.sync="pageForm" ref="tableListRef" title="periodName" @ready="onReady">
<template v-slot="{index,row}">
<table-column label="开始时间">{{row.startTime}}</table-column>
<table-column label="结束时间">{{row.endTime}}</table-column>
<table-column label="请假人">{{row.userName}}</table-column>
<table-column label="请假事由">{{JSON.parse(row.instanceVariable).f_data.leaveReason || ''}}</table-column>
<table-column label="所属会议">{{row.meetingName}}</table-column>
<table-column label="会议类型">{{row.typeName}}</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="onApproval(row)">
<i class="fa fa-edit"></i>
<span>审核</span>
</div>
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
<i class="fa fa-reply"></i>
<span>撤回</span>
</div>
</template>
</table-list>
<leave-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="danger" block @click="handleTaskAction(6)">退回</van-button>
<van-button type="danger" block @click="handleTaskAction(20)">不同意</van-button>
<van-button type="primary" block @click="handleTaskAction(1)">同意</van-button>
</div>
</div>
</leave-info>
</div>
<script>
<!--#include('../common/leaveInfo.js'){}#-->
new Vue({
el: "#app",
store,
components: {
'leave-info': leaveInfo,
},
data() {
return {
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
searchKeyword: '',
approvalText: "0",
approval: false,
year: new Date().getFullYear(),
type: null,
},
typeOptions: [],
formData: {},
showApprovalForm: false
}
},
methods: {
async onReady() {
const typeList = await this.queryMeetingType()
this.typeOptions = [
{
text: "全部类型",
value: null
}
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
if (this.typeOptions.length > 0) {
this.pageForm.type = this.typeOptions[0].value
this.doSearch()
}
},
onView(row) {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
},
onApproval(row) {
this.showApprovalForm = true
this.$refs.infoRef.onOpen(row)
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
},
async handleTaskAction(val) {
try {
await this.$refs.formRef.validate();
this.$dialog.confirm({
title: "提示",
message: "您确定要提交吗?"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.infoRef.onClose()
this.$toast.success(res.msg)
this.doSearch()
}
})
}).catch(() => {
})
} catch (error) {
}
},
onRevoke(row){
this.$dialog.confirm({
title: "提示",
message: "您确定要撤回吗?"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()
}
})
})
},
async queryMeetingType() {
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
return res.data
},
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$refs.tableListRef.doSearch()
})
}
},
})
</script>
<!--#
}
#-->
@@ -0,0 +1,197 @@
<!--#
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">
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
<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/meeting/leave/pageData" :page_form.sync="pageForm" ref="tableListRef" title="periodName" @ready="onReady">
<template v-slot="{index,row}">
<table-column label="开始时间">{{row.startTime}}</table-column>
<table-column label="结束时间">{{row.endTime}}</table-column>
<table-column label="请假人">{{row.userName}}</table-column>
<table-column label="请假事由">{{JSON.parse(row.instanceVariable).f_data.leaveReason || ''}}</table-column>
<table-column label="所属会议">{{row.meetingName}}</table-column>
<table-column label="会议类型">{{row.typeName}}</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" @click="onEdit(row)"
v-if="row.taskKey === 'startTask' || !row.instanceId">
<i class="fa fa-edit"></i>
<span>编辑</span>
</div>
<div class="action-btn delete" @click="onRevoke(row)"
v-if="row.canRevoke">
<i class="fa fa-undo"></i>
<span>撤回</span>
</div>
<div class="action-btn delete" @click="onDelete(row)"
v-if="row.taskKey === 'startTask' || !row.instanceId">
<i class="fa fa-trash"></i>
<span>删除</span>
</div>
</template>
</table-list>
<van-dialog v-model="visible" title="请假事由" show-cancel-button
:before-close="handleBeforeClose">
<van-field
style="padding: 20px 16px"
v-model="leaveReason"
label="请假事由"
placeholder="请输入请假事由"
required
rows="1"
autosize
type="textarea"
></van-field>
</van-dialog>
<leave-info ref="infoRef"></leave-info>
</div>
<script>
<!--#include('../common/leaveInfo.js'){}#-->
new Vue({
el: "#app",
store,
components: {
'leave-info': leaveInfo,
},
data() {
return {
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
year: new Date().getFullYear(),
type: null
},
typeOptions: [],
visible: false,
leaveReason: '',
editRow: {},
}
},
methods: {
async onReady() {
const typeList = await this.queryMeetingType()
this.typeOptions = [
{
text: "全部类型",
value: null
}
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
if (this.typeOptions.length > 0) {
this.pageForm.type = this.typeOptions[0].value
this.doSearch()
}
},
handleBeforeClose(action, done) {
if (action === 'confirm') {
if(!this.leaveReason) {
this.$toast('请输入请假事由')
done(false)
} else {
this.$axios.post("/platform/meeting/mine/submitAgain", {
id: this.editRow.id,
leaveReason: this.leaveReason,
taskId: this.editRow.taskId
})
.then((res) => {
done()
this.$toast(res.msg)
if (res.code === 0) {
this.doSearch()
this.reasonVisible = false
}
}).catch(() => { done() })
}
} else {
done()
}
},
onRevoke(row) {
this.$dialog.confirm({
title: "提示",
message: "您确定要撤回吗?"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
if (res.code === 0) {
this.$toast(res.msg)
this.doSearch()
}
})
})
},
onView(row) {
this.$refs.infoRef.onOpen(row)
},
onEdit(row) {
if(!row.canLeave) {
this.$toast.success('该场次不能请假')
return
}
this.editRow = row
this.visible = true
},
onDelete(row) {
this.$dialog.confirm({
title: "提示",
message: "确定要删除此申请吗?"
})
.then(() => {
this.$axios.post("/platform/meeting/leave/delete", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()
} else {
this.$toast.fail(res.msg)
}
})
})
.catch(() => {})
},
async queryMeetingType() {
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
return res.data
},
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$refs.tableListRef.doSearch()
})
}
},
})
</script>
<!--#
}
#-->
@@ -0,0 +1,194 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style scoped>
.sign_button .van-button{
width: 66px;
height: 30px;
font-size: 14px;
border-radius: 6px;
}
</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">
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
<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/meeting/mine/pageData" :page_form.sync="pageForm" ref="tableListRef" title="name" @ready="onReady">
<template v-slot="{index,row}">
<table-column label="会议类型">{{row.typeName}}</table-column>
<table-column label="会议地点">{{row.address}}</table-column>
<table-column label="创建时间">{{row.createTime}}</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" @click="leaveRow = row; leaveVisible = true">
<i class="fa fa-edit"></i>
<span>展开</span>
</div>
</template>
</table-list>
<van-action-sheet title="会议信息" v-model="leaveVisible" cancel-text="取消" close-on-click-action>
<button v-for="(item,index) in leaveRow.timePeriods" type="button" class="van-action-sheet__item">
<div style="display: flex; justify-content: space-between; align-items: center">
<div>
<div class="van-action-sheet__name">{{item.periodName}}</div>
<div class="van-action-sheet__subname">
{{$moment(item.startTime).format('MM-DD HH:mm') + ' 至 ' + $moment(item.endTime).format('MM-DD HH:mm')}}
</div>
</div>
<div class="sign_button">
<van-button v-if="item.joinStatus === true" @click.stop="onLeave(item)" size="mini" type="info">请假</van-button>
<van-button v-if="item.joinStatus === false" size="mini" type="info" disabled>您已请假</van-button>
<van-button v-if="item.signStatus === false" @click.stop="onSign(item)" size="mini" type="info">签到</van-button>
<van-button v-if="item.signStatus === true" size="mini" type="info" disabled>您已签到</van-button>
</div>
</div>
</button>
</van-action-sheet>
<van-dialog v-model="reasonVisible" title="请假事由" show-cancel-button
:before-close="handleBeforeClose">
<van-field
style="padding: 20px 16px"
v-model="leaveReason"
label="请假事由"
placeholder="请输入请假事由"
required
rows="1"
autosize
type="textarea"
></van-field>
</van-dialog>
<meeting-info ref="infoRef"></meeting-info>
</div>
<script>
<!--#include('../common/meetingInfo.js'){}#-->
new Vue({
el: "#app",
store,
components: {
'meeting-info': meetingInfo,
},
data() {
return {
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
year: new Date().getFullYear(),
type: null
},
typeOptions: [],
leaveRow: {},
leaveVisible: false,
reasonVisible: false,
leaveReason: '',
periodRow: {},
}
},
methods: {
async onReady() {
const typeList = await this.queryMeetingType()
this.typeOptions = [
{
text: "全部类型",
value: null
}
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
if (this.typeOptions.length > 0) {
this.pageForm.siteType = this.typeOptions[0].value
this.doSearch()
}
},
handleBeforeClose(action, done) {
if (action === 'confirm') {
if(!this.leaveReason) {
this.$toast('请输入请假事由')
done(false)
} else {
this.$axios.post("/platform/meeting/mine/leave", {
periodId: this.periodRow.id,
leaveReason: this.leaveReason,
})
.then((res) => {
done()
this.$toast(res.msg)
if (res.code === 0) {
this.doSearch()
this.reasonVisible = false
}
}).catch(() => { done() })
}
} else {
done()
}
},
onLeave(row) {
if(!row.canLeave) {
this.$toast('该场次不能请假')
return
}
this.periodRow = row
this.reasonVisible = true
},
onSign(row) {
this.$dialog.confirm({
title: "提示",
message: "您确定要签到吗?"
}).then(() => {
this.$axios.post("/platform/meeting/mine/sign", { periodId: row.id })
.then((res) => {
this.$toast(res.msg)
if (res.code === 0) {
this.doSearch()
this.leaveVisible = false
}
})
})
},
onView(row) {
this.$refs.infoRef.onOpen(row)
},
async queryMeetingType() {
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
return res.data
},
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$refs.tableListRef.doSearch()
})
}
},
})
</script>
<!--#
}
#-->
@@ -0,0 +1,190 @@
<!--#
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">
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
@change="doSearch"></van-dropdown-item>
</van-dropdown-menu>
<van-tabs v-model="pageForm.approvalText"
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
<van-tab title="已审核" name="1"></van-tab>
<van-tab title="未审核" name="0"></van-tab>
</van-tabs>
</van-sticky>
<table-list api="/platform/meeting/schoolUnionApproval/pageData" :page_form.sync="pageForm" ref="tableListRef" title="periodName" @ready="onReady">
<template v-slot="{index,row}">
<table-column label="开始时间">{{row.startTime}}</table-column>
<table-column label="结束时间">{{row.endTime}}</table-column>
<table-column label="请假人">{{row.userName}}</table-column>
<table-column label="请假事由">{{JSON.parse(row.instanceVariable).f_data.leaveReason || ''}}</table-column>
<table-column label="所属会议">{{row.meetingName}}</table-column>
<table-column label="会议类型">{{row.typeName}}</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="onApproval(row)">
<i class="fa fa-edit"></i>
<span>审核</span>
</div>
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
<i class="fa fa-reply"></i>
<span>撤回</span>
</div>
</template>
</table-list>
<leave-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="danger" block @click="handleTaskAction(6)">退回</van-button>
<van-button type="danger" block @click="handleTaskAction(20)">不同意</van-button>
<van-button type="primary" block @click="handleTaskAction(1)">同意</van-button>
</div>
</div>
</leave-info>
</div>
<script>
<!--#include('../common/leaveInfo.js'){}#-->
new Vue({
el: "#app",
store,
components: {
'leave-info': leaveInfo,
},
data() {
return {
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
searchKeyword: '',
approvalText: "0",
approval: false,
year: new Date().getFullYear(),
type: null,
},
typeOptions: [],
formData: {},
showApprovalForm: false
}
},
methods: {
async onReady() {
const typeList = await this.queryMeetingType()
this.typeOptions = [
{
text: "全部类型",
value: null
}
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
if (this.typeOptions.length > 0) {
this.pageForm.type = this.typeOptions[0].value
this.doSearch()
}
},
onView(row) {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
},
onApproval(row) {
this.showApprovalForm = true
this.$refs.infoRef.onOpen(row)
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
},
async handleTaskAction(val) {
try {
await this.$refs.formRef.validate();
this.$dialog.confirm({
title: "提示",
message: "您确定要提交吗?"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.infoRef.onClose()
this.$toast.success(res.msg)
this.doSearch()
}
})
}).catch(() => {
})
} catch (error) {
}
},
onRevoke(row){
this.$dialog.confirm({
title: "提示",
message: "您确定要撤回吗?"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()
}
})
})
},
async queryMeetingType() {
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
return res.data
},
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$refs.tableListRef.doSearch()
})
}
},
})
</script>
<!--#
}
#-->
@@ -15,6 +15,14 @@ const apply = {
</div>
</div>
</div>
<div class="calendar-right">
<van-icon size="16" color="white" name="arrow-down" @click="calendarVisible = true"></van-icon>
<van-calendar class="calendar-popup" v-model="calendarVisible" color="#246fb4" position="top" @confirm="calendarConfirm"
:default-date="new Date(selectDate)"
:formatter="calendarFormatter"
:first-day-of-week="1"
title="选择开始日期"></van-calendar>
</div>
</div>
<div class="container">
@@ -105,10 +113,19 @@ const apply = {
formVisible: false,
formData: {},
calendarVisible: false,
}
},
watch: {
computed: {
calendarFormatter(day) {
return (day) => {
if(!this.allowDayList.includes(this.$moment(day.date).format('YYYY-MM-DD'))) {
day.type = 'disabled'
}
return day
}
}
},
methods: {
async onOpen(row, applyRow = null) {
@@ -141,6 +158,12 @@ const apply = {
await this.queryTimesByDay()
this.setWeekList(this.selectDate)
},
async calendarConfirm(date) {
this.selectDate = this.$moment(date).format('YYYY-MM-DD')
this.setWeekList(date)
await this.queryTimesByDay()
this.calendarVisible = false
},
onApply() {
if(Object.keys(this.selected).length === 0) {
this.$toast('请选择要预约的时间')
@@ -246,12 +269,8 @@ const apply = {
},
// 查询哪些天是开放的
async queryAllowDay() {
const startTime = this.weekList.length === 0 ? this.$moment().format('YYYY-MM-DD') : this.weekList[0].dateStr
const endTime = this.weekList.length === 0 ? this.$moment().add(8, 'd').format('YYYY-MM-DD') : this.weekList[this.weekList.length - 1].dateStr
const {data} = await this.$axios.post("/platform/site/apply/queryAllowDay", {
siteId: this.row.id,
startTime: startTime,
endTime: endTime,
})
this.allowDayList = data
},
@@ -323,5 +342,20 @@ const apply = {
::v-deep table {
border-collapse: collapse;
}
::v-deep .calendar-right {
width: 30px;
max-width: 30px;
text-align: center;
height: 60%;
border-left: 1px solid #fff3f3;
display: flex;
align-items: center;
justify-content: center;
margin-left: 5px;
}
::v-deep .calendar-popup {
top: 46px;
}
`
}
@@ -49,7 +49,7 @@ layout("/layouts/platform_h5.html"){
<script>
<!--#include('../common/siteInfo.js'){}#-->
<!--#include('../common/apply.js'){}#-->
<!--#include('apply.js'){}#-->
new Vue({
el: "#app",
store,
@@ -75,6 +75,17 @@ layout("/layouts/platform_h5.html"){
this.$refs.infoRef.onOpen(row)
},
onApply(row) {
if(row.reserveTarget === 1 && !this.$auth.hasRoleOr('BRANCH_UNION_ADMIN, BRANCH_UNION_CHAIRMAN') && !this.$auth.hasRole('SYSADMIN')) {
this.$message.warning('该场地只能分工会预约')
return
}
if (row.sexLimit === 1 || row.sexLimit === 2) {
const sex = row.sexLimit === 1 ? '男' : '女'
if(!this.$store.state.user.sex.includes(sex)) {
this.$toast('抱歉,该场地仅限' + sex + '性会员预约')
return
}
}
this.$refs.applyRef.onOpen(row)
},
async onReady() {
@@ -62,7 +62,7 @@ layout("/layouts/platform_h5.html"){
</div>
<script>
<!--#include('../common/apply.js'){}#-->
<!--#include('../apply/apply.js'){}#-->
<!--#include('../common/info.js'){}#-->
new Vue({
el: "#app",
@@ -117,13 +117,13 @@ layout("/layouts/platform_h5.html"){
const res = await this.$axios.post('/platform/site/manage/info', { id: row.siteId })
this.$refs.applyRef.onOpen(res.data, row)
},
onDelete(id) {
onDelete(row) {
this.$dialog.confirm({
title: "提示",
message: "确定要删除此申请吗?"
})
.then(() => {
this.$axios.post("/platform/site/mine/delete", { id: id }).then((res) => {
this.$axios.post("/platform/site/mine/delete", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()
@@ -114,13 +114,13 @@ layout("/layouts/platform_h5.html"){
onEdit(row) {
this.$pjaxReplace("/platform/condolence/apply/h5?taskId=" + (row.startTaskId || "") + "&bizId=" + row.id)
},
onDelete(id) {
onDelete(row) {
this.$dialog.confirm({
title: "提示",
message: "确定要删除此申请吗?"
})
.then(() => {
this.$axios.post("/platform/condolence/mine/delete", { id: id }).then((res) => {
this.$axios.post("/platform/condolence/mine/delete", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()