This commit is contained in:
那些花儿
2025-06-20 14:48:06 +08:00
parent 3015f968e3
commit ca04b43385
19 changed files with 315 additions and 158 deletions
@@ -26,7 +26,7 @@ module.exports = {
props: {
value: { type: String },
code: {
type: String,
type: [String, Array],
default: ""
},
option_value: {
@@ -10,14 +10,14 @@ const MEMBER_MANAGE_TABLE = {
<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.isWelfareMember">
<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.isWelfareMember">-->
<!-- <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">
@@ -25,16 +25,17 @@ const MEMBER_MANAGE_TABLE = {
<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>-->
<!--<el-button @click="addMember" type="primary" size="small">新增会员</el-button>-->
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
<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"
@@ -59,11 +60,12 @@ const MEMBER_MANAGE_TABLE = {
</template>
</el-table-column>
</el-table-column>
<el-table-column v-if="$auth.hasRole('BRANCH_UNION_CHAIRMAN')" header-align="center" label="审核状态"
<el-table-column v-if="$auth.hasRole('BRANCH_UNION_CHAIRMAN')" header-align="center"
label="审核状态"
prop="auditState">
</el-table-column>
<el-table-column align="center" header-align="center" label="会员" prop="member"
show-overflow-tooltip sortable>
<template scope="{row}">
@@ -75,18 +77,18 @@ const MEMBER_MANAGE_TABLE = {
</span>
</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>
<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}">-->
<!-- <span class="text-success" v-if="row.welfareMember==1">-->
<!-- <i class="fa fa-circle ml5"></i> 是-->
<!-- </span>-->
<!-- <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}">
@@ -112,8 +114,8 @@ const MEMBER_MANAGE_TABLE = {
查看
</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'])">
:command="{type:'change',data:row}"
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','BRANCH_UNION_CHAIRMAN','BRANCH_UNION_CHAIRMAN'])">
变更
</el-dropdown-item>
<!--<el-dropdown-item
@@ -133,7 +135,7 @@ const MEMBER_MANAGE_TABLE = {
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog title="变更信息" :visible.sync="changeInfoVisible" width="70%">
<member-change-info ref="memberChangeInfoRef"></member-change-info>
</el-dialog>
@@ -158,7 +160,11 @@ const MEMBER_MANAGE_TABLE = {
{ prop: "unitName", label: "所属单位", sortable: true }
],
changeInfoVisible: false,
userId: ''
userId: "",
pageForm: {
isMember: 1,
changed: 2
}
}
},
methods: {
@@ -206,11 +212,11 @@ const MEMBER_MANAGE_TABLE = {
} else {
this.$message.error(res.msg)
}
})
})
})
},
openChange(data) {
this.$emit("change-member", {id: data.id, username: data.username})
this.$emit("change-member", { id: data.id, username: data.username })
},
openView(id) {
this.$emit("view-member", id)
@@ -221,7 +227,7 @@ const MEMBER_MANAGE_TABLE = {
openUserChangeInfo(row) {
this.changeInfoVisible = true
this.$nextTick(() => {
this.$refs.memberChangeInfoRef.onOpen(row.id,null)
this.$refs.memberChangeInfoRef.onOpen(row.id, null)
})
},
getChangeTypes(changeTypes) {
@@ -208,7 +208,6 @@ layout("/layouts/platform.html"){
{ prop: "sex", label: "性别" },
{ prop: "birthday", label: "出生年月", sortable: true },
{ prop: "mobile", label: "联系电话" },
{ prop: "idCard", label: "身份证号", width: 170 },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "preparedBy", label: "聘用方式", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
@@ -120,8 +120,6 @@ layout("/layouts/platform.html"){
{ prop: "sex", label: "性别" },
{ prop: "birthday", label: "出生年月", width: 120, sortable: true },
{ prop: "mobile", label: "联系电话" },
{ prop: "idCardType", label: "证件类型" },
{ prop: "idCard", label: "证件号码", width: 180 },
{ prop: "userState", label: "在职状态", width: 120, sortable: true },
{ prop: "personType", label: "教职工类别", width: 120, sortable: true },
{ prop: "preparedBy", label: "聘用方式", width: 120, sortable: true },
@@ -6,7 +6,7 @@ const optionSelect = {
<i class="el-icon-warning"></i>
<span>选择截止时间即将到期,请尽快选择!</span>
</div>
<!-- 选择提示 -->
<div class="welfare-notice">
<el-alert
@@ -15,7 +15,7 @@ const optionSelect = {
show-icon>
</el-alert>
</div>
<div class="welfare-content">
<!-- 项目信息卡片 -->
<el-card class="welfare-info-card">
@@ -37,11 +37,15 @@ const optionSelect = {
</div>
<div class="info-item">
<div class="info-label">选择时间</div>
<div class="info-value">{{ formatTimeRange(projectInfo.choiceTimeStart, projectInfo.choiceTimeEnd) }}</div>
<div class="info-value">{{ formatTimeRange(projectInfo.choiceTimeStart,
projectInfo.choiceTimeEnd) }}
</div>
</div>
<div class="info-item">
<div class="info-label">发放时间</div>
<div class="info-value">{{ formatTimeRange(projectInfo.provideTimeStart, projectInfo.provideTimeEnd) }}</div>
<div class="info-value">{{ formatTimeRange(projectInfo.provideTimeStart,
projectInfo.provideTimeEnd) }}
</div>
</div>
<div class="info-item">
<div class="info-label">发放地点</div>
@@ -49,7 +53,7 @@ const optionSelect = {
</div>
</div>
</el-card>
<!-- 福利选项 -->
<el-card class="welfare-options-card">
<div slot="header" class="welfare-info-header">
@@ -57,40 +61,42 @@ const optionSelect = {
<span>福利选项</span>
<span class="options-count">共 {{ projectInfo.options.length }} 项</span>
</div>
<div class="welfare-options-grid">
<div v-for="option in projectInfo.options"
:key="option.id"
class="welfare-option"
<div v-for="option in projectInfo.options"
:key="option.id"
class="welfare-option"
:class="{ selected: projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0 }"
@click="projectInfo.isCheckBox === 'radio' ? selectRadioOption(option.id) : null">
<el-tag v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0"
class="option-tag" type="primary" effect="plain">已选择</el-tag>
<el-tag
v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0"
class="option-tag" type="primary" effect="plain">已选择
</el-tag>
<div class="option-image">
<el-image :src="option.imgUrl" fit="cover"></el-image>
</div>
<div class="option-content">
<div class="option-title">{{ option.optionName }}</div>
<!-- 查看详情按钮 -->
<div class="option-detail-btn" @click.stop="showOptionDetail(option)">
<i class="el-icon-info"></i>
<span>查看详情</span>
</div>
<!-- 单选模式使用单选按钮 -->
<div class="option-radio" v-if="projectInfo.isCheckBox === 'radio'">
<el-radio v-model="selectedRadioId" :label="option.id">{{ null }}</el-radio>
</div>
<!-- 多选模式使用步进器 -->
<div class="option-stepper" v-else>
<el-input-number
v-model="option.selectNum"
:min="0"
<el-input-number
v-model="option.selectNum"
:min="0"
:max="projectInfo.multiSelectNum || 99"
size="small"
controls-position="right">
@@ -101,12 +107,13 @@ const optionSelect = {
</div>
</el-card>
</div>
<!-- 底部提交按钮 -->
<div class="welfare-footer">
<el-button type="primary" size="medium" :disabled="!hasSelection" @click="submitSelection">确认选择</el-button>
<el-button type="primary" size="medium" :disabled="!hasSelection" @click="submitSelection">确认选择
</el-button>
</div>
<!-- 选项详情弹窗 -->
<el-dialog
title="福利详情"
@@ -119,7 +126,7 @@ const optionSelect = {
<div class="welfare-detail-content" v-html="selectedOption.description"></div>
</div>
</el-dialog>
<!-- 确认弹窗 -->
<el-dialog
title="确认选择"
@@ -133,9 +140,9 @@ const optionSelect = {
<div class="confirm-section-title">联系信息</div>
<el-form :model="contactForm" ref="contactForm" :rules="contactRules">
<el-form-item prop="mobile">
<el-input
v-model="contactForm.mobile"
placeholder="请输入手机号码"
<el-input
v-model="contactForm.mobile"
placeholder="请输入手机号码"
maxlength="11"
clearable>
<template slot="prepend">联系电话</template>
@@ -143,14 +150,14 @@ const optionSelect = {
</el-form-item>
</el-form>
</div>
<div class="confirm-section-title">已选择项目</div>
<div class="selected-items">
<div v-for="option in selectedOptions" :key="option.id" class="selected-item">
<div class="selected-item-left">
<div class="selected-item-image">
<el-image
:src="option.imgUrl"
<el-image
:src="option.imgUrl"
fit="cover"
:preview-src-list="[option.imgUrl]">
<div slot="error" class="image-slot">
@@ -167,27 +174,27 @@ const optionSelect = {
</div>
</div>
<div class="selected-item-right">
<el-tag
size="small"
type="primary"
effect="plain"
<el-tag
size="small"
type="primary"
effect="plain"
v-if="projectInfo.isCheckBox === 'checkBox'">
× {{ option.selectNum }}
</el-tag>
</div>
</div>
</div>
<div class="confirm-total" v-if="projectInfo.isCheckBox === 'checkBox'">
<span class="total-label">总数量</span>
<span class="total-value">{{ totalSelectedCount }} 份</span>
</div>
<div class="confirm-warning" :class="{ 'warning': hasSubmittedBefore }">
<i class="el-icon-info"></i>
<span>{{ confirmMessage }}</span>
</div>
<div class="deadline-info" v-if="deadlineText">
<i class="el-icon-time"></i>
<span>{{ deadlineText }}</span>
@@ -200,16 +207,16 @@ const optionSelect = {
</el-dialog>
</div>
`,
store,
data() {
return {
projectId: null,
projectInfo: {},
userSelection: [],
welfareProvideMode: [],
welfareSignMode: [],
projectId: null, // 项目ID
userId: null, // 用户id 代选的时候用得到
projectInfo: {}, // 项目信息
userSelection: [], // 用户选择的选项
selectedRadioId: "", // 单选模式下选中的选项ID
showConfirmDialog: false,
isSubmitting: false,
showConfirmDialog: false, // 确认弹窗
isSubmitting: false, // 是否正在提交
hasSubmittedBefore: false, // 是否之前提交过
deadlineTime: null, // 选择截止时间
showOptionDetailDialog: false, // 选项详情弹窗
@@ -219,13 +226,18 @@ const optionSelect = {
},
contactRules: {
mobile: [
{ required: true, message: '请输入联系电话', trigger: 'blur' },
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
{ required: true, message: "请输入联系电话", trigger: "blur" },
{
pattern: /^1[3456789]\d{9}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
]
}
}
},
computed: {
// 是否有选择
hasSelection() {
if (this.projectInfo.isCheckBox === "radio") {
return !!this.selectedRadioId
@@ -235,6 +247,7 @@ const optionSelect = {
}
},
// 已选择的选项
selectedOptions() {
if (this.projectInfo.isCheckBox === "radio") {
if (!this.selectedRadioId || !this.projectInfo.options) return []
@@ -245,11 +258,13 @@ const optionSelect = {
}
},
// 已选择的数量
totalSelectedCount() {
if (!this.projectInfo.options) return 0
return this.projectInfo.options.reduce((sum, option) => sum + (option.selectNum || 0), 0)
},
// 截止时间快了
isDeadlineSoon() {
if (!this.projectInfo.choiceTimeEnd) return false
@@ -260,6 +275,7 @@ const optionSelect = {
return diffHours > 0 && diffHours < 24
},
// 截止时间提示
deadlineText() {
if (!this.deadlineTime) return ""
const now = new Date()
@@ -279,21 +295,36 @@ const optionSelect = {
}
},
// 确认弹窗提示
confirmMessage() {
if (this.hasSubmittedBefore) {
return "修改后的选择将覆盖之前的选择"
}
return "请仔细确认您的选择"
},
// 是否代选
isProxySelect() {
return !!this.userId
}
},
methods: {
onOpen(projectId) {
// 打开选择项目弹窗 userId为null默认则是本人
onOpen(projectId, userId = null) {
this.projectId = projectId
this.userId = userId
this.selectedRadioId = null
this.contactForm = {
mobile: ""
}
this.getProjectInfo()
},
// 获取项目信息
getProjectInfo() {
this.$axios.post("/platform/welfare/project/mange/findOne", { id: this.projectId }).then((res) => {
this.$axios.post("/platform/welfare/common/projectInfo", { id: this.projectId }).then((res) => {
if (res.code === 0) {
this.projectInfo = res.data
this.deadlineTime = this.projectInfo.choiceTimeEnd
@@ -314,17 +345,24 @@ const optionSelect = {
// 获取用户选择的数据
getUserSelection() {
this.$axios.post("/platform/welfare/userSelect/getUserSelection", { projectId: this.projectId }).then((resp) => {
let url = "/platform/welfare/userSelect/getUserSelection"
const formData = {
projectId: this.projectId
}
if (this.isProxySelect) {
url = "/platform/welfare/selection/situation/getUserSelection"
formData.userId = this.userId
}
this.$axios.post(url, formData).then((resp) => {
if (resp.code === 0) {
this.userSelection = resp.data
this.hasSubmittedBefore = this.userSelection.length > 0
// 如果有用户选择数据,从中获取手机号
if (this.userSelection && this.userSelection.length > 0 && this.userSelection[0].mobile) {
this.contactForm.mobile = this.userSelection[0].mobile
} else if (this.$store.user && this.$store.user.mobile) {
// 如果没有选择过,使用store中的默认手机号
this.contactForm.mobile = this.$store.user.mobile
if (this.userSelection && this.userSelection.length > 0) {
this.contactForm.mobile = this.userSelection[0]?.mobile
}
// 设置已选择的选项
@@ -356,11 +394,11 @@ const optionSelect = {
// 执行提交
doSubmit() {
// 验证手机号
this.$refs.contactForm.validate(valid => {
this.$refs.contactForm.validate((valid) => {
if (!valid) {
return
}
if (this.isSubmitting) return
this.isSubmitting = true
@@ -387,15 +425,23 @@ const optionSelect = {
}))
}
let url = "/platform/welfare/userSelect/confirmSelect"
const formData = {
projectId: this.projectId,
selections: JSON.stringify(selections)
}
if (this.isProxySelect) {
url = "/platform/welfare/selection/situation/confirmSelect"
formData.userId = this.userId
}
this.$axios
.post("/platform/welfare/userSelect/confirmSelect", {
projectId: this.projectId,
selections: JSON.stringify(selections)
})
.post(url, formData)
.then((res) => {
this.isSubmitting = false
if (res.code === 0) {
this.showConfirmDialog = false
this.$message.success("选择成功")
this.$emit("refresh")
} else {
@@ -516,9 +562,15 @@ const optionSelect = {
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.01); }
100% { transform: scale(1); }
0% {
transform: scale(1);
}
50% {
transform: scale(1.01);
}
100% {
transform: scale(1);
}
}
.welfare-deadline i {
@@ -568,7 +620,7 @@ const optionSelect = {
left: 0;
right: 0;
height: 40px;
background: linear-gradient(to top, rgba(255,255,255,1), rgba(255,255,255,0));
background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
}
.project-cover .el-image {
@@ -711,7 +763,7 @@ const optionSelect = {
left: 0;
right: 0;
height: 40px;
background: linear-gradient(to top, rgba(0,0,0,0.2), transparent);
background: linear-gradient(to top, rgba(0, 0, 0, 0.2), transparent);
}
.option-image .el-image {
@@ -826,7 +878,7 @@ const optionSelect = {
position: relative;
padding-left: 10px;
}
.confirm-section-title::before {
content: '';
position: absolute;
@@ -842,7 +894,7 @@ const optionSelect = {
.confirm-mobile-section {
margin-bottom: 20px;
}
.selected-items {
background: #f8f9fb;
border-radius: 8px;
@@ -1046,8 +1098,14 @@ const optionSelect = {
/* 动画 */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.welfare-select-container > * {
@@ -101,19 +101,28 @@ layout("/layouts/platform.html"){
></el-table-column>
<el-table-column align="center" fixed="right" header-align="center" label="操作" width="100px">
<template slot-scope="{row}">
<el-button @click="handleSelect(row)" size="mini" type="primary">代选</el-button>
<el-button size="mini" type="primary" @click="proxySelect(row)">代选</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog title="代选" :visible.sync="optionSelectVisible" width="60%">
<option-select ref="optionSelectRef" @refresh="optionSelectVisible=false;doSearch();"></option-select>
</el-dialog>
</guava>
</div>
<script>
<!--#include("../select/optionSelect.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"option-select": optionSelect
},
data() {
return {
pageForm: {
@@ -133,7 +142,8 @@ layout("/layouts/platform.html"){
{ prop: "welfareUnitName", label: "所属单位", sortable: true },
{ prop: "selectedOptions", label: "所选福利", sortable: true },
{ prop: "mobile", label: "联系电话", sortable: true }
]
],
optionSelectVisible: false
}
},
computed: {
@@ -145,6 +155,7 @@ layout("/layouts/platform.html"){
}
},
methods: {
// 获取福利列表
getWelfareList() {
this.$axios.post("/platform/welfare/common/list", { year: this.pageForm.year }).then((res) => {
this.projectOptions = res.data
@@ -157,6 +168,7 @@ layout("/layouts/platform.html"){
})
},
// 获取数据
pageData() {
this.tableLoading = true
this.$axios
@@ -172,12 +184,18 @@ layout("/layouts/platform.html"){
})
},
// 导出选择情况表
exportXlsx() {
this.$downLoad("/platform/welfare/selection/situation/exportXlsx", { pageForm: JSON.stringify(this.pageForm) })
},
// 管理员待选
handleSelect() {}
proxySelect(row) {
this.optionSelectVisible = true
this.$nextTick(() => {
this.$refs.optionSelectRef.onOpen(row.projectId, row.userId)
})
}
},
async created() {
this.getWelfareList()
@@ -811,7 +811,7 @@ layout("/layouts/platform_h5.html"){
methods: {
getProjectInfo() {
this.$axios.post("/platform/welfare/project/mange/findOne", { id: this.projectId }).then((res) => {
this.$axios.post("/platform/welfare/common/projectInfo", { id: this.projectId }).then((res) => {
if (res.code === 0) {
this.projectInfo = res.data
@@ -839,12 +839,11 @@ layout("/layouts/platform_h5.html"){
// 如果有用户选择数据,从中获取手机号
if (this.userSelection && this.userSelection.length > 0 && this.userSelection[0].mobile) {
this.formData.mobile = this.userSelection[0].mobile
// 获取签名信息(如果有)
if (this.userSelection[0].userSign) {
this.formData.userSign = this.userSelection[0].userSign
}
} else if (this.$store.user && this.$store.user.mobile) {
// 如果没有选择过,使用store中的默认手机号
debugger
@@ -1073,12 +1072,12 @@ layout("/layouts/platform_h5.html"){
this.selectedOption = option
this.showOptionDetailDialog = true
},
// 重置签名
resetSignature() {
this.formData.userSign = ""
// 如果组件有reset方法,调用它
if (this.$refs.signatureRef && typeof this.$refs.signatureRef.reset === 'function') {
if (this.$refs.signatureRef && typeof this.$refs.signatureRef.reset === "function") {
this.$refs.signatureRef.reset()
}
},
@@ -1145,7 +1144,7 @@ layout("/layouts/platform_h5.html"){
}
}
},
// 监听确认弹窗显示状态
showConfirmDialog(val) {
if (val && this.projectInfo.signMode === 2) {
@@ -1153,7 +1152,7 @@ layout("/layouts/platform_h5.html"){
this.$nextTick(() => {
if (this.$refs.signatureRef) {
// 如果组件有setSignature或类似方法可以调用
if (this.formData.userSign && typeof this.$refs.signatureRef.setSignature === 'function') {
if (this.formData.userSign && typeof this.$refs.signatureRef.setSignature === "function") {
this.$refs.signatureRef.setSignature(this.formData.userSign)
}
}