feat: 添加小程序access_token处理

fix: 修复测试数据BUG
master
Rmiku 2 months ago
parent 18b3a032f4
commit 8f903b1c4d
  1. 12
      app/Http/Controllers/Hospital/IntroduceController.php
  2. 72
      app/Http/Controllers/Notify/NotifyController.php
  3. 21
      app/Http/Controllers/Patient/PatientController.php
  4. 22
      app/Http/Controllers/Test/TestController.php
  5. 33
      app/Http/Logics/Notify/NotifyLogic.php
  6. 5
      app/Http/Logics/Outpatient/RecordLogic.php
  7. 35
      app/Http/Logics/Patient/PatientLogic.php
  8. 29
      app/Http/Logics/Registration/RecordLogic.php
  9. 24
      app/Http/Middleware/RecordApiLog.php
  10. 2
      app/Http/Resources/Outpatient/Pending/PendingListsResource.php
  11. 2
      app/Http/Resources/Registration/Schedule/DoctorListsResource.php
  12. 2
      app/Jobs/Message/Message.php
  13. 4
      app/Jobs/SendWeChatMessageJob.php
  14. 6
      app/Models/Order.php
  15. 118
      app/Utils/CentralControlAccessToken.php
  16. 3
      app/Utils/Helpers.php
  17. 14
      app/Utils/Traits/SendSubscribeMessage.php
  18. 45
      app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php
  19. 1
      composer.json
  20. 7
      routes/api.php

@ -93,7 +93,7 @@ class IntroduceController extends Controller
foreach ($doctor_lists as $k => $v) {
$doctor_lists[$k]['dept_name'] = $v->department->dept_name ?? '';
$doctor_lists[$k]['doctor_avatar'] = getAdminUploadImageUrl($v['doctor_avatar']);
$doctor_lists[$k]['doctor_avatar'] = getAdminUploadImageUrl((string) $v['doctor_avatar']);
}
return jsonResponse(Response::HTTP_OK, 'success.', $doctor_lists->toArray());
@ -123,7 +123,7 @@ class IntroduceController extends Controller
'doctor_name' => $doctor_details->doctor_name,
'doctor_title' => $doctor_details->doctor_title,
'doctor_specialty' => $doctor_details->doctor_specialty,
'avatar' => getAdminUploadImageUrl($doctor_details->avatar),
'avatar' => getAdminUploadImageUrl((string) $doctor_details->avatar),
'introduction' => $doctor_details->introduction ?: '',
'is_expert' => $doctor_details->is_expert,
];
@ -150,7 +150,7 @@ class IntroduceController extends Controller
'address' => $info->address ?: '',
'telephone' => $info->telephone ?: '',
'email' => $info->email ?: '',
'logo' => getAdminUploadImageUrl($info->logo),
'logo' => getAdminUploadImageUrl((string) $info->logo),
'website' => $info->website ?: '',
'description' => !empty($info['description']) ? html_entity_decode($info['description']) : ''
];
@ -199,7 +199,7 @@ class IntroduceController extends Controller
}
foreach ($new_lists as $v) {
$v['image'] = getAdminUploadImageUrl($v['image']);
$v['image'] = getAdminUploadImageUrl((string) $v['image']);
}
return jsonResponse(Response::HTTP_OK, 'success.', $new_lists);
@ -225,7 +225,7 @@ class IntroduceController extends Controller
throw new GeneralException('找不到该新闻动态信息');
}
$details['image'] = getAdminUploadImageUrl($details['image']);
$details['image'] = getAdminUploadImageUrl((string) $details['image']);
$details['content'] = !empty($details['content']) ? html_entity_decode($details['content']) : '';
return jsonResponse(Response::HTTP_OK, 'success.', $details);
@ -292,7 +292,7 @@ class IntroduceController extends Controller
}
foreach ($building_lists as $k => $v) {
$building_lists[$k]['image'] = getAdminUploadImageUrl($v['image']);
$building_lists[$k]['image'] = getAdminUploadImageUrl((string) $v['image']);
}
return jsonResponse(Response::HTTP_OK, 'success.', $building_lists);

