This commit is contained in:
2025-12-16 20:57:55 +08:00
parent f5b642c252
commit 74970eacb5
12 changed files with 422 additions and 167 deletions
@@ -106,6 +106,14 @@ public class WelfareSelectionSituationController {
situationService.exportXlsx(pageForm, response);
}
@At
@SaCheckPermission("welfare.selection.situation")
@Ok("void")
@ApiOperation("导出Excel")
public void receiveXlsx(@Valid @Param("pageForm") WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
situationService.receiveXlsx(pageForm, response);
}
@At
@SaCheckLogin
public Result getMobileByUserId(String userId) {
@@ -12,5 +12,6 @@ public interface WelfareSelectionSituationService extends BaseService<WelfareLis
Pagination pageData(WelfareSelectionSituationPageForm pageForm);
void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
}
@@ -16,13 +16,12 @@ import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -63,9 +62,27 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
public void updateProject(WelfareProject project) {
// 更新项目
update(project);
dao().clear(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", project.getId()));
List<WelfareProjectSubjectOption> optionList = dao().query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", project.getId()));
List<String> dbOptionIds = optionList.stream()
.map(WelfareProjectSubjectOption::getId)
.toList();
// 2. 获取 project 中的所有选项 ID(注意 null 安全)
List<String> projectOptionIds = project.getOptions() == null ?
Collections.emptyList() :
project.getOptions().stream()
.map(WelfareProjectSubjectOption::getId)
.filter(Objects::nonNull) // 避免 null id
.toList();
// 3. 找出需要删除的 ID:在 db 中但不在 project 中
List<String> toDeleteIds = dbOptionIds.stream()
.filter(id -> !projectOptionIds.contains(id))
.collect(Collectors.toList());
// 4. 批量删除
if (!toDeleteIds.isEmpty()) {
dao().clear(WelfareProjectSubjectOption.class,
Cnd.where(WelfareProjectSubjectOption::getId, "in", toDeleteIds));
}
// 新增或更新选项
for (WelfareProjectSubjectOption option : project.getOptions()) {
option.setWelfareId(project.getId());
dao().insertOrUpdate(option);
@@ -1,33 +1,45 @@
package com.budwk.app.zhgh.welfare.service.impl;
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareProject;
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.stream.Collectors;
@IocBean(args = {"refer:dao"})
@Slf4j
@@ -36,6 +48,9 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
super(dao);
}
@Inject
private SysFileService sysFileService;
@Override
public Pagination pageData(WelfareSelectionSituationPageForm pageForm) {
Sql sql = Sqls.create("""
@@ -46,7 +61,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
t1.welfareUnionName,
t1.welfareUnitName,
t1.welfareUnitId,
GROUP_CONCAT(DISTINCT t3.optionName) AS selectedOptions,
GROUP_CONCAT(DISTINCT t3.optionName ,'',t2.selectNum,'份)') AS selectedOptions,
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
t4.username AS userName,
@@ -105,7 +120,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
t1.id,
t1.welfareUnionName,
t1.welfareUnitName,
GROUP_CONCAT(DISTINCT t3.optionName) AS selectedOptions,
GROUP_CONCAT(DISTINCT t3.optionName,'',t2.selectNum,'份)') AS selectedOptions,
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
t4.username AS userName,
@@ -183,4 +198,84 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
log.error("导出Excel失败", e);
}
}
@Override
public void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
Sql sql = Sqls.create("""
SELECT
t1.*,
t2.userSign,
t3.username userName,
t3.loginname loginName,
GROUP_CONCAT(DISTINCT t2.selectOptionId) AS selectOptionIds
FROM
welfare_list t1
LEFT JOIN welfare_project_user_selection t2 ON t2.welfareId = t1.projectId
AND t2.selectUserId = t1.userId
LEFT JOIN sys_user t3 ON t3.id = t1.userId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t1.projectId", "=", pageForm.getProjectId());
cnd.groupBy("t1.id");
cnd.asc("t1.welfareUnitId");
sql.setCondition(cnd);
List<NutMap> list = listMap(sql);
List<WelfareProjectSubjectOption> optionList = dao().query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", pageForm.getProjectId()).asc("optionSort"));
for (NutMap map : list) {
if (map.get("selectOptionIds") != null){
String[] selectOptionIds = map.getString("selectOptionIds").split(",");
for (WelfareProjectSubjectOption option : optionList) {
if(Arrays.asList(selectOptionIds).contains(option.getId())){
map.put(option.getOptionName(), "");
}
}
}
if (map.get("userSign") != null){
try {
Sys_file file = dao().fetch(Sys_file.class, Cnd.where(Sys_file::getDownloadPath, "=", map.getString("userSign")));
byte[] userSignBytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath());
map.put("userSign", userSignBytes);
}catch (Exception e){
e.printStackTrace();
log.error("下载图片失败", e);
}
}
}
List<Map<String, Object>> safeList = list.stream().map(nutMap -> {
Map<String, Object> map = new HashMap<>(nutMap);
return map;
}).toList();
// 分组
Map<String, List<Map<String, Object>>> listMap = safeList.stream()
.collect(Collectors.groupingBy(n -> (String) n.get("welfareUnionName")));
// 构建 Excel 列
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginName", 20));
entities.add(new ExcelExportEntity("姓名", "userName", 20));
optionList.forEach(option -> {
entities.add(new ExcelExportEntity(option.getOptionName(), option.getOptionName(), 20));
});
ExcelExportEntity userSignEntity = new ExcelExportEntity("签字", "userSign", 20);
userSignEntity.setType(2);
userSignEntity.setExportImageType(2);
entities.add(userSignEntity);
// 导出
Workbook workbook = new HSSFWorkbook();
listMap.forEach((k, v) -> {
ExcelExportService service = new ExcelExportService();
ExportParams exportParams = new ExportParams();
exportParams.setSheetName(k);
exportParams.setType(ExcelType.HSSF);
service.createSheetForMap(workbook, exportParams, entities, v);
});
CommonDownloadUtil.download("领取表.xls", workbook, response);
}
}
@@ -100,6 +100,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
long teacherSum = welfareSelectionList.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId", "").equals(union.getString("id"))).count();
union.put("teacherSum", teacherSum);
// 已选人数
long selectedNum = welfareSelectionList.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId", "").equals(union.getString("id")) && v.getBoolean("has_selected")).count();
union.put("selectedNum", selectedNum);
@@ -109,8 +110,25 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
// 各选项的选择人数
for (WelfareProjectSubjectOption option : welfareOptions) {
long count = userSelections.stream().filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId").equals(union.getString("id")) && StrUtil.isNotBlank(v.getString("selectOptionId")) && v.getString("selectOptionId").equals(option.getId())).map(v -> v.getString("selectUserId")).distinct().count();
union.put(option.getId(), count);
int total = userSelections.stream()
.filter(v ->
StrUtil.isNotBlank(v.getString("welfareUnionId"))
&& v.getString("welfareUnionId").equals(union.getString("id"))
&& StrUtil.isNotBlank(v.getString("selectOptionId"))
&& v.getString("selectOptionId").equals(option.getId())
&& StrUtil.isNotBlank(v.getString("selectUserId")) // 确保 userId 有效
)
.collect(Collectors.toMap(
v -> v.getString("selectUserId"),
v -> v,
(existing, replacement) -> existing // 保留第一个
// 不传第四个参数,默认用 HashMap
))
.values()
.stream()
.mapToInt(v -> v.getInt("selectNum"))
.sum();
union.put(option.getId(), total);
}
}
@@ -360,7 +378,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
exportEntities.add(new ExcelExportEntity("电话号码", "mobile", 20));
exportEntities.add(new ExcelExportEntity("所在分工会", "welfareUnionName", 20));
exportEntities.add(new ExcelExportEntity("所在单位", "welfareUnitName", 20));
exportEntities.add(new ExcelExportEntity("所在福利", "optionName", 50));
exportEntities.add(new ExcelExportEntity("所在福利", "selectOptionName", 50));
Sql sql = Sqls.create("""
SELECT
@@ -419,14 +437,22 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("分工会", "name", 20));
entities.add(new ExcelExportEntity("本次福利会员人数", "teacherSum", 20));
entities.add(new ExcelExportEntity("已选人数", "selectedNum", 20));
entities.add(new ExcelExportEntity("未选人数", "unSelectedNum", 20));
ExcelExportEntity teacherSumEntity = new ExcelExportEntity("本次福利会员人数", "teacherSum", 20);
teacherSumEntity.setType(10);
entities.add(teacherSumEntity);
ExcelExportEntity selectedNumEntity = new ExcelExportEntity("已选人数", "selectedNum", 20);
selectedNumEntity.setType(10);
entities.add(selectedNumEntity);
ExcelExportEntity unSelectedNumEntity = new ExcelExportEntity("未选人数", "unSelectedNum", 20);
unSelectedNumEntity.setType(10);
entities.add(unSelectedNumEntity);
// 选项数据
List<WelfareProjectSubjectOption> welfareOptions = dao().query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", projectId));
for (WelfareProjectSubjectOption welfareOption : welfareOptions) {
entities.add(new ExcelExportEntity(welfareOption.getOptionName(), welfareOption.getId(), 20));
ExcelExportEntity entity = new ExcelExportEntity(welfareOption.getOptionName(), welfareOption.getId(), 20);
entity.setType(10);
entities.add(entity);
}
// 查询福利名单以及查询出选项数据
@@ -474,8 +500,25 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
// 各选项的选择人数
for (WelfareProjectSubjectOption option : welfareOptions) {
long count = userSelections.stream().filter(v -> v.getString("welfareUnionId").equals(union.getString("id")) && v.getString("selectOptionId").equals(option.getId())).map(v -> v.getString("selectUserId")).distinct().count();
union.put(option.getId(), count);
int total = userSelections.stream()
.filter(v ->
StrUtil.isNotBlank(v.getString("welfareUnionId"))
&& v.getString("welfareUnionId").equals(union.getString("id"))
&& StrUtil.isNotBlank(v.getString("selectOptionId"))
&& v.getString("selectOptionId").equals(option.getId())
&& StrUtil.isNotBlank(v.getString("selectUserId")) // 确保 userId 有效
)
.collect(Collectors.toMap(
v -> v.getString("selectUserId"),
v -> v,
(existing, replacement) -> existing // 保留第一个
// 不传第四个参数,默认用 HashMap
))
.values()
.stream()
.mapToInt(v -> v.getInt("selectNum"))
.sum();
union.put(option.getId(), total);
}
}
@@ -38,6 +38,12 @@ const selectView = {
<div class="info-item">
<div class="info-label">联系电话</div>
<div class="info-value">{{ mergedSelections[0]?.mobile || '暂无' }}</div>
</div>
<div class="info-item">
<div class="info-label">收货地址</div>
<div class="info-value">{{ mergedSelections[0]?.receiveAddress || '暂无' }}</div>
</div>
</div>
</div>
@@ -1,3 +1,4 @@
<!--#include("../addressManage/addressDialog.js"){}#-->
const optionSelect = {
template: /*language=HTML*/ `
<div class="welfare-select-container" v-if="projectInfo.id">
@@ -23,9 +24,9 @@ const optionSelect = {
<i class="el-icon-info"></i>
<span>项目信息</span>
</div>
<div class="project-cover" v-if="projectInfo.cover">
<!-- <div class="project-cover" v-if="projectInfo.cover">
<el-image :src="projectInfo.cover" fit="cover"></el-image>
</div>
</div>-->
<div class="welfare-info-content">
<div class="info-item">
<div class="info-label">项目名称</div>
@@ -133,7 +134,7 @@ const optionSelect = {
<el-dialog
title="确认选择"
:visible.sync="showConfirmDialog"
width="500px"
width="60%"
append-to-body
custom-class="welfare-confirm-dialog">
<div class="confirm-content">
@@ -141,6 +142,8 @@ const optionSelect = {
<div class="confirm-mobile-section">
<div class="confirm-section-title">联系信息</div>
<el-form :model="contactForm" ref="contactForm" :rules="contactRules" label-width="80px">
<el-row :gutter="10">
<el-col :span="24">
<el-form-item prop="mobile" label="联系电话">
<el-input
v-model="contactForm.mobile"
@@ -149,17 +152,27 @@ const optionSelect = {
clearable>
</el-input>
</el-form-item>
<el-form-item v-if="projectInfo.provideMode == 3" prop="receiveAddress" label="收货地址"
</el-col>
<el-col :span="20">
<el-form-item v-if="projectInfo.provideMode == 3" prop="receiveAddress"
label="收货地址"
:rules="[{ required: true, message: '请选择收货地址', trigger: 'change' }]">
<el-select v-model="contactForm.receiveAddress" placeholder="请选择收货地址"
style="width: 100%">
<el-option v-for="item in addressOptions"
:key="item.id"
:label="item.userName + ' ' + item.tel + ' ' + item.province + ' ' + item.city + ' ' + item.county + ' ' + item.addressDetail"
:value="item.userName + ' ' + item.tel + ' ' + item.province + ' ' + item.city + ' ' + item.county + ' ' + item.addressDetail">
:label="'收货人:'+item.userName + ',联系电话:' + item.tel + ',收货地址:' + item.province+ item.city+ item.county+ item.addressDetail"
:value="'收货人:'+item.userName + ',联系电话:' + item.tel + ',收货地址:' + item.province+ item.city+ item.county+ item.addressDetail">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-button @click="openAddress" type="primary">添加地址</el-button>
</el-col>
</el-row>
</el-form>
</div>
@@ -217,6 +230,8 @@ const optionSelect = {
<el-button type="primary" :loading="isSubmitting" @click="doSubmit">{{ hasSubmittedBefore ? '确认修改' : '确认提交' }}</el-button>
</span>
</el-dialog>
<address-dialog ref="addressDialog" @select_user_address="getAddress"></address-dialog>
</div>
`,
store,
@@ -250,6 +265,9 @@ const optionSelect = {
addressOptions: []
}
},
components: {
"address-dialog": ADDRESS_DIALOG
},
computed: {
// 是否有选择
hasSelection() {
@@ -323,6 +341,10 @@ const optionSelect = {
}
},
methods: {
openAddress() {
this.$refs.addressDialog.dialogVisible = true
this.$refs.addressDialog.formData = {userId: this.userId}
},
// 打开选择项目弹窗 userId为null默认则是本人
onOpen(projectId, userId = null) {
this.projectId = projectId
@@ -75,6 +75,10 @@ layout("/layouts/platform.html"){
<el-button type="primary" size="small" icon="el-icon-download" style="margin-left: 10px" @click="exportXlsx">
导出选择情况表
</el-button>
<el-button type="primary" size="small" icon="el-icon-download" style="margin-left: 10px" @click="receiveXlsx">
导出领取表
</el-button>
</table-tool>
<el-table
@@ -195,6 +199,11 @@ layout("/layouts/platform.html"){
this.$downLoad("/platform/welfare/selection/situation/exportXlsx", { pageForm: JSON.stringify(this.pageForm) })
},
// 导出选择情况表
receiveXlsx() {
this.$downLoad("/platform/welfare/selection/situation/receiveXlsx", { pageForm: JSON.stringify(this.pageForm) })
},
// 管理员待选
proxySelect(row) {
this.optionSelectVisible = true
@@ -85,11 +85,11 @@ layout("/layouts/platform_h5.html"){
<div class="wf-card-heading">{{row.name}}</div>
<div class="wf-time-row">
<span class="wf-time-label">开始时间:</span>
{{row.choiceTimeStart}}
{{$moment(row.choiceTimeStart).format('YYYY-MM-DD HH:mm')}}
</div>
<div class="wf-time-row">
<span class="wf-time-label">结束时间:</span>
{{row.choiceTimeEnd}}
{{$moment(row.choiceTimeEnd).format('YYYY-MM-DD HH:mm')}}
</div>
</div>
</div>
@@ -14,11 +14,16 @@ const selectView = {
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-skeleton title :row="6" :loading="loading" animated>
<!-- 项目基本信息 -->
<div class="welfare-card">
<van-collapse v-model="activeNames">
<van-collapse-item name="1">
<template #title>
<div class="welfare-card__header">
<i class="el-icon-s-flag"></i>
<span>项目基本信息</span>
</div>
</template>
<div class="welfare-card__content">
<div class="info-row">
<div class="info-row__label">项目名称</div>
@@ -27,23 +32,39 @@ const selectView = {
<div class="info-row info-row--time">
<div class="info-row__label">选择时间</div>
<div class="info-row__value">
<div class="time-item time-item--start">{{ projectInfo.choiceTimeStart }}</div>
<div class="time-item time-item--end">{{ projectInfo.choiceTimeEnd }}</div>
<div class="time-item time-item--start">{{
$moment(projectInfo.choiceTimeStart).format('YYYY-MM-DD HH:mm')
}}
</div>
<div class="time-item time-item--end">{{
$moment(projectInfo.choiceTimeEnd).format('YYYY-MM-DD HH:mm') }}
</div>
</div>
</div>
<div class="info-row info-row--time">
<div class="info-row__label">发放时间</div>
<div class="info-row__value">
<div class="time-item time-item--start">{{ projectInfo.provideTimeStart }}</div>
<div class="time-item time-item--end">{{ projectInfo.provideTimeEnd }}</div>
<div class="time-item time-item--start">{{
$moment(projectInfo.provideTimeStart).format('YYYY-MM-DD HH:mm')
}}
</div>
<div class="time-item time-item--end">{{
$moment(projectInfo.provideTimeEnd).format('YYYY-MM-DD HH:mm')
}}
</div>
</div>
</div>
<div class="info-row">
<div class="info-row__label">发放地点</div>
<div class="info-row__value">{{ projectInfo.provideAddress || '暂无' }}</div>
<div class="info-row__value">{{ projectInfo.provideAddress || '暂无'
}}
</div>
</div>
</div>
</van-collapse-item>
</van-collapse>
</div>
<!-- 联系信息 -->
<div class="welfare-card">
@@ -58,7 +79,9 @@ const selectView = {
</div>
<div class="info-row">
<div class="info-row__label">收货地址</div>
<div class="info-row__value">{{ mergedSelections[0]?.receiveAddress || '暂无' }}</div>
<div class="info-row__value">{{ mergedSelections[0]?.receiveAddress || '暂无'
}}
</div>
</div>
</div>
</div>
@@ -119,7 +142,8 @@ const selectView = {
>
<div class="welfare-detail" v-if="currentOption">
<van-skeleton title :row="10" :loading="descLoading" animated>
<div class="welfare-detail__content rich-text" v-html="currentOption.description || '暂无详细说明'"></div>
<div class="welfare-detail__content rich-text"
v-html="currentOption.description || '暂无详细说明'"></div>
</van-skeleton>
</div>
</van-action-sheet>
@@ -144,7 +168,8 @@ const selectView = {
},
selectedOptions: [],
detailVisible: false,
currentOption: null
currentOption: null,
activeNames:[]
}
},
computed: {
@@ -535,7 +535,8 @@ layout("/layouts/platform_h5.html"){
<div id="app" v-cloak>
<div class="page-container">
<van-nav-bar title="福利选择" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-nav-bar title="福利选择" left-text="返回" left-arrow @click-left="historyBack" fixed
placeholder></van-nav-bar>
<!-- 项目头部信息 -->
<div class="welfare-header" v-if="projectInfo.id">
@@ -567,26 +568,37 @@ layout("/layouts/platform_h5.html"){
<div class="welfare-notice">
<van-notice-bar wrapable :scrollable="false" background="#ecf6ff" color="var(--primary-color)">
<van-icon name="info-o" style="margin-right: 5px"></van-icon>
{{ projectInfo.isCheckBox === "radio" ? "请选择一项福利" : "您可以选择多项福利,最多可选 " + (projectInfo.multiSelectNum ||
{{ projectInfo.isCheckBox === "radio" ? "请选择一项福利" : "您可以选择多项福利,最多可选 " +
(projectInfo.multiSelectNum ||
projectInfo.options.length) + " 项" }}
</van-notice-bar>
</div>
<!-- 项目信息卡片 -->
<div class="welfare-info-card">
<van-collapse v-model="activeNames">
<van-collapse-item name="1">
<template #title>
<div class="welfare-info-header">
<div class="header-text">
<van-icon name="info-o" />
<van-icon name="info-o"></van-icon>
<span>项目信息</span>
</div>
</div>
</template>
<div class="welfare-cell-group">
<van-cell title="选择时间" :value="formatTimeRange(projectInfo.choiceTimeStart, projectInfo.choiceTimeEnd)"></van-cell>
<van-cell title="发放时间" :value="formatTimeRange(projectInfo.provideTimeStart, projectInfo.provideTimeEnd)"></van-cell>
<van-cell title="选择时间"
:value="formatTimeRange(projectInfo.choiceTimeStart, projectInfo.choiceTimeEnd)"></van-cell>
<van-cell title="发放时间"
:value="formatTimeRange(projectInfo.provideTimeStart, projectInfo.provideTimeEnd)"></van-cell>
<van-cell title="发放地点" :value="projectInfo.provideAddress"></van-cell>
</div>
</van-collapse-item>
<!-- <van-cell title="发放方式" :value="getProvideModeName(projectInfo.provideMode)"></van-cell>-->
<!-- <van-cell title="签字方式" :value="getSignModeName(projectInfo.signMode)"></van-cell>-->
</div>
</div>
<div class="section-divider"></div>
@@ -611,7 +623,8 @@ layout("/layouts/platform_h5.html"){
>
<div class="welfare-option-image">
<van-image :src="option.imgUrl" fit="cover" width="100%" height="100%" radius="4px"></van-image>
<div class="welfare-tag" v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0">
<div class="welfare-tag"
v-if="projectInfo.isCheckBox === 'radio' ? selectedRadioId === option.id : option.selectNum > 0">
<van-tag type="primary" round>已选择</van-tag>
</div>
</div>
@@ -658,13 +671,15 @@ layout("/layouts/platform_h5.html"){
<!-- 底部提交按钮 -->
<div class="welfare-footer" v-if="projectInfo.id">
<van-button type="primary" class="welfare-submit-btn" :disabled="submitButtonDisabled" @click="submitSelection" round>
<van-button type="primary" class="welfare-submit-btn" :disabled="submitButtonDisabled"
@click="submitSelection" round>
{{ isDeadlinePassed ? '已截止' : '确认选择' }}
</van-button>
</div>
<!-- 确认弹窗 -->
<van-action-sheet v-model="showConfirmDialog" :close-on-click-overlay="false" :round="true" :style="{ maxHeight: '90%' }">
<van-action-sheet v-model="showConfirmDialog" :close-on-click-overlay="false" :round="true"
:style="{ maxHeight: '90%' }">
<div class="confirm-action-sheet">
<div class="confirm-sheet-title">确认选择</div>
@@ -685,6 +700,8 @@ layout("/layouts/platform_h5.html"){
v-if="projectInfo.provideMode == 3"
v-model="formData.receiveAddress"
label="收货地址"
rows="4"
type="textarea"
placeholder="请选择收货地址"
readonly
is-link
@@ -713,7 +730,9 @@ layout("/layouts/platform_h5.html"){
<div class="confirm-section" v-if="projectInfo.signMode === 2">
<div class="confirm-section-title">请签字确认</div>
<h5-signature v-model="formData.userSign" ref="signatureRef"></h5-signature>
<div class="signature-tips">{{ formData.userSign ? '您已完成签名' : '请在上方空白区域完成签名' }}</div>
<div class="signature-tips">{{ formData.userSign ? '您已完成签名' : '请在上方空白区域完成签名'
}}
</div>
<div style="text-align: right; margin-top: 8px">
<van-button size="small" type="default" @click="resetSignature">重新签名</van-button>
</div>
@@ -721,14 +740,19 @@ layout("/layouts/platform_h5.html"){
</div>
<div class="confirm-fixed-buttons">
<van-button type="default" block round class="action-sheet-cancel" @click="showConfirmDialog = false">取消</van-button>
<van-button type="primary" block round @click="doSubmit">{{ hasSubmittedBefore ? '确认修改' : '确认提交' }}</van-button>
<van-button type="default" block round class="action-sheet-cancel"
@click="showConfirmDialog = false">取消
</van-button>
<van-button type="primary" block round @click="doSubmit">
{{ hasSubmittedBefore ? '确认修改' : '确认提交'}}
</van-button>
</div>
</div>
</van-action-sheet>
<!-- 选项详情弹窗 -->
<van-popup v-model="showOptionDetailDialog" round closeable close-icon="close" position="bottom" :style="{ maxHeight: '70%' }">
<van-popup v-model="showOptionDetailDialog" round closeable close-icon="close" position="bottom"
:style="{ maxHeight: '70%' }">
<div class="welfare-detail-popup" v-if="selectedOption">
<div class="welfare-detail-title">{{ selectedOption.optionName }}</div>
<div class="welfare-detail-content" v-html="selectedOption.description"></div>
@@ -748,16 +772,20 @@ layout("/layouts/platform_h5.html"){
<div style="display: flex; justify-content: space-between; align-items: flex-start">
<div style="flex: 1">
<div style="font-size: 16px; font-weight: 500; color: #323233; margin-bottom: 4px">
{{ address.userName }} {{ address.tel }}
收货人:{{ address.userName }}{{ address.tel }}
</div>
<div style="font-size: 14px; color: #646566; line-height: 1.4">
{{ address.province }}{{ address.city }}{{ address.county }}{{ address.addressDetail }}
收货地址: {{ address.province }}{{ address.city }}{{ address.county }}
{{address.addressDetail }}
</div>
</div>
<van-tag v-if="address.isDefault" type="primary" size="mini" style="margin-left: 8px">默认</van-tag>
<van-tag v-if="address.isDefault" type="primary" size="mini" style="margin-left: 8px">默认
</van-tag>
</div>
</div>
<div v-if="addressOptions.length === 0" style="text-align: center; padding: 40px 16px; color: #969799">暂无收货地址</div>
<div v-if="addressOptions.length === 0" style="text-align: center; padding: 40px 16px; color: #969799">
暂无收货地址
</div>
</div>
<div style="padding: 16px; border-top: 1px solid #f0f0f0; background: #fafafa">
<van-button type="info" block round @click="goToAddressManage">收货地址管理</van-button>
@@ -772,6 +800,7 @@ layout("/layouts/platform_h5.html"){
store,
data() {
return {
activeNames: [],
projectInfo: {},
userSelection: [],
welfareProvideMode: [],
@@ -1170,7 +1199,7 @@ layout("/layouts/platform_h5.html"){
// 选择收货地址
selectAddress(address) {
this.formData.receiveAddress =
address.userName + " " + address.tel + " " + address.province + address.city + address.county + address.addressDetail
"收货人:" + address.userName + ",联系电话:" + address.tel + ",收货地址:" + address.province + address.city + address.county + address.addressDetail
this.showAddressSheet = false
},
@@ -86,11 +86,11 @@ layout("/layouts/platform_h5.html"){
<div class="wf-card-heading">{{row.name}}</div>
<div class="wf-time-row">
<span class="wf-time-label">开始时间:</span>
{{row.choiceTimeStart}}
{{$moment(row.choiceTimeStart).format('YYYY-MM-DD HH:mm')}}
</div>
<div class="wf-time-row">
<span class="wf-time-label">结束时间:</span>
{{row.choiceTimeEnd}}
{{$moment(row.choiceTimeEnd).format('YYYY-MM-DD HH:mm')}}
</div>
</div>
</div>