diff --git a/backend/application/api/controller/Common.php b/backend/application/api/controller/Common.php
index 6069d23..a9111a8 100644
--- a/backend/application/api/controller/Common.php
+++ b/backend/application/api/controller/Common.php
@@ -7,6 +7,7 @@ use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\model\Area;
use app\common\model\Version;
+use app\common\service\DemandService;
use fast\Random;
use think\captcha\Captcha;
use think\Config;
@@ -189,6 +190,8 @@ class Common extends Api
'backendLabels' => $toLabels($back_techs),
'otherLabels' => $toLabels($other_techs),
'developTypes' => $developTypes,
+ // 平台服务费比例(0~1),前端据此计算开发者预计到手金额
+ 'platform_commission_ratio' => (float)DemandService::getPlatformCommissionRatio(),
];
$this->success('', $config);
diff --git a/backend/application/common/service/DemandService.php b/backend/application/common/service/DemandService.php
index 52c6dfb..da27180 100644
--- a/backend/application/common/service/DemandService.php
+++ b/backend/application/common/service/DemandService.php
@@ -72,6 +72,36 @@ class DemandService
const BUTTON_CONFIRM_RECEIPT = 'confirmReceipt'; //确认收货
const BUTTON_DELIVER_GOODS = 'deliverGoods'; //开发者发货
+ /**
+ * 获取平台服务费比例(0~1),后台填写大于 1 时按百分比处理,如 10 表示 10%
+ * @return string
+ */
+ public static function getPlatformCommissionRatio(): string
+ {
+ $ratio = config('site.platform_commission_ratio');
+ if (!is_numeric($ratio) || $ratio <= 0) {
+ return '0';
+ }
+ $ratio = (string)$ratio;
+ if (bccomp($ratio, '1', 4) > 0) {
+ $ratio = bcdiv($ratio, '100', 4);
+ }
+
+ return bccomp($ratio, '1', 4) > 0 ? '1' : bcadd($ratio, '0', 4);
+ }
+
+ /**
+ * 计算扣除平台服务费后开发者实得金额
+ * @param mixed $amount 订单金额(元)
+ * @return string
+ */
+ public static function getDeveloperIncome($amount): string
+ {
+ $ratio = self::getPlatformCommissionRatio();
+
+ return bcmul((string)$amount, bcsub('1', $ratio, 4), 2);
+ }
+
/**
* 创建需求
*
@@ -600,8 +630,7 @@ class DemandService
$userId = $contract->demandBidding->user_id;
//开发者冻结金额增加
$demandOrder = OrderService::getDemandOrder($demand->parent_order_no, OrderService::ORDER_TYPE_FIRST_PAYMENT);
- $ratio = (float)config('site.platform_commission_ratio');
- $amount = $demandOrder->payment_amount * (1 - $ratio);
+ $amount = self::getDeveloperIncome($demandOrder->payment_amount);
$title = OrderService::ORDER_TYPE_MAP[$demandOrder->order_type] ?? '需求收益';
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_FREEZE, $userId, $amount, $title . '-冻结金额增加', AccountLogService::TYPE_FREEZE, 0, AccountLogService::INC_EXP_INCREASE, $demandOrder->id);
AccountService::updateData($userId, 0, $amount, 0, 0, $log_res->id);
@@ -638,8 +667,7 @@ class DemandService
$userId = $demand->winBidding->user_id;
//开发者冻结金额增加
$demandOrder = OrderService::getDemandOrder($demand->parent_order_no, OrderService::ORDER_TYPE_FINAL_PAYMENT);
- $ratio = (float)config('site.platform_commission_ratio');
- $amount = $demandOrder->payment_amount * (1 - $ratio);
+ $amount = self::getDeveloperIncome($demandOrder->payment_amount);
$title = OrderService::ORDER_TYPE_MAP[$demandOrder->order_type] ?? '需求收益';
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_FREEZE, $userId, $amount, $title . '-冻结金额增加', AccountLogService::TYPE_FREEZE, 0, AccountLogService::INC_EXP_INCREASE, $demandOrder->id);
AccountService::updateData($userId, 0, $amount, 0, 0, $log_res->id);
@@ -728,12 +756,11 @@ class DemandService
'order_status' => DemandService::STATUS_CONFIRM_RECEIPT,
'settle_status' => CommonService::ONGOING,
];
- $ratio = (float)config('site.platform_commission_ratio');
- Demands::with(['demandContracts', 'winBidding'])->where($where)->chunk(100, function ($demands) use ($ratio) {
+ Demands::with(['demandContracts', 'winBidding'])->where($where)->chunk(100, function ($demands) {
foreach ($demands as $demand) {
try {
//开启事务 抛出异常时自动回滚
- DB::transaction(function () use ($demand, $ratio) {
+ DB::transaction(function () use ($demand) {
$userId = $demand->merchant->user_id;
$show_time = $demand->goodsInfo->show_time ? $demand->goodsInfo->show_time : $demand->goodsInfo->created_at;
Log::info('订单收益解冻:', ['show_time' => $show_time, 'unfreeze_time' => strtotime(date('Y-m-d', strtotime($show_time) + 3 * 3600) . ' 09:00')]);
@@ -741,7 +768,7 @@ class DemandService
$demand->status = DemandService::STATUS_FINISHED;
$demand->settle_status = CommonService::SUCCESS;
$demand->save();
- $amount = ($demand->demandContracts->total_amount ?? 0) * (1 - $ratio);
+ $amount = self::getDeveloperIncome($demand->demandContracts->total_amount ?? 0);
//写入余额日志
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_FREEZE, -$amount, '需求收益解冻-冻结扣除', AccountLogService::TYPE_UNFREEZE, 0, $demand->id, $demand->order_amount);
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_AMOUNT, +$amount, '需求收益解冻-余额增加', AccountLogService::TYPE_UNFREEZE, 0, $demand->id, $demand->order_amount);
diff --git a/frontend/miniapp/pages/demand/contract/index.js b/frontend/miniapp/pages/demand/contract/index.js
index deae751..792e928 100644
--- a/frontend/miniapp/pages/demand/contract/index.js
+++ b/frontend/miniapp/pages/demand/contract/index.js
@@ -1,5 +1,6 @@
import { fetchDemandContractDetail, demandOperate } from '../../../services/demand/fetchDemand';
+import { fetchPlatformCommissionRatio, calcActualAccount } from '../../../services/home/home';
// pages/demand/contract/index.js
Page({
@@ -9,6 +10,8 @@ Page({
data: {
demandId: 0,
actualAccount: 0,
+ commissionRatio: 0.1, // 平台服务费比例,来自 common/getMiniConfig
+ commissionPercent: 10, // 平台服务费百分比,用于提示文案
contract: null,
agreementUrl: '', // 签约条款URL
phoneError: '', // 个人联系电话错误提示
@@ -61,6 +64,17 @@ Page({
agreementUrl
});
this.getContractDetail();
+ this.loadCommissionRatio();
+ },
+
+ // 拉取平台服务费比例,并按新比例重算预计到手金额
+ async loadCommissionRatio() {
+ const ratio = await fetchPlatformCommissionRatio();
+ this.setData({
+ commissionRatio: ratio,
+ commissionPercent: Math.round(ratio * 10000) / 100,
+ actualAccount: calcActualAccount(this.data.formData?.totalCost, ratio)
+ });
},
/**
@@ -191,10 +205,9 @@ Page({
},
onTotalCostChange(e) {
- const number = Number(e.detail.value * 0.9);
this.setData({
'formData.totalCost': e.detail.value,
- 'actualAccount': Math.round(e.detail.value * 0.9)
+ actualAccount: calcActualAccount(e.detail.value, this.data.commissionRatio)
});
},
@@ -518,6 +531,7 @@ Page({
'formData.taskContent': resData.task_content,
'formData.needDays': resData.need_days,
'formData.totalCost': resData.total_amount,
+ actualAccount: calcActualAccount(resData.total_amount, this.data.commissionRatio),
});
// 客户签约时,附件展示开发者签约时上传的附件,仅可预览,不可删除和上传
diff --git a/frontend/miniapp/pages/demand/contract/index.wxml b/frontend/miniapp/pages/demand/contract/index.wxml
index 14920e6..7ca21a2 100644
--- a/frontend/miniapp/pages/demand/contract/index.wxml
+++ b/frontend/miniapp/pages/demand/contract/index.wxml
@@ -64,7 +64,7 @@
/>
-
+
diff --git a/frontend/miniapp/pages/demand/detail/index.js b/frontend/miniapp/pages/demand/detail/index.js
index 296c600..b4b1e29 100644
--- a/frontend/miniapp/pages/demand/detail/index.js
+++ b/frontend/miniapp/pages/demand/detail/index.js
@@ -1,5 +1,6 @@
// pages/demand/detail.js
import { fetchDemandDetail, joinDemandBidding, demandOperate } from '../../../services/demand/fetchDemand';
+import { fetchPlatformCommissionRatio, calcActualAccount } from '../../../services/home/home';
Page({
/**
@@ -11,6 +12,8 @@ Page({
needDays: '',
remark: '',
actualAccount: 0,
+ commissionRatio: 0.1, // 平台服务费比例,来自 common/getMiniConfig
+ commissionPercent: 10, // 平台服务费百分比,用于提示文案
activeValues: [0, 1, 2, 3, 4],
demandInfo: null,
freshPage: false, // 返回本页时是否需要重新拉取详情(签约/发货/支付后置为 true)
@@ -33,7 +36,7 @@ Page({
const demandInfo = res.data;
this.setData({
demandInfo,
- actualAccount: parseFloat(demandInfo?.myBidding?.quoted_price || demandInfo?.demand_contracts?.total_amount || 0) * 0.9
+ actualAccount: calcActualAccount(this.getQuoteAmount(demandInfo), this.data.commissionRatio)
}, () => resolve()); // setData 回调:页面已重新渲染
},
() => {
@@ -43,6 +46,19 @@ Page({
);
});
},
+ // 报价金额:优先已投标报价,其次合同总费用,最后为当前输入
+ getQuoteAmount(demandInfo) {
+ return demandInfo?.myBidding?.quoted_price || demandInfo?.demand_contracts?.total_amount || this.data.quotedPrice || 0;
+ },
+ // 拉取平台服务费比例,并按新比例重算预计到手金额
+ async loadCommissionRatio() {
+ const ratio = await fetchPlatformCommissionRatio();
+ this.setData({
+ commissionRatio: ratio,
+ commissionPercent: Math.round(ratio * 10000) / 100,
+ actualAccount: calcActualAccount(this.getQuoteAmount(this.data.demandInfo), ratio)
+ });
+ },
// 取文件扩展名对应的 openDocument 类型(默认 pdf)
getFileType(url) {
const ext = String(url || '').split('?')[0].split('#')[0].split('.').pop().toLowerCase();
@@ -178,8 +194,7 @@ Page({
const field = e.currentTarget.dataset.field;
const value = e.detail.value;
if (field == 'quotedPrice') {
- let actualAccount = parseInt(value * 0.9);
- this.setData({ actualAccount });
+ this.setData({ actualAccount: calcActualAccount(value, this.data.commissionRatio) });
}
this.setData({
[`${field}`]: value
@@ -682,6 +697,7 @@ Page({
opType
});
this.loadDemandDetail(id);
+ this.loadCommissionRatio();
wx.$util.checkSubscriptionsSetting();
//从列表「前去验收」进入时,提示先到沟通群查看/体验交付成果再验收
if (options.fromAccept == '1') {
diff --git a/frontend/miniapp/pages/demand/detail/index.wxml b/frontend/miniapp/pages/demand/detail/index.wxml
index 0292549..bcfc571 100644
--- a/frontend/miniapp/pages/demand/detail/index.wxml
+++ b/frontend/miniapp/pages/demand/detail/index.wxml
@@ -44,7 +44,7 @@
-
+
报价
diff --git a/frontend/miniapp/services/home/home.js b/frontend/miniapp/services/home/home.js
index 2f8c91e..46de38b 100644
--- a/frontend/miniapp/services/home/home.js
+++ b/frontend/miniapp/services/home/home.js
@@ -56,3 +56,39 @@ export function fetchHome() {
export function fetchConfig() {
return wx.$util.request(wx.$api.CommonGetMiniConfig, {}, 'GET');
}
+
+// 与后端 site.platform_commission_ratio 默认值一致,接口失败时兜底
+const DEFAULT_COMMISSION_RATIO = 0.1;
+let commissionRatioCache = null;
+
+/**
+ * 获取平台服务费比例(0~1),成功后缓存,失败返回默认值且不缓存,下次重新请求
+ * @returns {Promise}
+ */
+export async function fetchPlatformCommissionRatio() {
+ if (commissionRatioCache !== null) {
+ return commissionRatioCache;
+ }
+ try {
+ const res = await fetchConfig();
+ const ratio = Number(res?.data?.platform_commission_ratio);
+ if (res.code === 1 && ratio >= 0 && ratio <= 1) {
+ commissionRatioCache = ratio;
+ return ratio;
+ }
+ } catch (err) {
+ console.error('fetchPlatformCommissionRatio failed:', err);
+ }
+ return DEFAULT_COMMISSION_RATIO;
+}
+
+/**
+ * 计算扣除平台服务费后的预计到手金额(保留两位小数)
+ * @param {number|string} amount 报价/总费用(元)
+ * @param {number} ratio 平台服务费比例
+ * @returns {number}
+ */
+export function calcActualAccount(amount, ratio) {
+ const value = Number(amount) || 0;
+ return Math.round(value * (1 - ratio) * 100) / 100;
+}