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
@@ -327,7 +327,7 @@ div.base-info-item {
}
.step-list {
height: 60px;
height: 80px;
padding: 10px 30px;
background-color: #fff;
margin-bottom: 20px;
@@ -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>
<!--#
}
#-->
@@ -19,6 +19,12 @@ layout("/layouts/platform.html"){
}
</style>
<div id="app" v-clock>
<el-card shadow="never">
<snaker-start slot="header" label="建家申报" define_key="ZGXJSB"></snaker-start>
</el-card>
<guava ref="guava">
<template>
<el-card shadow="never">
@@ -101,11 +107,6 @@ layout("/layouts/platform.html"){
<el-form-item class="is-required" label="基层工会简况"
prop="basicInformation">
<text-editor v-model="formData.basicInformation"></text-editor>
<div style="text-align: right">
<span style="color: #0a84ff">当前字数:{{ formData.basicInformation ? (dd3s.html2txt(formData.basicInformation).length) : 0 }}</span>
<span>{{ ';最多500字' }}</span>
</div>
<!-- <el-input type="textarea" v-model="formData.basicInformation" maxlength="500" show-word-limit :rows="10"></el-input>-->
</el-form-item>
</el-col>
</el-row>
@@ -132,36 +133,14 @@ layout("/layouts/platform.html"){
el: '#app',
mixins: [initTableMixins],
data() {
const validBasicInformation = (rule, value, callback) => {
if (!this.formData.basicInformation || !dd3s.html2txt(this.formData.basicInformation)) {
callback(new Error('请填写基层工会简况'));
} else if (dd3s.html2txt(this.formData.basicInformation).length > 500) {
console.log(11)
callback(new Error('基层工会简况最多500字'));
} else {
callback();
}
};
return {
id: '',
formData: {},
formRules: {
mobile: [{required: true, message: '手机号不能为空', trigger: 'blur'},
{pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur'}],
basicInformation: [{
required: true,
message: '必填',
trigger: ['blur', 'change']
}],
constructionPlan: [{
required: true,
message: '必填',
trigger: ['blur', 'change']
}],
basicInformation: [{
validator: validBasicInformation,
trigger: ['blur', 'change']
}],
basicInformation: [{required: true, message: '必填', trigger: ['blur', 'change']}],
constructionPlan: [{required: true, message: '必填', trigger: ['blur', 'change']}],
},
}
},
@@ -0,0 +1,73 @@
const BANNER = {
template: /*language=HTML*/ `
<div class="banner-container">
<el-carousel :interval="5000" arrow="always" height="480px">
<el-carousel-item v-for="(banner, index) in banners" :key="index">
<a :href="banner.link" class="banner-item">
<img :src="banner.image" :alt="banner.title" class="banner-image">
<div class="banner-title">{{ banner.title }}</div>
</a>
</el-carousel-item>
</el-carousel>
</div>
`,
data() {
return {
banners: [
{
id: 1,
title: '618年中大促',
image: 'https://img10.360buyimg.com/babel/s1920x600_jfs/t1/211815/34/8529/107925/6111c8c9E4a1f8d2b/291c9c66391b8c6d.jpg',
link: '#'
},
{
id: 2,
title: '手机5折起',
image: 'https://img10.360buyimg.com/babel/s1920x600_jfs/t1/198372/22/19657/123948/6111c8c9E0d8a5c8d/1c8e6b1c8b5e5b8a.jpg',
link: '#'
},
{
id: 3,
title: '家电清凉一夏',
image: 'https://img10.360buyimg.com/babel/s1920x600_jfs/t1/198372/22/19657/123948/6111c8c9E0d8a5c8d/1c8e6b1c8b5e5b8a.jpg',
link: '#'
}
]
}
},
methods: {
},
style: /*language=CSS*/ `
.banner-container {
margin-bottom: 20px;
}
.banner-item {
position: relative;
display: block;
width: 100%;
height: 100%;
}
.banner-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.banner-title {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
color: white;
font-size: 30px;
font-weight: bold;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
background: rgba(0, 0, 0, 0.3);
padding: 10px 20px;
border-radius: 4px;
}
`
}
@@ -0,0 +1,356 @@
<!--#include("breadcrumbNav.js"){}#-->
const HEADER = {
template: /*language=HTML*/ `
<div>
<div class="header-top">
<div class="container">
<div class="welcome">欢迎来到京东商城</div>
<div class="user-info">
<template v-if="isLogin">
<a href="javascript:void(0)">我的订单</a>
<a href="javascript:void(0)">我的京东</a>
<a href="javascript:void(0)" @click="logout">退出</a>
</template>
<template v-else>
<a href="javascript:void(0)" @click="login">登录</a>
<a href="javascript:void(0)" @click="register">注册</a>
</template>
<a href="javascript:void(0)">我的订单</a>
<a href="javascript:void(0)">我的京东</a>
<a href="javascript:void(0)">企业采购</a>
<el-dropdown @command="handleService">
<span class="el-dropdown-link">
客户服务<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="help">帮助中心</el-dropdown-item>
<el-dropdown-item command="customer">在线客服</el-dropdown-item>
<el-dropdown-item command="after-sales">售后服务</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown @command="handleApp">
<span class="el-dropdown-link">
手机京东<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="app">京东APP</el-dropdown-item>
<el-dropdown-item command="wechat">微信小程序</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
<div class="header-main">
<div class="container">
<div class="logo">
<a href="/">
<img src="https://img11.360buyimg.com/jdcdh/s150x50_jfs/t1/173705/37/11987/5525/60b3d1c7E56f89c06/899d8b19c09f7d2c.png" alt="京东商城">
</a>
</div>
<div class="search-box">
<el-input
v-model="searchQuery"
placeholder="搜索商品"
@keyup.enter.native="handleSearch">
<el-button slot="append" type="danger" icon="el-icon-search" @click="handleSearch"></el-button>
</el-input>
<div class="hot-keys">
<a href="javascript:void(0)" v-for="(keyword, index) in hotSearch" :key="index">{{ keyword }}</a>
</div>
</div>
<div class="cart-box">
<el-badge :value="cartCount" :max="99">
<el-button type="danger" icon="el-icon-shopping-cart-2" size="medium">我的购物车</el-button>
</el-badge>
<div class="cart-dropdown" v-if="cartCount > 0">
<p>最近加入的商品</p>
<div class="cart-items">
<div class="cart-item" v-for="(item, index) in cartItems" :key="index">
<div class="item-image">
<img :src="item.image" alt="商品图片">
</div>
<div class="item-info">
<div class="item-name">{{ item.name }}</div>
<div class="item-price">¥{{ item.price }} × {{ item.quantity }}</div>
</div>
</div>
</div>
<div class="cart-footer">
<span>共 {{ cartCount }} 件商品</span>
<el-button type="danger" size="small">去购物车</el-button>
</div>
</div>
</div>
</div>
</div>
<div class="header-bottom">
<div class="container">
<nav class="main-nav">
<ul class="nav-list">
<li :class="{ 'active': activeNav === 'home' }">
<a href="/">首页</a>
</li>
<li :class="{ 'active': activeNav === 'electronics' }">
<a href="/category/electronics">手机数码</a>
</li>
<li :class="{ 'active': activeNav === 'home-appliance' }">
<a href="/category/appliance">家用电器</a>
</li>
<li :class="{ 'active': activeNav === 'computer' }">
<a href="/category/computer">电脑办公</a>
</li>
<li :class="{ 'active': activeNav === 'furniture' }">
<a href="/category/furniture">家居家装</a>
</li>
<li :class="{ 'active': activeNav === 'food' }">
<a href="/category/food">食品生鲜</a>
</li>
<li :class="{ 'active': activeNav === 'book' }">
<a href="/category/book">图书</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
`,
data() {
return {
searchQuery: '',
hotSearch: ['手机', '笔记本', '电视', '空调', '洗衣机', '冰箱'],
cartCount: 3,
cartItems: [
{ id: 1, name: 'Apple iPhone 13', price: 5999, quantity: 1, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 2, name: '华为MateBook X Pro', price: 8999, quantity: 1, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 3, name: '小米电视6 OLED', price: 5999, quantity: 1, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
],
isLogin: false,
activeNav: 'home'
}
},
methods: {
handleSearch() {
if (this.searchQuery.trim()) {
this.$emit('search', this.searchQuery);
console.log('搜索:', this.searchQuery);
}
},
handleService(command) {
console.log('客户服务:', command);
},
handleApp(command) {
console.log('手机京东:', command);
},
login() {
this.isLogin = true;
console.log('登录');
},
register() {
console.log('注册');
},
logout() {
this.isLogin = false;
console.log('退出');
}
},
created() {
},
style: /*language=CSS*/ `
.site-header {
background: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.header-top {
background: #f5f5f5;
height: 30px;
line-height: 30px;
font-size: 12px;
color: #999;
}
.container {
width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
}
.welcome {
float: left;
}
.user-info {
float: right;
}
.user-info a {
color: #999;
margin-left: 15px;
text-decoration: none;
}
.user-info a:hover {
color: #c81623;
}
.el-dropdown-link {
cursor: pointer;
color: #999;
}
.header-main {
padding: 20px 0;
}
.logo {
float: left;
width: 160px;
}
.logo img {
width: 100%;
}
.search-box {
float: left;
width: 550px;
margin: 0 20px;
}
.hot-keys {
margin-top: 8px;
}
.hot-keys a {
color: #999;
font-size: 12px;
margin-right: 10px;
text-decoration: none;
}
.hot-keys a:hover {
color: #c81623;
}
.cart-box {
float: right;
position: relative;
}
.cart-box:hover .cart-dropdown {
display: block;
}
.cart-dropdown {
position: absolute;
right: 0;
width: 300px;
background: #fff;
border: 1px solid #e0e0e0;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 1000;
display: none;
padding: 10px;
}
.cart-items {
max-height: 300px;
overflow-y: auto;
margin: 10px 0;
}
.cart-item {
display: flex;
padding: 10px 0;
border-bottom: 1px solid #eee;
}
.item-image {
width: 60px;
height: 60px;
margin-right: 10px;
}
.item-image img {
width: 100%;
height: 100%;
object-fit: contain;
}
.item-info {
flex: 1;
}
.item-name {
font-size: 13px;
color: #333;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-price {
font-size: 12px;
color: #c81623;
}
.cart-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 10px;
border-top: 1px solid #eee;
}
.header-bottom {
background: #c81623;
height: 40px;
}
.main-nav {
height: 40px;
line-height: 40px;
}
.nav-list {
display: flex;
list-style: none;
height: 40px;
line-height: 40px;
}
.nav-list li {
margin: 0 15px;
}
.nav-list a {
color: #fff;
text-decoration: none;
font-size: 16px;
font-weight: bold;
}
.nav-list a:hover {
color: #fff;
text-decoration: underline;
}
.nav-list .active a {
color: #fff;
position: relative;
}
.nav-list .active a::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: #fff;
}
`
}
@@ -0,0 +1,105 @@
const HOT_BRANDS = {
template: /*language=HTML*/ `
<div class="hot-brands">
<div class="section-header">
<h2 class="title">热门品牌</h2>
<div class="more">
<a href="javascript:void(0)">查看全部品牌 <i class="el-icon-arrow-right"></i></a>
</div>
</div>
<div class="brands-content">
<div class="brand-item" v-for="(brand, index) in brands" :key="index">
<a :href="brand.link">
<img :src="brand.logo" :alt="brand.name">
<div class="brand-name">{{ brand.name }}</div>
</a>
</div>
</div>
</div>
`,
data() {
return{
brands: [
{ id: 1, name: 'Apple', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/17745/33/1524/7225/5c3b6c97E0c4c9e92/44a8b4c0e0c8f8d8.png', link: '#' },
{ id: 2, name: '华为', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/35476/25/11785/6489/5d1c3e74E1c4c5a5b/0e0b8b6c8d7e8e8e.png', link: '#' },
{ id: 3, name: '小米', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/18563/13/11786/5790/5d1c3e74E0c4c5a5b/1e0b8b6c8d7e8e8e.png', link: '#' },
{ id: 4, name: '联想', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/36547/27/11785/5678/5d1c3e74E1c4c5a5b/2e0b8b6c8d7e8e8e.png', link: '#' },
{ id: 5, name: '海尔', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/37547/29/11785/5890/5d1c3e74E1c4c5a5b/3e0b8b6c8d7e8e8e.png', link: '#' },
{ id: 6, name: '美的', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/38547/31/11785/5987/5d1c3e74E1c4c5a5b/4e0b8b6c8d7e8e8e.png', link: '#' },
{ id: 7, name: '三星', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/39547/33/11785/6123/5d1c3e74E1c4c5a5b/5e0b8b6c8d7e8e8e.png', link: '#' },
{ id: 8, name: '索尼', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/40547/35/11785/6234/5d1c3e74E1c4c5a5b/6e0b8b6c8d7e8e8e.png', link: '#' }
]
}
},
methods: {
},
created() {
},
style: /*language=CSS*/ `
.hot-brands {
background: #fff;
border-radius: 4px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.title {
font-size: 20px;
color: #333;
font-weight: bold;
}
.more a {
color: #666;
font-size: 14px;
text-decoration: none;
}
.more a:hover {
color: #c81623;
}
.brands-content {
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: 15px;
}
.brand-item {
text-align: center;
padding: 10px 0;
transition: all 0.3s;
}
.brand-item:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transform: translateY(-3px);
border-radius: 4px;
}
.brand-item img {
width: 80%;
height: auto;
max-height: 40px;
object-fit: contain;
}
.brand-name {
margin-top: 8px;
font-size: 14px;
color: #333;
}
`
}
@@ -0,0 +1,855 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.jd-container {
max-width: 1200px;
margin: 0 auto;
background: #fff;
}
/* 顶部导航栏 */
.jd-header {
height: 110px;
background: #c81623;
display: flex;
align-items: center;
padding: 0 20px;
}
.jd-logo {
display: flex;
align-items: center;
color: #fff;
text-decoration: none;
}
.jd-logo img {
height: 60px;
margin-right: 15px;
}
.jd-logo h1 {
font-size: 28px;
font-weight: normal;
}
.jd-logo span {
font-size: 16px;
opacity: 0.9;
}
/* 购物车标题 */
.cart-title {
padding: 20px 20px 10px;
border-bottom: 2px solid #c81623;
}
.cart-title h2 {
font-size: 24px;
color: #c81623;
font-weight: normal;
}
/* 购物车表格 */
.cart-table {
padding: 0 20px;
}
.el-table {
border: 1px solid #e6e6e6;
margin-bottom: 20px;
}
.el-table th {
background-color: #f5f5f5;
padding: 10px 0;
font-weight: normal;
}
.product-cell {
display: flex;
align-items: center;
padding: 15px 0;
}
.product-image {
width: 80px;
height: 80px;
border: 1px solid #eee;
margin-right: 15px;
object-fit: cover;
}
.product-info {
flex: 1;
}
.product-name {
font-size: 14px;
line-height: 1.4;
color: #333;
margin-bottom: 5px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.product-desc {
font-size: 12px;
color: #999;
}
.spec-select {
width: 120px;
margin-top: 5px;
}
.price-cell {
color: #c81623;
font-weight: bold;
font-size: 16px;
}
.quantity-cell {
display: flex;
align-items: center;
}
.el-input-number {
width: 120px;
}
.el-input-number--mini .el-input__inner {
padding-left: 30px;
padding-right: 30px;
height: 30px;
line-height: 30px;
}
.el-input-number--mini .el-input-number__decrease,
.el-input-number--mini .el-input-number__increase {
width: 28px;
height: 28px;
line-height: 28px;
}
.subtotal {
color: #c81623;
font-weight: bold;
}
.delete-btn {
color: #999;
cursor: pointer;
transition: all 0.3s;
}
.delete-btn:hover {
color: #c81623;
}
/* 底部操作栏 */
.cart-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background: #fff;
border-top: 1px solid #e6e6e6;
position: relative;
}
.footer-left {
display: flex;
align-items: center;
}
.select-all {
margin-right: 20px;
font-size: 14px;
}
.selected-count {
color: #c81623;
font-weight: bold;
margin: 0 5px;
}
.total-price {
font-size: 18px;
color: #c81623;
font-weight: bold;
}
.settlement-btn {
background: #c81623;
border-color: #c81623;
color: #fff;
padding: 0 25px;
height: 36px;
font-size: 16px;
}
.settlement-btn:hover {
background: #a7141f;
border-color: #a7141f;
}
.settlement-btn:disabled {
background: #ccc;
border-color: #ccc;
}
/* 地址选择区域 */
.address-section {
padding: 15px 20px;
background: #f9f9f9;
border-top: 1px dashed #e6e6e6;
}
.address-title {
font-size: 14px;
color: #333;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.address-title i {
margin-right: 5px;
color: #c81623;
}
.address-list {
display: flex;
gap: 15px;
}
.address-card {
border: 1px solid #e6e6e6;
padding: 12px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
background: #fff;
position: relative;
width: 220px;
}
.address-card:hover {
border-color: #c81623;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.address-card.active {
border-color: #c81623;
background: #fff9f9;
}
.address-card.active::before {
content: '';
position: absolute;
top: 0;
right: 0;
border-width: 0 16px 16px 0;
border-style: solid;
border-color: #c81623 transparent;
}
.address-card.active::after {
content: '';
position: absolute;
top: 2px;
right: 2px;
width: 12px;
height: 6px;
border: 2px solid #fff;
border-top: none;
border-right: none;
transform: rotate(-45deg);
}
.address-name {
font-weight: bold;
margin-bottom: 5px;
}
.address-detail {
font-size: 13px;
color: #666;
line-height: 1.4;
}
.address-actions {
display: flex;
justify-content: flex-end;
margin-top: 10px;
}
.address-actions .el-button {
padding: 0;
font-size: 13px;
}
/* 空购物车状态 */
.empty-cart {
text-align: center;
padding: 50px 0;
}
.empty-cart img {
width: 180px;
margin-bottom: 20px;
}
.empty-cart p {
color: #999;
margin-bottom: 20px;
}
.continue-shopping {
background: #c81623;
color: #fff;
padding: 8px 25px;
border-radius: 2px;
text-decoration: none;
display: inline-block;
}
.continue-shopping:hover {
background: #a7141f;
}
/* 优惠信息 */
.promotion {
padding: 10px 20px;
background: #fff9f9;
border: 1px solid #ffeaea;
color: #c81623;
font-size: 13px;
}
.promotion i {
margin-right: 5px;
}
/* 响应式调整 */
@media (max-width: 768px) {
.cart-table {
padding: 0 10px;
}
.el-table {
font-size: 13px;
}
.product-name {
font-size: 13px;
}
.cart-footer {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.footer-right {
width: 100%;
display: flex;
justify-content: flex-end;
}
}
</style>
<div id="app">
<div class="jd-container">
<!-- 顶部导航 -->
<header class="jd-header">
<a href="#" class="jd-logo">
<img src="https://img12.360buyimg.com/img/jfs/t1/2022/36/7653/3103/5b9f5f5cE6c40a453/9c4c3d0a0e0d6e0d.png" alt="京东">
<div>
<h1>京东</h1>
<span>品质购物,品质生活</span>
</div>
</a>
</header>
<!-- 购物车标题 -->
<div class="cart-title">
<h2>我的购物车</h2>
</div>
<!-- 购物车内容 -->
<div v-if="cartItems.length > 0">
<div class="cart-table">
<!-- 购物车表格 -->
<el-table :data="cartItems" style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column label="商品" min-width="400">
<template slot-scope="scope">
<div class="product-cell">
<img :src="scope.row.image" :alt="scope.row.name" class="product-image">
<div class="product-info">
<div class="product-name">{{ scope.row.name }}</div>
<div class="product-desc">{{ scope.row.description }}</div>
<el-select v-model="scope.row.selectedSpec" size="mini" class="spec-select" @change="updateSpec(scope.row)">
<el-option
v-for="spec in scope.row.specs"
:key="spec.value"
:label="spec.label"
:value="spec.value">
</el-option>
</el-select>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="单价" width="120" align="center">
<template slot-scope="scope">
<div class="price-cell">¥{{ scope.row.price.toFixed(2) }}</div>
</template>
</el-table-column>
<el-table-column label="数量" width="150" align="center">
<template slot-scope="scope">
<div class="quantity-cell">
<el-input-number
v-model="scope.row.quantity"
:min="1"
:max="99"
size="mini"
@change="updateQuantity(scope.row)">
</el-input-number>
</div>
</template>
</el-table-column>
<el-table-column label="小计" width="120" align="center">
<template slot-scope="scope">
<div class="subtotal">¥{{ (scope.row.price * scope.row.quantity).toFixed(2) }}</div>
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template slot-scope="scope">
<span class="delete-btn" @click="removeItem(scope.row)">删除</span>
</template>
</el-table-column>
</el-table>
</div>
<!-- 收货地址选择 -->
<div class="address-section">
<div class="address-title">
<i class="el-icon-location-outline"></i>
<span>收货地址</span>
</div>
<div class="address-list">
<div
v-for="(address, index) in addresses"
:key="index"
class="address-card"
:class="{active: selectedAddress === index}"
@click="selectAddress(index)">
<div class="address-name">{{ address.name }} {{ address.phone }}</div>
<div class="address-detail">{{ address.province }} {{ address.city }} {{ address.district }} {{ address.street }}</div>
<div class="address-actions">
<el-button type="text" @click.stop="editAddress(index)">编辑</el-button>
<el-button type="text" @click.stop="removeAddress(index)">删除</el-button>
</div>
</div>
<div class="address-card" @click="addNewAddress">
<div style="text-align: center; padding: 20px 0; color: #c81623;">
<i class="el-icon-plus" style="font-size: 24px; display: block; margin-bottom: 5px;"></i>
<div>添加新地址</div>
</div>
</div>
</div>
</div>
<!-- 底部操作栏 -->
<div class="cart-footer">
<div class="footer-left">
<div class="select-all">
<el-checkbox v-model="selectAll" @change="toggleSelectAll">全选</el-checkbox>
</div>
<div>
已选择 <span class="selected-count">{{ selectedItems.length }}</span> 件商品
</div>
</div>
<div class="footer-right">
<div>
合计:<span class="total-price">¥{{ totalPrice.toFixed(2) }}</span>
<span style="color: #999; font-size: 13px; margin-left: 5px;">(不含运费)</span>
</div>
<el-button
type="danger"
class="settlement-btn"
:disabled="selectedItems.length === 0"
@click="checkout">
去结算
</el-button>
</div>
</div>
</div>
<!-- 空购物车 -->
<div v-else class="empty-cart">
<img src="https://img11.360buyimg.com/imagetools/jfs/t1/186857/25/10011/5375/60d9e586Ee3b46c7a/5a3d5c5b0d3a7a9d.png" alt="空购物车">
<p>您的购物车空空如也,快去挑选心仪的商品吧!</p>
<a href="#" class="continue-shopping">继续购物</a>
</div>
<!-- 地址编辑弹窗 -->
<el-dialog title="编辑收货地址" :visible.sync="addressDialogVisible" width="500px">
<el-form :model="currentAddress" label-width="80px">
<el-form-item label="收货人">
<el-input v-model="currentAddress.name" placeholder="请输入收货人姓名"></el-input>
</el-form-item>
<el-form-item label="手机号码">
<el-input v-model="currentAddress.phone" placeholder="请输入手机号码"></el-input>
</el-form-item>
<el-form-item label="所在地区">
<el-cascader
v-model="currentAddress.region"
:options="regionOptions"
placeholder="请选择省市区"
style="width: 100%;"></el-cascader>
</el-form-item>
<el-form-item label="详细地址">
<el-input
v-model="currentAddress.street"
type="textarea"
:rows="3"
placeholder="请输入详细地址,如街道、门牌号等"></el-input>
</el-form-item>
<el-form-item label="设为默认">
<el-switch v-model="currentAddress.isDefault"></el-switch>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addressDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="saveAddress">确 定</el-button>
</span>
</el-dialog>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
// 购物车商品数据
cartItems: [
{
id: 1,
name: 'Apple iPhone 13 256GB 国行正品 全网通5G手机',
description: '全新国行,官方正品,全国联保',
image: 'https://img14.360buyimg.com/n1/s200x200_jfs/t1/213334/24/9509/167699/616d8d9aE7c89c58e/3a5d4b9a5b9b1e8c.jpg',
price: 6999.00,
quantity: 1,
specs: [
{ label: '256GB 星光色', value: '256GB-星光色' },
{ label: '256GB 午夜色', value: '256GB-午夜色' },
{ label: '256GB 蓝色', value: '256GB-蓝色' },
{ label: '512GB 星光色', value: '512GB-星光色' }
],
selectedSpec: '256GB 星光色'
},
{
id: 2,
name: '小米电视6 OLED 55英寸 4K超高清 HDR10+ 智能液晶电视机',
description: 'OLED屏幕,极致色彩,智能语音控制',
image: 'https://img10.360buyimg.com/n1/s200x200_jfs/t1/197519/35/11029/141950/616d8d9aE7c89c58e/3a5d4b9a5b9b1e8c.jpg',
price: 4999.00,
quantity: 1,
specs: [
{ label: '55英寸', value: '55英寸' },
{ label: '65英寸', value: '65英寸' }
],
selectedSpec: '55英寸'
},
{
id: 3,
name: '飞利浦电动牙刷HX6730/02 成人声波震动牙刷',
description: '3种清洁模式,智能计时,30天超长续航',
image: 'https://img12.360buyimg.com/n1/s200x200_jfs/t1/199876/28/10998/98765/616d8d9aE7c89c58e/3a5d4b9a5b9b1e8c.jpg',
price: 299.00,
quantity: 2,
specs: [
{ label: '标准版', value: '标准版' },
{ label: '旅行套装', value: '旅行套装' }
],
selectedSpec: '标准版'
}
],
// 选中的商品
selectedItems: [],
// 收货地址
addresses: [
{
name: '张三',
phone: '138****1234',
province: '北京市',
city: '北京市',
district: '海淀区',
street: '中关村大街1号',
isDefault: true
},
{
name: '李四',
phone: '139****5678',
province: '上海市',
city: '上海市',
district: '浦东新区',
street: '张江高科技园区',
isDefault: false
}
],
selectedAddress: 0,
// 地址编辑相关
addressDialogVisible: false,
currentAddress: {
name: '',
phone: '',
region: [],
street: '',
isDefault: false
},
regionOptions: [
{
value: '北京市',
label: '北京市',
children: [
{
value: '北京市',
label: '北京市',
children: [
{ value: '东城区', label: '东城区' },
{ value: '西城区', label: '西城区' },
{ value: '朝阳区', label: '朝阳区' },
{ value: '海淀区', label: '海淀区' },
{ value: '丰台区', label: '丰台区' },
{ value: '石景山区', label: '石景山区' }
]
}
]
},
{
value: '上海市',
label: '上海市',
children: [
{
value: '上海市',
label: '上海市',
children: [
{ value: '黄浦区', label: '黄浦区' },
{ value: '徐汇区', label: '徐汇区' },
{ value: '长宁区', label: '长宁区' },
{ value: '静安区', label: '静安区' },
{ value: '浦东新区', label: '浦东新区' },
{ value: '闵行区', label: '闵行区' }
]
}
]
},
{
value: '广东省',
label: '广东省',
children: [
{
value: '广州市',
label: '广州市',
children: [
{ value: '越秀区', label: '越秀区' },
{ value: '海珠区', label: '海珠区' },
{ value: '天河区', label: '天河区' },
{ value: '白云区', label: '白云区' }
]
},
{
value: '深圳市',
label: '深圳市',
children: [
{ value: '福田区', label: '福田区' },
{ value: '罗湖区', label: '罗湖区' },
{ value: '南山区', label: '南山区' },
{ value: '宝安区', label: '宝安区' }
]
}
]
}
]
}
},
computed: {
// 全选状态
selectAll: {
get() {
return this.selectedItems.length === this.cartItems.length && this.cartItems.length > 0;
},
set(value) {
if (value) {
this.selectedItems = [...this.cartItems];
} else {
this.selectedItems = [];
}
}
},
// 计算总价
totalPrice() {
return this.selectedItems.reduce((total, item) => {
return total + (item.price * item.quantity);
}, 0);
}
},
methods: {
// 选择/取消选择商品
handleSelectionChange(selection) {
this.selectedItems = selection;
},
// 全选/取消全选
toggleSelectAll(value) {
this.selectAll = value;
},
// 更新商品数量
updateQuantity(item) {
const index = this.cartItems.findIndex(i => i.id === item.id);
if (index !== -1) {
this.$set(this.cartItems, index, { ...item });
}
},
// 更新商品规格
updateSpec(item) {
const index = this.cartItems.findIndex(i => i.id === item.id);
if (index !== -1) {
this.$set(this.cartItems, index, { ...item });
}
},
// 删除商品
removeItem(item) {
this.cartItems = this.cartItems.filter(i => i.id !== item.id);
this.selectedItems = this.selectedItems.filter(i => i.id !== item.id);
},
// 选择收货地址
selectAddress(index) {
this.selectedAddress = index;
},
// 编辑地址
editAddress(index) {
const address = this.addresses[index];
this.currentAddress = {
name: address.name,
phone: address.phone,
region: [address.province, address.city, address.district],
street: address.street,
isDefault: address.isDefault
};
this.addressDialogVisible = true;
},
// 删除地址
removeAddress(index) {
if (this.addresses.length <= 1) {
this.$message.warning('至少保留一个收货地址');
return;
}
this.addresses.splice(index, 1);
if (this.selectedAddress >= this.addresses.length) {
this.selectedAddress = this.addresses.length - 1;
}
this.$message.success('地址已删除');
},
// 添加新地址
addNewAddress() {
this.currentAddress = {
name: '',
phone: '',
region: [],
street: '',
isDefault: false
};
this.addressDialogVisible = true;
},
// 保存地址
saveAddress() {
if (!this.currentAddress.name || !this.currentAddress.phone) {
this.$message.error('请填写收货人和手机号');
return;
}
if (this.currentAddress.region.length < 3) {
this.$message.error('请选择完整的省市区');
return;
}
if (!this.currentAddress.street) {
this.$message.error('请填写详细地址');
return;
}
const newAddress = {
name: this.currentAddress.name,
phone: this.currentAddress.phone,
province: this.currentAddress.region[0],
city: this.currentAddress.region[1],
district: this.currentAddress.region[2],
street: this.currentAddress.street,
isDefault: this.currentAddress.isDefault
};
if (this.currentAddress.isDefault) {
// 如果设为默认,取消其他地址的默认状态
this.addresses.forEach(addr => {
addr.isDefault = false;
});
}
this.addresses.push(newAddress);
this.selectedAddress = this.addresses.length - 1;
this.addressDialogVisible = false;
this.$message.success('地址保存成功');
},
// 结算
checkout() {
if (this.selectedItems.length === 0) {
this.$message.warning('请至少选择一件商品');
return;
}
const address = this.addresses[this.selectedAddress];
this.$alert('是否确认订单', '确认订单', {
dangerouslyUseHTMLString: true,
confirmButtonText: '确认提交',
callback: action => {
if (action === 'confirm') {
this.$message.success('订单提交成功!');
// 清空购物车中已选商品
this.cartItems = this.cartItems.filter(item =>
!this.selectedItems.some(selected => selected.id === item.id)
);
this.selectedItems = [];
}
}
});
}
},
mounted() {
// 初始化选中所有商品
this.selectedItems = [...this.cartItems];
}
});
</script>
<!--#
}
#-->
@@ -0,0 +1,270 @@
const PRODUCT_SECTION = {
template: /*language=HTML*/ `
<div class="product-section" :style="{ backgroundColor: sectionBg }">
<div class="section-header">
<h2 class="title">{{ sectionTitle }}</h2>
<div class="section-tabs">
<span
v-for="(tab, index) in tabs"
:key="index"
:class="{ active: activeTab === tab }"
@click="activeTab = tab">
{{ tab }}
</span>
</div>
<div class="more">
<a href="javascript:void(0)">更多 <i class="el-icon-arrow-right"></i></a>
</div>
</div>
<div class="product-content">
<div class="product-sidebar" v-if="sidebarProducts && sidebarProducts.length > 0">
<div
v-for="(product, index) in sidebarProducts"
:key="index"
class="sidebar-item"
:class="{ 'big-item': index === 0 }">
<a href="javascript:void(0)">
<img :src="product.image" :alt="product.name">
<div class="info">
<div class="name">{{ product.name }}</div>
<div class="price">¥{{ product.price }}</div>
</div>
</a>
</div>
</div>
<div class="product-list">
<div
v-for="(product, index) in displayedProducts"
:key="index"
class="product-item">
<a href="javascript:void(0)">
<div class="product-image">
<img :src="product.image" :alt="product.name">
</div>
<div class="product-info">
<div class="product-name">{{ product.name }}</div>
<div class="product-price">¥{{ product.price }}</div>
<div class="product-desc">{{ product.desc }}</div>
</div>
</a>
</div>
</div>
</div>
</div>
`,
props: {
sectionTitle: {
type: String,
required: true
},
products: {
type: Array,
required: true
},
sidebarProducts: {
type: Array,
default: () => []
},
sectionBg: {
type: String,
default: '#fff'
}
},
data() {
return {
activeTab: '推荐',
tabs: ['推荐', '热卖', '新品']
}
},
computed: {
displayedProducts() {
// 这里可以根据activeTab筛选不同类别的商品
// 为简化示例,这里只返回前8个商品
return this.products.slice(0, 8);
}
},
style: /*language=CSS*/ `
.product-section {
padding: 20px;
border-radius: 4px;
margin-bottom: 20px;
}
.section-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
.title {
font-size: 20px;
color: #333;
font-weight: bold;
flex: 1;
}
.section-tabs {
display: flex;
margin-right: 20px;
}
.section-tabs span {
margin: 0 10px;
cursor: pointer;
padding: 5px 10px;
border-radius: 15px;
font-size: 14px;
color: #666;
}
.section-tabs span.active {
background: #c81623;
color: #fff;
}
.more a {
color: #666;
font-size: 14px;
text-decoration: none;
}
.more a:hover {
color: #c81623;
}
.product-content {
display: flex;
gap: 20px;
}
.product-sidebar {
width: 200px;
display: flex;
flex-direction: column;
gap: 10px;
}
.sidebar-item {
border-radius: 4px;
overflow: hidden;
transition: all 0.3s;
}
.sidebar-item:hover {
transform: translateY(-3px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.sidebar-item a {
display: block;
color: #333;
text-decoration: none;
}
.sidebar-item img {
width: 100%;
height: 100px;
object-fit: cover;
}
.info {
padding: 10px;
background: #fff;
}
.name {
font-size: 14px;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.price {
color: #c81623;
font-weight: bold;
}
.big-item {
height: 210px;
}
.big-item img {
height: 150px;
}
.product-list {
flex: 1;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.product-item {
background: #fff;
border-radius: 4px;
overflow: hidden;
transition: all 0.3s;
}
.product-item:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transform: translateY(-3px);
}
.product-item a {
display: block;
color: #333;
text-decoration: none;
}
.product-image {
width: 100%;
height: 180px;
display: flex;
align-items: center;
justify-content: center;
background: #f9f9f9;
overflow: hidden;
}
.product-image img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.product-info {
padding: 12px;
}
.product-name {
font-size: 14px;
color: #333;
height: 40px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
margin-bottom: 8px;
}
.product-price {
color: #e4393c;
font-weight: bold;
font-size: 16px;
margin-bottom: 5px;
}
.product-desc {
font-size: 12px;
color: #999;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
`
}
@@ -0,0 +1,312 @@
const SIDEBAR = {
template: /*language=HTML*/ `
<div class="sidebar">
<ul class="category-list">
<li class="category-item"
v-for="category in categories"
:key="category.id"
@mouseenter="showSubCategories(category)"
@mouseleave="hideSubCategories">
<router-link :to="'/category/' + category.id" class="category-link">
<span class="category-name">{{ category.name }}</span>
<i class="el-icon-arrow-right"></i>
</router-link>
<!-- 二级分类面板 -->
<div class="sub-category-panel" v-if="activeCategory && activeCategory.id === category.id">
<div class="sub-category-content">
<div class="sub-category-group" v-for="group in category.children" :key="group.id">
<h3 class="sub-category-title">
<router-link :to="'/category/' + group.id">{{ group.name }}</router-link>
</h3>
<ul class="sub-category-list">
<li v-for="child in group.children" :key="child.id">
<router-link :to="'/category/' + child.id">{{ child.name }}</router-link>
</li>
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
`,
data() {
return {
categories: [],
activeCategory: null,
loading: false
}
},
methods: {
showSubCategories(category) {
this.activeCategory = category;
},
hideSubCategories() {
setTimeout(() => {
if (!this.$el.matches(':hover') && !this.$el.querySelector('.sub-category-panel:hover')) {
this.activeCategory = null;
}
}, 300);
},
async getCategories() {
this.loading = true;
try {
this.categories = [
{
"id": "1348576427268399553",
"name": "家用电器",
"parentId": "0",
"level": 0,
"sortOrder": 1,
"children": [
{
"id": "1348576427268399567",
"name": "生活电器",
"parentId": "1348576427268399553",
"level": 1,
"sortOrder": 0,
"children": [
{"id": "1348576427268399568", "name": "电风扇", "level": 2},
{"id": "1348576427268399569", "name": "吸尘器", "level": 2},
{"id": "1348576427268399570", "name": "加湿器", "level": 2},
{"id": "1348576427268399571", "name": "净水设备", "level": 2},
{"id": "1348576427268399572", "name": "饮水机", "level": 2}
]
},
{
"id": "1348576427268399580",
"name": "大家电",
"parentId": "1348576427268399553",
"level": 1,
"sortOrder": 1,
"children": [
{"id": "1348576427268399581", "name": "电视", "level": 2},
{"id": "1348576427268399582", "name": "空调", "level": 2},
{"id": "1348576427268399583", "name": "冰箱", "level": 2},
{"id": "1348576427268399584", "name": "洗衣机", "level": 2}
]
}
]
},
{
"id": "1348576427268399600",
"name": "手机通讯",
"parentId": "0",
"level": 0,
"sortOrder": 2,
"children": [
{
"id": "1348576427268399601",
"name": "手机",
"parentId": "1348576427268399600",
"level": 1,
"children": [
{"id": "1348576427268399602", "name": "智能手机", "level": 2},
{"id": "1348576427268399603", "name": "游戏手机", "level": 2},
{"id": "1348576427268399604", "name": "老人手机", "level": 2}
]
},
{
"id": "1348576427268399605",
"name": "运营商",
"parentId": "1348576427268399600",
"level": 1,
"children": [
{"id": "1348576427268399606", "name": "合约机", "level": 2},
{"id": "1348576427268399607", "name": "选号中心", "level": 2}
]
}
]
},
{
"id": "1348576427268399700",
"name": "电脑办公",
"parentId": "0",
"level": 0,
"sortOrder": 3,
"children": [
{
"id": "1348576427268399701",
"name": "笔记本",
"parentId": "1348576427268399700",
"level": 1,
"children": [
{"id": "1348576427268399702", "name": "轻薄本", "level": 2},
{"id": "1348576427268399703", "name": "游戏本", "level": 2},
{"id": "1348576427268399704", "name": "商务本", "level": 2}
]
},
{
"id": "1348576427268399710",
"name": "台式机",
"parentId": "1348576427268399700",
"level": 1,
"children": [
{"id": "1348576427268399711", "name": "游戏台式机", "level": 2},
{"id": "1348576427268399712", "name": "设计师主机", "level": 2}
]
}
]
},
{
"id": "1348576427268399800",
"name": "食品生鲜",
"parentId": "0",
"level": 0,
"sortOrder": 4,
"children": [
{
"id": "1348576427268399801",
"name": "水果",
"parentId": "1348576427268399800",
"level": 1,
"children": [
{"id": "1348576427268399802", "name": "苹果", "level": 2},
{"id": "1348576427268399803", "name": "香蕉", "level": 2},
{"id": "1348576427268399804", "name": "橙子", "level": 2}
]
},
{
"id": "1348576427268399810",
"name": "肉禽蛋",
"parentId": "1348576427268399800",
"level": 1,
"children": [
{"id": "1348576427268399811", "name": "猪肉", "level": 2},
{"id": "1348576427268399812", "name": "牛肉", "level": 2},
{"id": "1348576427268399813", "name": "鸡蛋", "level": 2}
]
}
]
}
]
} catch (error) {
console.error('获取分类失败:', error);
this.$message.error('获取分类数据失败');
} finally {
this.loading = false;
}
}
},
async created() {
await this.getCategories()
},
style: /*language=CSS*/ `
.sidebar {
width: 210px;
background: #222;
border-radius: 4px;
overflow: hidden;
}
.category-list {
list-style: none;
}
.category-item {
position: relative;
border-bottom: 1px solid #333;
}
.category-link {
display: block;
padding: 12px 15px;
color: #fff;
text-decoration: none;
font-size: 14px;
transition: all 0.3s;
position: relative;
}
.category-link:hover {
background: #c81623;
padding-left: 20px;
}
.category-link:hover .el-icon-arrow-right {
opacity: 1;
}
.category-name {
display: inline-block;
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
}
.el-icon-arrow-right {
position: absolute;
right: 15px;
opacity: 0;
transition: opacity 0.3s;
}
.sub-category-panel {
position: absolute;
left: 210px;
top: 0;
width: 700px;
min-height: 400px;
background: #fff;
border: 1px solid #e0e0e0;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 1000;
padding: 20px;
border-radius: 0 4px 4px 0;
}
.sub-category-content {
display: flex;
flex-wrap: wrap;
}
.sub-category-group {
width: 230px;
margin-right: 20px;
margin-bottom: 15px;
}
.sub-category-title {
font-size: 16px;
color: #333;
margin-bottom: 10px;
}
.sub-category-title a {
color: #333;
font-weight: bold;
text-decoration: none;
}
.sub-category-title a:hover {
color: #c81623;
}
.sub-category-list {
list-style: none;
}
.sub-category-list li {
padding: 5px 0;
}
.sub-category-list li a {
color: #666;
text-decoration: none;
font-size: 14px;
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: color 0.2s;
}
.sub-category-list li a:hover {
color: #c81623;
padding-left: 5px;
}
`
}
@@ -0,0 +1,255 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.home-page {
background-color: #f5f5f5;
}
.main-content {
padding: 20px 0;
}
.container {
width: 1200px;
margin: 0 auto;
}
.content-wrapper {
display: flex;
gap: 20px;
}
.content-area {
flex: 1;
}
</style>
<div id="app">
<div class="home-page">
<!-- 顶部导航 -->
<header-component></header-component>
<!-- 主内容区域 -->
<div class="main-content">
<div class="container">
<div class="content-wrapper">
<!-- 左侧分类导航 -->
<category-nav :categories="categoryData"
@category-selected="handleCategorySelect"></category-nav>
<!-- 右侧内容区域 -->
<div class="content-area">
<!-- 轮播图 -->
<banner :banners="banners"></banner>
<!-- 热门品牌 -->
<hot-brands :brands="hotBrands"></hot-brands>
<!-- 家用电器专区 -->
<product-section
section-title="家用电器"
:products="applianceProducts"
:sidebar-products="applianceSidebar"
section-bg="#f9f9f9"></product-section>
<!-- 手机数码专区 -->
<product-section
section-title="手机数码"
:products="digitalProducts"
:sidebar-products="digitalSidebar"
section-bg="#fff"></product-section>
<!-- 电脑办公专区 -->
<product-section
section-title="电脑办公"
:products="computerProducts"
:sidebar-products="computerSidebar"
section-bg="#f9f9f9"></product-section>
<!-- 食品生鲜专区 -->
<product-section
section-title="食品生鲜"
:products="foodProducts"
:sidebar-products="foodSidebar"
section-bg="#fff"></product-section>
</div>
</div>
</div>
</div>
<!-- 页脚 -->
<footer-component></footer-component>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return{
// 分类数据(简化版,实际应用中从API获取)
categoryData: [
{
"id": "1348576427268399553",
"name": "家用电器",
"parentId": "0",
"level": 0,
"children": [
{
"id": "1348576427268399567",
"name": "生活电器",
"parentId": "1348576427268399553",
"level": 1,
"children": [
{"id": "1348576427268399568", "name": "电风扇", "level": 2},
{"id": "1348576427268399569", "name": "吸尘器", "level": 2},
{"id": "1348576427268399570", "name": "加湿器", "level": 2},
{"id": "1348576427268399571", "name": "净水设备", "level": 2}
]
},
{
"id": "1348576427268399580",
"name": "大家电",
"parentId": "1348576427268399553",
"level": 1,
"children": [
{"id": "1348576427268399581", "name": "电视", "level": 2},
{"id": "1348576427268399582", "name": "空调", "level": 2},
{"id": "1348576427268399583", "name": "冰箱", "level": 2},
{"id": "1348576427268399584", "name": "洗衣机", "level": 2}
]
}
]
},
{
"id": "1348576427268399600",
"name": "手机通讯",
"parentId": "0",
"level": 0,
"children": [
{
"id": "1348576427268399601",
"name": "手机",
"parentId": "1348576427268399600",
"level": 1,
"children": [
{"id": "1348576427268399602", "name": "智能手机", "level": 2},
{"id": "1348576427268399603", "name": "游戏手机", "level": 2},
{"id": "1348576427268399604", "name": "老人手机", "level": 2}
]
}
]
},
{
"id": "1348576427268399700",
"name": "电脑办公",
"parentId": "0",
"level": 0,
"children": [
{
"id": "1348576427268399701",
"name": "笔记本",
"parentId": "1348576427268399700",
"level": 1,
"children": [
{"id": "1348576427268399702", "name": "轻薄本", "level": 2},
{"id": "1348576427268399703", "name": "游戏本", "level": 2}
]
}
]
}
],
// 轮播图数据
banners: [
{ id: 1, image: 'https://img10.360buyimg.com/cms/jfs/t1/206882/36/9500/185895/613f845aE6f4c0d13/7b8c6a5a5e9b6e3a.jpg', url: '#' },
{ id: 2, image: 'https://img14.360buyimg.com/cms/jfs/t1/196395/24/18927/188310/613f845aE3d0e6e57/3d0e8b9b8b8e3a9f.jpg', url: '#' },
{ id: 3, image: 'https://img12.360buyimg.com/cms/jfs/t1/178900/38/20300/177950/613f845aE7e9c9c5f/9d1b4c7b3d7b6e3a.jpg', url: '#' }
],
// 热门品牌
hotBrands: [
{ id: 1, name: 'Apple', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
{ id: 2, name: '华为', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
{ id: 3, name: '小米', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
{ id: 4, name: '格力', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
{ id: 5, name: '联想', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' }
],
// 家用电器商品
applianceProducts: [
{ id: 1, name: '美的电风扇FS40-15HR', price: 199.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
{ id: 2, name: '戴森V11吸尘器', price: 4999.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
{ id: 3, name: '小米加湿器2', price: 199.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 4, name: '海尔净水器HRO75H1', price: 1299.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 5, name: '格力冷风扇', price: 599.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 6, name: '飞利浦空气净化器', price: 1599.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
],
applianceSidebar: [
{ id: 1, name: '电视', image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 2, name: '空调', image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 3, name: '冰箱', image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
],
// 手机数码商品
digitalProducts: [
{ id: 7, name: '华为Mate 50 Pro', price: 6999.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
{ id: 8, name: '小米13 Ultra', price: 5999.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 9, name: 'iPhone 14 Pro', price: 8999.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
{ id: 10, name: 'vivo X90 Pro+', price: 4999.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 11, name: 'OPPO Find X6', price: 4499.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 12, name: '荣耀Magic5 Pro', price: 4699.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
],
digitalSidebar: [
{ id: 1, name: '手机配件', image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 2, name: '智能手表', image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 3, name: '耳机', image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
],
// 电脑办公商品
computerProducts: [
{ id: 13, name: '联想拯救者Y9000P', price: 8999.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
{ id: 14, name: 'MacBook Pro 14', price: 15999.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
{ id: 15, name: '华为MateBook X Pro', price: 8999.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 16, name: '戴尔XPS 13', price: 9999.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 17, name: '惠普暗影精灵9', price: 6999.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 18, name: '外星人m16', price: 12999.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
],
computerSidebar: [
{ id: 1, name: '台式机', image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 2, name: '平板电脑', image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 3, name: '办公设备', image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
],
// 食品生鲜商品
foodProducts: [
{ id: 19, name: '五常大米5kg', price: 69.90, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 20, name: '进口牛排10片装', price: 199.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
{ id: 21, name: '智利车厘子5kg', price: 299.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 22, name: '阳澄湖大闸蟹4只装', price: 258.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
{ id: 23, name: '每日坚果750g', price: 89.90, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 24, name: '进口橄榄油500ml', price: 79.90, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
],
foodSidebar: [
{ id: 1, name: '新鲜水果', image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
{ id: 2, name: '肉禽蛋品', image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
{ id: 3, name: '海鲜水产', image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
]
}
},
methods: {
handleCategorySelect(category) {
console.log('Selected category:', category)
// 这里可以添加跳转到分类页面的逻辑
// this.$router.push({ name: 'category', params: { id: category.id } })
}
},
created() {
},
});
</script>
<!--#
}
#-->
@@ -0,0 +1,127 @@
const ADD_GOODS_FIRST = {
template: /*language=HTML*/ `
<div>
<!-- 商品分类 -->
<div class="content-goods-publish">
<div class="goods-category">
<ul v-if="categoryListLevel1.length > 0">
<li
v-for="(item, index) in categoryListLevel1"
:class="{ activeClass: category[0].name === item.name }"
@click="handleSelectCategory(item, index, 1)"
:key="index"
>
<span>{{ item.name }}</span>
<span>&gt;</span>
</li>
</ul>
<ul v-if="categoryListLevel2.length > 0">
<li
v-for="(item, index) in categoryListLevel2"
:class="{ activeClass: category[1].name === item.name }"
@click="handleSelectCategory(item, index, 2)"
:key="index"
>
<span>{{ item.name }}</span>
<span>&gt;</span>
</li>
</ul>
<ul v-if="categoryListLevel3.length > 0">
<li
v-for="(item, index) in categoryListLevel3"
:class="{ activeClass: category[2].name === item.name }"
@click="handleSelectCategory(item, index, 3)"
:key="index"
>
<span>{{ item.name }}</span>
</li>
</ul>
</div>
<p class="current-goods-category">
您当前选择的商品类别是:
<span>{{ category[0].name }}</span>
<span v-show="category[1].name">> {{ category[1].name }}</span>
<span v-show="category[2].name">> {{ category[2].name }}</span>
</p>
</div>
<!-- 底部按钮 -->
<div class="footer">
<el-button-group>
<el-button type="primary" @click="next">下一步</el-button>
</el-button-group>
</div>
</div>
`,
data(){
return {
// 商品分类选择数组
category: [
{ name: "", id: "" },
{ name: "", id: "" },
{ name: "", id: "" },
],
// 商品类型
goodsType: "PHYSICAL_GOODS",
/** 1级分类列表*/
categoryListLevel1: [],
/** 2级分类列表*/
categoryListLevel2: [],
/** 3级分类列表*/
categoryListLevel3: [],
}
},
methods: {
/** 选择商城商品分类 */
handleSelectCategory(row, index, level) {
if (level === 1) {
this.category.forEach((cate) => {
(cate.name = ""), (cate.id = "");
});
this.category[0].name = row.name;
this.category[0].id = row.id;
this.categoryListLevel2 = this.categoryListLevel1[index].children;
this.categoryListLevel3 = [];
} else if (level === 2) {
this.category[1].name = row.name;
this.category[1].id = row.id;
this.category[2].name = "";
this.category[2].id = "";
this.categoryListLevel3 = this.categoryListLevel2[index].children;
} else {
this.category[2].name = row.name;
this.category[2].id = row.id;
}
},
/** 查询下一级 商城商品分类*/
getAllCategory() {
this.$axios.post('/platform/mall/category/manage/allChildren').then((res) => {
if (res.code === 0 && res.data) {
this.categoryListLevel1 = res.data;
}
});
},
// 下一步
next() {
window.scrollTo(0, 0);
if (!this.category[0].name) {
this.$message.error("请选择商品分类");
} else if (!this.category[2].name) {
this.$message.error("必须选择到三级分类");
} else if (this.category[2].name) {
let params = {
category: this.category,
goodsType: this.goodsType,
};
this.$emit("change", params);
}
},
},
mounted() {
this.getAllCategory();
},
style: /*language=CSS*/ `
/deep/ .ivu-scroll-container {
height: 450px !important;
}
`,
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
const ADD_GOODS_THIRD = {
template: /*language=HTML*/ `
`,
data(){
return {
}
},
methods: {
},
}
@@ -0,0 +1,67 @@
<!--#
layout("/layouts/platform.html"){
#-->
<link rel="stylesheet" href="${base!}/assets/platform/module/mall/addGoods.css" />
<div id="app">
<div>
<div class="step-list">
<el-steps :active="activestep" align-center finish-status="success">
<el-step title="选择商品品类"></el-step>
<el-step title="填写商品详情"></el-step>
<el-step title="商品发布成功"></el-step>
</el-steps>
</div>
<!-- 第一步 选择分类 -->
<first-step ref='first' v-show="activestep === 0" @change="getFirstData"></first-step>
<!-- 第二步 商品详细信息 -->
<second-step ref='second' :first-data="firstData" v-if="activestep === 1"></second-step>
<!-- 第三步 发布完成 -->
<third-step ref='third' v-if="activestep === 2"></third-step>
</div>
</div>
<script>
<!--#include("addGoodsFirst.js"){}#-->
<!--#include("addGoodsSecond.js"){}#-->
<!--#include("addGoodsThird.js"){}#-->
const vue = new Vue({
el: '#app',
data(){
return {
/** 当前激活步骤*/
activestep: 0,
firstData: {}, // 第一步传递的数据
id: ''
}
},
components: {
'first-step': ADD_GOODS_FIRST,
'second-step': ADD_GOODS_SECOND,
'third-step': ADD_GOODS_THIRD,
},
methods: {
// 选择商品分类回调
getFirstData (item) {
this.firstData = item;
this.activestep = 1;
}
},
created () {
this.id = GetQueryString("id")
},
mounted () {
// 编辑商品、模板
if (this.id) {
this.activestep = 1;
} else {
this.activestep = 0
// this.$refs.first.selectGoodsType = true;
}
}
});
</script>
<!--#
}
#-->
@@ -0,0 +1,411 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<el-card>
<!-- 顶部按钮 -->
<div style="margin-bottom:10px">
<el-button type="primary" icon="el-icon-plus" @click="addParent">
添加一级分类
</el-button>
</div>
<!-- 表格 -->
<el-table
row-key="id"
:data="tableData"
style="width:100%"
lazy
:load="loadChildren"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="分类名称" prop="name"></el-table-column>
<el-table-column label="当前层级" prop="level">
<template slot-scope="{ row }">
{{ (row.level + 1) + '级' }}
</template>
</el-table-column>
<!-- 状态列 -->
<el-table-column label="状态" prop="delFlag">
<template slot-scope="{ row }">
<el-tag :type="row.delFlag ? 'danger' : 'success'">
{{ !row.delFlag ? '正常启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<!-- 你的业务列请自行补充 -->
<el-table-column label="操作" width="260">
<template slot-scope="scope">
<!-- 通用操作下拉 -->
<el-dropdown trigger="click" style="margin-right:6px">
<el-button size="mini">
操作<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="edit(scope.row)">
编辑
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.delFlag == true"
@click.native="enable(scope.row)"
>
启用
</el-dropdown-item>
<el-dropdown-item
v-if="scope.row.delFlag == false"
@click.native="disable(scope.row)"
>
禁用
</el-dropdown-item>
<el-dropdown-item @click.native="remove(scope.row)">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- 添加子分类(level ≠ 2 时显示) -->
<el-button
v-if="scope.row.level !== 2"
type="primary"
size="mini"
icon="el-icon-plus"
@click="addChildren(scope.row)"
>
添加子分类
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 新增/编辑分类弹窗 -->
<el-dialog
:title="modalTitle"
:visible.sync="modalVisible"
width="40%"
:close-on-click-modal="false"
>
<el-form ref="form" :model="formAdd" label-width="100px" :rules="formValidate">
<el-form-item
v-if="showParent"
label="上级分类"
prop="parentId"
style="display:none"
>
<el-input v-model="formAdd.parentId" placeholder="请输入上级分类" clearable></el-input>
</el-form-item>
<el-form-item label="层级" prop="level" style="display:none">
<el-input v-model="formAdd.level" placeholder="请输入层级" clearable></el-input>
</el-form-item>
<el-form-item label="分类名称" prop="name">
<el-input v-model="formAdd.name" placeholder="请输入分类名称" clearable></el-input>
</el-form-item>
<el-form-item v-if="formAdd.level !== 1" label="分类图标" prop="image">
<file-upload
:value.sync="formAdd.image"
:upload_number="1"
upload_mode="image"
upload_result_category="interval"
upload_result_type="url"
></file-upload>
<!--<upload-pic-input
v-model="formAdd.image"
style="width:100%"></upload-pic-input>-->
</el-form-item>
<el-form-item label="排序值" prop="sortOrder">
<el-input-number v-model="formAdd.sortOrder"></el-input-number>
</el-form-item>
<el-form-item label="是否启用" prop="delFlag">
<el-switch
v-model="formAdd.delFlag"
:active-value="false"
:inactive-value="true"
active-text="启用"
inactive-text="禁用"
></el-switch>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="modalVisible = false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="Submit">提交</el-button>
</div>
</el-dialog>
</el-card>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
recordLevel:[], // 记录当前层级
submitLoading: false, //加载状态
categoryList: [], // 分类列表
loading: false, // 加载状态
brands: [], //品牌集合
specifications: [], //规格集合
categoryId: "", // 分类id
categorySpecs: [], //已经选择的规格
modalType: 0, // 添加或编辑标识
modalVisible: false, // 添加或编辑显示
modalBrandVisible: false, //品牌关联编辑显示
modalSpecVisible: false, //品牌关联编辑显示
modalTitle: "", // 添加或编辑标题
showParent: false, // 是否展示上级菜单
parentTitle: "", // 父级菜单名称
modalBrandTitle: "", // 品牌弹窗标题
modalSpecTitle: "", // 规格弹窗标题
formAdd: {
// 添加或编辑表单对象初始化数据
parentId: "",
name: "",
image: "",
sortOrder: 0,
delFlag: 0,
level: 0,
},
brandForm: {
categoryBrands: [],
},
brandWay: "", //请求绑定品牌的信息
specForm: {}, // 规格数据
// 表单验证规则
formValidate: {
name: [{required: true, message: "请输入分类名称", trigger: ["blur", "change"]}],
sortOrder: [{required: true, message: "请输入排序值", trigger: ["blur", "change"]}],
},
tableColumns: [
{label: "分类名称", prop: "name"},
{label: "状态", prop: "delFlag"},
{label: "操作", prop: "action"},
],
tableData: [], // 表格数据
checkedCategoryChildren: "", //选中的分类子级
};
},
methods: {
// 初始化数据
init() {
this.getAllList(0);
},
// 添加子分类
addChildren(v) {
this.modalType = 0;
this.modalTitle = "添加子分类";
this.parentTitle = v.name;
this.formAdd.level = eval(v.level + "+1");
this.formAdd.commissionRate = v.commissionRate;
this.showParent = true;
delete this.formAdd.id;
this.formAdd.parentId = v.id;
this.modalVisible = true;
},
// 编辑分类
edit(v) {
this.modalType = 1;
this.modalTitle = "编辑";
this.formAdd.id = v.id;
this.formAdd.name = v.name;
this.formAdd.level = v.level;
this.formAdd.parentId = v.parentId;
this.formAdd.sortOrder = v.sortOrder;
this.formAdd.commissionRate = v.commissionRate;
this.formAdd.delFlag = v.delFlag;
this.formAdd.image = v.image;
this.showParent = false;
this.modalVisible = true;
},
// 添加一级分类
addParent() {
this.modalType = 0;
this.modalTitle = "添加一级分类";
this.parentTitle = "顶级分类";
this.showParent = true;
// this.$refs.form.resetFields();
delete this.formAdd.id;
this.formAdd.parentId = 0;
this.modalVisible = true;
},
// 提交
Submit() {
this.$refs.form.validate((valid) => {
if (valid) {
this.submitLoading = true;
if (this.modalType === 0) {
// 添加 避免编辑后传入id等数据 记得删除
delete this.formAdd.id;
this.$axios.post("/platform/mall/category/manage/saveCategory", this.formAdd).then((res) => {
this.submitLoading = false;
if (res.code === 0) {
this.$message.success("添加成功");
this.getAllList();
this.modalVisible = false;
// this.$refs.form.resetFields();
} else {
this.$message.error(res.message);
}
});
} else {
// 编辑
this.$axios.post("/platform/mall/category/manage/updateCategory", this.formAdd).then((res) => {
this.submitLoading = false;
if (res.code === 0) {
this.$message.success("修改成功");
this.getAllList();
this.modalVisible = false;
// this.$refs.form.resetFields();
} else {
this.$message.error(res.message);
}
});
}
}
});
},
// 删除分类
remove(v) {
this.$confirm("确定要删除 " + v.name + " ", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/mall/category/manage/delAllByIds", {
id: v.id
}).then((res) => {
if (res.code === 0) {
this.$message.success("操作成功");
this.getAllList();
} else {
this.$message.error(res.message);
}
});
})
},
// 异步手动加载分类名称
loadChildren(row, treeNode, resolve) {
// 记录层级(可选)
this.recordLevel[row.level] = row.id;
if (row.level === 0) {
// 根节点 -> 拿一级子节点
const children = this.categoryList
.find(item => item.id === row.id)
?.children || [];
// 给下一级节点加 hasChildren
children.forEach(child => {
child.hasChildren = !!(child.children && child.children.length);
});
setTimeout(() => resolve(children), 100);
} else {
// 非根节点 -> 用你原来的递归方法
this.deepCategoryChildren(row.id, this.categoryList);
setTimeout(() => {
const list = this.checkedCategoryChildren || [];
list.forEach(item => {
item.hasChildren = !!(item.children && item.children.length);
});
resolve(list);
}, 100);
}
},
// 通过递归children来实现手动加载数据
deepCategoryChildren(id, list) {
if (id != "0" && list.length != 0) {
for (let i = 0; i < list.length; i++) {
let item = list[i];
if (item.id == id) {
this.checkedCategoryChildren = item.children;
return;
} else {
this.deepCategoryChildren(id, item.children);
}
}
}
},
// 获取分类数据
getAllList() {
this.loading = true;
this.$axios.post("/platform/mall/category/manage/allChildren").then((res) => {
this.loading = false;
if (res.code === 0) {
localStorage.setItem("category", JSON.stringify(res.data));
this.categoryList = JSON.parse(JSON.stringify(res.data));
this.tableData = res.data
// this.tableData = res.data.map((item) => {
// if(this.recordLevel[0] && item.id === this.recordLevel[0]) {
// item._showChildren = true
// // 继续判断第二层
// if(this.recordLevel[1] && item.children){
// item.children.map((child)=>{
// if(this.recordLevel[1] && child.id === this.recordLevel[1]){
// child._showChildren = true
// }
// })
// }
// }else{
// if (item.children.length !== 0) {
// item.children = [];
// item._loading = false;
// }
// }
// return item;
// });
}
});
},
// 启用分类
enable(v) {
this.$confirm("您是否要启用当前分类 " + v.name + " 及其子分类?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/mall/category/manage/disable", {
id: v.id,
enableOperations: false
}).then((res) => {
if (res.code === 0) {
this.$message.success("操作成功");
this.getAllList(0);
} else {
this.$message.error(res.message);
}
});
})
},
// 禁用分类
disable(v) {
this.$confirm("您是否要启用当前分类 " + v.name + " 及其子分类?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/mall/category/manage/disable", {
id: v.id,
enableOperations: true
}).then((res) => {
if (res.code === 0) {
this.$message.success("操作成功");
this.getAllList(0);
} else {
this.$message.error(res.message);
}
});
})
},
},
mounted() {
this.init();
},
});
</script>
<!--#
}
#-->
@@ -373,7 +373,7 @@
},
findOne(id) {
this.$axios.post('/platform/difficultyHelp/view/findOne', { id }).then(res => {
this.$axios.post('/platform/difficultHelp/mine/findOne', { id }).then(res => {
if (res.code === 0) {
this.formData = res.data
}
@@ -3,86 +3,229 @@ layout("/layouts/platform.html"){
#-->
<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>
<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>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="申请记录">
<el-button size="small" type="primary" @click="onApply">帮扶申请</el-button>
</table-tool>
<snaker-start slot="header" label="困难帮扶申请" define_key="KNBF"></snaker-start>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="3" border>
<el-descriptions-item label="填写人姓名">
<el-form-item prop="proxyUserName">
<el-input readonly v-model="formData.proxyUserName"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="填写人工号">
<el-form-item prop="proxyLoginName">
<el-input readonly v-model="formData.proxyLoginName"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="申请模式">
<el-form-item prop="mode">
<el-select v-model="formData.mode" placeholder="申请模式">
@change="modeChange" style="width: 100%">
<el-option label="本人申请" value="1"></el-option>
<el-option v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, BRANCH_UNION_CHAIRMAN, BRANCH_UNION_OPERATOR')"
label="替他人申请" value="2"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="受补助人">
<template v-if="formData.mode == 2">
<el-select :remote-method="queryRecipients"
@change="userChange" clearable filterable
placeholder="输入工号或者姓名查找" remote
style="width: 100%" v-model="formData.userId">
<el-option :key="o.id"
:label="o.username+'('+o.loginname+')'"
:value="o.id"
v-for="o in subsidizedList"></el-option>
</el-select>
</template>
<template v-else>
<el-input readonly maxlength="100" type="text"
v-model="formData.userName"></el-input>
</template>
</el-descriptions-item>
<el-descriptions-item label="性别">
<el-form-item prop="sex">
<el-select v-model="formData.sex" placeholder="请选择性别" clearable style="width: 100%">
<el-option v-for="item in ['男性','女性']" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="出生年月">
<el-form-item prop="birthday">
<el-date-picker
clearable
style="width: 100%"
v-model="formData.birthday"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择出生年月">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属单位">
<el-form-item prop="unitName">
<el-input maxlength="50" clearable placeholder="所在单位"
readonly v-model="formData.unitName"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属工会">
<el-form-item prop="unionName">
<el-input maxlength="50" clearable placeholder="所属工会"
readonly v-model="formData.unionName"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="职务职称">
<el-form-item prop="officialCapacity">
<el-input maxlength="20" clearable placeholder="请填写职务职称"
v-model="formData.officialCapacity"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="手机号码">
<el-form-item prop="mobile">
<el-input maxlength="11" clearable placeholder="请填写手机号码"
v-model="formData.mobile" maxlength="11"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="身份证号" :span="2">
<el-form-item prop="idCard">
<el-input maxlength="20" clearable placeholder="请填写身份证号"
v-model="formData.idCard" maxlength="18"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="本人月收入">
<el-form-item prop="monthlyIncome">
<el-input-number clearable
style="width: 100%"
v-model="formData.monthlyIncome"
:min="0"
:max="9999999"
placeholder="请填写本人月收入">
</el-input-number>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="收款账户" :span="2">
<el-form-item prop="bankCardNum">
<el-input maxlength="20" clearable placeholder="请填写华夏银行工资卡号"
v-model="formData.bankCardNum"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="困难类型" :span="3">
<el-form-item prop="subsidyStandards">
<el-select v-model="formData.subsidyStandards" style="width: 100%">
<el-option v-for="(item,index) in subsidyStandards" :key="index" :label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="申请原因" :span="3">
<el-form-item prop="reason">
<el-input maxlength="500" :autosize="{ minRows: 5, maxRows: 10}"
placeholder="请简述申请原因"
clearable
show-word-limit
v-model="formData.reason"
type="textarea"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="家庭成员经济收入" :span="3">
<el-form-item prop="familyList">
<el-table :data="formData.familyList" border max-height="500" size="mini" style="width: 100%">
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
<el-table-column prop="name" label="姓名">
<template slot-scope="{row,$index}">
<el-form-item label-width="0"
:prop="'familyList.'+$index+'.name'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input v-model="row.name" placeholder="请输入姓名" clearable></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="relation" label="年龄(岁)">
<template slot-scope="{row,$index}">
<el-form-item label-width="0"
:prop="'familyList.'+$index+'.age'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number v-model="row.age" placeholder="请输入年龄" :min="1"
:max="100" :step="1" style="width: 100%" clearable></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="relation" label="关系">
<template slot-scope="{row,$index}">
<el-form-item label-width="0"
:prop="'familyList.'+$index+'.relation'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input v-model="row.relation" placeholder="请输入关系" clearable></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="monthlyIncome" label="月收入(元)">
<template slot-scope="{row,$index}">
<el-form-item label-width="0"
:prop="'familyList.'+$index+'.monthlyIncome'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number v-model="row.monthlyIncome" placeholder="请输入月收入"
:min="1" :step="1" style="width: 100%" clearable></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.familyList.push({})" icon="el-icon-plus" type="primary"
size="mini">添加
</el-button>
</template>
<template slot-scope="scope">
<el-button @click="formData.familyList.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="3">
<el-form-item prop="files">
<file-upload :value.sync="formData.files"
upload_mode="drag"
:upload_number="10" upload_result_category="array"
complete_result></file-upload>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="3">
<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=='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>
<!--#include("/layouts/pagination.html"){}#-->
<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>
@@ -92,82 +235,265 @@ layout("/layouts/platform.html"){
store,
data() {
return {
pageForm: {
year: this.$moment().format("YYYY")
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formData: {
id: GetQueryString("bizId"),
mode: '1'
},
tableColumns: [
{ prop: "loginName", label: "工号", sortable: true },
{ prop: "userName", label: "姓名", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
unions: [],
units: []
subsidyStandards: [
'患重大疾病(癌症)',
'本人家庭(仅指代本人及其配偶、子女共同组成的家庭)人均月收入低于1300元或本人配偶、子女患有重大疾病且自付医疗费用超过家庭年收入的80%',
'患精神类疾病',
'长期病休',
'其他特殊情况'
],
formRules: {
proxyUserName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
proxyLoginName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
sex: [{required: true, message: '必填', trigger: ['blur', 'change']}],
unitName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
unionName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
monthlyIncome: [{required: true, message: '必填', trigger: ['blur', 'change']}],
mobile: [{required: true, message: '必填', trigger: ['blur', 'change']}],
idCard: [{required: true, message: '必填', trigger: ['blur', 'change']}],
bankCardNum: [{required: true, message: '必填', trigger: ['blur', 'change']}],
officialCapacity: [{required: true, message: '必填', trigger: ['blur', 'change']}],
subsidyStandards: [{required: true, message: '必填', trigger: ['blur', 'change']}],
reason: [{required: true, message: '必填', trigger: ['blur', 'change']}],
sign: [{required: true, message: '必填', trigger: ['blur', 'change']}]
},
// 替他人申请相关
subsidizedList: []
}
},
methods: {
onApply() {
window.open("/flow/common/approval/form?defineKey=KNBF")
},
openView(row) {
window.open("/flow/common/approval/form?instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=KNBF")
},
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/difficultHelp/apply/onDelete", { id }).then((res) => {
this.$axios.post('/platform/difficultHelp/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/difficultHelp/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)
// 提交
onSubmit() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/difficultHelp/apply/submit', {
data: JSON.stringify(this.formData)
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/difficultHelp/mine'
}
})
})
},
onFinishTask() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/difficultHelp/apply/submitAgain', {
data: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/difficultHelp/mine'
}
})
})
},
// 查询受助人
queryRecipients(key) {
this.$axios.get("/platform/difficultHelp/apply/queryRecipients", {
key
}).then(res => {
if (res.code === 0) {
this.subsidizedList = res.data
}
})
},
findOne(id) {
this.$axios.post('/platform/difficultHelp/mine/findOne', { id }).then(res => {
if (res.code === 0) {
this.formData = res.data
}
})
},
async userChange() {
const user = this.subsidizedList.find(item => item.id === this.formData.userId)
if (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, 'sex', user.sex)
this.$set(this.formData, 'unitId', user.unitId)
this.$set(this.formData, 'unitName', user.unitName)
this.$set(this.formData, 'unionId', user.unionId)
this.$set(this.formData, 'unionName', user.unionName)
this.$set(this.formData, 'birthday', user.birthday)
this.$set(this.formData, 'mobile', user.mobile)
} else {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
this.$set(this.formData, 'userId', null)
this.$set(this.formData, 'userName', null)
this.$set(this.formData, 'loginName', null)
this.$set(this.formData, 'sex', null)
this.$set(this.formData, 'unitId', null)
this.$set(this.formData, 'unitName', null)
this.$set(this.formData, 'unionId', null)
this.$set(this.formData, 'unionName', null)
this.$set(this.formData, 'birthday', null)
this.$set(this.formData, 'mobile', null)
}
},
// 申请模式
modeChange(val) {
const user = this.$store.state.user
if (val === "1") {
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, 'proxyUserId', user.id)
this.$set(this.formData, 'proxyUserName', user.username)
this.$set(this.formData, 'proxyLoginName', user.loginname)
this.$set(this.formData, 'mode', "1")
this.$set(this.formData, 'sex', user.sex)
this.$set(this.formData, 'unitId', user.unit.id)
this.$set(this.formData, 'unitName', user.unit.name)
this.$set(this.formData, 'unionId', user.union.id)
this.$set(this.formData, 'unionName', user.union.name)
this.$set(this.formData, 'monthlyIncome', null)
this.$set(this.formData, 'birthday', user.birthday)
this.$set(this.formData, 'mobile', user.mobile)
this.$set(this.formData, 'homeAddress', user.homeAddress)
this.$set(this.formData, 'subsidyStandards', null)
this.$set(this.formData, 'reason', null)
this.$set(this.formData, 'remarks', null)
this.$set(this.formData, 'familyList', [])
this.$set(this.formData, 'files', [])
this.queryRecipients(user.loginname)
} else {
this.formData = {}
this.$set(this.formData, 'proxyUserId', user.id)
this.$set(this.formData, 'proxyUserName', user.username)
this.$set(this.formData, 'proxyLoginName', user.loginname)
this.$set(this.formData, 'mode', "2")
this.$set(this.formData, 'familyList', [])
this.$set(this.formData, 'files', [])
}
},
/**
* 检验身份证号
* @param idCard
* @returns {{status: number, msg: string}}
*/
isValidIdCard(idCard) {
// 校验18位身份证号
const format18 = /^(((([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([5][0-4])|([6][1-5])|([7][1])|([8][1-2]))\d{4})|(([9](([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([5][0-4])|([6][1-5])|([7][1])|([8][1-2])))\d{3}))(([1][9]\d{2})|([2]\d{3}))(([0][1-9])|([1][0-2]))(([0][1-9])|([1-2][0-9])|([3][0-1]))\d{3}[0-9xX]$/;
// 校验15位身份证号
const format15 = /^\d{15}$/;
// 校验外国人永久居留身份证号
const format15Foreign = /^[a-zA-Z]{3}[0-9]{4}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{2}$/;
// 校验格式
if (!(format18.test(idCard) || format15.test(idCard) || format15Foreign.test(idCard))) {
return { status: 0, msg: '身份证号码格式不正确' };
}
// 校验出生日期
let year, month, day;
if (idCard.length === 18) {
year = idCard.substr(6, 4);
month = idCard.substr(10, 2);
day = idCard.substr(12, 2);
} else if (idCard.length === 15) {
year = '19' + idCard.substr(6, 2);
month = idCard.substr(8, 2);
day = idCard.substr(10, 2);
} else {
return { status: 0, msg: '身份证号码格式不正确' };
}
const date = new Date(year, month - 1, day);
if (date.getFullYear() !== parseInt(year, 10) || date.getMonth() + 1 !== parseInt(month, 10) || date.getDate() !== parseInt(day, 10)) {
return { status: 0, msg: '身份证出生日期不正确' };
}
// 校验18位身份证号的校验码
if (idCard.length === 18) {
const coefficients = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
const checkCodeMap = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
let sum = 0;
for (let i = 0; i < 17; i++) {
sum += parseInt(idCard.charAt(i), 10) * coefficients[i];
}
const checkCode = checkCodeMap[sum % 11];
if (checkCode.toUpperCase() !== idCard.charAt(17).toUpperCase()) {
return { status: 0, msg: '身份证校验码不正确' };
}
}
return { status: 1, msg: '校验通过' };
},
/**
* 校验银行卡号
* @param bankCardNum
* @returns {{status: number, msg: string}}
*/
validateCard(bankCardNum) {
// 移除所有空格
bankCardNum = bankCardNum.replace(/\s+/g, '');
// 检查格式
const cardRegex = /^\d{13,19}$/;
if (!cardRegex.test(bankCardNum)) {
return { status: 0, msg: "银行卡号格式不正确,请输入13到19位数字。" };
}
// 检查Luhn算法
if (!/^\d+$/.test(bankCardNum)) {
return { status: 0, msg: "无效的卡号,请检查后再试。" };
}
let sum = 0;
let shouldDouble = false;
for (let i = bankCardNum.length - 1; i >= 0; i--) {
let digit = parseInt(bankCardNum.charAt(i));
if (shouldDouble) {
digit *= 2;
if (digit > 9) {
digit -= 9;
}
}
sum += digit;
shouldDouble = !shouldDouble;
}
if ((sum % 10) !== 0) {
return { status: 0, msg: "无效的卡号,请检查后再试。" };
}
return { status: 200, msg: "卡号有效。" };
}
},
async created() {
this.pageData()
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')) {
this.unions = await this.$businessTool.listUnion()
if (this.bizId) {
this.findOne(this.bizId)
} else {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
this.modeChange("1")
}
}
})
@@ -2,86 +2,113 @@
layout("/layouts/platform.html"){
#-->
<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>
<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>
</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=='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 scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="openRevoke(row)" size="mini" type="danger">
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<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 @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>
</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=='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],
@@ -103,18 +130,68 @@ layout("/layouts/platform.html"){
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
units: []
units: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row) {
window.open("/flow/common/approval/form?instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=KNBF")
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.onOpen(row)
})
},
openRevoke(row) {
console.log(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)
@@ -0,0 +1,134 @@
const INFO = {
template: /*language=HTML*/ `
<div>
<div class="process-title">申请信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div>
<el-descriptions :column="3" border>
<el-descriptions-item label="填写人姓名">{{ viewData.proxyUserName }}</el-descriptions-item>
<el-descriptions-item label="填写人工号">{{ viewData.proxyLoginName }}</el-descriptions-item>
<el-descriptions-item label="申请模式">{{ viewData.mode == 1 ? '本人申请' : '替他人申请' }}
</el-descriptions-item>
<el-descriptions-item label="受助人">{{ viewData.userName + '(' + viewData.loginName + ')' }}
</el-descriptions-item>
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
<el-descriptions-item label="出生年月">{{ viewData.birthday }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="所属单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="职务职称">{{ viewData.officialCapacity }}</el-descriptions-item>
<el-descriptions-item label="手机号码">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="身份证号" :span="2">{{ viewData.idCard }}</el-descriptions-item>
<el-descriptions-item label="月收入">{{ viewData.monthlyIncome }}</el-descriptions-item>
<el-descriptions-item label="收款账户" :span="2">{{ viewData.bankCardNum }}</el-descriptions-item>
<el-descriptions-item label="困难类型" :span="3">{{ viewData.subsidyStandards }}</el-descriptions-item>
<el-descriptions-item label="申请原因" :span="3">{{ viewData.reason }}</el-descriptions-item>
<el-descriptions-item label="家庭成员经济收入" :span="3">
<el-table :data="viewData.familyList" border style="width: 92%">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="姓名" prop="name"></el-table-column>
<el-table-column prop="relation" label="年龄(岁)"></el-table-column>
<el-table-column prop="relation" label="关系"></el-table-column>
<el-table-column prop="monthlyIncome" label="月收入(元)"></el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="3">
<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="3">
<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>
<template v-if="task.taskFormData.tf_money">
<el-descriptions-item label="审批金额">{{ '¥' + task.taskFormData.tf_money }}</el-descriptions-item>
</template>
<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,
}
},
methods: {
// 打开
onOpen(row) {
this.row = row
this.info()
this.getDoneTasks()
},
// 获取申请信息
info() {
this.$axios.post("/platform/difficultHelp/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)
}
},
}
@@ -0,0 +1,179 @@
<!--#
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 @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>
</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=='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: "userName", label: "姓名", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
unions: [],
units: []
}
},
components: {
"info": INFO
},
methods: {
onApply(){
window.location.href = '/platform/difficultHelp/apply'
},
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onEdit(row) {
window.location.href = '/platform/difficultHelp/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((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/difficultHelp/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)
}
},
},
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)
}
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,170 @@
<!--#
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 @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>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="数据列表">
</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=='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="$auth.hasRole('SYSADMIN')" @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: "userName", label: "姓名", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
unions: [],
units: []
}
},
components: {
'info': INFO
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onEdit(row) {
window.location.href = '/platform/difficultHelp/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((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/difficultHelp/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)
}
},
},
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)
}
}
})
</script>
<!--#
}
#-->
@@ -2,86 +2,114 @@
layout("/layouts/platform.html"){
#-->
<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>
<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>
</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=='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 scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="openRevoke(row)" size="mini" type="danger">
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<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 @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>
</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=='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="100px" label-suffix="">
<el-form-item label="审核金额" prop="tf_money" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input-number placeholder="请输入金额" v-model="formData.tf_money" style="width: 60%"></el-input-number>
</el-form-item>
<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],
@@ -103,18 +131,71 @@ layout("/layouts/platform.html"){
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
units: []
units: [],
// 审核相关
formData: {
tf_money: 0,
tf_opinion: "",
},
showApprovalForm: false
}
},
components: {
'info': INFO,
},
methods: {
openView(row) {
window.open("/flow/common/approval/form?instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=KNBF")
openView(row){
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.onOpen(row)
})
},
openRevoke(row) {
console.log(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)
@@ -76,6 +76,7 @@
<script>
new Vue({
el: "#difficult_help_view",
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
businessId: GetQueryString("businessId"),
@@ -86,14 +87,18 @@
},
methods: {
info() {
this.$axios.post("/platform/difficultHelp/view/findOne", { id: this.businessId }).then((res) => {
this.$axios.post("/platform/difficultHelp/mine/findOne", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { instanceId: this.instance})
this.$axios.post("/flow/common/doneTasks", { instanceId: this.instanceId }).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
}
},
created() {
@@ -2,63 +2,92 @@
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool 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"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='sign'">
<el-image v-if="row.sign" :src="row.sign" style="height: 60px"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</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 scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="openRevoke(row)" size="mini" type="danger">
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool 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"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='sign'">
<el-image v-if="row.sign" :src="row.sign" style="height: 60px"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</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 scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">
查看
</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="openRevoke(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"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
new Vue({
el: "#app",
@@ -81,33 +110,68 @@ layout("/layouts/platform.html"){
{ prop: "taskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
// 审核相关
showApprovalForm: false,
formData: {
tf_opinion: ""
},
}
},
components: {
'info': INFO,
'common-query': COMMON_QUERY,
},
methods: {
openView(row) {
window.open("/flow/common/approval/form?instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=HYRH")
this.$refs.guava.edit(()=>{
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.onOpen(row)
})
},
openRevoke(taskId) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
// this.$axios.post("/platform/member/apply/branchUnionAudit/revoke", { taskId }).then((res) => {
// if (res.code === 0) {
// this.$message.success(res.msg)
// this.doSearch()
// } else {
// this.$message.warning(res.msg)
// }
// })
})
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()
}
})
})
},
openRevoke(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()
}
})
})
},
search(pageForm){
if (pageForm) {
@@ -0,0 +1,138 @@
const INFO = {
template: /*language=HTML*/ `
<div>
<div class="process-title">
申请信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div>
<el-descriptions :column="3" border>
<el-descriptions-item label="工号">{{ viewData.loginname }}</el-descriptions-item>
<el-descriptions-item label="姓名">{{ viewData.username }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
<el-descriptions-item label="民族">{{ viewData.nation }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ $moment(viewData.birthday).format("YYYY年MM月DD日") }}</el-descriptions-item>
<el-descriptions-item label="政治面貌">{{ viewData.political }}</el-descriptions-item>
<el-descriptions-item label="学历">{{ viewData.education }}</el-descriptions-item>
<el-descriptions-item label="学位">{{ viewData.academicDegree }}</el-descriptions-item>
<el-descriptions-item label="党政职务">{{ viewData.position }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="所属校区">{{ viewData.campus }}</el-descriptions-item>
<el-descriptions-item label="身份证号码">{{ viewData.idCard }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="电子邮箱">{{ viewData.email }}</el-descriptions-item>
<el-descriptions-item label="在职状态">{{ viewData.userState }}</el-descriptions-item>
<el-descriptions-item label="人员类型">{{ viewData.personType }}</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="家庭主要成员" :span="3">
<el-table v-if="viewData.families&&viewData.families.length"
:data="viewData.families" size="mini" border
:header-cell-style="{background:'#eff3f6'}"
style="width: 100%">
<el-table-column prop="relation" label="与本人关系" align="center" header-align="center">
</el-table-column>
<el-table-column prop="name" label="姓名" align="center" header-align="center">
</el-table-column>
<el-table-column prop="unit" label="单位" align="center" header-align="center">
</el-table-column>
<el-table-column prop="remark" label="备注" align="center" header-align="center">
</el-table-column>
</el-table>
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<div v-if="viewData.personalData" class="text-left" v-html="viewData.personalData"></div>
<el-tag type="warning" v-else>暂无</el-tag>
</el-descriptions-item>
<el-descriptions-item label="签字信息" :span="3">
<el-image v-if="viewData.sign" :src="viewData.sign"
class="signature-image"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<template v-if="task.taskFormData.tf_allocation_unionId">
<el-descriptions-item label="分配工会" :span="1.5">
{{ task.taskFormData.tf_allocation_unionName }}
</el-descriptions-item>
<el-descriptions-item label="分配前工会" :span="1.5">
{{ task.taskFormData.tf_self_unionName }}
</el-descriptions-item>
</template>
<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 {
transmitData: {},
viewData: {},
doneTasks: []
}
},
methods: {
onOpen(transmitData) {
this.transmitData = transmitData
this.info()
this.getDoneTasks()
},
info() {
this.$axios.post("/platform/member/apply/mine/findMemberApplyRecord", { id: this.transmitData.id }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { bizId: this.transmitData.id }).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
// 查看流程图
openChart(){
this.$refs.snakerChartRef.onOpenFull(this.transmitData.instanceProcessDefineId, this.transmitData.instanceId)
}
}
}
@@ -2,154 +2,154 @@
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="申请列表">
<el-button size="small" type="primary" @click="$store.dispatch('pjaxRoute', '/platform/member/apply/submit')">申请入会</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"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='sign'">
<el-image v-if="row.sign" :src="row.sign"
class="signature-image"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="220">
<template slot-scope="{row}">
<el-button @click="openChangeView(row)" size="mini" type="primary">查看</el-button>
<el-button
v-if="[10,40,70].includes(row.processInstanceNodeCode)"
size="mini"
type="primary"
@click="$store.dispatch('pjaxRoute', '/platform/member/apply/submit?id='+row.id)"
>
编辑
</el-button>
<el-button
v-if="[20].includes(row.processInstanceNodeCode) && !row.nextTaskIsComplete"
size="mini"
type="danger"
@click="openRevoke(row)"
>
撤销
</el-button>
<el-button v-if="[10].includes(row.processInstanceNodeCode)" size="mini" type="danger" @click="doDelete(row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #view>
<member-apply-audit-info ref="memberApplyAuditInfoRef"></member-apply-audit-info>
</template>
</guava>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</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"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='sign'">
<el-image v-if="row.sign" :src="row.sign" style="height: 60px"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</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' || !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="info"></info>
</template>
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
<!--#include("../common/memberApplyAuditInfo.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{ prop: "loginname", label: "工号", sortable: true },
{ prop: "username", label: "姓名", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "preparedBy", label: "聘用方式", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "sign", label: "签字" },
{ prop: "processInstanceNodeName", label: "当前节点", sortable: true }
],
unions: [],
units: []
}
},
components: {
'common-query': COMMON_QUERY,
'member-apply-audit-info': MEMBER_APPLY_AUDIT_INFO
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.memberApplyAuditInfoRef.onOpen(row.userId)
})
},
openRevoke(row) {
this.$confirm("您确定要撤销申请吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/member/apply/mine/revokeApply", { id: row.id }).then((resp) => {
this.$message.success(resp.msg)
this.doSearch()
})
})
},
doDelete(row) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/member/apply/mine/delete", { id: row.id }).then((resp) => {
this.$message.success(resp.msg)
this.doSearch()
})
})
},
openChangeView(row) {
this.$refs.guava.public(() => {
this.$refs.memberAuditChangeInfoRef.onOpen({ recordId: row.id, userId: row.userId })
})
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
}
this.doSearch()
},
},
created() {
this.pageData()
}
})
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{ prop: "loginName", label: "工号", sortable: true },
{ prop: "userName", label: "姓名", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "preparedBy", label: "聘用方式", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "sign", label: "签字" },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
units: []
}
},
components: {
'info': INFO,
'common-query': COMMON_QUERY,
},
methods: {
onApply() {
window.location.href = '/platform/member/apply/submit'
},
openView(row) {
this.$refs.guava.view(() => {
this.$refs.info.onOpen(row)
})
},
onEdit(row) {
window.location.href = '/platform/member/apply/submit?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/member/apply/mine/onDelete", { id }).then((res) => {
if (res.code === 0) {
this.doSearch()
this.$message.success(res.msg)
}
})
})
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
}
this.doSearch()
},
},
created() {
this.pageData()
}
})
</script>
<!--#
@@ -2,64 +2,110 @@
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool 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"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='sign'">
<el-image v-if="row.sign" :src="row.sign" style="height: 60px"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</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 scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="openRevoke(row)" size="mini" type="danger">
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool 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"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='sign'">
<el-image v-if="row.sign" :src="row.sign" style="height: 60px"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</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 scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button v-if="row.canRevoke" @click="openRevoke(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="130px" label-suffix="">
<el-row :gutter="20" v-if="formData.origin === 'HMC'">
<el-col :span="12">
<el-form-item label="分配工会关系" prop="tf_allocation_unionId"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-select clearable filterable placeholder="请选择工会" style="width: 100%;"
@change="assignmentUnionName"
v-model="formData.tf_allocation_unionId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="当前所在工会" prop="tf_self_unionName">
<el-input v-model="formData.tf_self_unionName" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<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"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
new Vue({
el: "#app",
@@ -82,17 +128,59 @@ layout("/layouts/platform.html"){
{ prop: "taskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
// 审核相关
showApprovalForm: false,
formData: {
tf_opinion: ""
},
unions: [],
}
},
components: {
'info': INFO,
'common-query': COMMON_QUERY,
},
methods: {
openView(row) {
window.open("/flow/common/approval/form?instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=HYRH")
this.$refs.guava.edit(()=>{
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
origin: row.origin,
processTaskId: row.taskId,
taskName: row.curTaskName
}
if (row.origin === "HMC") {
this.$set(this.formData, "tf_self_unionName", this.$store.state.user.union.name)
}
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()
}
})
})
},
openRevoke(taskId) {
this.$confirm("您确定要撤回吗?", "提示", {
@@ -100,7 +188,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/platform/member/apply/schoolUnionAudit/revoke", { taskId }).then((res) => {
this.$axios.post("/flow/common/revokeTask", { taskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
@@ -114,9 +202,17 @@ layout("/layouts/platform.html"){
}
this.doSearch()
},
// 分配工会名称
assignmentUnionName(val) {
const union = this.unions.find(item => item.id === val)
this.$set(this.formData, "tf_allocation_unionName", union.name)
},
},
created() {
this.pageData()
this.$businessTool.listUnion().then(data => {
this.unions = data
})
}
})
</script>
@@ -1,466 +0,0 @@
<div id="member_apply">
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="3" border>
<el-descriptions-item label="工号">
<el-form-item prop="loginname">
<el-input v-model="formData.loginname" readonly size="small"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="姓名">
<el-form-item prop="username">
<el-input v-model="formData.username" readonly size="small"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="性别">
<el-form-item prop="sex">
<el-radio-group v-model="formData.sex" size="small">
<el-radio border label="男性"></el-radio>
<el-radio border label="女性"></el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="民族">
<el-form-item prop="nation">
<dict-select style="width: 100%" placeholder="请选择民族" v-model="formData.nation"
code="USER_NATION"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="出生日期">
<el-form-item prop="birthday">
<el-date-picker v-model="formData.birthday" type="date"
placeholder="请选择出生日期"
value-format="yyyy-MM-dd"
style="width: 100%"></el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="政治面貌">
<el-form-item prop="political">
<dict-select style="width: 100%" placeholder="请选择政治面貌" v-model="formData.political"
code="POLITICAL_STATUS"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="学历">
<el-form-item prop="education">
<dict-select style="width: 100%" placeholder="请选择学历" v-model="formData.education"
code="USER_EDUCATION"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="学位">
<el-form-item prop="academicDegree">
<dict-select style="width: 100%" placeholder="请选择学位" v-model="formData.academicDegree"
code="USER_ACADEMIC_DEGREE"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="党政职务">
<el-form-item prop="position">
<el-input v-model="formData.position" placeholder="请输入党政职务"
maxlength="50"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="工作单位">
<el-form-item prop="unitId">
<el-select clearable filterable placeholder="请选择工作单位" style="width: 100%"
disabled @change="getUnionName(formData.unitId)"
v-model="formData.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属工会">
<el-form-item prop="unionName">
<el-input v-model="formData.unionName" disabled placeholder="请输入所属工会"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属校区">
<el-form-item prop="campus">
<dict-select style="width: 100%" placeholder="请选择所属校区" v-model="formData.campus"
code="USER_CAMPUS"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="在职状态">
<el-form-item prop="userState">
<dict-select v-model="formData.userState" code="USER_STATE"
disabled style="width: 100%"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="人员类型">
<el-form-item prop="personType">
<dict-select v-model="formData.personType" code="PERSON_TYPE"
disabled style="width: 100%"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="身份证号码">
<el-form-item prop="idCard">
<el-input v-model="formData.idCard" disabled placeholder="请输入身份证号码" maxlength="18"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="联系电话">
<el-form-item prop="mobile">
<el-input v-model="formData.mobile" disabled placeholder="请输入联系电话" maxlength="32"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="电子邮箱">
<el-form-item prop="email">
<el-input v-model="formData.email" placeholder="请输入电子邮箱" maxlength="50"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="家庭主要成员" :span="3">
<el-form-item prop="families">
<el-table :data="formData.families" border size="small">
<el-table-column label="关系" prop="relation">
<template slot-scope="{row}">
<el-input v-model="row.relation" maxlength="50"
placeholder="请输入与本人关系"></el-input>
</template>
</el-table-column>
<el-table-column label="姓名" prop="name">
<template slot-scope="{row}">
<el-input v-model="row.name" maxlength="50" placeholder="请输入姓名"></el-input>
</template>
</el-table-column>
<el-table-column label="工作单位" prop="unit">
<template slot-scope="{row}">
<el-input v-model="row.unit" maxlength="100"
placeholder="请输入工作单位"></el-input>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark">
<template slot-scope="{row}">
<el-input v-model="row.remark" maxlength="100" placeholder="请输入备注"></el-input>
</template>
</el-table-column>
<el-table-column width="100px">
<template slot="header" slot-scope="scope">
<el-button type="primary" size="mini"
@click="formData.families.push({})">添加
</el-button>
</template>
<template slot-scope="scope">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="formData.families.length===0"
@click="formData.families.splice(scope.$index,1)"
></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<el-form-item prop="personalData">
<text-editor v-model="formData.personalData"></text-editor>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="入会意愿" :span="3">
<el-form-item prop="isVoluntary">
<el-checkbox
size="medium"
style="width: 95%; color: #F56C6C; display: flex; align-items: center;"
v-model="formData.isVoluntary">
<div>
<span style="flex: 1; word-wrap: break-word; word-break: break-all; white-space: normal;">
我自愿申请加入学校工会,并委托学校按规定代为扣缴工会会员会费。
</span>
</div>
<div>
<span style="flex: 1; word-wrap: break-word; word-break: break-all; white-space: normal;">
我将严格遵守工会章程,认真执行工会决议,积极参与工会活动,主动融入“学校健康幸福家”建设,为营造温暖、和谐、奋进的校园氛围贡献力量,以实际行动助力学校各项事业发展。
</span>
</div>
</el-checkbox>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="3">
<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: "#member_apply",
store,
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
units: [],
formData: {
families: []
},
formRules: {
username: [{required: false, message: "必填", trigger: ["change", "blur"]}],
sex: [{required: false, message: "必填", trigger: ["change", "blur"]}],
isVoluntary: [{required: true, message: "必填", trigger: ["change", "blur"]}],
sign: [{required: true, message: "必填", trigger: ["change", "blur"]}],
email: [
{
validator: (rule, value, callback) => {
if (!value) {
callback();
} else if (/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)) {
callback();
} else {
callback(new Error("邮箱格式错误"));
}
},
trigger: ["change", "blur"]
}
],
idCard: [
{
validator: (rule, value, callback) => {
if (!value) {
// 如果值为空,直接通过校验
callback();
} else if (/^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}(\d|[Xx])$/.test(value)) {
// 18位身份证号码格式正确
callback();
} else if (/^[1-9]\d{7}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 15位身份证号码格式正确
callback();
} else if (/^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 外国人身份证号码格式正确(18位)
callback();
} else if (/^[1-9]\d{7}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 外国人身份证号码格式正确(15位)
callback();
} else {
// 格式错误,返回错误信息
callback(new Error("身份证号码格式错误"));
}
},
trigger: ["change", "blur"]
}
],
mobile: [
{
validator: (rule, value, callback) => {
if (!value) {
// 如果值为空,直接通过校验
callback();
} else if (/^[1][345789][0-9]{9}$/.test(value)) {
// 手机号格式正确
callback();
} else if (/^\d+-\d+$/.test(value) && value.length <= 16) {
// 座机号格式正确
callback();
} else {
// 格式错误,返回错误信息
callback(new Error(value.includes('-') ? '座机号码格式错误' : '手机号码格式错误'));
}
},
trigger: ["change", "blur"]
}
]
},
}
},
methods: {
// 提交
handleTaskAction(val) {
this.$refs.formRef.validate((valid) => {
if (valid) {
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 validateApply() {
if (this.formData.id) {
return
}
// const resp = await $.post('/platform/member/apply/submit/validateApply')
// if (resp.code === 0 && resp.data > 0) {
// this.$confirm("您有其他入会流程正在进行中,请勿重复申请,如需查看详情,可前往我的申请界面,是否前往?", "提示", { type: "warning" })
// .then(() => {
// this.member = true
// this.$store.dispatch("pjaxRoute", "/platform/member/apply/mine")
// })
// .catch(() => {
// this.member = true
// })
// }
},
async init() {
let user
const resp = await $.post('/platform/member/apply/submit/getSelfUserInfo')
if (resp.code === 0) {
if (!resp.data) {
user = this.$store.state.user
} else {
user = resp.data
}
} else {
user = this.$store.state.user
}
this.member = user.member
if (this.id) {
this.$axios.post("/platform/member/apply/submit/findApplyById", { id: this.id }).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
} else {
const {
id,
username,
loginname,
sex,
nation,
birthday,
political,
education,
academicDegree,
position,
unitId,
unitName,
unit,
unionId,
unionName,
union,
campus,
userState,
personType,
idCard,
mobile,
email,
families,
personalData
} = user
this.$set(this.formData, "userId", id)
this.$set(this.formData, "username", username)
this.$set(this.formData, "loginname", loginname)
this.$set(this.formData, "birthday", birthday)
this.$set(this.formData, "sex", sex)
this.$set(this.formData, "idCard", idCard)
this.$set(this.formData, "nation", nation)
this.$set(this.formData, "political", political)
this.$set(this.formData, "position", position)
this.$set(this.formData, "education", education)
this.$set(this.formData, "academicDegree", academicDegree)
this.$set(this.formData, "campus", campus)
this.$set(this.formData, "userState", userState)
this.$set(this.formData, "personType", personType)
this.$set(this.formData, "unitName", unit ? unit.name : unitName)
this.$set(this.formData, "unitId", unit ? unit.id : unitId)
this.$set(this.formData, "unionName", union ? union.name : unionName)
this.$set(this.formData, "unionId", union ? union.id : unionId)
this.$set(this.formData, "mobile", mobile)
this.$set(this.formData, "email", email)
this.$set(this.formData, "families", families ? families : [])
this.$set(this.formData, "personalData", personalData)
}
},
},
async created() {
this.init()
this.units = await this.$businessTool.listUnit()
await this.validateApply()
}
})
</script>
@@ -3,147 +3,421 @@ layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</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"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='sign'">
<el-image v-if="row.sign" :src="row.sign" style="height: 60px"></el-image>
<el-tag type="warning" v-else>暂无</el-tag>
</template>
<snaker-start slot="header" label="入会申请" define_key="HYRH"></snaker-start>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="3" border>
<el-descriptions-item label="工号">
<el-form-item prop="loginname">
<el-input v-model="formData.loginname" readonly size="small"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="姓名">
<el-form-item prop="username">
<el-input v-model="formData.username" readonly size="small"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="性别">
<el-form-item prop="sex">
<el-radio-group v-model="formData.sex" size="small">
<el-radio border label="男性"></el-radio>
<el-radio border label="女性"></el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<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>
<!--#include("/layouts/pagination.html"){}#-->
<el-descriptions-item label="民族">
<el-form-item prop="nation">
<dict-select style="width: 100%" placeholder="请选择民族" v-model="formData.nation"
code="USER_NATION"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="出生日期">
<el-form-item prop="birthday">
<el-date-picker v-model="formData.birthday" type="date"
placeholder="请选择出生日期"
value-format="yyyy-MM-dd"
style="width: 100%"></el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="政治面貌">
<el-form-item prop="political">
<dict-select style="width: 100%" placeholder="请选择政治面貌" v-model="formData.political"
code="USER_POLITICAL"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="学历">
<el-form-item prop="education">
<dict-select style="width: 100%" placeholder="请选择学历" v-model="formData.education"
code="USER_EDUCATION"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="学位">
<el-form-item prop="academicDegree">
<dict-select style="width: 100%" placeholder="请选择学位" v-model="formData.academicDegree"
code="USER_ACADEMIC_DEGREE"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="党政职务">
<el-form-item prop="position">
<el-input v-model="formData.position" placeholder="请输入党政职务"
maxlength="50"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="工作单位">
<el-form-item prop="unitId">
<el-select clearable filterable placeholder="请选择工作单位" style="width: 100%"
disabled @change="getUnionName(formData.unitId)"
v-model="formData.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属工会">
<el-form-item prop="unionName">
<el-input v-model="formData.unionName" disabled placeholder="请输入所属工会"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属校区">
<el-form-item prop="campus">
<dict-select style="width: 100%" placeholder="请选择所属校区" v-model="formData.campus"
code="USER_CAMPUS"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="在职状态">
<el-form-item prop="userState">
<dict-select v-model="formData.userState" code="USER_STATE"
disabled style="width: 100%"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="人员类型">
<el-form-item prop="personType">
<dict-select v-model="formData.personType" code="PERSON_TYPE"
disabled style="width: 100%"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="身份证号码">
<el-form-item prop="idCard">
<el-input v-model="formData.idCard" disabled placeholder="请输入身份证号码" maxlength="18"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="联系电话">
<el-form-item prop="mobile">
<el-input v-model="formData.mobile" disabled placeholder="请输入联系电话" maxlength="32"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="电子邮箱">
<el-form-item prop="email">
<el-input v-model="formData.email" placeholder="请输入电子邮箱" maxlength="50"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="家庭主要成员" :span="3">
<el-form-item prop="families">
<el-table :data="formData.families" border size="small">
<el-table-column label="关系" prop="relation">
<template slot-scope="{row}">
<el-input v-model="row.relation" maxlength="50"
placeholder="请输入与本人关系"></el-input>
</template>
</el-table-column>
<el-table-column label="姓名" prop="name">
<template slot-scope="{row}">
<el-input v-model="row.name" maxlength="50" placeholder="请输入姓名"></el-input>
</template>
</el-table-column>
<el-table-column label="工作单位" prop="unit">
<template slot-scope="{row}">
<el-input v-model="row.unit" maxlength="100"
placeholder="请输入工作单位"></el-input>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark">
<template slot-scope="{row}">
<el-input v-model="row.remark" maxlength="100" placeholder="请输入备注"></el-input>
</template>
</el-table-column>
<el-table-column width="100px">
<template slot="header" slot-scope="scope">
<el-button type="primary" size="mini"
@click="formData.families.push({})">添加
</el-button>
</template>
<template slot-scope="scope">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="formData.families.length===0"
@click="formData.families.splice(scope.$index,1)"
></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<el-form-item prop="personalData">
<text-editor v-model="formData.personalData"></text-editor>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="入会意愿" :span="3">
<el-form-item prop="isVoluntary">
<el-checkbox
size="medium"
style="width: 95%; color: #F56C6C; display: flex; align-items: center;"
v-model="formData.isVoluntary">
<div>
<span style="flex: 1; word-wrap: break-word; word-break: break-all; white-space: normal;">
我自愿申请加入学校工会,并委托学校按规定代为扣缴工会会员会费。
</span>
</div>
<div>
<span style="flex: 1; word-wrap: break-word; word-break: break-all; white-space: normal;">
我将严格遵守工会章程,认真执行工会决议,积极参与工会活动,主动融入“学校健康幸福家”建设,为营造温暖、和谐、奋进的校园氛围贡献力量,以实际行动助力学校各项事业发展。
</span>
</div>
</el-checkbox>
</el-form-item>
</el-descriptions-item>
<!-- <el-descriptions-item label="签字" :span="3">-->
<!-- <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>
</div>
<script>
<!--#include("../common/commonQuery.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{ prop: "loginName", label: "工号", sortable: true },
{ prop: "userName", label: "姓名", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "preparedBy", label: "聘用方式", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "sign", label: "签字" },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
units: []
id: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
units: [],
formData: {
families: []
},
formRules: {
username: [{required: false, message: "必填", trigger: ["change", "blur"]}],
sex: [{required: false, message: "必填", trigger: ["change", "blur"]}],
isVoluntary: [{required: true, message: "必填", trigger: ["change", "blur"]}],
sign: [{required: true, message: "必填", trigger: ["change", "blur"]}],
email: [
{
validator: (rule, value, callback) => {
if (!value) {
callback();
} else if (/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)) {
callback();
} else {
callback(new Error("邮箱格式错误"));
}
},
trigger: ["change", "blur"]
}
],
idCard: [
{
validator: (rule, value, callback) => {
if (!value) {
// 如果值为空,直接通过校验
callback();
} else if (/^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}(\d|[Xx])$/.test(value)) {
// 18位身份证号码格式正确
callback();
} else if (/^[1-9]\d{7}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 15位身份证号码格式正确
callback();
} else if (/^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 外国人身份证号码格式正确(18位)
callback();
} else if (/^[1-9]\d{7}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 外国人身份证号码格式正确(15位)
callback();
} else {
// 格式错误,返回错误信息
callback(new Error("身份证号码格式错误"));
}
},
trigger: ["change", "blur"]
}
],
mobile: [
{
validator: (rule, value, callback) => {
if (!value) {
// 如果值为空,直接通过校验
callback();
} else if (/^[1][345789][0-9]{9}$/.test(value)) {
// 手机号格式正确
callback();
} else if (/^\d+-\d+$/.test(value) && value.length <= 16) {
// 座机号格式正确
callback();
} else {
// 格式错误,返回错误信息
callback(new Error(value.includes('-') ? '座机号码格式错误' : '手机号码格式错误'));
}
},
trigger: ["change", "blur"]
}
]
},
}
},
components: {
'common-query': COMMON_QUERY,
},
methods: {
onApply() {
window.open("/flow/common/approval/form?defineKey=HYRH")
},
openView(row) {
window.open("/flow/common/approval/form?instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=HYRH")
},
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/member/apply/submit/onDelete", { id }).then((res) => {
this.$axios.post('/platform/member/apply/submit/save', {data: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.doSearch()
this.$message.success(res.msg)
window.location.href = '/platform/member/apply/mine'
}
})
})
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/member/apply/submit/submit', {
data: JSON.stringify(this.formData)
}).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
window.location.href = '/platform/member/apply/mine'
}
})
})
}
})
},
onFinishTask() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/member/apply/submit/submitAgain', {
data: JSON.stringify(this.formData),
taskId: this.taskId,
}).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
window.location.href = '/platform/member/apply/mine'
}
})
})
},
async init() {
let user
const resp = await $.post('/platform/member/apply/submit/getSelfUserInfo')
if (resp.code === 0) {
if (!resp.data) {
user = this.$store.state.user
} else {
user = resp.data
}
} else {
user = this.$store.state.user
}
this.member = user.member
if (this.id) {
const res = await this.$axios.post("/platform/member/apply/submit/findApplyById", { id: this.id })
debugger
if (res.code === 0) {
this.formData = res.data
}
} else {
const {
id,
username,
loginname,
sex,
nation,
birthday,
political,
education,
academicDegree,
position,
unitId,
unitName,
unit,
unionId,
unionName,
union,
campus,
userState,
personType,
idCard,
mobile,
email,
families,
personalData
} = user
this.$set(this.formData, "userId", id)
this.$set(this.formData, "username", username)
this.$set(this.formData, "loginname", loginname)
this.$set(this.formData, "birthday", birthday)
this.$set(this.formData, "sex", sex)
this.$set(this.formData, "idCard", idCard)
this.$set(this.formData, "nation", nation)
this.$set(this.formData, "political", political)
this.$set(this.formData, "position", position)
this.$set(this.formData, "education", education)
this.$set(this.formData, "academicDegree", academicDegree)
this.$set(this.formData, "campus", campus)
this.$set(this.formData, "userState", userState)
this.$set(this.formData, "personType", personType)
this.$set(this.formData, "unitName", unit ? unit.name : unitName)
this.$set(this.formData, "unitId", unit ? unit.id : unitId)
this.$set(this.formData, "unionName", union ? union.name : unionName)
this.$set(this.formData, "unionId", union ? union.id : unionId)
this.$set(this.formData, "mobile", mobile)
this.$set(this.formData, "email", email)
this.$set(this.formData, "families", families ? families : [])
this.$set(this.formData, "personalData", personalData)
}
this.doSearch()
},
},
created() {
this.pageData()
this.init()
this.$businessTool.listUnit().then((data) => {
this.units = data
})
}
})
</script>
@@ -100,7 +100,7 @@
},
methods: {
info() {
this.$axios.post("/platform/member/apply/view/findMemberApplyRecord", { id: this.businessId }).then((res) => {
this.$axios.post("/platform/member/apply/mine/findMemberApplyRecord", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
@@ -4,90 +4,80 @@ layout("/layouts/platform.html"){
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="审核列表">
<el-radio-group @change="search" 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" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openUserView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='changeTypes'">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="审核列表">
<el-radio-group @change="search" 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" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='changeTypes'">
<span style="color: #0e78c5;cursor: pointer" @click="openView(row)">
{{getChangeTypes(row.changeTypes)}}
</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">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger">
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</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>
<!-- <template #view>-->
<!-- <member-info ref="memberInfoRef"></member-info>-->
<!-- </template>-->
<!-- -->
<!-- <template #public>-->
<!-- <member-change-audit-info ref="memberChangeAuditInfoRef"></member-change-audit-info>-->
<!-- <div v-if="showApprovalForm">-->
<!-- <el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">-->
<!-- <el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:false,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- <el-row type="flex" justify="end">-->
<!-- <el-button plain @click="$refs.guava.index()">取消</el-button>-->
<!-- <el-button type="danger" @click="doApproval('BACK')">退回重新填写</el-button>-->
<!-- <el-button type="danger" @click="doApproval('REJECT')">拒绝</el-button>-->
<!-- <el-button type="primary" @click="doApproval('PASS')">同意</el-button>-->
<!-- </el-row>-->
<!-- </div>-->
<!-- </template>-->
</guava>
</div>
<script>
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
new Vue({
@@ -114,76 +104,70 @@ layout("/layouts/platform.html"){
],
changeTypeData: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
'common-query': COMMON_QUERY,
},
methods: {
openView(row){
this.$refs.guava.public(() => {
this.$refs.memberInfoRef.onOpen(row.userId)
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openUserView(row){
this.$refs.guava.view(() => {
this.$refs.memberChangeAuditInfoRef.onOpen(row.userId)
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.onOpen(row)
})
},
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
// this.$refs.guava.public(() => {
// this.showApprovalForm = true
// this.formData = row.approvalParam
// this.$refs.memberChangeAuditInfoRef.onOpen(data.id)
// })
},
doApproval(approvalType) {
let msg = '确定要同意此条申请吗?'
if (approvalType === 'REJECT') {
msg = '确定要拒绝此教工的入会申请吗?'
} else if (approvalType === 'BACK') {
msg = '确定要退回此条申请吗?'
}
this.$confirm(msg, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
this.formData.bpmTaskApprovalType = approvalType
this.$refs.approvalFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/platform/member/change/branchUnion/audit/approval", {
approval: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
}
})
})
},
openRevoke(taskId) {
this.$confirm("您确定要撤回吗?", "提示", {
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/member/change/branchUnion/audit/revoke", { taskId }).then((resp) => {
this.$message.success(resp.msg)
this.doSearch()
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()
}
})
})
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
@@ -0,0 +1,176 @@
const INFO = {
template: /*language=HTML*/ `
<div>
<div class="process-title">申请信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div>
<el-tabs v-model="activeName">
<el-tab-pane label="基础信息" name="basicInfo">
<el-descriptions :column="3" border class="descriptions-form">
<el-descriptions-item label="工号">{{ viewData.loginname }}</el-descriptions-item>
<el-descriptions-item label="姓名">{{ viewData.username }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
<el-descriptions-item label="民族">{{ viewData.nation }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ viewData.birthday ?
$moment(viewData.birthday).format("YYYY年MM月DD日") : '暂无' }}
</el-descriptions-item>
<el-descriptions-item label="政治面貌">{{ viewData.political }}</el-descriptions-item>
<el-descriptions-item label="学历">{{ viewData.education }}</el-descriptions-item>
<el-descriptions-item label="学位">{{ viewData.academicDegree }}</el-descriptions-item>
<el-descriptions-item label="党政职务">{{ viewData.position }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitname }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionname }}</el-descriptions-item>
<el-descriptions-item label="所属校区">{{ viewData.campus }}</el-descriptions-item>
<el-descriptions-item label="身份证号码">{{ viewData.idCard }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="电子邮箱">{{ viewData.email }}</el-descriptions-item>
<el-descriptions-item label="在职状态">{{ viewData.userState }}</el-descriptions-item>
<el-descriptions-item label="人员类型">{{ viewData.personType }}</el-descriptions-item>
<el-descriptions-item label="进校时间">{{ viewData.schoolTime }}</el-descriptions-item>
<template v-if="viewData.userState == '退休'">
<el-descriptions-item label="退休日期">{{ viewData.retireDate ?
$moment(viewData.retireDate).format("YYYY-MM-DD") : '暂无' }}
</el-descriptions-item>
<el-descriptions-item label="福利享受截止日期">{{
$moment(viewData.welfareStopDate).format("YYYY-MM-DD") }}
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
</template>
<el-descriptions-item label="会员状态">{{ viewData.member ? '会员' : '非会员' }}
</el-descriptions-item>
<el-descriptions-item label="福利会员状态">{{ viewData.welfareMember ? '福利会员' : '非福利会员'
}}
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="家庭主要成员" :span="3">
<el-table v-if="viewData.families&&viewData.families.length"
:data="viewData.families" size="mini" border
:header-cell-style="{background:'#eff3f6'}"
style="width: 100%">
<el-table-column prop="relation" label="与本人关系" align="center"
header-align="center">
</el-table-column>
<el-table-column prop="name" label="姓名" align="center" header-align="center">
</el-table-column>
<el-table-column prop="unit" label="单位" align="center" header-align="center">
</el-table-column>
<el-table-column prop="remark" label="备注" align="center" header-align="center">
</el-table-column>
</el-table>
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<template slot="label">个人简况</template>
<div v-if="viewData.vita" class="text-left" v-html="viewData.vita"></div>
<span v-else>无数据</span>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="变更信息" name="changeInfo" v-if="viewData.changeInfos">
<el-table :data="viewData.changeInfos" :size="tableSize" @sort-change="pageOrder" ref="table"
row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column prop="fieldName" label="变更字段" header-align="center"></el-table-column>
<el-table-column prop="sourceValue" label="原数据" header-align="center">
<template slot-scope="{row}">
<div v-html="row.sourceValue"></div>
</template>
</el-table-column>
<el-table-column prop="newValue" label="新数据" header-align="center">
<template slot-scope="{row}">
<div v-html="row.newValue"></div>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
}}({{task.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{
task.taskFormData.opinion }}
</el-descriptions-item>
</el-descriptions>
</div>
</template>
<slot></slot>
<snaker-chart ref="snakerChartRef"></snaker-chart>
</div>
`,
store,
mixins: [initTableMixins],
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data(){
return {
viewData: {},
doneTasks: [],
row: null,
activeName: "basicInfo",
}
},
methods: {
// 打开
onOpen(row) {
this.row = row
this.info()
this.getDoneTasks()
},
// 获取申请信息
info() {
this.$axios.post("/platform/member/change/view/findMemberChangeRecord", { 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)
}
}
}
@@ -8,7 +8,7 @@ const MEMBER_ALL_CHANGE_INFO = {
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
<el-descriptions-item label="民族">{{ viewData.nation }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ moment(viewData.birthday).format("YYYY年MM月DD日") }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ $moment(viewData.birthday).format("YYYY年MM月DD日") }}</el-descriptions-item>
<el-descriptions-item label="政治面貌">{{ viewData.political }}</el-descriptions-item>
<el-descriptions-item label="学历">{{ viewData.education }}</el-descriptions-item>
@@ -28,8 +28,8 @@ const MEMBER_ALL_CHANGE_INFO = {
<el-descriptions-item label="进校时间">{{ viewData.schoolTime }}</el-descriptions-item>
<template v-if="viewData.userState == '退休'">
<el-descriptions-item label="退休日期">{{ viewData.retireDate ? moment(viewData.retireDate).format("YYYY-MM-DD") : '暂无' }}</el-descriptions-item>
<el-descriptions-item label="福利享受截止日期">{{ moment(viewData.welfareStopDate).format("YYYY-MM-DD") }}</el-descriptions-item>
<el-descriptions-item label="退休日期">{{ viewData.retireDate ? $moment(viewData.retireDate).format("YYYY-MM-DD") : '暂无' }}</el-descriptions-item>
<el-descriptions-item label="福利享受截止日期">{{ $moment(viewData.welfareStopDate).format("YYYY-MM-DD") }}</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
</template>
@@ -96,7 +96,7 @@ const MEMBER_ALL_CHANGE_INFO = {
},
methods:{
onOpen(userId){
$.post('/platform/member/change/mange/getAllChangeMemberInfo', {userId})
this.$axios.post('/platform/member/change/manage/getAllChangeMemberInfo', {userId})
.then(resp => {
if (resp.code === 0) {
this.viewData = resp.data
@@ -1,144 +0,0 @@
const MEMBER_CHANGE_AUDIT_INFO = {
template: /*language=HTML*/ `
<div>
<el-tabs v-model="activeName">
<el-tab-pane label="基础信息" name="basicInfo">
<el-descriptions :column="3" border class="descriptions-form">
<el-descriptions-item label="工号">{{ viewData.loginname }}</el-descriptions-item>
<el-descriptions-item label="姓名">{{ viewData.username }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
<el-descriptions-item label="民族">{{ viewData.nation }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ viewData.birthday ? moment(viewData.birthday).format("YYYY年MM月DD日") : '暂无' }}</el-descriptions-item>
<el-descriptions-item label="政治面貌">{{ viewData.political }}</el-descriptions-item>
<el-descriptions-item label="学历">{{ viewData.education }}</el-descriptions-item>
<el-descriptions-item label="学位">{{ viewData.academicDegree }}</el-descriptions-item>
<el-descriptions-item label="党政职务">{{ viewData.position }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitname }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionname }}</el-descriptions-item>
<el-descriptions-item label="所属校区">{{ viewData.campus }}</el-descriptions-item>
<el-descriptions-item label="身份证号码">{{ viewData.idCard }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="电子邮箱">{{ viewData.email }}</el-descriptions-item>
<el-descriptions-item label="在职状态">{{ viewData.userState }}</el-descriptions-item>
<el-descriptions-item label="人员类型">{{ viewData.personType }}</el-descriptions-item>
<el-descriptions-item label="进校时间">{{ viewData.schoolTime }}</el-descriptions-item>
<template v-if="viewData.userState == '退休'">
<el-descriptions-item label="退休日期">{{ viewData.retireDate ? moment(viewData.retireDate).format("YYYY-MM-DD") : '暂无' }}</el-descriptions-item>
<el-descriptions-item label="福利享受截止日期">{{ moment(viewData.welfareStopDate).format("YYYY-MM-DD") }}</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
</template>
<el-descriptions-item label="会员状态">{{ viewData.member ? '会员' : '非会员' }}</el-descriptions-item>
<el-descriptions-item label="福利会员状态">{{ viewData.welfareMember ? '福利会员' : '非福利会员' }}</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="家庭主要成员" :span="3">
<el-table v-if="viewData.families&&viewData.families.length"
:data="viewData.families" size="mini" border
:header-cell-style="{background:'#eff3f6'}"
style="width: 100%">
<el-table-column prop="relation" label="与本人关系" align="center" header-align="center">
</el-table-column>
<el-table-column prop="name" label="姓名" align="center" header-align="center">
</el-table-column>
<el-table-column prop="unit" label="单位" align="center" header-align="center">
</el-table-column>
<el-table-column prop="remark" label="备注" align="center" header-align="center">
</el-table-column>
</el-table>
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<template slot="label">个人简况</template>
<div v-if="viewData.vita" class="text-left" v-html="viewData.vita"></div>
<span v-else>无数据</span>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="变更信息" name="changeInfo" v-if="viewData.changeInfos">
<el-table :data="viewData.changeInfos" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column prop="fieldName" label="变更字段" header-align="center"></el-table-column>
<el-table-column prop="sourceValue" label="原数据" header-align="center">
<template slot-scope="{row}">
<div v-html="row.sourceValue"></div>
</template>
</el-table-column>
<el-table-column prop="newValue" label="新数据" header-align="center">
<template slot-scope="{row}">
<div v-html="row.newValue"></div>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane v-if="viewData.nodeTasks && viewData.nodeTasks.length > 0" label="审核信息" name="audit">
<div>
<div v-for="nodeTask in viewData.nodeTasks" :key="nodeTask.id">
<div class="process-title">
{{nodeTask.nodeName}}
</div>
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id"
style="margin-bottom: 10px">
<el-descriptions-item label="审核人">
{{ task.actualOwnerLoginName + '-' + task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="审核时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="审核结果">
<div v-if="task.extVariable">
<el-tag type="success" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'PASS'">同意
</el-tag>
<el-tag type="danger" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'BACK'">退回
</el-tag>
<el-tag type="danger" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'REJECT'">拒绝
</el-tag>
</div>
</el-descriptions-item>
<el-descriptions-item label="审核意见" :span="3">
{{ task.extVariable.approvalOpinion }}
</el-descriptions-item>
<template v-if="$auth.hasRoleOr('SYSADMIN') && task.extVariable.approvalRemark">
<el-descriptions-item label="审核说明" :span="3">
{{ task.extVariable.approvalRemark }}
</el-descriptions-item>
</template>
<el-descriptions-item label="签字" :span="3">
<el-image :src="task.extVariable.approvalSignature"
v-if="task.extVariable && task.extVariable.approvalSignature"
class="signature-image"></el-image>
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
`,
mixins: [initTableMixins],
data(){
return{
activeName: "basicInfo",
viewData: {
changeInfos: [],
nodeTasks: {},
}
}
},
methods: {
async onOpen(id){
const resp = await $.post('/platform/member/change/mine/findMemberChangeRecord', {id})
if (resp.code === 0) {
this.viewData = resp.data
}
}
}
}
@@ -3,150 +3,148 @@ layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable filterable
placeholder="所属工会" style="width: 100%;" v-model="pageForm.unionId">
<el-option :key="item.id" :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 :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="性别">
<dict-select v-model="pageForm.sex" placeholder="性别" @change="doSearch"
code="USER_SEX"></dict-select>
</search-item>
<search-item label="在职状态">
<dict-select v-model="pageForm.userState" placeholder="在职状态" @change="doSearch"
code="USER_STATE"></dict-select>
</search-item>
<search-item label="人员类型">
<dict-select v-model="pageForm.personType" placeholder="人员类型" @change="doSearch"
code="PERSON_TYPE"></dict-select>
</search-item>
<search-item label="更新日期">
<el-date-picker :picker-options="pickerOptions" @change="changeDateRangeChange"
align="right" end-placeholder="结束日期" format="yyyy-MM-dd"
range-separator="-" start-placeholder="开始日期" style="width: 100%"
type="datetimerange" v-model="pageForm.changeDateRange"
value-format="yyyy-MM-dd"></el-date-picker>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="人员列表">
<el-radio-group @change="doSearch" class="mr5"
size="small"
v-model="pageForm.isMember">
<el-radio-button :label="null">全部教工</el-radio-button>
<el-radio-button :label="1">会员</el-radio-button>
<el-radio-button :label="0">非会员</el-radio-button>
</el-radio-group>
<span class="text-danger">人员异动:</span>
<el-radio-group @change="doSearch" class="mr5" size="small"
v-model="pageForm.changed">
<el-radio-button :label="2">全部</el-radio-button>
<el-radio-button :label="1">异动</el-radio-button>
<el-radio-button :label="0">未异动</el-radio-button>
</el-radio-group>
<!--<div v-if="pageForm.changed == '1'" class="div-enum">
<dict-select v-model="pageForm.USER_CHANGE_TYPE" placeholder="异动类型" @change="doSearch"
code="UserType"></dict-select>
</div>-->
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
class="vi-table" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label" :prop="column.prop"
:sortable="column.sortable" :width="column.width"
align="center" header-align="center" min-width="100px"
show-overflow-tooltip v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row.id)" type="primary">{{row.loginname}}</el-link>
</template>
</el-table-column>
<el-table-column header-align="center" label="异动信息">
<el-table-column align="center" header-align="center" label="更新时间"
min-width="145px" prop="changeTime"
show-overflow-tooltip sortable>
</el-table-column>
<el-table-column align="center" header-align="center" label="异动类型"
prop="changeType" show-overflow-tooltip sortable>
<template scope="{row}">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable filterable
placeholder="所属工会" style="width: 100%;" v-model="pageForm.unionId">
<el-option :key="item.id" :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 :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="性别">
<dict-select v-model="pageForm.sex" placeholder="性别" @change="doSearch"
code="USER_SEX"></dict-select>
</search-item>
<search-item label="在职状态">
<dict-select v-model="pageForm.userState" placeholder="在职状态" @change="doSearch"
code="USER_STATE"></dict-select>
</search-item>
<search-item label="人员类型">
<dict-select v-model="pageForm.personType" placeholder="人员类型" @change="doSearch"
code="PERSON_TYPE"></dict-select>
</search-item>
<search-item label="更新日期">
<el-date-picker :picker-options="pickerOptions" @change="changeDateRangeChange"
align="right" end-placeholder="结束日期" format="yyyy-MM-dd"
range-separator="-" start-placeholder="开始日期" style="width: 100%"
type="datetimerange" v-model="pageForm.changeDateRange"
value-format="yyyy-MM-dd"></el-date-picker>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="人员列表">
<el-radio-group @change="doSearch" class="mr5"
size="small"
v-model="pageForm.isMember">
<el-radio-button :label="null">全部教工</el-radio-button>
<el-radio-button :label="1">会员</el-radio-button>
<el-radio-button :label="0">会员</el-radio-button>
</el-radio-group>
<span class="text-danger">人员异动:</span>
<el-radio-group @change="doSearch" class="mr5" size="small"
v-model="pageForm.changed">
<el-radio-button :label="2">全部</el-radio-button>
<el-radio-button :label="1">异动</el-radio-button>
<el-radio-button :label="0">异动</el-radio-button>
</el-radio-group>
<!--<div v-if="pageForm.changed == '1'" class="div-enum">
<dict-select v-model="pageForm.USER_CHANGE_TYPE" placeholder="异动类型" @change="doSearch"
code="UserType"></dict-select>
</div>-->
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
class="vi-table" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label" :prop="column.prop"
:sortable="column.sortable" :width="column.width"
align="center" header-align="center" min-width="100px"
show-overflow-tooltip v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row.id)" type="primary">{{row.loginname}}</el-link>
</template>
</el-table-column>
<el-table-column header-align="center" label="异动信息">
<el-table-column align="center" header-align="center" label="更新时间"
min-width="145px" prop="changeTime"
show-overflow-tooltip sortable>
</el-table-column>
<el-table-column align="center" header-align="center" label="异动类型"
prop="changeType" show-overflow-tooltip sortable>
<template scope="{row}">
<span style="color: #0e78c5;cursor: pointer" @click="openUserChangeInfo(row)">
{{getChangeTypes(row.changeTypes)}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column align="center" header-align="center" label="会员" prop="member"
show-overflow-tooltip sortable>
<template scope="{row}">
</template>
</el-table-column>
</el-table-column>
<el-table-column align="center" header-align="center" label="会员" prop="member"
show-overflow-tooltip sortable>
<template scope="{row}">
<span class="text-success " v-if="row.member==1">
<i class="fa fa-circle ml5"></i>
</span>
<span class="text-danger" v-else>
<span class="text-danger" v-else>
<i class="fa fa-circle ml5"></i>
</span>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="福利会员" prop="member"
show-overflow-tooltip sortable>
<template scope="{row}">
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="福利会员" prop="member"
show-overflow-tooltip sortable>
<template scope="{row}">
<span class="text-success " v-if="row.welfareMember==1">
<i class="fa fa-circle ml5"></i>
</span>
<span class="text-danger" v-else>
<span class="text-danger" v-else>
<i class="fa fa-circle ml5"></i>
</span>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作"
prop="userOnline"
width="100px">
<template scope="{row}">
<el-dropdown @command="dropdownCommand">
<el-button plain size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'view',data:row}">
查看
</el-dropdown-item>
<el-dropdown-item
:command="{type:'change',data:row}"
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','BRANCH_UNION_CHAIRMAN','BRANCH_UNION_CHAIRMAN'])">
变更
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作"
prop="userOnline"
width="100px">
<template scope="{row}">
<el-dropdown @command="dropdownCommand">
<el-button plain size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'view',data:row}">
查看
</el-dropdown-item>
<el-dropdown-item
:command="{type:'change',data:row}"
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','BRANCH_UNION_CHAIRMAN','BRANCH_UNION_CHAIRMAN'])">
变更
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<member-info ref="memberInfoRef"></member-info>
@@ -155,6 +153,10 @@ layout("/layouts/platform.html"){
<template #public>
<member-change ref="memberChangeRef" @do-back="$refs.guava.index()" @do-submit="doSubmit"></member-change>
</template>
<template #edit>
<member-all-change ref="memberAllChangeRef"></member-all-change>
</template>
</guava>
</div>
@@ -162,6 +164,7 @@ layout("/layouts/platform.html"){
<!--#include("../../common/info/memberInfo.js"){}#-->
<!--#include("../common/memberChange.js"){}#-->
<!--#include("../common/memberAllChangeInfo.js"){}#-->
new Vue({
el: "#app",
@@ -207,7 +210,6 @@ layout("/layouts/platform.html"){
},
unions: [],
units: [],
changeType: {},
id: "",
url: "",
tableColumns: [
@@ -220,10 +222,13 @@ layout("/layouts/platform.html"){
{prop: 'unionName', label: '所属工会', sortable: true},
{prop: 'unitName', label: '所属单位', sortable: true},
],
changeTypeData: []
},
components: {
"member-info": MEMBER_INFO,
"member-change": MEMBER_CHANGE,
"member-all-change": MEMBER_ALL_CHANGE_INFO,
},
methods: {
dropdownCommand(command) {
@@ -239,29 +244,39 @@ layout("/layouts/platform.html"){
this.$refs.memberChangeRef.init(id)
})
},
doSubmit(){
},
openView(id) {
this.$refs.guava.view(() => {
this.$refs.memberInfoRef.onOpen(id)
})
},
addMember() {
this.$refs.guava.edit()
},
openUserChangeInfo() {
},
getChangeTypes(changeTypes) {
if (changeTypes) {
const c = JSON.parse(changeTypes)
return c.map(v => {
return this.changeType[v]
}).join(',')
}
return null
openUserChangeInfo(row) {
this.$refs.guava.edit(() => {
this.$refs.memberAllChangeRef.onOpen(row.id)
})
},
async doSubmit(data) {
const resp = this.$axios.post("/platform/member/change/manage/doSubmitChange", data)
if (resp.code === 0) {
this.$message.success(resp.msg)
this.$refs.guava.index()
this.pageData()
}
},
getChangeTypes(changeTypes){
if (!changeTypes) return null
const changeTypesList = JSON.parse(changeTypes)
if (changeTypesList) {
if (!changeTypesList || changeTypesList.length === 0 || !this.changeTypeData || this.changeTypeData.length === 0) return null
return changeTypesList
.map((v) => {
return this.changeTypeData.find((item) => item.name === v).changeTypeName
})
.join(",")
}
return null
},
changeDateRangeChange(val) {
if (val && val.length > 0) {
this.pageForm.changeDateBefore = val[0]
@@ -279,9 +294,7 @@ layout("/layouts/platform.html"){
this.unions = data
})
}
this.$businessTool.getDictOptions("MEMBER_CHANGE_TYPE").then(data => {
this.changeType = data
})
this.changeTypeData = await this.$businessTool.getEnumOptions("MemberChangeType")
this.url = isAdmin ? "/platform/member/school/manage/generalMemberChange" : "/platform/member/branch/manage/generalMemberChange"
},
async flushUnits() {
@@ -2,146 +2,150 @@
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<template>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="申请列表">
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='changeTypes'">
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="申请列表">
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='changeTypes'">
<span style="color: #0e78c5;cursor: pointer" @click="openView(row)">
{{getChangeTypes(row.changeTypes)}}
</span>
</template>
</el-table-column>
<el-table-column label="操作" width="220">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.applyStateId === 10010"
@click="sublime.jumpPagePjax('/platform/member/change/apply?id=' + row.id)"
size="mini" type="primary">编辑</el-button>
<!-- <el-button v-if="row.applyStateId === 20" @click="doRevoke(row)" size="mini" type="warning">撤销</el-button>-->
<el-button v-if="row.applyStateId === 10010" @click="doDelete(row)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #view>
<member-change-audit-info ref="memberChangeAuditInfoRef"></member-change-audit-info>
</template>
</guava>
</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/commonQuery.js"){}#-->
<!--#include("../common/memberChangeAuditInfo.js"){}#-->
new Vue({
el: '#app',
mixins: [initTableMixins],
data(){
return{
tableColumns: [
{ prop: "loginname", label: "工号", sortable: true },
{ prop: "username", label: "姓名", sortable: true },
{ prop: "sex", label: "性别", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "changeTypes", label: "变更类型", sortable: true, width: 200 },
{ prop: "applyDateTime", label: "申请时间", sortable: true },
{ prop: "stateName", label: "当前节点", sortable: true }
],
changeTypeData: [],
}
},
components: {
'common-query': COMMON_QUERY,
'member-change-audit-info': MEMBER_CHANGE_AUDIT_INFO
},
methods: {
openView(row){
this.$refs.guava.view()
this.$nextTick(() => {
this.$refs.memberChangeAuditInfoRef.onOpen(row.id)
})
},
async doRevoke(row){
const confirm = await this.$confirm('确定要撤销该条申请吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm === "confirm") {
const resp = await $.post("/platform/member/change/mine/doRevoke", { id: row.id })
if (resp.code === 0) {
this.pageData()
this.$message.success(resp.msg)
} else {
this.$message.error(resp.msg)
}
}
},
async doDelete(row){
const confirm = await this.$confirm('确定要删除该条申请吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm === "confirm") {
const resp = await $.post("/platform/member/change/mine/doDelete", { id: row.id })
if (resp.code === 0) {
this.pageData()
this.$message.success(resp.msg)
} else {
this.$message.error(resp.msg)
}
}
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
}
this.doSearch()
},
getChangeTypes(changeTypes){
const changeTypesList = JSON.parse(changeTypes)
if (changeTypesList) {
if (!changeTypesList || changeTypesList.length === 0 || !this.changeTypeData || this.changeTypeData.length === 0) return null
return changeTypesList
.map((v) => {
return this.changeTypeData.find((item) => item.type === v).changeTypeName
})
.join(",")
}
return null
}
},
async created(){
this.pageData()
this.changeTypeData = await this.$businessTool.getEnumOptions("MemberChangeType")
}
})
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
new Vue({
el: '#app',
mixins: [initTableMixins],
data(){
return{
tableColumns: [
{ prop: "loginname", label: "工号", sortable: true },
{ prop: "username", label: "姓名", sortable: true },
{ prop: "sex", label: "性别", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "changeTypes", label: "变更类型", sortable: true, width: 200 },
{ prop: "applyDateTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
changeTypeData: [],
}
},
components: {
'info': INFO,
'common-query': COMMON_QUERY,
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onEdit(row) {
window.location.href = '/platform/member/change/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((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/member/change/mine/onDelete", {id}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
}
this.doSearch()
},
getChangeTypes(changeTypes){
const changeTypesList = JSON.parse(changeTypes)
if (changeTypesList) {
if (!changeTypesList || changeTypesList.length === 0 || !this.changeTypeData || this.changeTypeData.length === 0) return null
return changeTypesList
.map((v) => {
return this.changeTypeData.find((item) => item.name === v).changeTypeName
})
.join(",")
}
return null
}
},
async created(){
this.pageData()
this.changeTypeData = await this.$businessTool.getEnumOptions("MemberChangeType")
}
})
</script>
<!--#
}
@@ -98,7 +98,7 @@ layout("/layouts/platform.html"){
</template>
<template #view>
<member-change-audit-info ref="memberChangeAuditInfoRef"></member-change-audit-info>
<member-all-change ref="memberAllChangeRef"></member-all-change>
</template>
<template #edit>
@@ -110,7 +110,7 @@ layout("/layouts/platform.html"){
<script>
<!--#include("../../common/info/memberInfo.js"){}#-->
<!--#include("../common/memberChangeAuditInfo.js"){}#-->
<!--#include("../common/memberAllChangeInfo.js"){}#-->
new Vue({
el:'#app',
@@ -136,7 +136,7 @@ layout("/layouts/platform.html"){
},
components: {
'member-info': MEMBER_INFO,
'member-change-audit-info': MEMBER_CHANGE_AUDIT_INFO,
"member-all-change": MEMBER_ALL_CHANGE_INFO,
},
methods: {
openUserView(row){
@@ -146,10 +146,11 @@ layout("/layouts/platform.html"){
},
openView(row){
this.$refs.guava.view(() => {
this.$refs.memberChangeAuditInfoRef.onOpen(row.id)
this.$refs.memberAllChangeRef.onOpen(row.userId)
})
},
getChangeTypes(changeTypes){
if (!changeTypes) return null
const changeTypesList = JSON.parse(changeTypes)
if (changeTypesList) {
if (!changeTypesList || changeTypesList.length === 0 || !this.changeTypeData || this.changeTypeData.length === 0) return null
@@ -4,90 +4,82 @@ layout("/layouts/platform.html"){
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="审核列表">
<el-radio-group @change="search" 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" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openUserView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='changeTypes'">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="审核列表">
<el-radio-group @change="search" 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" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openUserView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='changeTypes'">
<span style="color: #0e78c5;cursor: pointer" @click="openView(row)">
{{getChangeTypes(row.changeTypes)}}
</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">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger">
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</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 #view>-->
<!-- <member-info ref="memberInfoRef"></member-info>-->
<!-- </template>-->
<!-- -->
<!-- <template #public>-->
<!-- <member-change-audit-info ref="memberChangeAuditInfoRef"></member-change-audit-info>-->
<!-- <div v-if="showApprovalForm">-->
<!-- <el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">-->
<!-- <el-form-item label="审意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:false,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- <el-row type="flex" justify="end">-->
<!-- <el-button plain @click="$refs.guava.index()">取消</el-button>-->
<!-- <el-button type="danger" @click="doApproval('BACK')">退回重新填写</el-button>-->
<!-- <el-button type="danger" @click="doApproval('REJECT')">拒绝</el-button>-->
<!-- <el-button type="primary" @click="doApproval('PASS')">同意</el-button>-->
<!-- </el-row>-->
<!-- </div>-->
<!-- </template>-->
<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"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
new Vue({
@@ -114,71 +106,70 @@ layout("/layouts/platform.html"){
],
changeTypeData: [],
// 审核相关
formData: {},
showApprovalForm: false
}
},
components: {
'info': INFO,
'common-query': COMMON_QUERY,
},
methods: {
openView(row){
this.$refs.guava.public(() => {
this.$refs.memberInfoRef.onOpen(row.userId)
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.infoRef.onOpen(row)
})
},
openUserView(row){
this.$refs.guava.view(() => {
this.$refs.memberChangeAuditInfoRef.onOpen(row.userId)
openAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.infoRef.onOpen(row)
})
},
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
},
doApproval(approvalType) {
let msg = '确定要同意此条申请吗?'
if (approvalType === 'REJECT') {
msg = '确定要拒绝此教工的入会申请吗?'
} else if (approvalType === 'BACK') {
msg = '确定要退回此条申请吗?'
}
this.$confirm(msg, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
this.formData.bpmTaskApprovalType = approvalType
this.$refs.approvalFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/platform/member/change/schoolUnion/audit/approval", {
approval: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
}
})
})
},
openRevoke(taskId) {
this.$confirm("您确定要撤回吗?", "提示", {
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/member/change/schoolUnion/audit/revoke", { taskId }).then((resp) => {
this.$message.success(resp.msg)
this.doSearch()
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()
}
})
})
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
@@ -2,151 +2,544 @@
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<template>
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="申请列表">
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
header-align="center"
min-width="100px"
show-overflow-tooltip
v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='changeTypes'">
<span style="color: #0e78c5;cursor: pointer" @click="openView(row)">
{{getChangeTypes(row.changeTypes)}}
</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">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.applyStateId === 10010"
@click="sublime.jumpPagePjax('/platform/member/change/apply?id=' + row.id)"
size="mini" type="primary">编辑</el-button>
<el-button v-if="row.taskKey === 'apply'" size="mini"
@click="onDelete(row)" type="danger">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<el-card shadow="never">
<snaker-start slot="header" label="会员变更" define_key="HYBG"></snaker-start>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="3" border>
<el-descriptions-item label="工号">
<el-form-item prop="loginname">
<el-input v-model="formData.loginname" readonly size="small"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="姓名">
<el-form-item prop="username">
<el-input v-model="formData.username" readonly size="small"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="性别">
<el-form-item prop="sex">
<el-radio-group :disabled="allowFields('sex')" v-model="formData.sex" size="small">
<el-radio border label="男性"></el-radio>
<el-radio border label="女性"></el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="民族">
<el-form-item prop="nation">
<dict-select style="width: 100%" placeholder="请选择民族" v-model="formData.nation"
:disabled="allowFields('nation')" code="USER_NATION"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="出生日期">
<el-form-item prop="birthday">
<el-date-picker v-model="formData.birthday"
type="date"
:disabled="allowFields('birthday')"
placeholder="请选择出生日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
style="width: 100%"></el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="政治面貌">
<el-form-item prop="political">
<dict-select style="width: 100%" placeholder="请选择政治面貌" v-model="formData.political"
:disabled="allowFields('political')" code="USER_POLITICAL"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="学历">
<el-form-item prop="education">
<dict-select style="width: 100%" placeholder="请选择学历" v-model="formData.education"
:disabled="allowFields('education')" code="USER_EDUCATION"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="学位">
<el-form-item prop="academicDegree">
<dict-select style="width: 100%" placeholder="请选择学位" v-model="formData.academicDegree"
:disabled="allowFields('academicDegree')" code="USER_ACADEMIC_DEGREE"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="党政职务">
<el-form-item prop="position">
<el-input v-model="formData.position" placeholder="请输入党政职务"
:disabled="allowFields('position')" maxlength="50"></el-input>
</el-form-item>
</el-descriptions-item>
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN, SCHOOL_UNION_MEMBER_ADMIN')">
<el-descriptions-item label="工作单位">
<el-form-item prop="unitId">
<el-select clearable filterable placeholder="请选择工作单位" style="width: 100%"
v-model="formData.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属工会">
<el-form-item prop="unionId">
<el-select clearable filterable placeholder="请选择所属工会" style="width: 100%"
v-model="formData.unionId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
</template>
<template v-else>
<el-descriptions-item label="工作单位">
<el-form-item prop="unitId">
<el-select clearable filterable placeholder="请选择工作单位" style="width: 100%"
:disabled="allowFields('unitId')" @change="getUnionName"
v-model="formData.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属工会">
<el-form-item prop="unionName">
<el-input v-model="formData.unionName" disabled placeholder="请输入所属工会"></el-input>
</el-form-item>
</el-descriptions-item>
</template>
<el-descriptions-item label="所属校区">
<el-form-item prop="campus">
<dict-select style="width: 100%" placeholder="请选择所属校区" v-model="formData.campus"
:disabled="allowFields('campus')" code="USER_CAMPUS"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="身份证号码">
<el-form-item prop="idCard">
<el-input v-model="formData.idCard" :disabled="allowFields('idCard')" placeholder="请输入身份证号码" maxlength="18"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="联系电话">
<el-form-item prop="mobile">
<el-input v-model="formData.mobile" :disabled="allowFields('mobile')" placeholder="请输入联系电话" maxlength="15"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="电子邮箱">
<el-form-item prop="email">
<el-input v-model="formData.email" :disabled="allowFields('email')" placeholder="请输入电子邮箱" maxlength="50"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="在职状态">
<el-form-item prop="userState">
<dict-select v-model="formData.userState" code="USER_STATE"
:disabled="allowFields('userState')" style="width: 100%"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="人员类型">
<el-form-item prop="personType">
<dict-select v-model="formData.personType" code="PERSON_TYPE"
:disabled="allowFields('personType')" style="width: 100%"></dict-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<template v-if="formData.userState == '退休'">
<el-descriptions-item label="退休日期">
<el-form-item prop="retireDate">
<el-date-picker v-model="formData.retireDate"
type="date"
placeholder="请选择出生日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
style="width: 100%"></el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="福利享受截止日期">
<el-form-item prop="welfareStopDate">
<el-date-picker v-model="formData.welfareStopDate"
type="date"
:disabled="isView"
placeholder="请选择福利享受截止日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
style="width: 100%"></el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
</template>
<el-descriptions-item label="会员状态" :span="1.5">
<el-form-item prop="member">
<el-radio-group v-model="formData.member" size="small">
<el-radio border :label="true">会员</el-radio>
<el-radio border :label="false">非会员</el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="福利会员状态" :span="1.5">
<el-form-item prop="welfareMember">
<el-radio-group v-model="formData.welfareMember" size="small">
<el-radio border :label="true">福利会员</el-radio>
<el-radio border :label="false">非福利会员</el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<!--<template v-if="formData.member == 1">
<el-descriptions-item label="是否加入会员组别">
<el-form-item prop="member">
<el-radio-group v-model="formData.isJoinActivityMemberScope" size="small">
<el-radio border :label="true">是</el-radio>
<el-radio border :label="false">否</el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
</template>
<template v-if="formData.member == 0">
<el-descriptions-item label="是否退出会员组别">
<el-form-item prop="member">
<el-radio-group v-model="formData.isExitActivityMemberScope" size="small">
<el-radio border :label="true">是</el-radio>
<el-radio border :label="false">否</el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
</template>
<template v-if="formData.member != null && !formData.welfareMember">
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
</template>
<template v-if="formData.welfareMember == true">
<el-descriptions-item label="是否加入福利项目">
<el-form-item prop="isJoinWelfareProject">
<el-radio-group v-model="formData.isJoinWelfareProject" size="small">
<el-radio border :label="true">是</el-radio>
<el-radio border :label="false">否</el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<template v-if="formData.isJoinWelfareProject">
<el-descriptions-item label="选择福利项目">
<el-form-item prop="welfareProjectId">
<el-select clearable filterable placeholder="请选择福利项目" style="width: 100%"
v-model="formData.welfareProjectId">
<el-option v-for="item in welfareProjectList"
:key="id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
</template>
<template v-else>
<el-descriptions-item></el-descriptions-item>
</template>
</template>-->
<template v-if="">
<el-descriptions-item label="家庭主要成员" :span="3">
<el-form-item prop="families">
<el-table :data="formData.families" border size="small">
<el-table-column label="关系" prop="relation">
<template slot-scope="{row}">
<el-input v-model="row.relation" maxlength="50"
placeholder="请输入与本人关系"></el-input>
</template>
</el-table-column>
<el-table-column label="姓名" prop="name">
<template slot-scope="{row}">
<el-input v-model="row.name" maxlength="50" placeholder="请输入姓名"></el-input>
</template>
</el-table-column>
<el-table-column label="工作单位" prop="unit">
<template slot-scope="{row}">
<el-input v-model="row.unit" maxlength="100"
placeholder="请输入工作单位"></el-input>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark">
<template slot-scope="{row}">
<el-input v-model="row.remark" maxlength="100" placeholder="请输入备注"></el-input>
</template>
</el-table-column>
<el-table-column width="100px">
<template slot="header" slot-scope="scope">
<el-button type="primary" size="mini" :disabled="allowFields('families')"
@click="formData.families.push({})">添加
</el-button>
</template>
<template slot-scope="scope">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="formData.families.length===0 || allowFields('families')"
@click="formData.families.splice(scope.$index,1)"
></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="个人简历" :span="3">
<el-form-item prop="personalData">
<text-editor v-model="formData.personalData"></text-editor>
</el-form-item>
</el-descriptions-item>
</template>
</el-descriptions>
</el-form>
<template #view>
<member-change-audit-info ref="memberChangeAuditInfoRef"></member-change-audit-info>
</template>
</guava>
<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>
<!--#include("../common/commonQuery.js"){}#-->
<!--#include("../common/memberChangeAuditInfo.js"){}#-->
new Vue({
el: '#app',
mixins: [initTableMixins],
store,
data(){
return{
tableColumns: [
{ prop: "loginname", label: "工号", sortable: true },
{ prop: "username", label: "姓名", sortable: true },
{ prop: "sex", label: "性别", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "changeTypes", label: "变更类型", sortable: true, width: 200 },
{ prop: "applyDateTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
changeTypeData: [],
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
units: [],
unions: [],
// 允许变更的字段
allowChangeFields: [],
formData: {
families: [],
},
formRules: {
username: [{required: false, message: "必填", trigger: ["change", "blur"]}],
sex: [{required: false, message: "必填", trigger: ["change", "blur"]}],
email: [
{
validator: (rule, value, callback) => {
if (!value) {
callback();
} else if (/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)) {
callback();
} else {
callback(new Error("邮箱格式错误"));
}
},
trigger: ["change", "blur"]
}
],
idCard: [
{
validator: (rule, value, callback) => {
if (!value) {
// 如果值为空,直接通过校验
callback();
} else if (/^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}(\d|[Xx])$/.test(value)) {
// 18位身份证号码格式正确
callback();
} else if (/^[1-9]\d{7}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 15位身份证号码格式正确
callback();
} else if (/^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 外国人身份证号码格式正确(18位)
callback();
} else if (/^[1-9]\d{7}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/.test(value)) {
// 外国人身份证号码格式正确(15位)
callback();
} else {
// 格式错误,返回错误信息
callback(new Error("身份证号码格式错误"));
}
},
trigger: ["change", "blur"]
}
],
mobile: [
{
validator: (rule, value, callback) => {
if (!value) {
// 如果值为空,直接通过校验
callback();
} else if (/^[1][345789][0-9]{9}$/.test(value)) {
// 手机号格式正确
callback();
} else if (/^\d+-\d+$/.test(value) && value.length <= 16) {
// 座机号格式正确
callback();
} else {
// 格式错误,返回错误信息
callback(new Error(value.includes('-') ? '座机号码格式错误' : '手机号码格式错误'));
}
},
trigger: ["change", "blur"]
}
]
},
}
},
components: {
'common-query': COMMON_QUERY,
'member-change-audit-info': MEMBER_CHANGE_AUDIT_INFO
},
methods: {
openView(row){
this.$refs.guava.view()
this.$nextTick(() => {
this.$refs.memberChangeAuditInfoRef.onOpen(row.id)
// 保存
onSave() {
this.$confirm("您确定保存吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/member/change/apply/save', {data: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.$message.success("保存成功")
window.location.href = '/platform/member/change/mine'
}
})
})
},
async doRevoke(row){
const confirm = await this.$confirm('确定要撤销该条申请吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
// 提交
onSubmit() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/member/change/apply/submit', {
data: JSON.stringify(this.formData)
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/member/change/mine'
}
})
})
if (confirm === "confirm") {
const resp = await $.post("/platform/member/change/mine/doRevoke", { id: row.id })
if (resp.code === 0) {
this.pageData()
this.$message.success(resp.msg)
} else {
this.$message.error(resp.msg)
}
}
},
async onDelete(row){
const confirm = await this.$confirm('确定要删除该条申请吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
onFinishTask() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/member/change/apply/submitAgain', {
data: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/member/change/mine'
}
})
})
if (confirm === "confirm") {
const resp = await $.post("/platform/member/change/mine/doDelete", { id: row.id })
if (resp.code === 0) {
this.pageData()
this.$message.success(resp.msg)
} else {
this.$message.error(resp.msg)
}
},
// 获取表单工会名称
getUnionName(val){
const data = this.units.find(v => v.id === val)
this.$set(this.formData, 'unionName', data ? data.unionname : '')
},
// 获取表单可编辑的字段信息
allowFields(prop) {
return !this.allowChangeFields.map(v => v.code).includes(prop)
},
// 初始化表单数据
async init(userId){
if (userId) {
this.isShow = false
await this.getUserById(userId)
} else {
this.isShow = true
this.user = this.$store.state.user
}
this.getFormDataValue()
this.allowChangeFields = await this.$businessTool.getDictOptions("ALLOW_CHANGE_FIELDS")
if (this.$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_MEMBER_ADMIN, SCHOOL_UNION_ADMIN')) {
this.units = await this.$businessTool.listUnit()
this.unions = await this.$businessTool.listUnion()
} else {
this.units = await this.$businessTool.listUnit(this.user.union.id)
}
},
search(pageForm){
if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm}
// 获取根据userId获取用户信息
async getUserById(userId){
const resp = await this.$axios.post("/platform/member/change/apply/getUserByIdForMemberChange", { userId })
if (resp.code === 0) {
this.user = resp.data
}
this.doSearch()
},
getChangeTypes(changeTypes){
const changeTypesList = JSON.parse(changeTypes)
if (changeTypesList) {
if (!changeTypesList || changeTypesList.length === 0 || !this.changeTypeData || this.changeTypeData.length === 0) return null
return changeTypesList
.map((v) => {
return this.changeTypeData.find((item) => item.name === v).changeTypeName
})
.join(",")
getFormDataValue(){
if (this.bizId) {
this.$axios.post("/platform/member/change/apply/findChangeById", { id: this.bizId }).then((res) => {
if (res.code === 0) {
this.formData = res.data
this.formData.unionid = this.user.unionid
if (this.formData.families) {
this.formData.families = JSON.parse(this.formData.families)
} else {
this.formData.families = []
}
}
})
} else {
const {
id,
username,
loginname,
sex,
member,
welfareMember,
nation,
birthday,
political,
education,
academicDegree,
position,
unit,
union,
campus,
userState,
personType,
preparedBy,
idCard,
mobile,
email,
families,
personalData
} = this.user
this.$set(this.formData, "userId", id)
this.$set(this.formData, "username", username)
this.$set(this.formData, "loginname", loginname)
this.$set(this.formData, "birthday", birthday)
this.$set(this.formData, "sex", sex)
this.$set(this.formData, "member", member === 1)
this.$set(this.formData, "welfareMember", welfareMember === 1)
this.$set(this.formData, "idCard", idCard)
this.$set(this.formData, "nation", nation)
this.$set(this.formData, "political", political)
this.$set(this.formData, "position", position)
this.$set(this.formData, "education", education)
this.$set(this.formData, "academicDegree", academicDegree)
this.$set(this.formData, "campus", campus)
this.$set(this.formData, "userState", userState)
this.$set(this.formData, "personType", personType)
this.$set(this.formData, "preparedBy", preparedBy)
this.$set(this.formData, "unitName", unit ? unit.name : null)
this.$set(this.formData, "unitId", unit ? unit.id : null)
this.$set(this.formData, "unionName", union ? union.name : null)
this.$set(this.formData, "unionId", union ? union.id : null)
this.$set(this.formData, "mobile", mobile)
this.$set(this.formData, "email", email)
this.$set(this.formData, "families", families ? families : [])
this.$set(this.formData, "personalData", personalData)
}
return null
}
},
async created(){
this.pageData()
this.changeTypeData = await this.$businessTool.getEnumOptions("MemberChangeType")
this.init()
}
})
</script>
@@ -312,7 +312,7 @@ layout("/layouts/platform_h5.html"){
return { value: item.name, text: item.name }
})
// 政治面貌
const politicalData = await this.$businessTool.getDictOptions('POLITICAL_STATUS')
const politicalData = await this.$businessTool.getDictOptions('USER_POLITICAL')
this.politicalColumns = politicalData.map(item => {
return { value: item.name, text: item.name }
})