feat: 等级设置页面改动

This commit is contained in:
lzhizhao 2025-08-07 23:34:38 +08:00
parent c20de1f827
commit 28e887552e
5 changed files with 993 additions and 392 deletions

View File

@ -49,7 +49,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -62,7 +62,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -75,7 +75,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -88,7 +88,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -101,7 +101,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -114,7 +114,7 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -128,7 +128,7 @@ export default {
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: [],
hideInMenu: true, hideInMenu: true
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -141,7 +141,7 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -154,7 +154,7 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -167,7 +167,7 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -180,7 +180,7 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -193,7 +193,7 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -206,7 +206,7 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -219,9 +219,9 @@ export default {
elIcon: "el-icon-user", elIcon: "el-icon-user",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ]
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -246,7 +246,7 @@ export default {
elIcon: "el-icon-user", elIcon: "el-icon-user",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -259,7 +259,7 @@ export default {
elIcon: "el-icon-data-analysis", elIcon: "el-icon-data-analysis",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -272,9 +272,9 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ]
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -288,7 +288,7 @@ export default {
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: [],
hideInMenu: true, hideInMenu: true
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -313,9 +313,9 @@ export default {
elIcon: "el-icon-postcard", elIcon: "el-icon-postcard",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ]
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -328,7 +328,7 @@ export default {
elIcon: "el-icon-document-remove", elIcon: "el-icon-document-remove",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -353,7 +353,7 @@ export default {
elIcon: "el-icon-postcard", elIcon: "el-icon-postcard",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -366,9 +366,9 @@ export default {
elIcon: "el-icon-postcard", elIcon: "el-icon-postcard",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ]
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -386,14 +386,14 @@ export default {
menuId: getUUID(), menuId: getUUID(),
parentId: 0, parentId: 0,
parentName: null, parentName: null,
name: "会员等级管理", name: "等级设置",
url: "marketing/level/index", url: "marketing/level/index",
perms: "", perms: "",
type: 1, type: 1,
elIcon: "el-icon-user", elIcon: "el-icon-user",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -406,7 +406,7 @@ export default {
elIcon: "el-icon-data-analysis", elIcon: "el-icon-data-analysis",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -419,7 +419,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -432,7 +432,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -445,9 +445,9 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ]
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -472,7 +472,7 @@ export default {
elIcon: "el-icon-user", elIcon: "el-icon-user",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -485,7 +485,7 @@ export default {
elIcon: "el-icon-data-analysis", elIcon: "el-icon-data-analysis",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -498,7 +498,7 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -511,10 +511,10 @@ export default {
elIcon: "el-icon-shopping-cart-full", elIcon: "el-icon-shopping-cart-full",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ],
hideInMenu: true, hideInMenu: true
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -539,9 +539,9 @@ export default {
elIcon: "el-icon-menu", elIcon: "el-icon-menu",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ]
}, },
{ {
menuId: getUUID(), menuId: getUUID(),
@ -566,11 +566,65 @@ export default {
elIcon: "el-icon-postcard", elIcon: "el-icon-postcard",
orderNum: 0, orderNum: 0,
open: null, open: null,
list: [], list: []
}, }
], ]
}, }
// {
// menuId: getUUID(),
// parentId: 0,
// parentName: null,
// name: "会员管理",
// url: "member-management",
// perms: "",
// type: 0,
// elIcon: "el-icon-user-solid",
// orderNum: 0,
// open: null,
// list: [
// {
// menuId: getUUID(),
// parentId: 0,
// parentName: null,
// name: "等级设置",
// url: "member-management/level-setting/index",
// perms: "",
// type: 1,
// elIcon: "el-icon-star-on",
// orderNum: 0,
// open: null,
// list: []
// }
// ]
// },
// {
// menuId: getUUID(),
// parentId: 0,
// parentName: null,
// name: "会员列表",
// url: "member-list",
// perms: "",
// type: 0,
// elIcon: "el-icon-user",
// orderNum: 0,
// open: null,
// list: [
// {
// menuId: getUUID(),
// parentId: 0,
// parentName: null,
// name: "会员列表",
// url: "member-list/member-list/index",
// perms: "",
// type: 1,
// elIcon: "el-icon-user",
// orderNum: 0,
// open: null,
// list: []
// }
// ]
// }
], ],
code: 0, code: 0,
permissions: [], permissions: []
}; };

View File

