oil-station/fuintAdmin/src/views/member/index.vue
2024-01-11 13:55:20 +08:00

817 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-card >
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<!-- <el-form-item label="来源油站" prop="storeIds">-->
<!-- <el-select v-model="queryParams.storeId" filterable clearable placeholder="来源油站" style="width: 100%;">-->
<!-- <el-option v-for="item in storeList" :key="item.id" :label="item.name" :value="item.id"/>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="会员号" prop="userNo">
<el-input
v-model="queryParams.userNo"
placeholder="请输入会员号"
clearable
style="width: 240px;"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号" prop="mobile">
<el-input
v-model="queryParams.mobile"
placeholder="请输入会员手机号"
clearable
style="width: 240px;"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入会员名称"
clearable
style="width: 240px;"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="会员等级" prop="gradeId">
<el-select
v-model="queryParams.gradeId"
clearable
placeholder="全部"
>
<el-option v-for="grade in userGradeList" :key="grade.id+''" :label="grade.name" :value="grade.id+''"/>
</el-select>
</el-form-item>
<el-form-item label="" prop="balance">
<el-select
v-model="ifBalance"
clearable
placeholder="全部"
>
<el-option label="有储值余额" value="haveBalance"/>
<el-option label="无储值余额" value="noHaveBalance"/>
</el-select>
</el-form-item>
<el-form-item label="" prop="status">
<el-select
v-model="queryParams.official"
placeholder="全部"
clearable
style="width: 240px"
>
<el-option
v-for="dict in dict.type.official"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="注册时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
size="medium"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card style="margin-top: 20px">
<div>统计</div>
<template>
<div>
<el-row :gutter="20">
<el-col :span="4">
<div class="sta">
<el-statistic
group-separator=","
:value="total"
title="会员总数"
></el-statistic>
</div>
</el-col>
<el-col :span="4">
<div class="sta">
<el-statistic title="今日新增/昨日新增">
<template slot="formatter">
{{ addNum }}/{{ yesterdayAddNum }}
</template>
</el-statistic>
</div>
</el-col>
<el-col :span="4">
<div class="sta">
<el-statistic
group-separator=","
:precision="2"
:value="balance"
title="储值总余额"
></el-statistic>
</div>
</el-col>
<!-- <el-col :span="4">-->
<!-- <div class="sta">-->
<!-- <el-statistic-->
<!-- group-separator=","-->
<!-- :precision="2"-->
<!-- :value="literCard"-->
<!-- title="升数卡总余额"-->
<!-- ></el-statistic>-->
<!-- </div>-->
<!-- </el-col>-->
<el-col :span="4">
<div class="sta">
<el-statistic
group-separator=","
:value="point"
title="积分总余额"
></el-statistic>
</div>
</el-col>
<!-- <el-col :span="4">-->
<!-- <div class="sta">-->
<!-- <el-statistic-->
<!-- group-separator=","-->
<!-- :precision="2"-->
<!-- :value="refuelMoney"-->
<!-- title="加油金余额"-->
<!-- ></el-statistic>-->
<!-- </div>-->
<!-- </el-col>-->
</el-row>
</div>
</template>
</el-card>
<el-card style="margin-top: 20px">
<el-button
type="primary"
icon="el-icon-plus"
@click="handleAdd"
>新增会员</el-button>
<el-table ref="tables" v-loading="loading" :data="list"
@selection-change="handleSelectionChange" :default-sort="defaultSort"
@sort-change="handleSortChange">
<el-table-column label="会员ID" prop="id" align="center" width="60"/>
<el-table-column label="头像" align="center" width="70">
<template slot-scope="scope">
<img v-if="scope.row.avatar" class="list-avatar" :src="baseUrl + scope.row.avatar">
<img v-else class="list-avatar" src="@/assets/images/avatar.png">
</template>
</el-table-column>
<el-table-column label="会员号" align="center" prop="userNo" width="150"/>
<el-table-column label="名称" align="center" prop="name" >
<template slot-scope="scope">
<span style="color: #409EFF;cursor: pointer " @click="goDedi(scope.row.id)">{{ scope.row.name ? scope.row.name : "--" }}</span>
</template>
</el-table-column>
<el-table-column label="手机号" align="center" prop="mobile" width="110">
<template slot-scope="scope">
<span>{{ scope.row.mobile ? scope.row.mobile : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="会员等级" align="center" prop="gradeId" width="80">
<template slot-scope="scope">
<span>{{ scope.row.gradeId ? getName(allUserGrade, scope.row.gradeId) : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="储值卡" align="center" prop="cardBalance">
<template slot-scope="scope">
<div>{{ scope.row.cardBalance ? scope.row.cardBalance.toFixed(2) : '0.00' }}</div>
</template>
</el-table-column>
<el-table-column label="积分" align="center" prop="points">
<template slot-scope="scope">
<div><span>{{ scope.row.points ? scope.row.points : '0.00' }}</span></div>
</template>
</el-table-column>
<el-table-column label="加油次数" align="center" prop="consumeNum">
<template slot-scope="scope">
<div>{{ scope.row.consumeNum ? scope.row.consumeNum : '0' }}</div>
</template>
</el-table-column>
<el-table-column label="注册时间" align="center" width="160" prop="createTime">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.zhzt" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="公众号" align="center" prop="official">
<template slot-scope="scope">
<dict-tag :options="dict.type.official" :value="scope.row.official"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="120" fixed='right'>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.page"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-card>
<!-- 添加会员信息,选择是否批量录入-->
<el-dialog :title="title" width="55%" :visible.sync="openUser" append-to-body>
<el-alert
type="info"
:closable="false">
<p v-for="(item,index) in addMember" :id="index">
{{item}}
</p>
</el-alert>
<div style="margin: 10px 0">
<el-button type="primary"
icon="el-icon-edit-outline" @click="addOne" round>录入单个会员</el-button>
<el-button type="primary"
icon="el-icon-connection" @click="addMult" round>批量导入会员</el-button>
</div>
<div>
<el-table ref="tables" v-loading="loading" :data="userList">
<el-table-column prop="batchNumber" align="center" label="批次号" width="200"/>
<el-table-column prop="type" align="center" label="类型"/>
<el-table-column prop="memberNumber" align="center" label="会员数"/>
<el-table-column label="执行结果" align="center" >
<el-table-column prop="successNumber" align="center" label="成功人数"/>
<el-table-column prop="errorNumber" align="center" label="失败人数"/>
<el-table-column prop="repeatNumber" align="center" label="重复人数"/>
</el-table-column>
<el-table-column prop="createTime" align="center" label="处理时间" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<!-- <el-table-column prop="date" align="center" label="处理结果详情"/>-->
</el-table>
<pagination
:total="total1"
:page.sync="queryParams.page"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</el-dialog>
<!-- 添加或修改对话框 -->
<el-dialog :close-on-click-modal="false" :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="24">
<el-form-item label="会员名称" prop="name" style="width: 420px">
<el-input v-model="form.name" placeholder="请输入会员名称" maxlength="30" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="手机号" prop="mobile">
<el-input v-model="form.mobile" placeholder="请输入手机号" maxlength="30"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="会员等级" prop="gradeId">
<el-select
v-model="form.gradeId"
placeholder="会员等级"
style="width: 300px"
>
<el-option v-for="grade in userGradeList" :key="grade.id+''" :label="grade.name" :value="grade.id"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="会员号" prop="userNo">
<el-input v-model="form.userNo" placeholder="请输入会员号,为空系统将自动分配" maxlength="30" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="身份证号" prop="idcard">
<el-input v-model="form.idcard" placeholder="请输入身份证号" maxlength="30"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="会员初始积分" prop="points">
<el-input :disabled="title == '编辑会员'" v-model="form.points" placeholder="请输入会员初始积分" maxlength="30"/>
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>-->
<!-- <el-col :span="24">-->
<!-- <el-form-item label="初始加油金" prop="refuelMoney">-->
<!-- <el-input v-model="form.refuelMoney" placeholder="0" maxlength="30"/>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- </el-row>-->
<el-row>
<el-col :span="24">
<el-form-item label="储值通用余额" prop="cardBalance">
<el-input :disabled="title == '编辑会员'" v-model="form.cardBalance" placeholder="请输入储值卡初始余额" maxlength="30"/>
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>-->
<!-- <el-col :span="24">-->
<!-- <el-form-item label="升数卡余额" prop="literCard">-->
<!-- <el-input v-model="form.literCard" placeholder="0" maxlength="30"/>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- </el-row>-->
<el-row>
<el-col :span="24">
<el-form-item label="是否关注公众号">
<el-radio-group v-model="form.official">
<el-radio label="ygz" value="ygz">已关注</el-radio>
<el-radio label="wgz" value="wgz">未关注</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="会员状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio label="qy" value="qy">启用</el-radio>
<el-radio label="jy" value="jy">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<!-- 批量录入会员信息-->
<el-dialog :title="title" :visible.sync="openUpload" append-to-body>
<div style="height: 60px;line-height: 30px">
<div> 第一步: 下载示例模板,按照模板填写会员数据,手机号为必填项 </div>
<a style="margin-left: 50px;color: #00afff"
href="/dev-api/excel/export"> 会员示例模板.xlsx </a>
</div>
<div style="margin: 20px 0">
<div>第二步: 选择用户数据上传并导入会员</div>
<el-upload
class="upload-demo"
v-loading="uploading"
action="/dev-api/excel/import"
:headers="headers"
:limit="1"
:on-change="handleChange"
style="margin-left: 50px"
:file-list="fileList">
<el-button size="small" type="success" icon="el-icon-upload">点击上传</el-button>
<div slot="tip">只能上传xls/xlsx文件单次最大5000行会员数据且不超过1M 超出请分文件处理</div>
</el-upload>
<!-- <el-button type="primary" round @click="importUser">主要按钮</el-button>-->
</div>
</el-dialog>
<!-- 批量导入结果-->
<el-dialog width="400px" style="margin-top: 150px" :title="title" :visible.sync="openResult" append-to-body>
<div class="huiyuan">
会员总数:<span class="num">{{result.total}}</span> 人
</div>
<div class="huiyuan">
成功人数:<span class="num">{{result.success}}</span> 人
</div>
<div class="huiyuan">
失败人数:<span class="num">{{result.error}}</span> 人
<span v-if="result.error!=0" style="color: red;font-size: 12px">手机号不可为空</span>
</div>
<div class="huiyuan">
重复人数:<span class="num">{{result.repeat}}</span>
</div>
</el-dialog>
<!-- 余额充值对话框 -->
<balanceRecharge :showDialog="openBalance" :userId="userId" @closeDialog="closeDialog" @close="closeDialog"/>
<!-- 积分充值对话框 -->
<pointRecharge :showDialog="openPoint" :userId="userId" @closeDialog="closeDialog" @close="closeDialog"/>
</div>
</template>
<script>
import { getMemberList, updateMemberStatus, getMemberInfo, saveMember, deleteMember } from "@/api/member";
import balanceRecharge from "./balanceRecharge";
import pointRecharge from "./pointRecharge";
import {
addUser,
delUser,
exportUsers,
getUser,
getUserMobile, getUserPhone,
listStatistic,
listUser, listUserStatistic,
updateUser
} from "@/api/staff/user/user";
import {allUserGrade, listUserGrade} from "@/api/staff/user/usergrade";
import {ljStoreList, storesList} from "@/api/staff/store";
import {getSysConfig} from "@/api/staff/user/sysconfig";
import { getToken } from "@/utils/auth";
import {paymentApi} from "@/api/payment/fypay";
export default {
name: "MemberIndex",
components: { balanceRecharge, pointRecharge },
dicts: ['official','zhzt'],
data() {
return {
baseUrl:process.env.VUE_APP_BASE_API,
result:{},
// 是否自动上传
isUpload:false,
headers: {
'Access-Token': getToken(),
},
// 文件上传信息
fileList: [],
addMember:[],
// 余额
balance:'',
// 积分
point:'',
// 升数卡
literCard:'',
// 加油金
refuelMoney:'',
// 今日新增
addNum:'',
// 昨日新增
yesterdayAddNum:'',
// 遮罩层
loading: true,
uploading: false,
uploadingFile: 0,
// 标题
title: "",
// 选中数组
ids: [],
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
total1: 0,
// 表格数据
list: [],
// 会员表格数据
userList: [],
// 当前店铺会员等级列表
userGradeList: [],
// 所有等级信息
allUserGrade:[],
// 店铺列表
storeList: [],
storeIds: [],
// 是否显示修改对话框
open: false,
openUser: false,
openUpload: false,
openResult: false,
// 当前操作用户
userId: '',
// 是否弹层充值
openBalance: false,
// 是否弹层积分
openPoint: false,
// 日期范围
dateRange: [],
// 默认排序
defaultSort: {prop: 'updateTime', order: 'descending'},
// 表单参数
form: { id: '', name: '', gradeId: '', mobile: '', userNo: '',points:0, startTime: '',
endTime: '', refuelMoney:'0',official:'wgz',
cardBalance:0, literCard:'0', sex: 1, idcard: '', birthday: '', address: '', status: "qy", description: '' },
// 查询参数
queryParams: {
page: 1,
pageSize: 10,
mobile: '',
id: '',
userNo: '',
name: '',
gradeId: '',
status: '',
storeId: '',
official:'',
cardBalance:'',
},
ifBalance:'',
// 表单校验
rules: {
name: [
{ required: true, message: "会员名称不能为空", trigger: "blur" },
// { min: 2, max: 200, message: '会员名称长度必须介于2 和 100 之间', trigger: 'blur' }
],
gradeId: [{ required: true, message: "请选择会员等级", trigger: "blur" }],
status: [{ required: true, message: "请选择会员状态", trigger: "blur" }],
mobile: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{ min: 8, max: 11, message: '请输入正确的手机号', trigger: 'blur' }
],
}
};
},
created() {
this.getList();
this.getStatistic();
this.getConfig();
this.getUserList();
},
methods: {
// 跳转详情页
goDedi(id){
this.$router.push({
path:"/member/userInfo",
query:{
id:id
}
})
},
getUserList(){
this.loading = true;
listUserStatistic().then( response => {
this.userList = response.data.records;
this.total1 = response.data.total;
this.loading = false;
});
},
// 查询列表
getList() {
this.loading = true;
listUser(this.addDateRange(this.queryParams, this.dateRange)).then( response => {
this.list = response.data.records;
this.total = response.data.total;
this.loading = false;
});
},
// 获得统计信息
getStatistic(){
listStatistic(this.addDateRange(this.queryParams, this.dateRange)).then( response => {
this.addNum = response.data.addNum;
this.yesterdayAddNum = response.data.yesterdayAddNum;
this.balance = response.data.balance;
this.point = response.data.point;
});
allUserGrade().then( response => {
this.allUserGrade = response.data
});
listUserGrade({page:1,pageSize:20}).then( response => {
this.userGradeList = response.data.records;
});
storesList().then( response => {
this.storeList = response.data
});
},
// 搜索按钮操作
handleQuery() {
this.queryParams.page = 1;
if (this.ifBalance=='haveBalance'){
this.queryParams.cardBalance = 1;
}else {
this.queryParams.cardBalance = 2;
}
if (this.ifBalance==''){
this.queryParams.cardBalance = ''
}
this.getList();
},
// 重置按钮操作
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.queryParams.storeId = '';
this.queryParams.official = "";
this.ifBalance = ""
this.storeIds = [];
this.$refs.tables.sort(this.defaultSort.prop, this.defaultSort.order);
this.handleQuery();
},
// 状态修改
handleStatusChange(row) {
let text = row.status == "A" ? "启用" : "禁用";
this.$modal.confirm('确认要' + text + '"' + row.name + '"吗?').then(function() {
return updateMemberStatus(row.id, row.status);
}).then(() => {
this.$modal.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "N" ? "A" : "N";
});
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.multiple = !selection.length
},
// 排序触发事件
handleSortChange(column, prop, order) {
this.queryParams.orderByColumn = column.prop;
this.queryParams.isAsc = column.order;
this.getList();
},
// 余额充值操作
handleBalance(userId) {
this.openBalance = true;
this.userId = userId.toString();
},
// 导入会员信息
importUser(){
this.openResult = true;
this.title = "会员创建结果";
this.getList();
this.getUserList();
},
// 积分变更操作
handlePoint(userId) {
this.openPoint = true
this.userId = userId.toString();
},
// 关闭对话框
closeDialog(dialog) {
if (dialog == 'balance') {
this.openBalance = false;
}
if (dialog == 'point') {
this.openPoint = false;
}
this.userId = "";
this.getList();
},
// 新增按钮操作
handleAdd() {
this.openUser = true;
this.title = "新增会员";
},
// 新增按钮操作
addOne() {
this.reset();
this.open = true;
this.title = "录入会员";
},
addMult(){
this.openUpload = true;
this.title = "批量导入会员";
},
// 获取配置信息
getConfig(){
getSysConfig('addMember').then(response => {
this.addMember = response.data.split(";")
});
},
// 表单重置
reset() {
this.resetForm("form");
this.form= { id: '', name: '', gradeId: '', mobile: '', userNo: '',points:0, startTime: '', endTime: '',
refuelMoney:'0',official:'wgz',cardBalance:0, literCard:'0', sex: 1, idcard: '', birthday: '', address: '',
status: "qy", description: ''
}
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 提交按钮
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id) {
updateUser(this.form).then(response => {
if (response.data==1){
this.$modal.msgSuccess("修改会员成功");
this.open = false;
this.getList();
}else {
this.$modal.msgError("手机号已存在");
}
});
} else {
getUserPhone({mobile:this.form.mobile}).then( response => {
if(response.data){
this.$modal.msgError("手机号已存在");
}else {
addUser(this.form).then(res => {
this.$modal.msgSuccess("新增会员成功");
this.open = false;
this.openUser = false;
this.getList();
this.getUserList();
});
}
})
}
}
});
},
// 修改按钮操作
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getUser(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "编辑会员";
});
},
// 删除按钮操作
handleDelete(row) {
const name = row.name
this.$modal.confirm('确定删除"' + name + '"的会员信息?').then(function() {
// return deleteMember(row.id);
return delUser(row.id);
}).then(() => {
this.queryParams.page = 1
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
handleChange(file, fileList) {
this.uploading = true;
if(file.status === 'success'){
this.uploading = false;
this.openUpload = false;
this.openUser = false;
this.importUser();
this.fileList.splice(0,1)
this.result = file.response.data
}
},
}
};
</script>
<style scoped>
.app-container{
width: 100%;
height: 100%;
background: #f6f8f9;
}
.sta{
height: 100px;
margin-top: 10px;
background: #f6f8f9;
padding-top: 30px;
}
.huiyuan{
height: 30px;
line-height: 30px;
font-size: 16px;
}
.num{
font-weight: bold;
color: red;
font-size: 18px;
}
</style>