| | |
| | | <!-- 标题 --> |
| | | <view class="header"> |
| | | <text class="title">用户列表</text> |
| | | |
| | | </view> |
| | | <view> |
| | | <button class="add-btn" @click="navigateToAdd()">新增用户</button> |
| | | <button class="add-btn" @click="navigateToAdd()" :disabled="!isShopkeeper">新增用户</button> |
| | | </view> |
| | | <!-- 搜索框 --> |
| | | <view class="search-box"> |
| | | <u-search v-model="query.realName" placeholder="搜索姓名" :showAction="false" @change="searchUser()"></u-search> |
| | | <u-search v-model="query.realName" placeholder="搜索姓名" :showAction="false" @change="searchClerk()"></u-search> |
| | | </view> |
| | | |
| | | <!-- 用户列表 --> |
| | | <scroll-view scroll-y class="user-list" @scrolltolower="loadMore" v-if="userList.length > 0"> |
| | | <view class="user-item" v-for="(user, index) in userList" :key="user.id" > |
| | | <scroll-view scroll-y class="clerk-list" @scrolltolower="loadMore" v-if="clerkList.length > 0"> |
| | | <view class="clerk-item" v-for="(clerk, index) in clerkList" :key="clerk.id" > |
| | | |
| | | <view class="user-info"> |
| | | <text class="realName">{{ user.realName }}</text> |
| | | <text class="mobile">{{ user.mobile }}</text> |
| | | <view class="clerk-info"> |
| | | <text class="realName">{{ clerk.realName ? clerk.realName: '未设置人名' }}</text> |
| | | <text class="mobile">{{ clerk.mobile }}</text> |
| | | </view> |
| | | <!-- 操作按钮区域 --> |
| | | <view class="action-buttons"> |
| | | <u-button type="primary" size="mini" @click.stop="navigateToDetail(user.id)" class="edit-btn">修改</u-button> |
| | | <u-button type="error" size="mini" @click.stop="deleteUser(user.id)" |
| | | class="delete-btn">删除</u-button> |
| | | </view> |
| | | <u-button type="primary" size="mini" @click.stop="restPassword(clerk.memberId)" class="edit-btn" :disabled="!checkPermission(clerk)">重置密码</u-button> |
| | | <u-button type="primary" size="mini" @click.stop="navigateToDetail(clerk.id)" class="edit-btn" :disabled="!checkPermission(clerk)">修改</u-button> |
| | | <u-button type="error" size="mini" @click.stop="deleteUser(clerk.id)" |
| | | class="delete-btn" :disabled="!checkPermission(clerk)">删除</u-button> |
| | | </view> |
| | | |
| | | </view> |
| | | |
| | | <!-- 加载更多提示 --> |
| | | <view class="load-more" v-if="loading"> |
| | | <u-loading :show="loading"></u-loading> |
| | | |
| | | <view class="load-more"> |
| | | <u-loadmore |
| | | v-if="clerkList.length > 0" |
| | | :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" |
| | | :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" |
| | | /> |
| | | </view> |
| | | <view class="load-more" v-if="noMoreData"> |
| | | <text>没有更多数据了</text> |
| | | <view style="height:150rpx"> |
| | | |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <!-- 空状态 --> |
| | | <view class="empty" v-else> |
| | | <text>暂无用户数据</text> |
| | | </view> |
| | | |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | getPage, |
| | | del, |
| | | add, |
| | | update |
| | | update, |
| | | restPassword, |
| | | checkClerkPermission |
| | | } from "@/api/userPermissions.js" |
| | | import UIcon from '@/uview-components/uview-ui/components/u-icon/u-icon.vue'; |
| | | import UButton from '@/uview-components/uview-ui/components/u-button/u-button.vue'; |
| | |
| | | import UInput from '@/uview-components/uview-ui/components/u-input/u-input.vue'; |
| | | import USearch from '@/uview-components/uview-ui/components/u-search/u-search.vue'; |
| | | import UPopup from '@/uview-components/uview-ui/components/u-popup/u-popup.vue'; |
| | | import ULoading from '@/uview-components/uview-ui/components/u-loading/u-loading.vue' |
| | | import ULoading from '@/uview-components/uview-ui/components/u-loading/u-loading.vue'; |
| | | import ULoadmore from '@/uview-components/uview-ui/components/u-loadmore/u-loadmore.vue'; |
| | | |
| | | |
| | | import storage from "@/utils/storage.js"; //缓存 |
| | | import { |
| | | getUserInfo |
| | | } from "@/api/members"; |
| | | |
| | | export default { |
| | | components: { |
| | | UIcon, |
| | |
| | | UInput, |
| | | USearch, |
| | | UPopup, |
| | | ULoading |
| | | ULoading, |
| | | ULoadmore, |
| | | }, |
| | | data() { |
| | | return { |
| | | userList: [], // 用户列表数据 |
| | | total:0, |
| | | clerkList: [], // 用户列表数据 |
| | | loading: false, // 加载状态 |
| | | noMoreData: false, // 是否没有更多数据 |
| | | noMore: false, // 是否没有更多数据 |
| | | query: { |
| | | realName: '', |
| | | page: 1, |
| | | pageSize: 10, |
| | | } |
| | | |
| | | |
| | | pageNumber: 1, |
| | | pageSize: 15, |
| | | }, |
| | | isSuper:false, |
| | | isShopkeeper:false, |
| | | clerkId:'',//登录账号id |
| | | } |
| | | }, |
| | | onShow() { |
| | |
| | | }, |
| | | onLoad() { |
| | | this.getPage() |
| | | //获得用户权限 |
| | | checkClerkPermission().then(res=>{ |
| | | this.isSuper = res.data.data.isSuper; |
| | | this.isShopkeeper = res.data.data.isShopkeeper; |
| | | this.clerkId = res.data.data.clerkId; |
| | | }) |
| | | |
| | | }, |
| | | |
| | | methods: { |
| | | //检查权限 |
| | | checkPermission(clerk){ |
| | | if(this.isShopkeeper){ |
| | | return true; |
| | | } |
| | | if(this.clerkId === clerk.id){ |
| | | return true; |
| | | }else{ |
| | | if(this.isSuper && !clerk.isSuper){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | }, |
| | | restPassword(id){ |
| | | restPassword(id).then(res=>{ |
| | | if(res.statusCode === 200){ |
| | | uni.showToast({ |
| | | title: res.data.msg, // 提示文字 |
| | | icon: 'none', // 图标类型(success/loading/none) |
| | | mask: true // 是否显示透明蒙层(防止触摸穿透) |
| | | }); |
| | | } |
| | | }) |
| | | }, |
| | | async getPage() { |
| | | // |
| | | uni.showLoading({ |
| | |
| | | getPage(this.query).then(res => { |
| | | uni.hideLoading(); |
| | | if (res.statusCode === 200) { |
| | | const data = res.data.data; |
| | | if (this.query.page === 1) { |
| | | this.userList = data || []; |
| | | } else { |
| | | // 否则追加数据 |
| | | this.userList = [...this.userList, ...(data || [])]; |
| | | |
| | | } |
| | | const newData = res.data.data; |
| | | // 更新总数据量 |
| | | this.total = res.data.total || 0; |
| | | // 追加或替换数据 |
| | | this.clerkList = this.query.pageNumber === 1 ? |
| | | newData : |
| | | [...this.clerkList, ...newData]; |
| | | |
| | | // 判断是否还有更多数据 |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.clerkList.length >= this.total; |
| | | |
| | | } |
| | | }) |
| | | |
| | |
| | | }, |
| | | |
| | | // 搜索用户 |
| | | searchUser() { |
| | | this.query.page = 1 |
| | | this.noMoreData = false |
| | | this.userList = [] |
| | | searchClerk() { |
| | | this.query.pageNumber = 1 |
| | | this.noMore = false |
| | | this.clerkList = [] |
| | | this.getPage() |
| | | }, |
| | | |
| | | // 加载更多 |
| | | loadMore() { |
| | | if (!this.noMoreData) { |
| | | this.query.page++ |
| | | if (!this.noMore) { |
| | | this.query.pageNumber++ |
| | | this.getPage() |
| | | } |
| | | }, |
| | |
| | | this.getPage(); |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | |
| | | |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .user-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 20rpx; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | | } |
| | | |
| | | .user-info { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .action-buttons { |
| | | display: flex; |
| | | margin-left: 20rpx; |
| | |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .user-list { |
| | | .clerk-list { |
| | | flex: 1; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .user-item { |
| | | .clerk-item { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 20rpx; |
| | |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .user-info { |
| | | .clerk-info { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .load-more { |
| | | padding: 20rpx; |
| | | text-align: center; |
| | | color: #999; |
| | | font-size: 28rpx; |
| | | } |
| | | padding: 20rpx 0; |
| | | text-align: center; |
| | | color: #999; |
| | | font-size: 26rpx; |
| | | background-color: #f7f8fa; |
| | | } |
| | | |
| | | .empty { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 40rpx; |
| | | |
| | | image { |
| | | width: 200rpx; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | text { |
| | | color: #999; |
| | | font-size: 28rpx; |
| | | } |
| | | } |
| | | </style> |