feat: 会员详情弹框样式
This commit is contained in:
parent
8aa41006de
commit
562a766257
|
@ -414,7 +414,7 @@ export default {
|
||||||
menuId: getUUID(),
|
menuId: getUUID(),
|
||||||
parentId: 0,
|
parentId: 0,
|
||||||
parentName: null,
|
parentName: null,
|
||||||
name: "用户管理",
|
name: "会员列表",
|
||||||
url: "marketing/user/index",
|
url: "marketing/user/index",
|
||||||
perms: "",
|
perms: "",
|
||||||
type: 1,
|
type: 1,
|
||||||
|
|
|
@ -32,6 +32,12 @@ const globalRoutes = [
|
||||||
component: _import("common/login"),
|
component: _import("common/login"),
|
||||||
name: "login",
|
name: "login",
|
||||||
meta: { title: "登录" }
|
meta: { title: "登录" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/test-member-detail",
|
||||||
|
component: _import("test-member-detail"),
|
||||||
|
name: "test-member-detail",
|
||||||
|
meta: { title: "会员详情样式测试" }
|
||||||
}
|
}
|
||||||
//test用,会员管理
|
//test用,会员管理
|
||||||
];
|
];
|
||||||
|
|
|
@ -6,34 +6,34 @@
|
||||||
* @Description:
|
* @Description:
|
||||||
* @FilePath: \background-front-end\src\utils\httpRequest.js
|
* @FilePath: \background-front-end\src\utils\httpRequest.js
|
||||||
*/
|
*/
|
||||||
import Vue from 'vue'
|
import Vue from "vue";
|
||||||
import axios from 'axios'
|
import axios from "axios";
|
||||||
import router from '@/router'
|
import router from "@/router";
|
||||||
import qs from 'qs'
|
import qs from "qs";
|
||||||
import merge from 'lodash/merge'
|
import merge from "lodash/merge";
|
||||||
import { Message } from 'element-ui'
|
import { Message } from "element-ui";
|
||||||
import { clearLoginInfo } from '@/utils'
|
import { clearLoginInfo } from "@/utils";
|
||||||
import commonUtil from './common'
|
import commonUtil from "./common";
|
||||||
import des from './des.js'
|
import des from "./des.js";
|
||||||
|
|
||||||
const http = axios.create({
|
const http = axios.create({
|
||||||
baseURL:
|
baseURL:
|
||||||
process.env.NODE_ENV !== 'production' && process.env.OPEN_PROXY
|
process.env.NODE_ENV !== "production" && process.env.OPEN_PROXY
|
||||||
? '/proxyApi/'
|
? "/proxyApi/"
|
||||||
: window.SITE_CONFIG.baseUrl,
|
: window.SITE_CONFIG.baseUrl,
|
||||||
timeout: 1000 * 30,
|
timeout: 1000 * 30,
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json; charset=utf-8'
|
"Content-Type": "application/json; charset=utf-8"
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求拦截
|
* 请求拦截
|
||||||
*/
|
*/
|
||||||
http.interceptors.request.use(
|
http.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
config.headers['token'] = `Bearer ${Vue.cookie.get('token')}` // 请求头带上token
|
config.headers["token"] = `Bearer ${Vue.cookie.get("token")}`; // 请求头带上token
|
||||||
// 针对post请求加密
|
// 针对post请求加密
|
||||||
// if (config.method.toLowerCase() === "post" && process.env.NODE_ENV === "production" ) {
|
// if (config.method.toLowerCase() === "post" && process.env.NODE_ENV === "production" ) {
|
||||||
// //如果已经转成字符串了,就不用再转了
|
// //如果已经转成字符串了,就不用再转了
|
||||||
|
@ -47,16 +47,16 @@ http.interceptors.request.use(
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
console.log(`【请求】${config.url}`, config)
|
console.log(`【请求】${config.url}`, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
return config
|
return config;
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
return Promise.reject(error)
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * 响应拦截
|
// * 响应拦截
|
||||||
|
@ -147,56 +147,56 @@ http.interceptors.request.use(
|
||||||
http.interceptors.response.use(
|
http.interceptors.response.use(
|
||||||
response => {
|
response => {
|
||||||
//开发环境下才可以打印日志
|
//开发环境下才可以打印日志
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
console.log(`【响应】${response.config.url}`, response)
|
console.log(`【响应】${response.config.url}`, response);
|
||||||
}
|
}
|
||||||
if (response.data && response.data.code == 401) {
|
if (response.data && response.data.code == 401) {
|
||||||
// 401, 权限未认证
|
// 401, 权限未认证
|
||||||
clearLoginInfo()
|
clearLoginInfo();
|
||||||
router.push({ name: 'login' })
|
router.push({ name: "login" });
|
||||||
return Promise.resolve(response)
|
return Promise.resolve(response);
|
||||||
} else if (response.data && response.data.code != 200) {
|
} else if (response.data && response.data.code != 200) {
|
||||||
// Message.closeAll();
|
// Message.closeAll();
|
||||||
Message({
|
Message({
|
||||||
message: response.data.msg || response.data.message,
|
message: response.data.msg || response.data.message,
|
||||||
type: 'error'
|
type: "error"
|
||||||
})
|
});
|
||||||
return Promise.reject(response)
|
return Promise.reject(response);
|
||||||
} else {
|
} else {
|
||||||
//请求成功的情况
|
//请求成功的情况
|
||||||
//如果是开发模式下,都要弹出
|
//如果是开发模式下,都要弹出
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
// Message.closeAll();
|
// Message.closeAll();
|
||||||
if (!response.config.hidemsg) {
|
if (!response.config.hidemsg) {
|
||||||
Message({
|
// Message({
|
||||||
message: response.data.msg || response.data.message,
|
// message: response.data.msg || response.data.message,
|
||||||
type: 'success'
|
// type: 'success'
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 生产环境下限制性弹出
|
// 生产环境下限制性弹出
|
||||||
else {
|
else {
|
||||||
if (
|
if (
|
||||||
response.data.msg != 'success' &&
|
response.data.msg != "success" &&
|
||||||
response.data.msg != '查询成功' &&
|
response.data.msg != "查询成功" &&
|
||||||
Object.prototype.toString.call(response.data) === '[object Object]'
|
Object.prototype.toString.call(response.data) === "[object Object]"
|
||||||
) {
|
) {
|
||||||
// Message.closeAll();
|
// Message.closeAll();
|
||||||
if (!response.config.hidemsg) {
|
if (!response.config.hidemsg) {
|
||||||
Message({
|
Message({
|
||||||
message: response.data.msg || response.data.message,
|
message: response.data.msg || response.data.message,
|
||||||
type: 'success'
|
type: "success"
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Promise.resolve(response)
|
return Promise.resolve(response);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
return Promise.reject(error)
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求地址处理
|
* 请求地址处理
|
||||||
|
@ -205,11 +205,11 @@ http.interceptors.response.use(
|
||||||
http.adornUrl = actionName => {
|
http.adornUrl = actionName => {
|
||||||
// 非生产环境 && 开启代理, 接口前缀统一使用[/proxyApi/]前缀做代理拦截!
|
// 非生产环境 && 开启代理, 接口前缀统一使用[/proxyApi/]前缀做代理拦截!
|
||||||
return (
|
return (
|
||||||
(process.env.NODE_ENV !== 'production' && process.env.OPEN_PROXY
|
(process.env.NODE_ENV !== "production" && process.env.OPEN_PROXY
|
||||||
? '/proxyApi/'
|
? "/proxyApi/"
|
||||||
: window.SITE_CONFIG.baseUrl) + actionName
|
: window.SITE_CONFIG.baseUrl) + actionName
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get请求参数处理
|
* get请求参数处理
|
||||||
|
@ -219,9 +219,9 @@ http.adornUrl = actionName => {
|
||||||
http.adornParams = (params = {}, openDefultParams = true) => {
|
http.adornParams = (params = {}, openDefultParams = true) => {
|
||||||
var defaults = {
|
var defaults = {
|
||||||
t: new Date().getTime()
|
t: new Date().getTime()
|
||||||
}
|
};
|
||||||
return openDefultParams ? merge(defaults, params) : params
|
return openDefultParams ? merge(defaults, params) : params;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* post请求数据处理
|
* post请求数据处理
|
||||||
|
@ -231,12 +231,12 @@ http.adornParams = (params = {}, openDefultParams = true) => {
|
||||||
* json: 'application/json; charset=utf-8'
|
* json: 'application/json; charset=utf-8'
|
||||||
* form: 'application/x-www-form-urlencoded; charset=utf-8'
|
* form: 'application/x-www-form-urlencoded; charset=utf-8'
|
||||||
*/
|
*/
|
||||||
http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => {
|
http.adornData = (data = {}, openDefultdata = true, contentType = "json") => {
|
||||||
var defaults = {
|
var defaults = {
|
||||||
t: new Date().getTime()
|
t: new Date().getTime()
|
||||||
}
|
};
|
||||||
data = openDefultdata ? merge(defaults, data) : data
|
data = openDefultdata ? merge(defaults, data) : data;
|
||||||
return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
|
return contentType === "json" ? JSON.stringify(data) : qs.stringify(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default http
|
export default http;
|
||||||
|
|
|
@ -951,7 +951,6 @@ export default {
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.level-detail {
|
.level-detail {
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
min-height: calc(100vh - 84px);
|
min-height: calc(100vh - 84px);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
>
|
>
|
||||||
<template slot="tableTop">
|
<template slot="tableTop">
|
||||||
<el-form :inline="true" :model="form" class="demo-form-inline">
|
<el-form :inline="true" :model="form" class="demo-form-inline">
|
||||||
<el-form-item v-if="storeList.length > 1" label="店铺">
|
<el-form-item v-if="storeList.length > 1" label="所属店铺">
|
||||||
<el-select v-model="formInline.shopId" placeholder="请选择店铺">
|
<el-select v-model="formInline.shopId" placeholder="请选择店铺">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in storeList"
|
v-for="item in storeList"
|
||||||
|
@ -22,40 +22,23 @@
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="用户ID">
|
|
||||||
<el-input
|
|
||||||
placeholder="请输入用户ID"
|
|
||||||
v-model="form.userId"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="用户昵称">
|
<el-form-item label="用户昵称">
|
||||||
<el-input
|
<el-input
|
||||||
placeholder="请输入用户昵称"
|
placeholder="请输入用户昵称"
|
||||||
v-model="form.username"
|
v-model="form.username"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="会员等级id">
|
<el-form-item label="会员等级">
|
||||||
<el-input
|
<el-select
|
||||||
placeholder="请输入会员等级id"
|
|
||||||
v-model="form.levelId"
|
v-model="form.levelId"
|
||||||
></el-input>
|
placeholder="请选择会员等级"
|
||||||
</el-form-item>
|
clearable
|
||||||
<el-form-item label="手机号">
|
>
|
||||||
<el-input
|
|
||||||
placeholder="请输入手机号"
|
|
||||||
v-model="form.mobile"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="会员状态">
|
|
||||||
<el-select v-model="form.isMemberUser" placeholder="请选择会员状态">
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in [
|
v-for="item in memberLevelList"
|
||||||
{ label: '是', value: 1 },
|
:key="item.levelId"
|
||||||
{ label: '否', value: 0 },
|
:label="item.levelName"
|
||||||
]"
|
:value="item.levelId"
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -90,31 +73,32 @@
|
||||||
<div class="stat-item">
|
<div class="stat-item">
|
||||||
<i style="font-size: 22px" class="el-icon-user-solid"></i>
|
<i style="font-size: 22px" class="el-icon-user-solid"></i>
|
||||||
<div class="stat-right">
|
<div class="stat-right">
|
||||||
<div class="stat-title">用户数量(人)</div>
|
|
||||||
<div class="stat-value">
|
<div class="stat-value">
|
||||||
<span style="font-size: 20px">{{
|
<span style="font-size: 20px">{{
|
||||||
overviewList.totalCount
|
overviewList.totalCount
|
||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stat-title">会员总数</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-item">
|
<div class="stat-item">
|
||||||
<i style="font-size: 22px" class="el-icon-s-custom"></i>
|
<i style="font-size: 22px" class="el-icon-s-custom"></i>
|
||||||
<div class="stat-right">
|
<div class="stat-right">
|
||||||
<div class="stat-title">今日新增(人)</div>
|
|
||||||
<div class="stat-value">
|
<div class="stat-value">
|
||||||
<span style="font-size: 20px">{{
|
<span style="font-size: 20px">{{
|
||||||
overviewList.todayCount
|
overviewList.todayCount
|
||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stat-title">今日新增</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2">
|
<!-- 测试按钮 -->
|
||||||
<el-button type="success" size="small" @click="userExport"
|
<!-- <div class="test-buttons" style="margin-bottom: 10px;">
|
||||||
>导出</el-button
|
<el-button type="success" size="small" @click="showTestDetail">
|
||||||
>
|
测试查看会员详情样式
|
||||||
</div>
|
</el-button>
|
||||||
|
</div> -->
|
||||||
</template>
|
</template>
|
||||||
</obj-table-plus>
|
</obj-table-plus>
|
||||||
<!-- 修改积分或成长值 -->
|
<!-- 修改积分或成长值 -->
|
||||||
|
@ -128,8 +112,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as XLSX from "xlsx";
|
|
||||||
import { saveAs } from "file-saver";
|
|
||||||
import modifyPoints from "./popup/modify-points.vue";
|
import modifyPoints from "./popup/modify-points.vue";
|
||||||
import viewDetails from "./popup/view-details.vue";
|
import viewDetails from "./popup/view-details.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
|
@ -141,7 +123,7 @@ export default {
|
||||||
formInline: {
|
formInline: {
|
||||||
marketId: "",
|
marketId: "",
|
||||||
shopId: "",
|
shopId: "",
|
||||||
unitType: "",
|
unitType: ""
|
||||||
},
|
},
|
||||||
form: {},
|
form: {},
|
||||||
tableProp: {
|
tableProp: {
|
||||||
|
@ -149,12 +131,13 @@ export default {
|
||||||
border: true,
|
border: true,
|
||||||
height: "auto",
|
height: "auto",
|
||||||
"row-id": "id",
|
"row-id": "id",
|
||||||
"show-overflow": false,
|
"show-overflow": false
|
||||||
},
|
},
|
||||||
productFilterType: "SALE",
|
productFilterType: "SALE",
|
||||||
selectList: [],
|
selectList: [],
|
||||||
value1: [],
|
value1: [],
|
||||||
overviewList: {},
|
overviewList: {},
|
||||||
|
memberLevelList: [] // 会员等级列表
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -164,45 +147,57 @@ export default {
|
||||||
? 3
|
? 3
|
||||||
: 2,
|
: 2,
|
||||||
marketId: this.marketId,
|
marketId: this.marketId,
|
||||||
shopId: this.shopId,
|
shopId: this.shopId
|
||||||
};
|
};
|
||||||
|
this.getMemberLevelList();
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.oTable.reload();
|
this.$refs.oTable.reload();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// getData() {
|
// 获取会员等级列表
|
||||||
// this.$api.mer_admin
|
getMemberLevelList() {
|
||||||
// .storeList({ marketId: this.formInline.marketId })
|
this.$api.marketing
|
||||||
// .then((res) => {
|
.marketingLevelPage({
|
||||||
// this.storeList = res.data.data;
|
...this.formInline
|
||||||
// this.formInline.shopId = res.data.data[0].shopId;
|
})
|
||||||
// this.$nextTick(() => {
|
.then(res => {
|
||||||
// this.$refs.oTable.reload();
|
if (res.data.code === 0) {
|
||||||
// });
|
this.memberLevelList = res.data.data || [];
|
||||||
// });
|
}
|
||||||
// },
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.memberLevelList = [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 手机号脱敏处理
|
||||||
|
maskMobile(mobile) {
|
||||||
|
if (!mobile || mobile.length !== 11) {
|
||||||
|
return mobile;
|
||||||
|
}
|
||||||
|
return mobile.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
|
||||||
|
},
|
||||||
queryList(pageNo, pageSize) {
|
queryList(pageNo, pageSize) {
|
||||||
this.$api.marketing
|
this.$api.marketing
|
||||||
.marketingUserPage({
|
.marketingUserPage({
|
||||||
pageNumber: pageNo,
|
pageNumber: pageNo,
|
||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
...this.formInline,
|
...this.formInline,
|
||||||
...this.form,
|
...this.form
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then(res => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
this.$refs.oTable.complete(
|
this.$refs.oTable.complete(
|
||||||
res.data.data.data,
|
res.data.data.data,
|
||||||
Number(res.data.data.total)
|
Number(res.data.data.total)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch(() => {
|
||||||
this.$refs.oTable.complete(false);
|
this.$refs.oTable.complete(false);
|
||||||
});
|
});
|
||||||
this.$api.marketing
|
this.$api.marketing
|
||||||
.overview({ ...this.formInline, ...this.form })
|
.overview({ ...this.formInline, ...this.form })
|
||||||
.then((res) => {
|
.then(res => {
|
||||||
this.overviewList = res.data.data;
|
this.overviewList = res.data.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -212,6 +207,27 @@ export default {
|
||||||
this.$refs.oTable.reload();
|
this.$refs.oTable.reload();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 测试查看会员详情样式
|
||||||
|
showTestDetail() {
|
||||||
|
// 模拟会员数据
|
||||||
|
const testMemberData = {
|
||||||
|
userId: "3",
|
||||||
|
username: "张三",
|
||||||
|
mobile: "13812341234",
|
||||||
|
birthday: "1990-05-15",
|
||||||
|
headUrl:
|
||||||
|
"https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png",
|
||||||
|
levelName: "LV2",
|
||||||
|
growthValue: 1250,
|
||||||
|
memberPoints: 890,
|
||||||
|
joinTime: "2023-01-15 10:30:00",
|
||||||
|
registrationTime: "2023-01-15 10:30:00",
|
||||||
|
id: 1 // 表示是会员
|
||||||
|
};
|
||||||
|
|
||||||
|
// 调用详情弹框
|
||||||
|
this.$refs.viewDetails.toggle(testMemberData).add();
|
||||||
|
},
|
||||||
changeTime(val) {
|
changeTime(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.form.startRegistrationTime = val[0];
|
this.form.startRegistrationTime = val[0];
|
||||||
|
@ -220,56 +236,24 @@ export default {
|
||||||
this.form.startRegistrationTime = "";
|
this.form.startRegistrationTime = "";
|
||||||
this.form.endRegistrationTime = "";
|
this.form.endRegistrationTime = "";
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
async userExport() {
|
|
||||||
let now = new Date();
|
|
||||||
let year = now.getFullYear();
|
|
||||||
let month = now.getMonth() + 1;
|
|
||||||
let day = now.getDate();
|
|
||||||
let res = await this.$api.marketing.marketingUserPage({
|
|
||||||
pageNumber: 1,
|
|
||||||
pageSize: 9999999,
|
|
||||||
...this.formInline,
|
|
||||||
...this.form,
|
|
||||||
});
|
|
||||||
console.log(res);
|
|
||||||
let userData = res.data.data.data.map((item) => {
|
|
||||||
return {
|
|
||||||
用户ID: item.userId,
|
|
||||||
用户头像: item.headUrl,
|
|
||||||
用户昵称: item.username,
|
|
||||||
手机号: item.mobile,
|
|
||||||
会员等级id: item.levelId,
|
|
||||||
会员等级名称: item.levelName,
|
|
||||||
生日: item.birthday,
|
|
||||||
注册时间: item.registrationTime,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const workbook = XLSX.utils.book_new();
|
|
||||||
const worksheet = XLSX.utils.json_to_sheet(userData);
|
|
||||||
|
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, "用户管理");
|
|
||||||
const excelData = XLSX.write(workbook, {
|
|
||||||
type: "array",
|
|
||||||
bookType: "xlsx",
|
|
||||||
});
|
|
||||||
const blob = new Blob([excelData], { type: "application/octet-stream" });
|
|
||||||
saveAs(blob, `用户管理-${year + "" + month + day}.xlsx`);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
tableCols() {
|
tableCols() {
|
||||||
return [
|
return [
|
||||||
{ type: "checkbox", width: "60px", fixed: "left" },
|
{ type: "checkbox", width: "60px", fixed: "left" },
|
||||||
// { type: "seq", width: "60px", align: "center", title: "序号" },
|
|
||||||
{
|
{
|
||||||
title: "用戶ID",
|
title: "所属店铺",
|
||||||
align: "center",
|
align: "center",
|
||||||
field: "userId",
|
field: "shopName"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "用戶头像",
|
title: "用户ID",
|
||||||
|
align: "center",
|
||||||
|
field: "userId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "用户头像",
|
||||||
align: "center",
|
align: "center",
|
||||||
field: "headUrl",
|
field: "headUrl",
|
||||||
type: "jsx",
|
type: "jsx",
|
||||||
|
@ -281,52 +265,60 @@ export default {
|
||||||
preview-src-list={[row.headUrl]}
|
preview-src-list={[row.headUrl]}
|
||||||
></el-image>
|
></el-image>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "用戶昵称",
|
title: "用户昵称",
|
||||||
align: "center",
|
align: "center",
|
||||||
field: "username",
|
field: "username"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "手机号",
|
title: "手机号",
|
||||||
align: "center",
|
align: "center",
|
||||||
field: "mobile",
|
field: "mobile",
|
||||||
},
|
type: "jsx",
|
||||||
// {
|
render: ({ row }) => {
|
||||||
// title: "进行中订单数",
|
return <span>{this.maskMobile(row.mobile)}</span>;
|
||||||
// align: "center",
|
}
|
||||||
// field: "name",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "完成订单数",
|
|
||||||
// align: "center",
|
|
||||||
// field: "name",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "消费金额(元)",
|
|
||||||
// align: "center",
|
|
||||||
// field: "name",
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
title: "会员等级id",
|
|
||||||
align: "center",
|
|
||||||
field: "levelId",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "会员等级名称",
|
title: "会员等级",
|
||||||
align: "center",
|
align: "center",
|
||||||
field: "levelName",
|
field: "levelName",
|
||||||
|
width: "120px",
|
||||||
|
type: "jsx",
|
||||||
|
render: ({ row }) => {
|
||||||
|
if (!row.levelName) {
|
||||||
|
return <span>-</span>;
|
||||||
|
}
|
||||||
|
// 根据等级名称设置不同颜色
|
||||||
|
const getTagType = levelName => {
|
||||||
|
if (levelName.includes("LV1") || levelName.includes("1"))
|
||||||
|
return "";
|
||||||
|
if (levelName.includes("LV2") || levelName.includes("2"))
|
||||||
|
return "success";
|
||||||
|
if (levelName.includes("LV3") || levelName.includes("3"))
|
||||||
|
return "warning";
|
||||||
|
if (levelName.includes("LV4") || levelName.includes("4"))
|
||||||
|
return "danger";
|
||||||
|
return "info";
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<el-tag type={getTagType(row.levelName)} size="small">
|
||||||
|
{row.levelName}
|
||||||
|
</el-tag>
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "生日",
|
title: "生日",
|
||||||
align: "center",
|
align: "center",
|
||||||
field: "birthday",
|
field: "birthday"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "注册时间",
|
title: "注册时间",
|
||||||
align: "center",
|
align: "center",
|
||||||
field: "registrationTime",
|
field: "registrationTime"
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// title: "限量",
|
// title: "限量",
|
||||||
|
@ -338,66 +330,28 @@ export default {
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
type: "jsx",
|
type: "jsx",
|
||||||
align: "center",
|
align: "center",
|
||||||
width: "280px",
|
width: "100px",
|
||||||
render: ({ row }) => {
|
render: ({ row }) => {
|
||||||
let viewDetails = () => {
|
let viewDetails = () => {
|
||||||
this.$api.marketing
|
this.$api.marketing
|
||||||
.memberUnitUserDetail({
|
.memberUnitUserDetail({
|
||||||
...this.formInline,
|
...this.formInline,
|
||||||
userId: row.userId,
|
userId: row.userId
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then(res => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
this.$refs.viewDetails.toggle(res.data.data).add();
|
this.$refs.viewDetails.toggle(res.data.data).add();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let points = () => {
|
|
||||||
this.$api.marketing
|
|
||||||
.memberUnitUserDetail({
|
|
||||||
...this.formInline,
|
|
||||||
userId: row.userId,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
console.log(res);
|
|
||||||
this.$refs.modifyPoints.toggle(res.data.data).add();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
let growthValue = () => {
|
|
||||||
this.$api.marketing
|
|
||||||
.memberUnitUserDetail({
|
|
||||||
...this.formInline,
|
|
||||||
userId: row.userId,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
console.log(res);
|
|
||||||
this.$refs.modifyPoints.toggle(res.data.data).update();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<el-button size="mini" type="primary" onClick={viewDetails}>
|
<el-button size="mini" type="primary" onClick={viewDetails}>
|
||||||
详情
|
详情
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
|
||||||
v-show={!row.id}
|
|
||||||
size="mini"
|
|
||||||
type="primary"
|
|
||||||
onClick={points}
|
|
||||||
>
|
|
||||||
修改积分
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-show={!row.id}
|
|
||||||
size="mini"
|
|
||||||
type="primary"
|
|
||||||
onClick={growthValue}
|
|
||||||
>
|
|
||||||
修改成长值
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
tableEvent() {
|
tableEvent() {
|
||||||
|
@ -407,7 +361,7 @@ export default {
|
||||||
},
|
},
|
||||||
"checkbox-change": ({ records, reserves }) => {
|
"checkbox-change": ({ records, reserves }) => {
|
||||||
this.selectList = [...records, ...reserves];
|
this.selectList = [...records, ...reserves];
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
...mapState("userData", [
|
...mapState("userData", [
|
||||||
|
@ -415,9 +369,9 @@ export default {
|
||||||
"marketList",
|
"marketList",
|
||||||
"storeList",
|
"storeList",
|
||||||
"marketId",
|
"marketId",
|
||||||
"shopId",
|
"shopId"
|
||||||
]),
|
])
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -433,7 +387,7 @@ export default {
|
||||||
}
|
}
|
||||||
.stat-item {
|
.stat-item {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
margin: 20px 20px;
|
margin: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
title="成长值详情"
|
||||||
|
:visible.sync="visible"
|
||||||
|
width="500px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<div class="detail-content">
|
||||||
|
<!-- 基础信息 -->
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">变化原因:</span>
|
||||||
|
<span class="value">{{ detailData.changeReason || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">变化时间:</span>
|
||||||
|
<span class="value">{{ detailData.changeTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">成长值增加:</span>
|
||||||
|
<span class="value growth-value" :style="{ color: getGrowthColor(detailData.growthChange) }">
|
||||||
|
{{ detailData.growthChange > 0 ? '+' : '' }}{{ detailData.growthChange || 0 }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 有关联订单时显示的字段 -->
|
||||||
|
<template v-if="hasRelatedOrder">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单编号:</span>
|
||||||
|
<span class="value">{{ detailData.relatedOrder || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单总金额:</span>
|
||||||
|
<span class="value">¥{{ detailData.orderAmount || '0.00' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单时间:</span>
|
||||||
|
<span class="value">{{ detailData.orderTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单归属摊位:</span>
|
||||||
|
<span class="value">{{ detailData.shopName || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">成长值变化:</span>
|
||||||
|
<span class="value growth-value" :style="{ color: getGrowthColor(detailData.growthChange) }">
|
||||||
|
{{ detailData.growthChange > 0 ? '+' : '' }}{{ detailData.growthChange || 0 }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 无关联订单时显示的描述 -->
|
||||||
|
<template v-if="!hasRelatedOrder && detailData.description">
|
||||||
|
<div class="description-section">
|
||||||
|
<div class="description-text">
|
||||||
|
{{ detailData.description }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "GrowthDetail",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
detailData: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasRelatedOrder() {
|
||||||
|
return this.detailData.relatedOrder && this.detailData.relatedOrder !== '-';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
show(data) {
|
||||||
|
this.detailData = data;
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.visible = false;
|
||||||
|
this.detailData = {};
|
||||||
|
},
|
||||||
|
getGrowthColor(value) {
|
||||||
|
return value > 0 ? '#67C23A' : '#F56C6C';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.detail-content {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 500;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #303133;
|
||||||
|
flex: 1;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.growth-value {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-section {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px dashed #e4e7ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-text {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
background: #f5f7fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 4px solid #409eff;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,168 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
title="积分详情"
|
||||||
|
:visible.sync="visible"
|
||||||
|
width="500px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<div class="detail-content">
|
||||||
|
<!-- 基础信息 -->
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">变化原因:</span>
|
||||||
|
<span class="value">{{ detailData.changeReason || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">变化时间:</span>
|
||||||
|
<span class="value">{{ detailData.changeTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">积分变动:</span>
|
||||||
|
<span class="value points-value" :style="{ color: getPointsColor(detailData.pointsChange) }">
|
||||||
|
{{ detailData.pointsChange > 0 ? '+' : '' }}{{ detailData.pointsChange || 0 }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 有关联订单时显示的字段 -->
|
||||||
|
<template v-if="hasRelatedOrder">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单编号:</span>
|
||||||
|
<span class="value">{{ detailData.relatedOrder || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单总金额:</span>
|
||||||
|
<span class="value">¥{{ detailData.orderAmount || '0.00' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单时间:</span>
|
||||||
|
<span class="value">{{ detailData.orderTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">订单归属摊位:</span>
|
||||||
|
<span class="value">{{ detailData.shopName || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 无关联订单且是使用积分时显示的字段 -->
|
||||||
|
<template v-if="!hasRelatedOrder && isPointsUsage">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">兑换商品:</span>
|
||||||
|
<span class="value">{{ detailData.exchangeProduct || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="label">兑换数量:</span>
|
||||||
|
<span class="value">{{ detailData.exchangeQuantity || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="description-section">
|
||||||
|
<div class="description-text">
|
||||||
|
{{ detailData.usageDescription || '使用积分兑换商品,兑换成功后积分将被扣除且不可退还。' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 无关联订单且是获得积分时显示的描述 -->
|
||||||
|
<template v-if="!hasRelatedOrder && !isPointsUsage && detailData.description">
|
||||||
|
<div class="description-section">
|
||||||
|
<div class="description-text">
|
||||||
|
{{ detailData.description }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "PointsDetail",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
detailData: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasRelatedOrder() {
|
||||||
|
return this.detailData.relatedOrder && this.detailData.relatedOrder !== '-';
|
||||||
|
},
|
||||||
|
isPointsUsage() {
|
||||||
|
return this.detailData.pointsChange < 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
show(data) {
|
||||||
|
this.detailData = data;
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.visible = false;
|
||||||
|
this.detailData = {};
|
||||||
|
},
|
||||||
|
getPointsColor(value) {
|
||||||
|
return value > 0 ? '#67C23A' : '#F56C6C';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.detail-content {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 500;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #303133;
|
||||||
|
flex: 1;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.points-value {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-section {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px dashed #e4e7ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-text {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
background: #f5f7fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 4px solid #409eff;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -9,55 +9,285 @@
|
||||||
:modalHandles="modalHandles"
|
:modalHandles="modalHandles"
|
||||||
>
|
>
|
||||||
<template slot="dialog__after">
|
<template slot="dialog__after">
|
||||||
<div style="padding: 20px">
|
<!-- 用户信息顶部展示 -->
|
||||||
<el-descriptions title="用户信息">
|
<div class="user-info-header">
|
||||||
<el-descriptions-item label="头像">
|
<div class="user-basic-info">
|
||||||
<el-image
|
<div class="info-row">
|
||||||
style="width: 60px; height: 60px"
|
<div class="info-item">
|
||||||
:src="modalData.headUrl"
|
<span class="label">会员姓名:</span>
|
||||||
:preview-src-list="[modalData.headUrl]"
|
<span class="value">{{ modalData.username || "-" }}</span>
|
||||||
>
|
|
||||||
</el-image>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="用户名">{{
|
|
||||||
modalData.username
|
|
||||||
}}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="ID">{{
|
|
||||||
modalData.userId
|
|
||||||
}}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="手机号">{{
|
|
||||||
modalData.mobile
|
|
||||||
}}</el-descriptions-item>
|
|
||||||
<!-- <el-descriptions-item label=""
|
|
||||||
>江苏省苏州市吴中区吴中大道 1188 号</el-descriptions-item
|
|
||||||
> -->
|
|
||||||
</el-descriptions>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="info-item">
|
||||||
v-if="modalData.id"
|
<span class="label">系统编号:</span>
|
||||||
style="margin-top: 20px; border-top: 1px solid #ccc; padding: 20px"
|
<span class="value">{{ modalData.userId || "-" }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">手机号:</span>
|
||||||
|
<span class="value">{{ maskMobile(modalData.mobile) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">生日:</span>
|
||||||
|
<span class="value">{{ modalData.birthday || "-" }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="user-stats">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-number">{{ modalData.growthValue || 0 }}</div>
|
||||||
|
<div class="stat-label">会员成长值</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-number">{{ modalData.memberPoints || 0 }}</div>
|
||||||
|
<div class="stat-label">会员积分</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-number">{{ couponCount }}</div>
|
||||||
|
<div class="stat-label">会员优惠券</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tab分页内容 -->
|
||||||
|
<div class="tab-content">
|
||||||
|
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||||
|
<el-tab-pane label="会员成长值明细" name="growth">
|
||||||
|
<el-table
|
||||||
|
:data="growthList"
|
||||||
|
border
|
||||||
|
style="width: 100%"
|
||||||
|
v-loading="growthLoading"
|
||||||
>
|
>
|
||||||
<el-descriptions title="会员信息">
|
<el-table-column
|
||||||
<el-descriptions-item label="会员名称">{{
|
prop="changeTime"
|
||||||
modalData.levelName
|
label="变化时间"
|
||||||
}}</el-descriptions-item>
|
width="180"
|
||||||
<el-descriptions-item label="生日">{{
|
align="center"
|
||||||
modalData.birthday
|
>
|
||||||
}}</el-descriptions-item>
|
</el-table-column>
|
||||||
<el-descriptions-item label="加入会员时间">{{
|
<el-table-column
|
||||||
modalData.joinTime
|
prop="growthChange"
|
||||||
}}</el-descriptions-item>
|
label="成长值变动"
|
||||||
</el-descriptions>
|
width="120"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span
|
||||||
|
:style="{
|
||||||
|
color:
|
||||||
|
scope.row.growthChange > 0 ? '#67C23A' : '#F56C6C'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ scope.row.growthChange > 0 ? "+" : ""
|
||||||
|
}}{{ scope.row.growthChange }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="relatedOrder"
|
||||||
|
label="关联订单"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="详情" width="100" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
@click="viewGrowthDetail(scope.row)"
|
||||||
|
>
|
||||||
|
查看详情
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleGrowthSizeChange"
|
||||||
|
@current-change="handleGrowthCurrentChange"
|
||||||
|
:current-page="growthPagination.currentPage"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:page-size="growthPagination.pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="growthPagination.total"
|
||||||
|
style="margin-top: 20px; text-align: center"
|
||||||
|
>
|
||||||
|
</el-pagination>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="会员积分明细" name="points">
|
||||||
|
<el-table
|
||||||
|
:data="pointsList"
|
||||||
|
border
|
||||||
|
style="width: 100%"
|
||||||
|
v-loading="pointsLoading"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
prop="changeTime"
|
||||||
|
label="变化时间"
|
||||||
|
width="180"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="pointsChange"
|
||||||
|
label="积分变动"
|
||||||
|
width="120"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span
|
||||||
|
:style="{
|
||||||
|
color:
|
||||||
|
scope.row.pointsChange > 0 ? '#67C23A' : '#F56C6C'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ scope.row.pointsChange > 0 ? "+" : ""
|
||||||
|
}}{{ scope.row.pointsChange }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="changeType"
|
||||||
|
label="变动类型"
|
||||||
|
width="120"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="relatedOrder"
|
||||||
|
label="关联订单"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="详情" width="100" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
@click="viewPointsDetail(scope.row)"
|
||||||
|
>
|
||||||
|
查看详情
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handlePointsSizeChange"
|
||||||
|
@current-change="handlePointsCurrentChange"
|
||||||
|
:current-page="pointsPagination.currentPage"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:page-size="pointsPagination.pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="pointsPagination.total"
|
||||||
|
style="margin-top: 20px; text-align: center"
|
||||||
|
>
|
||||||
|
</el-pagination>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="会员优惠券" name="coupons">
|
||||||
|
<el-table
|
||||||
|
:data="couponsList"
|
||||||
|
border
|
||||||
|
style="width: 100%"
|
||||||
|
v-loading="couponsLoading"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
prop="couponName"
|
||||||
|
label="优惠券名称"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="couponType"
|
||||||
|
label="类型"
|
||||||
|
width="100"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="faceValue"
|
||||||
|
label="面额"
|
||||||
|
width="100"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.couponType === '折扣券'"
|
||||||
|
>{{ scope.row.faceValue }}折</span
|
||||||
|
>
|
||||||
|
<span v-else>¥{{ scope.row.faceValue }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="useCondition"
|
||||||
|
label="使用条件"
|
||||||
|
width="120"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="receiveTime"
|
||||||
|
label="获得时间"
|
||||||
|
width="180"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="validPeriod"
|
||||||
|
label="有效期"
|
||||||
|
width="180"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="useStatus"
|
||||||
|
label="使用状态"
|
||||||
|
width="100"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag
|
||||||
|
:type="getStatusTagType(scope.row.useStatus)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{ scope.row.useStatus }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleCouponsSizeChange"
|
||||||
|
@current-change="handleCouponsCurrentChange"
|
||||||
|
:current-page="couponsPagination.currentPage"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:page-size="couponsPagination.pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="couponsPagination.total"
|
||||||
|
style="margin-top: 20px; text-align: center"
|
||||||
|
>
|
||||||
|
</el-pagination>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</obj-modal>
|
</obj-modal>
|
||||||
|
|
||||||
|
<!-- 成长值详情弹框 -->
|
||||||
|
<growth-detail ref="growthDetail"></growth-detail>
|
||||||
|
|
||||||
|
<!-- 积分详情弹框 -->
|
||||||
|
<points-detail ref="pointsDetail"></points-detail>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { debounce, cloneDeep } from "lodash";
|
import { cloneDeep } from "lodash";
|
||||||
import { Divider } from "element-ui";
|
import GrowthDetail from "./growth-detail.vue";
|
||||||
|
import PointsDetail from "./points-detail.vue";
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {
|
||||||
|
GrowthDetail,
|
||||||
|
PointsDetail
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isAdd: true,
|
isAdd: true,
|
||||||
|
@ -65,9 +295,36 @@ export default {
|
||||||
modalConfig: {
|
modalConfig: {
|
||||||
title: "用户详情",
|
title: "用户详情",
|
||||||
show: false,
|
show: false,
|
||||||
width: "60%",
|
width: "80%"
|
||||||
},
|
},
|
||||||
modalData: {},
|
modalData: {},
|
||||||
|
// Tab相关数据
|
||||||
|
activeTab: "growth",
|
||||||
|
couponCount: 0,
|
||||||
|
// 成长值明细
|
||||||
|
growthList: [],
|
||||||
|
growthLoading: false,
|
||||||
|
growthPagination: {
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
},
|
||||||
|
// 积分明细
|
||||||
|
pointsList: [],
|
||||||
|
pointsLoading: false,
|
||||||
|
pointsPagination: {
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
},
|
||||||
|
// 优惠券
|
||||||
|
couponsList: [],
|
||||||
|
couponsLoading: false,
|
||||||
|
couponsPagination: {
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -78,10 +335,17 @@ export default {
|
||||||
this.$refs.modal.resetFields();
|
this.$refs.modal.resetFields();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
queryTableData(pageNo, pageSize) {},
|
// 手机号脱敏处理
|
||||||
|
maskMobile(mobile) {
|
||||||
|
if (!mobile || mobile.length !== 11) {
|
||||||
|
return mobile;
|
||||||
|
}
|
||||||
|
return mobile.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
|
||||||
|
},
|
||||||
|
queryTableData() {},
|
||||||
toggle(e) {
|
toggle(e) {
|
||||||
if (this.modalConfig.show == false) {
|
if (this.modalConfig.show == false) {
|
||||||
this.modalConfig.show = true;
|
this.modalConfig.show = true;
|
||||||
|
@ -98,12 +362,222 @@ export default {
|
||||||
},
|
},
|
||||||
update: () => {
|
update: () => {
|
||||||
this.isAdd = false;
|
this.isAdd = false;
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
init(row) {
|
init(row) {
|
||||||
this.modalData = row;
|
this.modalData = row;
|
||||||
|
this.loadTabData();
|
||||||
},
|
},
|
||||||
|
// Tab切换处理
|
||||||
|
handleTabClick(tab) {
|
||||||
|
this.activeTab = tab.name;
|
||||||
|
this.loadTabData();
|
||||||
|
},
|
||||||
|
// 加载Tab数据
|
||||||
|
loadTabData() {
|
||||||
|
switch (this.activeTab) {
|
||||||
|
case "growth":
|
||||||
|
this.loadGrowthData();
|
||||||
|
break;
|
||||||
|
case "points":
|
||||||
|
this.loadPointsData();
|
||||||
|
break;
|
||||||
|
case "coupons":
|
||||||
|
this.loadCouponsData();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 加载成长值明细数据
|
||||||
|
loadGrowthData() {
|
||||||
|
this.growthLoading = true;
|
||||||
|
// 模拟数据,实际应该调用API
|
||||||
|
setTimeout(() => {
|
||||||
|
this.growthList = [
|
||||||
|
{
|
||||||
|
changeTime: "2025-07-24 17:20",
|
||||||
|
growthChange: 35,
|
||||||
|
relatedOrder: "ORD9296",
|
||||||
|
changeReason: "订单消费",
|
||||||
|
orderAmount: "89.99",
|
||||||
|
orderTime: "2025-07-24 17:20",
|
||||||
|
shopName: "美食餐厅"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
changeTime: "2025-07-12 17:20",
|
||||||
|
growthChange: 100,
|
||||||
|
relatedOrder: "-",
|
||||||
|
changeReason: "活动奖励",
|
||||||
|
description: "参与平台活动获得的成长值奖励"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
changeTime: "2024-01-05 16:45:33",
|
||||||
|
growthChange: 30,
|
||||||
|
relatedOrder: "ORDER202401503",
|
||||||
|
changeReason: "订单消费",
|
||||||
|
orderAmount: "65.50",
|
||||||
|
orderTime: "2024-01-05 16:45:33",
|
||||||
|
shopName: "便利超市"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
this.growthPagination.total = 3;
|
||||||
|
this.growthLoading = false;
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
// 加载积分明细数据
|
||||||
|
loadPointsData() {
|
||||||
|
this.pointsLoading = true;
|
||||||
|
// 模拟数据,实际应该调用API
|
||||||
|
setTimeout(() => {
|
||||||
|
this.pointsList = [
|
||||||
|
{
|
||||||
|
changeTime: "2025-07-24 17:20",
|
||||||
|
pointsChange: 25,
|
||||||
|
changeType: "订单消费",
|
||||||
|
relatedOrder: "ORD9296",
|
||||||
|
changeReason: "订单消费",
|
||||||
|
orderAmount: "78.30",
|
||||||
|
orderTime: "2025-07-24 17:20",
|
||||||
|
shopName: "运动健身店"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
changeTime: "2025-07-20 15:30",
|
||||||
|
pointsChange: -50,
|
||||||
|
changeType: "兑换商品",
|
||||||
|
relatedOrder: "-",
|
||||||
|
changeReason: "兑换商品",
|
||||||
|
exchangeProduct: "精美水杯",
|
||||||
|
exchangeQuantity: "1个",
|
||||||
|
usageDescription:
|
||||||
|
"使用50积分兑换商品,兑换成功后积分将被扣除且不可退还。"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
changeTime: "2025-07-12 17:20",
|
||||||
|
pointsChange: 80,
|
||||||
|
changeType: "完成任务",
|
||||||
|
relatedOrder: "-",
|
||||||
|
changeReason: "完成任务",
|
||||||
|
description: "完成平台指定任务获得的积分奖励"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
changeTime: "2024-01-08 15:45:30",
|
||||||
|
pointsChange: 10,
|
||||||
|
changeType: "签到奖励",
|
||||||
|
relatedOrder: "-",
|
||||||
|
changeReason: "签到奖励",
|
||||||
|
description: "每日签到获得的积分奖励"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
this.pointsPagination.total = 4;
|
||||||
|
this.pointsLoading = false;
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
// 加载优惠券数据
|
||||||
|
loadCouponsData() {
|
||||||
|
this.couponsLoading = true;
|
||||||
|
// 模拟数据,实际应该调用API
|
||||||
|
setTimeout(() => {
|
||||||
|
this.couponsList = [
|
||||||
|
{
|
||||||
|
couponName: "新用户专享券",
|
||||||
|
couponType: "满减券",
|
||||||
|
faceValue: 20,
|
||||||
|
useCondition: "满100元可用",
|
||||||
|
receiveTime: "2024-01-01 10:00:00",
|
||||||
|
validPeriod: "2024-02-01",
|
||||||
|
useStatus: "可使用"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
couponName: "生日特惠券",
|
||||||
|
couponType: "折扣券",
|
||||||
|
faceValue: 9,
|
||||||
|
useCondition: "全品类可用",
|
||||||
|
receiveTime: "2024-01-05 12:30:15",
|
||||||
|
validPeriod: "2024-02-05",
|
||||||
|
useStatus: "可使用"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
couponName: "积分兑换券",
|
||||||
|
couponType: "满减券",
|
||||||
|
faceValue: 50,
|
||||||
|
useCondition: "满300元可用",
|
||||||
|
receiveTime: "2024-01-10 16:20:30",
|
||||||
|
validPeriod: "2024-03-10",
|
||||||
|
useStatus: "可使用"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
couponName: "限时抢购券",
|
||||||
|
couponType: "满减券",
|
||||||
|
faceValue: 10,
|
||||||
|
useCondition: "满50元可用",
|
||||||
|
receiveTime: "2023-12-20 14:15:20",
|
||||||
|
validPeriod: "2024-01-20",
|
||||||
|
useStatus: "已过期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
couponName: "会员专属券",
|
||||||
|
couponType: "满减券",
|
||||||
|
faceValue: 30,
|
||||||
|
useCondition: "满200元可用",
|
||||||
|
receiveTime: "2023-12-15 09:45:10",
|
||||||
|
validPeriod: "2024-01-15",
|
||||||
|
useStatus: "已使用"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
this.couponsPagination.total = 5;
|
||||||
|
this.couponCount = this.couponsList.filter(
|
||||||
|
item => item.useStatus === "可使用"
|
||||||
|
).length;
|
||||||
|
this.couponsLoading = false;
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
// 成长值分页处理
|
||||||
|
handleGrowthSizeChange(val) {
|
||||||
|
this.growthPagination.pageSize = val;
|
||||||
|
this.loadGrowthData();
|
||||||
|
},
|
||||||
|
handleGrowthCurrentChange(val) {
|
||||||
|
this.growthPagination.currentPage = val;
|
||||||
|
this.loadGrowthData();
|
||||||
|
},
|
||||||
|
// 积分分页处理
|
||||||
|
handlePointsSizeChange(val) {
|
||||||
|
this.pointsPagination.pageSize = val;
|
||||||
|
this.loadPointsData();
|
||||||
|
},
|
||||||
|
handlePointsCurrentChange(val) {
|
||||||
|
this.pointsPagination.currentPage = val;
|
||||||
|
this.loadPointsData();
|
||||||
|
},
|
||||||
|
// 优惠券分页处理
|
||||||
|
handleCouponsSizeChange(val) {
|
||||||
|
this.couponsPagination.pageSize = val;
|
||||||
|
this.loadCouponsData();
|
||||||
|
},
|
||||||
|
handleCouponsCurrentChange(val) {
|
||||||
|
this.couponsPagination.currentPage = val;
|
||||||
|
this.loadCouponsData();
|
||||||
|
},
|
||||||
|
// 查看详情方法
|
||||||
|
viewGrowthDetail(row) {
|
||||||
|
this.$refs.growthDetail.show(row);
|
||||||
|
},
|
||||||
|
viewPointsDetail(row) {
|
||||||
|
this.$refs.pointsDetail.show(row);
|
||||||
|
},
|
||||||
|
// 获取状态标签类型
|
||||||
|
getStatusTagType(status) {
|
||||||
|
switch (status) {
|
||||||
|
case "可使用":
|
||||||
|
return "success";
|
||||||
|
case "已使用":
|
||||||
|
return "info";
|
||||||
|
case "已过期":
|
||||||
|
return "danger";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
modalCols() {
|
modalCols() {
|
||||||
|
@ -112,30 +586,70 @@ export default {
|
||||||
modalHandles() {
|
modalHandles() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: "取消",
|
label: "关闭",
|
||||||
handle: () => {
|
handle: () => {
|
||||||
this.toggle();
|
this.toggle();
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
{
|
|
||||||
label: this.isAdd ? "确认添加" : "确认",
|
|
||||||
type: "primary",
|
|
||||||
loading: this.isLoading,
|
|
||||||
submit: true,
|
|
||||||
handle: () => {
|
|
||||||
console.log(JSON.parse(JSON.stringify(this.modalData)));
|
|
||||||
this.$emit(
|
|
||||||
"addCouponData",
|
|
||||||
JSON.parse(JSON.stringify(this.modalData))
|
|
||||||
);
|
|
||||||
this.toggle();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
asyncComputed: {}
|
||||||
asyncComputed: {},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.user-info-header {
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-basic-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #303133;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-stats {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
text-align: center;
|
||||||
|
padding: 15px 20px;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-number {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #409eff;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -0,0 +1,160 @@
|
||||||
|
<template>
|
||||||
|
<div class="test-page">
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>会员详情弹框样式测试页面</h2>
|
||||||
|
<p>点击下面的按钮查看不同会员数据的详情弹框效果</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-buttons">
|
||||||
|
<el-button type="primary" @click="showMemberDetail1">
|
||||||
|
查看会员详情 - 张三 (LV2会员)
|
||||||
|
</el-button>
|
||||||
|
<el-button type="success" @click="showMemberDetail2">
|
||||||
|
查看会员详情 - 李四 (LV3会员)
|
||||||
|
</el-button>
|
||||||
|
<el-button type="warning" @click="showMemberDetail3">
|
||||||
|
查看会员详情 - 王五 (LV1会员)
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-list">
|
||||||
|
<h3>功能特点说明:</h3>
|
||||||
|
<ul>
|
||||||
|
<li>✅ 用户信息顶部展示:会员姓名、系统编号、手机号(脱敏)、生日</li>
|
||||||
|
<li>✅ 右侧统计卡片:会员成长值、会员积分、会员优惠券数量</li>
|
||||||
|
<li>✅ 三个Tab分页:会员成长值明细、会员积分明细、会员优惠券</li>
|
||||||
|
<li>✅ 成长值明细:变化时间、成长值变动(带颜色)、关联订单、查看详情</li>
|
||||||
|
<li>✅ 积分明细:变化时间、积分变动(带颜色)、变动类型、关联订单、查看详情</li>
|
||||||
|
<li>✅ 优惠券列表:名称、类型、面额、使用条件、获得时间、有效期、使用状态(Tag)</li>
|
||||||
|
<li>✅ 完整的分页功能</li>
|
||||||
|
<li>✅ 响应式布局和美观的样式</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 会员详情弹框组件 -->
|
||||||
|
<viewDetails ref="viewDetails"></viewDetails>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import viewDetails from "./modules/marketing/user/popup/view-details.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestMemberDetail",
|
||||||
|
components: {
|
||||||
|
viewDetails
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 测试会员1 - 张三
|
||||||
|
showMemberDetail1() {
|
||||||
|
const testMemberData = {
|
||||||
|
userId: "3",
|
||||||
|
username: "张三",
|
||||||
|
mobile: "13812341234",
|
||||||
|
birthday: "1990-05-15",
|
||||||
|
headUrl: "https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png",
|
||||||
|
levelName: "LV2",
|
||||||
|
growthValue: 1250,
|
||||||
|
memberPoints: 890,
|
||||||
|
joinTime: "2023-01-15 10:30:00",
|
||||||
|
registrationTime: "2023-01-15 10:30:00",
|
||||||
|
id: 1
|
||||||
|
};
|
||||||
|
this.$refs.viewDetails.toggle(testMemberData).add();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 测试会员2 - 李四
|
||||||
|
showMemberDetail2() {
|
||||||
|
const testMemberData = {
|
||||||
|
userId: "15",
|
||||||
|
username: "李四",
|
||||||
|
mobile: "15987654321",
|
||||||
|
birthday: "1985-12-20",
|
||||||
|
headUrl: "https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png",
|
||||||
|
levelName: "LV3",
|
||||||
|
growthValue: 2800,
|
||||||
|
memberPoints: 1560,
|
||||||
|
joinTime: "2022-08-10 14:20:00",
|
||||||
|
registrationTime: "2022-08-10 14:20:00",
|
||||||
|
id: 2
|
||||||
|
};
|
||||||
|
this.$refs.viewDetails.toggle(testMemberData).add();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 测试会员3 - 王五
|
||||||
|
showMemberDetail3() {
|
||||||
|
const testMemberData = {
|
||||||
|
userId: "28",
|
||||||
|
username: "王五",
|
||||||
|
mobile: "18666888999",
|
||||||
|
birthday: "1995-03-08",
|
||||||
|
headUrl: "https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png",
|
||||||
|
levelName: "LV1",
|
||||||
|
growthValue: 350,
|
||||||
|
memberPoints: 120,
|
||||||
|
joinTime: "2024-01-05 09:15:00",
|
||||||
|
registrationTime: "2024-01-05 09:15:00",
|
||||||
|
id: 3
|
||||||
|
};
|
||||||
|
this.$refs.viewDetails.toggle(testMemberData).add();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.test-page {
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-buttons {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin: 0 10px 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-list {
|
||||||
|
background: #f5f7fa;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue