初始化提交

This commit is contained in:
wucongxing 2023-02-17 17:10:16 +08:00
commit 4ca844f470
152 changed files with 20390 additions and 0 deletions

17
.env.example Normal file
View File

@ -0,0 +1,17 @@
APP_NAME=skeleton
APP_ENV=dev
DB_DRIVER=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=hyperf
DB_USERNAME=root
DB_PASSWORD=
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
DB_PREFIX=
REDIS_HOST=localhost
REDIS_AUTH=(null)
REDIS_PORT=6379
REDIS_DB=0

54
.github/workflows/Dockerfile vendored Normal file
View File

@ -0,0 +1,54 @@
# Default Dockerfile
#
# @link https://www.hyperf.io
# @document https://hyperf.wiki
# @contact group@hyperf.io
# @license https://github.com/hyperf/hyperf/blob/master/LICENSE
FROM hyperf/hyperf:8.0-alpine-v3.16-swoole
LABEL maintainer="Hyperf Developers <group@hyperf.io>" version="1.0" license="MIT" app.name="Hyperf"
##
# ---------- env settings ----------
##
# --build-arg timezone=Asia/Shanghai
ARG timezone
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
APP_ENV=prod \
SCAN_CACHEABLE=(true)
# update
RUN set -ex \
# show php version and extensions
&& php -v \
&& php -m \
&& php --ri swoole \
# ---------- some config ----------
&& cd /etc/php* \
# - config PHP
&& { \
echo "upload_max_filesize=128M"; \
echo "post_max_size=128M"; \
echo "memory_limit=1G"; \
echo "date.timezone=${TIMEZONE}"; \
} | tee conf.d/99_overrides.ini \
# - config timezone
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo "${TIMEZONE}" > /etc/timezone \
# ---------- clear works ----------
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
WORKDIR /opt/www
# Composer Cache
# COPY ./composer.* /opt/www/
# RUN composer install --no-dev --no-scripts
COPY . /opt/www
RUN print "\n" | composer install -o && php bin/hyperf.php
EXPOSE 9501
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]

12
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,12 @@
name: Build Docker
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build
run: cp -rf .github/workflows/Dockerfile . && docker build -t hyperf .

25
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,25 @@
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
name: Release
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
.buildpath
.settings/
.project
*.patch
.idea/
.git/
runtime/
vendor/
.phpintel/
.env
.DS_Store
.phpunit*
*.cache

57
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,57 @@
# usermod -aG docker gitlab-runner
stages:
- build
- deploy
variables:
PROJECT_NAME: hyperf
REGISTRY_URL: registry-docker.org
build_test_docker:
stage: build
before_script:
# - git submodule sync --recursive
# - git submodule update --init --recursive
script:
- docker build . -t $PROJECT_NAME
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:test
- docker push $REGISTRY_URL/$PROJECT_NAME:test
only:
- test
tags:
- builder
deploy_test_docker:
stage: deploy
script:
- docker stack deploy -c deploy.test.yml --with-registry-auth $PROJECT_NAME
only:
- test
tags:
- test
build_docker:
stage: build
before_script:
# - git submodule sync --recursive
# - git submodule update --init --recursive
script:
- docker build . -t $PROJECT_NAME
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:latest
- docker push $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME
- docker push $REGISTRY_URL/$PROJECT_NAME:latest
only:
- tags
tags:
- builder
deploy_docker:
stage: deploy
script:
- echo SUCCESS
only:
- tags
tags:
- builder

91
.php-cs-fixer.php Normal file
View File

@ -0,0 +1,91 @@
<?php
$header = <<<'EOF'
This file is part of Hyperf.
@link https://www.hyperf.io
@document https://hyperf.wiki
@contact group@hyperf.io
@license https://github.com/hyperf/hyperf/blob/master/LICENSE
EOF;
return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'@Symfony' => true,
'@DoctrineAnnotation' => true,
'@PhpCsFixer' => true,
'header_comment' => [
'comment_type' => 'PHPDoc',
'header' => $header,
'separate' => 'none',
'location' => 'after_declare_strict',
],
'array_syntax' => [
'syntax' => 'short'
],
'list_syntax' => [
'syntax' => 'short'
],
'concat_space' => [
'spacing' => 'one'
],
'blank_line_before_statement' => [
'statements' => [
'declare',
],
],
'general_phpdoc_annotation_remove' => [
'annotations' => [
'author'
],
],
'ordered_imports' => [
'imports_order' => [
'class', 'function', 'const',
],
'sort_algorithm' => 'alpha',
],
'single_line_comment_style' => [
'comment_types' => [
],
],
'yoda_style' => [
'always_move_variable' => false,
'equal' => false,
'identical' => false,
],
'phpdoc_align' => [
'align' => 'left',
],
'multiline_whitespace_before_semicolons' => [
'strategy' => 'no_multi_line',
],
'constant_case' => [
'case' => 'lower',
],
'class_attributes_separation' => true,
'combine_consecutive_unsets' => true,
'declare_strict_types' => true,
'linebreak_after_opening_tag' => true,
'lowercase_static_reference' => true,
'no_useless_else' => true,
'no_unused_imports' => true,
'not_operator_with_successor_space' => true,
'not_operator_with_space' => false,
'ordered_class_elements' => true,
'php_unit_strict' => false,
'phpdoc_separation' => false,
'single_quote' => true,
'standardize_not_equals' => true,
'multiline_comment_opening_closing' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->exclude('public')
->exclude('runtime')
->exclude('vendor')
->in(__DIR__)
)
->setUsingCache(false);

9
.phpstorm.meta.php Normal file
View File

@ -0,0 +1,9 @@
<?php
namespace PHPSTORM_META {
// Reflect
override(\Psr\Container\ContainerInterface::get(0), map(['' => '@']));
override(\Hyperf\Context\Context::get(0), map(['' => '@']));
override(\make(0), map(['' => '@']));
override(\di(0), map(['' => '@']));
}

54
Dockerfile Normal file
View File

@ -0,0 +1,54 @@
# Default Dockerfile
#
# @link https://www.hyperf.io
# @document https://hyperf.wiki
# @contact group@hyperf.io
# @license https://github.com/hyperf/hyperf/blob/master/LICENSE
FROM hyperf/hyperf:8.0-alpine-v3.16-swoole
LABEL maintainer="Hyperf Developers <group@hyperf.io>" version="1.0" license="MIT" app.name="Hyperf"
##
# ---------- env settings ----------
##
# --build-arg timezone=Asia/Shanghai
ARG timezone
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
APP_ENV=prod \
SCAN_CACHEABLE=(true)
# update
RUN set -ex \
# show php version and extensions
&& php -v \
&& php -m \
&& php --ri swoole \
# ---------- some config ----------
&& cd /etc/php* \
# - config PHP
&& { \
echo "upload_max_filesize=128M"; \
echo "post_max_size=128M"; \
echo "memory_limit=1G"; \
echo "date.timezone=${TIMEZONE}"; \
} | tee conf.d/99_overrides.ini \
# - config timezone
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo "${TIMEZONE}" > /etc/timezone \
# ---------- clear works ----------
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
WORKDIR /opt/www
# Composer Cache
# COPY ./composer.* /opt/www/
# RUN composer install --no-dev --no-scripts
COPY . /opt/www
RUN composer install --no-dev -o && php bin/hyperf.php
EXPOSE 9501
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Hyperf
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

16
README.md Normal file
View File

@ -0,0 +1,16 @@
# 描述
肝胆相照互联网医院患者、医生、药师端小程序后台api接口项目
# 要求
- 框架 >= hyperf3.0.0
- PHP >= 8.0
- Swoole PHP extension >= 4.5and Disabled `Short Name`
- OpenSSL PHP 拓展
- JSON PHP 拓展
- PDO PHP 拓展 If you need to use MySQL Client
- Redis PHP 拓展 If you need to use Redis Client
# 启动方式
$ php bin/hyperf.php start
$ 访问`http://localhost:9501/`

138
app/Common/Common.php Normal file
View File

@ -0,0 +1,138 @@
<?php
use App\Constants\HttpEnumCode;
/**
* @method:打印使用,格式化打印数据
* @param mixed ...$vars
*/
function dump(...$vars)
{
ob_start();
var_dump(...$vars);
$output = ob_get_clean();
$output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
if (PHP_SAPI == 'cli') {
$output = PHP_EOL . $output . PHP_EOL;
} else {
if (!extension_loaded('xdebug')) {
$output = htmlspecialchars($output, ENT_SUBSTITUTE);
}
$output = '<pre>' . $output . '</pre>';
}
echo $output;
}
/**
* 成功返回
* @param array $data 需返回数据
* @param int $code code枚举码
* @param string $message 返回提示信息
* @return array
*/
function success(array $data = [], int $code = HttpEnumCode::HTTP_SUCCESS, string $message = ""): array
{
if (empty($message)) {
$message = HttpEnumCode::getMessage($code);
}
return [
'code' => $code,
'data' => $data,
'message' => $message
];
}
/**
* 失败返回
* @param int $code code枚举码
* @param string $message 返回提示信息
* @param array $data 需返回数据
* @return array
*/
function fail(int $code = HttpEnumCode::HTTP_ERROR, string $message = "", array $data = []): array
{
if (empty($message)) {
$message = HttpEnumCode::getMessage($code);
}
return [
'code' => $code,
'data' => $data,
'message' => $message
];
}
/**
* 转换用户类型-字符串
* @param int|string $user_type 用户类型1:患者 2:医生 3:药师)
* @return string
*/
function UserTypeToString(int|string $user_type): string
{
if ($user_type == 1) {
$result = "患者端";
} elseif ($user_type == 2) {
$result = "医生端";
} elseif ($user_type == 3) {
$result = "药师端";
} else {
$result = "未知";
}
return $result;
}
/**
* 获取身份证年龄
* @param $idCard
* @return false|int|mixed|string
*/
function getIdCardAge(string $idCard): mixed
{
$age_time = strtotime(substr($idCard, 6, 8));
if ($age_time === false) {
return false;
}
list($y1, $m1, $d1) = explode("-", date("Y-m-d", $age_time));
$now_time = strtotime("now");
list($y2, $m2, $d2) = explode("-", date("Y-m-d", $now_time));
$age = $y2 - $y1;
if ((int)($m2 . $d2) < (int)($m1 . $d1)) {
$age -= 1;
}
return $age;
}
/**
* 获取身份证性别
* @param string $idCard
* @return int
*/
function getIdCardSex(string $idCard): int
{
if(empty($idCard)) {
return 0;
}
$sexint = (int) substr($idCard, 16, 1);
return $sexint % 2 === 0 ? 2 : 1;
}
/**
* 添加阿里云oss前缀网址
* @param $path
* @return string
*/
function addAliyunOssWebsite($path): string
{
if (empty($path)){
return "";
}
return "https://" . config('alibaba.oss.endpoint') . $path;
}

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace App\Constants;
use Hyperf\Constants\AbstractConstants;
use Hyperf\Constants\Annotation\Constants;
/**
* 医生职称
*/
#[Constants]
class DoctorTitleCode extends AbstractConstants
{
/**
* @Message("执业医师")
*/
const LICENSED_PHYSICIAN = 1;
/**
* @Message("主治医师")
*/
const ATTENDING_DOCTOR = 2;
/**
* @Message("副主任医师")
*/
const DEPUTY_CHIEF_PHYSICIAN = 2;
/**
* @Message("主任医师")
*/
const CHIEF_PHYSICIAN = 2;
}

View File

@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace App\Constants;
use Hyperf\Constants\AbstractConstants;
use Hyperf\Constants\Annotation\Constants;
#[Constants]
class HttpEnumCode extends AbstractConstants
{
/* -------------------------------200成功请求---------------------------------- */
/**
* @Message("成功")
*/
const HTTP_SUCCESS = 200;
/**
* @Message("失败")
*/
const HTTP_ERROR = -1;
/**
* @Message("用户状态异常")
*/
const USER_STATUS_ERROR = 201;
/**
* @Message("用户已被禁用")
*/
const USER_STATUS_DISABLE = 202;
/**
* @Message("手机号超出规定时间内最大获取次数,请您稍后再试")
*/
const PHONE_MAXIMUM = 203;
/**
* @Message("验证码错误")
*/
const CODE_ERROR = 204;
/**
* @Message("验证码已过期")
*/
const CODE_EXPIRED = 205;
/* -------------------------------400客户端错误---------------------------------- */
/**
* @Message("错误请求")
*/
const CLIENT_HTTP_ERROR = 400;
/**
* @Message("未授权")
*/
const CLIENT_HTTP_UNAUTHORIZED = 401;
/**
* @Message("禁止请求")
*/
const HTTP_PROHIBIT = 403;
/**
* @Message("token错误/无效")
*/
const TOKEN_ERROR = 405;
/**
* @Message("token过期")
*/
const TOKEN_EXPTIRED = 406;
/**
* @Message("手机号格式错误")
*/
const MOBILE_FORMAT_ERROR = 407;
/**
* @Message("日期格式错误")
*/
const DATE_FORMAT_ERROR = 408;
/* -------------------------------500服务端错误---------------------------------- */
/**
* @Message("服务器异常")
*/
const SERVER_ERROR = 500;
/**
* @Message("微信授权失败")
*/
const GET_WX_ERROR = 501;
/**
* @Message("微信授权过期")
*/
const WX_CODE_ERROR = 502;
/**
* @Message("短信发送失败")
*/
const CODE_FAIL = 503;
}

View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Controller;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Psr\Container\ContainerInterface;
abstract class AbstractController
{
#[Inject]
protected ContainerInterface $container;
#[Inject]
protected RequestInterface $request;
#[Inject]
protected ResponseInterface $response;
}

View File