@ -3,13 +3,14 @@ declare(strict_types = 1);
namespace App\Http\Controllers\Notify;
use App\Dictionary\WeChat\Payment\V2Api;
use App\Http\Controllers\Controller;
use App\Http\Logics\Notify\NotifyLogic;
use App\Utils\Traits\Logger;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use EasyWeChat\Pay\Message;
use EasyWeChat\Kernel\Support\Xml;
use Exception;
use Nyholm\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use ReflectionException;
use Throwable;
@ -42,29 +43,58 @@ class NotifyController extends Controller
$app = getWeChatMiniProgramPaymentApp();
$server = $app->getServer();
$server->handlePaid(function (Message $message, \Closure $next) use ($app) {
// $message->out_trade_no 获取商户订单号
// $message->payer['openid'] 获取支付者 openid
// 🚨🚨🚨 注意:推送信息不一定靠谱哈,请务必验证
// 建议是拿订单号调用微信支付查询接口,
$this->info('接收回调消息', $message->toArray());
try{
// 验证签名通过,业务处理
$app->getValidator()->validate($app->getRequest());
$message = $server->getRequestMessage();
$this->info('接收回调消息', $message->toArray());
// 业务处理
$result = $this->notify_logic->notifyHandle($message);
try {
// 验证签名通过,业务处理
// $app->getValidator()->validate($app->getRequest());
$this->info('接受回调消息结果', ['result' => $result]);
} catch(\Exception $e){
// 验证失败
$err_msg = '订单验证签名失败:'. $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
$this->error($err_msg, [$message->toArray()]);
// 业务处理
$result = $this->notify_logic->notifyHandle($message);
$this->info('接受回调消息结果', ['result' => $result]);
if ($result) {
return $this->returnSuccess();
}
return $next($message);
});
return $this->returnFailure('订单处理失败');
} catch (Exception $e) {
// 验证失败
$err_msg = '订单处理流程失败:' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
$this->error($err_msg, [$message->toArray()]);
// 返回 SUCCESS 或者 FAIL 等其他状态
return $this->returnFailure('订单处理异常');
}
}
return $server->serve();
/**
* 返回成功
* @return Response
*/
public function returnSuccess(): Response
{
return new Response(200, [],
Xml::build([
'return_code' => 'SUCCESS',
'return_msg' => 'OK'
])
);
}
/**
* 返回失败
* @param string $error_msg
* @return Response
*/
public function returnFailure(string $error_msg): Response
{
return new Response(200, [],
Xml::build([
'return_code' => 'FAIL',
'return_msg' => $error_msg
])
);
}
}

@ -99,8 +99,27 @@ class PatientController
*/
public function delete(Request $request, string $patient_id): JsonResponse
{
$this->patient_logic->cancelBindPatient($patient_id);
$this->patient_logic->cancelBindPatient($patient_id);
return jsonResponse(Response::HTTP_OK, 'delete success.');
}
/**
* 获取手机号码
* @param Request $request
* @return JsonResponse
* @throws GeneralException
*/
public function getPhoneNumber(Request $request): JsonResponse
{
$validated = $request->validate([
'code' => 'required',
],[
'code.required' => '数据错误',
]);
$phone_info = $this->patient_logic->getPhoneNumber($validated['code']);
return jsonResponse(Response::HTTP_OK, 'success', ['phone_info' => $phone_info]);
}
}

@ -0,0 +1,22 @@
<?php
declare(strict_types = 1);
namespace App\Http\Controllers\Test;
use App\Utils\Traits\SendSubscribeMessage;
use UnifyPayment\Cores\Struct\RefundOrder;
use UnifyPayment\Unify;
class TestController
{
use SendSubscribeMessage;
public function test(): void
{
$app = getWeChatMiniProgramApp();
dd($app->getAccessToken()->getToken());
// $refund = new RefundOrder('WXM20250208110845293', 'WXM20250208110845293_R123', '0.01', '人工退费');
// $response = Unify::common(config('unify'))->order->refund($refund);
// dd($response);
}
}

@ -111,7 +111,7 @@ class NotifyLogic
}
} catch (GeneralException|Exception $e) {
$err_msg = $e->getMessage().' ON '. $e->getFile(). ':'. $e->getLine();
recordLog('NotifyLog', $err_msg);
$this->error('挂号流程错误:'. $err_msg);
$this->unlockOrder($notify->out_trade_no, $lock_id);
return false;
}
@ -137,7 +137,7 @@ class NotifyLogic
$order_info->patient_id,
$order_info->patient_name,
$record->dept_id,
$record->docttor_id,
$record->doctor_id,
$record->reg_id,
$extra['scheduleInfo']['rankId'],
$record->visit_date,
@ -155,14 +155,14 @@ class NotifyLogic
if (isset($response['success']) && $response['success'] === true) {
// 成功流程
$order_info->orderConfirm($order_info->order_id, $response['visitNo'], $response);
$order_info->orderConfirm($order_info->order_id, $response['response']['visitNo'], $response);
// 支付平台业务确认
$this->unifyConfirm($notify['out_trade_no'], $response['visitNo'], $notify['openid'], $notify['transaction_id']);
$this->unifyConfirm($notify['out_trade_no'], $response['response']['visitNo'], $notify['openid'], $notify['transaction_id']);
// 推送成功
$this->sendRegistrationSuccessMessage($order_info);
} else if (isset($response['success']) && $response['success'] === false) {
} else if (isset($response['success']) && $response['success'] === false && $response['msg'] !== '服务异常') {
// 失败流程
$this->handleOrderReverse($order_info, $response['msg'] ?? '');
@ -185,24 +185,27 @@ class NotifyLogic
*/
public function outpatientOrderHandle(OrderModel $order_info, Message $notify): void
{
// 挂号确认
$patient = $order_info->patient;
// 缴费确认
$record = $order_info->outpatientPaymentRecord;
$extra = json_decode(reset($order_info->outpatientPaymentRecord), true);
$pay_time = strtotime($notify->time_end);
foreach ($record as $v) {
$extra_info = json_decode($v->extra_info, true);
$prescription_ids[] = $extra_info['prescriptionId'];
}
// 如果没查到对应的缴费处方记录,直接跳出
if (empty($extra_info) || empty($prescription_ids)) {
return;
}
$this->info('处方记录信息:'.$order_info->order_id, [$prescription_ids]);
$data = [
$order_info->patient_id,
'0',
date('Y-m-d', $extra['visitDate']),
$extra_info['strVisitDate'],
implode(',', $prescription_ids),
$extra['visitNumber'],
$extra_info['visitNumber'],
'',
$order_info->order_id,
PayType::WECHAT_PAY->hisCode(),
@ -215,14 +218,14 @@ class NotifyLogic
// 保存返回信息
if (isset($response['success']) && $response['success'] === true) {
// 成功流程
$order_info->orderConfirm($order_info->order_id, $response['hosTranNo'], $response);
$order_info->orderConfirm($order_info->order_id, $response['response']['hosTranNo'], $response);
// 支付平台业务确认
$this->unifyConfirm($notify['out_trade_no'], $response['hosTranNo'], $notify['openid'], $notify['transaction_id']);
$this->unifyConfirm($notify['out_trade_no'], $response['response']['hosTranNo'], $notify['openid'], $notify['transaction_id']);
// 推送成功
$this->sendOutpatientPaymentSuccessMessage($order_info);
} else if (isset($response['success']) && $response['success'] === false) {
} else if (isset($response['success']) && $response['success'] === false && $response['msg'] !== '服务异常') {
// 失败流程
$this->handleOrderReverse($order_info, $response['msg']);

@ -11,6 +11,7 @@ use App\Utils\Traits\Logger;
use App\Utils\Traits\MiniProgramAuth;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use Symfony\Component\HttpFoundation\Response;
class RecordLogic
@ -47,7 +48,7 @@ class RecordLogic
}
// 缓存2小时
Cache::set('Outpatient.Record.'. $this->open_id.'.'. $patient_id, json_encode($response, JSON_UNESCAPED_UNICODE), 2 * 60 * 60);
Redis::setex('Outpatient.Record.'. $this->open_id.'.'. $patient_id, 2 * 60 * 60, json_encode($response, JSON_UNESCAPED_UNICODE));
return $response;
}
@ -82,7 +83,7 @@ class RecordLogic
{
$cache_key = 'Outpatient.Record.'. $this->open_id.'.'. $patient_id;
$record_info = Cache::get($cache_key);
$record_info = Redis::get($cache_key);
if (empty($record_info)) {
throw new GeneralException($response['ERRORMSG'] ?? '查询不到缴费记录,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE);
}

@ -5,6 +5,7 @@ namespace App\Http\Logics\Patient;
use App\Dictionary\Patient\CardType;
use App\Dictionary\Patient\Sex;
use App\Dictionary\WeChat\MiniProgram\OpenApi;
use App\Exceptions\GeneralException;
use App\Models\Patient;
use App\Services\HisHttp\Client;
@ -12,8 +13,10 @@ use App\Utils\Traits\Logger;
use App\Utils\Traits\MiniProgramAuth;
use App\Utils\Traits\SendSubscribeMessage;
use App\Utils\Traits\UniversalEncryption;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
class PatientLogic
{
@ -270,7 +273,37 @@ class PatientLogic
throw new GeneralException('解绑失败,请稍后再试!', Response::HTTP_INTERNAL_SERVER_ERROR);
}
$this->sendUnbindPatientSubscribeMessage($this->open_id, $info->id, $info['name'], '', $patient_number);
$this->sendUnbindPatientSubscribeMessage($this->open_id, $info->id, $info['name'], ' ', $patient_number);
return true;
}
/**
* 获取患者手机号码
* @param string $code
* @return array
* @throws GeneralException
*/
public function getPhoneNumber(string $code): array
{
try {
$mini = getWeChatMiniProgramApp();
$response = $mini->getClient()->postJson(OpenApi::GET_PHONE_NUMBER->value, [
'code' => $code
]);
$this->info('获取手机号码接口返回', [$response]);
if ($response['errcode'] !== 0 || empty($response['phone_info'])) {
throw new GeneralException('获取手机号码失败,请稍后再试!');
}
return $response['phone_info'];
} catch (ExceptionInterface|Exception $e) {
//service error
$message = $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
$this->error('获取手机号码接口报错', [$message]);
throw new GeneralException('获取手机号码失败,请稍后再试!', Response::HTTP_BAD_REQUEST);
}
}
}

@ -5,6 +5,7 @@ namespace App\Http\Logics\Registration;
use App\Dictionary\Order\PayType;
use App\Dictionary\Order\SourceId;
use App\Dictionary\Order\Status;
use App\Dictionary\Order\Type;
use App\Exceptions\GeneralException;
use App\Models\Order;
@ -141,6 +142,7 @@ class RecordLogic
throw new GeneralException($response['msg'] ?? '退号失败,请重新再试!', Response::HTTP_BAD_REQUEST);
}
// 创建退款单
$refund_order_id = $this->order_model->getRefundOrderId($order_id);
$refund_order_info = $this->order_model->createRefundOReverseOrder(
@ -161,22 +163,25 @@ class RecordLogic
throw new GeneralException($response['msg'] ?? '退号成功,退费失败,请重新再试!', Response::HTTP_BAD_REQUEST);
}
// 退款
try {
$refund_order_obj = new RefundOrder($order_id, $refund_order_id, $fee, '患者自行退号退费');
$response = Unify::common(config('unify'))->order->refund($refund_order_obj);
$this->info('退号退费结果', $response);
// 非免费号,需要退费
if ($fee > 0) {
// 退款
try {
$refund_order_obj = new RefundOrder($order_id, $refund_order_id, $fee, '患者自行退号退费');
$response = Unify::common(config('unify'))->order->refund($refund_order_obj);
$this->info('退号退费结果', $response);
} catch (ReflectionException $e) {
$this->order_model->reverseOrderOpera($refund_order_id, $fee, false);
} catch (ReflectionException $e) {
$this->order_model->reverseOrderOpera($refund_order_id, $fee, false);
throw new GeneralException($e->getMessage() ?? '退号成功,退费失败,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE);
}
throw new GeneralException($e->getMessage() ?? '退号成功,退费失败,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE);
}
if (empty($response) || $response['status'] !== 200 || $response['success'] !== true) {
$this->order_model->reverseOrderOpera($refund_order_id, $fee, false);
if (empty($response) || $response['status'] !== 200 || $response['success'] !== true) {
$this->order_model->reverseOrderOpera($refund_order_id, $fee, false);
throw new GeneralException($response['msg'] ?? '退号成功,退费失败,请重新再试!', Response::HTTP_BAD_REQUEST);
throw new GeneralException($response['msg'] ?? '退号成功,退费失败,请重新再试!', Response::HTTP_BAD_REQUEST);
}
}
$this->order_model->reverseOrderOpera($refund_order_id, $fee, true);

@ -6,6 +6,7 @@ use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
class RecordApiLog
{
@ -23,9 +24,9 @@ class RecordApiLog
/**
* @param Request $request
* @param Response|JsonResponse $response
* @param Response|JsonResponse|HttpResponse $response
*/
public function terminate(Request $request, Response|JsonResponse $response): void
public function terminate(Request $request, Response|JsonResponse|HttpResponse $response): void
{
//结束时间
$end = microtime(true);
@ -34,25 +35,32 @@ class RecordApiLog
$ip = json_encode($request->ips(),256);
if ($response instanceof JsonResponse) {
$responseStr = $this->getJsonResponseStr($response);
$response_str = $this->getJsonResponseStr($response);
} else {
$responseStr = $this->getResponseStr($response);
$response_str = $this->getResponseStr($response);
}
// 回调消息获取request_data
if (stripos($request->url, 'notify') !== false) {
$request_data = file_get_contents('php://input') ?: file_get_contents('php://temp');
} else {
$request_data = request()->all();
}
recordLog('RecordApiUse', implode("\n", [
'请求地址: '. $ip. '|'. $request->method(). '|'. $request->url(),
'请求入参: '. json_encode(request()->all(), JSON_UNESCAPED_UNICODE),
'请求出参: '. $responseStr,
'请求入参: '. json_encode($request_data, JSON_UNESCAPED_UNICODE),
'请求出参: '. $response_str,
'耗时: '. sprintf("%.6f", $diff). 's'
]));
}
/**
* 获取响应字符串
* @param Response $response
* @param Response|HttpResponse $response
* @return string
*/
protected function getResponseStr(Response $response): string
protected function getResponseStr(Response|HttpResponse $response): string
{
return PHP_EOL. sprintf('HTTP/%s %s %s', $response->getProtocolVersion(), $response->getStatusCode(), Response::$statusTexts[$response->getStatusCode()]). PHP_EOL.
$response->headers. PHP_EOL.

@ -31,7 +31,7 @@ class PendingListsResource extends JsonResource
'remark' => $v['remarks'],
'is_self_pay' => $v['isexpense'],
'prescription_number' => $v['nrescriptionNumber'],
'exec_address' => $v['takeMedicine'],
'exec_address' => $v['takeMedicine'] ?: '',
'visit_no' => $v['visitNumber'],
];
}

@ -71,7 +71,7 @@ class DoctorListsResource extends JsonResource
->orderBy('id', 'ASC')
->get();
$doctor_lists = $doctor_lists->keyBy('doctor_id')->map(function ($value) { return (array)$value; })->toArray();
$doctor_lists = $doctor_lists->keyBy('doctor_id')->map(function ($value) { return $value->toArray(); })->toArray();
Redis::setex('doctor.lists', 4 * 3600, json_encode($doctor_lists, JSON_UNESCAPED_UNICODE));
}

@ -41,7 +41,7 @@ abstract class Message
/** @var Response $response */
$response = $this->getApp()->getClient()->postJson($type->api()->value, $message);
Log::channel('SendWeChatMessage')->info('Push WeChat Message', [$type->label(), $message, $response->getContent(false)]);
Log::channel('send_wechat_message')->info('Push WeChat Message', [$type->label(), $message, $response->getContent(false)]);
return $response;
}

@ -97,14 +97,14 @@ class SendWeChatMessageJob implements ShouldQueue, ShouldBeUnique
$data = $response->toArray(false);
if ($response->isSuccessful()) {
$this->successful((string)$data['errcode']);
$this->successful((string)($data['msgid'] ?? $data['errcode']));
} else {
$this->retry((string)$data['errmsg']);
}
} catch (Exception|Throwable $e) {
$message = $e->getMessage().' in '.$e->getFile().':'.$e->getLine();
Log::channel('SendWeChatMessage')->info('Push WeChat Message Error', [$this->message->id, $message]);
Log::channel('send_wechat_message')->info('Push WeChat Message Error', [$this->message->id, $message]);
$this->retry($e->getMessage());
}

@ -80,7 +80,7 @@ class Order extends Model
*/
public function patient(): belongsTo
{
return $this->belongsTo(Patient::class, 'id', 'relate_patient_id');
return $this->belongsTo(Patient::class, 'relate_patient_id', 'id');
}
/**
@ -294,10 +294,10 @@ class Order extends Model
break;
case Type::OUTPATIENT_PAYMENT->value:
$record = $order->outpatientPaymentRecord;
$extra_info = json_decode($record->extra_info, true);
$extra_info['confirm_response'] = $response;
foreach ($record as $v) {
$extra_info = json_decode($v->extra_info, true);
$extra_info['confirm_response'] = $response;
$v->update(['extra_info' => json_encode($extra_info, JSON_UNESCAPED_UNICODE)]);
}
break;

@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
namespace App\Utils;
use App\Dictionary\WeChat\Official\OpenApi;
use EasyWeChat\Kernel\Contracts\RefreshableAccessToken;
use HttpException;
use Illuminate\Support\Facades\Redis;
use JsonException;
use JetBrains\PhpStorm\ArrayShape;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class CentralControlAccessToken implements RefreshableAccessToken
{
public function __construct(){}
/**
* Access Token Save Key.
*
* @return string
*/
public function getKey(): string
{
return 'mini_platform:access_token';
}
/**
* Get Access Token.
*
* @return string
*
* @throws ClientExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws HttpException
* @throws JsonException
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function getToken(): string
{
$token = Redis::get($this->getKey());
if ($token && is_string($token)) {
return $token;
}
return $this->refresh();
}
/**
* Get Access Token For Query Params.
*
* @return array<string, string>
*
* @throws ClientExceptionInterface
* @throws ContainerExceptionInterface
* @throws DecodingExceptionInterface
* @throws HttpException
* @throws JsonException
* @throws NotFoundExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
#[ArrayShape(['access_token' => "string"])]
public function toQuery(): array
{
return ['access_token' => $this->getToken()];
}
/**
* @return string
*
* @throws HttpException
* @throws JsonException
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function refresh(): string
{
$client = HttpClient::create(['base_uri' => 'https://api.weixin.qq.com/']);
$response = $client->request(
'GET',
OpenApi::GET_ACCESS_TOKEN->value,
[
'query' => [
'grant_type' => 'client_credential',
'appid' => config('wechat.mini.app_id'),
'secret' =>config('wechat.mini.secret'),
],
]
)->toArray(false);
if (empty($response['access_token'])) {
throw new HttpException('Failed to get access_token: '. json_encode($response, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE)
);
}
Redis::setex($this->getKey(), (int)$response['expires_in'] - 300, $response['access_token']);
return $response['access_token'];
}
}

@ -4,6 +4,7 @@ use EasyWeChat\MiniApp\Application as MiniApplication;
use EasyWeChat\Pay\Application as PayApplication;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Route;
use App\Utils\CentralControlAccessToken;
if (!function_exists('jsonResponse')) {
/**
@ -763,7 +764,7 @@ if (!function_exists('getWeChatMiniProgramApp')) {
*/
function getWeChatMiniProgramApp(): MiniApplication
{
return new MiniApplication(config('wechat.mini'));
return (new MiniApplication(config('wechat.mini')))->setAccessToken(new CentralControlAccessToken());
}
}

