Files
xk-api-yii/member/modules/v1/controllers/ProductOrderController.php
2026-02-07 16:52:55 +08:00

588 lines
23 KiB
PHP

<?php
namespace member\modules\v1\controllers;
use common\core\BaseAppController;
use common\enums\ProductOrderEnum;
use common\forms\ProductCancelForm;
use common\forms\ProductRefundCancelForm;
use common\forms\ProductRefundForm;
use common\jobs\ProductOrderSyncPlatformJob;
use common\models\oldDb\Address;
use common\models\oldDb\ChineseRepice;
use common\models\oldDb\DoctorInfo;
use common\models\oldDb\GranularRepice;
use common\models\oldDb\Prescription;
use common\models\oldDb\ProductOrder;
use common\models\oldDb\ProductOrderItems;
use common\models\oldDb\Region;
use common\models\oldDb\ServicePackageRepice;
use common\models\oldDb\Store;
use common\models\oldDb\SystemConfig;
use common\models\oldDb\User;
use common\models\oldDb\WestRepice;
use common\modelsgii\oldDb\RefundReason;
use common\services\ExpressService;
use member\models\forms\ProductOrderSubmitForm;
use yii\db\Exception;
use yii\helpers\Json;
/**
* @doc-module 产品订单
*/
class ProductOrderController extends BaseAppController
{
/**
* @doc-name 列表
* @doc-desc west或chinese返回null,表示没有中药或西药,status传-1为全部
* @doc-param string keyword 搜索 / optional
* @doc-param int status 0未支付1待发货2待收货3待评价4已退款5退款中6已收货
* @doc-return mixed @List{id-int-产品id,p_id-int-处方id,total_price-float-总价格,@Content{content-string-药品信息,number-int-数量,total_price-float-单价,status-int-产品订单状态0未支付1待发货2待收货3待评价4已退款5退款中6已收货7确认收货}} 列表信息
* @doc-return mixed @Pagination{total-int-总数,totalPage-int-总页数,pageSize-float-每页条数} 分页信息
*/
public function actionList()
{
$post = \Yii::$app->request->post();
$ProductOrder = ProductOrder::find()->where([
'user_id' => \Yii::$app->user->identity->getId(),
// 'store_id' => $post['store_id'] ?? 11001
])->orderBy('created_at DESC');
switch ($post['type']) {
case 'unpaid'://未支付
$ProductOrder->andWhere([
'status' => ProductOrderEnum::UNPAY
])->all();
break;
case 'wait_send'://待发货
$ProductOrder->andWhere([
'status' => ProductOrderEnum::WAIT_SEND
])->all();
break;
case 'wait_accept'://待收货
$ProductOrder->andWhere([
'status' => ProductOrderEnum::WAIT_ACCEPT
])->all();
break;
case 'finished'://已完成(已取消、已收货、已退款、待评价)
$ProductOrder->andWhere([
'in','status',[ProductOrderEnum::CANCEL, ProductOrderEnum::ACCEPTED, ProductOrderEnum::CONFIRM,ProductOrderEnum::REFUND, ProductOrderEnum::WAIT_COMMENT]
])->all();
break;
default:
break;
}
$this->field = [
ProductOrder::class => [
'id','order_no', 'items_price','trans_expenses','decoct_price','process_price','treatement_price','total_pay_price','prescription_type', 'p_id','is_pay', 'status', 'cancel_status', 'refund_status',
'cancel_status_text' => function ($q){
return ProductOrderEnum::CANCEL_STATUS_TEXT[$q->cancel_status];
},
'refund_status_text' => function ($q){
return ProductOrderEnum::REFUND_STATUS_TEXT[$q->refund_status];
},
'status_text' => function ($q) {
return ProductOrderEnum::STATUS_TEXT[$q->status];
},
'number' => function ($q) {
return ProductOrderItems::find()->where(['product_order_id' => $q->id])->count();
},
'items' => function ($q) {
return ProductOrderItems::find()->where(['product_order_id' => $q->id])->with([
'drug' => function($q){
$q->select('function,specification');
}
])->asArray()->all();
},
'store' => function ($q) {
return Store::find()->select('id,name')->where(['id' => $q->store_id])->one();
},
'forbiddenRefund' => 1
// 'forbiddenRefund'=>function($fund){
// $config = \Yii::$app->params;
// $orderForbiddenRefundTime = isset($config['product_order']['forbidden_refund_time']) ? $config['product_order']['forbidden_refund_time'] :3600*24*7;
// if ($fund->prescription_type==1 || $fund->prescription_type==3){
// return 1;////禁止退款
// }else{
// if (time()-$fund->pay_time<=$orderForbiddenRefundTime){
// return 0;//可以退款
// }else{
// return 1;//禁止退款
// }
// }
// }
]
];
return $this->create($ProductOrder, $post);
}
//根据互医的订单编号获取萧康的订单id
public function actionOnlineToLocal(){
$param = \Yii::$app->request->get();
$this->requestValidate($param, [
[['order_no'], 'required']
]);
$productOrder = ProductOrder::find()->where([
'sync_order_no' => $param['order_no'],
'user_id' => \Yii::$app->user->identity->getId()
])->one();
if(!$productOrder){
throw new Exception('订单生成中,请稍后');
}
return ['order_id' => $productOrder->id];
}
/***
* 预约购药
*/
public function actionAppointMedicine()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['prescription_id', 'required']
]);
$ProductOrder = ProductOrder::find()->select('id,order_no,is_online,su_id,p_id,user_id,is_pay,prescription_type,address_id,address,decoct_price,order_type,items_price,process_price,treatement_price,total_pay_price,pay_method,trans_expenses,created_at,received_time,cancel_status,refund_status,status')->where([
'p_id' => $post['prescription_id'],
'user_id' => \Yii::$app->user->identity->getId(),
// 'store_id' => $post['store_id']
])->asArray()->one();
if(!$ProductOrder){
throw new Exception('订单不存在');
}
$ProductOrder['created_at'] = date('Y-m-d H:i:s', $ProductOrder['created_at']);
$forbiddenRefund = 0;
$config = \Yii::$app->params;
$orderForbiddenRefundTime = isset($config['product_order']['forbidden_refund_time']) ? $config['product_order']['forbidden_refund_time'] : 24*3600*30;
if(time() >= $orderForbiddenRefundTime + $ProductOrder['received_time']?? 0){
$forbiddenRefund = 1;
}
$ProductOrder['forbidden_refund'] = $forbiddenRefund;
$userInfo = User::find()->select('id,nickname,avatarurl')->where([
'id' => $ProductOrder['user_id']
])->asArray()->one();
$hospital = DoctorInfo::find()->select('hospital_id')->where([
'su_id' => $ProductOrder['su_id']
])->with(['hospital' => function ($h) {
$h->select('name');
}])->asArray()->one();
$prescription = Prescription::find()->select('cr_ids,wr_ids,gr_ids,category,store_id')->where(['id' => $ProductOrder['p_id']])->one();
// 获取处方来源诊所信息
$prescriptionStore = null;
if ($prescription && isset($prescription['store_id']) && $prescription['store_id']) {
$prescriptionStore = Store::find()->select('id,name,mobile,position')->where(['id' => $prescription['store_id']])->asArray()->one();
}
if($prescription && $prescription['wr_ids']){
$wr_ids = explode(',', $prescription['wr_ids']);
if ($ProductOrder['prescription_type'] == 5) {
$west = ServicePackageRepice::find()->select('content,number,total_price')->where([
'in', 'id', $wr_ids
])->all();
} else {
$west = WestRepice::find()->select('content,number,total_price')->where([
'in', 'id', $wr_ids
])->all();
}
foreach ($west as $value) {
$value['content']=Json::decode($value['content']);
}
$count = count($west);
}else if($prescription && $prescription['cr_ids']){
$cr_ids = explode(',', $prescription['cr_ids']);
$chinese = ChineseRepice::find()->select('content,total_price')->where([
'in', 'id', $cr_ids
])->all();
foreach ($chinese as $val) {
$content = Json::decode($val['content']);
foreach ($content as $v){
$chinese['list'][]= $v;
}
}
$count = count($chinese['list']);
}else{
$gr_ids = explode(',', $prescription['gr_ids']);
$granular = GranularRepice::find()->select('content,total_price')->where([
'in', 'id', $gr_ids
])->all();
foreach ($granular as $val) {
$content = Json::decode($val['content']);
foreach ($content as $v){
$granular['list'][]= $v;
}
}
$count = count($granular['list']);
}
if ($ProductOrder['p_id'] !== 0 && $ProductOrder['order_type'] !== 2) {
if ($prescription && isset($prescription['category']) && $prescription['category'] === 2) {
$ProductOrder['total_pay_price'] = $ProductOrder['trans_expenses'];
$ProductOrder['items_price'] = 0;
}
}
$ProductOrder['count'] = $count;
return [
'ProductOrder' => $ProductOrder,
'userInfo' => $userInfo,
'hospital' => $hospital,
'west' => $west ?? null,
'chinese' => $chinese ?? null,
'granular' => $granular ?? null,
'store' => $prescriptionStore ? ['store' => $prescriptionStore] : null,
];
}
/**
* 代煎服务费用信息
*/
public function actionDecoctService(){
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['order_id', 'required']
]);
$ProductOrder = ProductOrder::find()->select('dosage,prescription_type')->where([
'id' => $post['order_id'],
'user_id' => \Yii::$app->user->identity->getId(),
'store_id' => $post['store_id'],
'status' => 0,
'cancel_status' => 0
])->asArray()->one();
if(!$ProductOrder){
throw new Exception('订单信息错误');
}
if($ProductOrder['dosage'] == 0){
throw new Exception('只有中药和颗粒药订单提供代煎服务');
}
$systemConfig = SystemConfig::find()->where(['type' => $ProductOrder['prescription_type']])->one();
return [
'decoct_price' => $systemConfig->value,
'dosage' => $ProductOrder['dosage'],
'total_decoct_price' => round($ProductOrder['dosage'] * $systemConfig->value, 2)
];
}
/**
* 更新代煎服务费用
*/
public function actionUpdateDecoctService(){
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['order_id', 'required']
]);
$ProductOrder = ProductOrder::find()->where([
'id' => $post['order_id'],
'user_id' => \Yii::$app->user->identity->getId(),
'store_id' => $post['store_id'],
'status' => 0,
'cancel_status' => 0
])->one();
if(!$ProductOrder){
throw new Exception('订单信息错误');
}
if($ProductOrder['prescription_type'] == 2){
throw new Exception('只有中药和颗粒药订单提供代煎服务');
}
if($post['is_decoct'] ){ // 代煎
if(!$ProductOrder->is_decoct){
$systemConfig = SystemConfig::find()->where(['type' => $ProductOrder->prescription_type])->one();
//根据剂数计算代煎费用
$dosage = $ProductOrder->dosage;
$decoctPrice = $dosage * $systemConfig->value;
$ProductOrder->is_decoct = 1;
$ProductOrder->decoct_price = $decoctPrice;
$ProductOrder->total_pay_price = $ProductOrder->total_pay_price + $decoctPrice;
$ProductOrder->saveOrFail();
}
} else {
if($ProductOrder->is_decoct && $ProductOrder->decoct_price > 0){
$ProductOrder->is_decoct = 0;
$ProductOrder->total_pay_price = $ProductOrder->total_pay_price - $ProductOrder->decoct_price;
$ProductOrder->decoct_price = 0;
$ProductOrder->saveOrFail();
}
}
return ['success'];
}
/**
* 更新订单收货地址
*/
public function actionUpdateDelivery(){
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
[['order_id', 'delivery_method'], 'required'],
[['address_id'], 'integer']
]);
$ProductOrder = ProductOrder::find()->where([
'id' => $post['order_id'],
'user_id' => \Yii::$app->user->identity->getId(),
// 'store_id' => $post['store_id'],
'status' => 0,
'cancel_status' => 0
])->one();
if (!$ProductOrder) throw new Exception('产品订单不存在');
if(!$post['delivery_method']){ // 快递配送
if(!$post['address_id']){
throw new Exception('请选择收货地址');
}
$address = Address::find()->select(['id','name','mobile','province','region','detail_address'])->where([
'id' => $post['address_id'],
'user_id' => \Yii::$app->user->identity->getId()
])->asArray()->one();
if (!$address) throw new Exception('收货地址不存在');
$ProductOrder->address_id = $address['id'];
$ProductOrder->address = json_encode($address);
$ProductOrder->express_name = $address['name'];
$ProductOrder->express_mobile = $address['mobile'];
$ProductOrder->express_region = $address['region'];
$ProductOrder->express_address = $address['detail_address'];
if(!$ProductOrder->is_free_shipping) {
$region = Region::find()->where(['name' => $address['province']])->one();
$ProductOrder->total_pay_price = $ProductOrder->total_pay_price - $ProductOrder->trans_expenses + $region->express_fee;
$ProductOrder->trans_expenses = $region->express_fee;
}
$ProductOrder->delivery_method = 0;
$ProductOrder->saveOrFail();
} else { //门店自提
if(!$ProductOrder->delivery_method){
if ($ProductOrder->is_online != 0) {
throw new Exception('在线复诊订单不支持药店自提请选择收货地址');
}
$ProductOrder->address_id = 0;
$ProductOrder->address = '';
$ProductOrder->express_name = '';
$ProductOrder->express_mobile = '';
$ProductOrder->express_region = '';
$ProductOrder->express_address = '';
$ProductOrder->delivery_method = 1;
$ProductOrder->total_pay_price = $ProductOrder->total_pay_price - $ProductOrder->trans_expenses;
$ProductOrder->trans_expenses = 0;
$ProductOrder->saveOrFail();
}
}
return ['success'];
}
/**
* @doc-name 订单信息
* @doc-param int order_id 订单id
* @doc-return mixed @UserInfo{avatarurl-string-头像,@Address{name-string-名字,mobile-string-手机号码,region-string-地区,detail_address-string-详细地址}} 用户信息
* @doc-return mixed @Hospital{hospital_id-int-id,@Hospital{name-string-名字}} 医院信息
* @doc-return mixed @ProductOrder{order_no-string-订单编号,total_pay_price-float-实付金额,pay_method-int-支付方式1线上2线下,trans_expenses-float-运费,created_at-int-下单时间,status-int-产品订单状态0未支付1待发货2待收货3待评价4已退款5退款中6已收货7确认收货,is_pay-int-是否支付0否1是} 产品订单信息
* @doc-return mixed @Chinese{content-string-信息,total_price-float-单价} 药品信息
* @doc-return mixed @West{content-string-信息,number-int-数量,total_price-float-单价} 药品信息
*/
public function actionInfo()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['order_id', 'required']
]);
$ProductOrder = ProductOrder::find()->select('id,is_online,order_no,delivery_method,su_id,p_id,user_id,is_pay,prescription_type,address_id,address,decoct_price,items_price,process_price,treatement_price,total_pay_price,pay_method,trans_expenses,created_at,cancel_status,refund_status,status,pay_time')->where([
'id' => $post['order_id'],
'user_id' => \Yii::$app->user->identity->getId(),
// 'store_id' => $post['store_id']
])->asArray()->one();
$ProductOrder['created_at'] = date('Y-m-d H:i:s', $ProductOrder['created_at']);
$forbiddenRefund = 1;
$config = \Yii::$app->params;
$orderForbiddenRefundTime = isset($config['product_order']['forbidden_refund_time']) ? $config['product_order']['forbidden_refund_time'] :3600*24*7;
if ($ProductOrder['prescription_type']==2 || $ProductOrder['prescription_type']==4){
if (time()-$ProductOrder['pay_time']<=$orderForbiddenRefundTime){
$ProductOrder['forbidden_refund'] = 0;//可以退款
}else{
$ProductOrder['forbidden_refund']=$forbiddenRefund;//禁止退款
}
}else{
$ProductOrder['forbidden_refund'] = $forbiddenRefund;//禁止退款
}
$userInfo = User::find()->select('id,nickname,avatarurl')->where([
'id' => $ProductOrder['user_id']
])->asArray()->one();
$hospital = DoctorInfo::find()->select('hospital_id')->where([
'su_id' => $ProductOrder['su_id']
])->with(['hospital' => function ($h) {
$h->select('name');
}])->asArray()->one();
$ProductOrderItems = ProductOrderItems::find()->where(['product_order_id' => $ProductOrder['id']])->with(['drug' => function($q){
$q->select('id,drug_name,function,specification,usage,instruction');
}])->asArray()->all();
$ProductOrder['count'] = count($ProductOrderItems);
// 获取处方来源诊所信息
$prescriptionStore = null;
if ($ProductOrder['p_id']) {
$prescription = Prescription::find()->select('store_id')->where(['id' => $ProductOrder['p_id']])->asArray()->one();
if ($prescription && isset($prescription['store_id']) && $prescription['store_id']) {
$prescriptionStore = Store::find()->select('id,name,mobile,position')->where(['id' => $prescription['store_id']])->asArray()->one();
}
}
return [
'ProductOrder' => $ProductOrder,
'userInfo' => $userInfo,
'hospital' => $hospital,
'ProductOrderItems' => $ProductOrderItems,
'store' => $prescriptionStore ? ['store' => $prescriptionStore] : null,
];
}
/**
* @doc-name 支付产品订单
* @doc-param int order_id 订单id
* @doc-return int is_paid 1已支付0未支付
* @doc-return int order_id 订单id
* @doc-return array config 支付配置参数,在is_paid=0时返回
*/
public function actionPay()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['order_id', 'required']
]);
$form = new ProductOrderSubmitForm();
return $form->getPayData($post);
}
/**
* @doc-name 产品订单确认收货
* @doc-param int order_id 订单id
*/
public function actionReceive()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['order_id', 'required']
]);
$ProductOrder = ProductOrder::find()->where(['id' => $post['order_id'],'user_id' => \Yii::$app->user->identity->getId()])->one();
if($ProductOrder->status != ProductOrderEnum::WAIT_ACCEPT){
throw new Exception('订单状态错误');
}
$ProductOrder->status = ProductOrderEnum::CONFIRM;
$ProductOrder->received_time = time();
$ProductOrder->save();
if($ProductOrder->is_online){ //平台订单状态同步
\Yii::$app->queue->delay(0)->push(new ProductOrderSyncPlatformJob([
'orderId' => $this->event->order->id,
'status' => 4
]));
}
return ['签收成功'];
}
/**
* @doc-name 产品订单取消
* @doc-param int order_id 订单id
*/
public function actionCancel()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['order_id', 'required']
]);
$form = new ProductCancelForm();
return $form->cancel($post);
}
/**
* @doc-name 产品订单退款
* @doc-param int order_id 订单id
*/
public function actionRefundBase()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
[['order_id'], 'required']
]);
$productOrder = ProductOrder::find()->where([
'id' => $post['order_id'],
'user_id' => \Yii::$app->user->identity->getId(),
'store_id' => $post['store_id']
])->select('id,total_pay_price,trans_expenses,items_price')->one();
return $productOrder;
}
/**
* @doc-name 产品订单退款
* @doc-param int order_id 订单id
*/
public function actionRefund()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
[['order_id', 'reason'], 'required']
]);
$form = new ProductRefundForm();
return $form->refund($post);
}
/**
* @doc-name 产品订单退款原因
* @doc-param int order_id 订单id
*/
public function actionRefundReason()
{
$list = RefundReason::find()->select('id,reason as text')->asArray()->all();
return $list;
}
/**
* @doc-name 产品订单退款申请撤销
* @doc-param int order_id 订单id
*/
public function actionRefundCancel()
{
$post = \Yii::$app->request->post();
$this->requestValidate($post, [
['order_id', 'required']
]);
$form = new ProductRefundCancelForm();
return $form->cancel($post['order_id']);
}
/**
* 物流详情
*/
public function actionExpress(){
$get = \Yii::$app->request->get();
$this->requestValidate($get, [
['order_id', 'required']
]);
$express = (new ExpressService())->detail($get['order_id']);
return $express;
}
}