This commit is contained in:
Paidax
2025-09-02 08:46:56 +08:00
parent 1c805dcd51
commit 1531aea1d6
163 changed files with 16426 additions and 6025 deletions
@@ -141,6 +141,7 @@
<file-upload :value.sync="formData.files"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
@@ -188,6 +189,12 @@
handleTaskAction(val) {
this.$refs.formRef.validate((valid) => {
if (valid) {
if (this.formData.planDate && this.formData.planDate.length > 0) {
this.formData.planStartTime = this.formData.planDate[0]
this.formData.planEndTime = this.formData.planDate[1]
}
if (!this.instanceId) {
this.handleApply(val)
} else {
@@ -306,6 +313,7 @@
this.findOne(this.businessId)
} else {
const user = this.$store.state.user
this.$set(this.formData, "userId", user.id)
this.$set(this.formData, "userName", user.username)
this.$set(this.formData, "loginName", user.loginname)
this.$set(this.formData, "mobile", user.mobile)
@@ -1,104 +1,179 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-descriptions-item__label.is-bordered-label {
width: 15% !important;
}
.el-descriptions-item__label {
width: 15% !important;
}
</style>
<div id="app">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<snaker-start slot="header" label="活动申报" define_key="HDSB"></snaker-start>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="2" border>
<el-descriptions-item label="活动名称">
<el-form-item prop="activityName">
<el-input placeholder="请输入内容" style="width: 100%" v-model="formData.activityName">
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动类型">
<el-form-item prop="activityType">
<el-select @change="activityTypeChange" placeholder="请选择活动类型"
style="width: 100%" v-model="formData.activityType">
<el-option
:key="item.name"
:label="item.typeName"
:value="item.name"
v-for="item in activityDeclareReimbursementList">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, CLUB_MANAGER, CLUB_PRESIDENT')">
<search-item label="所属协会">
<el-select clearable filterable placeholder="所属协会"
style="width: 100%;" v-model="pageForm.clubId">
<el-option :label="item.clubName" :value="item.id"
v-for="item in clubs"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="申报记录">
<el-button size="small" type="primary" @click="onApply">活动申报</el-button>
</table-tool>
<el-descriptions-item label="申请人姓名">
<el-form-item prop="userName">
<el-input disabled type="text" v-model="formData.userName"></el-input>
</el-form-item>
</el-descriptions-item>
<template v-if="formData.activityType == 'CLUB'">
<el-descriptions-item label="申请协会">
<el-form-item prop="clubId" label="申请协会">
<el-select v-model="formData.clubId" placeholder="请选择协会"
@change="setDeclareUnitName" style="width: 100%">
<el-option
v-for="item in clubList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
</template>
<template v-else>
<el-descriptions-item label="申请单位">
<el-form-item prop="declareUnitName">
<el-input readonly v-model="formData.declareUnitName" type="text" placeholder="请选择项目类型,自动填充"></el-input>
</el-form-item>
</el-descriptions-item>
</template>
<el-descriptions-item label="联系方式">
<el-form-item prop="mobile">
<el-input type="text" v-model="formData.mobile" placeholder="请输入联系方式" maxlength="11"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="申请时间">
<el-form-item prop="applyTime">
<el-input disabled type="text" v-model="formData.applyTime"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动计划时间">
<el-form-item prop="planDate">
<el-date-picker
start-placeholder="开始日期"
range-separator="-"
end-placeholder="结束日期"
style="width: 100%"
type="daterange"
v-model="formData.planDate"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动人数">
<el-form-item prop="activityNumber">
<el-input-number v-model="formData.activityNumber" placeholder="请输入活动人数"></el-input-number>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动地址" :span="2">
<el-form-item prop="activityAddress">
<el-input maxlength="150" placeholder="请填写活动地址" type="text"
v-model="formData.activityAddress"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动预算费用" :span="2">
<el-form-item prop="budgets">
<el-table :data="formData.budgets" border max-height="500" size="mini" style="width: 95%">
<el-table-column label="序号" sortable type="index" width="100"></el-table-column>
<el-table-column label="费用项目名称" prop="name">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.name'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input v-model="row.name" maxlength="50"
placeholder="请输入费用项目名称"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="预算费用" prop="budgetPrice">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.budgetPrice'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number placeholder="预算费用" v-model="row.budgetPrice" :precision="2"
style="width: 100%" :min="1"></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" width="150px">
<template slot="header" slot-scope="scope">
<el-button @click="formData.budgets.push({})" icon="el-icon-plus" type="primary"
size="mini">添加
</el-button>
</template>
<template slot-scope="scope">
<el-button :disabled="formData.budgets.length==1"
@click="formData.budgets.splice(scope.$index,1)"
size="mini"
icon="el-icon-delete"
type="danger"></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动方案及简介" :span="2">
<el-form-item prop="activityContent">
<text-editor v-model="formData.activityContent"></text-editor>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<el-form-item prop="files">
<file-upload :value.sync="formData.files"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-form-item prop="sign">
<pc-signature v-model="formData.sign"></pc-signature>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="220" fixed="right">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">
查看
</el-button>
<el-button v-if="row.taskKey === 'startTask'" @click="onEdit(row)" size="mini" type="primary">
编辑
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">
撤回
</el-button>
<el-button @click="onDelete(row.id)" size="mini" type="danger">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" class="mt20">
<el-button type="primary" plain @click="onSave">保存</el-button>
<el-button type="primary" @click="onSubmit" v-if="!taskId">提交</el-button>
<el-button type="primary" @click="onFinishTask" v-else>提交1</el-button>
</el-row>
</el-card>
</div>
<script>
@@ -108,90 +183,140 @@ layout("/layouts/platform.html"){
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formData: {
id: GetQueryString("businessId"),
planDate: []
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
units: [],
clubs: []
formRules: {
activityName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
activityType: [{required: true, message: '必填', trigger: ['blur', 'change']}],
fundsUnitName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
declareUnitName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
planDate: [{required: true, message: '必填', trigger: ['blur', 'change']}],
budgets: [{required: true, message: '必填', trigger: ['blur', 'change']}],
clubId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
mobile: [{required: true, message: '必填', trigger: ['blur', 'change']}],
sign: [{required: true, message: '必填', trigger: ['blur', 'change']}],
},
activityDeclareReimbursementList: [],
clubList: [],
}
},
methods: {
onApply() {
window.open("/flow/common/approval/form?defineKey=HDSB")
},
openView(row) {
window.open("/flow/common/approval/form?instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=HDSB")
},
onEdit(row) {
window.open(
"/flow/common/approval/form?taskId=" +
(row.taskId || "") +
"&instanceId=" +
(row.instanceId || "") +
"&businessId=" +
row.id +
"&defineKey=HYRH"
)
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
// 保存
onSave() {
this.$confirm("您确定保存吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((resp) => {
this.$message.success(resp.msg)
this.pageData()
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/activityDeclare/apply/onDelete", { id }).then((res) => {
if (this.formData.planDate && this.formData.planDate.length > 0) {
this.formData.planStartTime = this.formData.planDate[0]
this.formData.planEndTime = this.formData.planDate[1]
}
this.$axios.post('/platform/activityDeclare/apply/save', {data: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.doSearch()
this.$message.success(res.msg)
this.$message.success("保存成功")
window.location.href = '/platform/activityDeclare/mine'
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
// 提交
onSubmit() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
if (this.formData.planDate && this.formData.planDate.length > 0) {
this.formData.planStartTime = this.formData.planDate[0]
this.formData.planEndTime = this.formData.planDate[1]
}
this.$axios.post('/platform/activityDeclare/apply/submit', {
data: JSON.stringify(this.formData)
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/activityDeclare/mine'
}
})
})
},
onFinishTask() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
if (this.formData.planDate && this.formData.planDate.length > 0) {
this.formData.planStartTime = this.formData.planDate[0]
this.formData.planEndTime = this.formData.planDate[1]
}
this.$axios.post('/platform/activityDeclare/apply/submitAgain', {
data: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/activityDeclare/mine'
}
})
})
},
// 设置申报主体名称
setDeclareUnitName(val){
const club = this.clubList.find(v => v.id === val)
this.$set(this.formData, "declareUnitName", club ? club.clubName : null)
},
// 申请类型选中
activityTypeChange(val) {
if (val === "SCHOOL_UNION") {
this.$set(this.formData, "declareUnitName", "校工会")
} else if (val === "BRANCH_UNION") {
this.$set(this.formData, "declareUnitName", this.$store.state.user.union.name)
this.$set(this.formData, "unionId", this.$store.state.user.union.id)
}
},
findOne(id) {
this.$axios.post("/platform/activityDeclare/mine/findOne", { id })
.then((res) => {
if (res.code === 0) {
this.formData = res.data
if (res.data.clubId) {
this.setDeclareUnitName(res.data.clubId)
}
if (res.data.planStartTime && res.data.planEndTime) {
this.$set(this.formData, "planDate", [res.data.planStartTime, res.data.planEndTime])
}
} else {
this.$message.error(res.msg)
}
})
},
async init() {
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
if (this.bizId) {
this.findOne(this.bizId)
} else {
const user = this.$store.state.user
this.$set(this.formData, "userId", user.id)
this.$set(this.formData, "userName", user.username)
this.$set(this.formData, "loginName", user.loginname)
this.$set(this.formData, "mobile", user.mobile)
this.$set(this.formData, "applyTime", this.$moment().format("YYYY-MM-DD"))
this.$set(this.formData, "budgets", [])
}
}
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
this.clubs = await this.$businessTool.listClub()
} else {
if (this.$auth.hasRoleOr('CLUB_MANAGER, CLUB_PRESIDENT')) {
this.clubs = await this.$businessTool.listClub()
}
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.init()
}
})
</script>
@@ -0,0 +1,134 @@
<div id="activity_declare_view">
<el-descriptions :column="2" border>
<el-descriptions-item label="活动名称">{{ viewData.activityName }}</el-descriptions-item>
<el-descriptions-item label="活动类型">{{ getActivityTypeName(viewData.activityType) }}</el-descriptions-item>
<el-descriptions-item label="申请人">{{ viewData.userName + '(' + viewData.loginName + ')' }}</el-descriptions-item>
<el-descriptions-item :label="viewData.activityType == 'CLUB' ? '申请协会' : '申请单位'">{{ viewData.declareUnitName }}</el-descriptions-item>
<el-descriptions-item label="联系方式">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ viewData.applyTime }}</el-descriptions-item>
<el-descriptions-item label="活动计划时间">{{ viewData.planStartTime + ' ~ ' + viewData.planEndTime }}</el-descriptions-item>
<el-descriptions-item label="活动人数">{{ viewData.activityNumber }}</el-descriptions-item>
<el-descriptions-item label="活动地址" :span="2">{{ viewData.activityAddress }}</el-descriptions-item>
<el-descriptions-item label="活动预算费用" :span="2">
<el-table :data="viewData.budgets" border max-height="500" size="mini" style="width: calc(1200px - 150px - 15%)">
<el-table-column label="序号" sortable type="index" width="100"></el-table-column>
<el-table-column label="费用项目名称" prop="name"></el-table-column>
<el-table-column label="预算费用" prop="budgetPrice"></el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="活动方案及简介" :span="2">
<div v-html="viewData.activityContent"></div>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<file-preview v-if="viewData.files && viewData.files.length > 0" :files="viewData.files" complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-image v-if="viewData.sign"
:src="viewData.sign"
class="signature-image"></el-image>
<span v-else>暂无</span>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="task-panel mt10">
<div class="task-panel-header">{{ 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="办理意见" :span="3" v-if="!task.ext.isFirstTaskNode">{{ task.taskFormData.opinion }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
</div>
<script>
new Vue({
el: "#activity_declare_view",
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
viewData: {},
doneTasks: [],
activityDeclareReimbursementList: []
}
},
methods: {
info() {
this.$axios.post("/platform/activityDeclare/mine/findOne", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
// if (res.data.budgets) {
// this.viewData.budgets = JSON.parse(res.data.budgets)
// }
}
})
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { instanceId: this.instanceId }).then((res) => {
debugger
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.info()
this.getDoneTasks()
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<style>
.task-panel {
background: white;
border-radius: 4px;
overflow: hidden;
}
.task-panel-header {
background: rgb(250, 250, 250);
border: 1px solid rgb(228, 231, 237);
border-bottom: none;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.el-descriptions-item__label.is-bordered-label {
width: 15% !important;
}
.el-descriptions-item__label {
width: 15% !important;
}
</style>
@@ -0,0 +1,49 @@
<div id="activity_declare_branch_union_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_declare_branch_union_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,233 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
} else {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,49 @@
<div id="activity_declare_club_principal_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_declare_club_principal_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,212 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属协会">
<el-select clearable filterable placeholder="所属协会"
style="width: 100%;" v-model="pageForm.clubId">
<el-option :label="item.clubName" :value="item.id"
v-for="item in clubs"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.clubs = await this.$businessTool.listClub()
} else {
this.clubs = await this.$businessTool.listClub()
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,149 @@
const INFO = {
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.activityName }}</el-descriptions-item>
<el-descriptions-item label="活动类型">{{ getActivityTypeName(viewData.activityType) }}
</el-descriptions-item>
<el-descriptions-item label="申请人">{{ viewData.userName + '(' + viewData.loginName + ')' }}
</el-descriptions-item>
<el-descriptions-item :label="viewData.activityType == 'CLUB' ? '申请协会' : '申请单位'">{{
viewData.declareUnitName }}
</el-descriptions-item>
<el-descriptions-item label="联系方式">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ viewData.applyTime }}</el-descriptions-item>
<el-descriptions-item label="活动计划时间">{{ $moment(viewData.planStartTime).format('YYYY-MM-DD') + ' ~ ' + $moment(viewData.planEndTime).format('YYYY-MM-DD') }}
</el-descriptions-item>
<el-descriptions-item label="活动人数">{{ viewData.activityNumber }}</el-descriptions-item>
<el-descriptions-item label="活动地址" :span="2">{{ viewData.activityAddress }}</el-descriptions-item>
<el-descriptions-item label="活动预算费用" :span="2">
<el-table :data="viewData.budgets" border max-height="500" size="mini"
style="width: 95%">
<el-table-column label="序号" sortable type="index" width="100"></el-table-column>
<el-table-column label="费用项目名称" prop="name"></el-table-column>
<el-table-column label="预算费用" prop="budgetPrice"></el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="活动方案及简介" :span="2">
<div v-html="viewData.activityContent"></div>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<file-preview v-if="viewData.files && viewData.files.length > 0" :files="viewData.files"
complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-image v-if="viewData.sign"
:src="viewData.sign"
class="signature-image"></el-image>
<span v-else>暂无</span>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="task-panel 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="办理意见" :span="3" 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 {
viewData: {},
doneTasks: [],
row: null,
activityDeclareReimbursementList: []
}
},
methods: {
// 打开
onOpen(row) {
this.row = row
this.info()
this.getDoneTasks()
},
// 获取申请信息
info() {
this.$axios.post("/platform/activityDeclare/mine/findOne", { id: this.row.id }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
// 获取已办任务审批记录
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)
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
},
style: /*language=CSS*/ `
.el-descriptions-item__label.is-bordered-label {
width: 15% !important;
}
.el-descriptions-item__label {
width: 15% !important;
}
`
}
@@ -0,0 +1,212 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, CLUB_MANAGER, CLUB_PRESIDENT')">
<search-item label="所属协会">
<el-select clearable filterable placeholder="所属协会"
style="width: 100%;" v-model="pageForm.clubId">
<el-option :label="item.clubName" :value="item.id"
v-for="item in clubs"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="申报记录">
<el-button size="small" type="primary" @click="onApply">活动申报</el-button>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="openView(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" @click="onRevoke(row)" size="mini" type="danger">撤回
</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>
<info ref="infoRef"></info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
units: [],
clubs: [],
activityDeclareReimbursementList: []
}
},
components: {
'info': INFO
},
methods: {
onApply() {
window.location.href = '/platform/activityDeclare/apply'
},
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onEdit(row) {
window.location.href = '/platform/activityDeclare/apply?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((resp) => {
this.$message.success(resp.msg)
this.pageData()
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/activityDeclare/mine/onDelete", { id }).then((res) => {
if (res.code === 0) {
this.doSearch()
this.$message.success(res.msg)
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
console.log(this.$store.state.user)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
this.clubs = await this.$businessTool.listClub()
} else {
if (this.$auth.hasRoleOr('CLUB_MANAGER, CLUB_PRESIDENT')) {
this.clubs = await this.$businessTool.listClub()
}
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,49 @@
<div id="activity_declare_school_principal_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_declare_school_principal_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,233 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
} else {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,49 @@
<div id="activity_declare_school_union_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_declare_school_union_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,233 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
} else {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,326 @@
<div id="activity_reimbursement_apply">
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="2" border>
<el-descriptions-item label="活动名称">
<el-form-item prop="id">
<el-select v-model="formData.id"
style="width: 100%;"
@change="activityChange(formData.id)"
filterable placeholder="请选择活动">
<el-option
v-for="item in activityOptions"
:key="item.id"
:label="item.activityName + '(' + item.declareUnitName + ')'"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="相关数据">
<el-button size="small" type="primary">查看申报信息</el-button>
</el-descriptions-item>
<el-descriptions-item label="实际活动时间" :span="2">
<el-form-item prop="activityTime">
<el-date-picker
start-placeholder="开始日期"
range-separator="-"
end-placeholder="结束日期"
style="width: 100%"
type="daterange"
v-model="formData.activityTime"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动预算费用" :span="2">
<el-form-item prop="budgets">
<el-table :data="formData.budgets" border max-height="500" size="mini" style="width: 100%">
<el-table-column label="序号" sortable fixed type="index" width="60"></el-table-column>
<el-table-column label="费用项目名称" fixed prop="name" width="200">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.name'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input v-model="row.name" style="width: 100%" maxlength="50"
placeholder="请输入费用项目名称"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="预算费用" prop="budgetPrice" width="250">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.budgetPrice'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number placeholder="预算费用" v-model="row.budgetPrice"
:precision="2" style="width: 100%"
:min="1"></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="实际费用" prop="actualPrice" width="250">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.actualPrice'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number placeholder="请填写实际费用" v-model="row.actualPrice"
:precision="2" style="width: 100%"
:min="0"></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="收款人" prop="payeeId" width="200">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.payeeId'">
<el-input v-model="row.username" maxlength="50"
@input="getCardNumberByPayeeId(row)"
placeholder="请输入收款人"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="支行名称" prop="bankName" width="300">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.bankName'">
<el-input v-model="row.bankName" maxlength="80"
placeholder="请输入支行名称"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="报销卡号" prop="bankCardNum" width="250">
<template scope="{row,$index}">
<el-form-item label-width="0">
<el-input type="number" v-model="row.bankCardNum"
maxlength="50"
placeholder="请输入报销卡号"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" width="400">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.remark'">
<el-input v-model="row.remark" maxlength="200"
placeholder="请输入备注"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column fixed="right" header-align="center" label="操作" width="100">
<template slot="header" slot-scope="scope">
<el-button @click="formData.budgets.push({})" type="primary" size="mini">添加</el-button>
</template>
<template slot-scope="scope">
<el-button :disabled="formData.budgets.length==1"
@click="formData.budgets.splice(scope.$index,1)"
size="mini"
icon="el-icon-delete"
type="danger"></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="发票" :span="2">
<el-form-item prop="billFiles">
<file-upload :value.sync="formData.billFiles"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动报道照片/总结/链接" :span="2">
<el-form-item prop="photoFiles">
<file-upload :value.sync="formData.photoFiles"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="奖品/纪念品/服装/道具等活动人员名单" :span="2">
<el-form-item prop="otherFiles">
<file-upload :value.sync="formData.otherFiles"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-form-item prop="sign">
<pc-signature v-model="formData.sign"></pc-signature>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction" @save-draft="handleSaveDraft"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_reimbursement_apply",
store,
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
formData: {
id: GetQueryString("businessId"),
activityTime: []
},
formRules: {
id: [{required: true, message: "必填", trigger: ['change', 'blur']}]
},
activityOptions: []
}
},
methods: {
// 提交
handleTaskAction(val) {
if (!this.formData.id) {
this.$message.warning("请选择活动后才能保存")
}
this.$refs.formRef.validate((valid) => {
if (valid) {
if (this.formData.activityTime && this.formData.activityTime.length > 0) {
this.formData.startTime = this.formData.activityTime[0]
this.formData.endTime = this.formData.activityTime[1]
}
if (!this.instanceId) {
this.handleApply(val)
} else {
this.handleReApply(val)
}
}
})
},
// 提交申请
handleApply(val) {
this.$confirm("您确定要提交吗?", "提示", { type: "warning" })
.then(() => {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios
.post("/flow/common/startInstanceAndExecute", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete"
})
}
})
}
})
})
},
// 重新提交申请
handleReApply(val) {
this.$confirm("您确定要提交吗?", "提示", { type: "warning" })
.then(() => {
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
processTaskId: val.taskId,
processInstanceId: val.instanceId,
submitType: val.submitType,
f_data: JSON.stringify(this.formData)
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
window.GlobalBroadcastChannel.postMessage({
type: "task-complete"
})
}
})
})
},
// 保存
handleSaveDraft(val) {
this.$confirm("您确定要保存吗?", "提示", { type: "warning" })
.then(() => {
this.$axios
.post("/flow/common/startInstance", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.parent.postMessage(
{
type: "task-complete"
},
"*"
)
}
})
})
},
// 取消
handleCancel() {
},
async getCardNumberByPayeeId(row) {
const resp = await $.get('/platform/activityReimbursement/apply/getCardNumberByPayeeId', {username:row.username})
if (resp.code === 0) {
if (resp.data) {
this.$set(row, "bankCardNum", resp.data.bankCardNum)
this.$set(row, "bankName", resp.data.bankName)
}
}
},
async activityChange(id) {
const {code, data} = await $.get('/platform/activityDeclare/mine/findOne', {id: id})
if (code === 0) {
this.formData = {
...this.formData,
...data
}
if (data.planStartTime && data.planEndTime) {
this.formData.activityTime = [
new Date(data.planStartTime),
new Date(data.planEndTime)
]
}
}
},
async getActivityReimbursementByUser() {
const {code, data} = await $.get('/platform/activityReimbursement/apply/getActivityReimbursementByUser');
if (code === 0) {
this.activityOptions = data
}
},
},
async created() {
await this.getActivityReimbursementByUser()
},
})
</script>
<style>
.el-descriptions-item__label {
width: 15% !important;
}
</style>
@@ -0,0 +1,336 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<div>
<el-card shadow="never">
<snaker-start slot="header" label="活动报销" define_key="HDBX"></snaker-start>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="2" border>
<el-descriptions-item label="活动名称">
<el-form-item prop="id">
<el-select v-model="formData.id"
style="width: 100%;"
@change="activityChange"
filterable placeholder="请选择活动">
<el-option
v-for="item in activityOptions"
:key="item.id"
:label="item.activityName + '(' + item.declareUnitName + ')'"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<template v-if="formData.id">
<el-descriptions-item label="相关数据">
<el-button size="small" type="primary" @click="viewDeclare">查看申报信息</el-button>
</el-descriptions-item>
</template>
<template v-else>
<el-descriptions-item></el-descriptions-item>
</template>
<el-descriptions-item label="实际活动时间" :span="2">
<el-form-item prop="activityTime">
<el-date-picker
start-placeholder="开始日期"
range-separator="-"
end-placeholder="结束日期"
style="width: 100%"
type="daterange"
v-model="formData.activityTime"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动预算费用" :span="2">
<el-form-item prop="budgets">
<el-table :data="formData.budgets" border max-height="500" size="mini" style="width: 100%">
<el-table-column label="序号" sortable fixed type="index" width="60"></el-table-column>
<el-table-column label="费用项目名称" fixed prop="name" width="200">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.name'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input v-model="row.name" style="width: 100%" maxlength="50"
placeholder="请输入费用项目名称"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="预算费用" prop="budgetPrice" width="250">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.budgetPrice'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number placeholder="预算费用" v-model="row.budgetPrice"
:precision="2" style="width: 100%"
:min="1"></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="实际费用" prop="actualPrice" width="250">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.actualPrice'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number placeholder="请填写实际费用" v-model="row.actualPrice"
:precision="2" style="width: 100%"
:min="0"></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="收款人" prop="payeeId" width="200">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.payeeId'">
<el-input v-model="row.username" maxlength="50"
@input="getCardNumberByPayeeId(row)"
placeholder="请输入收款人"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="支行名称" prop="bankName" width="300">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.bankName'">
<el-input v-model="row.bankName" maxlength="80"
placeholder="请输入支行名称"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="报销卡号" prop="bankCardNum" width="250">
<template scope="{row,$index}">
<el-form-item label-width="0">
<el-input type="number" v-model="row.bankCardNum"
maxlength="50"
placeholder="请输入报销卡号"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" width="400">
<template scope="{row,$index}">
<el-form-item label-width="0"
:prop="'budgets.'+$index+'.remark'">
<el-input v-model="row.remark" maxlength="200"
placeholder="请输入备注"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column fixed="right" header-align="center" label="操作" width="100">
<template slot="header" slot-scope="scope">
<el-button @click="formData.budgets.push({})" type="primary" size="mini">添加</el-button>
</template>
<template slot-scope="scope">
<el-button :disabled="formData.budgets.length==1"
@click="formData.budgets.splice(scope.$index,1)"
size="mini"
icon="el-icon-delete"
type="danger"></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="发票" :span="2">
<el-form-item prop="billFiles">
<file-upload :value.sync="formData.billFiles"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="活动报道照片/总结/链接" :span="2">
<el-form-item prop="photoFiles">
<file-upload :value.sync="formData.photoFiles"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="奖品/纪念品/服装/道具等活动人员名单" :span="2">
<el-form-item prop="otherFiles">
<file-upload :value.sync="formData.otherFiles"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
accept=".doc, .docx, .xls, .xlsx, .pdf, .ppt, .jpg, .jpeg, .png"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-form-item prop="sign">
<pc-signature v-model="formData.sign"></pc-signature>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
<el-row type="flex" justify="end" class="mt20">
<el-button type="primary" plain @click="onSave">保存</el-button>
<el-button type="primary" @click="onSubmit" v-if="!taskId">提交</el-button>
<el-button type="primary" @click="onFinishTask" v-else>提交1</el-button>
</el-row>
</el-card>
<el-dialog title="申报数据" :visible.sync="declareDialogVisible" width="60%">
<div style="max-height: 68vh;overflow-y: auto">
<info ref="infoRef"></info>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="declareDialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</div>
<script>
<!--#include("../../declare/common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formData: {
id: GetQueryString("businessId"),
activityTime: []
},
formRules: {
id: [{required: true, message: "必填", trigger: ['change', 'blur']}]
},
activityOptions: [],
declareDialogVisible: false
}
},
components: {
"info": INFO,
},
methods: {
// 保存
onSave() {
this.$confirm("您确定保存吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
if (this.formData.activityTime && this.formData.activityTime.length > 0) {
this.formData.startTime = this.formData.activityTime[0]
this.formData.endTime = this.formData.activityTime[1]
}
this.$axios.post('/platform/activityReimbursement/apply/save', {data: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.$message.success("保存成功")
window.location.href = '/platform/activityReimbursement/mine'
}
})
})
},
// 提交
onSubmit() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
if (this.formData.activityTime && this.formData.activityTime.length > 0) {
this.formData.startTime = this.formData.activityTime[0]
this.formData.endTime = this.formData.activityTime[1]
}
this.$axios.post('/platform/activityReimbursement/apply/submit', {
data: JSON.stringify(this.formData)
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/activityReimbursement/mine'
}
})
})
},
onFinishTask() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
if (this.formData.activityTime && this.formData.activityTime.length > 0) {
this.formData.startTime = this.formData.activityTime[0]
this.formData.endTime = this.formData.activityTime[1]
}
this.$axios.post('/platform/activityReimbursement/apply/submitAgain', {
data: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/activityReimbursement/mine'
}
})
})
},
// 查看申报数据
viewDeclare() {
this.declareDialogVisible = true
this.$nextTick(() => {
this.$refs.infoRef.onOpen({id: this.formData.id})
})
},
async getCardNumberByPayeeId(row) {
const resp = await this.$axios.post('/platform/activityReimbursement/apply/getCardNumberByPayeeId', {username:row.username})
if (resp.code === 0) {
if (resp.data) {
this.$set(row, "bankCardNum", resp.data.bankCardNum)
this.$set(row, "bankName", resp.data.bankName)
}
}
},
async activityChange(id) {
const {code, data} = await this.$axios.post('/platform/activityDeclare/mine/findOne', {id: id})
if (code === 0) {
this.formData = {
...this.formData,
...data
}
if (data.planStartTime && data.planEndTime) {
this.formData.activityTime = [
new Date(data.planStartTime),
new Date(data.planEndTime)
]
}
}
},
async getActivityReimbursementByUser() {
const {code, data} = await this.$axios.post('/platform/activityReimbursement/apply/getActivityReimbursementByUser');
if (code === 0) {
this.activityOptions = data
}
},
},
async created() {
await this.getActivityReimbursementByUser()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,152 @@
<div id="activity_declare_view">
<el-descriptions :column="2" border>
<el-descriptions-item label="活动名称">{{ viewData.activityName }}</el-descriptions-item>
<el-descriptions-item label="活动类型">{{ getActivityTypeName(viewData.activityType) }}</el-descriptions-item>
<el-descriptions-item label="申请人">{{ viewData.userName + '(' + viewData.loginName + ')' }}</el-descriptions-item>
<el-descriptions-item :label="viewData.activityType == 'CLUB' ? '申请协会' : '申请单位'">{{ viewData.declareUnitName }}</el-descriptions-item>
<el-descriptions-item label="联系方式">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ viewData.applyTime }}</el-descriptions-item>
<el-descriptions-item label="活动计划时间">{{ (viewData.planStartTime ? viewData.planStartTime : '未填写') + ' ~ ' + (viewData.planEndTime ? viewData.planEndTime : '未填写') }}</el-descriptions-item>
<el-descriptions-item label="活动人数">{{ viewData.activityNumber }}</el-descriptions-item>
<el-descriptions-item label="实际活动时间" :span="2">{{ (viewData.startTime ? viewData.startTime : '未填写') + ' ~ ' + (viewData.endTime ? viewData.endTime : '未填写') }}</el-descriptions-item>
<el-descriptions-item label="活动地址" :span="2">{{ viewData.activityAddress }}</el-descriptions-item>
<el-descriptions-item label="活动预算费用" :span="2">
<el-table :data="viewData.budgets" border max-height="500" size="mini" style="width: calc(1200px - 150px - 15%)">
<el-table-column label="序号" sortable type="index" fixed></el-table-column>
<el-table-column label="费用项目名称" fixed prop="name" fixed></el-table-column>
<el-table-column label="预算费用" prop="budgetPrice"></el-table-column>
<el-table-column label="实际费用" prop="actualPrice"></el-table-column>
<el-table-column label="收款人" prop="username"></el-table-column>
<el-table-column label="支行名称" prop="bankName"></el-table-column>
<el-table-column label="报销卡号" prop="bankCardNum"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="活动方案及简介" :span="2">
<div v-html="viewData.activityContent"></div>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<file-preview v-if="viewData.files && viewData.files.length > 0" :files="viewData.files" complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="发票" :span="2">
<file-preview v-if="viewData.billFiles && viewData.billFiles.length > 0" :files="viewData.billFiles" complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="活动报道照片/总结/链接" :span="2">
<file-preview v-if="viewData.photoFiles && viewData.photoFiles.length > 0" :files="viewData.photoFiles" complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="奖品/纪念品/服装/道具等活动人员名单" :span="2">
<file-preview v-if="viewData.otherFiles && viewData.otherFiles.length > 0" :files="viewData.otherFiles" complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-image v-if="viewData.sign"
:src="viewData.sign"
class="signature-image"></el-image>
<span v-else>暂无</span>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="task-panel mt10">
<div class="task-panel-header">{{ 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="办理意见" :span="3" v-if="!task.ext.isFirstTaskNode">{{ task.taskFormData.opinion }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
</div>
<script>
new Vue({
el: "#activity_declare_view",
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
viewData: {},
doneTasks: [],
activityDeclareReimbursementList: []
}
},
methods: {
info() {
this.$axios.post("/platform/activityReimbursement/apply/findOne", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { instanceId: this.instanceId }).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.info()
this.getDoneTasks()
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<style>
.task-panel {
background: white;
border-radius: 4px;
overflow: hidden;
}
.task-panel-header {
background: rgb(250, 250, 250);
border: 1px solid rgb(228, 231, 237);
border-bottom: none;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.el-descriptions-item__label.is-bordered-label {
width: 15% !important;
}
.el-descriptions-item__label {
width: 15% !important;
}
</style>
@@ -0,0 +1,572 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.top_block {
width: 100%;
padding: 20px 80px;
border-bottom: 10px solid rgb(240, 240, 240);
}
.top_title {
font-size: 14px;
color: #808492;
height: 30px;
line-height: 30px;
margin-bottom: 5px;
}
.top_num {
font-size: 26px;
}
.cut-off-line {
width: 1px;
height: 70%;
position: absolute;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: rgb(230, 230, 230);
}
.year input {
text-align: center;
}
.chartTitle {
font-size: 14px;
color: #808492;
margin-bottom: 20px;
}
</style>
<div id="app" v-cloak>
<div class="p10">
<el-card shadow="never">
<div class="top_block" v-loading="top_block_loading">
<el-row :gutter="60">
<div style="position: absolute;top: -35px;right: -8px">
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="numForm.startYear"
type="year" :clearable="false"
value-format="yyyy"
@change="getNumData()"
placeholder="选择年">
</el-date-picker>
-
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="numForm.endYear"
type="year" :clearable="false"
value-format="yyyy"
@change="getNumData()"
placeholder="选择年">
</el-date-picker>
</div>
<el-col :span="4" style="position: relative">
<div class="top_title">校工会活动总人数</div>
<div class="top_num">{{numData.schoolSignNum?numData.schoolSignNum:'0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div class="top_title">分工会活动总人数</div>
<div class="top_num">{{numData.unionSignNum?numData.unionSignNum:'0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div class="top_title">协会活动总人数</div>
<div class="top_num">{{numData.clubSignNum?numData.clubSignNum:'0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div class="top_title">校工会活动报销费用(元)
</div>
<div class="top_num">{{numData.schoolActivityMoney?numData.schoolActivityMoney:'0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div class="top_title">分工会活动报销费用(元)
</div>
<div class="top_num">{{numData.unionActivityMoney?numData.unionActivityMoney:'0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4">
<div class="top_title">社团活动报销费用(元)
</div>
<div class="top_num">{{numData.clubActivityMoney?numData.clubActivityMoney:'0'}}</div>
</el-col>
</el-row>
</div>
<el-row style="padding: 30px 0;border-bottom: 10px solid rgb(240, 240, 240)">
<div style="position: absolute;top: 25px;right: 40px;z-index: 200">
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="activityTypeForm.startYear"
type="year" :clearable="false"
value-format="yyyy"
@change="getActivityTypeChart();getActivityTypePieNum();"
placeholder="选择年">
</el-date-picker>
-
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="activityTypeForm.endYear"
type="year" :clearable="false"
value-format="yyyy"
@change="getActivityTypeChart();getActivityTypePieNum();"
placeholder="选择年">
</el-date-picker>
</div>
<el-col :span="12" style="padding: 0 20px;"
v-loading="activity_type_loading">
<div class="chartTitle">活动类型</div>
<div id="activityTypeChart" style="width: 100%;height: 330px;"></div>
</el-col>
<el-col :span="12" style="padding: 0 20px;position: relative"
v-loading="activity_type_pie_loading">
<div class="chartTitle">活动类型占比</div>
<div id="activityTypePieChart" style="width: 100%;height: 330px;"></div>
</el-col>
</el-row>
<el-row style="padding: 30px 0;border-bottom: 10px solid rgb(240, 240, 240)">
<div style="position: absolute;top: 25px;right: 40px;z-index: 2000">
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="activityJfForm.startYear"
type="year" :clearable="false"
value-format="yyyy"
@change="getActivityJfPieNum();getActivityJfChart()"
placeholder="选择年">
</el-date-picker>
-
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="activityJfForm.endYear"
type="year" :clearable="false"
value-format="yyyy"
@change="getActivityJfPieNum();getActivityJfChart();"
placeholder="选择年">
</el-date-picker>
</div>
<el-col :span="12" style="padding: 0 20px;"
v-loading="activity_jf_loading">
<div class="chartTitle">活动报销费用</div>
<div id="activityJfChart" style="width: 100%;height: 330px;"></div>
</el-col>
<el-col :span="12" style="padding: 0 20px;position: relative"
v-loading="activity_jf_pie_loading">
<div class="chartTitle">活动报销费用占比</div>
<div id="activityJfPieChart" style="width: 100%;height: 330px;"></div>
</el-col>
</el-row>
<el-row style="padding: 30px 0;border-bottom: 10px solid rgb(240, 240, 240)">
<div style="position: absolute;top: 25px;right: 40px;z-index: 999">
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="allUnionYear"
type="year" :clearable="false"
value-format="yyyy" @change="allUnionActivityAndJf"
placeholder="选择年">
</el-date-picker>
</div>
<el-col :span="24" style="padding: 0 20px"
v-loading="all_union_loading">
<div class="chartTitle" style="margin-bottom: 50px">{{allUnionYear}}年工会报销费用及活动情况
<el-tooltip class="item" effect="dark" :content="'点击切换为' + unionTip " placement="top">
<el-button type="text" icon="el-icon-sort" @click="doUnionSwitch"></el-button>
</el-tooltip>
</div>
<div id="allUnionChart" style="width: 100%;height: 300px;"></div>
</el-col>
</el-row>
<el-row style="padding: 30px 0;border-bottom: 10px solid rgb(240, 240, 240)">
<div style="position: absolute;top: 25px;right: 40px;z-index: 999">
<el-date-picker
class="year"
style="width: 120px;"
size="mini"
v-model="allClubYear"
type="year" :clearable="false"
value-format="yyyy" @change="allClubActivityAndJf"
placeholder="选择年">
</el-date-picker>
</div>
<el-col :span="24" style="padding: 0 20px"
v-loading="all_club_loading">
<div class="chartTitle" style="margin-bottom: 50px">{{allClubYear}}年社团报销费用及活动情况
<el-tooltip class="item" effect="dark" :content="'点击切换为' + clubTip " placement="top">
<el-button type="text" icon="el-icon-sort" @click="doClubSwitch"></el-button>
</el-tooltip>
</div>
<div id="allClubChart" style="width: 100%;height: 300px;"></div>
</el-col>
</el-row>
</el-card>
</div>
</div>
<script>
const vue = new Vue({
el: '#app',
data() {
return {
top_block_loading: false,
numForm: {
startYear: new Date().getFullYear() - 2 + '',
endYear: new Date().getFullYear() + '',
},
numData: {},
activity_type_loading: false,
activity_type_pie_loading: false,
activityTypePieChart: null,
activityTypeForm: {
startYear: new Date().getFullYear() - 2 + '',
endYear: new Date().getFullYear() + '',
},
activity_jf_loading: false,
activity_jf_pie_loading: false,
activityJfPieChart: null,
activityJfForm: {
startYear: new Date().getFullYear() - 2 + '',
endYear: new Date().getFullYear() + '',
},
all_union_loading: false,
unionTip:'分工会活动数',
allUnionYear: moment().format('YYYY'),
isUnionJf:true,
all_club_loading: false,
clubTip:'协会活动数',
allClubYear: moment().format('YYYY'),
isClubJf:true,
}
},
methods: {
async getNumData() {
this.top_block_loading = true
const resp = await this.$axios.post("/platform/activityReimbursement/board/getNumData", this.numForm)
if (resp.code === 0) {
this.numData = resp.data
}
this.top_block_loading = false
},
async getActivityTypeChart() {
this.activity_type_loading = true
const resp = await this.$axios.post("/platform/activityReimbursement/board/getActivityTypeChart", this.activityTypeForm)
if (resp.code === 0) {
let {data} = resp
document.getElementById("activityTypeChart").innerHTML = ''
const config = {
isGroup: true,
"legend": {
"position": "top-right",
"flipPage": false
},
"autoFit": false,
"width": $('#activityTypeChart').width(),
"height": $('#activityTypeChart').height(),
"xField": "year",
"yField": "num",
"seriesField": "type",
}
const plot = new G2Plot.Column(document.getElementById("activityTypeChart"), {
data,
...config,
});
plot.render();
}
this.activity_type_loading = false
},
async getActivityTypePieNum() {
this.activity_type_pie_loading = true
// 销毁旧的图表实例(如果存在)
if (this.activityTypePieChart) {
this.activityTypePieChart.destroy();
}
const resp = await this.$axios.post("/platform/activityReimbursement/board/getActivityTypePieNum", this.activityTypeForm)
if (resp.code === 0) {
let {data} = resp
const config = {
"legend": {
"flipPage": false
},
"label": {
"type": "spider",
"offset": 50
},
"width": $('#activityTypePieChart').width(),
"height": $('#activityTypePieChart').height(),
"forceFit": false,
"radius": 1,
"colorField": "type",
"angleField": "num",
meta: {
type: {
alias: '类别',
},
num: {
alias: '数量',
}
},
}
this.activityTypePieChart = new G2Plot.Pie(document.getElementById("activityTypePieChart"), {
data,
...config,
});
this.activityTypePieChart.render();
}
this.activity_type_pie_loading = false
},
async getActivityJfChart() {
this.activity_type_loading = true
const resp = await this.$axios.post("/platform/activityReimbursement/board/getActivityMoneyChart", this.activityJfForm)
if (resp.code === 0) {
let {data} = resp
document.getElementById("activityJfChart").innerHTML = ''
const config = {
isGroup: true,
"legend": {
"position": "top-right",
"flipPage": false
},
"autoFit": false,
"width": $('#activityJfChart').width(),
"height": $('#activityJfChart').height(),
"xField": "year",
"yField": "num",
"seriesField": "type",
}
const plot = new G2Plot.Column(document.getElementById("activityJfChart"), {
data,
...config,
});
plot.render();
}
this.activity_type_loading = false
},
async getActivityJfPieNum() {
this.activity_jf_pie_loading = true
// 销毁旧的图表实例(如果存在)
if (this.activityJfPieChart) {
this.activityJfPieChart.destroy();
}
const resp = await this.$axios.post("/platform/activityReimbursement/board/getActivityMoneyPieNum", this.activityJfForm)
if (resp.code === 0) {
let {data} = resp
const config = {
"legend": {
"flipPage": false
},
"label": {
"type": "spider",
"offset": 50
},
"width": $('#activityJfPieChart').width(),
"height": $('#activityJfPieChart').height(),
"forceFit": false,
"radius": 1,
"colorField": "type",
"angleField": "num",
meta: {
type: {
alias: '类别',
},
num: {
alias: '数量',
}
},
}
this.activityJfPieChart = new G2Plot.Pie(document.getElementById("activityJfPieChart"), {
data,
...config,
});
this.activityJfPieChart.render();
}
this.activity_jf_pie_loading = false
},
async doUnionSwitch(){
this.isUnionJf = !this.isUnionJf
this.unionTip = this.isUnionJf ? '分工会活动数' : '分工会经费详情'
await this.allUnionActivityAndJf();
},
async allUnionActivityAndJf() {
this.all_union_loading = true
const resp = await this.$axios.post("/platform/activityReimbursement/board/allUnionActivityAndMoney",{
year:this.allUnionYear,
isUnionMoney:this.isUnionJf
})
if (resp.code === 0) {
let {data} = resp
document.getElementById("allUnionChart").innerHTML = ''
const config = {
isStack: true,
"legend": {
"position": "top-right",
"flipPage": false
},
autoFit: true,
title: {
visible: true,
text: this.allUnionYear + '年工会经费及活动详情',
},
description: {
visible: true,
text: '单位(元)',
},
xField: 'unionname',
yField: 'money',
stackField: 'type',
color: ["#5B8FF9", "#5AD8A6"],
"xAxis": {
label: {
formatter: (v) => {
if (data.length > 30 && v.length > 3) {
return v.substr(0, 2) + '...'
} else if (data.length > 20 && v.length > 4) {
return v.substr(0, 3) + '...'
} else if (data.length > 10 && v.length > 6) {
return v.substr(0, 5) + '...'
}
return v
}
}
},
"yAxis": {},
meta: {
unionname: {
alias: '工会',
},
money: {
alias: this.isUnionJf?'金额':'活动数',
}
},
connectedArea: {
visible: true,
triggerOn: false,
},
}
const plot = new G2Plot.Column(document.getElementById("allUnionChart"), {
data,
...config,
});
plot.render();
}
this.all_union_loading = false
},
async doClubSwitch(){
this.isClubJf = !this.isClubJf
this.clubTip = this.isClubJf ? '协会活动数' : '协会经费详情'
await this.allClubActivityAndJf();
},
async allClubActivityAndJf(){
this.all_club_loading = true
const resp = await this.$axios.post("/platform/activityReimbursement/board/allClubActivityAndMoney",{
year:this.allClubYear,
isClubMoney:this.isClubJf
})
if (resp.code === 0) {
let {data} = resp
document.getElementById("allClubChart").innerHTML = ''
const config = {
isStack: true,
"legend": {
"position": "top-right",
"flipPage": false
},
autoFit: true,
title: {
visible: true,
text: this.allClubYear + '年工会经费及活动详情',
},
description: {
visible: true,
text: '单位(元)',
},
xField: 'clubName',
yField: 'money',
stackField: 'type',
color: ["#5B8FF9", "#5AD8A6"],
"xAxis": {
label: {
formatter: (v) => {
if (data.length > 30 && v.length > 3) {
return v.substr(0, 2) + '...'
} else if (data.length > 20 && v.length > 4) {
return v.substr(0, 3) + '...'
} else if (data.length > 10 && v.length > 6) {
return v.substr(0, 5) + '...'
}
return v
}
}
},
"yAxis": {},
meta: {
clubName: {
alias: '协会',
},
money: {
alias: this.isClubJf?'金额':'活动数',
}
},
connectedArea: {
visible: true,
triggerOn: false,
},
}
const plot = new G2Plot.Column(document.getElementById("allClubChart"), {
data,
...config,
});
plot.render();
}
this.all_club_loading = false
},
},
async created() {
await this.getNumData()
},
async mounted() {
await this.getActivityJfChart()
await this.getActivityTypeChart()
await this.getActivityTypePieNum()
await this.getActivityJfPieNum()
await this.allUnionActivityAndJf()
await this.allClubActivityAndJf()
},
});
</script>
<!--#
}
#-->
@@ -0,0 +1,49 @@
<div id="activity_reimbursement_branch_union_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_reimbursement_branch_union_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,233 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
} else {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,49 @@
<div id="activity_reimbursement_club_principal_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_reimbursement_club_principal_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,212 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属协会">
<el-select clearable filterable placeholder="所属协会"
style="width: 100%;" v-model="pageForm.clubId">
<el-option :label="item.clubName" :value="item.id"
v-for="item in clubs"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.clubs = await this.$businessTool.listClub()
} else {
this.clubs = await this.$businessTool.listClub()
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,177 @@
const INFO = {
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.activityName }}</el-descriptions-item>
<el-descriptions-item label="活动类型">{{ getActivityTypeName(viewData.activityType) }}
</el-descriptions-item>
<el-descriptions-item label="申请人">{{ viewData.userName + '(' + viewData.loginName + ')' }}
</el-descriptions-item>
<el-descriptions-item :label="viewData.activityType == 'CLUB' ? '申请协会' : '申请单位'">{{
viewData.declareUnitName }}
</el-descriptions-item>
<el-descriptions-item label="联系方式">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ viewData.applyTime }}</el-descriptions-item>
<el-descriptions-item label="活动计划时间">{{ (viewData.planStartTime ? viewData.planStartTime : '未填写')
+ ' ~ ' + (viewData.planEndTime ? viewData.planEndTime : '未填写') }}
</el-descriptions-item>
<el-descriptions-item label="活动人数">{{ viewData.activityNumber }}</el-descriptions-item>
<el-descriptions-item label="实际活动时间" :span="2">{{ (viewData.startTime ? viewData.startTime :
'未填写') + ' ~ ' + (viewData.endTime ? viewData.endTime : '未填写') }}
</el-descriptions-item>
<el-descriptions-item label="活动地址" :span="2">{{ viewData.activityAddress }}</el-descriptions-item>
<el-descriptions-item label="活动预算费用" :span="2">
<el-table :data="viewData.budgets" border max-height="500" size="mini"
style="width: calc(1200px - 150px - 15%)">
<el-table-column label="序号" sortable type="index" fixed></el-table-column>
<el-table-column label="费用项目名称" fixed prop="name" fixed></el-table-column>
<el-table-column label="预算费用" prop="budgetPrice"></el-table-column>
<el-table-column label="实际费用" prop="actualPrice"></el-table-column>
<el-table-column label="收款人" prop="username"></el-table-column>
<el-table-column label="支行名称" prop="bankName"></el-table-column>
<el-table-column label="报销卡号" prop="bankCardNum"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="活动方案及简介" :span="2">
<div v-html="viewData.activityContent"></div>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<file-preview v-if="viewData.files && viewData.files.length > 0" :files="viewData.files"
complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="发票" :span="2">
<file-preview v-if="viewData.billFiles && viewData.billFiles.length > 0" :files="viewData.billFiles"
complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="活动报道照片/总结/链接" :span="2">
<file-preview v-if="viewData.photoFiles && viewData.photoFiles.length > 0"
:files="viewData.photoFiles" complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="奖品/纪念品/服装/道具等活动人员名单" :span="2">
<file-preview v-if="viewData.otherFiles && viewData.otherFiles.length > 0"
:files="viewData.otherFiles" complete_result></file-preview>
<span v-else>暂无</span>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="2">
<el-image v-if="viewData.sign"
:src="viewData.sign"
class="signature-image"></el-image>
<span v-else>暂无</span>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="task-panel 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="办理意见" :span="3" 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 {
viewData: {},
doneTasks: [],
row: null,
activityDeclareReimbursementList: []
}
},
methods: {
// 打开
onOpen(row) {
this.row = row
this.info()
this.getDoneTasks()
},
// 获取申请信息
info() {
this.$axios.post("/platform/activityReimbursement/mine/findOne", { id: this.row.id }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
// 获取已办任务审批记录
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)
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
},
style: /*language=CSS*/ `
.el-descriptions-item__label.is-bordered-label {
width: 15% !important;
}
.el-descriptions-item__label {
width: 15% !important;
}
`
}
@@ -0,0 +1,210 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, CLUB_MANAGER, CLUB_PRESIDENT')">
<search-item label="所属协会">
<el-select clearable filterable placeholder="所属协会"
style="width: 100%;" v-model="pageForm.clubId">
<el-option :label="item.clubName" :value="item.id"
v-for="item in clubs"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="申报记录">
<el-button size="small" type="primary" @click="onApply">活动申报</el-button>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="openView(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" @click="onRevoke(row)" size="mini" type="danger">撤回
</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>
<info ref="infoRef"></info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
units: [],
clubs: [],
activityDeclareReimbursementList: []
}
},
components: {
'info': INFO
},
methods: {
onApply() {
window.location.href = '/platform/activityReimbursement/apply'
},
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onEdit(row) {
window.location.href = '/platform/activityReimbursement/apply?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((resp) => {
this.$message.success(resp.msg)
this.pageData()
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/activityReimbursement/mine/onDelete", { id }).then((res) => {
if (res.code === 0) {
this.doSearch()
this.$message.success(res.msg)
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
this.clubs = await this.$businessTool.listClub()
} else {
if (this.$auth.hasRoleOr('CLUB_MANAGER, CLUB_PRESIDENT')) {
this.clubs = await this.$businessTool.listClub()
}
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,49 @@
<div id="activity_reimbursement_school_principal_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_reimbursement_school_principal_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,233 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
} else {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,49 @@
<div id="activity_reimbursement_school_union_approval_form">
<el-form :model="formData" ref="formRef" 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>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#activity_reimbursement_school_union_approval_form",
data() {
return {
businessId: GetQueryString("businessId"),
formData: {
tf_opinion: ""
},
}
},
methods: {
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (valid) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
}
})
},
handleCancel(val) {
console.log(val)
},
}
})
</script>
@@ -0,0 +1,233 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<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">
</el-date-picker>
</search-item>
<search-item label="申请人">
<el-input placeholder="请输入申请人工号或姓名" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_ADMIN')">
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable
filterable
placeholder="所属工会"
style="width: 100%;"
v-model="pageForm.unionId">
<el-option :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="所属单位"
style="width: 100%;" v-model="pageForm.unitId">
<el-option :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
</template>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<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" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" header-align="center" label="序号"
type="index" width="60px"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginName'">
<span>{{row.userName + '(' + row.loginName + ')' }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='activityType'">
<span>{{ getActivityTypeName(row.activityType) }}</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(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>
<info ref="infoRef">
<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>
</info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
},
tableColumns: [
{ prop: "loginName", label: "申报人", sortable: true },
{ prop: "mobile", label: "联系方式"},
{ prop: "activityName", label: "活动名称"},
{ prop: "activityType", label: "活动类型"},
{ prop: "declareUnitName", label: "申报单位/协会", sortable: true },
{ prop: "activityNumber", label: "活动人数", sortable: true },
{ prop: "applyTime", label: "申报时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
activityDeclareReimbursementList: [],
unions: [],
units: [],
clubs: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.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()
}
})
})
},
async flushUnits(){
this.$set(this.pageForm, "unitId", null)
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit(this.pageForm.unionId)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
},
getActivityTypeName(type) {
const data = this.activityDeclareReimbursementList.find(item => item.name === type)
return data ? data.typeName : ""
},
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
} else {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
}
this.activityDeclareReimbursementList = await this.$businessTool.getEnumOptions("ActivityDeclareReimbursement")
}
})
</script>
<!--#
}
#-->