@ -55,7 +55,7 @@ trait SendSubscribeMessage
}
/**
* 发送绑患者订阅消息
* 发送绑患者订阅消息
* @param string $open_id
* @param int $relate_patient_id
* @param string $patient_name
@ -73,7 +73,7 @@ trait SendSubscribeMessage
'data' => [
'thing1' => ['value' => $patient_name],
'time2' => ['value' => date('Y-m-d H:i')],
'thing3' => ['value' => '已解除绑定关系,无法使用线上线下就医服务'],
'thing3' => ['value' => '已解除绑定关系,无法使用线上线下就医服务'],
'character_string5' => ['value' => $inpatient_id],
'character_string6' => ['value' => $patient_id],
],
@ -135,7 +135,7 @@ trait SendSubscribeMessage
'thing17' => ['value' => $record->dept_location],
'character_string15' => ['value' => $visit_time],
'thing19' => ['value' => $record->doctor_name],
'amount13' => ['value' => $order->fee / 100],
'amount13' => ['value' => ($order->fee / 100). '元'],
],
'miniprogram_state' => config('custom.mini_program_message_state')
];
@ -166,7 +166,7 @@ trait SendSubscribeMessage
'thing3' => ['value' => $record->doctor_name],
'name1' => ['value' => $order->patient_name],
'time4' => ['value' => $visit_time],
'amount13' => ['value' => $order->fee / 100],
'amount13' => ['value' => ($order->fee / 100). '元'],
],
'miniprogram_state' => config('custom.mini_program_message_state')
];
@ -224,9 +224,9 @@ trait SendSubscribeMessage
'page' => 'pagesA/outpatient/outPayList',
'data' => [
'date5' => ['value' => date('Y-m-d')],
'amount6' => ['value' => $order->fee / 100],
'amount6' => ['value' => ($order->fee / 100). '元'],
'character_string7' => ['value' => $order->order_id],
'character_string14' => ['value' => $order->patient_id],
'character_string14' => ['value' => $order->patient->patient_number],
'thing9' => ['value' => '门诊缴费'],
],
'miniprogram_state' => config('custom.mini_program_message_state')
@ -256,7 +256,7 @@ trait SendSubscribeMessage
'character_string1' => ['value' => $order->order_id],
'thing2' => ['value' => '门诊缴费'],
'name3' => ['value' => $order->patient_name],
'amount4' => ['value' => $order->fee / 100],
'amount4' => ['value' => ($order->fee / 100). '元'],
'date6' => ['value' => date('Y-m-d')],
],
'miniprogram_state' => config('custom.mini_program_message_state')

File diff suppressed because one or more lines are too long

@ -12,6 +12,7 @@
"ext-redis": "*",
"ext-simplexml": "*",
"ext-soap": "*",
"ext-http": "*",
"laravel/framework": "^11.31",
"laravel/sanctum": "^4.0",
"laravel/tinker": "^2.9",

@ -11,6 +11,7 @@ use App\Http\Controllers\Registration\RecordController as RegistrationRecordCont
use App\Http\Controllers\Registration\RegisterController;
use App\Http\Controllers\Registration\ScheduleController;
use App\Http\Controllers\Dictionary\ItemController;
use App\Http\Controllers\Test\TestController;
use Illuminate\Support\Facades\Route;
Route::middleware(['apiLog'])->group(function() {
@ -18,6 +19,9 @@ Route::middleware(['apiLog'])->group(function() {
Route::post('login', [AuthController::class, 'login']);
Route::any('unauthorized', [AuthController::class, 'unauthorized'])->name('login');
// 测试接口
Route::get('test', [TestController::class, 'test']);
// 支付回调
Route::any('notify', [NotifyController::class, 'notify']);
@ -30,6 +34,9 @@ Route::middleware(['apiLog'])->group(function() {
Route::post('/bind', [PatientController::class, 'bind']);
Route::post('/{patient_id}/default', [PatientController::class, 'setDefault']);
Route::delete('/{patient_id}/delete', [PatientController::class, 'delete']);
// 获取手机号码
Route::get('/phone', [PatientController::class, 'getPhoneNumber']);
});
// 挂号模块

Loading…
Cancel
Save