This commit is contained in:
aaron 2025-03-10 16:14:19 +08:00
parent ac51b22378
commit 9a7052af78
2 changed files with 462 additions and 32 deletions

View File

@ -36,12 +36,7 @@
{{ formatDateTime(record.create_time) }}
</template>
<template v-if="column.key === 'qrcode'">
<a-image
v-if="record.qy_group_qrcode"
:src="record.qy_group_qrcode"
:width="50"
alt="群二维码"
/>
<a v-if="record.qy_group_qrcode" @click="previewQRCode(record.qy_group_qrcode)">查看二维码</a>
<span v-else>-</span>
</template>
<template v-if="column.key === 'delivery_price'">
@ -52,11 +47,31 @@
</div>
</div>
</template>
<template v-if="column.key === 'profit_sharing'">
<div v-if="record.profit_sharing" class="profit-sharing-info-table">
<div class="profit-rate-item">
<span class="rate-label">平台</span>
<span class="rate-value">{{ record.profit_sharing.platform_rate }}%</span>
<span class="rate-label">运营商</span>
<span class="rate-value">{{ record.profit_sharing.partner_rate }}%</span>
</div>
<div class="profit-rate-item">
<span class="rate-label">管理员</span>
<span class="rate-value">{{ record.profit_sharing.admin_rate }}%</span>
<span class="rate-label">配送员</span>
<span class="rate-value">{{ record.profit_sharing.delivery_rate }}%</span>
</div>
</div>
<a-tag v-else color="orange">未设置</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<div class="action-buttons">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a @click="handleEditDeliveryPrice(record)">配送定价</a>
</a-space>
<a-divider type="vertical" />
<a @click="handleEditProfitSharing(record)">设置分润</a>
</div>
</template>
</template>
</a-table>
@ -147,16 +162,6 @@
<div style="margin-top: 8px">上传群二维码</div>
</div>
</a-upload>
<!-- 添加预览模态框 -->
<a-modal
v-model:visible="previewVisible"
:title="previewTitle"
:footer="null"
@cancel="handlePreviewCancel"
>
<img style="width: 100%" :src="previewImage" />
</a-modal>
</div>
</a-form-item>
</a-form>
@ -219,7 +224,108 @@
</a-form-item>
</a-form>
</a-modal>
<!-- 分润设置模态框 -->
<a-modal
v-model:visible="profitSharingModalVisible"
title="分润设置"
@ok="handleProfitSharingSave"
@cancel="handleProfitSharingCancel"
:confirmLoading="profitSharingSaving"
width="500px"
>
<div class="profit-sharing-header">
<div class="profit-sharing-title">
<span>小区名称</span>
<span class="profit-sharing-community-name">{{ currentCommunityName }}</span>
</div>
<div class="profit-sharing-tip">
注意平台分润比例将自动计算确保总比例等于100%
</div>
</div>
<div class="profit-sharing-form">
<div class="profit-rate-row">
<div class="profit-rate-label">平台分润比例 (%)</div>
<div class="profit-rate-input">
<a-input-number
v-model:value="profitSharingForm.platform_rate"
:min="0"
:max="100"
:precision="0"
style="width: 100%"
disabled
class="platform-rate-input"
/>
</div>
<div class="profit-rate-tip">自动计算</div>
</div>
<div class="profit-rate-row">
<div class="profit-rate-label">运营商分润比例 (%)</div>
<div class="profit-rate-input">
<a-input-number
v-model:value="profitSharingForm.partner_rate"
:min="0"
:max="100"
:precision="0"
style="width: 100%"
placeholder="请输入"
@change="calculatePlatformRate"
/>
</div>
<div class="profit-rate-tip">运营商获得的分润</div>
</div>
<div class="profit-rate-row">
<div class="profit-rate-label">管理员分润比例 (%)</div>
<div class="profit-rate-input">
<a-input-number
v-model:value="profitSharingForm.admin_rate"
:min="0"
:max="100"
:precision="0"
style="width: 100%"
placeholder="请输入"
@change="calculatePlatformRate"
/>
</div>
<div class="profit-rate-tip">小区管理员获得的分润</div>
</div>
<div class="profit-rate-row">
<div class="profit-rate-label">配送员分润比例 (%)</div>
<div class="profit-rate-input">
<a-input-number
v-model:value="profitSharingForm.delivery_rate"
:min="0"
:max="100"
:precision="0"
style="width: 100%"
placeholder="请输入"
@change="calculatePlatformRate"
/>
</div>
<div class="profit-rate-tip">配送员获得的分润</div>
</div>
</div>
<div class="total-rate-info" :class="{ 'rate-error': !isRateValid }">
<span>总比例{{ getTotalRate() }}%</span>
<span v-if="!isRateValid" class="rate-error-message">总比例必须等于100%</span>
</div>
</a-modal>
</div>
<!-- 二维码预览模态框 -->
<a-modal
v-model:visible="previewVisible"
:title="previewTitle"
:footer="null"
@cancel="handlePreviewCancel"
>
<img style="width: 100%" :src="previewImage" />
</a-modal>
</page-container>
</template>
@ -305,10 +411,9 @@ export default defineComponent({
width: 200,
},
{
title: '地址',
dataIndex: 'address',
key: 'address',
width: 200,
title: '分润比例',
key: 'profit_sharing',
width: 220,
},
{
title: '位置',
@ -332,7 +437,7 @@ export default defineComponent({
{
title: '操作',
key: 'action',
width: 120,
width: 200,
align: 'center',
fixed: 'right'
},
@ -501,6 +606,14 @@ export default defineComponent({
//
const previewQRCode = async (file) => {
// URL
if (typeof file === 'string') {
previewImage.value = file
previewVisible.value = true
previewTitle.value = '群二维码预览'
return
}
// 使 url
if (file.url) {
previewImage.value = file.url
@ -700,6 +813,164 @@ export default defineComponent({
}
}
//
const profitSharingModalVisible = ref(false)
const profitSharingSaving = ref(false)
const currentCommunityName = ref('')
const isRateValid = ref(true)
const profitSharingForm = ref({
platform_rate: 10,
partner_rate: 10,
admin_rate: 10,
delivery_rate: 70
})
//
const handleEditProfitSharing = async (record) => {
currentCommunityId.value = record.id
currentCommunityName.value = record.name
profitSharingSaving.value = true
try {
//
const hasProfitSharing = record.profit_sharing !== null
if (hasProfitSharing) {
// 使
profitSharingForm.value = {
platform_rate: record.profit_sharing.platform_rate,
partner_rate: record.profit_sharing.partner_rate,
admin_rate: record.profit_sharing.admin_rate,
delivery_rate: record.profit_sharing.delivery_rate
}
} else {
// 使
profitSharingForm.value = {
platform_rate: 10,
partner_rate: 10,
admin_rate: 10,
delivery_rate: 70
}
}
validateTotalRate()
profitSharingModalVisible.value = true
} catch (error) {
console.error('获取分润设置失败:', error)
message.error('获取分润设置失败')
} finally {
profitSharingSaving.value = false
}
}
//
const calculatePlatformRate = () => {
const otherRatesTotal =
profitSharingForm.value.partner_rate +
profitSharingForm.value.admin_rate +
profitSharingForm.value.delivery_rate
// 100%
if (otherRatesTotal > 100) {
message.warning('其他分润比例之和不能超过100%')
return
}
//
profitSharingForm.value.platform_rate = 100 - otherRatesTotal
//
validateTotalRate()
}
//
const getTotalRate = () => {
return (
profitSharingForm.value.platform_rate +
profitSharingForm.value.partner_rate +
profitSharingForm.value.admin_rate +
profitSharingForm.value.delivery_rate
)
}
// 100%
const validateTotalRate = () => {
const total = getTotalRate()
isRateValid.value = total === 100
return isRateValid.value
}
//
const handleProfitSharingSave = async () => {
if (!validateTotalRate()) {
message.error('所有比例之和必须等于100%')
return
}
try {
profitSharingSaving.value = true
const params = {
platform_rate: profitSharingForm.value.platform_rate,
partner_rate: profitSharingForm.value.partner_rate,
admin_rate: profitSharingForm.value.admin_rate,
delivery_rate: profitSharingForm.value.delivery_rate
}
//
const currentCommunity = tableData.value.find(item => item.id === currentCommunityId.value)
const hasProfitSharing = currentCommunity && currentCommunity.profit_sharing !== null
let res
if (hasProfitSharing) {
//
res = await request.put(`/api/community-profit-sharings/community/${currentCommunityId.value}`, params)
} else {
//
res = await request.post('/api/community-profit-sharings/', {
...params,
community_id: currentCommunityId.value
})
}
if (res.code === 200) {
//
const index = tableData.value.findIndex(item => item.id === currentCommunityId.value)
if (index !== -1) {
//
if (!tableData.value[index].profit_sharing) {
tableData.value[index].profit_sharing = {}
}
tableData.value[index].profit_sharing = {
platform_rate: params.platform_rate,
partner_rate: params.partner_rate,
admin_rate: params.admin_rate,
delivery_rate: params.delivery_rate
}
}
message.success('分润设置保存成功')
profitSharingModalVisible.value = false
} else {
message.error(res.message || '保存失败')
}
} catch (error) {
console.error('保存分润设置失败:', error)
message.error('保存失败')
} finally {
profitSharingSaving.value = false
}
}
//
const handleProfitSharingCancel = () => {
profitSharingModalVisible.value = false
currentCommunityId.value = null
currentCommunityName.value = ''
}
onMounted(() => {
fetchData()
})
@ -740,7 +1011,18 @@ export default defineComponent({
deliveryPriceForm,
handleEditDeliveryPrice,
handleDeliveryPriceSave,
handleDeliveryPriceCancel
handleDeliveryPriceCancel,
profitSharingModalVisible,
profitSharingSaving,
profitSharingForm,
currentCommunityName,
isRateValid,
handleEditProfitSharing,
handleProfitSharingSave,
handleProfitSharingCancel,
getTotalRate,
validateTotalRate,
calculatePlatformRate
}
}
})
@ -1094,4 +1376,142 @@ export default defineComponent({
}
}
}
/* 添加分润设置相关的样式 */
.profit-sharing-info {
margin-bottom: 16px;
padding: 12px;
background-color: #f9f9f9;
border-radius: 4px;
}
.profit-sharing-header {
margin-bottom: 16px;
padding: 12px;
background-color: #f9f9f9;
border-radius: 4px;
}
.profit-sharing-title {
margin-bottom: 8px;
font-size: 14px;
}
.profit-sharing-community-name {
font-weight: 500;
color: #1890ff;
}
.profit-sharing-tip {
font-size: 12px;
color: #ff4d4f;
}
.profit-sharing-form {
margin-bottom: 16px;
}
.profit-rate-row {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.profit-rate-label {
width: 150px;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
}
.profit-rate-input {
width: 100px;
margin-right: 12px;
}
.profit-rate-tip {
flex: 1;
font-size: 12px;
color: rgba(0, 0, 0, 0.45);
}
.total-rate-info {
margin-top: 16px;
padding: 8px 12px;
background-color: #f6ffed;
border-radius: 4px;
border: 1px solid #b7eb8f;
color: #52c41a;
font-weight: 500;
text-align: center;
}
.rate-error {
background-color: #fff2f0;
border-color: #ffccc7;
color: #ff4d4f;
}
.rate-error-message {
margin-left: 8px;
font-weight: normal;
}
/* 表格中分润比例显示样式 */
.profit-sharing-info-table {
display: flex;
flex-direction: column;
gap: 6px;
font-size: 12px;
padding: 4px 0;
}
.profit-rate-item {
display: flex;
align-items: center;
line-height: 1.5;
}
.rate-label {
color: rgba(0, 0, 0, 0.65);
margin-right: 4px;
margin-left: 8px;
white-space: nowrap;
}
.rate-label:first-child {
margin-left: 0;
}
.rate-value {
font-weight: 500;
color: #1890ff;
margin-right: 12px;
white-space: nowrap;
}
/* 操作列按钮样式 */
.action-buttons {
display: flex;
justify-content: center;
align-items: center;
white-space: nowrap;
}
.action-buttons a {
white-space: nowrap;
}
:deep(.ant-divider-vertical) {
margin: 0 8px;
}
/* 平台分润比例输入框样式 */
.platform-rate-input {
background-color: #f5f5f5;
}
:deep(.platform-rate-input .ant-input-number-input) {
color: #1890ff;
font-weight: 500;
}
</style>

View File

@ -51,7 +51,6 @@
<a-form-item
label="运营商"
name="user_id"
:rules="[{ required: true, message: '运营商必须选择' }]"
>
<div class="user-search">
<a-input-search
@ -91,6 +90,9 @@
</a-button>
</div>
</div>
<div v-if="!selectedUser" class="no-user-selected">
<span class="tip-text">可选未选择运营商</span>
</div>
</a-form-item>
</a-form>
</a-modal>
@ -294,11 +296,6 @@ export default defineComponent({
return
}
if (!formData.user_id) {
message.warning('请选择运营商')
return
}
try {
submitting.value = true
let res
@ -307,13 +304,13 @@ export default defineComponent({
//
res = await request.put(`/api/community-sets/${editingSetId.value}`, {
set_name: formData.set_name,
user_id: formData.user_id
user_id: formData.user_id || null
})
} else {
//
res = await request.post('/api/community-sets/', {
set_name: formData.set_name,
user_id: formData.user_id
user_id: formData.user_id || null
})
}
@ -481,4 +478,17 @@ export default defineComponent({
.selected-info .user-phone {
margin-bottom: 0;
}
.no-user-selected {
margin-top: 8px;
padding: 8px 12px;
background-color: #f9f9f9;
border-radius: 4px;
border: 1px dashed #d9d9d9;
}
.tip-text {
color: #999;
font-size: 14px;
}
</style>