需求列表状态刷新优化
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
});
|
||||
|
||||
// 客户签约时,附件展示开发者签约时上传的附件,仅可预览,不可删除和上传
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/>
|
||||
</view>
|
||||
|
||||
<t-input label="总费用" placeholder="请输入总费用" suffix="元" align="right" type="number" tips="{{source == 'dev' ? '预计到手金额 ' + actualAccount + '元 + 10%的平台服务费' : '总费用 = 首付款50% + 尾款50%'}}" disabled="{{source != 'dev'}}" value="{{formData.totalCost}}" bind:change="onTotalCostChange" />
|
||||
<t-input label="总费用" placeholder="请输入总费用" suffix="元" align="right" type="number" tips="{{source == 'dev' ? '预计到手金额 ' + actualAccount + '元 + ' + commissionPercent + '%的平台服务费' : '总费用 = 首付款50% + 尾款50%'}}" disabled="{{source != 'dev'}}" value="{{formData.totalCost}}" bind:change="onTotalCostChange" />
|
||||
<t-input label="开发工期" placeholder="请输入开发工期" suffix="天" align="right" type="number" disabled="{{source != 'dev'}}" value="{{formData.needDays}}" bind:change="onDevelopmentPeriodChange" />
|
||||
</view>
|
||||
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
</t-collapse-panel>
|
||||
<t-collapse-panel header="{{opType=='quote' ? '我的报价' : '开发人员报价'}}" value="{{3}}" expandIcon>
|
||||
<view>
|
||||
<t-input style="--td-input-border-color: rgb(238, 116, 2);" placeholder="填写报价金额" suffix="元" align="right" type="number" value="{{opType=='quote' ? demandInfo.myBidding.quoted_price || demandInfo.demand_contracts.total_amount ||quotedPrice : demandInfo.winBidding.quoted_price}}" disabled="{{opType=='quote' && (!demandInfo.myBidding && !demandInfo.demand_contracts) ? false : true}}" tips="{{opType=='quote' && actualAccount > 0 ? '预计到手金额 ' + actualAccount + '元 + 10%的平台服务费' : ''}}" data-field="quotedPrice" bindchange="onInputChange">
|
||||
<t-input style="--td-input-border-color: rgb(238, 116, 2);" placeholder="填写报价金额" suffix="元" align="right" type="number" value="{{opType=='quote' ? demandInfo.myBidding.quoted_price || demandInfo.demand_contracts.total_amount ||quotedPrice : demandInfo.winBidding.quoted_price}}" disabled="{{opType=='quote' && (!demandInfo.myBidding && !demandInfo.demand_contracts) ? false : true}}" tips="{{opType=='quote' && actualAccount > 0 ? '预计到手金额 ' + actualAccount + '元 + ' + commissionPercent + '%的平台服务费' : ''}}" data-field="quotedPrice" bindchange="onInputChange">
|
||||
<view slot="label" class="custom-label">报价</view>
|
||||
</t-input>
|
||||
<t-input placeholder="填写预计工期" suffix="天" align="right" disabled="{{opType=='quote' && (!demandInfo.myBidding && !demandInfo.demand_contracts) ? false : true}}" type="number" value="{{opType=='quote' ? demandInfo.myBidding.need_days || demandInfo.demand_contracts.need_days || needDays : demandInfo.winBidding.need_days}}" data-field="needDays" bindchange="onInputChange">
|
||||
|
||||
@@ -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<number>}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user