improve: 后台用户编辑

This commit is contained in:
From-wh 2023-03-06 15:44:15 +08:00
parent dfbe4047f9
commit 29d49573b5
5 changed files with 714 additions and 65 deletions

View File

@ -1,8 +1,8 @@
<template>
<div style="width: 100%">
<Drawer title="用户详情" :closable="false" width="900" scrollable v-model="modals">
<Drawer title="用户详情" :closable="false" width="1100" scrollable v-model="modals" @on-visible-change="draChange">
<Spin size="large" fix v-if="spinShow"></Spin>
<div class="acea-row">
<div class="acea-row head">
<div class="avatar mr15"><img :src="psInfo.avatar" /></div>
<div class="dashboard-workplace-header-tip">
<p class="dashboard-workplace-header-tip-title" v-text="psInfo.nickname || '-'"></p>
@ -12,6 +12,11 @@
}}</span>
</div>
</div>
<div class="edit-btn">
<Button v-if="!isEdit" type="primary" @click="edit">编辑</Button>
<Button v-if="isEdit" class="mr20" @click="edit">取消</Button>
<Button v-if="isEdit" type="primary" @click="editSave">保存</Button>
</div>
</div>
<Row type="flex" justify="space-between" class="mt25">
@ -29,31 +34,37 @@
</Col>
<Col span="24">
<Table
:columns="columns"
:data="userLists"
max-height="400"
ref="table"
:loading="loading"
no-userFrom-text="暂无数据"
no-filtered-userFrom-text="暂无筛选结果"
>
<template slot-scope="{ row }" slot="number">
<div :class="row.pm ? 'plusColor' : 'reduceColor'">
{{ row.pm ? '+' + row.number : '-' + row.number }}
</div>
</template>
</Table>
<div class="acea-row row-right page">
<Page
:total="total"
:current="userFrom.page"
show-elevator
show-total
@on-change="pageChange"
:page-size="userFrom.limit"
/>
</div>
<template v-if="activeName === 'user'">
<userEditForm ref="editForm" :userId="userId" @success="getDetails(userId)" v-if="isEdit"></userEditForm>
<user-info :ps-info="psInfo" v-else></user-info>
</template>
<template v-else>
<Table
:columns="columns"
:data="userLists"
max-height="400"
ref="table"
:loading="loading"
no-userFrom-text="暂无数据"
no-filtered-userFrom-text="暂无筛选结果"
>
<template slot-scope="{ row }" slot="number">
<div :class="row.pm ? 'plusColor' : 'reduceColor'">
{{ row.pm ? '+' + row.number : '-' + row.number }}
</div>
</template>
</Table>
<div class="acea-row row-right page">
<Page
:total="total"
:current="userFrom.page"
show-elevator
show-total
@on-change="pageChange"
:page-size="userFrom.limit"
/>
</div>
</template>
</Col>
</Row>
</Drawer>
@ -62,13 +73,18 @@
<script>
import { detailsApi, infoApi } from '@/api/user';
import userInfo from './userInfo';
import userEditForm from './userEditForm';
export default {
name: 'userDetails',
components: { userInfo, userEditForm },
data() {
return {
isEdit: false,
theme2: 'light',
list: [
{ val: 'user', label: '用户信息' },
{ val: 'order', label: '消费记录' },
{ val: 'integral', label: '积分明细' },
{ val: 'sign', label: '签到记录' },
@ -90,23 +106,36 @@ export default {
columns: [],
userLists: [],
psInfo: {},
activeName: 'order',
activeName: 'user',
};
},
created() {},
methods: {
edit() {
this.isEdit = !this.isEdit;
},
editSave() {
this.$refs.editForm.setUser();
},
draChange(status) {
console.log(status);
if (!status) {
this.isEdit = false;
}
},
// 会员详情
getDetails(id) {
this.activeName = 'order';
this.activeName = 'user';
this.userId = id;
this.spinShow = true;
this.isEdit = false;
detailsApi(id)
.then(async (res) => {
if (res.status === 200) {
let data = res.data;
this.detailsData = data.headerList;
this.psInfo = data.ps_info;
this.changeType('order');
// this.changeType('user');
this.spinShow = false;
} else {
this.spinShow = false;
@ -127,6 +156,8 @@ export default {
this.loading = true;
this.userFrom.type = name;
this.activeName = name;
this.isEdit = false;
if (name == 'user') return;
if (this.userFrom.type === '') {
this.userFrom.type = 'order';
}
@ -326,6 +357,16 @@ export default {
height: 100%;
}
}
.head {
position: relative;
.edit-btn {
position: absolute;
right: 10px;
top: 0px;
display: flex;
align-items: center;
}
}
.dashboard-workplace {
&-header {
&-avatar {

View File

@ -146,9 +146,6 @@ export default {
return {
modals: false,
labelShow: false,
orderStatus: 0,
total_num: 0,
splitSwitch: true,
formItem: {
uid: 0,
real_name: '',
@ -166,12 +163,6 @@ export default {
is_promoter: 0,
status: 1,
},
express: [],
expressTemp: [],
deliveryList: [],
temp: {},
export_open: true,
manyFormValidate: [],
groupInfo: [],
labelInfo: [],
levelInfo: [],

View File

@ -0,0 +1,422 @@
<template>
<div class="user-info">
<Form ref="formItem" :rules="ruleValidate" :model="formItem" :label-width="100" @submit.native.prevent>
<div class="section">
<div class="section-hd">基本信息</div>
<div class="section-bd">
<div class="item">
<FormItem label="用户ID:">
<Input class="form-sty" disabled v-model="formItem.uid" placeholder="请输入编号"></Input>
</FormItem>
</div>
<div class="item">
<FormItem label="真实姓名:" prop="real_name">
<Input class="form-sty" v-model.trim="formItem.real_name" placeholder="请输入真实姓名"></Input>
</FormItem>
</div>
<div class="item">
<FormItem label="手机号码:" prop="phone">
<Input class="form-sty" v-model="formItem.phone" placeholder="请输入手机号码"></Input>
</FormItem>
</div>
<div class="item">
<FormItem label="生日:">
<DatePicker
class="form-sty"
type="date"
:value="formItem.birthday"
placeholder="请选择生日"
format="yyyy-MM-dd"
@on-change="formItem.birthday = $event"
></DatePicker>
</FormItem>
</div>
<div class="item">
<FormItem label="身份证号:">
<Input class="form-sty" v-model.trim="formItem.card_id" placeholder="请输入身份证号"></Input>
</FormItem>
</div>
<div class="item">
<FormItem label="用户地址:">
<Input class="form-sty" v-model="formItem.addres" placeholder="请输入用户地址"></Input>
</FormItem>
</div>
</div>
</div>
<div class="section">
<div class="section-hd">密码</div>
<div class="section-bd">
<div class="item">
<FormItem label="登录密码:" prop="pwd">
<Input
class="form-sty"
type="password"
v-model="formItem.pwd"
placeholder="请输入登录密码(修改用户可不填写,不填写不修改原密码)"
></Input>
</FormItem>
</div>
<div class="item">
<FormItem label="确认密码:" prop="true_pwd">
<Input
class="form-sty"
type="password"
v-model="formItem.true_pwd"
placeholder="请输入确认密码(修改用户可不填写,不填写不修改原密码)"
></Input>
</FormItem>
</div>
</div>
</div>
<div class="section">
<div class="section-hd">用户概况</div>
<div class="section-bd">
<div class="item">
<FormItem label="用户等级:">
<Select v-model="formItem.level" class="form-sty" clearable>
<Option v-for="(item, index) in infoData.levelInfo" :key="index" :value="item.id">{{
item.name
}}</Option>
</Select>
</FormItem>
</div>
<div class="item">
<FormItem label="用户分组:">
<Select v-model="formItem.group_id" class="form-sty" clearable>
<Option v-for="(item, index) in infoData.groupInfo" :key="index" :value="item.id">{{
item.group_name
}}</Option>
</Select>
</FormItem>
</div>
<div class="item lang">
<FormItem label="用户标签:">
<div style="display: flex">
<div class="labelInput acea-row row-between-wrapper" @click="openLabel">
<div style="width: 90%">
<div v-if="dataLabel.length">
<Tag closable v-for="(item, index) in dataLabel" :key="index" @on-close="closeLabel(item)">{{
item.label_name
}}</Tag>
</div>
<span class="span" v-else>选择用户关联标签</span>
</div>
<div class="ivu-icon ivu-icon-ios-arrow-down"></div>
</div>
<span class="addfont" @click="addLabel">新增标签</span>
</div>
</FormItem>
</div>
<div class="item lang">
<FormItem label="推广资格:">
<RadioGroup v-model="formItem.spread_open" class="form-sty">
<Radio :label="1">开启</Radio>
<Radio :label="0">关闭</Radio>
</RadioGroup>
<div class="tip">关闭用户的推广资格后,在任何分销模式下该用户都无分销权限</div>
</FormItem>
</div>
<div class="item lang">
<FormItem label="推广权限:">
<RadioGroup v-model="formItem.is_promoter" class="form-sty">
<Radio :label="1">开启</Radio>
<Radio :label="0">关闭</Radio>
<div class="tip">指定分销模式下,开启或关闭用户的推广权限</div>
</RadioGroup>
</FormItem>
</div>
<div class="item lang">
<FormItem label="用户状态:">
<RadioGroup v-model="formItem.status" class="form-sty">
<Radio :label="1">开启</Radio>
<Radio :label="0">锁定</Radio>
</RadioGroup>
</FormItem>
</div>
</div>
</div>
<div class="section">
<div class="section-hd">用户备注</div>
<div class="section-bd">
<FormItem label="用户备注:">
<Input class="form-sty" v-model="formItem.mark" placeholder="请输入用户备注"></Input>
</FormItem>
</div>
</div>
</Form>
<Modal v-model="labelShow" scrollable title="请选择用户标签" :closable="false" width="500" :footer-hide="true">
<userLabel
v-if="labelShow"
:only_get="true"
:uid="formItem.uid"
@close="labelClose"
@activeData="activeData"
></userLabel>
</Modal>
</div>
</template>
<script>
import userLabel from '@/components/userLabel';
import { userLabelAddApi, getUserInfo, editUser, setUser } from '@/api/user';
import dayjs from 'dayjs';
export default {
name: 'userInfo',
components: { userLabel },
props: {
userId: {
type: Number,
default: 0,
},
},
filters: {
timeFormat(value) {
if (!value) {
return '-';
}
return dayjs(value * 1000).format('YYYY-MM-DD HH:mm:ss');
},
gender(value) {
if (value == 1) {
return '男';
} else if (value == 2) {
return '女';
} else {
return '未知';
}
},
},
data() {
return {
labelShow: false,
formItem: {
uid: 0,
real_name: '',
phone: '',
birthday: '',
card_id: '',
addres: '',
mark: '',
pwd: '',
true_pwd: '',
level: '',
group_id: '',
label_id: [],
spread_open: 0,
is_promoter: 0,
status: 1,
},
groupInfo: [],
labelInfo: [],
levelInfo: [],
infoData: {
groupInfo: [],
labelInfo: [],
levelInfo: [],
},
ruleValidate: {
real_name: [{ required: true, message: ' ', trigger: 'blur' }],
phone: [{ required: true, message: ' ', trigger: 'blur' }],
pwd: [{ required: true, message: ' ', trigger: 'blur' }],
true_pwd: [{ required: true, message: ' ', trigger: 'blur' }],
},
dataLabel: [],
};
},
computed: {
hasExtendInfo() {
// return this.psInfo.extend_info.some((item) => item.value);
},
},
created() {
this.getUserFrom(this.userId);
// this.formItem = this.userData.userInfo;
},
methods: {
setUser() {
let data = this.formItem;
let ids = [];
this.dataLabel.map((i) => {
ids.push(i.id);
});
data.label_id = ids;
// if (!data.real_name) return this.$Message.warning("请输入真实姓名");
// if (!data.phone) return this.$Message.warning("请输入手机号");
// if (!data.pwd) return this.$Message.warning("请输入密码");
// if (!data.true_pwd) return this.$Message.warning("请输入确认密码");
if (data.uid) {
editUser(data)
.then((res) => {
this.$Message.success(res.msg);
this.$emit('success');
})
.catch((err) => {
this.$Message.error(err.msg);
});
} else {
setUser(data)
.then((res) => {
this.$emit('success');
this.$Message.success(res.msg);
})
.catch((err) => {
this.$Message.error(err.msg);
});
}
},
addLabel() {
this.$modalForm(userLabelAddApi(0)).then(() => {});
},
openLabel(row) {
this.labelShow = true;
this.$refs.userLabel.userLabel(JSON.parse(JSON.stringify(this.infoData.labelInfo)));
},
closeLabel(label) {
let index = this.dataLabel.indexOf(this.dataLabel.filter((d) => d.id == label.id)[0]);
this.dataLabel.splice(index, 1);
},
getUserFrom(id) {
getUserInfo(id)
.then(async (res) => {
this.userData = res.data;
this.$set(this.infoData, 'groupInfo', this.userData.groupInfo);
this.$set(this.infoData, 'levelInfo', this.userData.levelInfo);
this.$set(this.infoData, 'labelInfo', this.userData.labelInfo);
let arr = Object.keys(this.formItem);
if (this.userData.userInfo) {
arr.map((i) => {
this.formItem[i] = this.userData.userInfo[i];
});
if (!this.formItem.birthday) this.formItem.birthday = '';
if (this.formItem.label_id.length) {
this.dataLabel = this.formItem.label_id;
}
} else {
this.reset();
}
})
.catch((res) => {
this.$Message.error(res.msg);
});
},
// 标签弹窗关闭
labelClose() {
this.labelShow = false;
},
activeData(dataLabel) {
this.labelShow = false;
this.dataLabel = dataLabel;
},
reset() {
this.formItem = {
uid: '',
real_name: '',
phone: '',
birthday: '',
card_id: '',
addres: '',
mark: '',
pwd: '',
true_pwd: '',
level: '',
group_id: '',
label_id: [],
spread_open: 0,
is_promoter: 0,
status: 1,
};
},
},
};
</script>
<style lang="less" scoped>
.labelInput {
border: 1px solid #dcdee2;
width: 300px;
padding: 0 8px;
border-radius: 5px;
min-height: 30px;
cursor: pointer;
.span {
color: #c5c8ce;
}
.iconxiayi {
font-size: 12px;
}
}
.width-add {
width: 40px;
}
.mr30 {
margin-right: 30px;
}
.user-info {
.section {
padding: 25px 0;
border-bottom: 1px dashed #eeeeee;
&-hd {
padding-left: 10px;
border-left: 3px solid #1890ff;
font-weight: 500;
font-size: 14px;
line-height: 16px;
color: #303133;
}
&-bd {
display: flex;
flex-wrap: wrap;
}
.item {
width: 50%;
display: flex;
margin: 16px 0px 0 0;
font-size: 13px;
color: #606266;
&:nth-child(3n + 3) {
margin: 16px 0 0;
}
.form-sty {
width: 300px;
}
.ivu-form-item {
margin: 3px 0;
}
.addfont {
display: inline-block;
font-size: 13px;
font-weight: 400;
color: #1890ff;
margin-left: 14px;
cursor: pointer;
margin-left: 10px;
}
}
.item.lang {
width: 100%;
}
.value {
flex: 1;
}
.avatar {
width: 60px;
height: 60px;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
}
}
</style>

View File

@ -0,0 +1,190 @@
<template>
<div class="user-info">
<div class="section">
<div class="section-hd">基本信息</div>
<div class="section-bd">
<div class="item">
<div>用户编号:</div>
<div class="value">{{ psInfo.uid }}</div>
</div>
<div class="item">
<div>真实姓名:</div>
<div class="value">{{ psInfo.real_name || '-' }}</div>
</div>
<div class="item">
<div>手机号码:</div>
<div class="value">{{ psInfo.phone || '-' }}</div>
</div>
<div class="item">
<div>生日:</div>
<div class="value">{{ psInfo.birthday | timeFormat('birthday') }}</div>
</div>
<div class="item">
<div>性别:</div>
<div v-if="psInfo.sex" class="value">{{ psInfo.sex == 1 ? '男' : '女' }}</div>
<div v-else class="value">保密</div>
</div>
<div class="item">
<div>身份证号:</div>
<div class="value">{{ psInfo.card_id || '-' }}</div>
</div>
<div class="item">
<div>用户地址:</div>
<div class="value">{{ `${psInfo.addres}` || '-' }}</div>
</div>
</div>
</div>
<div class="section">
<div class="section-hd">密码</div>
<div class="section-bd">
<div class="item">
<div>登录密码:</div>
<div class="value">********</div>
</div>
</div>
</div>
<div class="section">
<div class="section-hd">用户概况</div>
<div class="section-bd">
<div class="item">
<div>推广资格:</div>
<div class="value">{{ psInfo.spread_open ? '开启' : '关闭' }}</div>
</div>
<div class="item">
<div>用户状态:</div>
<div class="value">{{ psInfo.status ? '开启' : '锁定' }}</div>
</div>
<div class="item">
<div>用户等级:</div>
<div class="value">{{ psInfo.vip_name || '-' }}</div>
</div>
<div class="item">
<div>用户标签:</div>
<div class="value">{{ psInfo.label_list || '-' }}</div>
</div>
<div class="item">
<div>用户分组:</div>
<div class="value">{{ psInfo.group_name || '-' }}</div>
</div>
<div class="item">
<div>推广人:</div>
<div class="value">{{ psInfo.spread_uid_nickname || '-' }}</div>
</div>
<div class="item">
<div>注册时间:</div>
<div class="value">{{ psInfo.add_time | timeFormat }}</div>
</div>
<div class="item">
<div>登录时间:</div>
<div class="value">{{ psInfo.last_time | timeFormat }}</div>
</div>
<div v-if="psInfo.is_money_level" class="item">
<div>付费会员:</div>
<div class="value">
{{
psInfo.is_ever_level == 1 ? '永久会员' : psInfo.overdue_time ? `${psInfo.overdue_time} 到期` : '已过期'
}}
</div>
</div>
</div>
</div>
<div class="section">
<div class="section-hd">用户备注</div>
<div class="section-bd">
<div class="item">
<div>备注:</div>
<div class="value">{{ psInfo.mark || '-' }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import dayjs from 'dayjs';
export default {
name: 'userInfo',
props: {
psInfo: Object,
},
filters: {
timeFormat(value, birthday) {
let i = birthday ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss';
if (!value) {
return '-';
}
return dayjs(value * 1000).format(i);
},
gender(value) {
if (value == 1) {
return '男';
} else if (value == 2) {
return '女';
} else {
return '未知';
}
},
},
computed: {
hasExtendInfo() {
// return this.psInfo.extend_info.some((item) => item.value);
},
},
};
</script>
<style lang="less" scoped>
.width-add {
width: 40px;
}
.mr30 {
margin-right: 30px;
}
.user-info {
.section {
padding: 25px 0;
border-bottom: 1px dashed #eeeeee;
&-hd {
padding-left: 10px;
border-left: 3px solid #1890ff;
font-weight: 500;
font-size: 14px;
line-height: 16px;
color: #303133;
}
&-bd {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 0 0 calc(~'(100% - 60px) / 3');
display: flex;
margin: 16px 30px 0 0;
font-size: 13px;
color: #606266;
&:nth-child(3n + 3) {
margin: 16px 0 0;
}
}
.value {
flex: 1;
}
.avatar {
width: 60px;
height: 60px;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
}
}
</style>

View File

@ -13,16 +13,16 @@
>
<Row :gutter="16">
<Col v-bind="grid">
<FormItem label="用户搜索:" label-for="nickname">
<Input v-model="userFrom.nickname" placeholder="请输入用户" element-id="nickname" clearable>
<Select v-model="field_key" slot="prepend" style="width: 80px">
<Option value="all">全部</Option>
<Option value="uid">UID</Option>
<Option value="phone">手机号</Option>
<Option value="nickname">用户昵称</Option>
</Select>
</Input>
</FormItem>
<FormItem label="用户搜索:" label-for="nickname">
<Input v-model="userFrom.nickname" placeholder="请输入用户" element-id="nickname" clearable>
<Select v-model="field_key" slot="prepend" style="width: 80px">
<Option value="all">全部</Option>
<Option value="uid">UID</Option>
<Option value="phone">手机号</Option>
<Option value="nickname">用户昵称</Option>
</Select>
</Input>
</FormItem>
</Col>
<Col span="12" class="ivu-text-left userFrom" v-if="!collapse">
<FormItem>
@ -42,11 +42,11 @@
<div style="width: 90%">
<div v-if="selectDataLabel.length">
<Tag
:closable="false"
v-for="(item, index) in selectDataLabel"
@on-close="closeLabel(item)"
:key="index"
>{{ item.label_name }}</Tag
:closable="false"
v-for="(item, index) in selectDataLabel"
@on-close="closeLabel(item)"
:key="index"
>{{ item.label_name }}</Tag
>
</div>
<span class="span" v-else>选择用户关联标签</span>
@ -75,8 +75,8 @@
<Select v-model="group_id" placeholder="请选择用户分组" element-id="group_id" clearable>
<Option value="all">全部</Option>
<Option :value="item.id" v-for="(item, index) in groupList" :key="index">{{
item.group_name
}}</Option>
item.group_name
}}</Option>
</Select>
</FormItem>
</Col>
@ -182,11 +182,11 @@
<Col v-bind="grid">
<FormItem label="地区:" label-for="country">
<Select
v-model="userFrom.country"
placeholder="请选择国家"
element-id="country"
clearable
@on-change="changeCountry"
v-model="userFrom.country"
placeholder="请选择国家"
element-id="country"
clearable
@on-change="changeCountry"
>
<Option value="domestic">中国</Option>
<Option value="abroad">外国</Option>
@ -281,7 +281,8 @@
<!-- </template>-->
<template slot-scope="{ row, index }" slot="action">
<template v-if="row.is_del != 1">
<a @click="edit(row)">编辑</a>
<a @click="userDetail(row)">详情</a>
<Divider type="vertical" />
<Dropdown @on-click="changeMenu(row, $event, index)" :transfer="true">
<a href="javascript:void(0)">
@ -289,7 +290,7 @@
<Icon type="ios-arrow-down"></Icon>
</a>
<DropdownMenu slot="list">
<DropdownItem name="1">账户详情</DropdownItem>
<!-- <DropdownItem name="1">编辑</DropdownItem> -->
<DropdownItem name="2">积分余额</DropdownItem>
<DropdownItem name="3">赠送会员</DropdownItem>
<!-- <DropdownItem name="4" v-if="row.vip_name">清除等级</DropdownItem>-->
@ -890,6 +891,11 @@ export default {
this.timeVal = e;
this.userFrom.user_time = this.timeVal.join('-');
},
userDetail(row) {
console.log(row.uid)
this.$refs.userDetails.modals = true;
this.$refs.userDetails.getDetails(row.uid);
},
// 操作
changeMenu(row, name, index) {
let uid = [];
@ -897,8 +903,7 @@ export default {
let uids = { uids: uid };
switch (name) {
case '1':
this.$refs.userDetails.modals = true;
this.$refs.userDetails.getDetails(row.uid);
this.edit(row);
break;
case '2':
this.getOtherFrom(row.uid);