@ -1,14 +1,16 @@
import Vue from 'vue' import Vue from "vue";
import router from '@/router' import router from "@/router";
import store from '@/store' import store from "@/store";
/** /**
* 获取uuid * 获取uuid
*/ */
export function getUUID() { export function getUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16) return (c === "x" ? (Math.random() * 16) | 0 : "r&0x3" | "0x8").toString(
}) 16
);
});
} }
/** /**
@ -17,9 +19,9 @@ export function getUUID() {
*/ */
export function isAuth(key) { export function isAuth(key) {
return ( return (
JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== JSON.parse(sessionStorage.getItem("permissions") || "[]").indexOf(key) !==
-1 || false -1 || false
) );
} }
/** /**
@ -28,87 +30,87 @@ export function isAuth(key) {
* @param {*} id * @param {*} id
* @param {*} pid * @param {*} pid
*/ */
export function treeDataTranslate(data, id = 'id', pid = 'parentId') { export function treeDataTranslate(data, id = "id", pid = "parentId") {
var res = [] var res = [];
var temp = {} var temp = {};
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
temp[data[i][id]] = data[i] temp[data[i][id]] = data[i];
} }
for (var k = 0; k < data.length; k++) { for (var k = 0; k < data.length; k++) {
if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) { if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
if (!temp[data[k][pid]]['children']) { if (!temp[data[k][pid]]["children"]) {
temp[data[k][pid]]['children'] = [] temp[data[k][pid]]["children"] = [];
} }
if (!temp[data[k][pid]]['_level']) { if (!temp[data[k][pid]]["_level"]) {
temp[data[k][pid]]['_level'] = 1 temp[data[k][pid]]["_level"] = 1;
} }
data[k]['_level'] = temp[data[k][pid]]._level + 1 data[k]["_level"] = temp[data[k][pid]]._level + 1;
temp[data[k][pid]]['children'].push(data[k]) temp[data[k][pid]]["children"].push(data[k]);
} else { } else {
res.push(data[k]) res.push(data[k]);
} }
} }
return res return res;
} }
/** /**
* 清除登录信息 * 清除登录信息
*/ */
export function clearLoginInfo() { export function clearLoginInfo() {
Vue.cookie.delete('token') Vue.cookie.delete("token");
store.commit('resetStore') store.commit("resetStore");
sessionStorage.removeItem('password') sessionStorage.removeItem("password");
sessionStorage.removeItem('role') sessionStorage.removeItem("role");
sessionStorage.removeItem('userInfo') sessionStorage.removeItem("userInfo");
router.options.isAddDynamicMenuRoutes = false router.options.isAddDynamicMenuRoutes = false;
} }
// 深拷贝对象 // 深拷贝对象
export function deepClone(obj) { export function deepClone(obj) {
const _toString = Object.prototype.toString const _toString = Object.prototype.toString;
// null, undefined, non-object, function // null, undefined, non-object, function
if (!obj || typeof obj !== 'object') { if (!obj || typeof obj !== "object") {
return obj return obj;
} }
// DOM Node // DOM Node
if (obj.nodeType && 'cloneNode' in obj) { if (obj.nodeType && "cloneNode" in obj) {
return obj.cloneNode(true) return obj.cloneNode(true);
} }
// Date // Date
if (_toString.call(obj) === '[object Date]') { if (_toString.call(obj) === "[object Date]") {
return new Date(obj.getTime()) return new Date(obj.getTime());
} }
// RegExp // RegExp
if (_toString.call(obj) === '[object RegExp]') { if (_toString.call(obj) === "[object RegExp]") {
const flags = [] const flags = [];
if (obj.global) { if (obj.global) {
flags.push('g') flags.push("g");
} }
if (obj.multiline) { if (obj.multiline) {
flags.push('m') flags.push("m");
} }
if (obj.ignoreCase) { if (obj.ignoreCase) {
flags.push('i') flags.push("i");
} }
return new RegExp(obj.source, flags.join('')) return new RegExp(obj.source, flags.join(""));
} }
const result = Array.isArray(obj) const result = Array.isArray(obj)
? [] ? []
: obj.constructor : obj.constructor
? new obj.constructor() ? new obj.constructor()
: {} : {};
for (const key in obj) { for (const key in obj) {
result[key] = deepClone(obj[key]) result[key] = deepClone(obj[key]);
} }
return result return result;
} }
/** /**
@ -117,22 +119,22 @@ export function deepClone(obj) {
* @param {*} max * @param {*} max
*/ */
export function getDay(day) { export function getDay(day) {
let today = new Date() let today = new Date();
let targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day let targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day;
today.setTime(targetday_milliseconds) //注意,这行是关键代码 today.setTime(targetday_milliseconds); //注意,这行是关键代码
let tYear = today.getFullYear() let tYear = today.getFullYear();
let tMonth = today.getMonth() let tMonth = today.getMonth();
let tDate = today.getDate() let tDate = today.getDate();
tMonth = doHandleMonth(tMonth + 1) tMonth = doHandleMonth(tMonth + 1);
tDate = doHandleMonth(tDate) tDate = doHandleMonth(tDate);
return tYear + '-' + tMonth + '-' + tDate return tYear + "-" + tMonth + "-" + tDate;
} }
function doHandleMonth(month) { function doHandleMonth(month) {
let m = month let m = month;
if (month.toString().length === 1) { if (month.toString().length === 1) {
m = '0' + month m = "0" + month;
} }
return m return m;
} }
/** /**
* 权限 * 权限
@ -140,142 +142,151 @@ function doHandleMonth(month) {
* @param {*} max * @param {*} max
*/ */
export function getMenu(role, manageMode) { export function getMenu(role, manageMode) {
if (role == 'ROLE_MANAGER') { if (role == "ROLE_MANAGER") {
return [ return [
'operation-management', "operation-management",
'operation-management/commodity/index', "operation-management/commodity/index",
'operation-management/order/index', "operation-management/order/index",
'operation-management/banner/index', "operation-management/banner/index",
'operation-management/notice/index', "operation-management/notice/index",
'operation-management/paynotice/index', "operation-management/paynotice/index",
'operation-management/role/index', "operation-management/role/index",
'datacenter', "datacenter",
'datacenter/customer-analysis/index', "datacenter/customer-analysis/index",
'datacenter/product-analysis/index', "datacenter/product-analysis/index",
'datacenter/order-analysis/index', "datacenter/order-analysis/index",
'coupon/index', "coupon/index",
'presale', "presale",
'presale/products/index', "presale/products/index",
'presale/order/index', "presale/order/index",
'marketing', "marketing",
'marketing/level/index', "marketing/level/index",
'marketing/user/index', "marketing/user/index",
'marketing/points-setting/index', "marketing/points-setting/index",
'marketing/points-mall/index', "marketing/points-mall/index",
'marketing/points-order/index', "marketing/points-order/index",
'local-course/resources', // "member-management",
'wallet/index', // "member-management/level-setting/index",
'ogistics-fare', // "member-list",
'logistics-fare/logistics-template/index', // "member-list/member-list/index",
'bank-card/index', "local-course/resources",
'operation-management/total-order/index', "wallet/index",
'operation-management/accountNumber/index' "ogistics-fare",
] "logistics-fare/logistics-template/index",
} else if (role == 'ROLE_MERCHANT') { "bank-card/index",
"operation-management/total-order/index",
"operation-management/accountNumber/index"
];
} else if (role == "ROLE_MERCHANT") {
if (manageMode === 1) { if (manageMode === 1) {
return [ return [
'operation-management', "operation-management",
'operation-management/commodity/index', "operation-management/commodity/index",
'operation-management/order/index', "operation-management/order/index",
'operation-management/banner/index', "operation-management/banner/index",
'operation-management/notice/index', "operation-management/notice/index",
'operation-management/paynotice/index', "operation-management/paynotice/index",
'operation-management/role/index', "operation-management/role/index",
'datacenter', "datacenter",
'datacenter/customer-analysis/index', "datacenter/customer-analysis/index",
'datacenter/product-analysis/index', "datacenter/product-analysis/index",
'datacenter/order-analysis/index', "datacenter/order-analysis/index",
'coupon/index', "coupon/index",
'presale', "presale",
'presale/products/index', "presale/products/index",
'presale/order/index', "presale/order/index",
'marketing', "marketing",
// 'marketing/level/index', "marketing/points-mall/index",
// 'marketing/user/index', "marketing/points-order/index",
// 'marketing/points-setting/index', // "member-management",
'marketing/points-mall/index', // "member-management/level-setting/index",
'marketing/points-order/index', // "member-list",
'local-course/resources', // "member-list/member-list/index",
'wallet/index', "local-course/resources",
'ogistics-fare', "wallet/index",
'logistics-fare/logistics-template/index', "ogistics-fare",
'bank-card/index', "logistics-fare/logistics-template/index",
'operation-management/total-order/index', "bank-card/index",
'operation-management/accountNumber/index' "operation-management/total-order/index",
] "operation-management/accountNumber/index"
];
} else { } else {
return [ return [
'operation-management', "operation-management",
'operation-management/commodity/index', "operation-management/commodity/index",
'operation-management/order/index', "operation-management/order/index",
'operation-management/banner/index', "operation-management/banner/index",
'operation-management/notice/index', "operation-management/notice/index",
'operation-management/paynotice/index', "operation-management/paynotice/index",
'operation-management/role/index', "operation-management/role/index",
'datacenter', "datacenter",
'datacenter/customer-analysis/index', "datacenter/customer-analysis/index",
'datacenter/product-analysis/index', "datacenter/product-analysis/index",
'datacenter/order-analysis/index', "datacenter/order-analysis/index",
'coupon/index', "coupon/index",
'presale', "presale",
'presale/products/index', "presale/products/index",
'presale/order/index', "presale/order/index",
'marketing', "marketing",
'marketing/level/index', "marketing/level/index",
'marketing/user/index', "marketing/user/index",
'marketing/points-setting/index', "marketing/points-setting/index",
'marketing/points-mall/index', "marketing/points-mall/index",
'marketing/points-order/index', "marketing/points-order/index",
'local-course/resources', // "member-management",
'wallet/index', // "member-management/level-setting/index",
'ogistics-fare', // "member-list",
'logistics-fare/logistics-template/index', // "member-list/member-list/index",
'bank-card/index', "local-course/resources",
'operation-management/total-order/index', "wallet/index",
'operation-management/accountNumber/index' "ogistics-fare",
] "logistics-fare/logistics-template/index",
"bank-card/index",
"operation-management/total-order/index",
"operation-management/accountNumber/index"
];
} }
} else if (role == 'ROLE_BRAND_MANAGER') { } else if (role == "ROLE_BRAND_MANAGER") {
return [ return [
'operation-management', "operation-management",
// "operation-management/shop-list/index", // "operation-management/shop-list/index",
'operation-management/brand-market/index', "operation-management/brand-market/index",
'operation-management/brand-store/index', "operation-management/brand-store/index",
'operation-management/distributor/index', "operation-management/distributor/index",
// "operation-management/order/index", // "operation-management/order/index",
'operation-management/brand-order/index', "operation-management/brand-order/index",
// "operation-management/role/index", // "operation-management/role/index",
'datacenter', "datacenter",
'datacenter/customer-analysis/index', "datacenter/customer-analysis/index",
'datacenter/product-analysis/index', "datacenter/product-analysis/index",
'datacenter/order-analysis/index', "datacenter/order-analysis/index",
'brand', "brand",
'brand/config/index', "brand/config/index",
'local-course/resources', "local-course/resources",
'wallet/index' "wallet/index"
// "operation-management/accountNumber/index", // "operation-management/accountNumber/index",
] ];
} else if (role == 'ROLE_AGENT') { } else if (role == "ROLE_AGENT") {
return [ return [
'operation-management', "operation-management",
'operation-management/shop-list/index', "operation-management/shop-list/index",
'operation-management/market-list/index', "operation-management/market-list/index",
// "operation-management/order/index", // "operation-management/order/index",
'operation-management/brand-order/index', "operation-management/brand-order/index",
// "operation-management/role/index", // "operation-management/role/index",
'datacenter', "datacenter",
'datacenter/customer-analysis/index', "datacenter/customer-analysis/index",
'datacenter/product-analysis/index', "datacenter/product-analysis/index",
'datacenter/order-analysis/index', "datacenter/order-analysis/index",
'local-course/resources', "local-course/resources",
'wallet/index' "wallet/index"
// "operation-management/accountNumber/index", // "operation-management/accountNumber/index",
] ];
} else { } else {
return null return null;
} }
} }
export function isNumberStr(str) { export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str);
} }

View File

@ -1,202 +1,342 @@
<template> <template>
<div> <div class="level-setting">
<div class="tips"> <!-- 摊铺选择 -->
<div>请谨慎操作此页面数据避免频繁修改导致会员流失等不必要的损失</div> <div class="shop-selector" v-if="storeList.length > 1">
<div style="margin-top: 10px">
请注意用户一旦达到某会员等级后续修改会员等级要求不会影响用户已达到的会员等级但可享有该等级对应的会员权益
</div>
<div style="margin-top: 20px">
举例24年2月用户在本商铺的成长值达到500升级为VIP2,此时,VIP2会员权益享有的生日优惠卷1
</div>
<div style="margin-top: 10px">
24年3月本商铺修改VIP2所需成长值为700并新增会员生日优惠卷2修改提交后,该用户会员等级保持VIP2不变且享有会员优惠卷1和会员优惠卷2
</div>
</div>
<div v-if="storeList.length > 1">
<el-form :inline="true" :model="formInline" class="demo-form-inline"> <el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="摊铺:"> <el-form-item label="摊铺名称">
<el-select v-model="formInline.shopId" placeholder="请选择摊铺::"> <el-select
v-model="formInline.shopIds"
placeholder="请选择摊铺位名称..."
style="width: 300px"
multiple
collapse-tags
@change="handleShopChange"
>
<el-option <el-option
v-for="item in storeList" v-for="item in storeList"
:key="item.shopId" :key="item.shopId"
:label="item.shopName" :label="item.shopName"
:value="item.shopId" :value="item.shopId"
></el-option> >
</el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="getList" type="primary">查询</el-button> <el-button type="primary" @click="getList">查询</el-button>
<el-button @click="handleBatchLevelSetting"
>批量会员等级编辑</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="tipsLevel">
<div> <!-- 数据表格 -->
<span style="margin-right: 30px">全部等级({{ list.length }})</span <div class="table-container">
><el-button @click="add" type="primary">+新增等级</el-button> <el-table :data="tableData" border style="width: 100%">
</div>
<div>
<span v-if="!form.effective" style="margin-right: 30px"
>未开通会员</span
>
<span v-if="form.effective" style="margin-right: 30px"
>会员到期时间 {{ form.effectiveEndTime }}</span
>
<el-button @click="addSetMenu" type="primary">购买工具</el-button>
</div>
</div>
<el-table :data="list" :border="true" style="width: 100%">
<el-table-column <el-table-column
prop="shopName"
label="摊铺名称"
width="140" width="140"
align="center" align="center"
label="等级名称"
prop="levelName"
/>
<el-table-column
width="140"
align="center"
label="所需成长值"
prop="requiredGrowthValue"
/>
<el-table-column
width="140"
align="center"
label="会员人数"
prop="memberCount"
> >
</el-table-column> </el-table-column>
<el-table-column label="是否启用会员" width="140" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.enableMember"
@change="handleMemberToggle(scope.row)"
>
</el-switch>
</template>
</el-table-column>
<el-table-column prop="memberLevels" label="会员等级" align="center">
<template slot-scope="scope">
<span
v-if="scope.row.memberLevels && scope.row.memberLevels.length > 0"
>
{{ scope.row.memberLevels.join(", ") }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" width="140" align="center">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
@click="handleLevelSetting(scope.row)"
>
设置等级明细
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 会员等级明细弹窗 -->
<el-dialog
title="会员等级明细"
:visible.sync="levelDialogVisible"
width="80%"
:before-close="handleDialogClose"
>
<div class="level-detail-dialog">
<div class="dialog-header">
<div class="shop-info">
<span>摊铺{{ currentShop.shopName }}</span>
</div>
<div class="dialog-actions">
<el-button type="primary" size="small" @click="handleEditLevel"
>等级编辑</el-button
>
<el-button type="success" size="small" @click="handleSaveLevel"
>提交</el-button
>
</div>
</div>
<!-- 会员等级明细表格 -->
<el-table
:data="levelDetailData"
border
style="width: 100%; margin-top: 20px;"
>
<el-table-column <el-table-column
prop="levelName"
label="等级名称"
width="100"
align="center" align="center"
label="会员权益"
prop="packageEffectiveTimeQuantity"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<div> <span :style="{ color: getLevelColor(scope.row.levelName) }">
<span>{{ scope.row.enableMemberDiscount ? "会员折扣," : "" }}</span> {{ scope.row.levelName }}
<span>{{ </span>
scope.row.enablePointsRedemption ? "积分兑换," : ""
}}</span>
<span>{{
scope.row.enableBirthdayCoupons ? "生日优惠卷," : ""
}}</span>
<span>{{
scope.row.enableBirthdayReward ? "生日双倍积分" : ""
}}</span>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
<!-- <el-table-column align="center" label="操作" fixed="right" width="240"> --> prop="requiredGrowthValue"
<!-- <template v-slot="scope"> label="所需成长值"
<el-button @click="add(scope.row)" type="primary">编辑</el-button> width="120"
<el-button @click="add(scope.row)" type="primary">转移</el-button> align="center"
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
icon-color="#626AEF"
title="确定删除吗?"
@confirm="confirmEvent(scope.row)"
@cancel="cancelEvent"
> >
<template #reference> <template slot-scope="scope">
<el-button type="danger">删除</el-button> <span style="color: #1890ff;">{{
scope.row.requiredGrowthValue
}}</span>
</template> </template>
</el-popconfirm> </el-table-column>
</template> --> <el-table-column
<!-- </el-table-column> --> prop="memberCount"
label="会员人数"
width="100"
align="center"
>
<template slot-scope="scope">
<span style="color: #52c41a;">{{ scope.row.memberCount }}</span>
</template>
</el-table-column>
<el-table-column
prop="memberBenefits"
label="会员权益"
align="center"
>
<template slot-scope="scope">
<span style="color: #666;">{{ scope.row.memberBenefits }}</span>
</template>
</el-table-column>
</el-table> </el-table>
<!-- 添加 --> </div>
<addOrUpdate @getList="getList" ref="addOrUpdate"></addOrUpdate> </el-dialog>
<!-- 添加套餐 -->
<set-menu @getList="getList" ref="setMenu"></set-menu>
</div> </div>
</template> </template>
<script> <script>
import setMenu from "./popup/set-menu.vue";
import addOrUpdate from "./popup/add-or-update.vue";
import { mapState } from "vuex"; import { mapState } from "vuex";
export default { export default {
components: { name: "LevelSetting",
addOrUpdate,
setMenu,
},
data() { data() {
return { return {
list: [],
formInline: { formInline: {
unitType: "", shopIds: []
marketId: "",
shopId: "",
}, },
form: {}, tableData: [],
levelDialogVisible: false,
currentShop: {},
levelDetailData: [
{
levelName: "LV1",
requiredGrowthValue: "100",
memberCount: "1,250",
memberBenefits: "新会员双倍积分,享受基础会员价格优惠"
},
{
levelName: "LV2",
requiredGrowthValue: "500",
memberCount: "850",
memberBenefits: "享受9.5折优惠,每月专属优惠券,生日礼品"
},
{
levelName: "LV3",
requiredGrowthValue: "1,200",
memberCount: "450",
memberBenefits: "享受9折优惠免费配送服务专属客服支持"
},
{
levelName: "LV4",
requiredGrowthValue: "2,500",
memberCount: "180",
memberBenefits: "享受8.5折优惠,优先配送,专属活动邀请,年度礼品"
}
]
}; };
}, },
created() {
this.formInline = {
unitType:
JSON.parse(sessionStorage.getItem("userInfo")).role == "ROLE_MERCHANT"
? 3
: 2,
marketId: this.marketId,
shopId: this.shopId,
};
this.getList();
},
methods: {
// getData() {
// this.$api.mer_admin
// .storeList({ marketId: this.formInline.marketId })
// .then((res) => {
// this.storeList = res.data.data;
// this.formInline.shopId = res.data.data[0].shopId;
// this.$nextTick(() => {
// this.getList();
// });
// });
// },
getList() {
this.$api.marketing.marketingLevelPage(this.formInline).then((res) => {
this.list = res.data.data ? res.data.data : [];
});
this.$api.marketing.getEffective(this.formInline).then((res) => {
console.log(res);
this.form = res.data.data;
});
},
add() {
this.$refs.addOrUpdate.toggle().add(this.formInline);
},
addSetMenu() {
this.$refs.setMenu.toggle().add(this.formInline);
},
confirmEvent() {},
cancelEvent() {},
},
computed: { computed: {
...mapState("userData", [ ...mapState("userData", ["storeList", "shopId", "marketId"])
"isMerchant",
"marketList",
"storeList",
"marketId",
"shopId",
]),
}, },
created() {
this.initData();
},
methods: {
initData() {
//
this.formInline.shopIds = this.storeList.map(store => store.shopId);
this.getList();
},
getList() {
// ID
if (this.formInline.shopIds.length === 0) {
this.tableData = [];
return;
}
const selectedStores = this.storeList.filter(store =>
this.formInline.shopIds.includes(store.shopId)
);
this.tableData = selectedStores.map(store => ({
shopId: store.shopId,
shopName: store.shopName,
enableMember: Math.random() > 0.5, //
memberLevels: this.generateRandomLevels()
}));
},
generateRandomLevels() {
const levels = ["lv1", "lv2", "lv3", "lv4"];
const count = Math.floor(Math.random() * 4) + 1;
return levels.slice(0, count);
},
handleShopChange() {
this.getList();
},
handleMemberToggle(row) {
// /
console.log(
"Toggle member for shop:",
row.shopName,
"Enable:",
row.enableMember
);
// API
},
handleLevelSetting(row) {
this.currentShop = row;
this.levelDialogVisible = true;
},
handleBatchLevelSetting() {
//
this.$message.info("批量会员等级编辑功能待实现");
},
handleDialogClose() {
this.levelDialogVisible = false;
this.currentShop = {};
},
handleEditLevel() {
//
this.$message.info("等级编辑功能待实现");
},
handleSaveLevel() {
//
this.$message.success("等级明细保存成功");
this.handleDialogClose();
},
getLevelColor(levelName) {
const colorMap = {
LV1: "#52c41a",
LV2: "#1890ff",
LV3: "#fa8c16",
LV4: "#f5222d"
};
return colorMap[levelName] || "#666";
}
}
}; };
</script> </script>
<style scoped lang="scss" > <style lang="scss" scoped>
.tips { .level-setting {
padding: 15px; .shop-selector {
margin-bottom: 20px; margin-bottom: 20px;
border-radius: 10px; padding: 15px;
width: 100%; background: #f5f5f5;
font-size: 16px; border-radius: 4px;
background: #e5e5e5; }
color: #faa639;
} .table-container {
.tipsLevel { .el-table {
margin: 20px 0; .el-switch {
margin: 0;
}
}
}
.level-detail-dialog {
.dialog-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
margin-bottom: 10px;
.shop-info {
padding: 8px 12px;
background: #f0f9ff;
border-radius: 4px;
color: #1890ff;
font-weight: 500;
}
.dialog-actions {
.el-button {
margin-left: 8px;
}
}
}
.el-table {
.el-table__header {
th {
background-color: #fafafa;
color: #333;
font-weight: 600;
}
}
.el-table__body {
td {
padding: 12px 0;
}
}
}
}
} }
</style> </style>

View File

@ -0,0 +1,29 @@
<template>
<div class="mod-config">
<h2>会员列表</h2>
<p>这里是会员列表页面内容</p>
</div>
</template>
<script>
export default {
name: "MemberList",
data() {
return {
//
};
},
created() {
//
},
methods: {
//
}
};
</script>
<style lang="scss" scoped>
.mod-config {
padding: 20px;
}
</style>

View File

@ -0,0 +1,367 @@
<template>
<div class="level-setting">
<!-- 等级设置标题 -->
<div class="header">
<h3>等级设置</h3>
</div>
<!-- 摊铺选择 -->
<div class="shop-selector" v-if="storeList.length > 1">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="摊铺名称">
<el-select
v-model="formInline.shopIds"
placeholder="请选择摊铺位名称..."
style="width: 300px"
multiple
collapse-tags
@change="handleShopChange"
>
<el-option
v-for="item in storeList"
:key="item.shopId"
:label="item.shopName"
:value="item.shopId"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList">查询</el-button>
<el-button @click="handleBatchLevelSetting"
>批量会员等级编辑</el-button
>
</el-form-item>
</el-form>
</div>
<!-- 数据表格 -->
<div class="table-container">
<el-table :data="tableData" border style="width: 100%">
<el-table-column
prop="shopName"
label="摊铺名称"
width="140"
align="center"
>
</el-table-column>
<el-table-column label="是否启用会员" width="140" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.enableMember"
@change="handleMemberToggle(scope.row)"
>
</el-switch>
</template>
</el-table-column>
<el-table-column prop="memberLevels" label="会员等级" align="center">
<template slot-scope="scope">
<span
v-if="scope.row.memberLevels && scope.row.memberLevels.length > 0"
>
{{ scope.row.memberLevels.join(", ") }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" width="140" align="center">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
@click="handleLevelSetting(scope.row)"
>
设置等级明细
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 会员等级明细弹窗 -->
<el-dialog
title="会员等级明细"
:visible.sync="levelDialogVisible"
width="80%"
:before-close="handleDialogClose"
>
<div class="level-detail-dialog">
<div class="dialog-header">
<div class="shop-info">
<span>摊铺{{ currentShop.shopName }}</span>
</div>
<div class="dialog-actions">
<el-button type="primary" size="small" @click="handleEditLevel"
>等级编辑</el-button
>
<el-button type="success" size="small" @click="handleSaveLevel"
>提交</el-button
>
</div>
</div>
<!-- 会员等级明细表格 -->
<el-table
:data="levelDetailData"
border
style="width: 100%; margin-top: 20px;"
>
<el-table-column
prop="levelName"
label="等级名称"
width="100"
align="center"
>
<template slot-scope="scope">
<span :style="{ color: getLevelColor(scope.row.levelName) }">
{{ scope.row.levelName }}
</span>
</template>
</el-table-column>
<el-table-column
prop="requiredGrowthValue"
label="所需成长值"
width="120"
align="center"
>
<template slot-scope="scope">
<span style="color: #1890ff;">{{
scope.row.requiredGrowthValue
}}</span>
</template>
</el-table-column>
<el-table-column
prop="memberCount"
label="会员人数"
width="100"
align="center"
>
<template slot-scope="scope">
<span style="color: #52c41a;">{{ scope.row.memberCount }}</span>
</template>
</el-table-column>
<el-table-column
prop="memberBenefits"
label="会员权益"
align="center"
>
<template slot-scope="scope">
<span style="color: #666;">{{ scope.row.memberBenefits }}</span>
</template>
</el-table-column>
</el-table>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "LevelSetting",
data() {
return {
formInline: {
shopIds: []
},
tableData: [],
levelDialogVisible: false,
currentShop: {},
levelDetailData: [
{
levelName: "LV1",
requiredGrowthValue: "100",
memberCount: "1,250",
memberBenefits: "新会员双倍积分,享受基础会员价格优惠"
},
{
levelName: "LV2",
requiredGrowthValue: "500",
memberCount: "850",
memberBenefits: "享受9.5折优惠,每月专属优惠券,生日礼品"
},
{
levelName: "LV3",
requiredGrowthValue: "1,200",
memberCount: "450",
memberBenefits: "享受9折优惠免费配送服务专属客服支持"
},
{
levelName: "LV4",
requiredGrowthValue: "2,500",
memberCount: "180",
memberBenefits: "享受8.5折优惠,优先配送,专属活动邀请,年度礼品"
}
]
};
},
computed: {
...mapState("userData", ["storeList", "shopId", "marketId"])
},
created() {
this.initData();
},
methods: {
initData() {
//
this.formInline.shopIds = this.storeList.map(store => store.shopId);
this.getList();
},
getList() {
// ID
if (this.formInline.shopIds.length === 0) {
this.tableData = [];
return;
}
const selectedStores = this.storeList.filter(store =>
this.formInline.shopIds.includes(store.shopId)
);
this.tableData = selectedStores.map(store => ({
shopId: store.shopId,
shopName: store.shopName,
enableMember: Math.random() > 0.5, //
memberLevels: this.generateRandomLevels()
}));
},
generateRandomLevels() {
const levels = ["lv1", "lv2", "lv3", "lv4"];
const count = Math.floor(Math.random() * 4) + 1;
return levels.slice(0, count);
},
handleShopChange() {
this.getList();
},
handleMemberToggle(row) {
// /
console.log(
"Toggle member for shop:",
row.shopName,
"Enable:",
row.enableMember
);
// API
},
handleLevelSetting(row) {
this.currentShop = row;
this.levelDialogVisible = true;
},
handleBatchLevelSetting() {
//
this.$message.info("批量会员等级编辑功能待实现");
},
handleDialogClose() {
this.levelDialogVisible = false;
this.currentShop = {};
},
handleEditLevel() {
//
this.$message.info("等级编辑功能待实现");
},
handleSaveLevel() {
//
this.$message.success("等级明细保存成功");
this.handleDialogClose();
},
getLevelColor(levelName) {
const colorMap = {
LV1: "#52c41a",
LV2: "#1890ff",
LV3: "#fa8c16",
LV4: "#f5222d"
};
return colorMap[levelName] || "#666";
}
}
};
</script>
<style lang="scss" scoped>
.level-setting {
padding: 20px;
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h3 {
margin: 0;
font-size: 18px;
font-weight: 600;
}
.dropdown-container {
color: #999;
font-size: 14px;
}
}
.shop-selector {
margin-bottom: 20px;
padding: 15px;
background: #f5f5f5;
border-radius: 4px;
}
.table-container {
.el-table {
.el-switch {
margin: 0;
}
}
}
.level-detail-dialog {
.dialog-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
.shop-info {
padding: 8px 12px;
background: #f0f9ff;
border-radius: 4px;
color: #1890ff;
font-weight: 500;
}
.dialog-actions {
.el-button {
margin-left: 8px;
}
}
}
.el-table {
.el-table__header {
th {
background-color: #fafafa;
color: #333;
font-weight: 600;
}
}
.el-table__body {
td {
padding: 12px 0;
}
}
}
}
}
</style>