@ -0,0 +1,61 @@
<?php
namespace App\Controller;
use App\Request\AreaRequest;
use App\Services\AreaService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
class AreaController extends AbstractController
{
/**
* 获取省份信息
* @return ResponseInterface
*/
public function getProvince(): ResponseInterface
{
$areaService = new AreaService();
$data = $areaService->getProvince();
return $this->response->json($data);
}
/**
* 获取城市信息
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getCity(): ResponseInterface
{
$request = $this->container->get(AreaRequest::class);
$request->scene('getCity')->validateResolved();
$areaService = new AreaService();
$data = $areaService->getCity();
return $this->response->json($data);
}
/**
* 获取区县信息
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getCounty(): ResponseInterface
{
$request = $this->container->get(AreaRequest::class);
$request->scene('getCounty')->validateResolved();
$areaService = new AreaService();
$data = $areaService->getCounty();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Controller;
use App\Request\BasicDataRequest;
use App\Services\BasicDataService;
use App\Services\SafeService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
* 基础数据
*/
class BasicDataController extends AbstractController
{
/**
* 获取医院数据
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getHospital(): ResponseInterface
{
$request = $this->container->get(BasicDataRequest::class);
$request->scene('getHospital')->validateResolved();
$BasicDataService = new BasicDataService();
$data = $BasicDataService->getHospital();
return $this->response->json($data);
}
/**
* 获取自定义科室数据
* @return ResponseInterface
*/
public function getCustomDepartment(): ResponseInterface
{
$BasicDataService = new BasicDataService();
$data = $BasicDataService->getCustomDepartment();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Controller;
use App\Request\CodeRequest;
use App\Services\CodeService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
class CodeController extends AbstractController
{
/**
* 获取手机号验证码
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getPhoneCode(): ResponseInterface
{
$request = $this->container->get(CodeRequest::class);
$request->scene('getPhoneCode')->validateResolved();
$CodeService = new CodeService();
$data = fail();
$scene = $this->request->input('scene');
switch ($scene) {
case 1:
// 登陆
$data = $CodeService->getLoginPhoneCode();
break;
default:
// code...
break;
}
return $this->response->json($data);
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Controller;
use App\Request\DiseaseRequest;
use App\Services\DiseaseService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
class DiseaseController extends AbstractController
{
/**
* 专长列表
* @return ResponseInterface
*/
public function getDiseaseExpertiseList(): ResponseInterface
{
$DiseaseService = new DiseaseService();
$data = $DiseaseService->getDiseaseExpertiseList();
return $this->response->json($data);
}
/**
* 搜索疾病分类
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getDiseaseSearch(): ResponseInterface
{
$request = $this->container->get(DiseaseRequest::class);
$request->scene('getDiseaseSearch')->validateResolved();
$DiseaseService = new DiseaseService();
$data = $DiseaseService->getDiseaseSearch();
return $this->response->json($data);
}
/**
* 获取常见疾病分类
* @return ResponseInterface
*/
public function getDiseaseHot(): ResponseInterface
{
$DiseaseService = new DiseaseService();
$data = $DiseaseService->getDiseaseHot();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace App\Controller;
use App\Request\DoctorAuthRequest;
use App\Request\PatientFamilyRequest;
use App\Services\DoctorAuthService;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
* 医生认证
*/
class DoctorAuthController extends AbstractController
{
/**
* 获取实名认证信息
* @return ResponseInterface
*/
public function getAuthReal(): ResponseInterface
{
$DoctorAuthService = new DoctorAuthService();
$data = $DoctorAuthService->getAuthReal();
return $this->response->json($data);
}
/**
* 新增实名认证
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface|GuzzleException
*/
public function addAuthReal(): ResponseInterface
{
$request = $this->container->get(DoctorAuthRequest::class);
$request->scene('addAuthReal')->validateResolved();
$DoctorAuthService = new DoctorAuthService();
$data = $DoctorAuthService->addAuthReal();
return $this->response->json($data);
}
/**
* 获取身份认证信息
* @return ResponseInterface
*/
public function getAuthIden(): ResponseInterface
{
$DoctorAuthService = new DoctorAuthService();
$data = $DoctorAuthService->getAuthIden();
return $this->response->json($data);
}
/**
* 新增身份认证信息
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface|GuzzleException
*/
public function addAuthIden(): ResponseInterface
{
$request = $this->container->get(DoctorAuthRequest::class);
$request->scene('addAuthIden')->validateResolved();
$DoctorAuthService = new DoctorAuthService();
$data = $DoctorAuthService->addAuthIden();
return $this->response->json($data);
}
/**
* 获取多点执业认证信息
* @return ResponseInterface
*/
public function getAuthMulti(): ResponseInterface
{
$DoctorAuthService = new DoctorAuthService();
$data = $DoctorAuthService->getAuthMulti();
return $this->response->json($data);
}
/**
* 新增多点执业认证信息
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface|GuzzleException
*/
public function addAuthMulti(): ResponseInterface
{
$request = $this->container->get(DoctorAuthRequest::class);
$request->scene('addAuthMulti')->validateResolved();
$DoctorAuthService = new DoctorAuthService();
$data = $DoctorAuthService->addAuthMulti();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Controller;
use App\Model\Area;
use App\Model\Hospital;
use App\Model\TbHospitalMy;
use App\Services\IndexService;
use App\Utils\Prescription;
use Hyperf\DbConnection\Db;
use Hyperf\Snowflake\IdGeneratorInterface;
use Psr\Http\Message\ResponseInterface;
/**
* 首页
*/
class IndexController extends AbstractController
{
/**
* 医生端-首页
* @return ResponseInterface
*/
public function doctorIndex(): ResponseInterface
{
$IndexService = new IndexService();
$data = $IndexService->getDoctorIndex();
return $this->response->json($data);
}
/**
* 患者端-首页
* @return ResponseInterface
*/
public function patientIndex(): ResponseInterface
{
$IndexService = new IndexService();
$data = $IndexService->getPatientIndex();
return $this->response->json($data);
}
/**
* 医师端-首页
* @return ResponseInterface
*/
public function pharmacistIndex(): ResponseInterface
{
$IndexService = new IndexService();
$data = $IndexService->getPharmacistIndex();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace App\Controller;
use App\Request\LoginRequest;
use App\Services\LoginService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
* 登陆
*/
class LoginController extends AbstractController
{
/**
* 微信手机号登陆
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function wechatMobileLogin(): ResponseInterface
{
// 验证参数
$request = $this->container->get(LoginRequest::class);
$request->scene('wechatMobileLogin')->validateResolved();
$LoginService = new LoginService();
$data = $LoginService->wechatMobileLogin();
return $this->response->json($data);
}
// 手机号登陆
public function mobileLogin(): ResponseInterface
{
// 验证参数
$request = $this->container->get(LoginRequest::class);
$request->scene('mobileLogin')->validateResolved();
$LoginService = new LoginService();
$data = $LoginService->mobileLogin();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Controller;
use App\Constants\HttpEnumCode;
use App\Request\OrderInquiryRequest;
use App\Request\PublicRequest;
use App\Services\OrderInquiryService;
use App\Services\PublicService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
* 问诊订单
*/
class OrderInquiryController extends AbstractController
{
#[Inject]
protected ValidatorFactoryInterface $validationFactory;
/**
* 创建问诊订单
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function addInquiryOrder(): ResponseInterface
{
$request = $this->container->get(OrderInquiryRequest::class);
$request->scene('addInquiryOrder')->validateResolved();
$OrderInquiryService = new OrderInquiryService();
$data = $OrderInquiryService->addInquiryOrder();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Controller;
use App\Services\PatientCaseService;
use Psr\Http\Message\ResponseInterface;
/**
* 病例
*/
class PatientCaseController extends AbstractController
{
/**
* 获取患者最后一份问诊病例
* @return ResponseInterface
*/
public function getLastCase(): ResponseInterface
{
$PatientCaseService = new PatientCaseService();
$data = $PatientCaseService->getLastCase();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Controller;
use App\Services\MyDoctorService;
use Psr\Http\Message\ResponseInterface;
/**
* 患者端个人中心
*/
class PatientCenterController extends AbstractController
{
/**
* 删除我的医生
* 首页-个人中心
* @return ResponseInterface
*/
public function deleteMyDoctor(): ResponseInterface
{
$patientFamilyService = new MyDoctorService();
$data = $patientFamilyService->deleteMyDoctor();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace App\Controller;
use App\Request\PatientDoctorRequest;
use App\Services\PatientDoctorService;
use App\Services\UserDoctorService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
* 患者端医生数据
*/
class PatientDoctorController extends AbstractController
{
/**
* 获取问诊医生列表
* 专家问诊-公益问诊共用
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getInquiryDoctorList(): ResponseInterface
{
$request = $this->container->get(PatientDoctorRequest::class);
$request->scene('getInquiryDoctorList')->validateResolved();
$PatientDoctorService = new PatientDoctorService();
$data = $PatientDoctorService->getInquiryDoctorList();
return $this->response->json($data);
}
/**
* 获取问诊医生详情
* @return ResponseInterface
*/
public function getInquiryDoctorInfo(): ResponseInterface
{
$PatientDoctorService = new PatientDoctorService();
$data = $PatientDoctorService->getInquiryDoctorInfo();
return $this->response->json($data);
}
/**
* 获取医生评价
* @return ResponseInterface
*/
public function getDoctorEvaluationList(): ResponseInterface
{
$PatientDoctorService = new PatientDoctorService();
$data = $PatientDoctorService->getDoctorEvaluationList();
return $this->response->json($data);
}
/**
* 医生详情简介-详情中的简介
* @return ResponseInterface
*/
public function getDoctorProfile(): ResponseInterface
{
$PatientDoctorService = new PatientDoctorService();
$data = $PatientDoctorService->getDoctorProfile();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace App\Controller;
use App\Constants\HttpEnumCode;
use App\Request\PatientFamilyRequest;
use App\Services\PatientFamilyService;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Hyperf\Di\Annotation\Inject;
/**
* 家庭成员
*/
class PatientFamilyController extends AbstractController
{
#[Inject]
protected ValidatorFactoryInterface $validationFactory;
/**
* 获取家庭成员列表
* @return ResponseInterface
*/
public function getFamilyList(): ResponseInterface
{
$patientFamilyService = new PatientFamilyService();
$data = $patientFamilyService->getFamilyList();
return $this->response->json($data);
}
/**
* 新增家庭成员
* @return array|ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function addFamily(): array|ResponseInterface
{
$request = $this->container->get(PatientFamilyRequest::class);
$request->scene('addFamily')->validateResolved();
// 检测入参身份证号
$res = $this->checkRequestIdCard();
if (!empty($res)) {
return fail(HttpEnumCode::HTTP_ERROR, $res);
}
$patientFamilyService = new PatientFamilyService();
$data = $patientFamilyService->addFamily();
return $this->response->json($data);
}
/**
* 检测入参身份证号
* @return string
*/
private function checkRequestIdCard(): string
{
$messages = [
'id_number.regex' => '证件号错误',
];
$validator = $this->validationFactory->make($this->request->all(), [
'type' => 'required',
], $messages);
$validator->sometimes(
['id_number'],
['regex:/^(?:1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5])\d{4}(?:1[89]|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dxX]$/'],
function ($input) {
return $input->type == 1;
}
);
if ($validator->fails()) {
return $validator->errors()->first();
}
return "";
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Controller;
use App\Request\SafeRequest;
use App\Services\SafeService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
class SafeController extends AbstractController
{
/**
* 获取oss签名数据
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getOssSign(): ResponseInterface
{
$request = $this->container->get(SafeRequest::class);
$request->scene('getOssSign')->validateResolved();
$SafeService = new SafeService();
$data = $SafeService->getOssSign();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Controller;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Request\UserRequest;
use App\Services\UserService;
use App\Utils\Http;
use Psr\Http\Message\ResponseInterface;
class UserController extends AbstractController
{
}

View File

@ -0,0 +1,75 @@
<?php
namespace App\Controller;
use App\Request\DoctorAuthRequest;
use App\Request\UserDoctorRequest;
use App\Services\DoctorAuthService;
use App\Services\DoctorInquiryService;
use App\Services\UserDoctorService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
class UserDoctorController extends AbstractController
{
/**
* 获取医生专长列表
* 身份认证
* @return ResponseInterface
*/
public function getAuthDoctorExpertise(): ResponseInterface
{
$UserDoctorService = new UserDoctorService();
$data = $UserDoctorService->getAuthDoctorExpertise();
return $this->response->json($data);
}
/**
* 获取医生问诊配置
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getInquiryConfig(): ResponseInterface
{
$request = $this->container->get(UserDoctorRequest::class);
$request->scene('getInquiryConfig')->validateResolved();
$DoctorInquiryService = new DoctorInquiryService();
$data = $DoctorInquiryService->getInquiryConfig();
return $this->response->json($data);
}
/**
* 医生问诊开关
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function putInquiryOpen(): ResponseInterface
{
$request = $this->container->get(UserDoctorRequest::class);
$request->scene('putInquiryOpen')->validateResolved();
$DoctorInquiryService = new DoctorInquiryService();
$data = $DoctorInquiryService->putInquiryOpen();
return $this->response->json($data);
}
/**
* 修改医生问诊配置
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function putInquiryConfig(): ResponseInterface
{
$request = $this->container->get(UserDoctorRequest::class);
$request->scene('putInquiryConfig')->validateResolved();
$DoctorInquiryService = new DoctorInquiryService();
$data = $DoctorInquiryService->putInquiryConfig();
return $this->response->json($data);
}
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Exception;
use App\Constants\HttpEnumCode;
use Hyperf\Server\Exception\ServerException;
use Throwable;
class BusinessException extends ServerException
{
public function __construct(string $message = null, int $code = 500, Throwable $previous = null)
{
if (is_null($message)) {
$message = HttpEnumCode::getMessage($code);
}
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Exception\Handler;
use App\Constants\HttpEnumCode;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Snowflake\IdGeneratorInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Hyperf\Di\Annotation\Inject;
use Throwable;
class AppExceptionHandler extends ExceptionHandler
{
#[Inject]
protected StdoutLoggerInterface $logger;
protected string $environment;
#[Inject]
protected ContainerInterface $container;
public function __construct(StdoutLoggerInterface $logger)
{
$this->logger = $logger;
$this->environment = env("APP_ENV", 'prod');
}
public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
{
try {
if ($this->environment != "dev"){
// 生产环境 固定返回服务器错误
$message = HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR);
}else{
$message = $throwable->getMessage();
}
$generator = $this->container->get(IdGeneratorInterface::class);
} catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
$this->logger->error($throwable->getTraceAsString());
return $response->withHeader('Server', 'gdxz')->withStatus(500)->withBody(new SwooleStream('服务器错误'));
}
$id = $generator->generate();
$data = json_encode([
'data' => $id,
'code' => HttpEnumCode::SERVER_ERROR,
'message' => $message,
], JSON_UNESCAPED_UNICODE);
$this->logger->error($id . "-start");
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
$this->logger->error($throwable->getTraceAsString());
$this->logger->error($id . "-end");
return $response->withStatus(500)->withHeader('content-type', 'application/json; charset=utf-8')->withBody(new SwooleStream($data));
}
public function isValid(Throwable $throwable): bool
{
return true;
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace App\Exception\Handler;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Snowflake\IdGeneratorInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Hyperf\Di\Annotation\Inject;
use Throwable;
class BusinessExceptionHandler extends ExceptionHandler
{
#[Inject]
protected StdoutLoggerInterface $logger;
protected string $environment;
#[Inject]
protected ContainerInterface $container;
public function __construct(StdoutLoggerInterface $logger)
{
$this->logger = $logger;
$this->environment = env("APP_ENV", 'prod');
}
public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
{
// 判断被捕获到的异常是希望被捕获的异常
if ($throwable instanceof BusinessException) {
if ($this->environment != "dev"){
// 生产环境 固定返回服务器错误
$message = HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR);
}else{
$message = $throwable->getMessage();
}
$generator = $this->container->get(IdGeneratorInterface::class);
$id = $generator->generate();
$data = json_encode([
'data' => $id,
'code' => $throwable->getCode(),
'message' => $message,
], JSON_UNESCAPED_UNICODE);
$this->logger->error($id . "-start");
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
$this->logger->error($throwable->getTraceAsString());
$this->logger->error($id . "-end");
// 阻止异常冒泡
$this->stopPropagation();
return $response->withStatus(500)->withHeader('content-type', 'application/json; charset=utf-8')->withBody(new SwooleStream($data));
}
// 交给下一个异常处理器
return $response;
// 或者不做处理直接屏蔽异常
}
/**
* 判断该异常处理器是否要对该异常进行处理
*/
public function isValid(Throwable $throwable): bool
{
return true;
}
}

View File

@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Exception\Handler;
//use App\Exception\ValidationException;
use App\Constants\HttpEnumCode;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use \Hyperf\Validation\ValidationException;
use Throwable;
class ValidationExceptionHandler extends ExceptionHandler
{
/**
* @var StdoutLoggerInterface
*/
protected $logger;
public function __construct(StdoutLoggerInterface $logger)
{
$this->logger = $logger;
}
public function handle(Throwable $throwable, ResponseInterface $response)
{
// 判断被捕获到的异常是希望被捕获的异常
if ($throwable instanceof ValidationException) {
$body = $throwable->validator->errors()->first();
// 阻止异常冒泡
$this->stopPropagation();
// 格式化输出
$data = json_encode([
'data' => [],
'code' => HttpEnumCode::CLIENT_HTTP_ERROR,
'message' => $body,
], JSON_UNESCAPED_UNICODE);
return $response->withStatus($throwable->status)->withHeader('content-type', 'application/json; charset=utf-8')->withBody(new SwooleStream($data));
}
// 交给下一个异常处理器
return $response;
}
public function isValid(Throwable $throwable): bool
{
return true;
}
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Exception;
use Hyperf\Server\Exception\ServerException;
class ValidationException extends ServerException
{
}

View File

@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Listener;
use Hyperf\Database\Events\QueryExecuted;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\Arr;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
#[Listener]
class DbQueryExecutedListener implements ListenerInterface
{
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(ContainerInterface $container)
{
$this->logger = $container->get(LoggerFactory::class)->get('sql');
}
public function listen(): array
{
return [
QueryExecuted::class,
];
}
/**
* @param QueryExecuted $event
*/
public function process(object $event): void
{
if ($event instanceof QueryExecuted) {
$sql = $event->sql;
if (! Arr::isAssoc($event->bindings)) {
$position = 0;
foreach ($event->bindings as $value) {
$position = strpos($sql, '?', $position);
if ($position === false) {
break;
}
$value = "'{$value}'";
$sql = substr_replace($sql, $value, $position, 1);
$position += strlen($value);
}
}
$this->logger->info(sprintf('[%s] %s', $event->time, $sql));
}
}
}

View File

@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Listener;
use Hyperf\AsyncQueue\AnnotationJob;
use Hyperf\AsyncQueue\Event\AfterHandle;
use Hyperf\AsyncQueue\Event\BeforeHandle;
use Hyperf\AsyncQueue\Event\Event;
use Hyperf\AsyncQueue\Event\FailedHandle;
use Hyperf\AsyncQueue\Event\RetryHandle;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\ExceptionHandler\Formatter\FormatterInterface;
use Hyperf\Logger\LoggerFactory;
use Psr\Log\LoggerInterface;
#[Listener]
class QueueHandleListener implements ListenerInterface
{
protected LoggerInterface $logger;
public function __construct(LoggerFactory $loggerFactory, protected FormatterInterface $formatter)
{
$this->logger = $loggerFactory->get('queue');
}
public function listen(): array
{
return [
AfterHandle::class,
BeforeHandle::class,
FailedHandle::class,
RetryHandle::class,
];
}
public function process(object $event): void
{
if ($event instanceof Event && $event->message->job()) {
$job = $event->message->job();
$jobClass = get_class($job);
if ($job instanceof AnnotationJob) {
$jobClass = sprintf('Job[%s@%s]', $job->class, $job->method);
}
$date = date('Y-m-d H:i:s');
switch (true) {
case $event instanceof BeforeHandle:
$this->logger->info(sprintf('[%s] Processing %s.', $date, $jobClass));
break;
case $event instanceof AfterHandle:
$this->logger->info(sprintf('[%s] Processed %s.', $date, $jobClass));
break;
case $event instanceof FailedHandle:
$this->logger->error(sprintf('[%s] Failed %s.', $date, $jobClass));
$this->logger->error($this->formatter->format($event->getThrowable()));
break;
case $event instanceof RetryHandle:
$this->logger->warning(sprintf('[%s] Retried %s.', $date, $jobClass));
break;
}
}
}
}

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Listener;
use Hyperf\Command\Event\AfterExecute;
use Hyperf\Coordinator\Constants;
use Hyperf\Coordinator\CoordinatorManager;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
#[Listener]
class ResumeExitCoordinatorListener implements ListenerInterface
{
public function listen(): array
{
return [
AfterExecute::class,
];
}
public function process(object $event): void
{
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
}
}

View File

@ -0,0 +1,154 @@
<?php
declare(strict_types=1);
namespace App\Middleware\Auth;
use App\Constants\HttpEnumCode;
use App\Model\User;
use App\Utils\Auth;
use App\Utils\Jwt;
use Hyperf\Context\Context;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Hyperf\Redis\Redis;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class AuthMiddleware implements MiddlewareInterface
{
/**
* @var ContainerInterface
*/
protected ContainerInterface $container;
protected HttpResponse $response;
protected RequestInterface $request;
public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
{
$this->container = $container;
$this->response = $response;
$this->request = $request;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$redis = $this->container->get(Redis::class);
$path_info = $this->request->getPathInfo();
$method = $this->request->getMethod();
$Auth = new Auth();
$Jwt = new Jwt();
// 获取token
$token = $this->getHeaderToken();
// 检测接口是否为免鉴权接口
$white_api = $Auth->checkApiWhiteList($path_info, $method);
if (!empty($token)){
if ($white_api){
// 存在token免鉴权
$res = $redis->get('jwt_black_' . $token);
if ($res && time() >= $res) {
// token存在黑名单中
return $handler->handle($request);
}
// jwt验证
try {
$result = $Jwt->decode($token);
}catch (\Throwable $e) {
return $handler->handle($request);
}
}else{
// 存在token鉴权
$res = $redis->get('jwt_black_' . $token);
if ($res && time() >= $res) {
// token存在黑名单中
return $this->response->json(fail(HttpEnumCode::HTTP_PROHIBIT));
}
// jwt验证
$result = $Jwt->decode($token);
// 处理即将过期token
$req = $Auth->checkTokenExpTime($result);
if ($req) {
// 即将过期重新下发token
$new_token = $Jwt->encode($result['userInfo']);
// 旧token加入黑名单 5天有效期5天内无法继续进行访问
$res = $redis->set('jwt_black_' . $token, $result['exp'], 30);
if (!$res) {
// 添加缓存失败
return $this->response->json(fail(HttpEnumCode::SERVER_ERROR));
}
$response = Context::get(ResponseInterface::class);
$response = $response->withHeader('Authorization', $new_token);
Context::set(ResponseInterface::class, $response);
}
}
}else{
if ($white_api){
// token为空免鉴权
return $handler->handle($request);
}else{
// token为空鉴权
return $this->response->json(fail(HttpEnumCode::TOKEN_ERROR));
}
}
if (empty($result)){
return $this->response->json(fail(HttpEnumCode::SERVER_ERROR));
}
// 检测用户状态
$params = array();
$params['user_id'] = $result['userInfo']['user_id'];
$user = User::getOne($params);
if (empty($user)){
return $this->response->json(fail(HttpEnumCode::USER_STATUS_ERROR));
}
if ($user['user_status'] == 0){
return $this->response->json(fail(HttpEnumCode::USER_STATUS_DISABLE));
}
if ($user['user_status'] != 1){
return $this->response->json(fail(HttpEnumCode::USER_STATUS_ERROR));
}
$request = $this->request->withAttribute('userInfo', $result['userInfo']);
$request = Context::set(ServerRequestInterface::class, $request);
return $handler->handle($request);
}
/**
* 获取header中的token
* @return string
*/
protected function getHeaderToken(): string
{
$bearer_token = $this->request->getHeader('Authorization');
if (empty($bearer_token)){
return "";
}
// 解析token
$token = explode(' ', $bearer_token[0]);
return $token[1] ?? "";
}
}

View File

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace App\Middleware;
use Hyperf\Contract\Arrayable;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* 核心类
*/
class CoreMiddleware extends \Hyperf\HttpServer\CoreMiddleware
{
/**
* Handle the response when cannot found any routes.
*
* @return array|Arrayable|mixed|ResponseInterface|string
*/
protected function handleNotFound(ServerRequestInterface $request): mixed
{
// 重写路由找不到的处理逻辑
return $this->response()->withStatus(404)->withBody(new SwooleStream('404 Not Found'));
}
/**
* Handle the response when the routes found but doesn't match any available methods.
*
* @return array|Arrayable|mixed|ResponseInterface|string
*/
protected function handleMethodNotAllowed(array $methods, ServerRequestInterface $request): mixed
{
// 重写 HTTP 方法不允许的处理逻辑
return $this->response()->withStatus(405)->withBody(new SwooleStream('Method Error'));
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace App\Middleware\Corss;
use Hyperf\Context\Context;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class CorssMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = Context::get(ResponseInterface::class);
$response = $response->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Credentials', 'true')
// Headers 可以根据实际情况进行改写。
->withHeader('Access-Control-Allow-Headers', 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,Authorization');
Context::set(ResponseInterface::class, $response);
if ($request->getMethod() == 'OPTIONS') {
return $response;
}
return $handler->handle($request);
}
}

61
app/Model/Area.php Normal file
View File

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $area_id 地区编号
* @property string $area_name 名称
* @property int $parent_id 上级编号
* @property string $zip 邮编
* @property int $area_type 类型(1:国家,2:,3:,4:区县)
*/
class Area extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'area';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['area_id', 'area_name', 'parent_id', 'zip', 'area_type'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['area_id' => 'integer', 'parent_id' => 'integer', 'area_type' => 'integer'];
protected string $primaryKey = "area_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $field
* @return Collection|array
*/
public static function getList(array $params = [], array $field = ['*']): Collection|array
{
return self::where($params)->get($field);
}
}

69
app/Model/Banner.php Normal file
View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $banner_id 主键id
* @property string $banner_name 图片名称
* @property string $banner_path 图片路径
* @property int $app_type 应用程序类型1:小程序 2:app
* @property int $client_type 客户端类型1:患者端 2:医生端 3:药师端)
* @property int $banner_place 展示位置1:首页)
* @property int $banner_status 状态0:删除 1:正常 2:禁用)
* @property int $banner_sort 排序值(越大排序越靠前)
* @property string $banner_link 跳转地址
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class Banner extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'banner';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['banner_id', 'banner_name', 'banner_path', 'app_type', 'client_type', 'banner_place', 'banner_status', 'banner_sort', 'banner_link', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['banner_id' => 'integer', 'app_type' => 'integer', 'client_type' => 'integer', 'banner_place' => 'integer', 'banner_status' => 'integer', 'banner_sort' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "banner_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取信息-多条
* @param array $params
* @param array $fields
* @param string $order
* @param string $direction
* @return object|null
*/
public static function getList(array $params, array $fields = ['*'], string $order = "banner_sort", string $direction = 'desc'): object|null
{
return self::where($params)->orderBy($order, $direction)->get($fields);
}
}

48
app/Model/BasicJob.php Normal file
View File

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $job_id 主键id
* @property string $job_name 职位名称
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class BasicJob extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'basic_job';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['job_id', 'job_name', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['job_id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "job_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*'],): object|null
{
return self::where($params)->first($fields);
}
}

48
app/Model/BasicNation.php Normal file
View File

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $nation_id 主键id
* @property string $nation_name 民族名称
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class BasicNation extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'basic_nation';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['nation_id', 'nation_name', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['nation_id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "nation_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*'],): object|null
{
return self::where($params)->first($fields);
}
}

77
app/Model/CodeLog.php Normal file
View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $code_log_id 主键id
* @property int $type 类型1:短信 2:邮件)
* @property int $status 状态1:发送成功 2:发送失败)
* @property int $scene 场景1:登陆)
* @property string $phone 手机号
* @property string $code 验证码
* @property string $third_code 第三方编码
* @property string $remarks 备注
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class CodeLog extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'code_log';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['code_log_id', 'type', 'status', 'scene', 'phone', 'code', 'third_code', 'remarks', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['code_log_id' => 'integer', 'type' => 'integer', 'status' => 'integer', 'scene' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "code_log_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取信息-多条
* @param array $params
* @param array $fields
* @param string $order
* @param string $direction
* @return object|null
*/
public static function getList(array $params, array $fields = ['*']): object|null
{
return self::where($params)->get($fields);
}
/**
* 新增-批量
* @param array $data
* @return \Hyperf\Database\Model\Model|CodeLog
*/
public static function addCodeLog(array $data): \Hyperf\Database\Model\Model|CodeLog
{
return self::create($data);
}
}

77
app/Model/Coupon.php Normal file
View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $coupon_id 主键id
* @property string $coupon_name 优惠卷名称
* @property string $coupon_icon 优惠卷图片
* @property int $coupon_client 使用平台1:小程序)
* @property int $coupon_type 优惠卷类型1:无门槛 2:满减)
* @property int $coupon_status 状态1:正常 2:强制失效 3:结束)
* @property int $distribution_object 发放对象1:新注册用户 2:会员 3:近期消费 4:近期购药)
* @property int $application_scope 适用范围1:全部 2:快速问诊 3:专家问诊 4:公益问诊 5:问诊购药)
* @property int $is_display 是否展示0: 1:是)
* @property int $distribution_with_day 发放关联时间(发放对象为近期消费等类型时规定天数)
* @property int $coupon_count 发放数量
* @property int $coupon_take_count 领取数量
* @property int $coupon_ used_count 使用数量
* @property string $coupon_price 优惠卷金额
* @property string $with_amount 符合满减标准金额(优惠卷类型为满减时使用)
* @property int $valid_type 有效类型1:绝对时效xxx-xxx时间段有效 2:相对时效 n天内有效
* @property int $valid_days 自领取之日起有效天数
* @property string $valid_start_time 开始使用时间
* @property string $valid_end_time 结束使用时间
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class Coupon extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'coupon';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['coupon_id', 'coupon_name', 'coupon_icon', 'coupon_client', 'coupon_type', 'coupon_status', 'distribution_object', 'application_scope', 'is_display', 'distribution_with_day', 'coupon_count', 'coupon_take_count', 'coupon_ used_count', 'coupon_price', 'with_amount', 'valid_type', 'valid_days', 'valid_start_time', 'valid_end_time', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['coupon_id' => 'integer', 'coupon_client' => 'integer', 'coupon_type' => 'integer', 'coupon_status' => 'integer', 'distribution_object' => 'integer', 'application_scope' => 'integer', 'is_display' => 'integer', 'distribution_with_day' => 'integer', 'coupon_count' => 'integer', 'coupon_take_count' => 'integer', 'coupon_ used_count' => 'integer', 'valid_type' => 'integer', 'valid_days' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "coupon_id";
/**
* 获取-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取信息-多条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getList(array $params, array $fields = ['*']): object|null
{
return self::where($params)->get($fields);
}
}

View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $disease_class_id 主键id
* @property string $disease_class_name 疾病分类名称
* @property int $expertise_id 医生专长id
* @property int $disease_class_status 状态0:删除 1:正常)
* @property int $disease_class_enable 是否启用0: 1:是)
* @property int $icd_id 标准分类id
* @property int $is_hot 是否热门0: 1:是)
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class DiseaseClass extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'disease_class';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['disease_class_id', 'disease_class_name', 'expertise_id', 'disease_class_status', 'disease_class_enable', 'icd_id', 'is_hot', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['disease_class_id' => 'integer', 'expertise_id' => 'integer', 'disease_class_status' => 'integer', 'disease_class_enable' => 'integer', 'icd_id' => 'integer', 'is_hot' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "disease_class_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*'],): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params = [], array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
/**
* 获取数据-限制条数
* @param array $params
* @param int|string $limit
* @param array $fields
* @return Collection|array
*/
public static function getLimit(array $params = [],int|string $limit = 5, array $fields = ['*']): Collection|array
{
return self::where($params)->limit($limit)->get($fields);
}
}

View File

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $expertise_id 主键id
* @property string $expertise_name 专长名称
* @property int $expertise_sort 排序(越大排序越靠前)
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class DiseaseClassExpertise extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'disease_class_expertise';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['expertise_id', 'expertise_name', 'expertise_sort', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['expertise_id' => 'integer', 'expertise_sort' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "expertise_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*'],): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取信息-排序-列表
* @param array $params
* @param array $fields
* @return array
*/
public static function getOrderList(array $params = [], array $fields = ['*'],): array
{
return self::where($params)->orderBy('expertise_sort','desc')->get($fields)->toArray();
}
}

View File

@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $doctor_expertise_id 主键id
* @property int $doctor_id 医生id
* @property int $expertise_id 专长id
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class DoctorExpertise extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'doctor_expertise';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['doctor_expertise_id', 'doctor_id', 'expertise_id', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['doctor_expertise_id' => 'integer', 'doctor_id' => 'integer', 'expertise_id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "doctor_expertise_id";
/**
* 关联专长表
*/
public function DiseaseClassExpertise(): HasOne
{
return $this->hasOne(DiseaseClassExpertise::class, 'expertise_id', 'expertise_id');
}
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 多条
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params, array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
/**
* 获取医生专长
* 关联专长表
* 多条
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getDiseaseClassExpertiseList(array $params, array $fields = ['*']): Collection|array
{
return self::with(['DiseaseClassExpertise'])->where($params)->get($fields);
}
/**
* 删除
* @param array $params
* @return int|mixed
*/
public static function deleteDoctorExpertise(array $params): mixed
{
return self::where($params)->delete();
}
/**
* 新增
* @param array $data
* @return DoctorExpertise|\Hyperf\Database\Model\Model
*/
public static function addDoctorExpertise(array $data): DoctorExpertise|\Hyperf\Database\Model\Model
{
return self::create($data);
}
}

View File

@ -0,0 +1,108 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $inquiry_config_id 主键id
* @property int $doctor_id 医生id
* @property int $system_inquiry_config_id 系统问诊配置表id
* @property int $inquiry_type 接诊类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @property int $inquiry_mode 接诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
* @property int $work_num_day 每日接诊数量
* @property string $inquiry_price 接诊价格(专家问诊-公益问诊)
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
* @property-read SystemInquiryConfig $SystemInquiryConfig
*/
class DoctorInquiryConfig extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'doctor_inquiry_config';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['inquiry_config_id', 'doctor_id', 'system_inquiry_config_id', 'inquiry_type', 'inquiry_mode', 'work_num_day', 'inquiry_price', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['inquiry_config_id' => 'integer', 'doctor_id' => 'integer', 'system_inquiry_config_id' => 'integer', 'inquiry_type' => 'integer', 'inquiry_mode' => 'integer', 'work_num_day' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "inquiry_config_id";
/**
* 关联系统问诊配置表
*/
public function SystemInquiryConfig(): HasOne
{
return $this->hasOne(SystemInquiryConfig::class, 'system_inquiry_config_id', 'system_inquiry_config_id');
}
/**
* 获取医生接诊配置信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取医生接诊配置信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getInquiryConfigOne(array $params, array $fields = ['*']): object|null
{
return self::with(['SystemInquiryConfig'])->where($params)->first($fields);
}
/**
* 获取医生接诊配置信息-多条
* 在线问诊+专家问诊
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getInquiryConfigList(array $params, array $fields = ['*']): object|null
{
return self::with(['SystemInquiryConfig'])
->where($params)->whereIn("inquiry_type",[1,3])->get($fields);
}
/**
* 创建
* @param array $data
* @return \Hyperf\Database\Model\Model|DoctorInquiryConfig
*/
public static function addInquiryConfig(array $data): \Hyperf\Database\Model\Model|DoctorInquiryConfig
{
return self::create($data);
}
/**
* 修改医生接诊配置
* @param array $params
* @param array $data
* @return int
*/
public static function editInquiryConfig(array $params = [], array $data = []): int
{
return self::where($params)->update($data);
}
}

View File

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $record_id 主键id
* @property int $doctor_id 医生id
* @property int $inquiry_config_id 接诊配置id
* @property string $old_price 原价格
* @property string $new_price 新价格
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class DoctorInquiryPriceRecord extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'doctor_inquiry_price_record';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['record_id', 'doctor_id', 'inquiry_config_id', 'old_price', 'new_price', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['record_id' => 'integer', 'doctor_id' => 'integer', 'inquiry_config_id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "record_id";
/**
* 获取是否存在
* @param array $params
* @return bool
*/
public static function getExists(array $params): bool
{
return self::where($params)->exists();
}
/**
* 获取数量
* @param array $params
* @return int
*/
public static function getCount(array $params): int
{
return self::where($params)->count();
}
}

85
app/Model/Hospital.php Normal file
View File

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $hospital_id 主键id
* @property string $hospital_name 医院名称
* @property int $hospital_status 状态0:禁用 1:正常 2:删除)
* @property string $hospital_level_name 医院等级名称
* @property string $post_code 邮政编码
* @property string $tele_phone 电话
* @property int $province_id 省份id
* @property string $province 省份
* @property int $city_id 城市id
* @property string $city 城市
* @property int $county_id 区县id
* @property string $county 区县
* @property string $address 地址
* @property string $lat 纬度
* @property string $lng 经度
* @property string $desc 简介
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class Hospital extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'hospital';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['hospital_id', 'hospital_name', 'hospital_status', 'hospital_level_name', 'post_code', 'tele_phone', 'province_id', 'province', 'city_id', 'city', 'county_id', 'county', 'address', 'lat', 'lng', 'desc', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['hospital_id' => 'integer', 'hospital_status' => 'integer', 'province_id' => 'integer', 'city_id' => 'integer', 'county_id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "hospital_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params = [], array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
/**
* 新增医院-批量
* @param array $data 新增数据
* @return \Hyperf\Database\Model\Model|Hospital
*/
public static function addHospital(array $data): \Hyperf\Database\Model\Model|Hospital
{
return self::create($data);
}
}

View File

@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $department_custom_id 主键id
* @property int $department_id 医院科室-标准id
* @property string $department_custom_name 科室名称-自定义
* @property string $department_name 科室名称-标准
* @property string $department_code 科室编码-标准
* @property int $department_status 状态1:正常 2:删除)
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class HospitalDepartmentCustom extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'hospital_department_custom';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['department_custom_id', 'department_id', 'department_custom_name', 'department_name', 'department_code', 'department_status', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['department_custom_id' => 'integer', 'department_id' => 'integer', 'department_status' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "department_custom_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params = [], array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
}

View File

@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $case_product_id 主键id
* @property int $inquiry_case_id 病例id
* @property int $product_id 商品id
* @property int $case_product_num 药品数量
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
* @property-read Product $Product
*/
class InquiryCaseProduct extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'inquiry_case_product';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['case_product_id', 'inquiry_case_id', 'product_id', 'case_product_num', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['case_product_id' => 'integer', 'inquiry_case_id' => 'integer', 'product_id' => 'integer', 'case_product_num' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "case_product_id";
/**
* 关联商品表
*/
public function Product(): HasOne
{
return $this->hasOne(Product::class, 'product_id', 'product_id');
}
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params = [], array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
/**
* 获取数据-关联商品表
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getWithProductList(array $params = [], array $fields = ['*']): Collection|array
{
return self::with([
"Product"
])
->where($params)
->get($fields);
}
}

18
app/Model/Model.php Normal file
View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Model;
use Hyperf\DbConnection\Model\Model as BaseModel;
abstract class Model extends BaseModel
{
}

69
app/Model/Module.php Normal file
View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $module_id 主键ID
* @property string $module_name 模块名称
* @property string $module_img_path 模块图片
* @property int $app_type 应用程序类型1:小程序 2:app
* @property int $client_type 类型1:患者端 2:医生端 3:药师端)
* @property int $module_place 展示位置1:首页)
* @property int $module_status 状态0:删除 1:正常 2:禁用)
* @property int $module_sort 排序值(越大排序越靠前)
* @property string $module_link 跳转地址
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class Module extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'module';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['module_id', 'module_name', 'module_img_path', 'app_type', 'client_type', 'module_place', 'module_status', 'module_sort', 'module_link', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['module_id' => 'integer', 'app_type' => 'integer', 'client_type' => 'integer', 'module_place' => 'integer', 'module_status' => 'integer', 'module_sort' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "module_id";
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取信息-多条
* @param array $params
* @param array $fields
* @param string $order
* @param string $direction
* @return object|null
*/
public static function getList(array $params, array $fields = ['*'], string $order = "module_sort", string $direction = 'desc'): object|null
{
return self::where($params)->orderBy($order, $direction)->get($fields);
}
}

View File

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $evaluation_id 主键id
* @property int $doctor_id 医生id
* @property int $patient_id 患者id
* @property int $order_inquiry_id 订单-问诊id
* @property string $reply_quality 回复质量(百分制)
* @property string $service_attitude 服务态度(百分制)
* @property string $reply_progress 回复速度(百分制)
* @property string $avg_score 平均得分(百分制)
* @property int $type 类型1:默认评价 2:主动评价)
* @property string $content 评价内容
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class OrderEvaluation extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'order_evaluation';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['evaluation_id', 'doctor_id', 'patient_id', 'order_inquiry_id', 'reply_quality', 'service_attitude', 'reply_progress', 'avg_score', 'type', 'content', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['evaluation_id' => 'integer', 'doctor_id' => 'integer', 'patient_id' => 'integer', 'order_inquiry_id' => 'integer', 'type' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "evaluation_id";
/**
* 获取评价列表-分页
* @param array $params 条件
* @param array $fields 字段
* @param int|null $page 页码
* @param int|null $per_page 每页个数
* @return array
*/
public static function getPage(array $params, array $fields = ["*"], int $page = null, ?int $per_page = 10): array
{
$raw = self::where($params)->paginate($per_page, $fields, "page", $page);
$data = array();
$data['current_page'] = $raw->currentPage();// 当前页码
$data['total'] = $raw->total();//数据总数
$data['data'] = $raw->items();//数据
$data['per_page'] = $raw->perPage();//每页个数
$data['last_page'] = $raw->lastPage();//最后一页
return $data;
}
}

105
app/Model/OrderInquiry.php Normal file
View File

@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $order_inquiry_id 主键id
* @property int $user_id 用户id-患者
* @property int $patient_id 患者id
* @property int $doctor_id 医生id未分配时为null
* @property int $family_id 家庭成员id就诊用户
* @property int $inquiry_type 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @property int $inquiry_mode 订单问诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
* @property int $inquiry_status 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
* @property int $is_delete 删除状态0: 1:是)
* @property int $inquiry_refund_status 问诊订单退款状态0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭)
* @property int $inquiry_pay_channel 支付渠道1:小程序支付 2:微信扫码支付)
* @property int $inquiry_pay_status 支付状态1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
* @property int $inquiry_no 订单编号
* @property string $escrow_trade_no 第三方支付流水号
* @property string $amount_total 订单金额
* @property string $payment_amount_total 实际付款金额
* @property string $pay_time 支付时间
* @property string $reception_time 接诊时间(已接诊)
* @property string $complete_time 订单完成时间(问诊完成时间)
* @property string $settlement_amount_total 订单与医生结算金额
* @property int $settlement_status 订单与医生结算状态0:未结算 1:已结算)
* @property string $settlement_time 订单与医生结算时间
* @property int $cancel_reason 取消订单原因1:医生未接诊 2:主动取消 3:无可分配医生 4:客服取消 5:支付超时)
* @property string $cancel_remarks 取消订单备注(自动添加)
* @property string $patient_name 患者姓名-就诊人
* @property string $patient_name_mask 患者姓名-就诊人(掩码)
* @property int $patient_sex 患者性别-就诊人0:未知 1: 2:女)
* @property int $patient_age 患者年龄-就诊人
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class OrderInquiry extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'order_inquiry';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['order_inquiry_id', 'user_id', 'patient_id', 'doctor_id', 'family_id', 'inquiry_type', 'inquiry_mode', 'inquiry_status', 'is_delete', 'inquiry_refund_status', 'inquiry_pay_channel', 'inquiry_pay_status', 'inquiry_no', 'escrow_trade_no', 'amount_total', 'payment_amount_total', 'pay_time', 'reception_time', 'complete_time', 'settlement_amount_total', 'settlement_status', 'settlement_time', 'cancel_reason', 'cancel_remarks', 'patient_name', 'patient_name_mask', 'patient_sex', 'patient_age', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['order_inquiry_id' => 'integer', 'user_id' => 'integer', 'patient_id' => 'integer', 'doctor_id' => 'integer', 'family_id' => 'integer', 'inquiry_type' => 'integer', 'inquiry_mode' => 'integer', 'inquiry_status' => 'integer', 'is_delete' => 'integer', 'inquiry_refund_status' => 'integer', 'inquiry_pay_channel' => 'integer', 'inquiry_pay_status' => 'integer', 'inquiry_no' => 'integer', 'settlement_status' => 'integer', 'cancel_reason' => 'integer', 'patient_sex' => 'integer', 'patient_age' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "order_inquiry_id";
/**
* 获取问诊订单-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 新增问诊订单-批量
* @param array $data 新增数据
* @return \Hyperf\Database\Model\Model|OrderInquiry
*/
public static function addUserDoctor(array $data): \Hyperf\Database\Model\Model|OrderInquiry
{
return self::create($data);
}
/**
* 获取信息-多条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getList(array $params, array $fields = ['*']): object|null
{
return self::where($params)->get($fields);
}
/**
* 获取数量
* @param array $params
* @return int
*/
public static function getCount(array $params): int
{
return self::where($params)->count();
}
}

View File

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $inquiry_case_id 主键id
* @property int $inquiry_cases_id 主键id
* @property int $user_id 用户id
* @property int $patient_id 患者id
* @property int $order_inquiry_id 订单-问诊id
* @property int $family_id 家庭成员id
* @property int $relation 与患者关系1:本人 2:父母 3:爱人 4:子女 5:亲戚 6:其他
* @property int $status 状态1:正常 2:删除)
* @property string $name 患者名称
* @property int $sex 患者性别0:未知 1: 2:女)
* @property int $age 患者年龄
* @property string $height 身高cm
* @property string $weight 体重kg
* @property int $disease_class_id 疾病分类id-系统
* @property string $disease_class_name 疾病名称-系统
* @property string $diagnosis_date 确诊日期
* @property string $disease_desc 病情描述(主诉)
* @property string $diagnose_images 复诊凭证(多个使用逗号分隔)
* @property int $is_allergy_history 是否存在过敏史0: 1:是)
* @property string $allergy_history 过敏史描述
* @property int $is_family_history 是否存在家族病史0: 1:是)
* @property string $family_history 家族病史描述
* @property int $is_pregnant 是否备孕、妊娠、哺乳期0: 1:是)
* @property string $pregnant 备孕、妊娠、哺乳期描述
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
* @property-read BasicJob $BasicJob
* @property-read BasicNation $BasicNation
* @property-read OrderInquiry $OrderInquiry
*/
class OrderInquiryCase extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'order_inquiry_case';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['inquiry_case_id', 'inquiry_cases_id', 'user_id', 'patient_id', 'order_inquiry_id', 'family_id', 'relation', 'status', 'name', 'sex', 'age', 'height', 'weight', 'disease_class_id', 'disease_class_name', 'diagnosis_date', 'disease_desc', 'diagnose_images', 'is_allergy_history', 'allergy_history', 'is_family_history', 'family_history', 'is_pregnant', 'pregnant', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['inquiry_case_id' => 'integer', 'inquiry_cases_id' => 'integer', 'user_id' => 'integer', 'patient_id' => 'integer', 'order_inquiry_id' => 'integer', 'family_id' => 'integer', 'relation' => 'integer', 'status' => 'integer', 'sex' => 'integer', 'age' => 'integer', 'disease_class_id' => 'integer', 'is_allergy_history' => 'integer', 'is_family_history' => 'integer', 'is_pregnant' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "inquiry_cases_id";
/**
* 关联问诊订单表
*/
public function OrderInquiry(): HasOne
{
return $this->hasOne(OrderInquiry::class, 'order_inquiry_id', 'order_inquiry_id');
}
/**
* 关联民族表
*/
public function BasicNation(): HasOne
{
return $this->hasOne(BasicNation::class, 'nation_id', 'nation_id');
}
/**
* 关联职位表
*/
public function BasicJob(): HasOne
{
return $this->hasOne(BasicJob::class, 'job_id', 'job_id');
}
/**
* 单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取结束问诊订单病例-
* @param array $params
* @param array $order_inquiry_params
* @param array $fields
* @return object|null
*/
public static function getEndOrderInquiryCaseOne(array $params, array $order_inquiry_params, array $fields = ['*']): object|null
{
return self::with([
"OrderInquiry",
])
->whereHas('OrderInquiry' , function($query) use ($order_inquiry_params){
$query->where($order_inquiry_params);
})
->where($params)
->first($fields);
}
}

View File

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Contract\LengthAwarePaginatorInterface;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $order_prescription_id 主键id
* @property int $order_inquiry_id 订单-问诊id
* @property int $doctor_id 医生id
* @property int $pharmacist_id 药师id
* @property int $icd_id 疾病id
* @property int $prescription_status 处方状态1:待审核 3:待使用 4:已失效 5:已使用)
* @property int $prescription_audit_status 处方审核状态0:审核中 1:审核成功 2:审核驳回)
* @property int $is_delete 是否删除0: 1:是)
* @property int $is_pass 处方平台是否审核通过0: 1:是)
* @property string $prescription 处方编号
* @property string $not_pass_reason 处方平台审核不通过原因
* @property string $audit_fail_reason 审核驳回原因
* @property string $doctor_name 医生名称
* @property string $patient_name 患者姓名-就诊人
* @property int $patient_sex 患者性别-就诊人1: 2:女)
* @property int $patient_age 患者年龄-就诊人
* @property string $drugs_info 药品数据
* @property string $prescription_img 处方图片
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class OrderPrescription extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'order_prescription';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['order_prescription_id', 'order_inquiry_id', 'doctor_id', 'pharmacist_id', 'icd_id', 'prescription_status', 'prescription_audit_status', 'is_delete', 'is_pass', 'prescription', 'not_pass_reason', 'audit_fail_reason', 'doctor_name', 'patient_name', 'patient_sex', 'patient_age', 'drugs_info', 'prescription_img', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['order_prescription_id' => 'integer', 'order_inquiry_id' => 'integer', 'doctor_id' => 'integer', 'pharmacist_id' => 'integer', 'icd_id' => 'integer', 'prescription_status' => 'integer', 'prescription_audit_status' => 'integer', 'is_delete' => 'integer', 'is_pass' => 'integer', 'patient_sex' => 'integer', 'patient_age' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "order_prescription_id";
/**
* 获取是否存在
* @param array $params
* @return bool
*/
public static function getExists(array $params): bool
{
return self::where($params)->exists();
}
/**
* 获取待审核处方列表-分页
* @param array $params 条件
* @param array $fields 字段
* @param int|null $page 页码
* @param int|null $per_page 每页个数
* @return array
*/
public static function getPage(array $params, array $fields = ["*"], int $page = null, ?int $per_page = 10): array
{
$raw = self::where($params)->paginate($per_page, $fields, "page", $page);
$data = array();
$data['current_page'] = $raw->currentPage();// 当前页码
$data['total'] = $raw->total();//数据总数
$data['data'] = $raw->items();//数据
$data['per_page'] = $raw->perPage();//每页个数
$data['last_page'] = $raw->lastPage();//最后一页
return $data;
}
}

106
app/Model/PatientFamily.php Normal file
View File

@ -0,0 +1,106 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $family_id 主键id
* @property int $patient_id 患者id
* @property int $relation 与患者关系1:本人 2:父母 3:爱人 4:子女 5:亲戚 6:其他
* @property int $status 状态1:正常 2:删除)
* @property int $is_default 是否默认0: 1:是)
* @property string $card_name 姓名
* @property string $card_name_mask 姓名(掩码)
* @property string $mobile 电话
* @property string $mobile_mask 电话(掩码)
* @property int $type 身份类型1:身份证 2:护照 3:港澳通行证 4:台胞证)
* @property string $id_number 证件号码
* @property string $id_number_mask 证件号码(掩码)
* @property int $sex 性别0:未知 1: 2:女)
* @property int $age 年龄
* @property int $province_id 省份id
* @property string $province 省份
* @property int $city_id 城市id
* @property string $city 城市
* @property int $county_id 区县id
* @property string $county 区县
* @property string $height 身高cm
* @property string $weight 体重kg
* @property int $marital_status 婚姻状况0:未婚 1:已婚 2:离异)
* @property int $nation_id 民族
* @property string $nation_name 民族名称
* @property int $job_id 职业
* @property string $job_name 职业名称
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class PatientFamily extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'patient_family';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['family_id', 'patient_id', 'relation', 'status', 'is_default', 'card_name', 'card_name_mask', 'mobile', 'mobile_mask', 'type', 'id_number', 'id_number_mask', 'sex', 'age', 'province_id', 'province', 'city_id', 'city', 'county_id', 'county', 'height', 'weight', 'marital_status', 'nation_id', 'nation_name', 'job_id', 'job_name', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['family_id' => 'integer', 'patient_id' => 'integer', 'relation' => 'integer', 'status' => 'integer', 'is_default' => 'integer', 'type' => 'integer', 'sex' => 'integer', 'age' => 'integer', 'province_id' => 'integer', 'city_id' => 'integer', 'county_id' => 'integer', 'marital_status' => 'integer', 'nation_id' => 'integer', 'job_id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "family_id";
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params = [], array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
/**
* 新增数据
* @param array $data
* @return Model|PatientFamily
*/
public static function addPatientFamily(array $data = []): Model|PatientFamily
{
return self::create($data);
}
/**
* 修改
* @param array $params
* @param array $data
* @return int
*/
public static function edit(array $params = [], array $data = []): int
{
return self::where($params)->update($data);
}
}

View File

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $patient_follow_id 主键id
* @property int $patient_id 患者id
* @property int $doctor_id 医生id
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class PatientFollow extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'patient_follow';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['patient_follow_id', 'patient_id', 'doctor_id', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['patient_follow_id' => 'integer', 'patient_id' => 'integer', 'doctor_id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "patient_follow_id";
/**
* 获取是否存在
* @param array $params
* @return bool
*/
public static function getExists(array $params): bool
{
return self::where($params)->exists();
}
}

View File

@ -0,0 +1,134 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Relations\BelongsTo;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Database\Model\Relations\HasOneThrough;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $history_inquiry_id 主键id
* @property int $patient_id 患者id
* @property int $doctor_id 医生id
* @property int $pharmacist_id 药师id
* @property int $order_inquiry_id 订单-问诊id
* @property int $history_status 删除状态0: 1:是)
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
* @property-read UserDoctor $UserDoctor
* @property-read Hospital $UserDoctorHospital
*/
class PatientHistoryInquiry extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'patient_history_inquiry';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['history_inquiry_id', 'patient_id', 'doctor_id', 'pharmacist_id', 'order_inquiry_id', 'history_status', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['history_inquiry_id' => 'integer', 'patient_id' => 'integer', 'doctor_id' => 'integer', 'pharmacist_id' => 'integer', 'order_inquiry_id' => 'integer', 'history_status' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "history_inquiry_id";
/**
* 关联医生表
*/
public function UserDoctor(): HasOne
{
return $this->hasOne(UserDoctor::class, 'doctor_id','doctor_id');
}
/**
* 远程关联医生表-医院表
* @return HasOneThrough
*/
public function UserDoctorHospital(): HasOneThrough
{
return $this->hasOneThrough(
Hospital::class,
UserDoctor::class,
"doctor_id",
"hospital_id",
"doctor_id",
"hospital_id",
);
}
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取信息-多条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getList(array $params, array $fields = ['*']): object|null
{
return self::where($params)->get($fields);
}
/**
* 获取信息-多条-限制条数
* @param array $params
* @param array $fields
* @param int $limit
*/
public static function getLimit(array $params, array $fields = ['*'],int $limit = 5): array
{
return self::where($params)->limit($limit)->get($fields)->toArray();
}
/**
* 获取首页用户历史问诊数据
* 关联表user_doctor
* @param array $params
* @param array $fields
* @param int $limit
* @return Collection|array|\Hyperf\Utils\Collection
*/
public static function getIndexHistoryDoctorLimit(array $params, array $fields = ["*"],int $limit = 5): Collection|array|\Hyperf\Utils\Collection
{
return self::with([
"UserDoctor:doctor_id,user_name,avatar,hospital_id",
"UserDoctor.Hospital:hospital_id,hospital_name"
])
->where($params)
->limit($limit)
->get($fields);
}
/**
* 修改
* @param array $params
* @param array $data
* @return int
*/
public static function edit(array $params = [], array $data = []): int
{
return self::where($params)->update($data);
}
}

View File

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $audit_statistics_id 主键id
* @property int $pharmacist_id 药师id
* @property string $statistics_date 统计日期
* @property int $audit_number 审核数量
* @property int $not_pass_number 审核不通过数量
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class PharmacistAuditStatistic extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'pharmacist_audit_statistics';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['audit_statistics_id', 'pharmacist_id', 'statistics_date', 'audit_number', 'not_pass_number', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['audit_statistics_id' => 'integer', 'pharmacist_id' => 'integer', 'audit_number' => 'integer', 'not_pass_number' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "audit_statistics_id";
/**
* 获取审方信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取审方数量
* @param array $params
* @return int
*/
public static function getCount(array $params): int
{
return self::where($params)->count();
}
}

89
app/Model/Product.php Normal file
View File

@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $product_id 主键id
* @property int $product_platform_id 处方平台商品id
* @property string $product_name 商品名称
* @property string $common_name 商品通用名
* @property string $product_price 商品价格
* @property string $mnemonic_code 商品助记码(首字母简拼)
* @property int $product_type 药品类型0:未知 1:中成药 2:西药)
* @property string $product_platform_code 处方平台商品编码
* @property string $product_pharmacy_code 第三方药店商品编码
* @property string $product_cover_img 商品封面图
* @property string $product_spec 商品规格
* @property string $license_number 批准文号
* @property string $manufacturer 生产厂家
* @property string $single_unit 单次剂量1次1包
* @property string $single_use 单次用法(例:口服)
* @property string $packaging_unit 基本包装单位(例:盒/)
* @property string $frequency_use 使用频率(1天3次)
* @property string $available_days 可用天数(3)
* @property string $product_remarks 商品备注
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class Product extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'product';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['product_id', 'product_platform_id', 'product_name', 'common_name', 'product_price', 'mnemonic_code', 'product_type', 'product_platform_code', 'product_pharmacy_code', 'product_cover_img', 'product_spec', 'license_number', 'manufacturer', 'single_unit', 'single_use', 'packaging_unit', 'frequency_use', 'available_days', 'product_remarks', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['product_id' => 'integer', 'product_platform_id' => 'integer', 'product_type' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "product_id";
/**
* 关联库存表
*/
public function ProductPlatformAmount(): HasOne
{
return $this->hasOne(ProductPlatformAmount::class, 'product_platform_id','product_platform_id');
}
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取库存信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getWithAmountOne(array $params, array $fields = ['*']): object|null
{
return self::with([
'ProductPlatformAmount'
])
->where($params)
->first($fields);
}
}

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $amount_id 主键id
* @property int $product_platform_id 商品id
* @property string $product_platform_code 处方平台商品编码
* @property int $real_stock 实际库存
* @property int $stock 现有库存
* @property int $lock_stock 锁定库存
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class ProductPlatformAmount extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'product_platform_amount';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['amount_id', 'product_platform_id', 'product_platform_code', 'real_stock', 'stock', 'lock_stock', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['amount_id' => 'integer', 'product_platform_id' => 'integer', 'real_stock' => 'integer', 'stock' => 'integer', 'lock_stock' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "amount_id";
}

View File

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $system_inquiry_config_id 主键id
* @property int $inquiry_type 接诊类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @property int $inquiry_mode 接诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
* @property int $max_work_num_day 每日最大接诊数量为0表示不限制接诊数量
* @property string $inquiry_price 接诊价格(存在多档次,逗号分隔)
* @property string $min_inquiry_price 最低接诊价格(专家问诊)
* @property string $max_inquiry_price 最高接诊价格(专家问诊)
* @property int $times_number 沟通次数0为不限制次数
* @property int $duration 沟通时长分钟0为不限制时长
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class SystemInquiryConfig extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'system_inquiry_config';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['system_inquiry_config_id', 'inquiry_type', 'inquiry_mode', 'max_work_num_day', 'inquiry_price', 'min_inquiry_price', 'max_inquiry_price', 'times_number', 'duration', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['system_inquiry_config_id' => 'integer', 'inquiry_type' => 'integer', 'inquiry_mode' => 'integer', 'max_work_num_day' => 'integer', 'times_number' => 'integer', 'duration' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "system_inquiry_config_id";
/**
* 获取医生接诊配置信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params = [], array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
}

View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $id id
* @property string $uuid 唯一uuid
* @property string $name 医院名称
* @property int $prov_id 省份id
* @property string $prov_name 省份名称
* @property int $city_id 城市id
* @property string $city_name 城市名称
* @property int $county_id 区县id
* @property string $county_name 区县名称
* @property string $road 街道
* @property string $address 详细地址
* @property string $postcode 邮政编码
* @property string $lat 纬度
* @property string $lng 纬度
* @property string $info 简介
* @property string $legal_person 法人
* @property string $office_phone 电话
* @property int $level 等级0未知 1三级甲等 2三级医院 3二级医院 4其他)
* @property string $create_date 创建日期
*/
class TbHospitalMy extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'tb_hospital_my';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['id', 'uuid', 'name', 'prov_id', 'prov_name', 'city_id', 'city_name', 'county_id', 'county_name', 'road', 'address', 'postcode', 'lat', 'lng', 'info', 'legal_person', 'office_phone', 'level', 'create_date'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['id' => 'integer', 'prov_id' => 'integer', 'city_id' => 'integer', 'county_id' => 'integer', 'level' => 'integer'];
protected string $primaryKey = "id";
/**
* 获取信息-多条
* @param array $params
* @param array $fields
* @param string $order
* @param string $direction
* @return object|null
*/
public static function getList(array $params = [], array $fields = ['*']): object|null
{
return self::where($params)->get($fields);
}
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
}

82
app/Model/User.php Normal file
View File

@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Builder;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $user_id 主键
* @property string $user_name 用户名称
* @property string $user_account 账号
* @property string $mobile 手机号
* @property string $wx_mobile 微信手机号
* @property string $user_password 密码
* @property string $salt 密码混淆码
* @property int $user_type 用户类型1:患者 2:医师 3:药师)
* @property int $user_status 状态0:禁用 1:正常 2:删除)
* @property int $register_method 注册方式1:微信小程序
* @property string $login_ip 登陆ip
* @property string $last_login_at 最后登陆时间
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class User extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'user';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['user_id', 'user_name', 'user_account', 'mobile', 'wx_mobile', 'user_password', 'salt', 'user_type', 'user_status', 'register_method', 'login_ip', 'last_login_at', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['user_id' => 'integer', 'user_type' => 'integer', 'user_status' => 'integer', 'register_method' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "user_id";
/**
* 获取用户信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
$result = self::where($params)->first($fields);
unset($result->user_password);
unset($result->salt);
return $result;
}
/**
* 新增用户-批量
* @param array $data 新增数据
* @return User|\Hyperf\Database\Model\Model
*/
public static function addUser(array $data): User|\Hyperf\Database\Model\Model
{
return self::create($data);
}
/**
* 修改用户-批量
* @param array $params
* @param array $data
* @return int
*/
public static function editUser(array $params = [], array $data = []) : int
{
return self::where($params)->update($data);
}
}

91
app/Model/UserCoupon.php Normal file
View File

@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $user_coupon_id 主键id
* @property int $user_id 用户id
* @property int $patient_id 患者id
* @property int $coupon_id 优惠卷id
* @property int $user_coupon_status 状态0:未使用 1:已使用 3:已过期)
* @property string $coupon_use_date 使用时间
* @property string $valid_start_time 开始使用时间
* @property string $valid_end_time 过期使用时间
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
* @property-read Coupon $Coupon
*/
class UserCoupon extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'user_coupon';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['user_coupon_id', 'user_id', 'patient_id', 'coupon_id', 'user_coupon_status', 'coupon_use_date', 'valid_start_time', 'valid_end_time', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['user_coupon_id' => 'integer', 'user_id' => 'integer', 'patient_id' => 'integer', 'coupon_id' => 'integer', 'user_coupon_status' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "user_coupon_id";
/**
* 关联医院表
*/
public function Coupon(): HasOne
{
return $this->hasOne(Coupon::class, 'coupon_id', 'coupon_id');
}
/**
* 获取-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取优惠卷信息-多条
* @param array $params
* @param array $coupon_params
* @param array $fields
* @return Collection|array
*/
public static function getWithCouponList(array $params,array $coupon_params, array $fields = ['*']): Collection|array
{
return self::with(['Coupon'])
->whereHas('Coupon' , function($query) use ($coupon_params){
$query->where($coupon_params);
})
->where($params)->get($fields);
}
/**
* 新增用户优惠卷
* @param array $data
* @return \Hyperf\Database\Model\Model|UserCoupon
*/
public static function addUserCoupon(array $data): \Hyperf\Database\Model\Model|UserCoupon
{
return self::create($data);
}
}

282
app/Model/UserDoctor.php Normal file
View File

@ -0,0 +1,282 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Relations\BelongsTo;
use Hyperf\Database\Model\Relations\HasMany;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Database\Model\Relations\HasOneThrough;
use Hyperf\DbConnection\Db;
use Hyperf\Snowflake\Concern\Snowflake;
use Hyperf\Utils\Arr;
/**
* @property int $doctor_id 主键
* @property int $user_id 用户id
* @property string $user_name 用户名称
* @property string $open_id 微信open_id
* @property string $union_id 微信开放平台唯一标识
* @property string $wx_session_key 微信会话密钥
* @property int $status 状态0:禁用 1:正常 2:删除)
* @property int $idcard_status 实名认证状态0:未认证 1:认证通过 2:认证失败)
* @property int $iden_auth_status 身份认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
* @property string $iden_auth_fail_reason 身份认证失败原因
* @property int $multi_point_status 医生多点执业认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
* @property string $multi_point_fail_reason 多点执业认证失败原因
* @property int $is_bind_bank 是否已绑定结算银行卡0: 1:是)
* @property int $is_recommend 是否首页推荐0: 1:是)
* @property string $mobile 电话
* @property int $sex 性别0:未知 1: 2:女)
* @property int $age 年龄
* @property string $avatar 头像
* @property int $doctor_title 医生职称1:执业医师 2:主治医师 3:副主任医师 4:主任医师)
* @property int $department_custom_id 科室id-自定义
* @property string $department_custom_name 科室名称(如未自己输入,填入标准科室名称)
* @property string $department_custom_mobile 科室电话
* @property int $hospital_id 所属医院id
* @property int $served_patients_num 服务患者数量
* @property string $praise_rate 好评率百分制。订单平均评价中超过4-5分的订单总数 / 总订单数 * 5
* @property string $avg_response_time 平均响应时间(分钟制)
* @property int $number_of_fans 被关注数量
* @property int $is_online 是否在线0:不在线 1:在线)
* @property int $is_img_expert_reception 是否参加专家图文接诊0: 1:是)
* @property int $is_img_welfare_reception 是否参加公益图文问诊0: 1:是)
* @property int $is_img_quick_reception 是否参加快速图文接诊0: 1:是)
* @property int $is_platform_deep_cooperation 是否平台深度合作医生0: 1:是)
* @property int $is_enterprise_deep_cooperation 是否企业深度合作医生0: 1:是)
* @property string $be_good_at 擅长
* @property string $brief_introduction 医生简介
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
* @property-read \Hyperf\Database\Model\Collection|DoctorExpertise[] $DoctorExpertise
* @property-read \Hyperf\Database\Model\Collection|DoctorInquiryConfig[] $DoctorInquiryConfig
* @property-read Hospital $Hospital
* @property-read \Hyperf\Database\Model\Collection|OrderInquiry[] $OrderInquiry
*/
class UserDoctor extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'user_doctor';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['doctor_id', 'user_id', 'user_name', 'open_id', 'union_id', 'wx_session_key', 'status', 'idcard_status', 'iden_auth_status', 'iden_auth_fail_reason', 'multi_point_status', 'multi_point_fail_reason', 'is_bind_bank', 'is_recommend', 'mobile', 'sex', 'age', 'avatar', 'doctor_title', 'department_custom_id', 'department_custom_name', 'department_custom_mobile', 'hospital_id', 'served_patients_num', 'praise_rate', 'avg_response_time', 'number_of_fans', 'is_online', 'is_img_expert_reception', 'is_img_welfare_reception', 'is_img_quick_reception', 'is_platform_deep_cooperation', 'is_enterprise_deep_cooperation', 'be_good_at', 'brief_introduction', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['doctor_id' => 'integer', 'user_id' => 'integer', 'status' => 'integer', 'idcard_status' => 'integer', 'iden_auth_status' => 'integer', 'multi_point_status' => 'integer', 'is_bind_bank' => 'integer', 'is_recommend' => 'integer', 'sex' => 'integer', 'age' => 'integer', 'doctor_title' => 'integer', 'department_custom_id' => 'integer', 'hospital_id' => 'integer', 'served_patients_num' => 'integer', 'number_of_fans' => 'integer', 'is_online' => 'integer', 'is_img_expert_reception' => 'integer', 'is_img_welfare_reception' => 'integer', 'is_img_quick_reception' => 'integer', 'is_platform_deep_cooperation' => 'integer', 'is_enterprise_deep_cooperation' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "doctor_id";
/**
* 关联医院表
*/
public function Hospital(): HasOne
{
return $this->hasOne(Hospital::class, 'hospital_id', 'hospital_id');
}
/**
* 关联问诊配置表(一对多)
* @return HasMany
*/
public function DoctorInquiryConfig(): HasMany
{
return $this->hasMany(DoctorInquiryConfig::class, "doctor_id", "doctor_id");
}
/**
* 关联医生专长表
* @return HasMany
*/
public function DoctorExpertise(): HasMany
{
return $this->hasMany(DoctorExpertise::class, "doctor_id", "doctor_id");
}
/**
* 关联订单-问诊表表
* @return HasMany
*/
public function OrderInquiry(): HasMany
{
return $this->hasMany(OrderInquiry::class, "doctor_id", "doctor_id");
}
/**
* 获取医生信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 新增医生-批量
* @param array $data 新增数据
* @return \Hyperf\Database\Model\Model|UserDoctor
*/
public static function addUserDoctor(array $data): \Hyperf\Database\Model\Model|UserDoctor
{
return self::create($data);
}
/**
* 修改医生-批量
* @param array $params
* @param array $data
* @return int
*/
public static function editUserDoctor(array $params = [], array $data = []): int
{
return self::where($params)->update($data);
}
/**
* 首页推荐医生
* 推荐规则:
* 1:平台深度合作医生
* 2:接诊量由高到低的医生
* 3:好评率由高到低的医生
* 5:在线
* 65个
* @param int $limit 数量
* @param array $fields
* @return array|Collection|\Hyperf\Utils\Collection
*/
public static function getIndexRecommendDoctorLimit(int $limit = 5, array $fields = ['*']): array|Collection|\Hyperf\Utils\Collection
{
$params = array();
// 状态0:禁用 1:正常 2:删除)
$params["status"] = 1;
// 身份认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
$params["iden_auth_status"] = 1;
// 是否在线0:不在线 1:在线)
$params["is_online"] = 1;
// 是否参加专家图文接诊0:否 1:是)
$params["is_img_expert_reception"] = 1;
$datas = self::with([
'Hospital:hospital_id,hospital_name,hospital_level_name',
'DoctorInquiryConfig',
'DoctorInquiryConfig.SystemInquiryConfig'
])
->where($params)
->orderBy("is_platform_deep_cooperation", "desc")
->orderBy("served_patients_num", "desc")
->orderBy("praise_rate", "desc")
->limit($limit)
->get($fields);
return $datas;
}
/**
* 获取问诊医生列表
* 专家问诊-公益问诊共用
* @param array $hospital_params 医院搜索条件
* @param array $doctor_params 医生搜索条件
* @param array $doctor_or_params 医生搜索条件
* @param array $doctor_expertise_params
* @param string|int $sort_order
* @param array $fields
* @param int|null $page
* @param int|null $per_page
* @return array
*/
public static function getInquiryDoctorPage(string $keyword = "",array $hospital_params = [],array $doctor_params = [],array $doctor_expertise_params = [],string|int $sort_order = 1,array $fields = ["*"], int $page = null, ?int $per_page = 10): array
{
$result = self::with([
"Hospital:hospital_id,hospital_name,hospital_status,hospital_level_name,province_id,city_id",
"DoctorExpertise" => function($query) use($doctor_expertise_params){
$query->where($doctor_expertise_params);
},
"DoctorExpertise.DiseaseClassExpertise:expertise_id,expertise_name",
"DoctorInquiryConfig" => function($query) use($sort_order){
$params = array();
$params['inquiry_mode'] = 1;// 接诊方式:图文
$query->where($params)->whereIn('inquiry_type',[1,3]);
if ($sort_order == 1){
// 综合
$query->orderBy('inquiry_price','asc');// 价格从低到高
}elseif ($sort_order == 3){
// 价格从低到高
$query->orderBy('inquiry_price','asc');
}elseif ($sort_order == 4){
// 价格从高到低
$query->orderBy('inquiry_price','desc');// 价格从高到低
}
return $query;
},
'DoctorInquiryConfig.SystemInquiryConfig',
])
->where($doctor_params)
->when($keyword,function ($query, $keyword){
$query->where(function($query) use ($keyword){
$query->orwhere("user_name",'like','%' . $keyword . '%');
$query->orwhere("hospital_name",'like','%' . $keyword . '%');
$query->orwhere("department_custom_name",'like','%' . $keyword . '%');
});
})
->when($sort_order,function ($query,$sort_order){
if ($sort_order == 1){
$query->orderBy('is_recommend','desc');// 是否首页推荐0:否 1:是)
$query->orderBy('avg_response_time','desc');// 响应时间快
$query->orderBy('served_patients_num','desc');// 服务数从多到少
$query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"),'asc');// 名称排名
}elseif ($sort_order == 2){
// 响应时间快
$query->orderBy('avg_response_time','desc');
$query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"),'asc');// 名称排名
}elseif ($sort_order == 3){
// 响应时间快
$query->orderBy('avg_response_time','desc');
$query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"),'asc');// 名称排名
}elseif ($sort_order == 4){
// 响应时间快
$query->orderBy('avg_response_time','desc');
$query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"),'asc');// 名称排名
}elseif ($sort_order == 5){
// 服务数从多到少
$query->orderBy('served_patients_num','desc');
$query->orderBy(Db::raw("convert(substr(user_name,1,1) using `GBK`)"),'asc');// 名称排名
}
return $query;
})
->whereExists(function ($query) use($hospital_params){
$query->select(Db::raw(1))
->from('hospital')
->whereColumn('hospital.hospital_id','user_doctor.hospital_id')
->where($hospital_params);
})
->paginate($per_page, $fields, "page", $page);
$data = array();
$data['current_page'] = $result->currentPage();// 当前页码
$data['total'] = $result->total();//数据总数
$data['data'] = $result->items();//数据
$data['per_page'] = $result->perPage();//每页个数
$data['last_page'] = $result->lastPage();//最后一页
return $data;
}
}

View File

@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $doctor_info_id 主键
* @property int $doctor_id 医生id
* @property int $card_type 类型1:身份证 2:护照 3:港澳通行证 4:台胞证)
* @property string $card_name 证件姓名
* @property string $card_name_mask 证件姓名(掩码)
* @property string $card_num 证件号码
* @property string $card_num_mask 证件号码(掩码)
* @property string $license_cert 医师执业证(逗号分隔)
* @property string $qualification_cert 医师资格证(逗号分隔)
* @property string $qualification_cert_num 医师资格证号(逗号分隔)
* @property string $work_cert 医师工作证(逗号分隔)
* @property string $multi_point_images 多点执业备案信息(逗号分隔)
* @property string $sign_image 签名图片
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class UserDoctorInfo extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'user_doctor_info';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['doctor_info_id', 'doctor_id', 'card_type', 'card_name', 'card_name_mask', 'card_num', 'card_num_mask', 'license_cert', 'qualification_cert', 'qualification_cert_num', 'work_cert', 'multi_point_images', 'sign_image', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['doctor_info_id' => 'integer', 'doctor_id' => 'integer', 'card_type' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "doctor_info_id";
/**
* 获取-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 新增医生详情-批量
* @param array $data 新增数据
* @return \Hyperf\Database\Model\Model|UserDoctorInfo
*/
public static function addUserDoctorInfo(array $data): \Hyperf\Database\Model\Model|UserDoctorInfo
{
return self::create($data);
}
/**
* 修改医生详情
* @param array $params
* @param array $data
* @return int
*/
public static function editUserDoctorInfo(array $params = [], array $data = []): int
{
return self::where($params)->update($data);
}
}

79
app/Model/UserPatient.php Normal file
View File

@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $patient_id 主键id
* @property int $user_id 用户id
* @property string $user_name 用户名称
* @property string $open_id 微信open_id
* @property string $union_id 微信开放平台唯一标识
* @property string $wx_session_key 微信会话密钥
* @property int $status 状态0:禁用 1:正常 2:删除)
* @property int $idcard_status 实名认证状态0:未认证 1:认证通过 2:认证失败)
* @property string $mobile 手机号
* @property int $sex 性别0:未知 1: 2:女)
* @property int $age 年龄
* @property string $avatar 头像
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class UserPatient extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'user_patient';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['patient_id', 'user_id', 'user_name', 'open_id', 'union_id', 'wx_session_key', 'status', 'idcard_status', 'mobile', 'sex', 'age', 'avatar', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['patient_id' => 'integer', 'user_id' => 'integer', 'status' => 'integer', 'idcard_status' => 'integer', 'sex' => 'integer', 'age' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "patient_id";
/**
* 获取患者信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 新增患者-批量
* @param array $data 新增数据
* @return UserPatient|\Hyperf\Database\Model\Model
*/
public static function addUserPatient(array $data): UserPatient|\Hyperf\Database\Model\Model
{
return self::create($data);
}
/**
* 修改患者-批量
* @param array $params
* @param array $data
* @return int
*/
public static function editUserPatient(array $params = [], array $data = []) : int
{
return self::where($params)->update($data);
}
}

View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $pharmacist_id 主键id
* @property int $user_id 用户id
* @property string $user_name 用户名称
* @property string $open_id 微信open_id
* @property string $union_id 微信开放平台唯一标识
* @property string $wx_session_key 微信会话密钥
* @property int $status 状态0:禁用 1:正常 2:删除)
* @property string $mobile 电话
* @property int $sex 性别0:未知 1: 2:女)
* @property int $age 年龄
* @property string $avatar 头像
* @property int $is_online 是否在线0:不在线 1:在线)
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class UserPharmacist extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'user_pharmacist';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['pharmacist_id', 'user_id', 'user_name', 'open_id', 'union_id', 'wx_session_key', 'status', 'mobile', 'sex', 'age', 'avatar', 'is_online', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['pharmacist_id' => 'integer', 'user_id' => 'integer', 'status' => 'integer', 'sex' => 'integer', 'age' => 'integer', 'is_online' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected string $primaryKey = "pharmacist_id";
/**
* 获取药师信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 修改药师-批量
* @param array $params
* @param array $data
* @return int
*/
public static function editUserPharmacist(array $params = [], array $data = []) : int
{
return self::where($params)->update($data);
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Process;
use Hyperf\AsyncQueue\Process\ConsumerProcess;
use Hyperf\Process\Annotation\Process;
#[Process]
class AsyncQueueConsumer extends ConsumerProcess
{
}

View File

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class AreaRequest extends FormRequest
{
protected array $scenes = [
'getCity' => ['area_id'],
'getCounty' => ['area_id'],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'area_id' => 'required',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'area_id.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class BasicDataRequest extends FormRequest
{
protected array $scenes = [
'getHospital' => [ // 获取医院数据
'province_id',
'city_id',
'county_id',
],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'province_id' => 'required_with:city_id,county_id',
'city_id' => 'required_with:county_id',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'province_id.required_with' => "请选择省份",
'city_id.required_with' => "请选择城市",
];
}
}

View File

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class CodeRequest extends FormRequest
{
protected array $scenes = [
'getPhoneCode' => ['phone','scene'],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'phone' => ['required','regex:/0?(13|14|15|17|18|19)[0-9]{9}/'],
'scene' => 'required|integer|min:1|max:1',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'phone.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'phone.regex' => HttpEnumCode::getMessage(HttpEnumCode::MOBILE_FORMAT_ERROR),
'user_type.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'scene.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class DiseaseRequest extends FormRequest
{
protected array $scenes = [
'getDiseaseSearch' => [ // 搜索疾病分类
'disease_class_name',
]
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'disease_class_name' => 'required',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'disease_class_name.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class DoctorAuthRequest extends FormRequest
{
protected array $scenes = [
'addAuthReal' => [ // 新增实名认证
'card_name',
'card_num'
],
'addAuthIden' => [ // 新增身份认证信息
'avatar',
'hospital_id',
'department_custom_id',
'department_custom_name',
'department_custom_mobile',
'doctor_title',
'brief_introduction',
'be_good_at',
'license_cert',
'qualification_cert',
'work_cert',
'doctor_expertise',
],
'addAuthMulti' => [ // 新增多点执业认证信息
'id_card_front',
'id_card_back',
'sign_image'
],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'card_name' => 'required',
'card_num' => 'required',
'avatar' => 'required|url',
'hospital_id' => 'required',
'department_custom_id' => 'required',
'department_custom_mobile' => 'required',
'doctor_title' => 'required|min:1|max:4',
'brief_introduction' => 'required',
'be_good_at' => 'required',
'license_cert' => 'required|array|min:1',
'qualification_cert' => 'required|array|min:1',
'work_cert' => 'required|array|min:1',
'doctor_expertise' => 'required|array|min:1',
'id_card_front' => 'required|url',
'id_card_back' => 'required|url',
'sign_image' => 'required|url',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'card_name.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'card_num.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'avatar.required' => "请上传头像",
'avatar.url' => "头像错误",
'hospital_id.required' => "请选择医院",
'department_custom_id.required' => "请选择科室",
'department_custom_mobile.required' => "请输入科室电话",
'doctor_title.required' => "请选择职称",
'doctor_title.min' => "职称错误",
'doctor_title.max' => "职称错误",
'brief_introduction.required' => "请填写个人简介",
'be_good_at.required' => "请填写擅长领域",
'license_cert.required' => "请上传医师执业证",
'license_cert.array' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'qualification_cert.required' => "请上传医师资格证",
'qualification_cert.array' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'work_cert.required' => "请上传职称证",
'work_cert.array' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'doctor_expertise.required' => "请选择专长",
'doctor_expertise.array' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'id_card_front.required' => "请上传身份证正面",
'id_card_front.url' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'id_card_back.required' => "请上传身份证反面",
'id_card_back.url' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'sign_image.required' => "请上传签名",
'sign_image.url' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class LoginRequest extends FormRequest
{
protected array $scenes = [
'wechatMobileLogin' => ['phone_code','wx_code','user_type'],
'mobileLogin' => ['code','phone','user_type'],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'phone_code' => 'required',
'wx_code' => 'required',
'user_type' => 'required|integer|min:1|max:3',
'code' => 'required',
'phone' => ['required','regex:/0?(13|14|15|17|18|19)[0-9]{9}/'],
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'phone_code.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'wx_code.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.integer' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'code.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'phone.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'phone.regex' => HttpEnumCode::getMessage(HttpEnumCode::MOBILE_FORMAT_ERROR),
];
}
}

View File

@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class OrderInquiryRequest extends FormRequest
{
protected array $scenes = [
'addInquiryOrder' => [
'patient_id',
'family_id',
'disease_class_id',
'diagnosis_date',
'disease_desc',
'is_allergy_history',// 过敏史
'allergy_history',
'is_family_history', // 家族病史
'family_history',
'is_pregnant',// 备孕、妊娠、哺乳期
'pregnant',
'product.product_ids', // 商品id
'product.product_num', // 药品数量
'height',
'weight',
'inquiry_type', // 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
'inquiry_mode', // 订单问诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'patient_id' => 'required',
'family_id' => 'required',
'disease_class_id' => 'required',
'diagnosis_date' => 'date',
'disease_desc' => 'required',
'is_allergy_history' => ['sometimes','numeric','min:0','max:1'],
'is_family_history' => ['sometimes','numeric','min:0','max:1'],
'is_pregnant' => ['sometimes','numeric','min:0','max:1'],
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'patient_id.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'family_id.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'disease_class_id.required' => "请您选择疾病",
'diagnosis_date.date' => HttpEnumCode::getMessage(HttpEnumCode::DATE_FORMAT_ERROR),
'disease_desc.required' => "请您输入病情主诉",
'is_allergy_history.numeric' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_allergy_history.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_allergy_history.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_family_history.numeric' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_family_history.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_family_history.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_pregnant.numeric' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_pregnant.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_pregnant.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class PatientDoctorRequest extends FormRequest
{
protected array $scenes = [
'getInquiryDoctorList' => ['expertise_id','province_id','city_id','sort_order','keyword'],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'sort_order' => 'sometimes|integer|min:1|max:5',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'sort_order.integer' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'sort_order.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'sort_order.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Validation\Request\FormRequest;
use Hyperf\Validation\Rule;
class PatientFamilyRequest extends FormRequest
{
/**
* @Inject
* @var ValidatorFactoryInterface
*/
protected ValidatorFactoryInterface $validationFactory;
protected array $scenes = [
'addFamily' => [ // 新增家庭成员
'relation',
'is_default',
'card_name',
'mobile',
'type',
'id_number',
'province_id',
'city_id',
'county_id',
'height',
'weight',
'marital_status',
]
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'card_name' => 'required',
'type' => ['required',Rule::in(['1', '2', '3', '4'])],
'id_number' => "required",
'mobile' => ['required','regex:/^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/'],
'relation' => ['required',Rule::in(['1', '2', '3', '4', '5', '6'])],
'city_id' => 'required_with:province_id',
'province_id' => 'required_with:city_id,county_id',
'is_default' => ['sometimes',Rule::in(['0', '1'])],
'height' => ['sometimes','numeric'], // 身高
'weight' => ['sometimes','numeric'], // 体重
'marital_status' => ['sometimes',Rule::in(['0', '1'])], // 婚姻状况(0:未婚 1:已婚)
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'name.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'type.required' => "请选择证件类型",
'type.in' => "证件类型错误",
'id_number.required' => "请选择证件号",
'mobile.required' => "手机号不能为空",
'mobile.regex' => "手机号格式错误",
'relation.required' => "请选择患者关系",
'relation.in' => "患者关系错误",
'city_id.required_with' => "请选择城市",
'province_id.required_with' => "请选择省份",
'is_default.in' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'height.numeric' => "身高错误",
'weight.numeric' => "体重错误",
'blood_type.in' => "血型错误",
'marital_status.in' => "婚姻状况错误",
];
}
}

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class SafeRequest extends FormRequest
{
protected array $scenes = [
'getOssSign' => ['user_type'],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'user_type' => 'required|integer|min:1|max:3',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'user_type.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.integer' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
use Hyperf\Validation\Rule;
class UserDoctorRequest extends FormRequest
{
protected array $scenes = [
'getInquiryConfig' => [ // 获取医生问诊配置
'inquiry_type',
'inquiry_mode',
],
'putInquiryOpen' => [ // 医生问诊开关
'inquiry_type',
'inquiry_mode',
'is_open',
],
'putInquiryConfig' => [ // 修改医生问诊配置
'inquiry_type',
'inquiry_mode',
'inquiry_price',
'work_num_day',
],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'inquiry_type' => 'required|integer|min:1|max:3',
'inquiry_mode' => 'required|integer|min:1|max:5',
'is_open' => "required|boolean",
'inquiry_price' => "required|min:0|numeric",
'work_num_day' => "required|min:0|numeric",
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'inquiry_type.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'inquiry_type.integer' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'inquiry_type.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'inquiry_type.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_open.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'is_open.boolean' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'inquiry_price.required' => "请填写价格",
'inquiry_price.min' => "价格填写错误",
'inquiry_price.numeric' => "价格填写错误",
'inquiry_mode.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'inquiry_mode.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'inquiry_mode.numeric' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'work_num_day.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'work_num_day.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'work_num_day.numeric' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace App\Request;
use App\Constants\HttpEnumCode;
use Hyperf\Validation\Request\FormRequest;
class UserRequest extends FormRequest
{
protected array $scenes = [
'wechatMobileLogin' => ['phone_code','wx_code','user_type'],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'phone_code' => 'required',
'wx_code' => 'required',
'user_type' => 'required|integer|min:1|max:3',
];
}
/**
* 获取已定义验证规则的错误消息.
*/
public function messages(): array
{
return [
'phone_code.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'wx_code.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.required' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.integer' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.min' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
'user_type.max' => HttpEnumCode::getMessage(HttpEnumCode::CLIENT_HTTP_ERROR),
];
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace App\Services;
use App\Model\Area as AreaModel;
class AreaService extends BaseService
{
/**
* 检测省市区省市区
* @param string $province_id
* @param string $city_id
* @param string $county_id
* @return bool
*/
public function checkAreaById(string $province_id, string $city_id, string $county_id): bool
{
// 检测省份
if (!empty($province_id)){
$province = $this->getAreaByAreaId($province_id);
if (empty($province['data'])){
return false;
}
}
// 检测城市
if (!empty($city_id) && !empty($province_id)){
$city = $this->getAreaByAreaId($city_id,$province_id);
if (empty($city['data'])){
return false;
}
}
// 检测区县
if (!empty($county_id) && !empty($city_id)){
$county = $this->getAreaByAreaId($county_id,$city_id);
if (empty($county['data'])){
return false;
}
}
if (!empty($province['data']) || !empty($city['data']) || !empty($county['data'])){
return true;
}
return false;
}
/**
* 获取省份列表
* @return array
*/
public function getProvince(): array
{
$params = array();
$params['parent_id'] = 1;
$params['area_type'] = 2;
$province = AreaModel::getList($params);
return empty($province) ? success() : success($province->toArray());
}
/**
* 获取城市列表
* @return array
*/
public function getCity(): array
{
$area_id = $this->request->input('area_id');
return $this->getAreaByParentId($area_id);
}
/**
* 获取区县信息
* @return array
*/
public function getCounty(): array
{
$area_id = $this->request->input('area_id');
return $this->getAreaByParentId($area_id);
}
/**
* 查询省市区-地区id
* @param string $area_id
* @param string $parent_id
* @return array
*/
protected function getAreaByAreaId(string $area_id, string $parent_id = ""): array
{
$params = array();
$params['area_id'] = $area_id;
if (!empty($parent_id)){
$params['parent_id'] = $parent_id;
}
$area = AreaModel::getOne($params);
return empty($area) ? success() : success($area->toArray());
}
/**
* 查询省市区-父级id
* @param string $parent_id
* @return array
*/
protected function getAreaByParentId(string $parent_id = ""): array
{
$params = array();
$params['parent_id'] = $parent_id;
$area = AreaModel::getList($params);
return empty($area) ? success() : success($area->toArray());
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Services;
use App\Constants\HttpEnumCode;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Psr\Container\ContainerInterface;
use Hyperf\Di\Annotation\Inject;
class BaseService
{
#[Inject]
protected ContainerInterface $container;
#[Inject]
protected RequestInterface $request;
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Services;
use App\Model\Hospital;
use App\Model\HospitalDepartmentCustom;
/**
* 基础数据服务类
*/
class BasicDataService extends BaseService
{
/**
* 获取医院数据
* @return array
*/
public function getHospital(): array
{
$hospital_name = $this->request->input('hospital_name');
$province_id = $this->request->input('province_id');
$city_id = $this->request->input('city_id');
$county_id = $this->request->input('county_id');
$params = array();
$params[] = ['hospital_status', '=', 1];
if (!empty($hospital_name)) {
$params[] = ['hospital_name', 'like', '%' . $hospital_name . '%'];
}
if (!empty($province_id)) {
$params[] = ['province_id', '=', $province_id];
}
if (!empty($city_id)) {
$params[] = ['city_id', '=', $city_id];
}
if (!empty($county_id)) {
$params[] = ['county_id', '=', $county_id];
}
$fields = [
'hospital_id',
'hospital_name',
];
$hospital = Hospital::getList($params,$fields);
if (empty($hospital)){
return success();
}
return success($hospital->toArray());
}
/**
* 获取自定义科室数据
* @return array
*/
public function getCustomDepartment(): array
{
$params = array();
$params['department_status'] = 1;
$fields = [
'department_custom_id',
'department_custom_name',
];
$hospital_department_custom = HospitalDepartmentCustom::getList($params,$fields);
if (empty($hospital_department_custom)){
return success();
}
return success($hospital_department_custom->toArray());
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace App\Services;
use App\Constants\HttpEnumCode;
use Extend\Alibaba\Dysms;
use Hyperf\Redis\Redis;
use Hyperf\Snowflake\IdGeneratorInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
/**
* 验证码
*/
class CodeService extends BaseService
{
/**
* 获取登陆验证码
* 5分钟内同一手机号请求三次
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getLoginPhoneCode(): array
{
$phone = $this->request->input('phone');
$redis = $this->container->get(Redis::class);
$redis_key = "login_code_count" . $phone;
$result = $redis->get($redis_key);
if (!empty($result)){
if ( $result > 3){
// 超出规定时间内最大获取次数
return fail(HttpEnumCode::PHONE_MAXIMUM);
}
}
$generator = $this->container->get(IdGeneratorInterface::class);
$template_code = "SMS_243055263";
$template_param = array();
$template_param['code'] = (int)substr($generator->generate(),-4);
// 发送短信
Dysms::sendSms($phone,$template_param,$template_code,1);
if (empty($result)){
$redis_value = 1;
}else{
$redis_value = $result + 1;
}
$res = $redis->set($redis_key,$redis_value,60*5);
if (!$res){
return fail(HttpEnumCode::SERVER_ERROR);
}
// 设置有效期
$res = $redis->set("login_code" . $phone,$template_param['code'],60*30);
if (!$res){
return fail(HttpEnumCode::SERVER_ERROR);
}
return success();
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace App\Services;
use App\Model\Coupon;
use App\Model\UserCoupon;
/**
* 优惠卷
*/
class CouponService extends BaseService
{
/**
* 获取用户可用优惠卷
* @param string|int $user_id 用户id
* @param string|int $inquiry_type 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @param int $coupon_client 使用平台1:小程序)
* @return array
*/
public function getUserUsableCoupon(string|int $user_id,string|int $inquiry_type,int $coupon_client = 1): array
{
// 问诊类型需加1
$inquiry_type = $inquiry_type + 1;
$params = array();
$params[] = ['user_id','=',$user_id];
$params[] = ['user_coupon_status','=',0];// 状态0:未使用 1:已使用 3:已过期)
$params[] = ['valid_start_time','>',date('Y-m-d H:i:s',time())]; // 有效使用时间
$params[] = ['valid_end_time','<',date('Y-m-d H:i:s',time())]; // 过期使用时间
$coupon_params = array();
$coupon_params[] = ['coupon_client','=',$coupon_client];
$coupon_params[] = ['coupon_status','=',1]; // 状态1:正常 2:强制失效 3:结束 4:删除)
$coupon_params[] = ['application_scope','in',[1,$inquiry_type]]; // 适用范围1:全部 2:快速问诊 3:专家问诊 4:公益问诊 5:问诊购药)
$user_coupon = UserCoupon::getWithCouponList($params,$coupon_params);
if (empty($user_coupon)){
return array();
}
return $user_coupon->toArray();
}
/**
* 发放用户优惠卷
* @param int $distribution_object 发放对象1:新注册用户 2:会员 3:近期消费 4:近期购药)
* @param string $user_id
* @param string $patient_id
* @param int $coupon_client 使用平台1:小程序)
* @return bool
*/
public function DistributeCoupon(int $distribution_object,string $user_id,string $patient_id,int $coupon_client = 1): bool
{
$params = array();
$params['coupon_client'] = $coupon_client;
$params['coupon_status'] = 1;
$params['distribution_object'] = $distribution_object; // 发放对象1:新注册用户 2:会员 3:近期消费 4:近期购药)
$coupon = Coupon::getList($params);
if (empty($coupon)){
return true;
}
foreach ($coupon as $key => $value){
// 判断发放数量
if ($value['coupon_count'] == $value['coupon_take_count']){
continue;
}
// 进行发放
$data = array();
$data['user_id'] = $user_id;
$data['patient_id'] = $patient_id;
$data['coupon_id'] = $value['coupon_id'];
if ($value['valid_type'] == 1){
// 有效类型1:绝对时效xxx-xxx时间段有效 2:相对时效 n天内有效
$data['valid_start_time'] = $value['valid_start_time']; // 有效使用时间
$data['valid_end_time'] = $value['valid_end_time']; // 过期使用时间
}elseif ($value['valid_type'] == 2){
// 有效类型1:绝对时效xxx-xxx时间段有效 2:相对时效 n天内有效
$data['valid_start_time'] = date('Y-m-d H:i:s',time()); // 有效使用时间
$data['valid_end_time'] = date("Y-m-d H:i:s",strtotime($value['valid_days'] . " day"));
}else{
return false;
}
$res = UserCoupon::addUserCoupon($data);
if (empty($res)){
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace App\Services;
use App\Model\DiseaseClass;
use App\Model\DiseaseClassExpertise;
use App\Request\DiseaseRequest;
use App\Request\PatientFamilyRequest;
class DiseaseService extends BaseService
{
/**
* 专长列表
* @return array
*/
public function getDiseaseExpertiseList(): array
{
$disease_class_expertise = DiseaseClassExpertise::getOrderList();
return success($disease_class_expertise);
}
/**
* 搜索疾病分类
* @return array
*/
public function getDiseaseSearch(): array
{
$disease_class_name = $this->request->input('disease_class_name');
$params = array();
$params[] = ["disease_class_status",1];
$params[] = ["disease_class_enable",1];
$params[] = ['disease_class_name', 'like', '%' . $disease_class_name . '%'];
$disease_class = DiseaseClass::getList($params);
return empty($disease_class) ? success() : success($disease_class->toArray()) ;
}
/**
* 获取常见疾病分类
* @return array
*/
public function getDiseaseHot(): array
{
$params = array();
$params[] = ["disease_class_status",1];
$params[] = ["disease_class_enable",1];
$params[] = ['is_hot', 1];
$disease_class = DiseaseClass::getLimit($params,10);
return empty($disease_class) ? success() : success($disease_class->toArray()) ;
}
}

View File

@ -0,0 +1,646 @@
<?php
namespace App\Services;
use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Model\DoctorExpertise;
use App\Model\Hospital;
use App\Model\HospitalDepartmentCustom;
use App\Model\UserDoctor;
use App\Model\UserDoctorInfo;
use App\Utils\Mask;
use App\Utils\PcreMatch;
use Extend\VerifyDun\IdCard;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\DbConnection\Db;
/**
* 医生认证
*/
class DoctorAuthService extends BaseService
{
/**
* 获取实名认证信息
* @return array
*/
public function getAuthReal(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
// 获取医生数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
// 实名认证状态0:未认证 1:认证通过 2:认证失败)
if ($doctor['idcard_status'] == 0) {
return success();
}
// 获取医生详情数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$params['card_type'] = 1;
$fields = [
'doctor_info_id',
'doctor_id',
'card_type',
'card_name',
'card_name_mask',
'card_num',
'card_num_mask',
];
$user_doctor_info = UserDoctorInfo::getOne($params, $fields);
if (empty($user_doctor_info)) {
return success();
}
return success($user_doctor_info->toArray());
}
/**
* 新增实名认证
* @return array
* @throws GuzzleException
*/
public function addAuthReal(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$card_name = $this->request->input('card_name');
$card_num = $this->request->input('card_num');
// 身份证验证
$card_num = PcreMatch::pregIdCard($card_num);
if (empty($card_num)) {
return fail();
}
// 身份证最后一位x转换为大写
$card_num = PcreMatch::pregIdCardX($card_num);
if (empty($card_num)) {
return fail();
}
// 身份证掩码
$card_num_mask = Mask::maskIdCard($card_num);
// 姓名掩码
$card_name_mask = Mask::maskNameStr($card_name);
// 获取医生数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
// 实名认证状态0:未认证 1:认证通过 2:认证失败)
if ($doctor['idcard_status'] == 1) {
return fail(HttpEnumCode::HTTP_ERROR, "不可修改");
}
// 网易易盾认证
// 实人认证-生产环境开启
if (env("APP_ENV") == "prod") {
$IdCard = new IdCard();
$params = array();
$params['name'] = $card_name;
$params['cardNo'] = $card_num;
$res = $IdCard->checkIdCard($params);
if (!empty($res)) {
return fail(HttpEnumCode::HTTP_ERROR, $res);
}
}
Db::beginTransaction();
try {
// 获取医生详情数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$user_doctor_info = UserDoctorInfo::getOne($params);
if (empty($user_doctor_info)) {
// 新增医生详情
$data = array();
$data['doctor_id'] = $user_info['client_user_id'];
$data['card_type'] = 1;
$data['card_name'] = $card_name;
$data['card_name_mask'] = $card_name_mask;
$data['card_num'] = $card_num;
$data['card_num_mask'] = $card_num_mask;
$user_doctor_info = UserDoctorInfo::addUserDoctorInfo($data);
if (empty($user_doctor_info)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 修改医生实名认证状态
$data = array();
$data['idcard_status'] = 1;
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$res = UserDoctor::editUserDoctor($params, $data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
} else {
if (!empty($user_doctor_info['card_name']) || !empty($user_doctor_info['card_num'])) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "不可修改");
}
// 已存在详情表数据,进行添加
$data = array();
$data['card_type'] = 1;
$data['card_name'] = $card_name;
$data['card_name_mask'] = $card_name_mask;
$data['card_num'] = $card_num;
$data['card_num_mask'] = $card_num_mask;
$data['updated_at'] = date('Y-m-d H:i:s', time());
$params = array();
$params['doctor_info_id'] = $user_doctor_info['doctor_info_id'];
$res = UserDoctorInfo::editUserDoctorInfo($params, $data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 修改医生实名认证状态
$data = array();
$data['idcard_status'] = 1;
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$res = UserDoctor::editUserDoctor($params, $data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
}
return success();
}
/**
* 获取身份认证信息
* @return array
*/
public function getAuthIden(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
// 获取医生数据
$fields = [
'doctor_id',
'user_id',
'idcard_status',
'iden_auth_status',
'iden_auth_fail_reason',
'avatar',
'hospital_id',
'department_custom_id',
'department_custom_name',
'department_custom_mobile',
'doctor_title',
'brief_introduction',
'be_good_at',
];
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params, $fields);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
// 实名认证状态0:未认证 1:认证通过 2:认证失败)
if ($doctor['idcard_status'] != 1) {
return fail(HttpEnumCode::HTTP_ERROR, "请先实名认证");
}
$result = $doctor->toArray();
// 头像
if (!empty($doctor['avatar'])){
$result['avatar'] = addAliyunOssWebsite($doctor['avatar']);
}
// 职称转换
$result['doctor_title_name'] = empty($doctor['doctor_title']) ? "" : DoctorTitleCode::getMessage($doctor['doctor_title']);
// 获取医生详情数据
$result['license_cert'] = [];
$result['qualification_cert'] = [];
$result['work_cert'] = [];
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$user_doctor_info = UserDoctorInfo::getOne($params);
if (!empty($user_doctor_info)) {
// 医师执业证
if (!empty($user_doctor_info['license_cert'])) {
$license_cert = explode(',', $user_doctor_info['license_cert']);
foreach ($license_cert as &$item){
$item = addAliyunOssWebsite($item);
}
$result['license_cert'] = $license_cert;
}
// 医师职称证
if (!empty($user_doctor_info['qualification_cert'])) {
$qualification_cert = explode(',', $user_doctor_info['qualification_cert']);
foreach ($qualification_cert as &$item){
$item = addAliyunOssWebsite($item);
}
$result['qualification_cert'] = $qualification_cert;
}
// 医师资格证
if (!empty($user_doctor_info['work_cert'])) {
$work_cert = explode(',', $user_doctor_info['work_cert']);
foreach ($work_cert as &$item){
$item = addAliyunOssWebsite($item);
}
$result['work_cert'] = $work_cert;
}
}
// 获取医生医院
$result['hospital'] = [];
$fields = [
'hospital_id',
'hospital_name',
'hospital_level_name',
];
$params = array();
$params['hospital_id'] = $doctor['hospital_id'];
$hospital = Hospital::getOne($params, $fields);
if (!empty($hospital)) {
$result['hospital'] = $hospital;
}
// 获取医生已选择专长
$UserDoctorService = new UserDoctorService();
$result['doctor_expertise'] = $UserDoctorService->getDoctorSelectedExpertise($doctor['doctor_id']);
return success($result);
}
/**
* 新增身份认证信息
* @return array
*/
public function addAuthIden(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$request_params = $this->request->all();
// 获取医生数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
// 实名认证状态0:未认证 1:认证通过 2:认证失败)
if ($doctor['idcard_status'] != 1) {
return fail(HttpEnumCode::HTTP_ERROR, "请先实名认证");
}
// 审核中
if ($doctor['iden_auth_status'] == 2) {
return fail(HttpEnumCode::HTTP_ERROR, "审核中,暂不允许修改");
}
// 组合存储数据
$doctor_data = array();// 医生
$doctor_info_data = array();// 医生详情
// 头像
$request_params['avatar'] = PcreMatch::pregRemoveOssWebsite($request_params['avatar']);
if ($doctor['avatar'] != $request_params['avatar']) {
$doctor_data['avatar'] = $request_params['avatar'];
}
// 职称
if ($doctor['doctor_title'] != $request_params['doctor_title']) {
$doctor_data['doctor_title'] = $request_params['doctor_title'];
}
// 医院
if ($doctor['hospital_id'] != $request_params['hospital_id']) {
$params = array();
$params['hospital_id'] = $request_params['hospital_id'];
$hospital = Hospital::getOne($params);
if (!empty($hospital)) {
return fail(HttpEnumCode::HTTP_ERROR, "医院选择错误");
}
$doctor_data['hospital_id'] = $request_params['hospital_id'];
}
// 科室
if ($doctor['department_custom_id'] != $request_params['department_custom_id']) {
$params = array();
$params['department_custom_id'] = $request_params['department_custom_id'];
$hospital_department_custom = HospitalDepartmentCustom::getOne($params);
if (empty($hospital_department_custom)) {
return fail(HttpEnumCode::HTTP_ERROR, "科室选择错误");
}
$doctor_data['department_custom_id'] = $request_params['department_custom_id'];
$doctor_data['department_custom_name'] = $hospital_department_custom['department_custom_name'];
if (!empty($request_params['department_custom_name'])) {
$doctor_data['department_custom_name'] = $request_params['department_custom_name'];
}
}
// 未认证-认证失败
if ($doctor['iden_auth_status'] == 0 || $doctor['iden_auth_status'] == 3) {
// 获取医生详情数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$user_doctor_info = UserDoctorInfo::getOne($params);
if (empty($user_doctor_info)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
// 执业证
$license_cert = implode(',', $request_params['license_cert']);
$license_cert = PcreMatch::pregRemoveOssWebsite($license_cert);
if ($user_doctor_info['license_cert'] != $license_cert) {
$doctor_info_data['license_cert'] = $license_cert;
}
// 医师资格证
$qualification_cert = implode(',', $request_params['qualification_cert']);
$qualification_cert = PcreMatch::pregRemoveOssWebsite($qualification_cert);
if ($user_doctor_info['qualification_cert'] != $qualification_cert) {
$doctor_info_data['qualification_cert'] = $qualification_cert;
}
// 医师工作证
$work_cert = implode(',', $request_params['work_cert']);
$work_cert = PcreMatch::pregRemoveOssWebsite($work_cert);
if ($user_doctor_info['work_cert'] != $work_cert) {
$doctor_info_data['work_cert'] = $work_cert;
}
}
//已选择专长列表
$expertise_ids = [];
// 获取医生专长
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor_expertise = DoctorExpertise::getList($params);
if (!empty($doctor_expertise)) {
$expertise_ids = array_column($doctor_expertise->toArray(),'expertise_id');
}
// 对比已选择专长
// 对比专长是否删除
$is_delete_expertise = array_diff($request_params['doctor_expertise'],$expertise_ids);
if (empty($is_delete_expertise)){
// 对比专长是否新增
$is_add_expertise = array_diff($expertise_ids,$request_params['doctor_expertise']) ;
}
// 专长是否改动false未改动 true已改动
$expertise_is_change = false;
if (!empty($is_delete_expertise) || !empty($is_add_expertise)){
$expertise_is_change = true;
}
Db::beginTransaction();
try {
// 专长有改动
if ($expertise_is_change){
// 删除原专长
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
DoctorExpertise::deleteDoctorExpertise($params);
// 新增专长
foreach ($request_params['doctor_expertise'] as $item) {
$data = array();
$data['doctor_id'] = $user_info['client_user_id'];
$data['expertise_id'] = $item;
$doctor_expertise = DoctorExpertise::addDoctorExpertise($data);
if (empty($doctor_expertise)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
}
// 医生数据
if (!empty($doctor_data)) {
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor_data['updated_at'] = date('Y-m-d H:i:s', time());
$res = UserDoctor::editUserDoctor($params, $doctor_data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
// 医生详情数据
if (!empty($doctor_info_data)) {
// 修改医生详情数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor_info_data['updated_at'] = date('Y-m-d H:i:s', time());
$res = UserDoctorInfo::editUserDoctorInfo($params, $doctor_info_data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
// 修改审核状态
if (!empty($doctor_data) || !empty($doctor_info_data) || $expertise_is_change){
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$data = array();
$data['iden_auth_status'] = 2;// 身份认证状态-审核中
$data['iden_auth_fail_reason'] = "";// 身份认证失败原因
$data['updated_at'] = date('Y-m-d H:i:s', time());
$res = UserDoctor::editUserDoctor($params, $data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
}
return success();
}
/**
* 获取多点执业认证信息
* @return array
*/
public function getAuthMulti(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
// 获取医生数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
// 获取医生详情数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$user_doctor_info = UserDoctorInfo::getOne($params);
if (empty($user_doctor_info)){
return success();
}
$result = array();
$result['id_card_front'] = addAliyunOssWebsite($user_doctor_info['id_card_front']);
$result['id_card_back'] = addAliyunOssWebsite($user_doctor_info['id_card_back']);
$result['sign_image'] = addAliyunOssWebsite($user_doctor_info['sign_image']);
$result['multi_point_status'] = $doctor['multi_point_status']; // 医生多点执业认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
$result['multi_point_fail_reason'] = $doctor['multi_point_fail_reason']; // 多点执业认证失败原因
return success($result);
}
/**
* 新增多点执业认证信息
* @return array
*/
public function addAuthMulti(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$id_card_front = $this->request->input('id_card_front');
$id_card_back = $this->request->input('id_card_back');
$sign_image = $this->request->input('sign_image');
// 获取医生数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行实名认证");
}
if ($doctor['iden_auth_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行身份认证");
}
// 审核中
if ($doctor['multi_point_status'] == 2){
return fail(HttpEnumCode::HTTP_ERROR, "审核中,暂不允许修改");
}
// 获取医生详情数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$user_doctor_info = UserDoctorInfo::getOne($params);
if (empty($user_doctor_info)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
$doctor_info_data = array();
// 身份证正面
$id_card_front = PcreMatch::pregRemoveOssWebsite($id_card_front);
if ($id_card_front != $user_doctor_info['id_card_front']){
$doctor_info_data['id_card_front'] = $id_card_front;
}
// 身份证反面
$id_card_back = PcreMatch::pregRemoveOssWebsite($id_card_back);
if ($id_card_back != $user_doctor_info['id_card_back']){
$doctor_info_data['id_card_back'] = $id_card_back;
}
// 签名
$sign_image = PcreMatch::pregRemoveOssWebsite($sign_image);
if ($sign_image != $user_doctor_info['sign_image']){
$doctor_info_data['sign_image'] = $sign_image;
}
if (empty($doctor_info_data)){
return success();
}
Db::beginTransaction();
try {
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$res = UserDoctorInfo::editUserDoctorInfo($params, $doctor_info_data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 修改审核状态
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$data = array();
$data['multi_point_status'] = 2;// 医生多点执业认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
$data['multi_point_fail_reason'] = "";// 多点执业认证失败原因
$data['updated_at'] = date('Y-m-d H:i:s', time());
$res = UserDoctor::editUserDoctor($params, $data);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
}
return success();
}
}

View File

@ -0,0 +1,335 @@
<?php
namespace App\Services;
use App\Constants\HttpEnumCode;
use App\Model\DoctorInquiryConfig;
use App\Model\DoctorInquiryPriceRecord;
use App\Model\SystemInquiryConfig;
use App\Model\UserDoctor;
use Hyperf\DbConnection\Db;
/**
* 医生问诊
*/
class DoctorInquiryService extends BaseService
{
/**
* 获取医生问诊配置
* @return array
*/
public function getInquiryConfig(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$inquiry_type = $this->request->input('inquiry_type');// 接诊类型1:专家问诊 2:快速问诊 3:公益问诊)
$inquiry_mode = $this->request->input('inquiry_mode');// 接诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
$result = array();
$result['info'] = array(); // 配置信息
$result['config'] = array(); // 系统配置
// 获取医生信息
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行实名认证");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行实名认证");
}
if ($doctor['iden_auth_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行身份认证");
}
// 接诊开关
$result['info']['is_open'] = 0;
if ($inquiry_type == 1){
// 专家
$result['info']['is_open'] = $doctor['is_img_expert_reception'];
}elseif ($inquiry_type == 2){
// 快速
$result['info']['is_open'] = $doctor['is_img_quick_reception'];
}elseif ($inquiry_type == 3){
// 公益
$result['info']['is_open'] = $doctor['is_img_welfare_reception'];
}
// 接诊价格
$result['info']['inquiry_price'] = 0;
// 接诊人数
$result['info']['work_num_day'] = 30;
// 系统问诊配置表
$params = array();
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = $inquiry_mode;
$system_inquiry_config = SystemInquiryConfig::getOne($params);
if (empty($system_inquiry_config)){
return fail(HttpEnumCode::SERVER_ERROR);
}
// 医生接诊配置表
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = $inquiry_mode;
$doctor_inquiry_config = DoctorInquiryConfig::getOne($params);
if (empty($doctor_inquiry_config)){
// 接诊价格
$result['info']['inquiry_price'] = $system_inquiry_config['inquiry_price'] ?: 0;
if ($inquiry_type == 3){
// 公益问诊,存在价格档次,默认第一档
$inquiry_price = explode(',',$system_inquiry_config['inquiry_price']);
$result['info']['inquiry_price'] = $inquiry_price[0];
}
}else{
// 接诊价格
$result['info']['inquiry_price'] = $doctor_inquiry_config['inquiry_price'] ?: 0;
if ($inquiry_type == 2){
// 快速-系统配置
$result['info']['inquiry_price'] = $system_inquiry_config['inquiry_price'];
}
$result['info']['work_num_day'] = $doctor_inquiry_config['work_num_day'] ?: 0;
}
// 每日最大接诊数量
$result['config']['max_work_num_day'] = $system_inquiry_config['max_work_num_day'];
// 最低接诊价格(专家问诊)
$result['config']['min_inquiry_price'] = $system_inquiry_config['min_inquiry_price'] ?: 0;
// 最高接诊价格(专家问诊)
$result['config']['max_inquiry_price'] = $system_inquiry_config['max_inquiry_price'] ?: 0;
// 默认价格
$result['config']['default_inquiry_price'] = $system_inquiry_config['max_inquiry_price'] ?: 0;
// 沟通次数0为不限制次数
$result['config']['times_number'] = $system_inquiry_config['times_number'];
// 沟通时长分钟0为不限制时长
$result['config']['duration'] = $system_inquiry_config['duration'];
return success($result);
}
/**
* 医生问诊开关
* @return array
*/
public function putInquiryOpen(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$inquiry_type = $this->request->input('inquiry_type');// 接诊类型1:专家问诊 2:快速问诊 3:公益问诊)
$inquiry_mode = $this->request->input('inquiry_mode');// 接诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
$is_open = $this->request->input('is_open');// 是否开启1:开启 0:关闭)
// 获取医生信息
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行实名认证");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行实名认证");
}
if ($doctor['iden_auth_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行身份认证");
}
// 医生接诊配置表
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = $inquiry_mode;
$doctor_inquiry_config = DoctorInquiryConfig::getOne($params);
if (empty($doctor_inquiry_config)){
if ($inquiry_type != 2){
// 快速问诊可能会存在未创建的情况
return fail(HttpEnumCode::HTTP_ERROR, "请先完善问诊配置");
}
}
Db::beginTransaction();
try {
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$data = array();
if ($inquiry_type == 1){
// 专家
$data['is_img_expert_reception'] = $is_open;
}elseif ($inquiry_type == 2){
// 快速
$data['is_img_quick_reception'] = $is_open;
}elseif ($inquiry_type == 3){
// 公益
$data['is_img_welfare_reception'] = $is_open;
}
UserDoctor::editUserDoctor($params,$data);
if ($inquiry_type == 2){
// 系统问诊配置表
$params = array();
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = $inquiry_mode;
$system_inquiry_config = SystemInquiryConfig::getOne($params);
if (empty($system_inquiry_config)){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 快速问诊,需创建
$data = array();
$data['doctor_id'] = $user_info['client_user_id'];
$data['system_inquiry_config_id'] = $system_inquiry_config['system_inquiry_config_id'];
$data['inquiry_type'] = $inquiry_type;
$data['inquiry_mode'] = $inquiry_mode;
$data['work_num_day'] = $system_inquiry_config['max_work_num_day'] ?: 0;
$data['inquiry_price'] = $system_inquiry_config['inquiry_price'];
$doctor_inquiry_config = DoctorInquiryConfig::addInquiryConfig($data);
if (empty($doctor_inquiry_config)){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
return success();
}
/**
* 修改医生问诊配置
* @return array
*/
public function putInquiryConfig(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$inquiry_type = $this->request->input('inquiry_type');// 接诊类型1:专家问诊 2:快速问诊 3:公益问诊)
$inquiry_mode = $this->request->input('inquiry_mode');// 接诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
$inquiry_price = $this->request->input('inquiry_price');// 接诊价格
$work_num_day = $this->request->input('work_num_day');// 每日接诊数量
if ($inquiry_type == 2){
// 快速问诊无需配置
return fail();
}
// 获取医生信息
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)) {
return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行实名认证");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行实名认证");
}
if ($doctor['iden_auth_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR, "请先进行身份认证");
}
// 系统问诊配置表
$params = array();
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = $inquiry_mode;
$system_inquiry_config = SystemInquiryConfig::getOne($params);
if (empty($system_inquiry_config)){
return fail(HttpEnumCode::SERVER_ERROR);
}
// 验证-每日接诊数量
if ($work_num_day > $system_inquiry_config['max_work_num_day']){
return fail(HttpEnumCode::HTTP_ERROR,"超出每日最大接诊数量");
}
// 验证-问诊价格
// 义诊时不判断,义诊为选择价格,价格后台可调节
if ($inquiry_type == 3){
if (!empty($system_inquiry_config['min_inquiry_price']) && !empty($system_inquiry_config['max_inquiry_price'])){
if ($inquiry_price > $system_inquiry_config['max_inquiry_price'] || $inquiry_price < $system_inquiry_config['min_inquiry_price']){
return fail(HttpEnumCode::HTTP_ERROR,"问诊价格填写错误");
}
}
}
// 开启事务锁
Db::beginTransaction();
try {
// 医生接诊配置表
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = $inquiry_mode;
$doctor_inquiry_config = DoctorInquiryConfig::getOne($params);
if (empty($doctor_inquiry_config)){
// 创建
$data = array();
$data['doctor_id'] = $user_info['client_user_id'];
$data['system_inquiry_config_id'] = $system_inquiry_config['system_inquiry_config_id'];
$data['inquiry_type'] = $inquiry_type;
$data['inquiry_mode'] = $inquiry_mode;
$data['work_num_day'] = $work_num_day;
$data['inquiry_price'] = $inquiry_price;
$doctor_inquiry_config = DoctorInquiryConfig::addInquiryConfig($data);
if (empty($doctor_inquiry_config)){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}else{
// 修改
if ($doctor_inquiry_config['work_num_day'] != $work_num_day || $doctor_inquiry_config['inquiry_price'] != $inquiry_price){
$params = array();
$params['inquiry_config_id'] = $doctor_inquiry_config['inquiry_config_id'];
$data = array();
$data['work_num_day'] = $work_num_day;
$data['inquiry_price'] = $inquiry_price;
DoctorInquiryConfig::editInquiryConfig($params,$data);
}
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
return success();
}
}

View File

@ -0,0 +1,325 @@
<?php
namespace App\Services;
use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Model\Banner as BannerModel;
use App\Model\DoctorInquiryConfig as DoctorInquiryConfigModel;
use App\Model\Module as ModuleModel;
use App\Model\PatientHistoryInquiry as PatientHistoryInquiryModel;
use App\Model\PharmacistAuditStatistic;
use App\Model\UserDoctor as UserDoctorModel;
use App\Model\UserPharmacist;
/**
* 首页模块
*/
class IndexService extends BaseService
{
/**
* 医生端-首页
* @return array
*/
public function getDoctorIndex(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
// 获取医生数据
$params = array();
$params['doctor_id'] = $user_info['client_user_id'];
$fields = [
"doctor_id",
"user_id",
"user_name",
"open_id",
"status",
"idcard_status",
"iden_auth_status",
"iden_auth_fail_reason",
"multi_point_status",
"is_bind_bank",
"mobile",
"avatar",
"praise_rate",
"avg_response_time",
"number_of_fans",
"is_online",
"is_img_expert_reception",
];
$doctor = UserDoctorModel::getOne($params, $fields);
if (empty($doctor)) {
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
if ($doctor['status'] == 0){
return fail(HttpEnumCode::USER_STATUS_DISABLE);
}
if ($doctor['status'] != 1){
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
$OrderInquiryService = new OrderInquiryService();
$OrderPrescriptionService = new OrderPrescriptionService();
// 获取未接诊患者个数
$not_accepted_inquiry_num = $OrderInquiryService->getDoctorNotAcceptedInquiryNum($doctor['doctor_id']);
// 获取接诊中患者个数
$accepting_inquiry_num = $OrderInquiryService->getDoctorAcceptingInquiryNum($doctor['doctor_id']);
// 获取被驳回处方数据
$reject_prescription_number = $OrderPrescriptionService->getDoctorExistsAuditFail($doctor['doctor_id']);
// 获取医生问诊价格
$params = array();
$params['doctor_id'] = $doctor['doctor_id'];
$params['inquiry_type'] = 1;// 接诊类型1:专家问诊 2:快速问诊 3:公益问诊)
$params['inquiry_mode'] = 1;// 接诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
$doctor_inquiry_config = DoctorInquiryConfigModel::getOne($params);
// 获取banner
$params = array();
$params["app_type"] = 1;
$params["client_type"] = 2;
$params["banner_place"] = 1;
$params["banner_status"] = 1;
$banner = BannerModel::getList($params);
$info = array();
$info['doctor_id'] = $doctor['doctor_id'];
$info['user_name'] = $doctor['user_name'];
$info['status'] = $doctor['status'];
$info['idcard_status'] = $doctor['idcard_status'];// 实名认证状态0:未认证 1:认证通过 2:认证失败)
$info['iden_auth_status'] = $doctor['idcard_status'];// 身份认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
$info['multi_point_status'] = $doctor['multi_point_status'];// 医生多点执业认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
$info['is_bind_bank'] = $doctor['is_bind_bank'];// 是否已绑定结算银行卡0:否 1:是)
$info['avatar'] = $doctor['avatar'];
$info['is_img_expert_reception'] = $doctor['is_img_expert_reception'];// 是否参加专家图文接诊0:否 1:是)
$info['praise_rate'] = $doctor['praise_rate'];// 好评率百分制。回复质量占4、服务态度占3、回复速度占3。每周计算一次
$info['avg_response_time'] = $doctor['avg_response_time'];// 平均响应时间(分钟制)
$info['number_of_fans'] = $doctor['number_of_fans'];// 被关注数量
$info['inquiry_price'] = $doctor_inquiry_config['inquiry_price'] ?? "";// 在线问诊价格
$info['not_accepted_inquiry_num'] = $not_accepted_inquiry_num ?? 0;// 获取未接诊患者个数
$info['accepting_inquiry_num'] = $accepting_inquiry_num ?? 0;// 获取接诊中患者个数
$info['reject_prescription_number'] = $reject_prescription_number ?? 0;// 获取被驳回处方数据
$data = array();
$data['banner'] = $banner ?? [];// banner
$data['info'] = $info;// 医生数据
return success($data);
}
/**
* 患者端-首页
* @return array
*/
public function getPatientIndex(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
// 获取banner
$params = array();
$params["app_type"] = 1;
$params["client_type"] = 1;
$params["banner_place"] = 1;
$params["banner_status"] = 1;
$banner = BannerModel::getList($params);
// 获取模块
$params = array();
$params["app_type"] = 1;
$params["client_type"] = 1;
$params["module_place"] = 1;
$params["module_status"] = 1;
$module = ModuleModel::getList($params);
// 我的医生
$my_doctor = [];
if (!empty($user_info)) {
$my_doctor = $this->getIndexPatientDoctor($user_info['client_user_id']);
}
// 推荐医生
$recommend_doctor = $this->getIndexRecommendDoctor();
$result = array();
$result["banner"] = $banner ?? [];// banner
$result["recommend_doctor"] = $recommend_doctor['data'] ?? []; // 推荐医生
$result["my_doctor"] = $my_doctor ?? []; // 我的医生
$result["module"] = $module ?? []; // 首页模块
return success($result);
}
/**
* 药师端-首页
* @return array
*/
public function getPharmacistIndex(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
// 获取药师数据
$params = array();
$params['pharmacist_id'] = $user_info['client_user_id'];
$fields = [
"pharmacist_id",
"user_id",
"user_name",
"open_id",
"status",
"avatar",
"is_online",
];
$user_pharmacist = UserPharmacist::getOne($params,$fields);
if (empty($user_pharmacist)) {
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
if ($user_pharmacist['status'] == 0){
return fail(HttpEnumCode::USER_STATUS_DISABLE);
}
if ($user_pharmacist['status'] != 1){
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
// 获取药师审方数量
$params = array();
$params['pharmacist_id'] = $user_pharmacist['pharmacist_id'];
$params['statistics_date'] = date('Y-m-d',time());
$audit_number = PharmacistAuditStatistic::getCount($params);
if (empty($audit_number)){
$audit_number = 0;
}
// 获取药师待审核处方
$OrderPrescriptionService = new OrderPrescriptionService();
$prescription = $OrderPrescriptionService->getPharmacistWaitAuditPage($user_pharmacist['pharmacist_id']);
// 组合返回数据
$data = array();
$data['pharmacist'] = $user_pharmacist;
$data['audit_number'] = $audit_number;
$data['prescription'] = $prescription;
return success($data);
}
/**
* 患者端-首页-我的医生-限制条数
* @param string $patient_id
* @return array
*/
protected function getIndexPatientDoctor(string $patient_id): array
{
$results = array();
$params = array();
$params['patient_id'] = $patient_id;
$params['history_status'] = 1;
$patient_history_doctors = PatientHistoryInquiryModel::getIndexHistoryDoctorLimit($params);
if (!empty($patient_history_doctors)) {
foreach ($patient_history_doctors as $patient_history_doctor) {
if (empty($patient_history_doctor['userDoctor'])) {
continue;
}
// 组合数据
$data = array();
$data['doctor_id'] = $patient_history_doctor['userDoctor']['doctor_id'];
$data['user_name'] = $patient_history_doctor['userDoctor']['user_name'];
$data['avatar'] = $patient_history_doctor['userDoctor']['avatar'];
$data['hospital_name'] = "";
if (!empty($patient_history_doctor['userDoctor']['Hospital'])) {
$data['hospital_name'] = $patient_history_doctor['userDoctor']['Hospital']['hospital_name'];
}
// 按照天来计算当日为1前一天为2 未服务过为0
if (empty($patient_history_doctor['created_at'])) {
$data['days'] = 0;
} else {
$data['days'] = ceil((strtotime(date('Y-m-d', strtotime('+1 day'))) - strtotime($patient_history_doctor['created_at'])) / 86400);
}
$results[] = $data;
unset($data);
}
}
return $results;
}
/**
* 患者端-首页-推荐医生-限制条数
* @return array
*/
protected function getIndexRecommendDoctor(): array
{
$results = array();
// 推荐医生
$fields = [
"doctor_id",
"user_id",
"user_name",
"status",
"multi_point_status",
"avatar",
"doctor_title",
"department_custom_name",
"hospital_id",
"is_online",
"is_img_expert_reception",
"be_good_at",
];
$recommend_doctors = UserDoctorModel::getIndexRecommendDoctorLimit(5, $fields);
if (empty($recommend_doctors)) {
return success();
}
foreach ($recommend_doctors as $recommend_doctor) {
$data = array();
$data['doctor_id'] = $recommend_doctor['doctor_id'];
$data['user_id'] = $recommend_doctor['user_id'];
$data['user_name'] = $recommend_doctor['user_name'];
$data['status'] = $recommend_doctor['status'];
$data['multi_point_status'] = $recommend_doctor['multi_point_status']; // 医生多点执业认证状态0:未认证 1:认证通过 2:审核中 3:认证失败)
$data['avatar'] = $recommend_doctor['avatar'];
$data['doctor_title'] = empty($recommend_doctor['doctor_title']) ? "" : DoctorTitleCode::getMessage($recommend_doctor['doctor_title']);
$data['department_custom_name'] = $recommend_doctor['department_custom_name'];
$data['is_online'] = $recommend_doctor['is_online'];
$data['be_good_at'] = $recommend_doctor['be_good_at'];
$data['hospital_name'] = $recommend_doctor['Hospital']['hospital_name'];
$data['hospital_level_name'] = $recommend_doctor['Hospital']['hospital_level_name'];
// 处理接诊价格
$data['price'] = 0;
$data['free_clinic_price'] = 0;
foreach ($recommend_doctor['DoctorInquiryConfig'] as $doctor_inquiry_config) {
if ($doctor_inquiry_config['inquiry_mode'] == 1){
if ($doctor_inquiry_config['inquiry_type'] == 1) {
// 专家问诊
$data['price'] = $doctor_inquiry_config['inquiry_price'];
}
if ($doctor_inquiry_config['inquiry_type'] == 3) {
// 公益
$data['free_clinic_price'] = $doctor_inquiry_config['inquiry_price'];
}
}
}
$results[] = $data;
unset($data);
}
return success($results);
}
}

View File

@ -0,0 +1,378 @@
<?php
namespace App\Services;
use App\Constants\HttpEnumCode;
use App\Model\User as UserModel;
use App\Model\UserDoctor as UserDoctorModel;
use App\Model\UserPatient as UserPatientModel;
use App\Model\UserPharmacist as UserPharmacistModel;
use App\Utils\Http;
use App\Utils\Jwt;
use App\Utils\WeChat;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class LoginService extends BaseService
{
/**
* 微信登陆
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function wechatMobileLogin(): array
{
$phone_code = $this->request->input('phone_code');
$wx_code = $this->request->input('wx_code');
$user_type = $this->request->input('user_type');
$weChat = $this->container->get(WeChat::class);
// // 获取手机号
// $phone_info = $weChat->getPhone($phone_code);
// if (empty($phone_info) || empty($phone_info['phone_info']) || empty($phone_info['phone_info']['purePhoneNumber'])){
// return fail(HttpEnumCode::GET_WX_ERROR);
// }
$phone_info['phone_info']['purePhoneNumber'] = "18221234161";
// 获取用户openid
// $wx_info_data = $weChat->codeToSession($wx_code);
$wx_info_data = array(
"session_key" => "SWfpkHtKZRq/G0ONoxigaQ==",
"openid" => "o9gYG441zEAHuYoNX7lwFKiQBzKE",
);
if (empty($wx_info_data['session_key']) || empty($wx_info_data['openid'])) {
return fail(HttpEnumCode::GET_WX_ERROR);
}
Db::beginTransaction();
try {
// 获取用户信息
$params = array();
$params['mobile'] = $phone_info['phone_info']['purePhoneNumber'];
$user = UserModel::getOne($params);
if (empty($user)) {
// 处理药师特殊情况,后台添加,前台不允许注册
if ($user_type == 3) {
return fail(HttpEnumCode::GET_WX_ERROR);
}
// 新增用户表
$data = array();
$data['user_name'] = substr($phone_info['phone_info']['purePhoneNumber'],-4);
$data['mobile'] = $phone_info['phone_info']['purePhoneNumber'];
$data['wx_mobile'] = $phone_info['phone_info']['purePhoneNumber'];
$data['user_type'] = $user_type;
$data['register_method'] = 1;//注册方式1:小程序授权 2:手机号
$data['login_ip'] = (new Http())->getIp() ?? "";// 登陆ip
$data['last_login_at'] = date('Y-m-d H:i:s', time());// 最后登陆时间
$user = UserModel::addUser($data);
if (empty($user)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 新增对应用户数据表
$data = array();
$data['user_id'] = $user->user_id;
$data['user_name'] = $user['user_name'];
$data['open_id'] = $wx_info_data['openid'];
$data['union_id'] = $wx_info_data['unionid'] ?? "";
$data['wx_session_key'] = $wx_info_data['session_key'];
$data['status'] = 1;
$data['mobile'] = $phone_info['phone_info']['purePhoneNumber'];
if ($user['user_type'] == 1) {
// 患者
$user_patient = UserPatientModel::addUserPatient($data);
if (empty($user_patient)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_patient['patient_id'];
// 发放用户优惠卷
$CouponService = new CouponService();
$res = $CouponService->DistributeCoupon(1,$user->user_id,$user_patient['patient_id']);
if (!$res){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
} elseif ($user['user_type'] == 2) {
// 新增医生表
$user_doctor = UserDoctorModel::addUserDoctor($data);
if (empty($user_doctor)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_doctor['doctor_id'];
}
} else {
// 已注册用户
// 重复注册不同端
if ($user_type != $user['user_type']) {
Db::rollBack();
$result = UserTypeToString($user['user_type']);
return fail(HttpEnumCode::GET_WX_ERROR, "手机号已在" . $result . "注册");
}
// 获取对应端用户信息
$params = array();
$params['user_id'] = $user->user_id;
if ($user['user_type'] == 1) {
$result = UserPatientModel::getOne($params);
if (!empty($result)){
$client_user_id = $result['patient_id'];
}
} elseif ($user['user_type'] == 2) {
$result = UserDoctorModel::getOne($params);
if (!empty($result)){
$client_user_id = $result['doctor_id'];
}
} elseif ($user['user_type'] == 3) {
$result = UserPharmacistModel::getOne($params);
if (!empty($result)){
$client_user_id = $result['pharmacist_id'];
}
}
if (empty($result)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 判断用户状态
if ($result['status'] != 1) {
Db::rollBack();
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
// 更新session_key
$data = array();
if ($wx_info_data['session_key'] != $result['session_key']) {
$data['wx_session_key'] = $wx_info_data['session_key'];
}
$data['updated_at'] = date('Y-m-d H:i:s', time());
$params = array();
if ($user['user_type'] == 1) {
$params['patient_id'] = $result['patient_id'];
$res = UserPatientModel::editUserPatient($params, $data);
} elseif ($user['user_type'] == 2) {
$params['doctor_id'] = $result['doctor_id'];
$res = UserDoctorModel::editUserDoctor($params, $data);
} elseif ($user['user_type'] == 3) {
$params['pharmacist_id'] = $result['pharmacist_id'];
$res = UserPharmacistModel::editUserPharmacist($params, $data);
}
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
}
// 记录用户登陆记录
$Http = new Http();
$login_ip = $Http->getIp();
$params = array();
$params['user_id'] = $user['user_id'];
$data = array();
$data['login_ip'] = $login_ip ?? "";
$data['last_login_at'] = date('Y-m-d H:i:s', time());
$res = UserModel::editUser($params,$data);
if (!$res){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 组合生成token的数据
$token_user_data = array();
$token_user_data['user_id'] = $user['user_id']; // 用户id
$token_user_data['user_type'] = $user['user_type'];// 用户类型
$token_user_data['open_id'] = $wx_info_data['openid'];// open_id
$token_user_data['client_user_id'] = $client_user_id;// 对应客户端id
// 发放token
$Jwt = new Jwt();
$token = $Jwt->encode($token_user_data);
// 组合返回数据
$data = array();
$data['token'] = $token;
$data['user_id'] = $user['user_id'];
$data['client_user_id'] = $client_user_id;
Db::commit();
return success($data);
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
}
}
// 手机号登陆
public function mobileLogin(){
$code = $this->request->input('code');
$phone = $this->request->input('phone');
$user_type = $this->request->input('user_type');
$redis = $this->container->get(Redis::class);
// 验证验证码
// $sms_code = $redis->get("login_code" . $phone);
// if (empty($sms_code)){
// return fail(HttpEnumCode::CODE_EXPIRED);
// }
//
// if ($sms_code != $code){
// return fail(HttpEnumCode::CODE_ERROR);
// }
Db::beginTransaction();
try {
// 获取用户信息
$params = array();
$params['mobile'] = $phone;
$user = UserModel::getOne($params);
if (empty($user)) {
// 处理药师特殊情况,后台添加,前台不允许注册
if ($user_type == 3) {
return fail(HttpEnumCode::GET_WX_ERROR);
}
// 新增用户表
$data = array();
$data['user_name'] = substr($phone,-4);
$data['mobile'] = $phone;
$data['wx_mobile'] = $phone;
$data['user_type'] = $user_type;
$data['register_method'] = 2;
$data['login_ip'] = (new Http())->getIp() ?? "";// 登陆ip
$data['last_login_at'] = date('Y-m-d H:i:s', time());// 最后登陆时间
$user = UserModel::addUser($data);
if (empty($user)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 新增对应用户数据表
$data = array();
$data['user_id'] = $user->user_id;
$data['user_name'] = $user['user_name'];
$data['status'] = 1;
$data['mobile'] = $phone;
if ($user['user_type'] == 1) {
// 患者
$user_patient = UserPatientModel::addUserPatient($data);
if (empty($user_patient)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_patient['patient_id'];
// 发放用户优惠卷
$CouponService = new CouponService();
$res = $CouponService->DistributeCoupon(1,$user->user_id,$user_patient['patient_id']);
if (!$res){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
} elseif ($user['user_type'] == 2) {
// 新增医生表
$user_doctor = UserDoctorModel::addUserDoctor($data);
if (empty($user_doctor)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
$client_user_id = $user_doctor['doctor_id'];
}
} else {
// 已注册用户
if ($user_type != $user['user_type']) {
Db::rollBack();
$result = UserTypeToString($user['user_type']);
return fail(HttpEnumCode::HTTP_ERROR, "手机号为" . $result . "账号");
}
$params = array();
$params['user_id'] = $user->user_id;
if ($user['user_type'] == 1) {
$result = UserPatientModel::getOne($params);
if (!empty($result)){
$client_user_id = $result['patient_id'];
}
} elseif ($user['user_type'] == 2) {
$result = UserDoctorModel::getOne($params);
if (!empty($result)){
$client_user_id = $result['doctor_id'];
}
} elseif ($user['user_type'] == 3) {
$result = UserPharmacistModel::getOne($params);
if (!empty($result)){
$client_user_id = $result['pharmacist_id'];
}
}
if (empty($result)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 判断用户状态
if ($result['status'] != 1) {
Db::rollBack();
return fail(HttpEnumCode::USER_STATUS_ERROR);
}
}
// 记录用户登陆记录
$Http = new Http();
$login_ip = $Http->getIp();
$params = array();
$params['user_id'] = $user['user_id'];
$data = array();
$data['login_ip'] = $login_ip ?? "";
$data['last_login_at'] = date('Y-m-d H:i:s', time());
$res = UserModel::editUser($params,$data);
if (!$res){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 组合生成token的数据
$token_user_data = array();
$token_user_data['user_id'] = $user['user_id']; // 用户id
$token_user_data['user_type'] = $user['user_type'];// 用户类型
$token_user_data['open_id'] = "";// open_id
$token_user_data['client_user_id'] = $client_user_id;// 对应客户端id
// 发放token
$Jwt = new Jwt();
$token = $Jwt->encode($token_user_data);
// 组合返回数据
$data = array();
$data['token'] = $token;
$data['user_id'] = $user['user_id'];
$data['client_user_id'] = $client_user_id;
Db::commit();
return success($data);
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace App\Services;
use App\Constants\HttpEnumCode;
use App\Model\PatientHistoryInquiry;
class MyDoctorService extends BaseService
{
/**
* 删除我的医生
* 首页-个人中心
* @return array
*/
public function deleteMyDoctor(): array
{
$history_inquiry_id = $this->request->route('history_inquiry_id');
$user_info = $this->request->getAttribute("userInfo") ?? [];
$params = array();
$params['history_inquiry_id'] = $history_inquiry_id;
$params['patient_id'] = $user_info['client_user_id'];
$patient_history_inquiry = PatientHistoryInquiry::getOne($params);
if (empty($patient_history_inquiry)){
return fail(HttpEnumCode::HTTP_ERROR, "数据不存在");
}
if ($patient_history_inquiry['history_status'] == 0){
return success();
}
$params = array();
$patient_history_inquiry['history_inquiry_id'] = $history_inquiry_id;
$data = array();
$data['history_status'] = 0;
$res = PatientHistoryInquiry::edit($params,$data);
if (!$res){
return fail(HttpEnumCode::SERVER_ERROR);
}
return success();
}
}

View File

@ -0,0 +1,257 @@
<?php
namespace App\Services;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Model\DiseaseClass;
use App\Model\DoctorInquiryConfig;
use App\Model\OrderInquiry;
use App\Model\PatientFamily;
use App\Model\Product;
use App\Model\SystemInquiryConfig;
use App\Model\UserDoctor;
use Hyperf\DbConnection\Db;
use Hyperf\Snowflake\IdGeneratorInterface;
/**
* 问诊订单
*/
class OrderInquiryService extends BaseService
{
/**
* 获取医生未接诊订单数量
* @param string $doctor_id 医生id
* @return int
*/
public function getDoctorNotAcceptedInquiryNum(string $doctor_id): int
{
$params = array();
$params['doctor_id'] = $doctor_id;
$params['inquiry_status'] = 3; // 待接诊
$params['inquiry_refund_status'] = 0; // 无退款
$order_inquiry_count = OrderInquiry::getCount($params);
if (!empty($order_inquiry_count) || $order_inquiry_count != 0){
$not_accepted_inquiry_num = $order_inquiry_count;
}else{
$not_accepted_inquiry_num = $order_inquiry_count;
}
return $not_accepted_inquiry_num;
}
/**
* 获取医生接诊中订单数量
* @param string $doctor_id 医生id
* @return int
*/
public function getDoctorAcceptingInquiryNum(string $doctor_id): int
{
$params = array();
$params['doctor_id'] = $doctor_id;
$params['inquiry_status'] = 4; // 已接诊
$params['inquiry_refund_status'] = 0; // 无退款
$order_inquiry_count = OrderInquiry::getCount($params);
if (!empty($order_inquiry_count) || $order_inquiry_count != 0){
$accepting_inquiry_num = $order_inquiry_count;
}else{
$accepting_inquiry_num = $order_inquiry_count;
}
return $accepting_inquiry_num;
}
// 创建问诊订单
public function addInquiryOrder(){
$user_info = $this->request->getAttribute("userInfo") ?? [];
$request_params = $this->request->all();
// 检测家庭成员是否存在
$params = array();
$params['family_id'] = $request_params['family_id'];
$params['patient_id'] = $user_info['client_user_id'];
$params['status'] = 1;
$patient_family = PatientFamily::getOne($params);
if (empty($patient_family)){
return fail(HttpEnumCode::HTTP_ERROR,"患者信息错误");
}
// 检测当前家庭成员是否和医生有未完成订单
$params = array();
$params[] = ['patient_id','=',$user_info['client_user_id']];
$params[] = ['family_id','=',$request_params['family_id']];
$params[] = ['inquiry_mode','=',1];
$params[] = ['inquiry_status','in',[1,2,3,4]]; // 1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消
$params[] = ['inquiry_refund_status','=',0];
$order_inquiry_count = OrderInquiry::getCount($params);
if ($order_inquiry_count != 0){
return fail(HttpEnumCode::HTTP_ERROR,"当前患者存在进行中的问诊订单");
}
// 问诊购药情况
if ($request_params['inquiry_type'] == 4){
// 问诊购药情况下是否包含用药意向
if (!empty($request_params['product'])){
foreach ($request_params['product'] as $item){
$params = array();
$params['product_id'] = $item['product_id'];
$product = Product::getWithAmountOne($params);
if (empty($product)){
return fail(HttpEnumCode::HTTP_ERROR,"意向药品错误");
}
// 检测商品库存
if (!empty($product['ProductPlatformAmount'])){
if ($item['product_num'] > $product['ProductPlatformAmount']['real_stock']){
// 此处是否需要特殊返回
return fail(HttpEnumCode::HTTP_ERROR,"意向药品库存不足");
}
}
// 用药意向是否和过敏史重叠
if (!empty($request_params['allergy_history'])){
$res = strpos($request_params['allergy_history'],$product['product_name']);
if ($res !== false){
return fail(HttpEnumCode::HTTP_ERROR,"过敏史中存在意向用药,请您仔细检查");
}
}
}
}
}
// 是否为孕妇
if (!empty($request_params['is_pregnant'])){
return fail(HttpEnumCode::HTTP_ERROR,"请您到线下问诊");
}
// 检测所患疾病是否正确
$params = array();
$params['disease_class_id'] = $request_params['disease_class_id'];
$params['disease_class_status'] = 1;
$disease_class = DiseaseClass::getOne($params);
if (empty($disease_class)){
return fail(HttpEnumCode::HTTP_ERROR,"疾病信息填写错误");
}
// 获取当前问诊医生信息
// 专家问诊-公益问诊
if ($request_params['inquiry_type'] == 3 || $request_params['inquiry_type'] == 1){
if (empty($request_params['doctor_id'])){
return fail(HttpEnumCode::HTTP_ERROR,"未选择医生");
}
$params = array();
$params['doctor_id'] = $request_params['doctor_id'];
$doctor = UserDoctor::getOne($params);
if (empty($doctor)){
return fail(HttpEnumCode::HTTP_ERROR,"未知医生");
}
if ($doctor['idcard_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR,"当前医生无法接诊,请重新选择");
}
if ($doctor['iden_auth_status'] != 1){
return fail(HttpEnumCode::HTTP_ERROR,"当前医生无法接诊,请重新选择");
}
}
// 获取问诊价格
$inquiry_price = $this->getDoctorInquiryPrice($request_params['inquiry_type'],$request_params['inquiry_mode'],$request_params['doctor_id'] ?? "");
// 获取可用优惠卷
$CouponService = new CouponService();
$user_coupon = $CouponService->getUserUsableCoupon($user_info['user_id'],$request_params['inquiry_type'],1);
Db::beginTransaction();
$generator = $this->container->get(IdGeneratorInterface::class);
try {
// 生成问诊订单
$data = array();
$data['user_id'] = $user_info['user_id'];
$data['patient_id'] = $user_info['client_user_id'];
$data['doctor_id'] = $request_params['doctor_id'] ?? "";
$data['family_id'] = $request_params['family_id'];
$data['inquiry_type'] = $request_params['inquiry_type'];
$data['inquiry_mode'] = $request_params['inquiry_mode'];
$data['inquiry_status'] = 1;// 1:待支付
$data['inquiry_no'] = $generator->generate();// 订单编号
$data['amount_total'] = $inquiry_price ?? 0;// 订单金额
$data['patient_name'] = $patient_family['card_name'];// 患者姓名-就诊人
$data['patient_name_mask'] = $patient_family['card_name_mask'];// 患者姓名-就诊人(掩码)
$data['patient_sex'] = $patient_family['sex'];// 患者性别-就诊人0:未知 1:男 2:女)
$data['patient_age'] = $patient_family['age'];// 患者年龄-就诊人
$order_inquiry = OrderInquiry::addUserDoctor($data);
if (empty($order_inquiry)){
return fail(HttpEnumCode::SERVER_ERROR,"订单创建失败");
}
// 增加患者问诊病例
$data = array();
$data['user_id'] = $user_info['user_id'];
$data['patient_id'] = $user_info['client_user_id'];
$data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];// 订单-问诊id
$data['family_id'] = $patient_family['family_id']; // 家庭成员id
$data['relation'] = $patient_family['relation']; // 与患者关系1:本人 2:父母 3:爱人 4:子女 5:亲戚 6:其他
$data['name'] = $patient_family['card_name']; // 患者名称
$data['sex'] = $patient_family['sex'] ?? 0; // 患者性别0:未知 1:男 2:女)
$data['age'] = $patient_family['age'] ?? null; // 患者年龄
$data['height'] = $request_params['height'] ?: $patient_family['height'] ?: null; // 身高cm
$data['weight'] = $request_params['weight'] ?: $patient_family['weight'] ?: null;; // 体重kg
$data['disease_class_id'] = $disease_class['disease_class_id']; // 疾病分类id-系统
$data['disease_class_name'] = $patient_family['card_name']; // 疾病名称-系统
$data['diagnosis_date'] = $patient_family['card_name']; // 确诊日期
$data['disease_desc'] = $patient_family['card_name']; // 病情描述(主诉)
$data['diagnose_images'] = $patient_family['card_name']; // 复诊凭证(多个使用逗号分隔)
$data['is_allergy_history'] = $patient_family['card_name']; // 是否存在过敏史0:否 1:是)
$data['allergy_history'] = $patient_family['card_name']; // 过敏史描述
$data['is_family_history'] = $patient_family['card_name']; // 是否存在家族病史0:否 1:是)
$data['family_history'] = $patient_family['card_name']; // 家族病史描述
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
// 添加患者病例
// 添加至具体队列
}
/**
* 获取问诊价格
* @param string|int $inquiry_type 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @param string|int $inquiry_mode 订单问诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
* @param string|int $doctor_id 医生id
* @return int
*/
public function getDoctorInquiryPrice(string|int $inquiry_type, string|int $inquiry_mode,string|int $doctor_id): int
{
if (empty($doctor_id)){
throw new BusinessException();
}
$params = array();
$params['doctor_id'] = $doctor_id;
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = $inquiry_mode;
$doctor_inquiry_config = DoctorInquiryConfig::getInquiryConfigOne($params);
if (empty($doctor_inquiry_config)){
throw new BusinessException( "当前医生未开通对应服务,请重新选择",HttpEnumCode::HTTP_ERROR);
}
$inquiry_price = $doctor_inquiry_config['inquiry_price'] ?: 0;
if ($inquiry_type == 2){
$inquiry_price = $doctor_inquiry_config['SystemInquiryConfig']['inquiry_price'];
}
return $inquiry_price;
}
}

Some files were not shown because too many files have changed in this diff Show More