Files
ss-tiku-manage-h5/src/pages/account/quota.vue

574 lines
11 KiB
Vue
Raw Normal View History

2026-01-29 18:29:34 +08:00
<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">
<input
v-model="totalQuota"
type="number"
class="quota-input"
placeholder="请输入总额度"
min="0"
max="1000"
/>
<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.name }}</view>
<view class="distributor-id">ID: {{ distributor.id }}</view>
</view>
<view class="quota-control">
<input
v-model="distributor.quota"
type="number"
class="quota-input"
placeholder="0"
min="0"
:max="maxDistributorQuota"
/>
<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"
// 当前月份
const currentMonth = ref('2026-01')
const currentMonthDisplay = ref('2026年01月')
// 总额度
const totalQuota = ref(100)
// 分销员列表
const distributors = ref([
{
id: 1,
name: '张分销',
quota: 30
},
{
id: 2,
name: '李分销',
quota: 25
},
{
id: 3,
name: '王分销',
quota: 20
},
{
id: 4,
name: '刘分销',
quota: 15
}
])
// 计算单个分销员最大可分配额度
const maxDistributorQuota = computed(() => {
return Math.floor(totalQuota.value * 0.5)
})
// 计算已分配额度
const allocatedQuota = computed(() => {
return distributors.value.reduce((sum, distributor) => {
return sum + parseInt(distributor.quota || 0)
}, 0)
})
// 计算剩余额度
const remainingQuota = computed(() => {
return totalQuota.value - allocatedQuota.value
})
// 返回上一页
function goBack() {
uni.navigateBack({ delta: 1 })
}
// 月份变更
function onMonthChange(e) {
currentMonth.value = e.detail.value
const date = new Date(e.detail.value)
currentMonthDisplay.value = `${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, '0')}`
// 实际项目中应根据选择的月份加载对应的额度配置
// loadQuotaByMonth(currentMonth.value)
}
// 保存配额
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: '保存中...' })
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '保存成功',
icon: 'success'
})
// 实际项目中应调用接口保存配额配置
// saveQuotaConfig()
}, 1500)
}
onMounted(() => {
// 实际项目中应从接口获取分销员列表和当前月份的配额配置
// loadDistributors()
// 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;
}
2026-01-30 14:08:23 +08:00
/* 平板和大屏响应式 */
@media screen and (min-width: 768px) {
2026-01-29 18:29:34 +08:00
.quota-manage-container {
max-width: 900px;
margin: 0 auto;
2026-01-30 14:08:23 +08:00
width: 100%;
}
.filter-section {
margin: 0 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;
2026-01-29 18:29:34 +08:00
}
.quota-input {
2026-01-30 14:08:23 +08:00
width: 180rpx;
height: 80rpx;
2026-01-29 18:29:34 +08:00
font-size: 28rpx;
2026-01-30 14:08:23 +08:00
padding: 0 20rpx;
}
.quota-unit {
font-size: 26rpx;
}
.quota-hint {
font-size: 22rpx;
2026-01-29 18:29:34 +08:00
}
.distributor-name {
font-size: 28rpx;
}
2026-01-30 14:08:23 +08:00
.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;
}
2026-01-29 18:29:34 +08:00
}
</style>