Files
xk-api-yii/admin/controllers/base/DataController.php
2025-04-01 18:38:36 +08:00

386 lines
15 KiB
PHP

<?php
namespace admin\controllers\base;
use admin\components\BaseAdminController;
use common\events\PrescriptionEvent;
use common\events\ProductOrderEvent;
use common\forms\ProductCancelForm;
use common\forms\ProductRefundForm;
use common\helpers\FuncHelper;
use common\jobs\Sms\WaitApprovalMessageJob;
use common\jobs\templateMessage\PrescriptionCreated;
use common\models\oldDb\Prescription;
use common\models\oldDb\ProductOrder;
use common\models\oldDb\ProductOrderLog;
use common\models\oldDb\Reconciliation;
use common\models\oldDb\Register;
use common\models\oldDb\Store;
use common\models\oldDb\User;
use common\services\JacErpService;
use yii\db\ActiveRecord;
use yii\db\Exception;
use yii\helpers\Json;
class DataController extends BaseAdminController
{
public $optional = ['count', 'top-drugs', 'trend', 'store-number', 'notify-order-generation', 'send-order'];
/**
* 获取首页统计数据
* @return array
*/
public function actionCount(): array
{
// 诊所
$storeCount = Store::find()->where(['is_delete' => 0]);
// 用户
$userCount = User::find();
// 订单
$orderCount = ProductOrder::find()->where(['is_pay' => 1]);
// 总成交
$totalPrice = Reconciliation::find()->where(['status' => 1]);
// 处方订单
// $prescriptionCount = Prescription::find()->where(['status' => 1]);
$prescriptionCount = Prescription::find()->where(['in', 'status', [0,1,3,4]]);
// 接诊人数
$registerCount = Register::find()->where(['in', 'status', [2, 3]]);
$totalPriceArr = 0;
$totalPriceSum = $totalPrice->select(['total_price'])->asArray()->all();
foreach ($totalPriceSum as $item) {
$totalPriceArr = bcadd($totalPriceArr, $item['total_price'], 2);
}
return [
'store' => intval($storeCount->count()),
'user' => intval($userCount->count()),
'order' => intval($orderCount->count()),
'total_price' => round($totalPriceArr, 2),
'prescription' => intval($prescriptionCount->count()),
'register' => intval($registerCount->count()),
'prescription_china' => intval(Prescription::find()->where(['in', 'status', [0,1,3,4]])->andWhere(['prescription_type' => 1])->count()),
// 'prescription_west' => intval(Prescription::find()->where(['in', 'status', [0,1,3,4]])->andWhere(['prescription_type' => 2])->count()),
'prescription_west' => intval(Prescription::find()->where(['in', 'status', [0,1,3,4]])->andWhere(['in', 'prescription_type', [2,4]])->count()),
'prescription_package_server' => intval(Prescription::find()->where(['in', 'status', [0,1,3,4]])->andWhere(['prescription_type' => 5])->count())
];
}
/**
* 获取销售量Top10的药品
* @return array|ActiveRecord[]
*/
public function actionTopDrugs(): array
{
// 通过yii_reconciliation表统计出前10的药品
$query = Reconciliation::find()
->with(['drug' => function ($query) {
$query->select(['id', 'drug_name', 'drug_number', 'type', 'image']);
}])
->select(['drug_id', 'sum(number) as number', 'sum(total_price) as total_price'])
->groupBy('drug_id')
->orderBy(['total_price' => SORT_DESC])
->limit(10)
->asArray();
$list = $query->all();
foreach ($list as &$item) {
$item['total_price'] = bcadd('0', $item['total_price'], 2);
}
return $list;
}
/**
* 获取趋势图数据
* @return array
*/
public function actionTrend(): array
{
// 根据$month列表的月份统计数据
$query = Reconciliation::find()->where(['between', 'created_at', strtotime(date('Y-01-01', strtotime('-11 month'))), strtotime(date('Y-m-d 23:59:59'))])->select([
'drug_type',
'total_price',
'status',
'created_at',
])->all();
$month = $this->getMonthsList(strtotime(date('Y-01-01', strtotime('-11 month'))), strtotime(date('Y-m-d')));
$saleMoney = [];
$refundMoney = [];
$drugSaleMoney = [
1 => ['name' => '中药', 'value' => 0],
2 => ['name' => '西药', 'value' => 0],
3 => ['name' => '保健食品', 'value' => 0],
4 => ['name' => '中成药', 'value' => 0],
5 => ['name' => '产品服务包', 'value' => 0],
];
// 药品分类
$drugType = [
1 => '中药',
2 => '西药',
3 => '保健食品',
4 => '中成药',
5 => '产品服务包',
];
// 总金额
$totalMoney = 0;
// TODO 暂时不统计供货价
// 判断获取时间方法
$dateStr = !empty($day) ? 'm-d' : 'Y-m';
$dateArr = !empty($day) ? $day : $month;
foreach ($dateArr as $v) {
if (!isset($saleMoney[$v])) $saleMoney[$v] = '0.00';
if (!isset($refundMoney[$v])) $refundMoney[$v] = '0.00';
}
foreach ($query as $v) {
$thisMonth = date($dateStr, $v['created_at']);
$saleMoney[$thisMonth] = bcadd($saleMoney[$thisMonth] ?? '0', $v['total_price'], 2);
$totalMoney = bcadd($totalMoney, $v['total_price'], 2);
// 药品
if (!isset($drugSaleMoney[$v['drug_type']])) {
$drugSaleMoney[$v['drug_type']] = [
'name' => $drugType[$v['drug_type']],
'value' => $v['total_price'],
];
} else {
$drugSaleMoney[$v['drug_type']]['value'] = bcadd($drugSaleMoney[$v['drug_type']]['value'] ?? '0', $v['total_price'], 2);
}
if ($v['status'] < 1) {
$refundMoney[$thisMonth] = bcadd($refundMoney[$thisMonth] ?? '0', $v['total_price'], 2);
}
}
// 循环$drugSaleMoney计算药品分类占比
// 循环$drugSaleMoney计算药品分类占比
foreach ($drugSaleMoney as $k => $v) {
if ($totalMoney == '0') {
// 处理总金额为零的情况
$drugSaleMoney[$k]['percentage'] = '0%';
} else {
$drugSaleMoney[$k]['percentage'] = bcadd(0, bcdiv($v['value'], $totalMoney, 6) * 100, 4) . '%';
}
}
return [
'month' => $month,
'price' => $this->getArrValues($saleMoney),
'refund_price' => $this->getArrValues($refundMoney),
'drug_data' => $this->getArrValues($drugSaleMoney),
];
}
/**
* 获取门店数量
* @return array
*/
public function actionStoreNumber(): array
{
$provinceId = 14;
$storeCount = Store::find()
->with(['city' => function ($query) {
$query->select(['id', 'name']);
}])
->where(['is_delete' => 0])
->andWhere(['province_id' => $provinceId])
->asArray()
->select(['city_id', 'province_id'])
->all();
$result = [];
foreach ($storeCount as $v) {
if (isset($result[$v['city_id']])) {
$result[$v['city_id']]['value'] += 1;
} else {
$result[$v['city_id']] = [
'name' => $v['city']['name'],
'value' => 1
];
}
}
return $result;
}
/**
* 获取月份
*
* @param $startTime
* @param $endTime
* @return array
*/
public function getMonthsList($startTime, $endTime): array
{
$monthList = [];
$currentTime = $startTime;
while ($currentTime <= $endTime) {
$monthList[] = date('Y-m', $currentTime);
$currentTime = strtotime('+1 month', $currentTime);
}
return $monthList;
}
/**
* 重置键值
* @param $originalArray
* @return array
*/
public function getArrValues($originalArray): array
{
$newArr = [];
foreach ($originalArray as $v) {
$newArr[] = $v;
}
return $newArr;
}
public function actionNotifyOrderGeneration()
{
$prescription = \Yii::$app->request->post('prescription');
// $this->requestValidate($param, [
// ['prescription', 'required'],
// ['product_order', 'required'],
// ]);
// $productOrder = $param['product_order'];
//触发处方自动失效事件
// $prescriptionEvent = new PrescriptionEvent();
// $prescriptionEvent->prescription = $prescription;
// $prescriptionEvent->sender = $this;
// \Yii::$app->trigger(Prescription::AUTO_EXPIRE, $prescriptionEvent);
//
//
// //触发订单创建事件
// $event = new ProductOrderEvent();
// $event->order = $productOrder;
// $event->sender = $this;
// \Yii::$app->trigger(ProductOrder::EVENT_CREATED, $event);
//处方开具待支付订阅消息通知
\Yii::$app->queue->push(new PrescriptionCreated([
'orderId' => $prescription,
]));
//处方生成短信通知药师审方
\Yii::$app->queue->push(new WaitApprovalMessageJob([
'orderId' => $prescription,
]));
return ['ok'];
}
/**
* 处理处方过期
* @return string[]
* @throws \yii\base\Exception
*/
public function prescriptionOver(): array
{
$orderId = \Yii::$app->request->post('order_id');
$userId = \Yii::$app->request->post('user_id');
$type = \Yii::$app->request->post('type');
if($type === 1){
// 自动退款
$ProductRefundForm = new ProductRefundForm();
$ProductRefundForm->refund([
'order_id' => $orderId,
'user_id' => $userId
]);
} else {
// 订单自动失效
$ProductCancelForm = new ProductCancelForm();
$ProductCancelForm->cancel([
'order_id' => $orderId,
'user_id' => $userId
], '处方失效,订单自动失效');
}
return ['ok'];
}
public function actionSendOrder()
{
$this->orderId = 117;
$t = \Yii::$app->db->beginTransaction();
try {
$this->setRequest();
$ProductOrder = ProductOrder::find()->with(['prescription','store'])->where([
'id' => $this->orderId,
'is_pay' => 1,
'is_online' => 0,
'status' => 1 //已付款待发货
])->one();
if (!$ProductOrder || !$ProductOrder->prescription || $ProductOrder->cancel_status == 1 || !$ProductOrder->store) {
throw new \Exception('订单不存在或已取消');
}
if($ProductOrder->prescription->status != 1){
throw new \Exception('处方未审核');
}
$prescriptionContent = Json::decode($ProductOrder->prescription->content);
$recipe = $prescriptionContent['repice'][0];
$recipeContent = Json::decode($recipe['content']);
$processContent = '';
if($recipe['process_rule_id'] != 0){
$processContent = '煎服,每天'.$recipe['deployment'].'次。'.$recipe['process_rule'];
} elseif ($recipe['package_method_id'] != 0) {
$processContent = '外配,每天'.$recipe['deployment'].'次。'. $recipe['process_rule'];
}
$params = [
'cht_id' => 'XK_'.$ProductOrder->user_id.'_'.$ProductOrder->up_id.'_'.$ProductOrder->prescription->register_id,
'ps_seq' => $ProductOrder->prescription->prescription_no,
'pat_name' => $prescriptionContent['patient']['name'],
'sex' => $prescriptionContent['patient']['sex'] == 1 ? '男':'女',
'age' => FuncHelper::getAgeFromIdNo($prescriptionContent['patient']['id_card']),
'tot_posts' => $recipe['dosage'],
'tisane_posts' => $recipe['dosage'],
'usage' => $processContent,//`, 每次'.$recipe['volume'].'ml
'doctor' => $prescriptionContent['doctor']['name'],
'department' => $prescriptionContent['doctor']['depart']['name'],//科室
'post_weight' => count($recipeContent),
'post_amount' => round($recipe['total_price']/$recipe['dosage'],2),
'diagnose' => $prescriptionContent['clinical_diagnose'],
'yw_type' => '1',
'submit_date' => date('Y-m-d'),
'get_no' => substr($ProductOrder->user_id.rand(1000,999).$ProductOrder->up_id,0,10)
];
if($ProductOrder->delivery_method){ //到店取货
$params['send_way'] = '0';
$params['telphone'] = $prescriptionContent['patient']['mobile'];
$params['addr'] = $ProductOrder->store->position;
} else { //快递到家
$params['send_way'] = '1';
$params['telphone'] = $ProductOrder->express_mobile;
$params['addr'] = $ProductOrder->express_region.$ProductOrder->express_address;
}
$details = [];
foreach ($recipeContent as $value) {
$detail = [
'drug_seq' => $value['drug_id'],
'his_prc_cod' => 'XK'.$value['id'],
'drug_name' => $value['name'],
'spec' => $value['number'].$value['unit']['name'],
'post_quantity' => $value['number'],
'note' => $value['order']?$value['useWay']['name']:'无',
'drug_price' => $value['price'],
'wholesale_price' => $value['buy_price'],
'unit' => $value['unit']['name'],
'tisane_prc_code' => $value['drug_number']
];
$details[] = $detail;
}
$params['details'] = $details;
\Yii::info(__METHOD__."——同步订单至江奥川erp(".$ProductOrder->store->erp_id.")原始数据: ".Json::encode($params));
$result = JacErpService::getInstance($ProductOrder->store->erp_id)->syncOrder($params);
if(!$result){
throw new \Exception('订单同步江奥川ERP失败:'.$this->getErrorMsg());
}
//订单更新为已同步erp
$ProductOrder->is_sync_erp = 1;
$ProductOrder->save();
$t->commit();
} catch (\Exception $exception) {
$t->rollBack();
ProductOrderLog::saveLog($this->orderId,'订单自动同步江奥川ERP('.$ProductOrder->store->erp_id.')异常:'.$exception->getMessage());
ProductOrderLog::saveLog($this->orderId,'订单自动同步江奥川ERP('.$ProductOrder->store->erp_id.')异常:'.$exception->getLine());
return;
}
}
}