Files
ss-tiku-manage-h5/src/pages/account/quota.vue
2026-02-26 11:04:40 +08:00

565 lines
11 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="quota-manage-container">
<!-- 页面标题 -->
<view class="page-header">
<view class="header-left" @click="goBack">
<view class="back-icon"></view>
</view>
<view class="header-title">赠会员额度分配</view>
<view class="header-right" @click="saveQuota">
<view class="save-btn">保存</view>
</view>
</view>
<!-- 筛选条件 -->
<view class="filter-section">
<view class="filter-row">
<view class="filter-item">
<view class="filter-label">选择月份</view>
<view class="filter-control">
<picker
mode="date"
fields="month"
:value="currentMonth"
start="2026-01"
end="2026-12"
@change="onMonthChange"
class="picker"
>
<view class="picker-text">{{ currentMonthDisplay }}</view>
</picker>
</view>
</view>
</view>
</view>
<!-- 总额度设置 -->
<view class="total-quota-section">
<view class="section-title">总额度设置</view>
<view class="quota-card">
<view class="quota-item">
<view class="quota-label">月度赠会员总额度</view>
<view class="quota-control">
<view class="quota-value">{{ totalQuota }}</view>
<view class="quota-unit"></view>
</view>
</view>
<view class="quota-hint">
总额度将分配给所有分销员
单个分销员最高可分配额度为总额度的50%
</view>
</view>
</view>
<!-- 分销员额度分配 -->
<view class="distributor-quota-section">
<view class="section-title">分销员额度分配</view>
<view class="quota-list">
<view
v-for="(distributor, index) in distributors"
:key="distributor.id"
class="quota-item"
>
<view class="distributor-info">
<view class="distributor-name">{{ distributor.distributorName }}</view>
<view class="distributor-id">ID: {{ distributor.distributorId }}</view>
</view>
<view class="quota-control">
<input
v-model="distributor.num"
type="number"
class="quota-input"
placeholder="0"
min="0"
:max="maxDistributorQuota(distributor.num)"
/>
<view class="quota-unit"></view>
</view>
</view>
</view>
</view>
<!-- 配额统计 -->
<view class="quota-stats">
<view class="stats-item">
<view class="stats-label">已分配额度</view>
<view class="stats-value">{{ allocatedQuota }} </view>
</view>
<view class="stats-item">
<view class="stats-label">剩余额度</view>
<view class="stats-value" :class="{ 'warning': remainingQuota < 0 }">
{{ remainingQuota }}
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from "vue"
import { getQuotaInfoWithUser, saveQuotaInfo, getQuotaList } from "@/api/member/quota"
// 当前月份
const currentMonth = ref(new Date().toISOString().substring(0, 7))
const currentMonthDisplay = ref(new Date().toISOString().substring(0, 7))
// 总额度
const totalQuota = ref(100)
// 分销员列表
const distributors = ref([])
const loadCurrentMonthQuota = () => {
getQuotaInfoWithUser({
year: currentMonth.value.split('-')[0],
month: currentMonth.value.split('-')[1]
}).then(res => {
totalQuota.value = res.data.num || 0
})
getQuotaList({
year: currentMonth.value.split('-')[0],
month: currentMonth.value.split('-')[1]
}).then(res => {
distributors.value = res.data || []
})
}
// 计算已分配额度
const allocatedQuota = computed(() => {
return distributors.value.reduce((sum, distributor) => {
return sum + parseInt(distributor.num || 0)
}, 0)
})
// 计算剩余额度
const remainingQuota = computed(() => {
return totalQuota.value - allocatedQuota.value
})
const maxDistributorQuota = (count) => {
return remainingQuota.value ? count + remainingQuota.value : count
}
// 返回上一页
function goBack() {
uni.navigateBack({ delta: 1 })
}
// 月份变更
function onMonthChange(e) {
currentMonth.value = e.detail.value
const date = new Date(e.detail.value)
currentMonthDisplay.value = new Date(date).toISOString().substring(0, 7)
loadCurrentMonthQuota()
}
// 保存配额
function saveQuota() {
if (!totalQuota.value || totalQuota.value <= 0) {
uni.showToast({
title: '请设置有效的总额度',
icon: 'none'
})
return
}
if (remainingQuota.value < 0) {
uni.showToast({
title: '已分配额度超过总额度',
icon: 'none'
})
return
}
uni.showLoading({ title: '保存中...' })
saveQuotaInfo({
year: currentMonth.value.split('-')[0],
month: currentMonth.value.split('-')[1],
nums: distributors.value.map(distributor => {
return {
distributorId: distributor.distributorId,
num: distributor.num
}
})
}).then(() => {
uni.hideLoading()
uni.showToast({
title: '保存成功',
icon: 'success'
})
})
}
onMounted(() => {
loadCurrentMonthQuota()
})
</script>
<style lang="scss" scoped>
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #f5f7fa;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
.quota-manage-container {
flex: 1;
display: flex;
flex-direction: column;
}
/* 页面头部 */
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 120rpx;
background-color: #fff;
padding: 0 32rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.header-left {
width: 60rpx;
}
.back-icon {
font-size: 40rpx;
color: #303133;
cursor: pointer;
}
.header-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
}
.header-right {
width: 60rpx;
text-align: right;
}
.save-btn {
font-size: 28rpx;
color: #409eff;
font-weight: 600;
cursor: pointer;
}
/* 筛选条件 */
.filter-section {
padding: 24rpx 32rpx;
background-color: #fff;
margin: 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.filter-row {
display: flex;
gap: 16rpx;
}
.filter-item {
flex: 1;
}
.filter-label {
font-size: 24rpx;
color: #606266;
margin-bottom: 8rpx;
}
.filter-control {
background-color: #f9f9f9;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
}
.picker {
display: flex;
justify-content: space-between;
align-items: center;
}
.picker-text {
font-size: 24rpx;
color: #303133;
}
/* 通用部分样式 */
.total-quota-section,
.distributor-quota-section {
padding: 32rpx;
background-color: #fff;
margin: 0 16rpx 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
margin-bottom: 24rpx;
padding-left: 12rpx;
border-left: 8rpx solid #409eff;
line-height: 1.2;
}
/* 总额度设置 */
.quota-card {
background-color: #f9f9f9;
border-radius: 12rpx;
padding: 24rpx;
}
.quota-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.quota-label {
font-size: 24rpx;
color: #606266;
}
.quota-control {
display: flex;
align-items: center;
gap: 8rpx;
}
.quota-input {
width: 120rpx;
height: 60rpx;
background-color: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 0 16rpx;
text-align: center;
font-size: 24rpx;
}
.quota-unit {
font-size: 24rpx;
color: #606266;
}
.quota-hint {
font-size: 20rpx;
color: #909399;
margin-top: 16rpx;
line-height: 1.4;
}
/* 分销员额度分配 */
.quota-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.distributor-info {
flex: 1;
margin-right: 24rpx;
}
.distributor-name {
font-size: 24rpx;
font-weight: 600;
color: #303133;
margin-bottom: 4rpx;
}
.distributor-id {
font-size: 20rpx;
color: #909399;
}
/* 配额统计 */
.quota-stats {
display: flex;
justify-content: space-around;
padding: 24rpx;
background-color: #fff;
margin: 0 16rpx 32rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.stats-item {
display: flex;
align-items: center;
gap: 8rpx;
}
.stats-label {
font-size: 24rpx;
color: #606266;
}
.stats-value {
font-size: 28rpx;
font-weight: bold;
color: #303133;
}
.stats-value.warning {
color: #f56c6c;
}
/* 平板和大屏响应式 */
@media screen and (min-width: 768px) {
.quota-manage-container {
max-width: 900px;
margin: 0 auto;
width: 100%;
}
.filter-section {
margin: 32rpx 24rpx;
padding: 32rpx;
}
.total-quota-section,
.distributor-quota-section {
margin: 0 32rpx 24rpx;
padding: 40rpx;
}
.quota-stats {
margin: 0 32rpx 32rpx;
padding: 32rpx;
}
.section-title {
font-size: 36rpx;
margin-bottom: 32rpx;
}
.filter-label {
font-size: 26rpx;
}
.picker-text {
font-size: 26rpx;
}
.filter-control {
padding: 20rpx;
}
.quota-item {
margin-bottom: 24rpx;
}
.quota-label {
font-size: 26rpx;
}
.quota-input {
width: 180rpx;
height: 80rpx;
font-size: 28rpx;
padding: 0 20rpx;
}
.quota-unit {
font-size: 26rpx;
}
.quota-hint {
font-size: 22rpx;
}
.distributor-name {
font-size: 28rpx;
}
.distributor-id {
font-size: 22rpx;
}
.stats-label {
font-size: 26rpx;
}
.stats-value {
font-size: 32rpx;
}
.quota-list {
gap: 24rpx;
}
}
/* 大屏设备响应式 */
@media screen and (min-width: 1024px) {
.quota-manage-container {
max-width: 1000px;
}
.section-title {
font-size: 40rpx;
}
.filter-label {
font-size: 28rpx;
}
.picker-text {
font-size: 28rpx;
}
.quota-label {
font-size: 28rpx;
}
.quota-input {
width: 200rpx;
height: 90rpx;
font-size: 32rpx;
}
.quota-unit {
font-size: 28rpx;
}
.quota-hint {
font-size: 24rpx;
}
.distributor-name {
font-size: 32rpx;
}
.distributor-id {
font-size: 24rpx;
}
.stats-label {
font-size: 28rpx;
}
.stats-value {
font-size: 36rpx;
}
}
</style>