Files
cashier_admin_app/pageUser/index/index.vue
2024-11-04 10:51:49 +08:00

808 lines
18 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>
<view class="safe-page">
<!-- <view class="bg-fff u-p-l-30 u-p-r-30 ">
<view class="myTabs u-m-t-20">
<my-tabs :list="tabsList" @change="tabsChange"></my-tabs>
</view>
</view> -->
<!-- 用户列表 -->
<template v-if="tabsCurrent===0">
<view class="input-wrapper u-p-l-30 u-p-r-30 u-p-b-30 bg-fff">
<view class="input-main">
<uni-easyinput class='jeepay-search' :inputBorder="false" :placeholder="pageData.search.placeholder"
v-model="pageData.search.value" @confirm="searchFunc">
<template #prefixIcon>
<image src="@/static/iconImg/icon-search.svg" class="input-icon" />
</template>
</uni-easyinput>
<button type="text" @click="searchFunc()">搜索</button>
</view>
</view>
<view class="u-p-30">
<view class="data-statistics">
<view class="u-font-32">数据统计</view>
<view class="u-m-t-40 u-flex u-row-between">
<view class=" ">
<view>会员数</view>
<view class="u-m-t-10 u-font-36 font-bold">{{pageData.allShopInfo.userTotal}}</view>
</view>
<view class="line-l-r u-p-l-30 u-p-r-30">
<view>会员余额</view>
<view class="u-m-t-10 u-font-36 font-bold">{{pageData.allShopInfo.balanceTotal}}</view>
</view>
<view class="">
<view>充值金额</view>
<view class="u-m-t-10 u-font-36 font-bold">{{pageData.allShopInfo.chageTotal}}</view>
</view>
</view>
</view>
</view>
<view class="goods-list u-p-l-30 u-p-r-30">
<view class="u-m-b-32" v-for="(item,index) in pageData.userList" :key="index">
<my-user @moreOperate="moreOperateClick" @remark="userRemarkClick" @bindMoblie="bindMoblieClick"
:index="index" :data="item" :showChecked="showChecked"
:showDetail="pageData.showGoodsDetail"></my-user>
</view>
<my-pagination @change="pageChange"></my-pagination>
</view>
<view class="fixed_b">
<my-button showShadow @tap="toAddUser" shape="circle">新建用户</my-button>
</view>
</template>
<!-- 导入用户 -->
<template v-else>
<view class="u-p-30">
<view class="data-statistics user-statistics">
<view class="u-m-t-40 u-flex u-font-24 no-wrap">
<view class="u-flex-1 after-r u-p-l-30 u-p-r-30">
<view>已关联用户</view>
<view class="u-m-t-20 u-font-36 font-bold">0</view>
</view>
<view class="u-flex-1 after-r u-p-l-30 u-p-r-30">
<view>已关联余额</view>
<view class="u-m-t-20 u-font-36 font-bold">0</view>
</view>
<view class="u-flex-1 u-p-l-30 u-p-r-30">
<view>已关联积分</view>
<view class="u-m-t-20 u-font-36 font-bold">0</view>
</view>
</view>
<view class="u-m-t-40 u-flex u-font-24 no-wrap">
<view class="u-flex-1 after-r u-p-l-30 u-p-r-30">
<view>未关联用户</view>
<view class="u-m-t-20 u-font-36 font-bold">0</view>
</view>
<view class="u-flex-1 after-r u-p-l-30 u-p-r-30">
<view>未关联余额</view>
<view class="u-m-t-20 u-font-36 font-bold">0</view>
</view>
<view class="u-flex-1 u-p-l-30 u-p-r-30">
<view>未关联积分</view>
<view class="u-m-t-20 u-font-36 font-bold">27</view>
</view>
</view>
</view>
</view>
<view class="fixed_b">
<my-button showShadow @tap="toAddUser" shape="circle">新建用户</my-button>
</view>
</template>
<!-- 备注弹窗 -->
<my-model ref="remarkModel" title="修改备注">
<template #desc>
<view class="u-p-30 u-m-t-20">
<uni-easyinput v-model="remarModelData.remark" placeholder="请输入备注"></uni-easyinput>
</view>
</template>
<template #btn>
<view class="u-m-t-40 u-p-b-60" style="padding: 0 100rpx;">
<my-button shape="circle" @tap="remarkModelConfirm">确定</my-button>
</view>
</template>
</my-model>
<!-- 绑定手机号弹窗 -->
<my-model ref="phoneModel" title="绑定手机号">
<template #desc>
<view class="u-p-30 u-m-t-20">
<uni-easyinput v-model="phoneModelData.phone" placeholder="输入手机号码"></uni-easyinput>
</view>
</template>
<template #btn>
<view class="u-m-t-40 u-p-b-60" style="padding: 0 100rpx;">
<my-button shape="circle" @tap="phoneModelConfirm">确定</my-button>
</view>
</template>
</my-model>
<!-- 商品库存修改弹窗 -->
<my-model ref="goodsStockModel" title="商品修改" @close="goodsStockModelClose">
<template #desc>
<view class="u-p-40 u-text-left">
<view>
<view class="">排序:</view>
<view class="u-m-t-24">
<uni-easyinput v-model="goodsStockData.sort" placeholder="请输入排序"></uni-easyinput>
</view>
</view>
<view class="u-flex u-m-t-32">
<view class="">库存:</view>
<view class="u-m-l-46 ">
<my-switch v-model="goodsStockData.openStock"></my-switch>
</view>
</view>
<view class="u-m-t-24 u-m-t-32" v-if="goodsStockData.openStock">
<view class="">数量:</view>
<view class="u-m-t-24">
<uni-easyinput v-model="goodsStockData.number" placeholder="请输入库存数量"></uni-easyinput>
</view>
</view>
</view>
</template>
<template #btn>
<view class="stock-btns u-p-b-40">
<my-button shape="circle" @click="goodsStockModelSave">保存</my-button>
<my-button shape="circle" type="default" @click="goodsStockModelCancel">取消</my-button>
</view>
</template>
</my-model>
<my-action-sheet @itemClick="actionSheetClick" ref="moreOperate" :list="moreOperateList"></my-action-sheet>
</view>
<!-- 增减余额 -->
<up-popup :show="datas.show" :round="18" mode="center" @close="close">
<view class="zhezhaopop">
<view class="">
<span></span>
<span>增减余额</span>
<up-icon @tap="confirm" name="close-circle-fill"></up-icon>
</view>
<view style="display: flex;align-items: center;padding: 24rpx;">
<image v-if="datas.activeUser?datas.activeUser.headImg:''" :src="datas.activeUser.headImg"
style="width: 52rpx;height: 52rpx;;background-color: #eee;"></image>
<view style="width: 52rpx;height: 52rpx;;background-color: #eee;" v-else>
</view>
<view style="margin-left: 12rpx;">
<view style="font-weight: 400;font-size: 28rpx;color: #333333;">
{{datas.activeUser?datas.activeUser.nickName:''}}
</view>
<view style="font-weight: 400;font-size: 24rpx;color: #999999;">
当前余额:{{datas.activeUser?datas.activeUser.amount:''}}
</view>
</view>
</view>
<view class="zhezhaopopthree">
<view style="font-weight: 400;font-size: 28rpx;color: #333333;">
增减
</view>
<view class="u-m-t-16">
<radio-group class="u-flex u-flex-wrap" @change="sizeChange($event,'operationType')">
<label class="radio u-m-r-60">
<radio value="in" :checked="datas.form.operationType == 'in'" class="scale7" />
<text>增加</text>
</label>
<label class="radio u-m-r-60">
<radio value="out" :checked="datas.form.operationType == 'out'" class="scale7" />
<text>扣除</text>
</label>
</radio-group>
</view>
</view>
<view class="zhezhaopopthree" v-if="datas.form.operationType=='in'">
<view style="font-weight: 400;font-size: 28rpx;color: #333333;">
类型
</view>
<view class="u-m-t-16">
<radio-group class="u-flex u-flex-wrap" @change="sizeChange($event,'type')">
<label class="radio u-m-r-60">
<radio value="inMoney" :checked="datas.form.type == 'inMoney'" class="scale7" />
<text>充值</text>
</label>
<label class="radio u-m-r-60">
<radio value="consumeIn" :checked="datas.form.type == 'consumeIn'" class="scale7" />
<text>消费退款</text>
</label>
</radio-group>
</view>
</view>
<view class="zhezhaopopthree" v-else>
<view style="font-weight: 400;font-size: 28rpx;color: #333333;">
类型
</view>
<view class="u-m-t-16">
<radio-group class="u-flex u-flex-wrap" @change="sizeChange($event,'type')">
<label class="radio u-m-r-60">
<radio value="consumeOut" :checked="datas.form.type == 'consumeOut'" class="scale7" />
<text>消费</text>
</label>
<label class="radio u-m-r-60">
<radio value="inMoneyOut" :checked="datas.form.type == 'inMoneyOut'" class="scale7" />
<text>充值退款</text>
</label>
</radio-group>
</view>
</view>
<view class="zhezhaopopfour">
<view style="font-weight: 400;font-size: 28rpx;color: #333333;">
</view>
<view class="">
<input type="number" v-model="datas.form.amount" placeholder="请输入金额" />
<view class="">
</view>
</view>
</view>
<up-button text="确认" @tap="callTabletakeNumberEvent" type="primary" class="buttomStyle"
shape="circle"></up-button>
</view>
</up-popup>
</template>
<script setup>
import {
reactive,
ref,
watch,
onMounted
} from 'vue';
import go from '@/commons/utils/go.js';
import myUser from './components/user.vue'
import infoBox from "@/commons/utils/infoBox.js"
import * as $Api from '@/http/yskApi/shop-user.js'
import API from '../../http/classApi';
import {
onShow,
} from '@dcloudio/uni-app';
import {
midfiyAccount
} from '@/http/yskApi/requestAll.js';
import {
onReachBottom
} from '@dcloudio/uni-app';
import {
hasPermission
} from '@/commons/utils/hasPermission.js';
let tabsCurrent = ref(0)
const tabsList = ['用户列表', '导入用户']
const remarkModel = ref(null)
const phoneModel = ref(null)
const moreOperate = ref(null)
let datas = reactive({
show: false,
form: {
operationType: 'in',
type: 'inMoney'
},
activeUser: null
})
let close = () => {
datas.form = {
operationType: 'in',
type: 'inMoney'
}
}
const confirm = () => {
datas.show = false;
};
function toAddUser() {
go.to('PAGES_USER_ADD')
}
let callTabletakeNumberEvent = async () => {
let res = await midfiyAccount({
id: datas.activeUser.id,
...datas.form
})
datas.show = false;
close()
getUser()
}
const remarModelData = reactive({
remark: ''
})
const phoneModelData = reactive({
phone: ''
})
function sizeChange(e, name) {
datas.form[name] = e.detail.value
if (name == 'operationType') {
if (datas.form.operationType == 'in') {
datas.form.type = 'inMoney'
} else {
datas.form.type = 'consumeOut'
}
}
}
const goodsStockModel = ref(null)
const moreOperateList = ['增减余额', '修改信息', ]
function moreOperateClick(d) {
datas.activeUser = pageData.userList[d]
moreOperate.value.open()
}
onReachBottom(() => {
++page.value
getUser()
});
function actionSheetClick(i) {
if (i == 0) {
hasPermission('允许修改会员余额').then(ele => {
if (ele) {
datas.show = true
}
})
} else if (i == 1) {
hasPermission('允许管理会员信息').then(ele => {
if (ele) {
go.to('PAGES_USER_ADD', datas.activeUser)
}
})
}
}
//修改备注弹窗展示
function bindMoblieClick() {
phoneModel.value.open()
}
//修改备注弹窗展示
function userRemarkClick() {
remarkModel.value.open()
}
//修改备注弹窗确认
function remarkModelConfirm() {
}
//修改手机号弹窗确认
function phoneModelConfirm() {
}
function returnGoodsStockData() {
return reactive({
sort: 0,
openStock: false,
number: 0,
})
}
let goodsStockData = returnGoodsStockData()
function goodsStockModelClose() {
console.log('goodsStockModelClose');
goodsStockData = returnGoodsStockData()
}
function goodsStockModelCancel() {
console.log('goodsStockModelCancel');
goodsStockModel.value.close()
}
function goodsStockModelSave() {
console.log('goodsStockModelSave');
}
//点击修改按钮弹出修改商品弹窗
function goodsChangeClick(index) {
console.log(index);
goodsStockModel.value.open()
}
function statesTableClick(index) {
pageData.stateCurrent = index
}
function states1TableClick(index) {
pageData.stateCurrent1 = index
}
let test = ref(false)
function tabsChange(i) {
console.log(i);
tabsCurrent.value = i
}
const pageData = reactive({
modelDesc: '是否下架',
stateCurrent: 0,
stateCurrent1: 0,
componentBottom: 264,
search: {
value: '',
placeholder: '搜索昵称、手机号码'
},
showGoodsDetail: false,
userList: [],
allShopInfo: {
balanceTotal: 0,
chageTotal: 0,
userTotal: 0
}
})
//改变商品的选中状态
function changeGoodsChecked(checked, index) {
if (index !== undefined) {
pageData.userList[index].checked = checked
} else {
pageData.userList.map(v => {
v.checked = checked
})
}
control.value.setisSelectAll(isAllChecked() ? true : false)
}
// 获取已经选中的商品
function getChechkeduserList() {
return pageData.userList.filter(v => v.checked)
}
//是否全部选中
function isAllChecked() {
return getChechkeduserList().length === pageData.userList.length
}
// 是否有商品选中
function isHasChekdGoods() {
return getChechkeduserList().length ? true : false
}
function searchFunc() {
page.value = 0
getUser()
}
let showChecked = ref(false)
//商品start
function goodsRadioClick(index) {
var checked = !pageData.userList[index].checked
changeGoodsChecked(checked, index)
}
//下架
function offShelf() {
const hasCheckedArr = getChechkeduserList()
const hasChecked = isHasChekdGoods()
if (!hasChecked) {
return infoBox.showToast('您还没有选中商品!')
}
model.value.open()
}
//商品end
// 页数改变事件
function pageChange(page) {
console.log(page);
}
//分类
const category = ref(null)
function toggleCategory() {
category.value.toggle()
}
function cateClick(cate) {
console.log(cate);
}
let page = ref(0)
async function getUser() {
const {
content
} = await $Api.queryAllShopUser({
isVip: 1,
size: 10,
page: page.value,
name: pageData.search.value
})
if (page.value == 0) {
pageData.userList = content
} else {
pageData.userList.push(...content)
}
}
async function getAllShopInfo() {
const res = await $Api.queryAllShopInfo()
pageData.allShopInfo = res
}
onShow(() => {
getUser()
getAllShopInfo()
})
</script>
<style scoped>
page {
background: #F9F9F9;
}
</style>
<style lang="scss" scoped>
.after-r,
.after-l {
position: relative;
}
.line-l-r {
position: relative;
&::after,
&:before {
position: absolute;
content: '';
top: 0;
bottom: 0;
width: 2px;
border-radius: 2px;
background-color: rgba(255, 255, 255, .3);
}
&::after {
right: 0;
}
&::before {
left: 0;
}
}
.after-r::after {
position: absolute;
content: '';
right: -40rpx;
top: 0;
bottom: 0;
width: 2px;
border-radius: 2px;
background-color: rgba(255, 255, 255, .3);
}
.data-statistics {
background-color: $my-main-color;
padding: 30rpx 30rpx 60rpx 40rpx;
color: #fff;
border-radius: 16rpx;
}
.user-statistics {
padding: 30rpx 0 60rpx 0;
.after-r::after {
right: 0;
}
.u-flex-1 {}
}
.stock-btns {
padding: 0 100rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
}
.safe-page {
background: #F9F9F9;
}
.icon-guige {
width: 42rpx;
height: 42rpx;
}
.bg-fff {
background-color: #fff;
}
.myTabs {
margin: 0 auto;
height: 64rpx;
}
.input-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 26rpx;
background-color: $J-bg-ff;
.input-main {
flex: 1;
display: flex;
align-items: center;
height: 64rpx;
image {
padding: 22rpx;
width: 26rpx;
height: 26rpx;
}
input {
flex: 1;
font-size: 27rpx;
}
::v-deep uni-button {
font-size: 28rpx;
color: $my-main-color;
background: rgba(255, 255, 255, 1);
}
::v-deep.uni-easyinput {
.uni-easyinput__content {
background-color: $J-bg-f5 !important;
border-radius: $J-b-r12;
.uni-easyinput__content-input {
padding-left: 0 !important;
.uni-input-input {
border-radius: $J-b-r12 !important;
overflow: hidden !important;
}
}
.uni-input-placeholder {
font-size: 27rpx;
}
.uni-icons {
color: rgba(230, 230, 230, 1) !important;
}
}
}
}
}
.zhezhaopop {
padding: 34rpx 32rpx;
width: 594rpx;
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
>view:first-child {
display: flex;
align-items: center;
justify-content: space-between;
>span:nth-child(2) {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
}
>view:nth-child(2) {
margin: 48rpx auto;
width: 492rpx;
height: 124rpx;
background: #FAFAFA;
border-radius: 12rpx 12rpx 12rpx 12rpx;
}
.zhezhaopopthree {
>view:nth-child(2) {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 24rpx;
>view {
width: 186rpx;
height: 56rpx;
line-height: 56rpx;
text-align: center;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
border: 2rpx solid #E5E5E5;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #666666;
}
.selectvalue {
color: #318AFE;
border: 2rpx solid #318AFE;
}
}
}
.zhezhaopopfour {
margin-top: 32rpx;
margin-bottom: 48rpx;
>view:nth-child(2) {
margin-top: 24rpx;
display: flex;
align-items: center;
>input {
width: 372rpx;
height: 84rpx;
background: #FFFFFF;
border-radius: 8rpx 0rpx 0rpx 8rpx;
border: 2rpx solid #E5E5E5;
padding-left: 24rpx;
}
>view {
width: 124rpx;
height: 86rpx;
line-height: 84rpx;
text-align: center;
background: #F7F7FA;
border-radius: 0rpx 8rpx 8rpx 0rpx;
border: 2rpx solid #E5E5E5;
color: #999999;
}
}
}
.buttomStyle {
margin-top: 48rpx;
width: 506rpx;
height: 80rpx;
/*#ifdef MP*/
padding-top: 48rpx;
/*#endif*/
}
}
.input-icon {
position: relative;
z-index: 10;
}
.search-button {
position: absolute;
right: 0;
background-color: transparent !important;
color: transparent !important;
}
.states1 {
margin-top: 78rpx;
.item {
font-size: 24rpx;
color: #666;
margin-right: 70rpx;
background: #F4F4F4;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
.item.active {
background: #E6F0FF;
color: $my-main-color;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
}
.fixed_b {
left: 90rpx;
right: 90rpx;
position: fixed;
bottom: calc(70rpx + env(safe-area-inset-bottom));
}
</style>