743 lines
32 KiB
PHP
743 lines
32 KiB
PHP
<?php
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\common\model\Demands;
|
|
use app\common\traits\ServiceTrait;
|
|
use Exception;
|
|
use think\Db;
|
|
use think\Log;
|
|
|
|
class DemandService
|
|
{
|
|
use ServiceTrait;
|
|
|
|
/** @var Demands */
|
|
public static $Model = Demands::class;
|
|
|
|
// 订单状态
|
|
const STATUS_NO = 0; //关闭
|
|
const STATUS_BIDDING = 1; //招标中
|
|
const STATUS_SIGNING = 2; //签约中
|
|
const STATUS_WORKING = 3; //工作中
|
|
const STATUS_ACCEPTING = 4; //验收中
|
|
const STATUS_CONFIRM_RECEIPT = 5; //待收货
|
|
const STATUS_FINISHED = 6; //已完成
|
|
const STATUS_CANCEL = 7; //已取消
|
|
|
|
const STATUS_MAP = [
|
|
self::STATUS_NO => '已关闭',
|
|
self::STATUS_BIDDING => '招标中',
|
|
self::STATUS_SIGNING => '签约中',
|
|
self::STATUS_WORKING => '工作中',
|
|
self::STATUS_ACCEPTING => '验收中',
|
|
self::STATUS_CONFIRM_RECEIPT => '待收货',
|
|
self::STATUS_FINISHED => '已完成',
|
|
self::STATUS_CANCEL => '已取消',
|
|
];
|
|
|
|
const PUBLISH_STATUS_MAP = [
|
|
CommonService::NO => '',
|
|
CommonService::ONGOING => '审核中',
|
|
CommonService::SUCCESS => '已发布',
|
|
CommonService::FAILED => '发布失败',
|
|
];
|
|
|
|
const WORK_STATUS_MAP = [
|
|
CommonService::NO => '',
|
|
CommonService::ONGOING => '工作中',
|
|
CommonService::SUCCESS => '工作完成',
|
|
CommonService::FAILED => '工作失败',
|
|
];
|
|
|
|
const ACCEPT_STATUS_MAP = [
|
|
CommonService::NO => '',
|
|
CommonService::ONGOING => '验收中',
|
|
CommonService::SUCCESS => '验收通过',
|
|
CommonService::FAILED => '验收失败',
|
|
];
|
|
|
|
const SETTLE_STATUS_MAP = [
|
|
CommonService::NO => '',
|
|
CommonService::ONGOING => '结算中',
|
|
CommonService::SUCCESS => '结算完成',
|
|
CommonService::FAILED => '结算失败',
|
|
];
|
|
|
|
const BUTTON_CONFIRM = 'confirm';//确认接单
|
|
const BUTTON_CONTRACT_DEV = 'contractDev'; //开发者签约
|
|
const BUTTON_CONTRACT_CUSTOMER = 'contractCustomer'; //客户签约
|
|
const BUTTON_COMPLETE_WORK = 'completeWork'; //完成工作
|
|
const BUTTON_ACCEPT_PASSED = 'acceptPassed'; //验收通过
|
|
const BUTTON_CONFIRM_RECEIPT = 'confirmReceipt'; //确认收货
|
|
const BUTTON_DELIVER_GOODS = 'deliverGoods'; //开发者发货
|
|
|
|
/**
|
|
* 创建需求
|
|
*
|
|
* @param array $data 需求数据
|
|
* @param int $userId 用户ID
|
|
* @return bool
|
|
* @throws Exception
|
|
*/
|
|
public static function create($data, $userId)
|
|
{
|
|
$saveData = [
|
|
'type' => 0,
|
|
'user_id' => $userId,
|
|
'parent_order_no' => generate_order_sn(),
|
|
'title' => mb_substr($data['desc'], 0, 16),
|
|
'desc' => $data['desc'],
|
|
'develop_type' => $data['develop_type'] ?? '',
|
|
'contact' => $data['contact'],
|
|
'images' => $data['images'] ?? [],
|
|
'files' => $data['files'] ?? [],
|
|
'budget_amount' => $data['budget_amount'] ?? 0,
|
|
'limit_time' => $data['limit_time'] ?? 0,
|
|
'publish_status' => CommonService::ONGOING,
|
|
'status' => self::STATUS_NO
|
|
];
|
|
|
|
$result = self::$Model::create($saveData);
|
|
if (!$result) {
|
|
throw new Exception('需求保存失败');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @throws
|
|
*/
|
|
public static function operateDemand($requestData, $userId)
|
|
{
|
|
$opType = $requestData['opType'] ?? 0;
|
|
switch ($opType) {
|
|
case self::BUTTON_CONFIRM:
|
|
$res = self::confirmDemand($requestData, $userId);
|
|
break;
|
|
case self::BUTTON_CONTRACT_DEV:
|
|
$res = self::devContract($requestData, $userId);
|
|
break;
|
|
case self::BUTTON_CONTRACT_CUSTOMER:
|
|
$res = self::customerContract($requestData);
|
|
break;
|
|
case self::BUTTON_COMPLETE_WORK:
|
|
$res = self::completeWork($requestData, $userId);
|
|
break;
|
|
case self::BUTTON_ACCEPT_PASSED:
|
|
$res = self::acceptPassed($requestData);
|
|
break;
|
|
case self::BUTTON_CONFIRM_RECEIPT:
|
|
$res = self::confirmReceipt($requestData, $userId);
|
|
break;
|
|
case self::BUTTON_DELIVER_GOODS:
|
|
$res = self::deliverGoods($requestData, $userId);
|
|
break;
|
|
default:
|
|
throw new \Exception('非法操作');
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 确认接单
|
|
* @param $requestData
|
|
* @param int $userId
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public static function confirmDemand($requestData, int $userId = 0)
|
|
{
|
|
try {
|
|
$demandId = $requestData['demandId'] ?? 0;
|
|
$agree = intval($requestData['agree'] ?? 0);
|
|
$demand = self::getOne(['id' => $demandId]);
|
|
if (!$demand) {
|
|
throw new \Exception('该需求不存在');
|
|
}
|
|
Db::startTrans();
|
|
if (!in_array($demand->status, [self::STATUS_BIDDING])) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能不能确认');
|
|
}
|
|
$userInfo = UserService::getOne(['id' => $userId]);
|
|
$where = ['demand_id' => $demandId, 'user_id' => $userId, 'bidding_status' => DemandBiddingService::STATUS_BIDDING_WIN, 'process_status' => DemandBiddingService::STATUS_PROCESS_ONGOING];
|
|
$demandBidding = DemandBiddingService::getOne($where);
|
|
if (!$demandBidding) {
|
|
throw new \Exception('您无需确认');
|
|
}
|
|
//修改投标状态
|
|
if ($agree) {
|
|
//确认接单
|
|
$upRes = DemandBiddingService::where($where)->update(['process_status' => DemandBiddingService::STATUS_PROCESS_CONFIRMED]);
|
|
if (!$upRes) {
|
|
throw new \Exception('更新投标状态失败');
|
|
}
|
|
//修改状态
|
|
$demand->status = self::STATUS_SIGNING;
|
|
$saveRes = $demand->save();
|
|
if (!$saveRes) {
|
|
exception('更新需求状态失败');
|
|
}
|
|
//更新显示二维码
|
|
DemandGroupChatService::updateQrCode($demandId);
|
|
//客户发送消息
|
|
$msgData = [
|
|
'values' => [
|
|
$userInfo->nickname,
|
|
'需求开发',
|
|
SubscribeMessageService::MSG_MAP[SubscribeMessageService::MSG_TEMP_DEMAND_MATCH_SUCCESS]['remark'],
|
|
]
|
|
];
|
|
(new EasyWeChatService())->sendMsg($demand->user_id, SubscribeMessageService::MSG_TEMP_DEMAND_MATCH_SUCCESS, $msgData);
|
|
} else {
|
|
//拒绝接单
|
|
$upRes = DemandBiddingService::where($where)->update(['bidding_status' => DemandBiddingService::STATUS_BIDDING_NO, 'process_status' => DemandBiddingService::STATUS_PROCESS_FAILED]);
|
|
if (!$upRes) {
|
|
throw new \Exception('更新投标状态失败');
|
|
}
|
|
//扣除信誉分5分,添加日志
|
|
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_CREDIT_SCORE, $userId, 5, '拒绝接单扣除', 0, AccountLogService::CREDIT_TYPE_DEMAND_REFUSE, AccountLogService::INC_EXP_EXPEND, $demandId);
|
|
AccountService::updateData($userId, 0, 0, -5, 0, $log_res->id);
|
|
}
|
|
Db::commit();
|
|
$info = DemandBiddingService::getOne($where);
|
|
return $info;
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 开发者签约
|
|
* @param $requestData
|
|
* @param int $userId
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public static function devContract($requestData, int $userId)
|
|
{
|
|
try {
|
|
$demandId = $requestData['demandId'] ?? 0;
|
|
$agree = intval($requestData['agree'] ?? 0);
|
|
$demand = self::getOne(['id' => $demandId]);
|
|
if (!$demand) {
|
|
throw new \Exception('该需求不存在');
|
|
}
|
|
Db::startTrans();
|
|
if ($agree) {
|
|
if (!in_array($demand->status, [self::STATUS_SIGNING])) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能不能签约');
|
|
}
|
|
//生成两个订单,签约记录
|
|
OrderService::createDemandOrder($requestData);
|
|
Db::commit();
|
|
//给客户发送签约提醒
|
|
$msgData = [
|
|
'values' => [
|
|
$demand->parent_order_no,
|
|
mb_substr($demand->desc, 0, 6),
|
|
intval($requestData['formData']['totalCost'] ?? 0),
|
|
SubscribeMessageService::MSG_MAP[SubscribeMessageService::MSG_TEMP_CONTRACT_SIGN]['remark'],
|
|
]
|
|
];
|
|
(new EasyWeChatService)->sendMsg($demand->user_id, SubscribeMessageService::MSG_TEMP_CONTRACT_SIGN, $msgData);
|
|
} else {
|
|
//拒绝签约
|
|
//中标去除
|
|
$where = ['demand_id' => $demandId, 'user_id' => $userId, 'bidding_status' => DemandBiddingService::STATUS_BIDDING_WIN];
|
|
$upRes = DemandBiddingService::where($where)->update(['bidding_status' => DemandBiddingService::STATUS_BIDDING_NO]);
|
|
if (!$upRes) {
|
|
exception('更新中标状态失败');
|
|
}
|
|
//扣除信誉分5分,添加日志
|
|
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_CREDIT_SCORE, $userId, 5, '放弃签约扣除', 0, AccountLogService::CREDIT_TYPE_CONTRACT_REFUSE, AccountLogService::INC_EXP_EXPEND, $demandId);
|
|
AccountService::updateData($userId, 0, 0, -5, 0, $log_res->id);
|
|
//订单状态还原
|
|
$demand->status = self::STATUS_BIDDING;
|
|
$demand->save();
|
|
Db::commit();
|
|
}
|
|
|
|
return $demand;
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 客户签约
|
|
* @param $requestData
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public static function customerContract($requestData)
|
|
{
|
|
try {
|
|
$demandId = $requestData['demandId'] ?? 0;
|
|
$contractType = $requestData['contractType'] ?? 1;
|
|
$demand = self::getOne(['id' => $demandId]);
|
|
$formData = $requestData['formData'] ?? [];
|
|
if (!$demand) {
|
|
throw new \Exception('该需求不存在');
|
|
}
|
|
Db::startTrans();
|
|
if (!in_array($demand->status, [self::STATUS_SIGNING])) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能签约');
|
|
}
|
|
//更新签约记录
|
|
$winContract = ContractService::updateCustomerContractData($demandId, $formData);
|
|
//如果新的合同金额与旧的合同金额不符,则通过修改尾款订单的金额的方式来弥补差价
|
|
$firstContract = ContractService::getFirstContract($demandId);
|
|
if ($firstContract && $firstContract->total_amount != $winContract->total_amount && $winContract->status2 != ContractService::STATUS_FINISHED) {
|
|
$diffAmount = $winContract->total_amount - $firstContract->total_amount;
|
|
//更新尾款订单的金额
|
|
$finalOrder = OrderService::getDemandOrder($demand->parent_order_no, OrderService::ORDER_TYPE_FINAL_PAYMENT);
|
|
$finalOrder->total_amount += $diffAmount;
|
|
$finalOrder->goods_amount += $diffAmount;
|
|
$finalOrder->payment_amount += $diffAmount;
|
|
$saveRes = $finalOrder->save();
|
|
if (!$saveRes) {
|
|
exception('弥补订单差价金额失败');
|
|
}
|
|
}
|
|
//获取签约订单用于支付
|
|
$order = OrderService::getDemandOrder($demand->parent_order_no, $contractType);
|
|
if (!$order) {
|
|
throw new \Exception('获取签约订单失败');
|
|
}
|
|
//如果客户已支付预付款,则直接调用支付成功的处理
|
|
if (in_array($order->order_status, [OrderService::ORDER_STATUS_WAIT_SHIP])) {
|
|
self::customerContractFinishedDeal(0, $demandId);
|
|
}
|
|
|
|
Db::commit();
|
|
return $order;
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 完成工作
|
|
* @param $requestData
|
|
* @param $userId
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public static function completeWork($requestData, $userId)
|
|
{
|
|
try {
|
|
$agree = intval($requestData['agree'] ?? 0);
|
|
$demandId = $requestData['demandId'] ?? 0;
|
|
$demand = self::getOne(['id' => $demandId]);
|
|
if (!$demand) {
|
|
throw new \Exception('该需求不存在');
|
|
}
|
|
Db::startTrans();
|
|
if ($agree) {
|
|
//完成工作
|
|
if (!in_array($demand->status, [self::STATUS_WORKING])) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能完成');
|
|
}
|
|
$demand->status = self::STATUS_ACCEPTING;
|
|
$demand->work_status = CommonService::SUCCESS;
|
|
$demand->accept_status = CommonService::ONGOING;
|
|
$demand->save();
|
|
Db::commit();
|
|
//给客户发送验收通知
|
|
$msgData = [
|
|
'values' => [
|
|
$demand->parent_order_no,
|
|
mb_substr($demand->desc, 0, 6),
|
|
mb_substr($demand->desc, 0, 11),
|
|
SubscribeMessageService::MSG_MAP[SubscribeMessageService::MSG_TEMP_WORK_ACCEPT]['remark'],
|
|
]
|
|
];
|
|
(new EasyWeChatService())->sendMsg($demand->user_id, SubscribeMessageService::MSG_TEMP_WORK_ACCEPT, $msgData);
|
|
} else {
|
|
//完成失败
|
|
//中标去除
|
|
$where = ['demand_id' => $demandId, 'user_id' => $userId, 'bidding_status' => DemandBiddingService::STATUS_BIDDING_WIN];
|
|
$upRes = DemandBiddingService::where($where)->update(['bidding_status' => DemandBiddingService::STATUS_BIDDING_NO]);
|
|
if (!$upRes) {
|
|
exception('更新中标状态失败');
|
|
}
|
|
//扣除信誉分5分,添加日志
|
|
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_CREDIT_SCORE, $userId, 10, '需求完成失败-信誉分扣除', 0, AccountLogService::CREDIT_TYPE_DEMAND_FAILED, AccountLogService::INC_EXP_EXPEND, $demandId);
|
|
AccountService::updateData($userId, 0, 0, -10, 0, $log_res->id);
|
|
//冻结余额退回
|
|
AccountService::freezeAmountRefund($demandId, $userId);
|
|
Db::commit();
|
|
//等待客服操作是否取消订单或重新安排开发人员
|
|
}
|
|
|
|
return $demand;
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 验收通过
|
|
* @param $requestData
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public static function acceptPassed($requestData)
|
|
{
|
|
try {
|
|
$demandId = $requestData['demandId'] ?? 0;
|
|
$contractType = $requestData['contractType'] ?? 2;
|
|
$agree = $requestData['agree'] ?? 0;
|
|
$reason = $requestData['reason'] ?? '';
|
|
$demand = self::getOne(['id' => $demandId], ['winBidding']);
|
|
if (!$demand) {
|
|
throw new \Exception('该需求不存在');
|
|
}
|
|
Db::startTrans();
|
|
if (!in_array($demand->status, [self::STATUS_ACCEPTING])) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能验收');
|
|
}
|
|
if (!$agree) {
|
|
//驳回重新工作
|
|
$demand->status = self::STATUS_WORKING;
|
|
$demand->work_status = CommonService::ONGOING;
|
|
$demand->accept_status = CommonService::FAILED;
|
|
$saveRes = $demand->save();
|
|
if (!$saveRes) {
|
|
exception('更新需求状态失败');
|
|
}
|
|
//给开发者发送验收失败的通知
|
|
$msgData = [
|
|
'values' => [
|
|
'整体功能验收',
|
|
'验收失败',
|
|
SubscribeMessageService::MSG_MAP[SubscribeMessageService::MSG_TEMP_WORK_ACCEPT_RESULT]['remarkFail'],
|
|
mb_substr($reason, 0, 16) ?: '需求未按要求完成开发'
|
|
]
|
|
];
|
|
(new EasyWeChatService)->sendMsg($demand->winBidding->user_id, SubscribeMessageService::MSG_TEMP_WORK_ACCEPT_RESULT, $msgData);
|
|
} else {
|
|
//返回订单用于支付尾款
|
|
$order = OrderService::getDemandOrder($demand->parent_order_no, $contractType);
|
|
if (!$order) {
|
|
throw new \Exception('获取签约订单失败');
|
|
}
|
|
}
|
|
Db::commit();
|
|
return $order ?? [];
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 开发者发货(交付开发成果)
|
|
* 凭证截图、交付附件与备注写入订单发货表,尾款订单转为已发货(待收货)
|
|
* @param $requestData
|
|
* @param $userId
|
|
* @return bool
|
|
* @throws Exception
|
|
*/
|
|
public static function deliverGoods($requestData, $userId)
|
|
{
|
|
try {
|
|
$demandId = $requestData['demandId'] ?? 0;
|
|
$images = array_values($requestData['images'] ?? []);
|
|
$files = array_values($requestData['files'] ?? []);
|
|
$remark = trim($requestData['remark'] ?? '');
|
|
Db::startTrans();
|
|
if (!$images || !$files) {
|
|
throw new \Exception('请上传开发完成的凭证截图和交付附件');
|
|
}
|
|
$demand = self::getOne(['id' => $demandId], ['winBidding']);
|
|
if (!$demand) {
|
|
throw new \Exception('该需求不存在');
|
|
}
|
|
if ($demand->status != self::STATUS_CONFIRM_RECEIPT) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能发货');
|
|
}
|
|
if (!$demand->winBidding || $demand->winBidding->user_id != $userId) {
|
|
throw new \Exception('只有中标开发者才能发货');
|
|
}
|
|
//尾款订单必须已支付(待发货)才能发货
|
|
$finalOrder = OrderService::getDemandOrder($demand->parent_order_no, OrderService::ORDER_TYPE_FINAL_PAYMENT);
|
|
if (!$finalOrder) {
|
|
throw new \Exception('获取尾款订单失败');
|
|
}
|
|
if ($finalOrder->order_status != OrderService::ORDER_STATUS_WAIT_SHIP) {
|
|
throw new \Exception('该订单为' . OrderService::ORDER_STATUS_MAP[$finalOrder->order_status] . ',不能发货');
|
|
}
|
|
//交付内容写入订单发货表
|
|
$spuId = $finalOrder->orderGoods[0]->spu_id ?? 0;
|
|
OrderShipService::createDemandDelivery($finalOrder->order_no, $spuId, $demandId, $images, $files, $remark);
|
|
//尾款订单改为已发货(待收货)
|
|
$upRes = OrderService::where(['id' => $finalOrder->id])->update(['order_status' => OrderService::ORDER_STATUS_SHIPPED]);
|
|
if (!$upRes) {
|
|
exception('更新发货状态失败');
|
|
}
|
|
Db::commit();
|
|
//给客户发送发货通知
|
|
$msgData = [
|
|
'values' => [
|
|
$finalOrder->order_no,
|
|
mb_substr($demand->title, 0, 20),
|
|
'已发货',
|
|
'开发成果已交付,请到需求详情查看交付内容并确认收货',
|
|
]
|
|
];
|
|
(new EasyWeChatService)->sendMsg($demand->user_id, SubscribeMessageService::MSG_TEMP_ORDER_SHIPPED, $msgData);
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 确认收货
|
|
* @param $requestData
|
|
* @param $userId
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public static function confirmReceipt($requestData, $userId)
|
|
{
|
|
try {
|
|
$demandId = $requestData['demandId'] ?? 0;
|
|
$demand = self::getOne(['id' => $demandId, 'user_id' => $userId]);
|
|
if (!$demand) {
|
|
throw new \Exception('该需求不存在');
|
|
}
|
|
Db::startTrans();
|
|
if (!in_array($demand->status, [self::STATUS_CONFIRM_RECEIPT])) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能确认收货');
|
|
}
|
|
//订单完成
|
|
$demand->status = self::STATUS_FINISHED;
|
|
$demand->settle_status = CommonService::ONGOING; //结算中
|
|
//返回订单用于支付尾款
|
|
$saveRes = $demand->save();
|
|
if (!$saveRes) {
|
|
exception('更新需求状态失败');
|
|
}
|
|
//关联订单状态改为已完成
|
|
$upRes = OrderService::where(['parent_order_no' => $demand->parent_order_no])->update(['order_status' => OrderService::ORDER_STATUS_FINISHED]);
|
|
if (!$upRes) {
|
|
exception('更新订单状态失败');
|
|
}
|
|
Db::commit();
|
|
return $demand;
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 客户签约并支付成功处理需求
|
|
* @param $parent_order_no
|
|
* @param int $demandId
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
public static function customerContractFinishedDeal($parent_order_no, int $demandId = 0)
|
|
{
|
|
$where = function ($query) use ($parent_order_no, $demandId) {
|
|
$query->where('parent_order_no', $parent_order_no)->whereOr('id', $demandId);
|
|
};
|
|
$demand = self::getOne($where, ['winBidding']);
|
|
if ($demand) {
|
|
//更新客户的签约状态 $demand->id
|
|
$contract = ContractService::getWinBiddingContract($demand->id);
|
|
//如果客户已经签约过,则跳过防止重复给开发者增加冻结金额
|
|
if ($contract->status2 == ContractService::STATUS_FINISHED) {
|
|
return;
|
|
}
|
|
$contract->status2 = ContractService::STATUS_FINISHED;
|
|
$contract->save();
|
|
//更新需求的状态
|
|
$demand->status = self::STATUS_WORKING;
|
|
$demand->save();
|
|
$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);
|
|
$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);
|
|
//给开发者发送开始工作的消息通知
|
|
$msgData = [
|
|
'values' => [
|
|
mb_substr($demand->desc, 0, 6),
|
|
date('Y.m.d', strtotime('+1 days')) . ' ~ ' . date('Y.m.d', strtotime("+$contract->need_days days")),
|
|
SubscribeMessageService::MSG_MAP[SubscribeMessageService::MSG_TEMP_WORK_START]['remark'],
|
|
]
|
|
];
|
|
(new EasyWeChatService)->sendMsg($userId, SubscribeMessageService::MSG_TEMP_WORK_START, $msgData);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 客户验收完成处理需求
|
|
* @param $parent_order_no
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
public static function customerWorkAcceptFinishedDeal($parent_order_no)
|
|
{
|
|
$demand = self::getOne(['parent_order_no' => $parent_order_no], ['winBidding']);
|
|
if ($demand && $demand->status == self::STATUS_ACCEPTING && $demand->accept_status != CommonService::SUCCESS) {
|
|
//更新需求的状态
|
|
$demand->status = self::STATUS_CONFIRM_RECEIPT;
|
|
$demand->accept_status = CommonService::SUCCESS;
|
|
$demand->accept_time = time();
|
|
$saveRes = $demand->save();
|
|
if (!$saveRes) {
|
|
exception('更新验收状态失败');
|
|
}
|
|
$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);
|
|
$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);
|
|
//给开发者发送验收结果的消息通知
|
|
$msgData = [
|
|
'values' => [
|
|
'整体功能验收',
|
|
'验收通过',
|
|
SubscribeMessageService::MSG_MAP[SubscribeMessageService::MSG_TEMP_WORK_ACCEPT_RESULT]['remark'],
|
|
'功能验收完成'
|
|
]
|
|
];
|
|
(new EasyWeChatService)->sendMsg($demand->winBidding->user_id, SubscribeMessageService::MSG_TEMP_WORK_ACCEPT_RESULT, $msgData);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 重新投标
|
|
* @param $demand
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public static function resetBiddingDeal($demand)
|
|
{
|
|
try {
|
|
Db::startTrans();
|
|
if (in_array($demand->status, [self::STATUS_CONFIRM_RECEIPT, self::STATUS_FINISHED, self::STATUS_CANCEL])) {
|
|
throw new \Exception('该需求为' . self::STATUS_MAP[$demand->status] . ',不能重新投标');
|
|
}
|
|
if (in_array($demand->settle_status, [CommonService::SUCCESS])) {
|
|
throw new \Exception('该需求为' . self::SETTLE_STATUS_MAP[$demand->settle_status] . ',不能重新投标');
|
|
}
|
|
$demandId = $demand->id;
|
|
$where = ['demand_id' => $demandId, 'bidding_status' => DemandBiddingService::STATUS_BIDDING_WIN];
|
|
$winBidding = DemandBiddingService::where($where)->find();
|
|
if ($winBidding) {
|
|
//中标去除
|
|
$winBidding->bidding_status = DemandBiddingService::STATUS_BIDDING_NO;
|
|
$upRes = $winBidding->save();
|
|
if (!$upRes) {
|
|
exception('更新中标状态失败');
|
|
}
|
|
$userId = $winBidding->user_id;
|
|
//扣除信誉分5分,添加日志
|
|
$log_res = AccountLogService::addLog(AccountLogService::ACCOUNT_TYPE_CREDIT_SCORE, $userId, 5, '系统自动操作-信誉分扣除', 0, AccountLogService::CREDIT_TYPE_ADMIN_OPERATE, AccountLogService::INC_EXP_EXPEND, $demandId);
|
|
AccountService::updateData($userId, 0, 0, -5, 0, $log_res->id);
|
|
//冻结余额退回
|
|
AccountService::freezeAmountRefund($demandId, $userId);
|
|
}
|
|
//继续投标,重置状态
|
|
$demand->status = self::STATUS_BIDDING;
|
|
$demand->work_status = CommonService::NO;
|
|
$demand->accept_status = CommonService::NO;
|
|
$demand->settle_status = CommonService::NO;
|
|
$saveRes = $demand->save();
|
|
if (!$saveRes) {
|
|
exception('更新需求状态失败');
|
|
}
|
|
Db::commit();
|
|
return $demand;
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 处理订单收益解冻
|
|
*/
|
|
public static function unfreeze()
|
|
{
|
|
//
|
|
$where = [
|
|
'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) {
|
|
foreach ($demands as $demand) {
|
|
try {
|
|
//开启事务 抛出异常时自动回滚
|
|
DB::transaction(function () use ($demand, $ratio) {
|
|
$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')]);
|
|
if (time() > strtotime(date('Y-m-d', strtotime('+1 day', strtotime($show_time) + 3 * 3600)) . ' 09:00')) {
|
|
$demand->status = DemandService::STATUS_FINISHED;
|
|
$demand->settle_status = CommonService::SUCCESS;
|
|
$demand->save();
|
|
$amount = ($demand->demandContracts->total_amount ?? 0) * (1 - $ratio);
|
|
//写入余额日志
|
|
$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);
|
|
//减去冻结,加到余额里面
|
|
AccountService::updateData($userId, $amount, -$amount, 0, 0, $log_res->id);
|
|
//发送余额解冻通知
|
|
}
|
|
});
|
|
} catch (\Exception $e) {
|
|
Log::info('需求结算处理异常:' . json_encode(['file' => $e->getFile(), 'line' => $e->getLine(), 'error' => $e->getMessage(), 'demand' => $demand], JSON_UNESCAPED_UNICODE));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 审核
|
|
* @param $id
|
|
* @return void
|
|
*/
|
|
public static function auditPass($id)
|
|
{
|
|
Db::transaction(function () use ($id) {
|
|
$demand = self::getOne(['id' => $id]);
|
|
if (!$demand) {
|
|
exception('该需求不存在');
|
|
}
|
|
if ($demand->publish_status == CommonService::SUCCESS) {
|
|
exception('已经审核通过,请勿重复审核');
|
|
}
|
|
//修改审核状态
|
|
$demand->status = self::STATUS_BIDDING;
|
|
$demand->publish_status = CommonService::SUCCESS;
|
|
$saveRes = $demand->save();
|
|
if (!$saveRes) {
|
|
exception('更新审核状态失败');
|
|
}
|
|
//发送审核结果-站内消息通知
|
|
});
|
|
}
|
|
} |