add: 增加新客立减
This commit is contained in:
parent
a62d4af819
commit
573d46b50d
|
|
@ -0,0 +1,21 @@
|
|||
import request from "@/utils/request";
|
||||
import { Market_BaseUrl } from "@/api/config";
|
||||
const baseURL = Market_BaseUrl + "/admin/consumeDiscount";
|
||||
const API = {
|
||||
getConfig(params: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
},
|
||||
editConfig(data: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
},
|
||||
}
|
||||
export default API;
|
||||
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import request from "@/utils/request";
|
||||
import { Market_BaseUrl } from "@/api/config";
|
||||
import { get } from "lodash";
|
||||
const baseURL = Market_BaseUrl + "/admin/coupon";
|
||||
const API = {
|
||||
getList(params: any) {
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -1,13 +1,15 @@
|
|||
<template>
|
||||
<div class="item">
|
||||
<img :src="getIconPath(props.icon)" class="icon" />
|
||||
<div class="info">
|
||||
<div class="name">{{ props.name }}</div>
|
||||
<div class="intro">
|
||||
{{ props.intro }}
|
||||
<div class="flex justify-between box">
|
||||
<div class="item">
|
||||
<img :src="getIconPath(props.icon)" class="icon" />
|
||||
<div class="info">
|
||||
<div class="name">{{ props.name }}</div>
|
||||
<div class="intro">
|
||||
{{ props.intro }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-30">
|
||||
<div>
|
||||
<el-switch v-model="isOpen" v-if="props.showSwitch" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -53,13 +55,15 @@ const getIconPath = (iconName) => {
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.box {
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
background-color: #f8f8f8;
|
||||
transition: all 0.1s ease-in-out;
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
transition: all 0.1s ease-in-out;
|
||||
|
||||
// &:hover {
|
||||
// cursor: pointer;
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="card">
|
||||
<div class="row" v-for="(item, index) in menus" :key="index">
|
||||
<div class="title">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<div class="menus_wrap">
|
||||
<div class="item" v-for="(val, i) in item.list" :key="i" @click="to(val)">
|
||||
<img :src="getIconPath(val.icon)" class="icon" @error="handleImageError(val)" />
|
||||
<div class="info">
|
||||
<div class="name">{{ val.name }}</div>
|
||||
<div class="intro">
|
||||
{{ val.intro }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-container">
|
||||
<div class="card">
|
||||
<div class="row" v-for="(item, index) in menus" :key="index">
|
||||
<div class="title">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<div class="menus_wrap">
|
||||
<div class="item" v-for="(val, i) in item.list" :key="i" @click="to(val)">
|
||||
<img :src="getIconPath(val.icon)" class="icon" @error="handleImageError(val)" />
|
||||
<div class="info">
|
||||
<div class="name">{{ val.name }}</div>
|
||||
<div class="intro">
|
||||
{{ val.intro }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
|
@ -27,228 +27,231 @@ import { ElMessage } from "element-plus";
|
|||
|
||||
const router = useRouter();
|
||||
const to = (item) => {
|
||||
if (!item.pathName) {
|
||||
ElMessage.warning("暂未开放");
|
||||
return;
|
||||
}
|
||||
router.push({
|
||||
name: item.pathName,
|
||||
});
|
||||
if (!item.pathName) {
|
||||
ElMessage.warning("暂未开放");
|
||||
return;
|
||||
}
|
||||
router.push({
|
||||
name: item.pathName,
|
||||
});
|
||||
};
|
||||
const menus = ref([
|
||||
{
|
||||
label: "营销",
|
||||
list: [
|
||||
{
|
||||
name: "霸王餐",
|
||||
icon: "bwc",
|
||||
pathName: "bwc",
|
||||
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||
},
|
||||
{ name: "邀请列表", icon: "yqlb", pathName: "invite", intro: "邀请好友领券" },
|
||||
{
|
||||
name: "积分锁客",
|
||||
icon: "jfsk",
|
||||
pathName: "points",
|
||||
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||
},
|
||||
{ name: "充值活动", icon: "czhd", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||
{ name: "弹窗广告", icon: "tcgg", pathName: "", intro: "设置弹窗广告" },
|
||||
{ name: "超级会员", icon: "cjhy", pathName: "superVip", intro: "用户会员管理设置" },
|
||||
{ name: "新客立减", icon: "xklj", pathName: "", intro: "首单下单减免金额" },
|
||||
{ name: "智慧充值", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||
{ name: "分销", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||
{
|
||||
name: "消费返现",
|
||||
icon: "xffx",
|
||||
pathName: "",
|
||||
intro: "用户下单后返现一定的金额到余额,可促进复购",
|
||||
},
|
||||
{
|
||||
name: "私域引流",
|
||||
icon: "syyl",
|
||||
pathName: "",
|
||||
intro: "可设置用户下单成功后的群二维码",
|
||||
},
|
||||
{ name: "满减活动", icon: "mjhd", pathName: "", intro: "达到指定支付金额享受减价" },
|
||||
{ name: "生日有礼", icon: "sryl", pathName: "", intro: "用户生日管理设置" },
|
||||
{
|
||||
name: "点餐智能推荐",
|
||||
icon: "dczntj",
|
||||
pathName: "",
|
||||
intro: "进入点单页X秒未点自动推荐商品,此推荐设置启用即生效",
|
||||
},
|
||||
{ name: "超值券包", icon: "czqb", pathName: "", intro: "下单加购" },
|
||||
{
|
||||
name: "套餐推广",
|
||||
icon: "tctg",
|
||||
pathName: "",
|
||||
intro: "下单通过用户邀请好友减免金额的方式裂变宣传套餐加购",
|
||||
},
|
||||
{
|
||||
name: "充值兑换码",
|
||||
icon: "czdhm",
|
||||
pathName: "",
|
||||
intro: "兑换码直充余额,可当作礼品赠送",
|
||||
},
|
||||
{ name: "券兑换码", icon: "qdhm", pathName: "", intro: "可添加多券组合兑换" },
|
||||
{ name: "限时折扣", icon: "xszk", pathName: "", intro: "批量设置商品折扣" },
|
||||
{ name: "商品拼团", icon: "sppt", pathName: "", intro: "拼团" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "优惠券",
|
||||
list: [
|
||||
{
|
||||
name: "满减券",
|
||||
icon: "mjq",
|
||||
pathName: "discount_coupon",
|
||||
intro: "用户满足指定金额后,可使用优惠券立减相应金额,如:设置满100-50券,符合要求的订单满100元后,立减50元。",
|
||||
},
|
||||
{
|
||||
name: "商品兑换券",
|
||||
icon: "spdhq",
|
||||
pathName: "product_redemption",
|
||||
intro: "设置可兑换成商品的券",
|
||||
},
|
||||
{
|
||||
name: "折扣券",
|
||||
icon: "zkq",
|
||||
pathName: "rebate_coupon",
|
||||
intro: "下单享折扣但折扣的金额将在券中抵扣。",
|
||||
},
|
||||
{
|
||||
name: "第二件半价券",
|
||||
icon: "dejbjq",
|
||||
pathName: "half_price",
|
||||
intro: "设置第二件半价券",
|
||||
},
|
||||
{
|
||||
name: "消费赠券",
|
||||
icon: "xfzq",
|
||||
pathName: "consume_ticket",
|
||||
intro: "达到指定消费金额赠送优惠券",
|
||||
},
|
||||
{
|
||||
name: "买一送一券",
|
||||
icon: "myzy",
|
||||
pathName: "buy_one",
|
||||
intro: "针对营销活动买一送一设置券品",
|
||||
},
|
||||
{
|
||||
name: "固定价格券",
|
||||
icon: "gdjkq",
|
||||
pathName: "",
|
||||
intro: "设置该券后,允许用户以固定价格兑换指定商品,如:设置一个固定价格9.9的券,商品20元,用户使用券后只需要9.9元兑换该商品。",
|
||||
},
|
||||
{
|
||||
name: "免配送费券",
|
||||
icon: "mfpsq",
|
||||
pathName: "",
|
||||
intro: "可设置一张免除订单配送费的券",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "推送功能",
|
||||
list: [
|
||||
{ name: "推送活动消息", icon: "tshdxx", pathName: "", intro: "给用户推送服务通知" },
|
||||
{ name: "短信推送", icon: "dxts", pathName: "", intro: "给用户推送服务通知" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "扩展功能",
|
||||
list: [
|
||||
{
|
||||
name: "微信公众号",
|
||||
icon: "wxgzh",
|
||||
pathName: "",
|
||||
intro: "授权微信公众号后,让你能够在后台查看和维护公众号的粉丝;同时你的店铺也有出现关注公众号的入口。",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "营销",
|
||||
list: [
|
||||
{
|
||||
name: "霸王餐",
|
||||
icon: "bwc",
|
||||
pathName: "bwc",
|
||||
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||
},
|
||||
{ name: "邀请列表", icon: "yqlb", pathName: "invite", intro: "邀请好友领券" },
|
||||
{
|
||||
name: "积分锁客",
|
||||
icon: "jfsk",
|
||||
pathName: "points",
|
||||
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||
},
|
||||
{ name: "充值活动", icon: "czhd", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||
{ name: "弹窗广告", icon: "tcgg", pathName: "", intro: "设置弹窗广告" },
|
||||
{ name: "超级会员", icon: "cjhy", pathName: "superVip", intro: "用户会员管理设置" },
|
||||
{ name: "新客立减", icon: "xklj", pathName: "newUserDiscount", intro: "首单下单减免金额" },
|
||||
{ name: "智慧充值", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||
{ name: "分销", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||
{
|
||||
name: "消费返现",
|
||||
icon: "xffx",
|
||||
pathName: "",
|
||||
intro: "用户下单后返现一定的金额到余额,可促进复购",
|
||||
},
|
||||
{
|
||||
name: "私域引流",
|
||||
icon: "syyl",
|
||||
pathName: "",
|
||||
intro: "可设置用户下单成功后的群二维码",
|
||||
},
|
||||
{ name: "满减活动", icon: "mjhd", pathName: "", intro: "达到指定支付金额享受减价" },
|
||||
{ name: "生日有礼", icon: "sryl", pathName: "", intro: "用户生日管理设置" },
|
||||
{
|
||||
name: "点餐智能推荐",
|
||||
icon: "dczntj",
|
||||
pathName: "",
|
||||
intro: "进入点单页X秒未点自动推荐商品,此推荐设置启用即生效",
|
||||
},
|
||||
{ name: "超值券包", icon: "czqb", pathName: "", intro: "下单加购" },
|
||||
{
|
||||
name: "套餐推广",
|
||||
icon: "tctg",
|
||||
pathName: "",
|
||||
intro: "下单通过用户邀请好友减免金额的方式裂变宣传套餐加购",
|
||||
},
|
||||
{
|
||||
name: "充值兑换码",
|
||||
icon: "czdhm",
|
||||
pathName: "",
|
||||
intro: "兑换码直充余额,可当作礼品赠送",
|
||||
},
|
||||
{ name: "券兑换码", icon: "qdhm", pathName: "", intro: "可添加多券组合兑换" },
|
||||
{ name: "限时折扣", icon: "xszk", pathName: "", intro: "批量设置商品折扣" },
|
||||
{ name: "商品拼团", icon: "sppt", pathName: "", intro: "拼团" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "优惠券",
|
||||
list: [
|
||||
{
|
||||
name: "满减券",
|
||||
icon: "mjq",
|
||||
pathName: "discount_coupon",
|
||||
intro:
|
||||
"用户满足指定金额后,可使用优惠券立减相应金额,如:设置满100-50券,符合要求的订单满100元后,立减50元。",
|
||||
},
|
||||
{
|
||||
name: "商品兑换券",
|
||||
icon: "spdhq",
|
||||
pathName: "product_redemption",
|
||||
intro: "设置可兑换成商品的券",
|
||||
},
|
||||
{
|
||||
name: "折扣券",
|
||||
icon: "zkq",
|
||||
pathName: "rebate_coupon",
|
||||
intro: "下单享折扣但折扣的金额将在券中抵扣。",
|
||||
},
|
||||
{
|
||||
name: "第二件半价券",
|
||||
icon: "dejbjq",
|
||||
pathName: "half_price",
|
||||
intro: "设置第二件半价券",
|
||||
},
|
||||
{
|
||||
name: "消费赠券",
|
||||
icon: "xfzq",
|
||||
pathName: "consume_ticket",
|
||||
intro: "达到指定消费金额赠送优惠券",
|
||||
},
|
||||
{
|
||||
name: "买一送一券",
|
||||
icon: "myzy",
|
||||
pathName: "buy_one",
|
||||
intro: "针对营销活动买一送一设置券品",
|
||||
},
|
||||
{
|
||||
name: "固定价格券",
|
||||
icon: "gdjkq",
|
||||
pathName: "",
|
||||
intro:
|
||||
"设置该券后,允许用户以固定价格兑换指定商品,如:设置一个固定价格9.9的券,商品20元,用户使用券后只需要9.9元兑换该商品。",
|
||||
},
|
||||
{
|
||||
name: "免配送费券",
|
||||
icon: "mfpsq",
|
||||
pathName: "",
|
||||
intro: "可设置一张免除订单配送费的券",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "推送功能",
|
||||
list: [
|
||||
{ name: "推送活动消息", icon: "tshdxx", pathName: "", intro: "给用户推送服务通知" },
|
||||
{ name: "短信推送", icon: "dxts", pathName: "", intro: "给用户推送服务通知" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "扩展功能",
|
||||
list: [
|
||||
{
|
||||
name: "微信公众号",
|
||||
icon: "wxgzh",
|
||||
pathName: "",
|
||||
intro:
|
||||
"授权微信公众号后,让你能够在后台查看和维护公众号的粉丝;同时你的店铺也有出现关注公众号的入口。",
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
// 动态获取PNG图标路径
|
||||
const getIconPath = (iconName) => {
|
||||
try {
|
||||
// 直接导入对应PNG文件
|
||||
return new URL(`/src/assets/applocation/${iconName}.png`, import.meta.url).href;
|
||||
} catch (error) {
|
||||
console.warn(`图标 ${iconName}.png 不存在`);
|
||||
return defaultIcon; // 图标不存在时使用默认图标
|
||||
}
|
||||
try {
|
||||
// 直接导入对应PNG文件
|
||||
return new URL(`/src/assets/applocation/${iconName}.png`, import.meta.url).href;
|
||||
} catch (error) {
|
||||
console.warn(`图标 ${iconName}.png 不存在`);
|
||||
return defaultIcon; // 图标不存在时使用默认图标
|
||||
}
|
||||
};
|
||||
|
||||
// 处理图片加载失败
|
||||
const handleImageError = (item) => {
|
||||
console.error(`图标 ${item.icon}.png 加载失败`);
|
||||
console.error(`图标 ${item.icon}.png 加载失败`);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 14px;
|
||||
padding: 14px;
|
||||
|
||||
.card {
|
||||
padding: 14px;
|
||||
background-color: #fff;
|
||||
.card {
|
||||
padding: 14px;
|
||||
background-color: #fff;
|
||||
|
||||
.row {
|
||||
padding-bottom: 14px;
|
||||
.row {
|
||||
padding-bottom: 14px;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.menus_wrap {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 14px;
|
||||
margin-top: 14px;
|
||||
.menus_wrap {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 14px;
|
||||
margin-top: 14px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
transition: all 0.1s ease-in-out;
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
transition: all 0.1s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: #d5ebff;
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: #d5ebff;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.info {
|
||||
.name {
|
||||
font-size: 14px;
|
||||
}
|
||||
.info {
|
||||
.name {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.intro {
|
||||
margin-top: 4px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.4em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.intro {
|
||||
margin-top: 4px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.4em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
<template>
|
||||
<div>
|
||||
<div v-for="(item, index) in modelValue" :key="index" class="flex gap-4 mb-2">
|
||||
<el-select
|
||||
v-model="item.coupon.id"
|
||||
placeholder="请选择优惠券"
|
||||
@change="changeCoupon($event, index)"
|
||||
>
|
||||
<el-option
|
||||
v-for="coupon in couponList"
|
||||
:key="coupon.id"
|
||||
:label="coupon.title"
|
||||
:value="coupon.id"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input v-model="item.num" placeholder="请输入数量">
|
||||
<template #append>数量</template>
|
||||
</el-input>
|
||||
<div>
|
||||
<el-link
|
||||
:underline="false"
|
||||
type="danger"
|
||||
class="no-wrap"
|
||||
@click="modelValue.splice(index, 1)"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<div class="flex gap-1 cursor-pointer" @click="addCoupon()">
|
||||
<el-icon color="#3F9EFF">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<el-link :underline="false" type="primary" class="no-wrap">新增券</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import couponApi from "@/api/market/coupon";
|
||||
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
const modelValue = defineModel({
|
||||
type: Array,
|
||||
default: () => [],
|
||||
});
|
||||
|
||||
// 优惠券列表
|
||||
const couponList = ref([]);
|
||||
function addCoupon() {
|
||||
if (!modelValue.value) {
|
||||
modelValue.value = [
|
||||
{
|
||||
num: 1,
|
||||
coupon: {
|
||||
id: null,
|
||||
},
|
||||
},
|
||||
];
|
||||
return;
|
||||
}
|
||||
modelValue.value.push({
|
||||
num: 1,
|
||||
coupon: {
|
||||
id: null,
|
||||
},
|
||||
});
|
||||
console.log(modelValue.value);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
couponApi.getList({ size: 999 }).then((res) => {
|
||||
if (res) {
|
||||
couponList.value = res.records || [];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function changeCoupon(e, index) {
|
||||
const coupon = couponList.value.find((item) => item.id === e);
|
||||
console.log(coupon);
|
||||
modelValue.value[index].coupon = coupon;
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-dialog title="购买会员方案" v-model="show" @close="reset" width="60%">
|
||||
<el-form :model="form" label-width="120px">
|
||||
<el-form-item label="周期名称" required>
|
||||
<el-input v-model="form.name" placeholder="周期名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="周期价格" required>
|
||||
<el-input v-model="form.price" placeholder="周期价格" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="赠送成长值" required>
|
||||
<el-input v-model="form.reward" placeholder="开通后立刻获得经验" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="赠送优惠券">
|
||||
<CouponLists v-model="form.couponList" />
|
||||
</el-form-item>
|
||||
<el-form-item label="周期时间" required>
|
||||
<div class="flex">
|
||||
<el-input-number
|
||||
style="width: 300px"
|
||||
v-model="form.circleTime"
|
||||
placeholder="周期时间"
|
||||
type="number"
|
||||
/>
|
||||
<el-select class="ml-2" v-model="form.circleUnit" placeholder="">
|
||||
<el-option label="年" value="年" />
|
||||
<el-option label="月" value="月" />
|
||||
<el-option label="周" value="周" />
|
||||
<el-option label="天" value="天" />
|
||||
</el-select>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="text-align: right; margin-top: 20px">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="submit">{{ isedit ? "更新" : "提交" }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import CouponLists from "./coup-lists.vue";
|
||||
|
||||
import { ref, toRaw } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
// 控制主弹窗显示
|
||||
const show = ref(false);
|
||||
|
||||
// 控制优惠券选择弹窗显示
|
||||
const couponDialogVisible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = ref({
|
||||
name: "",
|
||||
price: 0,
|
||||
reward: 0,
|
||||
couponList: [], // 存储已选择的优惠券
|
||||
circleTime: 1, // 会员周期
|
||||
circleUnit: "月", // 会员周期单位
|
||||
});
|
||||
|
||||
// 优惠券列表数据
|
||||
const couponList = ref([
|
||||
{ id: 1, name: "满100减10", value: "10元" },
|
||||
{ id: 2, name: "满200减30", value: "30元" },
|
||||
{ id: 3, name: "满500减100", value: "100元" },
|
||||
]);
|
||||
|
||||
// 已选择的优惠券
|
||||
const selectedCoupons = ref([]);
|
||||
|
||||
// 打开优惠券选择弹窗
|
||||
function openCouponDialog() {
|
||||
couponDialogVisible.value = true;
|
||||
}
|
||||
|
||||
// 关闭优惠券选择弹窗
|
||||
function closeCouponDialog() {
|
||||
couponDialogVisible.value = false;
|
||||
}
|
||||
|
||||
// 确认选择优惠券
|
||||
function confirmCouponSelection() {
|
||||
form.value.couponList = [...selectedCoupons.value];
|
||||
closeCouponDialog();
|
||||
}
|
||||
|
||||
// 处理优惠券选择
|
||||
function handleCouponSelection(selection) {
|
||||
selectedCoupons.value = selection;
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
function reset() {
|
||||
form.value = {
|
||||
name: "",
|
||||
price: 0,
|
||||
reward: 0,
|
||||
couponList: [],
|
||||
circleTime: "",
|
||||
};
|
||||
}
|
||||
|
||||
const emits = defineEmits(["submitSuccess"]);
|
||||
// 提交表单
|
||||
function submit() {
|
||||
if (!form.value.name) {
|
||||
ElMessage.error("请输入方案名称");
|
||||
return;
|
||||
}
|
||||
if (form.value.price <= 0) {
|
||||
ElMessage.error("请输入有效的价格");
|
||||
return;
|
||||
}
|
||||
if (!form.value.circleTime) {
|
||||
ElMessage.error("请选择会员周期");
|
||||
return;
|
||||
}
|
||||
const ispass = form.value.couponList.every((item) => item.num && item.coupon.id);
|
||||
if (!ispass) {
|
||||
ElMessage.error("请选择优惠券并输入数量");
|
||||
return;
|
||||
}
|
||||
console.log("提交表单数据:", form.value);
|
||||
emits("submitSuccess", form.value, dataIndex);
|
||||
// 在此处可以添加表单提交逻辑,例如调用 API
|
||||
close();
|
||||
}
|
||||
|
||||
let isedit = ref(false);
|
||||
let dataIndex = null;
|
||||
function open(data, index) {
|
||||
data = toRaw(data);
|
||||
console.log("data", data);
|
||||
console.log("index", index);
|
||||
if (data) {
|
||||
form.value = data;
|
||||
isedit.value = true;
|
||||
dataIndex = index;
|
||||
} else {
|
||||
isedit.value = false;
|
||||
dataIndex = null;
|
||||
}
|
||||
console.log(data);
|
||||
show.value = true;
|
||||
}
|
||||
function close() {
|
||||
show.value = false;
|
||||
reset();
|
||||
}
|
||||
defineExpose({ open, close, reset, submit });
|
||||
</script>
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
<template>
|
||||
<div class="m-4 bg-white p-4">
|
||||
<HeaderCard
|
||||
name="新客立减"
|
||||
intro="首单下单减免金额"
|
||||
icon="new_user_discount"
|
||||
showSwitch
|
||||
v-model:isOpen="isEnable"
|
||||
></HeaderCard>
|
||||
<el-form ref="form" :model="basicForm">
|
||||
<el-form-item label="减免方式">
|
||||
<div>
|
||||
<el-radio-group v-model="basicForm.discountType">
|
||||
<el-radio value="FIXED">固定金额</el-radio>
|
||||
<el-radio value="RANDOM">随机立减</el-radio>
|
||||
</el-radio-group>
|
||||
<div v-if="basicForm.discountType === 'FIXED'">
|
||||
<el-input type="number" v-model="basicForm.discountValue" placeholder="请输入金额">
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- 随机立减 -->
|
||||
<div v-if="basicForm.discountType == 'RANDOM'">
|
||||
<el-form-item label="会员周期列表">
|
||||
<el-button type="primary" @click="refDialogPlans.open()">添加方案</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-table :data="basicForm.randomDiscountList" border style="width: 60%">
|
||||
<el-table-column prop="amount" label="减免金融(元)" align="center" />
|
||||
<el-table-column prop="probability" label="概率(%)" align="center" />
|
||||
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="text" @click="refDialogPlans.open(scope.row, scope.$index)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button type="text" style="color: red" @click="deletePlan(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item label="可使用类型">
|
||||
<el-checkbox-group v-model="basicForm.useType">
|
||||
<el-checkbox
|
||||
v-model="item.value"
|
||||
:label="item.value"
|
||||
v-for="item in useTypeList"
|
||||
:key="item.value"
|
||||
>
|
||||
{{ item.label }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<div class="flex mt-10 justify-center gap-10">
|
||||
<el-button style="width: 100px" type="primary" @click="basicSubmit" size="large">
|
||||
保存
|
||||
</el-button>
|
||||
<el-button @click="close" style="width: 100px" size="large">取消</el-button>
|
||||
</div>
|
||||
|
||||
<DialogPlans ref="refDialogPlans" @submitSuccess="submitSuccess"></DialogPlans>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import shopApi from "@/api/account/shop";
|
||||
import consumeDiscountApi from "@/api/market/consumeDiscount";
|
||||
import HeaderCard from "../components/headerCard.vue";
|
||||
import DialogPlans from "./components/dialog-plans.vue";
|
||||
import CouponLists from "./components/coup-lists.vue";
|
||||
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const inputStyle = {
|
||||
width: "340px",
|
||||
};
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
//是否开启超级会员
|
||||
const isEnable = ref(false);
|
||||
|
||||
const refDialogPlans = ref();
|
||||
const configs = [
|
||||
{ name: "basic", label: "会员基础设置" },
|
||||
{ name: "lv", label: "会员等级设置" },
|
||||
{ name: "order", label: "购买会员订单" },
|
||||
];
|
||||
const activeTab = ref("basic");
|
||||
const useTypeList = ref([
|
||||
{ label: "堂食", value: "dine-in" },
|
||||
{ label: "外带", value: "take-out" },
|
||||
{ label: "外卖", value: "take-away" },
|
||||
]);
|
||||
const basicForm = reactive({
|
||||
isEnable: 0,
|
||||
discountType: "RANDOM",
|
||||
discountAmount: 0.0,
|
||||
randomDiscountList: [],
|
||||
useType: [],
|
||||
shopId: 0,
|
||||
});
|
||||
function deletePlan(row) {
|
||||
const index = basicForm.configList.indexOf(row);
|
||||
if (index > -1) {
|
||||
basicForm.configList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
function submitSuccess(plans, index) {
|
||||
if (!basicForm.configList) {
|
||||
basicForm.configList = [];
|
||||
}
|
||||
if (index !== null && index !== undefined) {
|
||||
basicForm.configList[index] = plans;
|
||||
return;
|
||||
}
|
||||
basicForm.configList.push(plans);
|
||||
}
|
||||
// 会员基础设置提交
|
||||
function basicSubmit() {
|
||||
const data = toRaw(basicForm);
|
||||
// if (data.openType == "PAY") {
|
||||
// data.conditionList = null;
|
||||
// }
|
||||
// if (data.openType == "CONDITION") {
|
||||
// data.configList = null;
|
||||
// }
|
||||
data.conditionList = useTypes.value
|
||||
.filter((v) => v.checked)
|
||||
.map((v) => {
|
||||
return {
|
||||
code: v.code,
|
||||
value: v.value,
|
||||
};
|
||||
});
|
||||
consumeDiscountApi.editConfig(data).then((res) => {
|
||||
ElMessage.success("保存成功");
|
||||
});
|
||||
// ElMessage.success("保存成功");
|
||||
}
|
||||
|
||||
// 会员等级列表
|
||||
const levels = ref([]);
|
||||
|
||||
// 当前选中的会员等级
|
||||
const selectedLevel = ref(null);
|
||||
|
||||
// 优惠券列表
|
||||
const couponList = ref([
|
||||
{ id: 1, name: "满100减10" },
|
||||
{ id: 2, name: "满200减30" },
|
||||
]);
|
||||
let activeLevelId = ref(null);
|
||||
// 添加会员等级
|
||||
function addLevel() {
|
||||
const nowLastVip = levels.value[levels.value.length - 1];
|
||||
let name = "VIP1";
|
||||
if (levels.value.length) {
|
||||
name = "VIP" + (levels.value.length + 1);
|
||||
}
|
||||
if (nowLastVip && !nowLastVip.id) {
|
||||
ElMessage.error("请先保存当前等级");
|
||||
return;
|
||||
}
|
||||
|
||||
const newLevel = {
|
||||
name,
|
||||
experienceValue: 0,
|
||||
discount: 1,
|
||||
logo: "",
|
||||
costRewardPoints: 1,
|
||||
isCostRewardPoints: 1,
|
||||
isCycleReward: 0,
|
||||
cycleTime: 1,
|
||||
cycleUnit: "月",
|
||||
cycleRewardPoints: 1,
|
||||
cycleRewardCouponList: [],
|
||||
};
|
||||
console.log(newLevel);
|
||||
levels.value.push(newLevel);
|
||||
selectedLevel.value = newLevel;
|
||||
activeLevelId.value = levels.value.length - 1;
|
||||
}
|
||||
|
||||
// 编辑会员等级
|
||||
function editLevel(level) {
|
||||
selectedLevel.value = level;
|
||||
}
|
||||
// 删除会员等级
|
||||
async function removeLevel(index) {
|
||||
const item = levels.value[index];
|
||||
const { id } = item;
|
||||
if (!id) {
|
||||
// 本地删除
|
||||
levels.value.splice(index, 1);
|
||||
const newLevel = levels.value[index - 1];
|
||||
selectedLevel.value = newLevel;
|
||||
activeLevelId.value = index - 1;
|
||||
ElMessage.success("删除成功");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm("确定要删除吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(async () => {
|
||||
const res = await consumeDiscountApi.levelDel({ id: id });
|
||||
if (res) {
|
||||
levels.value.splice(index, 1);
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
|
||||
const newLevel = levels.value[index - 1];
|
||||
selectedLevel.value = newLevel;
|
||||
activeLevelId.value = index - 1;
|
||||
});
|
||||
}
|
||||
// 保存会员等级
|
||||
async function saveLevel(level) {
|
||||
const isPass = level.cycleRewardCouponList.every((item) => item.num && item.coupon.id);
|
||||
if (!isPass) {
|
||||
ElMessage.error("请选择优惠券并输入数量");
|
||||
return;
|
||||
}
|
||||
const res = level.id
|
||||
? await consumeDiscountApi.levelEdit(level)
|
||||
: await consumeDiscountApi.levelAdd(level);
|
||||
if (res) {
|
||||
ElMessage.success("保存成功");
|
||||
}
|
||||
levelRefresh();
|
||||
}
|
||||
|
||||
const shops = ref([]);
|
||||
|
||||
async function levelRefresh() {
|
||||
consumeDiscountApi.levelList().then((res) => {
|
||||
if (res && res.length) {
|
||||
levels.value = res;
|
||||
if (res.length != 0) {
|
||||
selectedLevel.value = res[activeLevelId.value];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
async function init() {
|
||||
consumeDiscountApi.getConfig().then((res) => {
|
||||
Object.assign(basicForm, res);
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
//计算总优惠券数量
|
||||
function totalCount(arr) {
|
||||
return arr.reduce((total, item) => {
|
||||
return total + item.num * 1;
|
||||
}, 0);
|
||||
}
|
||||
//返回
|
||||
function close() {
|
||||
router.back();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs--border-card) {
|
||||
border: none;
|
||||
}
|
||||
:deep(.el-tabs--border-card > .el-tabs__header) {
|
||||
border: none;
|
||||
padding: 4px;
|
||||
}
|
||||
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item) {
|
||||
border: none;
|
||||
}
|
||||
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active) {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue