first commit

This commit is contained in:
2026-08-26 14:25:17 +08:00
commit 06debfd1fc
10595 changed files with 1836924 additions and 0 deletions
@@ -0,0 +1,562 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style>
.selection:not(:last-child) {
border-bottom: 1px dashed lightgrey;
}
.selection .van-checkbox-group .van-cell,
.selection .van-radio-group .van-cell {
flex-direction: row-reverse;
}
.selection .van-checkbox-group .van-cell .van-cell__title,
.selection .van-radio-group .van-cell .van-cell__title {
padding-left: 20px;
}
.selection .van-radio {
display: flex;
align-items: baseline;
}
.selection .van-cell__label {
max-height: 80px;
margin-left: 20px;
}
.confirmWelfareCell .van-cell__label {
white-space: normal;
}
.selection .van-cell__label .welfare_img {
width: 100px;
height: 80px;
}
.right_content {
width: calc(100% - 150px);
padding-left: 20px;
padding-right: 10px;
position: relative;
height: 100px;
}
.optionDesc {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
font-size: 13px;
color: #868282;
}
.desc img {
width: 100%;
}
.desc td {
border: 1pt solid #000000 !important;
}
.van-cell-group--inset {
margin: 10px 16px !important;
overflow: hidden;
/*border-radius: 8px;*/
}
.submitBar .van-info {
position: absolute;
bottom: 30px;
left: 25px;
top: auto;
right: auto;
}
.address-manage-button {
position: absolute;
bottom: 0;
width: calc(100% - 20px);
left: 0;
right: 0;
margin: 10px;
}
.addressClass .van-action-sheet__content {
padding-bottom: 70px;
}
</style>
<div id="app" v-cloak>
<div>
<van-sticky>
<van-nav-bar
@click-left="()=>this.$pjaxReplace('/platform/h5/welfare/userChoose/list')"
left-arrow
left-text="返回"
placeholder
title="福利详情"
></van-nav-bar>
</van-sticky>
<div v-if="projectInfo">
<van-image :src="projectInfo.cover" fit="cover" style="width: 100%; height: 150px"></van-image>
<!--基本信息-->
<van-cell-group class="van-cell-group--inset">
<van-cell>
<div style="font-weight: bold; font-size: 15px; display: flex; align-items: center">福利信息</div>
</van-cell>
<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" title="选择形式">{{projectInfo.isCheckBox==='checkBox'?'多选':'单选'}}</van-cell>
<van-cell
:border="false"
:value="projectInfo.multiSelectNum"
title="最多选几个"
v-if="projectInfo.isCheckBox==='checkBox'"
></van-cell>
<van-cell :border="false" title="发放形式">
<template>
{{welfareProvideMode.find(v=>v.code==projectInfo.provideMode) &&
welfareProvideMode.find(v=>v.code==projectInfo.provideMode).name}}
</template>
</van-cell>
<van-cell :border="false" title="签收形式">
<template>
{{welfareSignMode.find(v=>v.code==projectInfo.signMode) && welfareSignMode.find(v=>v.code==projectInfo.signMode).name}}
</template>
</van-cell>
<van-cell :border="false" title="选择时间">
<template #label>{{projectInfo.choiceTimeStart + ' 至 ' + projectInfo.choiceTimeEnd}}</template>
</van-cell>
</van-cell-group>
<!--礼品套餐-->
<div
class="van-cell-group--inset"
style="margin: 10px auto"
v-if="projectInfo.flexible && [2,3].includes(projectInfo.provideMode)
&& projectInfo.options
&& projectInfo.options.length>0"
>
<van-cell>
<div style="font-weight: bold; font-size: 15px; display: flex; align-items: center">选择套餐</div>
</van-cell>
<div style="margin-bottom: 30px">
<div>
<van-text-box
:content="option.supplier"
:cover="option.imgUrl"
:key="option.id"
:title="option.optionName"
sub-title=" "
type="5"
v-for="(option, optionIndex) in projectInfo.options"
>
<template #tip>
<span @click="openViewDesc(option.description)">查看详情</span>
</template>
<template>
<van-divider dashed />
<van-row class="padding10X padding-right14" justify="end" type="flex">
<van-stepper
:default-value="0"
:disabled="confirmButtonInfo.disabled"
:min="0"
@change="(value)=>{numChange(value,option,optionIndex)}"
async-change
button-size="20"
disable-input
integer
theme="round"
v-model="option.selectNum"
></van-stepper>
</van-row>
</template>
</van-text-box>
</div>
</div>
</div>
<van-submit-bar
:button-text="confirmButtonInfo.text"
@submit="confirmSelect"
class="submitBar"
tip="您可以在福利选择截至时间之前修改福利套餐"
tip-icon="info-o"
>
<van-icon :info="sumSelectNum" name="department" size="30" slot="left"></van-icon>
</van-submit-bar>
</div>
<van-popup :style="{ height: '100%',width: '100%'}" position="right" safe-area-inset-bottom v-model="descPopup">
<van-sticky>
<van-nav-bar @click-left="descPopup=false" fixed left-arrow left-text="返回" placeholder title="详情"></van-nav-bar>
</van-sticky>
<div style="margin-top: 45px">
<div @click="descImgClick" class="desc" v-html="desc"></div>
</div>
</van-popup>
<van-action-sheet :close-on-click-overlay="false" title="确认福利套餐" v-model="confirmPopup">
<div>
<!--选择的信息-->
<van-cell>
<van-icon class="van-cell__left-icon" color="red" name="info" slot="icon"></van-icon>
<div slot="title" style="font-weight: bold; font-size: 15px">已选福利</div>
</van-cell>
<van-cell style="padding: 0">
<van-card
:key="item.id"
:num="item.selectNum"
:thumb="item.imgUrl"
:title="item.optionName"
center
desc=""
style="border-radius: 8px; background: #ffffff"
v-for="item in selectedOptions"
></van-card>
</van-cell>
<!--邮寄到家 填写收货地址-->
<van-cell @click="selectAddressPopup = true" class="confirmWelfareCell" is-link v-if="projectInfo.provideMode===3">
<van-icon class="van-cell__left-icon" color="red" name="info" slot="icon"></van-icon>
<div slot="title" style="font-weight: bold; font-size: 15px">收货地址</div>
<template #label>
<span v-if="isEmptyObject(selectAddress)">请选择地址</span>
<span v-else>{{selectAddress}}</span>
</template>
</van-cell>
<!--电子签字-->
<van-cell v-if="projectInfo.signMode===2">
<van-icon class="van-cell__left-icon" color="red" name="info" slot="icon"></van-icon>
<div slot="title" style="font-weight: bold; font-size: 15px">电子签名</div>
<template #label>
<h5-signature v-model="userSign"></h5-signature>
</template>
</van-cell>
<div style="padding: 10px 16px; left: 0; right: 0; bottom: 0; background: #ffffff">
<van-button @click="submitSelect" round style="width: 100%" type="primary">提交</van-button>
</div>
</div>
</van-action-sheet>
<van-action-sheet :close-on-click-overlay="false" title="确认地址" v-model="selectAddressPopup" class="addressClass">
<div style="position: relative; height: 500px; overflow-y: auto">
<template v-if="addressList && addressList.length>0">
<van-cell
:key="item.id"
@click="addressClick(item);selectAddressPopup=false"
clickable
icon="location-o"
v-for="item in addressList"
>
<template #title>{{item.address}}</template>
</van-cell>
</template>
<van-empty image="/assets/platform/plugins/vant-green/images/nodata/nodata.png" description="暂无数据" v-else></van-empty>
</div>
<van-button @click="openAddressManage" block class="address-manage-button" round type="primary">地址管理</van-button>
</van-action-sheet>
</div>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
store,
data() {
return {
projectInfo: {},
userSelection: [],
welfareProvideMode: [],
welfareSignMode: [],
desc: null,
descPopup: false,
confirmPopup: false,
selectAddressPopup: false,
selectAddress: null,
addressList: [],
userSign: ""
}
},
computed: {
sumSelectNum() {
if (this.projectInfo && this.projectInfo.welfareProjectSubjects) {
return this.projectInfo.welfareProjectSubjects[0].options
.map((v) => v.selectNum)
.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
}
return 0
},
isSelect() {
if (this.userSelection && this.userSelection.length > 0) {
return true
}
return false
},
selectTime() {
if (this.userSelection && this.userSelection.length > 0) {
return this.userSelection[0].selectTime
}
return null
},
confirmButtonInfo() {
if (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 }
} else if (now > moment(choiceTimeEnd).valueOf()) {
return { text: "选择已结束", disabled: true }
} else if (now < moment(choiceTimeStart).valueOf()) {
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: true }
} else {
if (now > moment(choiceTimeStart).valueOf() && now < moment(overdueChoiceTimeEnd).valueOf()) {
return { text: this.isSelect ? "确定修改" : "确定选择", disabled: false }
} else if (now > moment(overdueChoiceTimeEnd).valueOf()) {
return { text: "选择已结束", disabled: true }
} else if (now < moment(choiceTimeStart).valueOf()) {
return { text: "选择未开始", disabled: true }
}
}
}
}
return { text: "", disabled: true }
},
selectedOptions() {
if (this.projectInfo && this.projectInfo.welfareProjectSubjects) {
return this.projectInfo.welfareProjectSubjects[0].options.filter((v) => v.selectNum >= 1)
}
return []
}
},
methods: {
isEmptyObject(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
return false
}
}
return true
},
getWelfareInfo() {
this.$axios.post("/platform/welfare/project/mange/findOne", { id: this.projectId }).then((res) => {
if (res.code === 0) {
this.projectInfo = res.data
} else {
this.$toast.fail(res.msg)
}
})
},
// 获取用户选择的数据
getUserSelection() {
this.$axios.post("/platform/welfare/userChoose/getUserSelection", { projectId: this.projectInfo.id }).then((resp) => {
if (resp.code === 0) {
this.userSelection = resp.data
this.echoUserSelection()
} else {
this.$toast(resp.msg)
}
})
},
//回显用户选择的数据
echoUserSelection() {
//获取用户当前选择的数量
// this.projectInfo.welfareProjectSubjects[0].options.forEach((v) => {
// const option = this.userSelection.find((x) => x.selectOptionId === v.id)
// if (option) {
// v.selectNum = option.selectNum
// } else {
// v.selectNum = 0
// }
// })
},
//查看详情
openViewDesc(desc) {
if (desc == null || desc.length === 0) {
this.$toast("没有更多了")
return
}
this.desc = desc
this.descPopup = true
},
descImgClick(e) {
if (e.target.tagName === "IMG") {
vant.ImagePreview([e.target.src])
}
},
//确定选择
async confirmSelect() {
if (this.confirmButtonInfo.disabled) {
this.$toast("当前时间段无法选择")
return
}
const { isCheckBox, multiSelectNum, singleOptionSupportMultipleSelection } = this.projectInfo
if (isCheckBox === "checkBox") {
if (this.sumSelectNum < multiSelectNum) {
//用户没有选择完
this.$toast("一共可以选择" + multiSelectNum + "份,您目前只选择了" + this.sumSelectNum + "份,快去选择吧!")
return
}
}
this.confirmPopup = true
//回显用户的地址
if (this.projectInfo.provideMode === 3 && this.isSelect && this.userSelection) {
this.selectAddress = this.userSelection[0].receiveAddress
}
//回显用户签名
if (this.projectInfo.signMode === 2 && this.isSelect && this.userSelection) {
this.userSign = this.userSelection[0].userSign
}
await this.selectUserAddress()
if (this.projectInfo.provideMode === 3 && !this.isSelect) {
const address = this.addressList.find((a) => a.isDefault)
if (address) {
const { province, city, county, addressDetail, name, tel } = address
this.selectAddress =
"收货地址:" + province + city + county + addressDetail + "," + "收件人:" + name + "," + "联系方式:" + tel
}
}
},
//数量更改
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 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 + "份")
}
},
//提交选择
async submitSelect() {
if (this.projectInfo.provideMode === 3) {
if (this.selectAddress == null || this.selectAddress === "") {
this.$toast("请填写您的收货地址")
return
}
}
if (this.projectInfo.signMode === 2) {
if (this.userSign == null || this.userSign === "") {
this.$toast("请签名")
return
}
}
const loading = this.$toast.loading({
message: "提交中...",
forbidClick: true,
overlay: true,
duration: 0
})
const formData = this.projectInfo.welfareProjectSubjects[0].options
.filter((v) => v.selectNum >= 1)
.map((v) => {
return {
welfareId: this.projectInfo.id,
subjectId: v.subjectId,
selectOptionId: v.id,
receiveAddress: this.selectAddress,
selectNum: v.selectNum,
userSign: this.userSign
}
})
const { code, msg, data } = await $.post("/platform/welfare/userChoose/confirmSelect", {
welfareUserSelections: JSON.stringify(formData),
projectId: this.projectInfo.id
})
if (code === 0) {
setTimeout(() => {
this.getUserSelection(this.projectId)
this.$toast.success(msg)
loading.close()
this.confirmPopup = false
}, 500)
} else {
this.$toast.fail(msg)
loading.close()
}
},
//地址列表点击
addressClick(item) {
const { province, city, county, addressDetail, name, tel } = item
this.selectAddress = "收货地址:" + province + city + county + addressDetail + "," + "收件人:" + name + "," + "联系方式:" + tel
},
async selectUserAddress() {
const resp = await this.$axios.post("/platform/welfare/addressManage/selectUserAddress", { userId: this.$store.state.user.id })
resp.data.map((r) => {
r.name = r.userName
r.address =
"收货地址:" +
r.province +
r.city +
r.county +
r.addressDetail +
"," +
"收件人:" +
r.name +
"," +
"联系方式:" +
r.tel +
(r.isDefault ? "【默认地址】" : "")
})
this.addressList = resp.data
},
//地址管理
openAddressManage() {
this.$pjaxReplace("/platform/h5/welfare/address/list?projectId=" + this.projectInfo.id)
}
},
async created() {
this.projectId = GetQueryString("id")
if (this.projectId) {
this.getWelfareInfo()
this.getUserSelection()
this.welfareProvideMode = await this.$businessTool.getDictOptions("welfareProvideMode")
this.welfareProvideMode.map((v) => {
v.code = Number(v.code)
})
this.welfareSignMode = await this.$businessTool.getDictOptions("welfareSignMode")
this.welfareSignMode.map((v) => {
v.code = Number(v.code)
})
}
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,140 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style>
.table-card {
position: relative;
background: #fff;
border-radius: 8px;
margin-bottom: 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
/* 左右布局容器 */
.card-content {
display: flex;
padding: 15px;
}
/* 左侧图片容器 */
.card-image {
width: 120px;
height: 120px;
flex-shrink: 0;
margin-right: 15px;
}
/* 右侧信息容器 */
.card-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* 标题样式 */
.card-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 8px;
color: #333;
}
/* 时间信息样式 */
.time-info {
font-size: 14px;
color: #666;
margin-bottom: 5px;
}
.time-label {
color: #999;
margin-right: 5px;
}
</style>
<div id="app" v-cloak>
<van-sticky>
<van-nav-bar @click-left="()=>this.$pjaxReplace('/platform/h5/home')" left-arrow left-text="返回" placeholder title="福利列表"></van-nav-bar>
<van-dropdown-menu>
<year-van-dropdown-item :num="10" v-model="pageForm.year" @change="doSearch"></year-van-dropdown-item>
</van-dropdown-menu>
</van-sticky>
<div>
<van-list :finished="finished" @load="pageData" finished-text="没有更多了" v-if="tableData.length>0" v-model="loading">
<div class="table-list">
<div class="table-card" v-for="row in tableData" :key="row.id" @click="openChoose(row)">
<van-tag mark :type="row.isChoose?'success':''" style="position: absolute; left: 5px; top: 5px; z-index: 1">
{{row.isChoose?'已选择':'未选择'}}
</van-tag>
<div class="card-content">
<div class="card-image">
<van-image :src="row.cover" fit="cover" width="100%" height="100%" radius="4"></van-image>
</div>
<div class="card-info">
<div class="card-title">{{row.name}}</div>
<div class="time-info">
<span class="time-label">开始时间:</span>
{{row.choiceTimeStart}}
</div>
<div class="time-info">
<span class="time-label">结束时间:</span>
{{row.choiceTimeEnd}}
</div>
</div>
</div>
</div>
</div>
</van-list>
<van-empty v-else image="/assets/platform/plugins/vant-green/images/nodata/nodata.png" description="暂无数据"></van-empty>
</div>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
data() {
return {
tableData: [],
finished: false,
loading: false,
pageForm: {
pageNumber: 1,
pageSize: 5,
totalCount: 0,
year: new Date().getFullYear()
}
}
},
methods: {
doSearch() {
this.tableKey = new Date().getTime()
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.tableData = []
this.pageData()
},
pageData() {
this.loading = true
this.$axios.post("/platform/welfare/userChoose/pageData", this.pageForm).then((res) => {
this.tableData = this.tableData.concat(res.data.list)
if (this.tableData.length === res.data.totalCount) {
this.finished = true
} else {
this.pageForm.pageNumber++
}
this.pageForm.totalCount = res.data.totalCount
this.loading = false
})
},
async openChoose(row) {
this.$pjaxReplace("/platform/h5/welfare/userChoose/index?id=" + row.id)
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->