cashier_app/pageMarket/distribution/add-fenxiao-user.vue

318 lines
8.0 KiB
Vue

<template>
<view class="min-page u-font-28">
<up-sticky>
<view class="top">
<up-search
v-model="searchText"
placeholder="搜索昵称、手机号"
@clear="refresh"
@search="refresh"
@custom="refresh"
></up-search>
</view>
</up-sticky>
<view class="list u-m-t-32">
<template v-if="list.length > 0">
<view class="box">
<view
v-for="(item, index) in list"
:key="index"
class="item"
@tap="chooseUser(index, item)"
>
<view class="u-flex u-row-between u-relative">
<view class="u-flex">
<view class="headimg u-flex u-row-center u-col-center">
<image
v-if="item.headImg"
:src="item.headImg"
class="img"
mode=""
></image>
</view>
<view class="u-m-l-12">
<view class="u-flex">
<view>{{ item.nickName }}</view>
<view class="u-m-l-14">{{ item.phone }}</view>
</view>
</view>
</view>
<view class="vip" v-if="item.isVip"
>会员等级{{ item.memberLevelName }}</view
>
</view>
<view class="u-flex u-row-between">
<view class="u-m-t-16 u-flex money" style="gap: 64rpx">
<view class="">
<view class="color-333 u-font-32 font-bold">{{
item.amount
}}</view>
<view class="u-flex u-m-t-12" style="align-items: baseline">
<text class="color-666">余额</text>
<up-icon name="arrow-right" size="14"></up-icon>
</view>
</view>
<view class="">
<view class="color-333 u-font-32 font-bold">{{
item.accountPoints
}}</view>
<view class="u-flex u-m-t-12" style="align-items: baseline">
<text class="color-666">积分</text>
<up-icon name="arrow-right" size="14"></up-icon>
</view>
</view>
<view class="">
<view class="color-333 u-font-32 font-bold">{{
item.accountPoints
}}</view>
<view class="u-flex u-m-t-12" style="align-items: baseline">
<text class="color-666">优惠券</text>
<up-icon name="arrow-right" size="14"></up-icon>
</view>
</view>
</view>
<my-radio
v-if="!isFenxiaoYuan(item)"
shape="square"
@change="chooseUser(index, item)"
v-model="item.checked"
:size="18"
border-color="#d1d1d1"
></my-radio>
</view>
</view>
</view>
<view class="u-m-t-32">
<my-pagination
:page="query.page"
:totalElements="query.totalElements"
:size="query.size"
@change="pageChange"
></my-pagination>
</view>
</template>
<template v-if="hasAjax && list.length <= 0">
<my-img-empty tips="未找到相关用户"></my-img-empty>
</template>
</view>
<view class="fixed-bottom">
<view class="u-flex-1 btn">已选择{{ hasSelected.length }}名用户</view>
<view class="u-flex-1 btn" @click="back">取消</view>
<view class="u-flex-1 btn my-bg-main" @click="confirm">确认</view>
</view>
<view style="height: 160rpx"></view>
</view>
</template>
<script setup>
import { ref, onMounted, computed } from "vue";
import { shopUserList } from "@/http/api/shopUser.js";
import * as distributionApi from "@/http/api/market/distribution.js";
const searchText = ref("");
const list = ref([]);
const pageNum = ref(1);
const isEnd = ref(false);
async function getList() {
const res = await shopUserList({
page: pageNum.value,
size: 10,
key:searchText.value
});
if (res) {
if (pageNum.value == 1) {
list.value = (res.records || []).map((item) => {
item.checked = false;
return item;
});
} else {
const newArr = (res.records || []).map((item) => {
item.checked = false;
return item;
});
list.value = [...list.value, ...newArr];
}
isEnd.value = pageNum.value >= res.totalPage * 1 ? true : false;
console.log(isEnd.value);
}
}
const hasSelected = computed(() => {
return list.value.filter((item) => item.checked);
});
function refresh(){
pageNum.value = 1;
isEnd.value = false;
getList()
}
// 取消
function back() {
uni.navigateBack({
delta: 1,
});
}
// 判断是否是分销员
function isFenxiaoYuan(item) {
const isFenxiao = item.distributionShops.split("_")[1];
return isFenxiao;
}
async function confirm() {
// 保留原有的前置校验
if (hasSelected.value.length <= 0) {
uni.showToast({
title: "请选择用户",
icon: "none",
});
return;
}
try {
// 1. 构建所有请求的 Promise 数组(并行执行前提)
const requestPromises = hasSelected.value.map((item) =>
distributionApi.addDistributionUser({
id: item.id,
openingMethod: "手动添加",
shopId: uni.getStorageSync("shopId"),
userId: item.userId,
})
);
// 2. 使用 Promise.all 并行执行所有请求
// 特点:所有请求同时发起,等待全部成功后才继续执行
await Promise.all(requestPromises);
// 3. 所有请求成功后,统一提示(避免多次弹窗叠加)
uni.showToast({
title: `成功添加 ${hasSelected.value.length} 个用户`,
icon: "none",
});
refresh()
} catch (error) {
// 4. 错误处理:只要有一个请求失败,就会进入 catch
uni.showToast({
title: "添加失败,请重试",
icon: "none",
});
console.error("用户添加失败:", error); // 便于调试
}
}
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
.min-page {
background: #f7f7f7;
}
.top {
background-color: #fff;
padding: 32rpx 28rpx;
}
:deep(.u-search__action) {
display: flex;
width: 120rpx !important;
color: #fff !important;
padding: 10rpx 32rpx;
justify-content: center;
align-items: center;
gap: 20rpx;
border-radius: 32rpx;
margin-left: 78rpx !important;
background: #318afe;
}
.scale7 {
transform: scale(0.7);
}
.search {
padding-right: 28rpx;
.icon-saoma {
margin-left: 20rpx;
width: 34rpx;
height: 32rpx;
}
}
.list {
.no-choose {
padding: 36rpx 30rpx 36rpx 24rpx;
}
.box {
// padding: 32rpx 30rpx 78rpx 24rpx;
.item {
padding: 32rpx 30rpx;
margin-bottom: 16rpx;
background-color: #fff;
.headimg {
border-radius: 12rpx 12rpx 12rpx 12rpx;
font-size: 0;
width: 84rpx;
height: 84rpx;
background-color: #eee;
overflow: hidden;
.img {
width: 84rpx;
height: 84rpx;
}
}
}
}
}
.vip {
position: absolute;
top: 0;
right: 0;
color: $my-main-color;
font-size: 32rpx;
font-weight: 700;
}
.money {
padding: 16rpx 24rpx;
border-radius: 8rpx;
background: #f8f8f8;
}
.fixed-bottom {
position: fixed;
text-align: center;
padding: 0;
bottom: calc(env(safe-area-inset-bottom) + 30rpx);
left: 0;
right: 0;
z-index: 10;
border-radius: 100rpx;
background-color: #3e3a3a;
color: #fff;
display: flex;
overflow: hidden;
.btn {
padding: 16rpx;
line-height: 40rpx;
&:first-child {
position: relative;
}
&:first-child::after {
content: "";
position: absolute;
display: block;
top: 20rpx;
right: 0;
bottom: 20rpx;
width: 1px;
border-radius: 1px;
background-color: #f7f7f7aa;
}
}
}
</style>