This commit is contained in:
2026-03-02 14:10:53 +08:00
parent 3abdd05ce9
commit f2b2bf129f
11 changed files with 829 additions and 633 deletions
@@ -1,13 +1,16 @@
package io.v.nutz.zhgh.mobile.welfare;
import cn.hutool.core.util.StrUtil;
import cn.wizzer.framework.page.Pagination;
import io.v.nutz.base.annontation.ViReturn;
import io.v.nutz.base.result.Result;
import io.v.nutz.base.service.SimpleService;
import io.v.nutz.base.utils.DateUtil;
import io.v.nutz.base.query.PageForm;
import io.v.nutz.base.utils.Vi;
import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.welfare.mode.WelfareProvideMode;
import io.v.nutz.zhgh.welfare.model.WelfareList;
import io.v.nutz.zhgh.welfare.model.WelfareProject;
import io.v.nutz.zhgh.welfare.model.WelfareProjectSubject;
import io.v.nutz.zhgh.welfare.model.WelfareProjectSubjectOption;
@@ -28,6 +31,7 @@ import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -178,5 +182,31 @@ public class MWelfareController {
}
/**
* 获取用户积分是否满足
*
* @param projectId
* @param totalIntegral
* @return
*/
@At
public Result validateUserIntegral(String projectId, String totalIntegral) {
BigDecimal totalIntegralBig = new BigDecimal(totalIntegral);
if (StrUtil.isBlank(projectId)) {
return Result.error("数据错误!");
}
WelfareList welfareList = dao.fetch(WelfareList.class, Cnd.where("projectId", "=", projectId).and("userId", "=", ShiroUtil.getPrincipalProperty("id")));
if (welfareList == null) {
return Result.error("您暂无此福利!");
}
WelfareProject project = simpleService.dao().fetch(WelfareProject.class, projectId);
totalIntegralBig = totalIntegralBig.divide(BigDecimal.valueOf(100));
if (project.getAllIntegral().compareTo(totalIntegralBig) < 0) {
return Result.error("您的积分不足!");
}
return Result.success();
}
}
@@ -162,7 +162,7 @@ public class ShoppingTypeApplyController {
ShoppingType shoppingType = baseService.dao().fetch(ShoppingType.class, shoppingId);
for (WelfareProjectSubjectOption option : welfareProjectSubjectOption) {
// option.setShoppingName(shoppingType.getShoppingName());
// option.setShoppingId(shoppingId);
option.setShoppingId(shoppingId);
option.setOptionType("套餐");
option.setSubjectId(projectSubject.getId());
}
@@ -254,13 +254,35 @@ public class ShoppingTypeApplyController {
String SqlChooseUserByStoreId = """
SELECT
su.id,su.username,su.loginname,wpus.selectTime,su.unionname
FROM
`welfare_project_user_selection` wpus
LEFT JOIN welfare_project wp ON wpus.welfareId=wp.id
LEFT JOIN welfare_project_subject_option wpso ON wpus.selectOptionId = wpso.id
LEFT JOIN `user` su ON su.id=wpus.selectUserId
SELECT
CASE
WHEN
wus.selectUserId IS NOT NULL THEN
1 ELSE 0
END AS isChoose,
wl.id,
wl.unionid,
wl.username,
wl.loginname,
wl.personType,
wl.userState,
wl.unionname,
wl.unitname,
wl.listId,
wus.userSign,
wus.courierNumber,
GROUP_CONCAT( DISTINCT
IF
( wus.receiveAddress IS NOT NULL AND wus.receiveAddress != '', wus.receiveAddress, '' )
) AS receiveAddress,
GROUP_CONCAT( DISTINCT wuso.optionName, '(', wus.selectNum, '份)' ) AS gist_list
FROM
view_welfare_list wl
LEFT JOIN welfare_project_user_selection wus ON wus.welfareId = wl.projectId
AND wus.selectUserId = wl.id
LEFT JOIN welfare_project_subject_option wuso ON wus.selectOptionId = wuso.id
LEFT JOIN welfare_project wp ON wp.id = wus.welfareId
$condition
""";
@@ -278,40 +300,15 @@ public class ShoppingTypeApplyController {
Sql sql = Sqls.create(SqlChooseUserByStoreId);
Cnd cnd = Cnd.NEW();
cnd.and("wpso.shoppingId", "=", id);
cnd.and("wuso.shoppingId", "=", id);
cnd.andEX("wp.schoolWelfareId", "=", schoolWelfareId);
cnd.and("wp.choiceTimeEnd", "<", DateUtil.now());
cnd.andEX("su.unionId", "=", unionId);
cnd.groupBy("su.id");
cnd.asc("wpso.optionName");
cnd.asc("su.loginname");
cnd.andEX("wl.unionId", "=", unionId);
cnd.groupBy("wl.id");
cnd.asc("wuso.optionName");
cnd.asc("wl.loginname");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(page.getPageNumber(), page.getPageSize(), sql);
List<NutMap> list = pagination.getList();
list.forEach(v -> {
Sql sql_gift = Sqls.create("""
select wpus.id,wpso.optionName,wpus.receiveAddress from welfare_project_user_selection wpus
left join welfare_project_subject_option wpso on wpso.id = wpus.selectOptionId
where wpus.selectUserId = @uid and wpso.shoppingId=@shoppingId
""");
sql_gift.setParam("uid", v.getString("id"));
sql_gift.setParam("shoppingId", id);
List<NutMap> gift_list = baseService.listMap(sql_gift);
if (Lang.isNotEmpty(gift_list)) {
v.put("gist_list", gift_list.stream().map(x -> x.getString("optionName")).collect(Collectors.joining("、")));
if (!gift_list.stream().findFirst().get().getString("receiveAddress").contains("undefined")) {
v.put("receiveAddress", gift_list.stream().findFirst().get().getString("receiveAddress"));
} else {
v.put("receiveAddress", "");
}
} else {
v.put("gist_list", "");
v.put("receiveAddress", "");
}
});
return pagination;
}
@@ -323,37 +320,15 @@ public class ShoppingTypeApplyController {
Sql sql = Sqls.create(SqlChooseUserByStoreId);
Cnd cnd = Cnd.NEW();
cnd.and("wpso.shoppingId", "=", id);
cnd.and("wuso.shoppingId", "=", id);
cnd.andEX("wp.schoolWelfareId", "=", schoolWelfareId);
cnd.and("wp.choiceTimeEnd", "<", DateUtil.now());
cnd.andEX("su.unionId", "=", unionId);
cnd.groupBy("su.id");
cnd.asc("wpso.optionName");
cnd.asc("su.loginname");
cnd.andEX("wl.unionId", "=", unionId);
cnd.groupBy("wl.id");
cnd.asc("wuso.optionName");
cnd.asc("wl.loginname");
sql.setCondition(cnd);
List<NutMap> list = baseService.listMap(sql);
list.forEach(v -> {
Sql sql_gift = Sqls.create("""
select wpus.id,wpso.optionName,wpus.receiveAddress from welfare_project_user_selection wpus
left join welfare_project_subject_option wpso on wpso.id = wpus.selectOptionId
where wpus.selectUserId = @uid and wpso.shoppingId=@shoppingId
""");
sql_gift.setParam("uid", v.getString("id"));
sql_gift.setParam("shoppingId", id);
List<NutMap> gift_list = baseService.listMap(sql_gift);
if (Lang.isNotEmpty(gift_list)) {
v.put("gist_list", gift_list.stream().map(x -> x.getString("optionName")).collect(Collectors.joining("、")));
if (!gift_list.stream().findFirst().get().getString("receiveAddress").contains("undefined")) {
v.put("receiveAddress", gift_list.stream().findFirst().get().getString("receiveAddress"));
} else {
v.put("receiveAddress", "");
}
} else {
v.put("gist_list", "");
v.put("receiveAddress", "");
}
});
List<ExcelExportEntity> entityList = new ArrayList<>();
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
@@ -191,6 +191,7 @@ public class WelfareProjectMangeController {
optionChain.add("isSystemDefault", o.getIsSystemDefault());
optionChain.add("optionSort", o.getOptionSort());
optionChain.add("imgUrl", o.getImgUrl());
optionChain.add("integral", o.getIntegral());
optionChain.add("description", o.getDescription());
optionChain.add("shoppingId", o.getShoppingId());
optionChain.add("shoppingName", o.getShoppingName());
@@ -234,7 +235,6 @@ public class WelfareProjectMangeController {
// }
}
dao.update(project);
}
dao.clear(WelfareMemberUnionConfirm.class, Cnd.where("projectId","=",project.getId()));
@@ -11,6 +11,7 @@ import io.v.nutz.sys.services.SysUserService;
import io.v.nutz.web.commons.slog.annotation.SLog;
import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.welfare.model.WelfareList;
import io.v.nutz.zhgh.welfare.model.WelfareProject;
import io.v.nutz.zhgh.welfare.model.WelfareUserSelection;
import io.v.nutz.zhgh.welfare.service.WelfareProjectService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@@ -29,6 +30,7 @@ import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -107,7 +109,7 @@ public class WelfareUserChooseController {
@SLog(type = "welfare", tag = "pc电脑选福利", msg = "福利")
@RequiresPermissions("welfare.user.choose")
public Object doChoose(String chooseIds, String projectId, String subjectId, String receiveAddress,
@Param(value = "mobile",required = false) String mobile) {
@Param(value = "mobile", required = false) String mobile) {
try {
lock.lock();
String userId = ShiroUtil.getUserId();
@@ -159,15 +161,44 @@ public class WelfareUserChooseController {
@SLog(type = "welfare", tag = "选择福利", msg = "福利")
@RequiresPermissions("welfare.user.choose")
public Result confirmSelect(@Param("welfareUserSelections") WelfareUserSelection[] welfareUserSelections,
String projectId, @Param(value = "mobile",required = false) String mobile) {
String totalIntegral,
String projectId, @Param(value = "mobile", required = false) String mobile) {
try {
lock.lock();
WelfareProject project = simpleService.dao().fetch(WelfareProject.class, projectId);
// 获取当前时间
Date now = new Date();
// 判断时间段是否已结束
if (now.after(project.getProvideTimeEnd())) {
return Result.error("您选择的时间段已结束!");
}
// 判断时间段是否尚未开始
if (now.before(project.getProvideTimeStart())) {
return Result.error("您选择的时间段尚未开始!");
}
String userId = ShiroUtil.getUserId();
int count = simpleService.dao().count(WelfareList.class, Cnd.where("projectId", "=", projectId).and("userId", "=", userId));
if (count <= 0) {
return Result.error("您不在此次选择名单中,如有疑问请及时联系校工会");
WelfareList welfareList = simpleService.dao().fetch(WelfareList.class, Cnd.where("projectId", "=", projectId).and("userId", "=", ShiroUtil.getUserId()));
if (Lang.isEmpty(welfareList)) {
return Result.error("您暂无权限!");
}
//如果是积分模式
if (project.getIsIntegralMode()) {
BigDecimal totalIntegralBig = new BigDecimal(totalIntegral);
totalIntegralBig = totalIntegralBig.divide(BigDecimal.valueOf(100));
if (totalIntegralBig.compareTo(BigDecimal.ZERO) == 0) {
return Result.error("请选择后在提交!");
}
if (project.getAllIntegral().compareTo(totalIntegralBig) < 0) {
return Result.error("您的积分不足!");
}
if (totalIntegralBig.compareTo(project.getAllIntegral()) < 0) {
BigDecimal remainingIntegral = project.getAllIntegral().subtract(totalIntegralBig);
return Result.error("您积分还剩余" + remainingIntegral + ",请选择后再提提交!");
}
}
//删除上次选择的
@@ -178,7 +209,7 @@ public class WelfareUserChooseController {
for (WelfareUserSelection welfareUserSelection : welfareUserSelections) {
welfareUserSelection.setSelectUserId(userId);
welfareUserSelection.setSelectTime(new Date());
if (welfareUserSelection.getSelectNum() > 1) {
if (welfareUserSelection.getSelectNum() > 1 && !project.getIsIntegralMode()) {
return Result.error("福利选择限制超过最大限制");
}
}
@@ -195,7 +226,7 @@ public class WelfareUserChooseController {
}
return Result.success("选择成功");
} catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
return Result.error();
} finally {
@@ -14,6 +14,7 @@ import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@@ -219,6 +220,17 @@ public class WelfareProject extends BaseModel implements Serializable, SysHomeCo
@ColDefine(type = ColType.BOOLEAN)
private Boolean isYearBirthday;
@Column
@Comment("是否积分模式")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isIntegralMode;
@Column
@Comment("总积分")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal allIntegral;
@Column
@Comment("是否禁用")
@Default("0")
@@ -89,4 +89,10 @@ public class WelfareProjectSubjectOption extends BaseModel {
@Comment("简短备注")
@ColDefine(type = ColType.VARCHAR,width = 100)
private String simpleDesc;
@Column
@Comment("套餐积分")
@Default("0")
@ColDefine(type = ColType.INT)
private Integer integral;
}
@@ -104,6 +104,14 @@
<el-input v-model="row.supplier" type="textarea" max="100"></el-input>
</template>
</el-table-column>
<el-table-column
align="center"
header-align="center"
v-if="is_integral_mode" label="所需积分" width="150">
<template slot-scope="{row}">
<el-input-number v-model="row.integral" style="width: 100%"></el-input-number>
</template>
</el-table-column>
<!-- <el-table-column label="备注2">
<template slot-scope="{row}">
@@ -129,7 +137,7 @@
:width="100"
:limit="1"
:file-type="['png','jpg']"
:file-size="0.2"
:file-size="5"
:size="[500,200]"
v-model="row.imgUrl"></image-upload>
</template>
@@ -175,7 +183,14 @@
<div class="s-operation">
<el-button size="small" type="primary"
@click="s.options.push({optionType:'套餐',optionNameId:'',optionName:'福利'+(s.options.length+1),optionSort:s.options.length+1,imgUrl:null,isDefaultOption:false,isSystemDefault:false})">
@click="s.options.push({optionType:'套餐',
optionNameId:'',
optionName:'福利'+(s.options.length+1),
optionSort:s.options.length+1,
imgUrl:null,
integral:0,
isDefaultOption:false,
isSystemDefault:false})">
添加福利
</el-button>
</div>
@@ -217,6 +232,10 @@ module.exports = {
subject: {
type: Array,
default: []
},
is_integral_mode: {
type: Boolean,
default: false
}
},
data() {
@@ -152,7 +152,8 @@ layout("/mobile/platform.html"){
<template v-show="vLoading && !vLoading.value">
<div>
<van-image :src="CREATE_PREVIEW_URL(projectInfo.cover)" fit="cover" style="width: 100%; height: 150px"></van-image>
<van-image :src="CREATE_PREVIEW_URL(projectInfo.cover)" fit="cover"
style="width: 100%; height: 150px"></van-image>
</div>
<!--基本信息-->
@@ -171,15 +172,17 @@ layout("/mobile/platform.html"){
<template v-if="clickUpOrDown">
<van-cell :border="false" :value="projectInfo.name" title="福利名称"></van-cell>
<van-cell :border="false" :value="projectInfo.festival" title="发放节日"></van-cell>
<van-cell :border="false" :value="projectInfo.gift" title="福利礼品" v-if="!projectInfo.flexible"></van-cell>
<van-cell :border="false" :value="projectInfo.gift" title="福利礼品"
v-if="!projectInfo.flexible"></van-cell>
<!--<van-cell :border="false" :value="projectInfo.provideAddress"
title="发放地点"></van-cell>-->
<van-cell :border="false" title="选择形式">{{projectInfo.isCheckBox==='checkBox'?'多选':'单选'}}</van-cell>
<van-cell :border="false" title="选择形式">{{projectInfo.isCheckBox==='checkBox'?'多选':'单选'}}
</van-cell>
<van-cell
:border="false"
:value="projectInfo.multiSelectNum"
title="最多选几个"
v-if="projectInfo.isCheckBox==='checkBox'"
:border="false"
:value="projectInfo.multiSelectNum"
title="最多选几个"
v-if="projectInfo.isCheckBox==='checkBox'"
></van-cell>
<van-cell :border="false" title="发放形式">
<template>
@@ -189,20 +192,26 @@ layout("/mobile/platform.html"){
</van-cell>
<van-cell :border="false" title="签收形式">
<template>
{{welfareSignMode.find(v=>v.code==projectInfo.signMode) && welfareSignMode.find(v=>v.code==projectInfo.signMode).description}}
{{welfareSignMode.find(v=>v.code==projectInfo.signMode) &&
welfareSignMode.find(v=>v.code==projectInfo.signMode).description}}
</template>
</van-cell>
<van-cell :border="false" title="选择时间">
<template #label>{{projectInfo.choiceTimeStart + ' 至 ' + projectInfo.choiceTimeEnd}}</template>
</van-cell>
<van-cell :border="false" title="当前可使用积分" v-if="projectInfo.isIntegralMode">
<template>
{{projectInfo.allIntegral}}
</template>
</van-cell>
</template>
</van-cell-group>
<!--礼品套餐-->
<div
class="van-cell-group--inset"
style="margin: 10px auto"
v-if="projectInfo.flexible && [2,3].includes(projectInfo.provideMode)
class="van-cell-group--inset"
style="margin: 10px auto"
v-if="projectInfo.flexible && [2,3].includes(projectInfo.provideMode)
&& projectInfo.welfareProjectSubjects
&& projectInfo.welfareProjectSubjects.length>0"
>
@@ -210,13 +219,14 @@ layout("/mobile/platform.html"){
<div style="font-weight: bold; font-size: 15px; display: flex; align-items: center">选择套餐</div>
</van-cell>
<div class="selection" style="background: #fff" v-for="(subject,sidx) in projectInfo.welfareProjectSubjects">
<div class="selection" style="background: #fff"
v-for="(subject,sidx) in projectInfo.welfareProjectSubjects">
<div style="display: flex; width: 100%; padding: 10px 0" v-for="(option, oidx) in subject.options">
<div style="width: 120px; height: 100px; display: flex; justify-content: center; align-items: center">
<div style="width: 120px; height: 130px; display: flex; justify-content: center; align-items: center">
<van-image
:src="FILE_STREAM_PREVIEW_ADDRESS+'?id='+option.imgUrl"
fit="contain"
style="width: 100px; height: 100px; border-radius: 10px"
:src="FILE_STREAM_PREVIEW_ADDRESS+'?id='+option.imgUrl"
fit="contain"
style="width: 100px; height: 130px; border-radius: 10px"
></van-image>
<!-- @click="vant.ImagePreview([CREATE_PREVIEW_URL(option.imgUrl)])"-->
</div>
@@ -230,34 +240,42 @@ layout("/mobile/platform.html"){
</div>
<div class="optionDesc" v-if="option.simpleDesc">备注:{{option.simpleDesc}}</div>
<div style="position: absolute; right: 10px; bottom: 0; left: 0; display: flex; justify-content: space-between">
<div @click="openViewDesc(option.description)" style="width: 70px; font-size: 13px; color: #918a8a; text-align: right">
<div @click="openViewDesc(option.description)"
style="width: 70px; font-size: 13px; color: #918a8a; text-align: right">
套餐详情
</div>
<van-stepper
:default-value="0"
:disabled="confirmButtonInfo.disabled"
:min="0"
@change="(value)=>{numChange(value,option,oidx)}"
async-change
button-size="20"
disable-input
integer
theme="round"
v-model="option.selectNum"
:default-value="0"
:disabled="confirmButtonInfo.disabled"
:min="0"
@change="(value)=>{numChange(value,option,oidx)}"
async-change
button-size="20"
disable-input
integer
theme="round"
v-model="option.selectNum"
></van-stepper>
</div>
<div v-if="projectInfo.isIntegralMode"
style="position: absolute; right: 20px; bottom: 0;top:105px;display: flex; justify-content: space-between">
<div style="font-size: 14px; line-height: 14px;">
积分:<span style="color:red; margin-left: 4px; font-size: 14px; line-height: 14px;">{{option.integral}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<van-submit-bar
:button-text="confirmButtonInfo.text"
@submit="confirmSelect"
tip="您可以在福利选择截至时间之前修改福利套餐"
tip-icon="info-o"
:button-text="confirmButtonInfo.text"
@submit="confirmSelect"
:price="totalIntegral"
tip="您可以在福利选择截至时间之前修改福利套餐"
tip-icon="info-o"
>
<div style="width: calc(100% - 110px)">
<div style="width: calc(100% - 400px)">
<div style="width: 25px; height: 25px; position: relative">
<van-icon name="shopping-cart-o" size="25"></van-icon>
<div class="van-info">{{sumSelectNum}}</div>
@@ -266,11 +284,13 @@ layout("/mobile/platform.html"){
</van-submit-bar>
</template>
<van-popup :style="{ height: '70%' }" closeable position="bottom" safe-area-inset-bottom v-model="selectAddressPopup">
<van-popup :style="{ height: '70%' }" closeable position="bottom" safe-area-inset-bottom
v-model="selectAddressPopup">
<div style="height: 100%">
<div style="font-size: 15px; font-weight: bold; text-align: center; padding-top: 16px">配送至</div>
<template v-if="addressList && addressList.length>0">
<van-cell @click="addressClick(item);selectAddressPopup=false" clickable icon="location-o" v-for="item in addressList">
<van-cell @click="addressClick(item);selectAddressPopup=false" clickable icon="location-o"
v-for="item in addressList">
<template #title>{{item.address}}</template>
<template #label>
<div>{{"地区:" + item.province + item.city + item.county}}</div>
@@ -283,7 +303,9 @@ layout("/mobile/platform.html"){
<van-empty description="暂无地址" v-else></van-empty>
<div style="position: absolute; bottom: 0; left: 0; box-sizing: border-box; width: 100%; padding: 0 16px; background: #fff">
<van-button @click="openAddressManage" block round style="height: 40px; margin: 5px 0" type="danger">地址管理</van-button>
<van-button @click="openAddressManage" block round style="height: 40px; margin: 5px 0" type="danger">
地址管理
</van-button>
</div>
</div>
</van-popup>
@@ -297,13 +319,13 @@ layout("/mobile/platform.html"){
</van-popup>
<van-popup
:close-on-click-overlay="false"
:style="{ height: '90vh', 'overflow-y':'auto', background:'#f9f9f9'}"
closeable
position="bottom"
round
safe-area-inset-bottom
v-model="confirmPopup"
:close-on-click-overlay="false"
:style="{ height: '90vh', 'overflow-y':'auto', background:'#f9f9f9'}"
closeable
position="bottom"
round
safe-area-inset-bottom
v-model="confirmPopup"
>
<div>
<!--选择的信息-->
@@ -314,16 +336,17 @@ layout("/mobile/platform.html"){
</van-cell>
<van-cell style="padding: 0" v-for="(item,index) in selectedOptions">
<van-card
:key="item.id"
:num="item.selectNum"
:thumb="FILE_STREAM_PREVIEW_ADDRESS+'?id='+item.imgUrl"
:title="item.optionName"
desc=""
style="border-radius: 8px; background: #ffffff"
:key="item.id"
:num="item.selectNum"
:thumb="FILE_STREAM_PREVIEW_ADDRESS+'?id='+item.imgUrl"
:title="item.optionName"
desc=""
style="border-radius: 8px; background: #ffffff"
></van-card>
<div class="van-hairline--top"></div>
<van-cell>
<van-field label="联系方式" v-model="mobile" required placeholder="请输入联系方式" type="tel" maxlength="11"></van-field>
<van-field label="联系方式" v-model="mobile" required placeholder="请输入联系方式" type="tel"
maxlength="11"></van-field>
</van-cell>
<van-cell @click="openShoppingPopup(item,index)" is-link title="取货门店" v-if="item.shoppingId">
<template #label>{{item.receiveAddress?item.receiveAddress:'暂未选择'}}</template>
@@ -354,7 +377,8 @@ layout("/mobile/platform.html"){
</van-cell>
<van-cell title="">
<template #label>
<mobile-sign :is_value_base64="false" prefix="welfare" ref="signature" v-model="signData"></mobile-sign>
<mobile-sign :is_value_base64="false" prefix="welfare" ref="signature"
v-model="signData"></mobile-sign>
</template>
</van-cell>
</div>
@@ -366,22 +390,24 @@ layout("/mobile/platform.html"){
</van-popup>
<van-popup
:style="{ height: '90vh', 'overflow-y':'auto', background:'#f9f9f9'}"
closeable
position="bottom"
round
safe-area-inset-bottom
v-model="shoppingPopup"
:style="{ height: '90vh', 'overflow-y':'auto', background:'#f9f9f9'}"
closeable
position="bottom"
round
safe-area-inset-bottom
v-model="shoppingPopup"
>
<div>
<div style="margin-top: 45px">
<van-search @search="onSearchShoppingAddress" placeholder="请输入门店关键词" show-action v-model="shoppingAddress">
<van-search @search="onSearchShoppingAddress" placeholder="请输入门店关键词" show-action
v-model="shoppingAddress">
<template #action>
<div @click="onSearchShoppingAddress">搜索</div>
</template>
</van-search>
<div class="van-cell-group--inset" v-if="offlineStoresOption && offlineStoresOption.length>0">
<van-cell icon="location-o" class="custom-cell" @click="addShopping(item.address)" v-for="item in offlineStoresOption">
<van-cell icon="location-o" class="custom-cell" @click="addShopping(item.address)"
v-for="item in offlineStoresOption">
{{item.address}}
</van-cell>
</div>
@@ -424,7 +450,8 @@ layout("/mobile/platform.html"){
optionData: {},
clickUpOrDown: false,
mobile: ""
mobile: "",
totalIntegral: 0
}
},
computed: {
@@ -450,36 +477,36 @@ layout("/mobile/platform.html"){
},
confirmButtonInfo() {
if (this.projectInfo) {
const { choiceTimeEnd, choiceTimeStart, overdueChoiceTimeEnd } = this.projectInfo
const {choiceTimeEnd, choiceTimeStart, overdueChoiceTimeEnd} = this.projectInfo
const now = moment().valueOf()
if (overdueChoiceTimeEnd == null || overdueChoiceTimeEnd === "") {
if (now > moment(choiceTimeStart).valueOf() && now < moment(choiceTimeEnd).valueOf()) {
return { text: this.isSelect ? "选好了,下一步" : "选好了,下一步", disabled: false }
return {text: this.isSelect ? "选好了,下一步" : "选好了,下一步", disabled: false}
} else if (now > moment(choiceTimeEnd).valueOf()) {
return { text: "选择已结束", disabled: true }
return {text: "选择已结束", disabled: true}
} else if (now < moment(choiceTimeStart).valueOf()) {
return { text: "选择未开始", disabled: true }
return {text: "选择未开始", disabled: true}
}
} else {
//已选择了不能再动了
if (this.isSelect) {
if (moment(this.selectTime).valueOf() > moment(choiceTimeEnd).valueOf() && now < moment(overdueChoiceTimeEnd).valueOf()) {
return { text: "下一步", disabled: false }
return {text: "下一步", disabled: false}
}
return { text: "选择已结束", disabled: true }
return {text: "选择已结束", disabled: true}
} else {
if (now > moment(choiceTimeStart).valueOf() && now < moment(overdueChoiceTimeEnd).valueOf()) {
return { text: this.isSelect ? "选好了,下一步" : "选好了,下一步", disabled: false }
return {text: this.isSelect ? "选好了,下一步" : "选好了,下一步", disabled: false}
} else if (now > moment(overdueChoiceTimeEnd).valueOf()) {
return { text: "选择已结束", disabled: true }
return {text: "选择已结束", disabled: true}
} else if (now < moment(choiceTimeStart).valueOf()) {
return { text: "选择未开始", disabled: true }
return {text: "选择未开始", disabled: true}
}
}
}
}
return { text: "", disabled: true }
return {text: "", disabled: true}
},
selectedOptions() {
if (this.projectInfo && this.projectInfo.welfareProjectSubjects) {
@@ -536,7 +563,7 @@ layout("/mobile/platform.html"){
overlay: true,
duration: 0
})
const resp = await $.post("/mobile/welfare/mine/deleteAddress", { id: item.id })
const resp = await $.post("/mobile/welfare/mine/deleteAddress", {id: item.id})
loading.close()
if (resp.code === 0) {
this.$toast.success(resp.msg)
@@ -556,23 +583,37 @@ layout("/mobile/platform.html"){
},
//数量更改
numChange(value, option, optionIndex) {
const { isCheckBox, multiSelectNum, singleOptionSupportMultipleSelection } = this.projectInfo
if (isCheckBox === "checkBox") {
//判断是否支持单个多选
if (!singleOptionSupportMultipleSelection && value > 1) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", 1)
this.$toast("此套餐最多只能选择1份")
return
const {
isIntegralMode,
isCheckBox,
multiSelectNum,
singleOptionSupportMultipleSelection
} = this.projectInfo
if (isIntegralMode) {
let totalIntegral = 0
this.projectInfo.welfareProjectSubjects[0].options.forEach(v => {
totalIntegral = totalIntegral + (v.integral * v.selectNum)
})
this.totalIntegral = totalIntegral * 100
} else {
if (isCheckBox === "checkBox") {
//判断是否支持单个多选
if (!singleOptionSupportMultipleSelection && value > 1) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", 1)
this.$toast("此套餐最多只能选择1份")
return
}
}
//获取用户当前选择的数量
const selectNums = this.projectInfo.welfareProjectSubjects[0].options.map((v) => v.selectNum)
const sum = selectNums.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
if (sum > multiSelectNum) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", value - 1)
this.$toast("此次福利最多只能选择" + multiSelectNum + "份")
}
}
//获取用户当前选择的数量
const selectNums = this.projectInfo.welfareProjectSubjects[0].options.map((v) => v.selectNum)
const sum = selectNums.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
if (sum > multiSelectNum) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", value - 1)
this.$toast("此次福利最多只能选择" + multiSelectNum + "份")
}
},
//确定选择
@@ -582,13 +623,25 @@ layout("/mobile/platform.html"){
return
}
const { isCheckBox, multiSelectNum, singleOptionSupportMultipleSelection } = this.projectInfo
if (isCheckBox === "checkBox") {
if (this.sumSelectNum < multiSelectNum) {
//用户没有选择完
this.$toast("一共可以选择" + multiSelectNum + "份,您目前只选择了" + this.sumSelectNum + "份,快去选择吧!")
const {id, isCheckBox, multiSelectNum, isIntegralMode} = this.projectInfo
//积分模式
if (isIntegralMode) {
const resp = await $.post("/mobile/welfare/list/validateUserIntegral", {
projectId: id,
totalIntegral: this.totalIntegral
})
if (resp.code !== 0) {
this.$toast.fail(resp.msg)
return
}
} else {
if (isCheckBox === "checkBox") {
if (this.sumSelectNum < multiSelectNum) {
//用户没有选择完
this.$toast("一共可以选择" + multiSelectNum + "份,您目前只选择了" + this.sumSelectNum + "份,快去选择吧!")
return
}
}
}
this.confirmPopup = true
@@ -643,7 +696,7 @@ layout("/mobile/platform.html"){
this.$modal.msg("请选择取货门店:" + notReceiveAddress.join(","))
return
}
const { code, msg, data } = await $.post("/platform/welfare/userChoose/confirmSelect", {
const {code, msg, data} = await $.post("/platform/welfare/userChoose/confirmSelect", {
welfareUserSelections: JSON.stringify(formData),
projectId: this.projectId,
mobile: this.mobile
@@ -696,12 +749,12 @@ layout("/mobile/platform.html"){
//地址列表点击
addressClick(item) {
const { province, city, county, address, name, tel } = item
const {province, city, county, address, name, tel} = item
this.selectAddress = "收货地址:" + province + city + county + address + "," + "收件人:" + name + "," + "联系方式:" + tel
},
async getProjectInfo() {
const resp = await $.get("/platform/welfare/common/findOne", { projectId: this.projectId })
const resp = await $.get("/platform/welfare/common/findOne", {projectId: this.projectId})
if (resp.code === 0) {
resp.data.multiSelectNum = resp.data.multiSelectNum ? resp.data.multiSelectNum : 1
this.projectInfo = resp.data
@@ -711,7 +764,7 @@ layout("/mobile/platform.html"){
//获取用户选择的数据
async getUserSelection(projectId) {
const resp = await $.get("/platform/welfare/mine/getUserSelection", { projectId: projectId })
const resp = await $.get("/platform/welfare/mine/getUserSelection", {projectId: projectId})
this.userSelection = resp.data
this.echoUserSelection()
},
@@ -11,12 +11,12 @@ layout("/layouts/platform.html"){
<div class="search-item-label">年&emsp;&emsp;度:</div>
<div class="search-item-option">
<el-date-picker
@change="doSearch"
placeholder="选择年"
style="width: 100%"
type="year"
v-model="pageForm.year"
value-format="yyyy"
@change="doSearch"
placeholder="选择年"
style="width: 100%"
type="year"
v-model="pageForm.year"
value-format="yyyy"
></el-date-picker>
</div>
</div>
@@ -24,8 +24,10 @@ layout("/layouts/platform.html"){
<div class="search-item" v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('SchoolUnionAdmin')}">
<div class="search-item-label">所属福利:</div>
<div class="search-item-option">
<el-select @change="projectChange" clearable style="width: 100%" v-model="pageForm.welfareId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in projectOptions"></el-option>
<el-select @change="projectChange" clearable style="width: 100%"
v-model="pageForm.welfareId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in projectOptions"></el-option>
</el-select>
</div>
</div>
@@ -34,10 +36,10 @@ layout("/layouts/platform.html"){
<div class="search-item-label">供应商:</div>
<div class="search-item-option">
<el-input
@keyup.enter.native="doSearch()"
clearable
placeholder="请输入供应商名称"
v-model="pageForm.shoppingName"
@keyup.enter.native="doSearch()"
clearable
placeholder="请输入供应商名称"
v-model="pageForm.shoppingName"
></el-input>
</div>
</div>
@@ -68,67 +70,68 @@ layout("/layouts/platform.html"){
</table-tool>
<el-table
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
class="vi-table"
row-key="id"
style="width: 100%; margin-bottom: 20px"
v-loading="tableLoading"
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
class="vi-table"
row-key="id"
style="width: 100%; margin-bottom: 20px"
v-loading="tableLoading"
>
<el-table-column
:index="indexMethod"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
: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"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='link'">
<el-link @click="openLink(row.link)" type="primary">{{row.link}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='qrCode'">
<el-image
:preview-src-list="[APP_DOMAIN+'/file_server/fileStreamPreview?id='+row.qrCodeId]"
:src="APP_DOMAIN+'/file_server/fileStreamPreview?id='+row.qrCodeId"
v-if="row.qrCodeId"
:preview-src-list="[APP_DOMAIN+'/file_server/fileStreamPreview?id='+row.qrCodeId]"
:src="APP_DOMAIN+'/file_server/fileStreamPreview?id='+row.qrCodeId"
v-if="row.qrCodeId"
></el-image>
<template v-else>暂无</template>
</template>
<template scope="{row}" v-else-if="column.prop=='isEnable'">
<template v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('SchoolUnionAdmin')}">
<el-switch
@change="isEnableChange(row.isEnable,row.id)"
active-color="#13ce66"
inactive-color="#ff4949"
v-model="row.isEnable"
@change="isEnableChange(row.isEnable,row.id)"
active-color="#13ce66"
inactive-color="#ff4949"
v-model="row.isEnable"
></el-switch>
</template>
<template v-else>
<el-switch active-color="#13ce66" disabled inactive-color="#ff4949" v-model="row.isEnable"></el-switch>
<el-switch active-color="#13ce66" disabled inactive-color="#ff4949"
v-model="row.isEnable"></el-switch>
</template>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" prop="userOnline" width="100px">
<el-table-column align="center" header-align="center" label="操作" prop="userOnline" width="300px">
<template scope="{row}">
<!-- <el-button size="mini" type="primary" plain @click="openPackage(row)">
录入套餐
</el-button>
<el-button size="mini" type="primary" @click="openPackage(row)">
录入套餐
</el-button>
<el-button size="mini" type="primary" plain @click="openView(row)">
查看领取情况
</el-button>-->
<el-button size="mini" type="primary" @click="openView(row)">
查看领取情况
</el-button>
<el-button @click="openEdit(row)" size="mini" type="primary">编辑</el-button>
<!-- <template v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('SchoolUnionAdmin')}">
@@ -150,32 +153,40 @@ layout("/layouts/platform.html"){
<vi-title2 class="mt20" title="会员所选明细">
<template #func>
<el-select
@change="chooseUserByStoreIdData"
clearable
filterable
filterable
placeholder="请选择工会查询"
v-model="choosePageForm.unionId"
@change="chooseUserByStoreIdData"
clearable
filterable
filterable
placeholder="请选择工会查询"
v-model="choosePageForm.unionId"
>
<el-option :key="item.id" :label="item.unionname" :value="item.id" v-for="item in unionOptions"></el-option>
<el-option :key="item.id" :label="item.unionname" :value="item.id"
v-for="item in unionOptions"></el-option>
</el-select>
<el-button @click="doChooseExport" class="ml10" icon="el-icon-download" plain type="primary">导出明细</el-button>
<el-button @click="doChooseExport" class="ml10" icon="el-icon-download" plain type="primary">
导出明细
</el-button>
</template>
</vi-title2>
<el-table
:data="chooseTableData"
:size="tableSize"
class="vi-table"
row-key="id"
style="width: 100%; margin-bottom: 20px"
v-loading="tableLoading"
:data="chooseTableData"
:size="tableSize"
class="vi-table"
row-key="id"
style="width: 100%; margin-bottom: 20px"
v-loading="tableLoading"
>
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index" width="80px"></el-table-column>
<el-table-column align="center" header-align="center" label="工号" prop="loginname" width="200px"></el-table-column>
<el-table-column align="center" header-align="center" label="姓名" prop="username" width="200px"></el-table-column>
<el-table-column align="center" header-align="center" label="所属基层工会" prop="unionname" width="200px"></el-table-column>
<el-table-column align="center" header-align="center" label="所选福利" prop="gist_list" width="200px"></el-table-column>
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index"
width="80px"></el-table-column>
<el-table-column align="center" header-align="center" label="工号" prop="loginname"
width="200px"></el-table-column>
<el-table-column align="center" header-align="center" label="姓名" prop="username"
width="200px"></el-table-column>
<el-table-column align="center" header-align="center" label="所属基层工会" prop="unionname"
width="200px"></el-table-column>
<el-table-column align="center" header-align="center" label="所选福利" prop="gist_list"
width="200px"></el-table-column>
<el-table-column align="center" header-align="center" label="配送地址" prop="receiveAddress">
<template scope="{row}">
@@ -185,13 +196,13 @@ layout("/layouts/platform.html"){
</el-table>
<el-row class="el-pagination-container" style="margin-bottom: 0px">
<el-pagination
:current-page="choosePageForm.pageNumber"
:page-size="choosePageForm.pageSize"
:page-sizes="[5,10, 20, 30, 50]"
:total="choosePageForm.totalCount"
@current-change="choosePageNumberChange"
@size-change="choosePageSizeChange"
layout="total, sizes, prev, pager, next"
:current-page="choosePageForm.pageNumber"
:page-size="choosePageForm.pageSize"
:page-sizes="[5,10, 20, 30, 50]"
:total="choosePageForm.totalCount"
@current-change="choosePageNumberChange"
@size-change="choosePageSizeChange"
layout="total, sizes, prev, pager, next"
></el-pagination>
</el-row>
@@ -263,7 +274,8 @@ layout("/layouts/platform.html"){
</template>
<template #edit>
<el-form :model="formData" :rules="rules" label-position="right" label-suffix=":" label-width="130px" ref="addForm">
<el-form :model="formData" :rules="rules" label-position="right" label-suffix=":" label-width="130px"
ref="addForm">
<el-row :gutter="60">
<el-col :span="12">
<el-form-item label="年度" prop="year">
@@ -280,22 +292,22 @@ layout("/layouts/platform.html"){
<el-col :span="12">
<el-form-item label="联系人" prop="loginName">
<el-select
:loading="selectLoading"
:remote-method="remoteMethod"
@change="userChang"
clearable
filterable
placeholder="请选择联系人"
remote
reserve-keyword
style="width: 100%"
v-model="formData.loginName"
:loading="selectLoading"
:remote-method="remoteMethod"
@change="userChang"
clearable
filterable
placeholder="请选择联系人"
remote
reserve-keyword
style="width: 100%"
v-model="formData.loginName"
>
<el-option
:key="item.loginname"
:label="item.username+'-'+item.loginname"
:value="item.loginname"
v-for="item in userList"
:key="item.loginname"
:label="item.username+'-'+item.loginname"
:value="item.loginname"
v-for="item in userList"
></el-option>
</el-select>
</el-form-item>
@@ -321,7 +333,8 @@ layout("/layouts/platform.html"){
<el-col :span="12">
<el-form-item label="所属福利" prop="welfareId">
<el-select clearable style="width: 100%" v-model="formData.welfareId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in projectOptions"></el-option>
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in projectOptions"></el-option>
</el-select>
</el-form-item>
</el-col>
@@ -340,28 +353,31 @@ layout("/layouts/platform.html"){
<el-col :span="24">
<el-form-item label="线下门店" prop="offlineStores">
<el-table :data="formData.offlineStores" border max-height="500" size="mini" style="width: 100%">
<el-table :data="formData.offlineStores" border max-height="500" size="mini"
style="width: 100%">
<el-table-column label="序号" sortable type="index" width="100"></el-table-column>
<el-table-column label="门店地址">
<template scope="{row,$index}">
<el-form-item label-width="0">
<el-input maxlength="50" placeholder="请输入门店地址" v-model="row.address"></el-input>
<el-input maxlength="50" placeholder="请输入门店地址"
v-model="row.address"></el-input>
</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.offlineStores.push({})" icon="el-icon-plus" size="mini" type="primary">
<el-button @click="formData.offlineStores.push({})" icon="el-icon-plus"
size="mini" type="primary">
添加
</el-button>
</template>
<template slot-scope="scope">
<el-button
:disabled="formData.offlineStores.length==1"
@click="formData.offlineStores.splice(scope.$index,1)"
icon="el-icon-delete"
size="mini"
type="danger"
:disabled="formData.offlineStores.length==1"
@click="formData.offlineStores.splice(scope.$index,1)"
icon="el-icon-delete"
size="mini"
type="danger"
></el-button>
</template>
</el-table-column>
@@ -381,7 +397,8 @@ layout("/layouts/platform.html"){
<el-col :span="24">
<el-form-item label="二维码" prop="qrCode">
<file-upload :files.sync="formData.qrCode" :max="1" :type="['jpg', 'jpeg', 'png','webp']" card>
<file-upload :files.sync="formData.qrCode" :max="1" :type="['jpg', 'jpeg', 'png','webp']"
card>
<template #el-upload__tip>
<span style="color: red">只能上传jpg,jpeg,png,webp格式的一张图片</span>
</template>
@@ -398,12 +415,14 @@ layout("/layouts/platform.html"){
</guava>
<el-drawer :before-close="handleClose" :visible.sync="packageDrawer" direction="rtl" size="60%" title="录入套餐">
<el-form :model="formData" :rules="rules" label-position="right" label-suffix=":" label-width="170px" ref="addForm">
<el-form :model="formData" :rules="rules" label-position="right" label-suffix=":" label-width="170px"
ref="addForm">
<el-row :gutter="60">
<el-col :span="12">
<el-form-item class="is-required" label="选择需要录入的福利" prop="projectId">
<el-select @change="projectChange" clearable disabled style="width: 100%" v-model="projectId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in projectOptions"></el-option>
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in projectOptions"></el-option>
</el-select>
</el-form-item>
</el-col>
@@ -418,7 +437,7 @@ layout("/layouts/platform.html"){
<el-table-column label="套餐名称" property="optionName">
<template slot-scope="{row}">
<div
style="
style="
border: 1px dashed rgb(217, 217, 217);
border-radius: 6px;
display: flex;
@@ -426,7 +445,8 @@ layout("/layouts/platform.html"){
padding-left: 10px;
"
>
<el-input autosize class="text-input" data-type="option" v-model="row.optionName"></el-input>
<el-input autosize class="text-input" data-type="option"
v-model="row.optionName"></el-input>
</div>
</template>
</el-table-column>
@@ -434,7 +454,7 @@ layout("/layouts/platform.html"){
<el-table-column label="排序" property="optionSort">
<template slot-scope="{row}">
<div
style="
style="
border: 1px dashed rgb(217, 217, 217);
border-radius: 6px;
display: flex;
@@ -442,22 +462,29 @@ layout("/layouts/platform.html"){
padding-left: 10px;
"
>
<el-input autosize class="text-input" data-type="option" v-model="row.optionSort"></el-input>
<el-input autosize class="text-input" data-type="option"
v-model="row.optionSort"></el-input>
</div>
</template>
</el-table-column>
<el-table-column label="备注1">
<template slot-scope="{row}">
<el-input v-model="row.supplier" type="textarea" max="100"></el-input>
</template>
</el-table-column>
<el-table-column label="图片" property="imgUrl">
<template slot-scope="{row,$index}">
<div @click="uploadClick($index)">
<el-upload
:action="FILE_UPLOAD_ADDRESS"
:on-success="onFileSuccess"
:show-file-list="false"
class="avatar-uploader"
:action="FILE_UPLOAD_ADDRESS"
:on-success="onFileSuccess"
:show-file-list="false"
class="avatar-uploader"
>
<div style="position: relative" v-if="row.imgUrl">
<img :src="FILE_STREAM_PREVIEW_ADDRESS+'?id='+row.imgUrl" class="avatar" />
<img :src="FILE_STREAM_PREVIEW_ADDRESS+'?id='+row.imgUrl"
class="avatar"/>
<div @click.stop="closePopover(row)">
<i class="el-icon-delete avatar-delete"></i>
</div>
@@ -470,7 +497,8 @@ layout("/layouts/platform.html"){
<el-table-column label="说明" property="description" width="120">
<template slot-scope="{row,$index}">
<el-link @click="openDescRichText(row.description,$index)" type="primary">编辑说明</el-link>
<el-link @click="openDescRichText(row.description,$index)" type="primary">编辑说明
</el-link>
</template>
</el-table-column>
@@ -478,11 +506,11 @@ layout("/layouts/platform.html"){
<template slot-scope="{row,$index}">
<div class="option-delete">
<el-button
@click="projectTableData.splice($index, 1)"
circle
icon="el-icon-delete"
size="mini"
type="danger"
@click="projectTableData.splice($index, 1)"
circle
icon="el-icon-delete"
size="mini"
type="danger"
></el-button>
</div>
</template>
@@ -490,8 +518,11 @@ layout("/layouts/platform.html"){
</el-table>
</div>
<el-button @click="doSubmitWelfare" style="float: right; margin-top: 10px; margin-right: 10px" type="success">提交</el-button>
<el-button @click="packageDrawer=false" plain style="float: right; margin-top: 10px; margin-right: 10px" type="primary">
<el-button @click="doSubmitWelfare" style="float: right; margin-top: 10px; margin-right: 10px"
type="success">提交
</el-button>
<el-button @click="packageDrawer=false" plain
style="float: right; margin-top: 10px; margin-right: 10px" type="primary">
取消
</el-button>
</el-col>
@@ -499,32 +530,13 @@ layout("/layouts/platform.html"){
</el-form>
</el-drawer>
<el-dialog :append-to-body="true" :close-on-click-modal="false" :fullscreen="true" :visible.sync="richTextDialog" title="编辑说明" width="80%">
<el-dialog :append-to-body="true" :close-on-click-modal="false" :visible.sync="richTextDialog"
title="编辑说明" width="60%">
<el-row :gutter="60">
<el-col :span="12">
<div id="descRichText"></div>
</el-col>
<el-col :span="12">
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-between; align-items: center">
<h3 style="color: #1867b0">上传文件</h3>
<file-upload :files.sync="files" :max="10" :source="1" ref="fileUpload"></file-upload>
</div>
</template>
<el-table :data="files" border class="mt10" height="260" stripe style="width: 100%">
<el-table-column label="文件名" prop="filename"></el-table-column>
<el-table-column label="文件路径" prop="url">
<template scope="{row}">{{APP_DOMAIN + FILE_STREAM_PREVIEW_ADDRESS + "?id=" + row.id}}</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" width="100px">
<template slot-scope="{row,$index}">
<el-button @click="doCopy(row)" icon="el-icon-folder-checked" size="mini" type="primary">复制</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-col :span="24">
<text-editor v-model="descRichTextContent"></text-editor>
</el-col>
</el-row>
<span class="dialog-footer" slot="footer">
@@ -571,20 +583,20 @@ layout("/layouts/platform.html"){
offlineStores: []
},
tableColumns: [
{ prop: "year", label: "年度", sortable: true },
{ prop: "shoppingName", label: "供应商名称", sortable: true },
{ prop: "userName", label: "联系人", sortable: true },
{ prop: "mobile", label: "联系方式" },
{ prop: "typeName", label: "类型", sortable: true },
{prop: "year", label: "年度", sortable: true},
{prop: "shoppingName", label: "供应商名称", sortable: true},
{prop: "userName", label: "联系人", sortable: true},
{prop: "mobile", label: "联系方式"},
{prop: "typeName", label: "类型", sortable: true},
// {prop: 'welfareName', label: '所属福利', sortable: true},
// {prop: 'qrCode', label: '二维码',},
{ prop: "link", label: "网址" }
{prop: "link", label: "网址"}
// {prop: 'isEnable', label: '启用状态', sortable: true},
],
rules: {
year: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
shoppingName: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
typeName: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
year: [{required: true, message: "必填", trigger: ["change", "blur"]}],
shoppingName: [{required: true, message: "必填", trigger: ["change", "blur"]}],
typeName: [{required: true, message: "必填", trigger: ["change", "blur"]}]
// loginName: [{required: true, message: '必填', trigger: ['change', 'blur']}],
// mobile: [{required: true, message: '必填', trigger: ['change', 'blur']}],
},
@@ -599,7 +611,8 @@ layout("/layouts/platform.html"){
pageOrderBy: "",
unionId: ""
},
unionOptions: []
unionOptions: [],
descRichTextContent:"",
}
},
methods: {
@@ -609,7 +622,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
const resp = await $.post(loc() + "/doDeleteUser", { id: id })
const resp = await $.post(loc() + "/doDeleteUser", {id: id})
if (resp.code === 0) {
this.doSearch()
this.notifySuccess(resp.msg)
@@ -656,24 +669,13 @@ layout("/layouts/platform.html"){
}
},
getRichText() {
this.$set(this.projectTableData[this.welfareIndex], "description", questionRichTextEditor.txt.html())
this.$set(this.projectTableData[this.welfareIndex], "description", this.descRichTextContent)
this.richTextDialog = false
},
openDescRichText(richText, index) {
this.welfareIndex = index
this.richTextDialog = true
this.$nextTick(() => {
$("#descRichText").html("")
questionRichTextEditor = new wangEditor("#descRichText")
questionRichTextEditor.config.onchange = (html) => {
richText = html ? html : ""
}
questionRichTextEditor.config.uploadImgShowBase64 = true
questionRichTextEditor.create()
if (richText) {
questionRichTextEditor.txt.html(richText)
}
})
this.descRichTextContent=richText
},
closePopover(o) {
const popovers = document.getElementsByClassName("el-popover")
@@ -683,7 +685,7 @@ layout("/layouts/platform.html"){
o.imgUrl = null
},
onFileSuccess(response, file, fileList) {
const { data } = response
const {data} = response
this.$set(this.projectTableData[this.idx], "imgUrl", data.filepath)
this.$forceUpdate()
},
@@ -691,7 +693,7 @@ layout("/layouts/platform.html"){
this.idx = idx
},
openPackage(row) {
if (!row.isEnable) {
if (row.isDisabled) {
this.notifyWarning("福利已开启,如需修改套餐请联系管理员")
return
}
@@ -708,7 +710,8 @@ layout("/layouts/platform.html"){
.then((_) => {
done()
})
.catch((_) => {})
.catch((_) => {
})
},
userChang(val) {
if (!val) {
@@ -767,12 +770,12 @@ layout("/layouts/platform.html"){
let schoolWelfareId = this.viewData.schoolWelfareId ? this.viewData.schoolWelfareId : ""
window.open(
loc() +
"/doChooseExport?id=" +
this.viewData.id +
"&schoolWelfareId=" +
schoolWelfareId +
"&unionId=" +
this.choosePageForm.unionId
"/doChooseExport?id=" +
this.viewData.id +
"&schoolWelfareId=" +
schoolWelfareId +
"&unionId=" +
this.choosePageForm.unionId
)
},
doDelete(id) {
@@ -781,7 +784,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
const resp = await $.post(loc() + "/doDelete", { id: id })
const resp = await $.post(loc() + "/doDelete", {id: id})
if (resp.code === 0) {
this.doSearch()
this.notifySuccess(resp.msg)
@@ -794,7 +797,7 @@ layout("/layouts/platform.html"){
window.open(url)
},
async isEnableChange(val, id) {
const resp = await $.post(loc() + "/isEnableChange", { isEnable: val, id: id })
const resp = await $.post(loc() + "/isEnableChange", {isEnable: val, id: id})
if (resp.code === 0) {
this.notifySuccess(resp.msg)
} else {
@@ -830,13 +833,13 @@ layout("/layouts/platform.html"){
this.$refs.guava.edit()
},
async getWelfare() {
const resp = await $.get(loc() + "/welfareProjectList", { year: this.pageForm.year })
const resp = await $.get(loc() + "/welfareProjectList", {year: this.pageForm.year})
this.projectOptions = resp.data
},
async submit() {
this.$refs["addForm"].validate(async (valid) => {
if (valid) {
const resp = await $.post(loc() + "/submit", { shoppingType: JSON.stringify(this.formData) })
const resp = await $.post(loc() + "/submit", {shoppingType: JSON.stringify(this.formData)})
if (resp.code === 0) {
this.doSearch()
this.$refs.guava.index()
@@ -875,7 +878,7 @@ layout("/layouts/platform.html"){
},
async getWelfareBySchoolWelfareId() {
if (this.viewData.schoolWelfareId) {
const resp = await $.post(loc() + "/getWelfareBySchoolWelfareId", { schoolWelfareId: this.viewData.schoolWelfareId })
const resp = await $.post(loc() + "/getWelfareBySchoolWelfareId", {schoolWelfareId: this.viewData.schoolWelfareId})
if (resp.code === 0) {
resp.data.map((v) => {
let name = v.choiceTimeEnd < moment().format("YYYY-MM-DD HH:mm:ss") ? "(已选完)" : "(未选完)"
@@ -65,11 +65,11 @@ layout("/layouts/platform.html"){
<div class="search-item-label">年&emsp;&emsp;度:</div>
<div class="search-item-option">
<el-date-picker
placeholder="请选择"
style="width: 100%"
type="year"
v-model="pageForm.year"
value-format="yyyy"
placeholder="请选择"
style="width: 100%"
type="year"
v-model="pageForm.year"
value-format="yyyy"
></el-date-picker>
</div>
</div>
@@ -78,11 +78,11 @@ layout("/layouts/platform.html"){
<div class="search-item-label">项目名称:</div>
<div class="search-item-option">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入内容"
style="width: 100%"
v-model="pageForm.name"
@keyup.enter.native="doSearch"
clearable
placeholder="请输入内容"
style="width: 100%"
v-model="pageForm.name"
></el-input>
</div>
</div>
@@ -95,19 +95,21 @@ layout("/layouts/platform.html"){
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="福利项目">
<template #func>
<el-button @click="openAdd" icon="el-icon-plus" size="small" type="primary" v-if="judgmentAuthority">新建福利项目</el-button>
<el-button @click="openAdd" icon="el-icon-plus" size="small" type="primary"
v-if="judgmentAuthority">新建福利项目
</el-button>
</template>
</table-tool>
<el-table
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
class="vi-table"
ref="table"
row-key="id"
style="width: 100%"
v-loading="tableLoading"
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
class="vi-table"
ref="table"
row-key="id"
style="width: 100%"
v-loading="tableLoading"
>
<el-table-column type="expand">
<template scope="{row}">
@@ -131,7 +133,9 @@ layout("/layouts/platform.html"){
</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-form-item label="签收形式">
{{welfareSignMode.find(v=>v.code==row.signMode).description}}
</el-form-item>
</el-col>
</el-row>
</el-form>
@@ -139,24 +143,24 @@ layout("/layouts/platform.html"){
</el-table-column>
<el-table-column
:index="indexMethod"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
: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"
: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=='provideTimeStart'">
<i class="el-icon-time"></i>
@@ -185,17 +189,25 @@ layout("/layouts/platform.html"){
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'openCode',data:row}">二维码</el-dropdown-item>
<el-dropdown-item :command="{type:'status',data:row}">{{row.isDisabled?'发布':'关闭'}}</el-dropdown-item>
<el-dropdown-item :command="{type:'sendMsg',data:row}">通知未选择人员</el-dropdown-item>
<el-dropdown-item :command="{type:'createList2',data:row}" v-if="row.created">更新福利名单</el-dropdown-item>
<el-dropdown-item :command="{type:'status',data:row}">
{{row.isDisabled?'发布':'关闭'}}
</el-dropdown-item>
<el-dropdown-item :command="{type:'sendMsg',data:row}">通知未选择人员
</el-dropdown-item>
<el-dropdown-item :command="{type:'createList2',data:row}" v-if="row.created">
更新福利名单
</el-dropdown-item>
<el-dropdown-item :command="{type:'createList',data:row}" v-if="judgmentAuthority">
{{row.created?'重置福利名单':'生成福利名单'}}
</el-dropdown-item>
<el-dropdown-item :command="{type:'edit',data:row}" v-if="judgmentAuthority">编辑</el-dropdown-item>
<el-dropdown-item :command="{type:'edit',data:row}" v-if="judgmentAuthority">编辑
</el-dropdown-item>
<el-dropdown-item :command="{type:'delete',data:row}" v-if="judgmentAuthority">删除</el-dropdown-item>
<el-dropdown-item :command="{type:'delete',data:row}" v-if="judgmentAuthority">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
@@ -216,7 +228,8 @@ layout("/layouts/platform.html"){
<el-row>
<el-col span="12">
<el-form-item label="发放节日" prop="festival">
<el-select filterable placeholder="发放节日" style="width: 100%" v-model="formData.festival">
<el-select filterable placeholder="发放节日" style="width: 100%"
v-model="formData.festival">
<el-option :key="f" :label="f" :value="f" v-for="f in festival"></el-option>
</el-select>
</el-form-item>
@@ -224,14 +237,14 @@ layout("/layouts/platform.html"){
<el-col span="12">
<el-form-item label="选择时间" prop="choiceTime">
<el-date-picker
@change="choiceTimeChange"
end-placeholder="结束时间"
range-separator="-"
start-placeholder="开始时间"
style="width: 100%"
type="datetimerange"
v-model="formData.choiceTime"
value-format="yyyy-MM-dd HH:mm:ss"
@change="choiceTimeChange"
end-placeholder="结束时间"
range-separator="-"
start-placeholder="开始时间"
style="width: 100%"
type="datetimerange"
v-model="formData.choiceTime"
value-format="yyyy-MM-dd HH:mm:ss"
></el-date-picker>
</el-form-item>
</el-col>
@@ -254,12 +267,12 @@ layout("/layouts/platform.html"){
<el-col span="12">
<el-form-item label="逾期选择时间" prop="overdueChoiceTimeEnd">
<el-date-picker
@change="choiceTimeChange"
placeholder="逾期未选择最后选择截至时间"
style="width: 100%"
type="datetime"
v-model="formData.overdueChoiceTimeEnd"
value-format="yyyy-MM-dd HH:mm:ss"
@change="choiceTimeChange"
placeholder="逾期未选择最后选择截至时间"
style="width: 100%"
type="datetime"
v-model="formData.overdueChoiceTimeEnd"
value-format="yyyy-MM-dd HH:mm:ss"
></el-date-picker>
</el-form-item>
</el-col>
@@ -279,63 +292,75 @@ layout("/layouts/platform.html"){
</el-row>
<el-row>
<el-col span="4">
<el-col span="8">
<el-form-item label="是否福利套餐" prop="flexible">
<el-switch @change="isCheckBoxChange" v-model="formData.flexible"></el-switch>
<el-radio-group v-model="formData.flexible" @change="isCheckBoxChange">
<el-radio :label="false" border>非套餐</el-radio>
<el-radio :label="true" border>套餐</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col span="4">
<el-form-item label="是否补发生日蛋糕券" prop="isYearBirthday">
<el-switch v-model="formData.isYearBirthday"></el-switch>
<el-col span="8">
<el-form-item label="是否积分模式" prop="isIntegralMode">
<el-radio-group v-model="formData.isIntegralMode">
<el-radio :label="false" border>非积分模式</el-radio>
<el-radio :label="true" border>积分模式</el-radio>
</el-radio-group>
</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="4" v-if="formData.isRoutine">
<el-form-item label="是否多选" prop="isCheckBox">
<el-col span="8" v-if="formData.isIntegralMode">
<el-form-item label="总积分" prop="allIntegral">
<el-input-number v-model="formData.allIntegral" style="width: 100%" min="0"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col span="6">
<el-form-item label="是否全年生日蛋糕券" prop="isYearBirthday">
<el-switch v-model="formData.isYearBirthday">
</el-switch>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="是否多选" prop="isCheckBox" v-if="formData.isRoutine">
<el-switch
@change="isCheckBoxChange"
active-value="checkBox"
inactive-value="radio"
v-model="formData.isCheckBox"
></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>
<template v-if="formData.isCheckBox=='checkBox'">
<el-col span="4">
<el-form-item label="是否支持单个多选" prop="singleOptionSupportMultipleSelection">
<el-switch v-model="formData.singleOptionSupportMultipleSelection"></el-switch>
</el-form-item>
</el-col>
<el-col span="4">
<el-form-item label="最多选几个" prop="multiSelectNum">
<el-input-number :max="10" :min="2" placeholder="最多选几个" v-model="formData.multiSelectNum"></el-input-number>
</el-form-item>
</el-col>
</template>
</el-row>
<el-form-item label="人员核对名单" prop="taskId" v-if="formData.isYearBirthday">
<el-select filterable placeholder="请选择人员核对名单" style="width: 100%" v-model="formData.taskId">
<el-option :label="item.taskName" :value="item.id" v-for="item in memberCheckTaskOptions"></el-option>
<el-select filterable placeholder="请选择人员核对名单" style="width: 100%"
v-model="formData.taskId">
<el-option :label="item.taskName" :value="item.id"
v-for="item in memberCheckTaskOptions"></el-option>
</el-select>
</el-form-item>
<el-form-item label="发放形式" prop="provideMode">
<el-radio-group size="medium" v-model="formData.provideMode">
<el-radio-button :key="item.code" :label="item.code" v-for="item in welfareProvideMode">{{item.description}}</el-radio-button>
<el-radio-button :key="item.code" :label="item.code" v-for="item in welfareProvideMode">
{{item.description}}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="签收形式" prop="signMode">
<el-radio-group size="medium" v-model="formData.signMode">
<el-radio-button :key="item.code" :label="item.code" v-for="item in welfareSignMode">{{item.description}}</el-radio-button>
<el-radio-button :key="item.code" :label="item.code" v-for="item in welfareSignMode">
{{item.description}}
</el-radio-button>
</el-radio-group>
</el-form-item>
@@ -347,12 +372,15 @@ layout("/layouts/platform.html"){
<!-- </el-form-item>-->
<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-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>
<question-naire :subject="formData.welfareProjectSubjects"
:is_integral_mode="formData.isIntegralMode"
ref="questionNaire"></question-naire>
</el-form-item>
</template>
@@ -371,14 +399,14 @@ layout("/layouts/platform.html"){
<el-form-item label="封面图片" prop="cover">
<image-Upload
:file-size="0.2"
:file-type="['png','jpg']"
:height="100"
:limit="1"
:size="[500,200]"
:width="100"
ref="imageUpload"
v-model="formData.cover"
:file-size="0.2"
:file-type="['png','jpg']"
:height="100"
:limit="1"
:size="[500,200]"
:width="100"
ref="imageUpload"
v-model="formData.cover"
></image-Upload>
</el-form-item>
</el-form>
@@ -407,7 +435,8 @@ layout("/layouts/platform.html"){
</el-row>
</el-dialog>
<el-dialog :close-on-click-modal="false" :visible.sync="sendMsgDialogVisible" title="请在下方填写需要发送的内容" width="50%">
<el-dialog :close-on-click-modal="false" :visible.sync="sendMsgDialogVisible" title="请在下方填写需要发送的内容"
width="50%">
<el-form :model="formData" label-width="80px" ref="sendForm">
<!-- <el-form-item
:rules="[{required: true, message: '请选择发送方式', trigger: ['blur', 'change']}]"
@@ -419,7 +448,8 @@ layout("/layouts/platform.html"){
</el-checkbox-group>
</el-form-item>
-->
<el-form-item :rules="[{required: true, message: '请选择发送内容', trigger: ['blur', 'change']}]" label="发送内容" prop="content">
<el-form-item :rules="[{required: true, message: '请选择发送内容', trigger: ['blur', 'change']}]"
label="发送内容" prop="content">
<el-input :rows="6" placeholder="请输入内容" type="textarea" v-model="formData.content"></el-input>
</el-form-item>
@@ -451,13 +481,13 @@ layout("/layouts/platform.html"){
value: "sex",
type: "select",
options: [
{ label: "男", value: "男" },
{ label: "女", value: "女" }
{label: "男", value: "男"},
{label: "女", value: "女"}
]
},
{ label: "出生日期", value: "birthday", type: "date" },
{ label: "是否会员", value: "member" },
{ label: "是否福利会员", value: "welfareMember" }
{label: "出生日期", value: "birthday", type: "date"},
{label: "是否会员", value: "member"},
{label: "是否福利会员", value: "welfareMember"}
],
welfareProvideMode: [],
@@ -467,23 +497,23 @@ layout("/layouts/platform.html"){
year: moment().format("YYYY")
},
tableColumns: [
{ prop: "year", label: "年度" },
{ prop: "name", label: "项目名称" },
{ prop: "gift", label: "福利礼品" },
{ prop: "provideTimeStart", label: "发放时间" }
{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"] }],
taskId: [{ required: true, message: "必填", trigger: ["blur", "change"] }]
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"]}],
taskId: [{required: true, message: "必填", trigger: ["blur", "change"]}]
},
welfare,
welfareUnitMode,
@@ -506,10 +536,10 @@ layout("/layouts/platform.html"){
},
methods: {
async getMemberCheckTaskOptions() {
const resp = await $.get("/platform/welfareMember/check/task/getAllTask", { year: this.pageForm.year })
const resp = await $.get("/platform/welfareMember/check/task/getAllTask", {year: this.pageForm.year})
this.memberCheckTaskOptions = resp.data.filter((item) => item.welfareCheckFilterMode === 2)
},
async projectStatusChange({ id, isDisabled: val }) {
async projectStatusChange({id, isDisabled: val}) {
const resp = await $.post(loc() + "/projectStatusChange", {
id,
val
@@ -767,7 +797,7 @@ layout("/layouts/platform.html"){
if ("confirm" == a) {
//确认后再执行
this.submitLoading = true
const resp = await $.post(loc() + "/delete", { id })
const resp = await $.post(loc() + "/delete", {id})
if (resp.code === 0) {
this.pageData()
this.notifySuccess(resp.msg)
@@ -780,7 +810,7 @@ layout("/layouts/platform.html"){
})
},
dropdownCommand(command) {
const { type, data } = command
const {type, data} = command
this.welfare_id = data.id
if (type == "view") {
this.openView(data.id)
@@ -804,7 +834,7 @@ layout("/layouts/platform.html"){
},
async openEdit(row) {
this.submitLoading = true
const resp = await $.get(loc() + "/findOne", { id: row.id })
const resp = await $.get(loc() + "/findOne", {id: row.id})
this.submitLoading = false
if (resp.code === 0) {
const data = resp.data
@@ -892,7 +922,7 @@ layout("/layouts/platform.html"){
value: "personType",
type: "select",
options: personType.map((v) => {
return { label: v.name, value: v.code }
return {label: v.name, value: v.code}
})
},
{
@@ -900,7 +930,7 @@ layout("/layouts/platform.html"){
value: "userState",
type: "select",
options: userState.map((v) => {
return { label: v.name, value: v.code }
return {label: v.name, value: v.code}
})
},
{
@@ -56,12 +56,12 @@ layout("/layouts/platform.html"){
<div class="search-item-label">年&emsp;&emsp;度:</div>
<div class="search-item-option">
<el-date-picker
@change="doSearch"
placeholder="请选择"
style="width: 100%"
type="year"
v-model="pageForm.year"
value-format="yyyy"
@change="doSearch"
placeholder="请选择"
style="width: 100%"
type="year"
v-model="pageForm.year"
value-format="yyyy"
></el-date-picker>
</div>
</div>
@@ -77,34 +77,34 @@ layout("/layouts/platform.html"){
</table-tool>
<el-table
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
ref="table"
row-key="id"
style="width: 100%"
v-loading="tableLoading"
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
ref="table"
row-key="id"
style="width: 100%"
v-loading="tableLoading"
>
<el-table-column
:index="indexMethod"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
:index="indexMethod"
align="center"
header-align="center"
label="序号"
type="index"
width="80px"
></el-table-column>
<el-table-column
:key="column.prop"
: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"
:key="column.prop"
: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=='choiceTime'">
<i class="el-icon-time"></i>
@@ -130,7 +130,9 @@ layout("/layouts/platform.html"){
<el-table-column align="center" header-align="center" label="操作" prop="userOnline" width="150px">
<template scope="{row}">
<el-button type="primary" size="mini" @click="openChoose(row)">{{confirmButtonInfo(row).text}}</el-button>
<el-button type="primary" size="mini" @click="openChoose(row)">
{{confirmButtonInfo(row).text}}
</el-button>
<!-- <el-button @click="openChoose(row)" size="mini" type="primary"-->
<!-- v-if="new Date().getTime()>moment(row.choiceTimeStart).valueOf()-->
@@ -165,7 +167,8 @@ layout("/layouts/platform.html"){
<el-form-item label="福利礼品">{{projectInfo.gift}}</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="选择形式">{{projectInfo.isCheckBox==='checkBox'?'多选':'单选'}}</el-form-item>
<el-form-item label="选择形式">{{projectInfo.isCheckBox==='checkBox'?'多选':'单选'}}
</el-form-item>
</el-col>
<el-col span="8" v-if="projectInfo.isCheckBox==='checkBox'">
<el-form-item label="最多选几个">{{projectInfo.multiSelectNum}}个</el-form-item>
@@ -187,7 +190,14 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="选择时间">{{projectInfo.choiceTimeStart}}至{{projectInfo.choiceTimeEnd}}</el-form-item>
<el-form-item label="选择时间">
{{projectInfo.choiceTimeStart}}至{{projectInfo.choiceTimeEnd}}
</el-form-item>
</el-col>
<el-col span="8" v-if="projectInfo.isIntegralMode">
<el-form-item label="福利总积分">
{{projectInfo.allIntegral}}
</el-form-item>
</el-col>
</el-row>
@@ -199,16 +209,17 @@ layout("/layouts/platform.html"){
<div slot="header" style="display: flex; justify-content: space-between">
<div style="color: #000; font-size: 18px">{{option.optionName}}</div>
<div>
<el-button @click.stop="viewDesc(option)" type="text">套餐详情</el-button>
<el-button @click.stop="viewDesc(option)" type="text">套餐详情
</el-button>
</div>
</div>
<div style="display: grid; grid-template-rows: auto 1fr auto; height: 200px">
<div style="display: flex">
<el-image
style="width: 150px; height: 150px"
:src="CREATE_PREVIEW_URL(option.imgUrl)"
fit="contain"
style="width: 150px; height: 150px"
:src="CREATE_PREVIEW_URL(option.imgUrl)"
fit="contain"
></el-image>
<div style="width: calc(100% - 150px); padding-left: 20px; position: relative">
@@ -217,8 +228,8 @@ layout("/layouts/platform.html"){
<el-tooltip placement="top" :content="option.supplier">
<!-- style="width: calc(100% - 80px);text-overflow: ellipsis;overflow: hidden;overflow-y: auto;height: 100px;" -->
<span
class="desc_value"
style="text-overflow: ellipsis; overflow: hidden; overflow-y: auto; height: 100px"
class="desc_value"
style="text-overflow: ellipsis; overflow: hidden; overflow-y: auto; height: 100px"
>
{{ option.supplier }}
</span>
@@ -230,31 +241,36 @@ layout("/layouts/platform.html"){
</div>
<div>
<el-input-number
:disabled="isView"
:max="option.maxNum"
:min="0"
@keydown.native="onKeydown"
@change="numChange(option.selectNum, option, oidx)"
style="width: 150px; position: absolute; right: 0; bottom: 0"
v-model="option.selectNum"
:disabled="isView"
:max="option.maxNum"
:min="0"
@keydown.native="onKeydown"
@change="numChange(option.selectNum, option, oidx)"
style="width: 150px; position: absolute; right: 0; bottom: 0"
v-model="option.selectNum"
></el-input-number>
</div>
<div style="width: 150px; position: absolute; right: 0; top: 160px;color:#ac3111;"
v-if="projectInfo.isIntegralMode">
所需积分:{{option.integral}}
</div>
</div>
</div>
<div style="margin-top: 17px">
<el-select
style="width: 100%"
clearable
filterable
v-if="option.receiveAddressList && option.receiveAddressList.length > 0 && option.selectNum > 0"
placeholder="请选择取货门店"
v-model="option.receiveAddress"
style="width: 100%"
clearable
filterable
v-if="option.receiveAddressList && option.receiveAddressList.length > 0 && option.selectNum > 0"
placeholder="请选择取货门店"
v-model="option.receiveAddress"
>
<el-option
v-for="item in option.receiveAddressList"
:key="item.address"
:label="item.address"
:value="item.address"
v-for="item in option.receiveAddressList"
:key="item.address"
:label="item.address"
:value="item.address"
></el-option>
</el-select>
</div>
@@ -269,12 +285,12 @@ layout("/layouts/platform.html"){
<el-col span="24">
<el-form-item label="联系方式" prop="mobile">
<el-input
v-model="formData.mobile"
placeholder="请输入联系方式"
:disabled="isView"
maxlength="11"
type="text"
show-word-limit
v-model="formData.mobile"
placeholder="请输入联系方式"
:disabled="isView"
maxlength="11"
type="text"
show-word-limit
></el-input>
</el-form-item>
</el-col>
@@ -287,17 +303,17 @@ layout("/layouts/platform.html"){
<div style="display: flex; column-gap: 10px">
<div style="flex: 1">
<el-select
@change="addressChange"
filterable
placeholder="请选择收货地址"
style="width: 100%"
v-model="formData.addressId"
@change="addressChange"
filterable
placeholder="请选择收货地址"
style="width: 100%"
v-model="formData.addressId"
>
<el-option
:key="item.id"
:label="item.name+' '+item.defaultName"
:value="item.id"
v-for="item in addressOptions"
:key="item.id"
:label="item.name+' '+item.defaultName"
:value="item.id"
v-for="item in addressOptions"
></el-option>
</el-select>
</div>
@@ -313,17 +329,17 @@ layout("/layouts/platform.html"){
</el-col>
<el-col span="24">
<el-form-item
:rules="{required:true,message: '请确认收货地址', trigger: 'blur'}"
label="请确认收货地址"
prop="receiveAddress"
:rules="{required:true,message: '请确认收货地址', trigger: 'blur'}"
label="请确认收货地址"
prop="receiveAddress"
>
<el-input
:rows="4"
disabled
maxlength="100"
placeholder="选择收货地址联动"
type="textarea"
v-model="formData.receiveAddress"
:rows="4"
disabled
maxlength="100"
placeholder="选择收货地址联动"
type="textarea"
v-model="formData.receiveAddress"
></el-input>
</el-form-item>
</el-col>
@@ -331,20 +347,20 @@ layout("/layouts/platform.html"){
</template>
<el-form-item
:rules="{required:true,message: '请签字', trigger: 'blur'}"
label="签字"
prop="sign"
v-if="projectInfo.signMode===2"
:rules="{required:true,message: '请签字', trigger: 'blur'}"
label="签字"
prop="sign"
v-if="projectInfo.signMode===2"
>
<template v-if="isChoice===0||!isView">
<sign :is_value_base64="false" :qz.sync="formData.sign" prefix="welfare" ref="sign"></sign>
</template>
<template v-else>
<el-image
:src="'/signature/getSignData?path=' +formData.imageUrl"
fit="contain"
style="height: 100px; width: 100%"
v-if="formData.imageUrl"
:src="'/signature/getSignData?path=' +formData.imageUrl"
fit="contain"
style="height: 100px; width: 100%"
v-if="formData.imageUrl"
></el-image>
<span v-else>暂无</span>
</template>
@@ -353,6 +369,8 @@ layout("/layouts/platform.html"){
</el-card>
<el-row class="mt20" justify="end" type="flex">
<span style="display:flex;align-items: center;margin-right: 10px;color: #ac3111"
v-if="projectInfo.isIntegralMode">总消耗积分:{{totalIntegral}}</span>
<el-button @click="$refs.guava.index()">关闭</el-button>
<el-button @click="doChoose" type="primary" v-if="!isView">确定</el-button>
</el-row>
@@ -366,30 +384,31 @@ layout("/layouts/platform.html"){
</el-drawer>
<el-dialog :close-on-click-modal="false" :visible.sync="addressDialogVisible" title="收货地址" width="40%">
<el-form :model="formData" label-position="right" :rules="formRules" label-suffix=":" label-width="120px" ref="addForm">
<el-form :model="formData" label-position="right" :rules="formRules" label-suffix=":" label-width="120px"
ref="addForm">
<el-row :gutter="60">
<el-col :span="24">
<el-form-item label="地址信息" prop="addressList">
<el-cascader
:options="dzOptions"
:props="{ expandTrigger: 'hover' }"
@change="handleChange"
clearable
placeholder="请选择地址信息"
style="width: 100%"
v-model="formData.addressList"
:options="dzOptions"
:props="{ expandTrigger: 'hover' }"
@change="handleChange"
clearable
placeholder="请选择地址信息"
style="width: 100%"
v-model="formData.addressList"
></el-cascader>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="详细地址" prop="addressDetail">
<el-input
maxlength="100"
placeholder="请输入详细地址信息,如道路、门牌号、小区、楼栋号、单元等信息"
rows="3"
show-word-limit
type="textarea"
v-model="formData.addressDetail"
maxlength="100"
placeholder="请输入详细地址信息,如道路、门牌号、小区、楼栋号、单元等信息"
rows="3"
show-word-limit
type="textarea"
v-model="formData.addressDetail"
></el-input>
</el-form-item>
</el-col>
@@ -400,20 +419,21 @@ layout("/layouts/platform.html"){
</el-col>
<el-col :span="24">
<el-form-item label="手机号码" prop="tel">
<el-input maxlength="11" placeholder="请填写手机号码" clearable v-model="formData.tel"></el-input>
<el-input maxlength="11" placeholder="请填写手机号码" clearable
v-model="formData.tel"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="是否默认" prop="isDefault">
<el-switch
v-model="formData.isDefault"
active-color="#13ce66"
inactive-color="#ff4949"
active-value="1"
inactive-value="0"
active-text="是"
inactive-text="否"
v-model="formData.isDefault"
active-color="#13ce66"
inactive-color="#ff4949"
active-value="1"
inactive-value="0"
active-text="是"
inactive-text="否"
></el-switch>
</el-form-item>
</el-col>
@@ -449,12 +469,12 @@ layout("/layouts/platform.html"){
year: moment().format("YYYY")
},
tableColumns: [
{ prop: "year", label: "年度" },
{ prop: "name", label: "项目名称" },
{ prop: "choiceTime", label: "选择时间" },
{ prop: "isChoose", label: "是否选择" },
{ prop: "gist_list", label: "所选福利" },
{ prop: "receiveAddress", label: "收货地址" }
{prop: "year", label: "年度"},
{prop: "name", label: "项目名称"},
{prop: "choiceTime", label: "选择时间"},
{prop: "isChoose", label: "是否选择"},
{prop: "gist_list", label: "所选福利"},
{prop: "receiveAddress", label: "收货地址"}
],
isView: false,
isChoice: false,
@@ -462,25 +482,26 @@ layout("/layouts/platform.html"){
addressDialogVisible: false,
formRules: {
addressList: [{ required: true, message: "请选择地址信息", trigger: ["blur", "change"] }],
addressDetail: [{ required: true, message: "请填写您的详细地址", trigger: ["blur", "change"] }],
userName: [{ required: true, message: "请填写收货人姓名", trigger: ["blur", "change"] }],
addressList: [{required: true, message: "请选择地址信息", trigger: ["blur", "change"]}],
addressDetail: [{required: true, message: "请填写您的详细地址", trigger: ["blur", "change"]}],
userName: [{required: true, message: "请填写收货人姓名", trigger: ["blur", "change"]}],
tel: [
{ required: true, message: "必填", trigger: ["blur", "change"] },
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号" }
{required: true, message: "必填", trigger: ["blur", "change"]},
{pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号"}
]
},
addFormRules: {
mobile: [
{ required: true, message: "必填", trigger: ["blur", "change"] },
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号" }
{required: true, message: "必填", trigger: ["blur", "change"]},
{pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号"}
]
},
// 供应商
shoppingType: [],
// 门店地址
offlineStoresOption: []
offlineStoresOption: [],
totalIntegral: 0,
}
},
computed: {
@@ -500,30 +521,30 @@ layout("/layouts/platform.html"){
}
},
confirmButtonInfo(row) {
const { choiceTimeEnd, choiceTimeStart, overdueChoiceTimeEnd, isChoose, selectTime } = row
const {choiceTimeEnd, choiceTimeStart, overdueChoiceTimeEnd, isChoose, selectTime} = row
const now = moment().valueOf()
if (overdueChoiceTimeEnd == null || overdueChoiceTimeEnd === "") {
if (now > moment(choiceTimeStart).valueOf() && now < moment(choiceTimeEnd).valueOf()) {
return { text: isChoose ? "修改" : "选择", disabled: false }
return {text: isChoose ? "修改" : "选择", disabled: false}
} else if (now > moment(choiceTimeEnd).valueOf()) {
return { text: "选择已结束", disabled: true }
return {text: "选择已结束", disabled: true}
} else if (now < moment(choiceTimeStart).valueOf()) {
return { text: "选择未开始", disabled: true }
return {text: "选择未开始", disabled: true}
}
} else {
//已选择了不能再动了
if (isChoose) {
if (moment(selectTime).valueOf() > moment(choiceTimeEnd).valueOf() && now < moment(overdueChoiceTimeEnd).valueOf()) {
return { text: "修改", disabled: false }
return {text: "修改", disabled: false}
}
return { text: "选择已结束", disabled: true }
return {text: "选择已结束", disabled: true}
} else {
if (now > moment(choiceTimeStart).valueOf() && now < moment(overdueChoiceTimeEnd).valueOf()) {
return { text: isChoose ? "修改" : "选择", disabled: false }
return {text: isChoose ? "修改" : "选择", disabled: false}
} else if (now > moment(overdueChoiceTimeEnd).valueOf()) {
return { text: "选择已结束", disabled: true }
return {text: "选择已结束", disabled: true}
} else if (now < moment(choiceTimeStart).valueOf()) {
return { text: "选择未开始", disabled: true }
return {text: "选择未开始", disabled: true}
}
}
}
@@ -583,27 +604,41 @@ layout("/layouts/platform.html"){
})
},
handlePlusButtonClick(value, option, optionIndex) {
const { isCheckBox, multiSelectNum, singleOptionSupportMultipleSelection } = this.projectInfo
if (isCheckBox === "checkBox") {
//判断是否支持单个多选
if (!singleOptionSupportMultipleSelection && value > 1) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", 1)
this.$message.warning("此套餐最多只能选择1份")
return
const {
isIntegralMode,
isCheckBox,
multiSelectNum,
singleOptionSupportMultipleSelection
} = this.projectInfo
//积分模式
if (isIntegralMode) {
let totalIntegral = 0
this.projectInfo.welfareProjectSubjects[0].options.forEach(v => {
totalIntegral = totalIntegral + (v.integral * v.selectNum)
})
this.totalIntegral = totalIntegral
} else {
if (isCheckBox === "checkBox") {
//判断是否支持单个多选
if (!singleOptionSupportMultipleSelection && value > 1) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", 1)
this.$message.warning("此套餐最多只能选择1份")
return
}
}
}
//获取用户当前选择的数量
const selectNums = this.projectInfo.welfareProjectSubjects[0].options.map((v) => v.selectNum)
const sum = selectNums.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
//获取用户当前选择的数量
const selectNums = this.projectInfo.welfareProjectSubjects[0].options.map((v) => v.selectNum)
const sum = selectNums.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
if (sum > multiSelectNum) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", value - 1)
this.$message.warning("此次福利最多只能选择" + multiSelectNum + "份")
if (sum > multiSelectNum) {
this.$set(this.projectInfo.welfareProjectSubjects[0].options[optionIndex], "selectNum", value - 1)
this.$message.warning("此次福利最多只能选择" + multiSelectNum + "份")
}
}
},
async getProjectInfo(id) {
const resp = await $.get("/platform/welfare/common/findOne", { projectId: id })
const resp = await $.get("/platform/welfare/common/findOne", {projectId: id})
if (resp.code === 0) {
resp.data.multiSelectNum = resp.data.multiSelectNum ? resp.data.multiSelectNum : 1
this.projectInfo = resp.data
@@ -634,7 +669,7 @@ layout("/layouts/platform.html"){
doChoose() {
this.$refs["addForm"].validate(async (valid) => {
if (valid) {
const { isCheckBox, multiSelectNum, singleOptionSupportMultipleSelection } = this.projectInfo
const {isCheckBox, multiSelectNum, singleOptionSupportMultipleSelection} = this.projectInfo
if (isCheckBox === "checkBox") {
if (this.sumSelectNum < multiSelectNum) {
//用户没有选择完
@@ -656,13 +691,14 @@ layout("/layouts/platform.html"){
.map((item) => {
return {
optionName: item.optionName,
receiveAddressList: item.receiveAddressList,
selectNum: item.selectNum,
receiveAddress: item.receiveAddress
}
})
let isReceiveAddress = true
for (const item of chooseOptions) {
if (!item.receiveAddress) {
if (!item.receiveAddress && item.receiveAddressList.length > 0) {
this.$message.warning(item.optionName + "还没有选择收货门店哦")
isReceiveAddress = false
break
@@ -697,22 +733,23 @@ layout("/layouts/platform.html"){
selectNum: v.selectNum
}
})
console.log(formData)
const { code, msg, data } = await $.post("/platform/welfare/userChoose/confirmSelect", {
const {code, msg, data} = await $.post("/platform/welfare/userChoose/confirmSelect", {
welfareUserSelections: JSON.stringify(formData),
projectId: this.projectInfo.id,
mobile: this.formData.mobile
mobile: this.formData.mobile,
totalIntegral: this.totalIntegral * 100
})
if (code === 0) {
this.$message.success("您已完成本次福利选择。")
this.doSearch()
this.$refs.guava.index()
} else {
this.$message({
message: msg,
type: "warning"
})
}
this.doSearch()
this.$refs.guava.index()
}
})
},
@@ -748,7 +785,7 @@ layout("/layouts/platform.html"){
},
//获取用户选择的数据
async getUserSelection(projectId) {
const resp = await $.get("/platform/welfare/mine/getUserSelection", { projectId: projectId })
const resp = await $.get("/platform/welfare/mine/getUserSelection", {projectId: projectId})
this.userSelection = resp.data
this.echoUserSelection()
},
@@ -767,7 +804,7 @@ layout("/layouts/platform.html"){
})
},
async getChoice() {
const resp = await $.get("/mobile/welfare/mine/isChoice", { projectId: this.projectInfo.id })
const resp = await $.get("/mobile/welfare/mine/isChoice", {projectId: this.projectInfo.id})
this.isChoice = resp.data
},
async selectUserAddress() {
@@ -788,7 +825,7 @@ layout("/layouts/platform.html"){
},
// 获取供应商
async getShoppingType() {
const { data } = await $.get("/platform/shoppingType/apply/getShoppingType")
const {data} = await $.get("/platform/shoppingType/apply/getShoppingType")
this.projectInfo.welfareProjectSubjects[0].options.forEach((item) => {
item.receiveAddressList = data.find((v) => v.id === item.shoppingId)?.offlineStores
})