Files
2026-09-08 19:49:21 +08:00

772 lines
34 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.flexible-gifts {
display: flex;
flex-direction: column
}
.flexible-gifts-item {
display: flex;
}
.flexible-gifts-item:not(:first-of-type) {
margin-top: 15px;
}
.flexible-gifts-item-input {
width: calc(100% - 144px);
}
.flexible-gifts-item-radio {
width: 100px;
text-align: center;
}
.flexible-gifts-item-delete {
width: 44px;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
<div id="app" class="platform" v-cloak>
<guava ref="guava" padding="0 20%">
<template>
<el-card shadow="never">
<div class="search">
<div class="search-item">
<div class="search-item-label">&emsp;&emsp;度:</div>
<div class="search-item-option">
<el-date-picker
v-model="pageForm.year"
type="year"
style="width: 100%"
value-format="yyyy"
placeholder="请选择">
</el-date-picker>
</div>
</div>
<div class="search-item">
<div class="search-item-label">项目名称:</div>
<div class="search-item-option">
<el-input placeholder="请输入内容" clearable v-model="pageForm.name"
@keyup.enter.native="doSearch" style="width:100%"></el-input>
</div>
</div>
<div class="search-query">
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索
</el-button>
</div>
</div>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="福利项目" :app="this">
<template #func>
<el-button v-if="judgmentAuthority" type="primary" size="small"
icon="el-icon-plus"
@click="openAdd">新建福利项目
</el-button>
</template>
</table-tool>
<el-table :data="tableData" style="width: 100%" row-key="id"
@sort-change="pageOrder" :size="tableSize"
v-loading="tableLoading" ref="table" class="vi-table">
<el-table-column type="expand">
<template scope="{row}">
<vi-title title="详细信息"></vi-title>
<el-form label-width="120px" label-suffix="">
<el-row gutter="20">
<el-col span="8">
<el-form-item label="项目名称">
{{ row.name }}
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="发放节日">
{{ row.festival }}
</el-form-item>
</el-col>
</el-row>
<el-form-item label="发放地点">
{{ row.provideAddress }}
</el-form-item>
<!-- <el-form-item label="弹性福利" v-if="row.flexible">
<el-row v-for="item,i in row.flexibleGifts">
{{i+1}}. {{item.name}} <span v-if="item.isDefault"
class="text-primary">(默认)</span>
</el-row>
</el-form-item>-->
<el-row gutter="20">
<el-col span="8">
<el-form-item label="发放形式">
{{welfareProvideMode.find(v=>v.code==row.provideMode).description}}
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="签收形式">
{{welfareSignMode.find(v=>v.code==row.signMode).description}}
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="通知推送">
{{welfareNoticePushMode.find(v=>v.code==row.noticePushMode).description}}
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" type="index"
:index="indexMethod" label="序号"
width="80px"></el-table-column>
<el-table-column
align="center"
header-align="center"
v-for="column in tableColumns"
show-overflow-tooltip
:sortable="column.sortable"
:label="column.label"
:prop="column.prop" :width="column.width" min-width="100px">
<template v-if="column.prop=='provideTimeStart'" scope="{row}">
<i class="el-icon-time"></i>&ensp;{{row.provideTimeStart}} <span
v-if="row.provideTimeEnd">- {{row.provideTimeEnd}}</span>
</template>
<template v-if="column.prop=='gift'" scope="{row}">
<span v-if="row.flexible">福利套餐</span>
<span v-else>{{row.gift}}</span>
</template>
</el-table-column>
<el-table-column prop="userOnline" align="center" header-align="center"
label="操作" width="150px">
<template scope="{row}">
<el-dropdown @command="dropdownCommand">
<el-button plain size="mini" :loading="submitLoading">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item :disabled="!row.created"
:command="{type:'export',data:row}">
导出签字表
</el-dropdown-item>-->
<!-- :disabled="moment().valueOf()>=moment(row.provideTimeStart).valueOf()"
-->
<el-dropdown-item
v-if="row.created"
:command="{type:'createList2',data:row}">
更新福利名单
</el-dropdown-item>
<el-dropdown-item
v-if="judgmentAuthority"
:command="{type:'createList',data:row}">
{{row.created?'重置福利名单':'生成福利名单'}}
</el-dropdown-item>
<el-dropdown-item v-if="judgmentAuthority"
:command="{type:'edit',data:row}">
编辑
</el-dropdown-item>
<el-dropdown-item v-if="judgmentAuthority"
:command="{type:'delete',data:row}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #edit>
<el-form :model="formData" ref="form" :rules="formRules" label-width="120px"
v-loading="formLoading">
<vi-title title="福利项目信息"></vi-title>
<el-form-item prop="name" label="项目名称">
<el-input v-model="formData.name" placeholder="项目名称" maxlength="100"></el-input>
</el-form-item>
<el-row>
<el-col span="12">
<el-form-item prop="festival" label="发放节日">
<el-select placeholder="发放节日"
style="width: 100%"
filterable
v-model="formData.festival">
<el-option v-for="f in festival" :key="f" :value="f"
:label="f"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col span="12">
<el-form-item prop="provideTime" label="发放时间">
<el-date-picker
style="width: 100%"
v-model="formData.provideTime"
type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间" @change="provideTimeChange">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="provideAddress" label="发放地点">
<el-input v-model="formData.provideAddress" placeholder="发放地点"
suffix-icon="el-icon-location-information" maxlength="200"></el-input>
</el-form-item>
<el-row>
<el-col span="6">
<el-form-item label="是否福利套餐" prop="flexible">
<el-switch v-model="formData.flexible" @change="isCheckBoxChange">
</el-switch>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="是否常规" prop="isRoutine" v-if="formData.flexible">
<el-switch v-model="formData.isRoutine">
</el-switch>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="是否多选" prop="isCheckBox" v-if="formData.isRoutine">
<el-switch
v-model="formData.isCheckBox"
active-value="checkBox"
inactive-value="radio" @change="isCheckBoxChange">
</el-switch>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="最多选几个" prop="multiSelectNum"
v-if="formData.isCheckBox=='checkBox'">
<el-input-number v-model="formData.multiSelectNum" placeholder="最多选几个"
:min="2" :max="10"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="福利礼品" prop="gift" v-if="!formData.flexible">
<el-input maxlength="100" placeholder="福利礼品" suffix-icon="el-icon-present"
v-model="formData.gift"></el-input>
</el-form-item>
<template v-if="formData.flexible">
<el-form-item label="福利选项" v-if="[2,3,4].includes(formData.provideMode)">
<question-naire :subject="formData.welfareProjectSubjects"
ref="questionNaire"
></question-naire>
</el-form-item>
</template>
<el-row>
<el-col span="12">
<el-form-item prop="provideMode" label="发放形式">
<el-radio-group v-model="formData.provideMode" size="small">
<el-radio v-for="item in welfareProvideMode" :key="item.code"
:label="item.code" border>
{{item.description}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col span="12" v-if="formData.provideMode===2||formData.provideMode===3">
<el-form-item prop="choiceTime" label="选择时间">
<el-date-picker
style="width: 100%"
v-model="formData.choiceTime"
type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间" @change="choiceTimeChange">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="signMode" label="签收形式">
<el-radio-group v-model="formData.signMode" size="small">
<el-radio v-for="item in welfareSignMode" :key="item.code"
:label="item.code" border>
{{item.description}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="noticePushMode" label="通知推送">
<el-radio-group v-model="formData.noticePushMode" size="small">
<el-radio v-for="item in welfareNoticePushMode" :key="item.code"
:label="item.code" border>
{{item.description}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="conditionStructure" label="发放范围">
<el-button @click="$refs.cnd.open()" size="small" icon="el-icon-s-operation">
打开
</el-button>
</el-form-item>
<el-form-item label="封面图片" prop="cover">
<!-- <file-upload :files.sync=""></file-upload>-->
<el-upload
:action="FILE_UPLOAD_ADDRESS"
:before-upload="beforeAvatarUpload"
:on-success="handleAvatarSuccess"
:show-file-list="false"
class="avatar-uploader">
<img :src="'${AppFileDomain!}'+'/fileStreamPreview?id='+formData.cover"
class="avatar"
v-if="formData.cover">
<i class="el-icon-plus avatar-uploader-icon" v-else></i>
</el-upload>
</el-form-item>
</el-form>
<el-button @click="save" v-loading="submitLoading" type="primary" style="float: right">
提交
</el-button>
</template>
<template #view>
</template>
</guava>
<condition ref="cnd" v-model="formData.conditionStructure" :fields="fields"></condition>
<el-dialog title="导出" :visible.sync="exportWelfareListDialog" width="40%">
<el-row class="pt5 pb5 text-danger">勾选需要导出的人员类型</el-row>
<el-row class="pt10 pb10">
<el-checkbox-group v-model="selPersonType">
<el-checkbox v-for="i in welfarePersonTypeList" :label="i.personType"></el-checkbox>
</el-checkbox-group>
</el-row>
<el-row type="flex" justify="end">
<el-button @click="doExportWelFareList" type="primary">确定</el-button>
</el-row>
</el-dialog>
</div>
<script>
<!--#include("/platform/welfare/include/common.js"){}#-->
var vue = new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return {
judgmentAuthority,
fields: [
{
label: '性别',
value: 'sex',
type: "select",
options: [{label: '男', value: '男'}, {label: '女', value: '女'}]
},
{label: '出生日期', value: 'birthday', type: "date"},
],
welfareProvideMode: [],
welfareSignMode: [],
welfareNoticePushMode: [],
pageForm: {
year: moment().format('YYYY')
},
tableColumns: [
{prop: 'year', label: '年度'},
{prop: 'name', label: '项目名称'},
{prop: 'gift', label: '福利礼品'},
{prop: 'provideTimeStart', label: '发放时间'},
],
formRules: {
name: [{required: true, message: '必填', trigger: ['blur', 'change']}],
festival: [{required: true, message: '必选', trigger: ['blur', 'change']}],
provideTime: [{required: true, message: '必选', trigger: ['blur', 'change']}],
choiceTime: [{required: true, message: '必选', trigger: ['blur', 'change']}],
provideAddress: [{required: true, message: '必选', trigger: ['blur', 'change']}],
provideMode: [{required: true, message: '必选', trigger: ['blur', 'change']}],
signMode: [{required: true, message: '必选', trigger: ['blur', 'change']}],
noticePushMode: [{required: true, message: '必选', trigger: ['blur', 'change']}],
gift: [{required: true, message: '必填', trigger: ['blur', 'change']}],
multiSelectNum: [{required: true, message: '必填', trigger: ['blur', 'change']}],
// flexible: [{required: true, message: '必填', trigger: ['blur', 'change']}],
},
welfare,
welfareUnitMode,
exportWelfareListDialog: false,
selPersonType: [],
welfare_id: null,
welfarePersonTypeList: []
}
},
components: {
'guava': httpVueLoader('/components/plugins/Guava.vue?v=1.0.0'),
'condition': httpVueLoader('/components/plugins/ConditionStructure.vue?v=1.0.0'),
'question-naire': httpVueLoader('/components/plugins/QuestionNaire.vue'),
},
methods: {
isCheckBoxChange() {
this.formData.welfareProjectSubjects = [{
subjectName: '请输入福利信息',
subjectType: this.formData.isCheckBox ? this.formData.isCheckBox : 'radio',
defaultOption: null,
options: [
{
optionType: "套餐",
optionName: '福利1',
optionNameId: '',
optionSort: '1',
imgUrl: ''
}
]
}]
},
async handleAvatarSuccess(res, file) {
this.$set(this.formData, 'cover', res.data.filepath)
await this.$refs['form'].validate()
},
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 4MB!');
}
return isJPG && isLt2M;
},
doExportWelFareList() {
this.exportWelfareList(this.welfare_id, this.selPersonType)
this.exportWelfareListDialog = false
},
exportWelfareList,
async save() {
const formValid = await this.$refs["form"].validate()
if (formValid) {
if (this.formData.flexible) {
const questionValid = this.$refs.questionNaire.validate()
if (!questionValid) {
this.$message.warning('题目信息填写不完整!')
return
}
}
this.submitLoading = true
const loading = this.$loading({
lock: true,
text: '数据保存中请稍后',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
const formData = clone(this.formData)
if (formData.isCheckBox === "radio") {
formData.multiSelectNum = 0
}
if (formData.flexible) {
formData.flexibleGifts.map(v => v.isDefault = false)
formData.flexibleGifts[formData.defaultFlexibleGifts].isDefault = true
formData.flexibleGifts = JSON.stringify(formData.flexibleGifts)
} else {
formData.flexibleGifts = null
}
if (formData.conditionStructure)
formData.conditionStructure = JSON.stringify(formData.conditionStructure)
if (this.formData.flexible && [2, 3, 4].includes(formData.provideMode)) {
formData.welfareProjectSubjects = JSON.stringify(this.$refs.questionNaire.subject)
}
if (!this.formData.id) {
const alert = await this.$alert('在发放福利前,请及时生成福利名单,便于教职工选择福利', '提醒', {
confirmButtonText: '确定',
})
}
const resp = await $.post(loc() + "/save", formData)
loading.close()
this.submitLoading = false
if(resp.code===0){
this.$refs.guava.index()
this.pageData()
}else{
this.notifyWarning(resp.msg)
}
}
},
provideTimeChange() {
if (this.formData.provideTime && this.formData.provideTime.length) {
this.formData.provideTimeStart = this.formData.provideTime[0]
this.formData.provideTimeEnd = this.formData.provideTime[1]
} else {
this.formData.provideTimeStart = ''
this.formData.provideTimeEnd = ''
}
},
choiceTimeChange() {
if (this.formData.choiceTime && this.formData.choiceTime.length) {
this.formData.choiceTimeStart = this.formData.choiceTime[0]
this.formData.choiceTimeEnd = this.formData.choiceTime[1]
} else {
this.formData.choiceTimeStart = ''
this.formData.choiceTimeEnd = ''
}
},
openAdd() {
this.formData = {
isRoutine: true,
isCheckBox: "radio",
defaultFlexibleGifts: 0,
flexible: false,
welfareProjectSubjects: [],
flexibleGifts: [{}]
}
this.$refs.guava.edit()
if (this.$refs.form)
this.$refs.form.resetFields();
},
async createList(row) {
let msg = row.created ? "务必确认是否重新生成福利名单,如果确认,系统将清空已经选取的福利信息。请再次确认 !!" : "确定要生成福利名单吗?"
this.$confirm(msg, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: async (a, b) => {
if ("confirm" == a) {//确认后再执行
this.submitLoading = true
const resp = await $.post(loc() + "/createList", {
id: row.id,
created: false
})
this.submitLoading = false
if(resp.code===0){
this.pageData()
}else{
this.notifyWarning(resp.msg)
}
}
}
})
},
async createList2(row) {
this.$confirm('系统根据现有的福利会员,更新当前福利名单,对已经选择的福利没有影响,请确认是否更新?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: async (a, b) => {
if ("confirm" == a) {//确认后再执行
this.submitLoading = true
const resp = await $.post(loc() + "/createList", {
id: row.id,
created: true
})
this.submitLoading = false
if(resp.code===0){
this.pageData()
this.notifySuccess(resp.msg)
}else{
this.notifyWarning(resp.msg)
}
}
}
})
},
doDelete(id) {
this.$confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: async (a, b) => {
if ("confirm" == a) {//确认后再执行
const resp = await $.post(loc() + "/delete", {id});
if(resp.code===0){
this.pageData()
}else{
this.notifyWarning(resp.msg)
}
}
}
});
},
dropdownCommand(command) {
const {type, data} = command
this.welfare_id = data.id
if (type == 'view') {
this.openView(data.id)
} else if (type == 'edit') {
this.openEdit(data)
} else if (type == 'delete') {
this.doDelete(data.id)
} else if (type == 'createList') {
this.createList(data)
} else if (type == 'createList2') {
this.createList2(data)
} else if (type == 'export') {
this.exportWelfareListDialog = true
// this.exportWelfareList(data.id)
}
},
async openEdit(row) {
this.submitLoading = true
const resp = await $.get(loc() + "/findOne", {id: row.id})
this.submitLoading = false
if(resp.code===0){
const data = resp.data
data.flexibleGifts = data.flexibleGifts || [{}]
const idx = data.flexibleGifts.findIndex(v => v.isDefault)
data.defaultFlexibleGifts = idx < 0 ? 0 : idx
data.provideTime = [data.provideTimeStart, data.provideTimeEnd]
data.choiceTime = [data.choiceTimeStart, data.choiceTimeEnd]
if (data.welfareProjectSubjects.length === 0) {
data.welfareProjectSubjects = [{
subjectName: '请输入福利信息',
subjectType: data.isCheckBox,
defaultOption: null,
options: [
{
optionType: "套餐",
optionName: '福利1',
optionNameId: '',
optionSort: '1',
imgUrl: ''
}
]
}]
} else {
data.welfareProjectSubjects.forEach(v => {
v.options.map(o => {
if (!o.optionNameId) {
o.optionNameId = ""
}
})
})
}
this.formData = data
this.$refs.guava.edit()
}else{
this.notifyWarning(resp.msg)
}
},
openView() {
this.$refs.guava.view()
},
pageData() {
sublime.showLoadingbar();
this.tableLoading = true
$.post(loc() + "/pageData", this.pageForm, (data) => {
sublime.closeLoadingbar();
this.tableLoading = false
if (data.code == 0) {
data.data.list.forEach(v => {
v.flexibleGifts = JSON.parse(v.flexibleGifts || "[]")
})
this.tableData = data.data.list;
this.pageForm.totalCount = data.data.totalCount;
} else {
this.$message.error(data.msg);
}
}, "json");
},
},
async created() {
this.pageData();
this.welfareProvideMode = await getEnumOptions("WelfareProvideMode")
this.welfareSignMode = await getEnumOptions("WelfareSignMode")
this.welfareNoticePushMode = await getEnumOptions("WelfareNoticePushMode")
this.welfarePersonTypeList = await getPersonTypeListGroupByWelfare()
this.welfarePersonTypeList.map(v => {
this.selPersonType.push(v.personType)
})
const personType = await getDictOptions("UserType")
const userState = await getDictOptions("userState")
this.fields = this.fields.concat([{
label: '人员类型',
value: 'personType',
type: "select",
options: personType.map(v => {
return {label: v.name, value: v.code}
})
}, {
label: '在职状态',
value: 'userState',
type: "select",
options: userState.map(v => {
return {label: v.name, value: v.code}
})
}])
}
})
</script>
<!--#
}
#-->