commit 4ca844f4701dfccc41f3339234dca1e9fdd2d5b5 Author: wucongxing <815046773@qq.com> Date: Fri Feb 17 17:10:16 2023 +0800 初始化提交 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..6879583 --- /dev/null +++ b/.env.example @@ -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 \ No newline at end of file diff --git a/.github/workflows/Dockerfile b/.github/workflows/Dockerfile new file mode 100644 index 0000000..0301e6d --- /dev/null +++ b/.github/workflows/Dockerfile @@ -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 " 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"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0ca82fa --- /dev/null +++ b/.github/workflows/build.yml @@ -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 . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0f7d23f --- /dev/null +++ b/.github/workflows/release.yml @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..70b4f13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +.buildpath +.settings/ +.project +*.patch +.idea/ +.git/ +runtime/ +vendor/ +.phpintel/ +.env +.DS_Store +.phpunit* +*.cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..a5fccae --- /dev/null +++ b/.gitlab-ci.yml @@ -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 diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..dd164b5 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,91 @@ +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); diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php new file mode 100644 index 0000000..811e1db --- /dev/null +++ b/.phpstorm.meta.php @@ -0,0 +1,9 @@ + '@'])); + override(\Hyperf\Context\Context::get(0), map(['' => '@'])); + override(\make(0), map(['' => '@'])); + override(\di(0), map(['' => '@'])); +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5f79621 --- /dev/null +++ b/Dockerfile @@ -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 " 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"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c35d3f5 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..442c728 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# 描述 +肝胆相照互联网医院,患者、医生、药师端小程序后台api接口项目 + +# 要求 +- 框架 >= hyperf3.0.0 +- PHP >= 8.0 +- Swoole PHP extension >= 4.5,and 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/` \ No newline at end of file diff --git a/app/Common/Common.php b/app/Common/Common.php new file mode 100644 index 0000000..e646848 --- /dev/null +++ b/app/Common/Common.php @@ -0,0 +1,138 @@ +\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 = '
' . $output . '
'; + } + + 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; +} \ No newline at end of file diff --git a/app/Constants/DoctorTitleCode.php b/app/Constants/DoctorTitleCode.php new file mode 100644 index 0000000..83d0c9e --- /dev/null +++ b/app/Constants/DoctorTitleCode.php @@ -0,0 +1,35 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/BasicDataController.php b/app/Controller/BasicDataController.php new file mode 100644 index 0000000..236e6cb --- /dev/null +++ b/app/Controller/BasicDataController.php @@ -0,0 +1,43 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/CodeController.php b/app/Controller/CodeController.php new file mode 100644 index 0000000..61cb6c3 --- /dev/null +++ b/app/Controller/CodeController.php @@ -0,0 +1,42 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/DiseaseController.php b/app/Controller/DiseaseController.php new file mode 100644 index 0000000..4a13f29 --- /dev/null +++ b/app/Controller/DiseaseController.php @@ -0,0 +1,50 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/DoctorAuthController.php b/app/Controller/DoctorAuthController.php new file mode 100644 index 0000000..af08fa0 --- /dev/null +++ b/app/Controller/DoctorAuthController.php @@ -0,0 +1,98 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/IndexController.php b/app/Controller/IndexController.php new file mode 100644 index 0000000..95e94ff --- /dev/null +++ b/app/Controller/IndexController.php @@ -0,0 +1,59 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/LoginController.php b/app/Controller/LoginController.php new file mode 100644 index 0000000..204d408 --- /dev/null +++ b/app/Controller/LoginController.php @@ -0,0 +1,44 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/OrderInquiryController.php b/app/Controller/OrderInquiryController.php new file mode 100644 index 0000000..d9e0a69 --- /dev/null +++ b/app/Controller/OrderInquiryController.php @@ -0,0 +1,39 @@ +container->get(OrderInquiryRequest::class); + $request->scene('addInquiryOrder')->validateResolved(); + + $OrderInquiryService = new OrderInquiryService(); + $data = $OrderInquiryService->addInquiryOrder(); + return $this->response->json($data); + } +} \ No newline at end of file diff --git a/app/Controller/PatientCaseController.php b/app/Controller/PatientCaseController.php new file mode 100644 index 0000000..2f716eb --- /dev/null +++ b/app/Controller/PatientCaseController.php @@ -0,0 +1,23 @@ +getLastCase(); + return $this->response->json($data); + } +} \ No newline at end of file diff --git a/app/Controller/PatientCenterController.php b/app/Controller/PatientCenterController.php new file mode 100644 index 0000000..585dc34 --- /dev/null +++ b/app/Controller/PatientCenterController.php @@ -0,0 +1,26 @@ +deleteMyDoctor(); + + return $this->response->json($data); + } +} \ No newline at end of file diff --git a/app/Controller/PatientDoctorController.php b/app/Controller/PatientDoctorController.php new file mode 100644 index 0000000..3b1b649 --- /dev/null +++ b/app/Controller/PatientDoctorController.php @@ -0,0 +1,66 @@ +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); + } +} \ No newline at end of file diff --git a/app/Controller/PatientFamilyController.php b/app/Controller/PatientFamilyController.php new file mode 100644 index 0000000..c0f7fa7 --- /dev/null +++ b/app/Controller/PatientFamilyController.php @@ -0,0 +1,82 @@ +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 ""; + } + +} \ No newline at end of file diff --git a/app/Controller/SafeController.php b/app/Controller/SafeController.php new file mode 100644 index 0000000..6ff2928 --- /dev/null +++ b/app/Controller/SafeController.php @@ -0,0 +1,28 @@ +container->get(SafeRequest::class); + $request->scene('getOssSign')->validateResolved(); + + $SafeService = new SafeService(); + $data = $SafeService->getOssSign(); + return $this->response->json($data); + } +} \ No newline at end of file diff --git a/app/Controller/UserController.php b/app/Controller/UserController.php new file mode 100644 index 0000000..068a517 --- /dev/null +++ b/app/Controller/UserController.php @@ -0,0 +1,15 @@ +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); + } +} \ No newline at end of file diff --git a/app/Exception/BusinessException.php b/app/Exception/BusinessException.php new file mode 100644 index 0000000..611cb91 --- /dev/null +++ b/app/Exception/BusinessException.php @@ -0,0 +1,28 @@ +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; + } +} diff --git a/app/Exception/Handler/BusinessExceptionHandler.php b/app/Exception/Handler/BusinessExceptionHandler.php new file mode 100644 index 0000000..f66d339 --- /dev/null +++ b/app/Exception/Handler/BusinessExceptionHandler.php @@ -0,0 +1,73 @@ +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; + } +} \ No newline at end of file diff --git a/app/Exception/Handler/ValidationExceptionHandler.php b/app/Exception/Handler/ValidationExceptionHandler.php new file mode 100644 index 0000000..d044c4c --- /dev/null +++ b/app/Exception/Handler/ValidationExceptionHandler.php @@ -0,0 +1,62 @@ +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; + } +} diff --git a/app/Exception/ValidationException.php b/app/Exception/ValidationException.php new file mode 100644 index 0000000..4905fea --- /dev/null +++ b/app/Exception/ValidationException.php @@ -0,0 +1,18 @@ +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)); + } + } +} diff --git a/app/Listener/QueueHandleListener.php b/app/Listener/QueueHandleListener.php new file mode 100644 index 0000000..d81c3bd --- /dev/null +++ b/app/Listener/QueueHandleListener.php @@ -0,0 +1,73 @@ +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; + } + } + } +} diff --git a/app/Listener/ResumeExitCoordinatorListener.php b/app/Listener/ResumeExitCoordinatorListener.php new file mode 100644 index 0000000..6a10f1e --- /dev/null +++ b/app/Listener/ResumeExitCoordinatorListener.php @@ -0,0 +1,34 @@ +resume(); + } +} diff --git a/app/Middleware/Auth/AuthMiddleware.php b/app/Middleware/Auth/AuthMiddleware.php new file mode 100644 index 0000000..53b1fee --- /dev/null +++ b/app/Middleware/Auth/AuthMiddleware.php @@ -0,0 +1,154 @@ +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] ?? ""; + } + + +} diff --git a/app/Middleware/CoreMiddleware.php b/app/Middleware/CoreMiddleware.php new file mode 100644 index 0000000..aacaa3c --- /dev/null +++ b/app/Middleware/CoreMiddleware.php @@ -0,0 +1,38 @@ +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')); + } +} diff --git a/app/Middleware/Corss/CorssMiddleware.php b/app/Middleware/Corss/CorssMiddleware.php new file mode 100644 index 0000000..5407f28 --- /dev/null +++ b/app/Middleware/Corss/CorssMiddleware.php @@ -0,0 +1,31 @@ +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); + } +} diff --git a/app/Model/Area.php b/app/Model/Area.php new file mode 100644 index 0000000..e0f5b77 --- /dev/null +++ b/app/Model/Area.php @@ -0,0 +1,61 @@ + '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); + } +} diff --git a/app/Model/Banner.php b/app/Model/Banner.php new file mode 100644 index 0000000..5d02661 --- /dev/null +++ b/app/Model/Banner.php @@ -0,0 +1,69 @@ + '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); + } + + +} diff --git a/app/Model/BasicJob.php b/app/Model/BasicJob.php new file mode 100644 index 0000000..d400ab9 --- /dev/null +++ b/app/Model/BasicJob.php @@ -0,0 +1,48 @@ + '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); + } +} diff --git a/app/Model/BasicNation.php b/app/Model/BasicNation.php new file mode 100644 index 0000000..0737682 --- /dev/null +++ b/app/Model/BasicNation.php @@ -0,0 +1,48 @@ + '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); + } +} diff --git a/app/Model/CodeLog.php b/app/Model/CodeLog.php new file mode 100644 index 0000000..58949e8 --- /dev/null +++ b/app/Model/CodeLog.php @@ -0,0 +1,77 @@ + '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); + } +} diff --git a/app/Model/Coupon.php b/app/Model/Coupon.php new file mode 100644 index 0000000..a41852d --- /dev/null +++ b/app/Model/Coupon.php @@ -0,0 +1,77 @@ + '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); + } + +} diff --git a/app/Model/DiseaseClass.php b/app/Model/DiseaseClass.php new file mode 100644 index 0000000..523f57a --- /dev/null +++ b/app/Model/DiseaseClass.php @@ -0,0 +1,77 @@ + '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); + } +} diff --git a/app/Model/DiseaseClassExpertise.php b/app/Model/DiseaseClassExpertise.php new file mode 100644 index 0000000..d80b024 --- /dev/null +++ b/app/Model/DiseaseClassExpertise.php @@ -0,0 +1,60 @@ + '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(); + } +} diff --git a/app/Model/DoctorExpertise.php b/app/Model/DoctorExpertise.php new file mode 100644 index 0000000..170ce90 --- /dev/null +++ b/app/Model/DoctorExpertise.php @@ -0,0 +1,103 @@ + '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); + } +} diff --git a/app/Model/DoctorInquiryConfig.php b/app/Model/DoctorInquiryConfig.php new file mode 100644 index 0000000..7b2a8fb --- /dev/null +++ b/app/Model/DoctorInquiryConfig.php @@ -0,0 +1,108 @@ + '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); + } +} diff --git a/app/Model/DoctorInquiryPriceRecord.php b/app/Model/DoctorInquiryPriceRecord.php new file mode 100644 index 0000000..fcc49e4 --- /dev/null +++ b/app/Model/DoctorInquiryPriceRecord.php @@ -0,0 +1,60 @@ + '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(); + } +} diff --git a/app/Model/Hospital.php b/app/Model/Hospital.php new file mode 100644 index 0000000..ac80e9f --- /dev/null +++ b/app/Model/Hospital.php @@ -0,0 +1,85 @@ + '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); + } + +} diff --git a/app/Model/HospitalDepartmentCustom.php b/app/Model/HospitalDepartmentCustom.php new file mode 100644 index 0000000..e5b43e8 --- /dev/null +++ b/app/Model/HospitalDepartmentCustom.php @@ -0,0 +1,64 @@ + '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); + } +} diff --git a/app/Model/InquiryCaseProduct.php b/app/Model/InquiryCaseProduct.php new file mode 100644 index 0000000..ef884e5 --- /dev/null +++ b/app/Model/InquiryCaseProduct.php @@ -0,0 +1,88 @@ + '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); + } + +} diff --git a/app/Model/Model.php b/app/Model/Model.php new file mode 100644 index 0000000..fe03061 --- /dev/null +++ b/app/Model/Model.php @@ -0,0 +1,18 @@ + '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); + } + +} diff --git a/app/Model/OrderEvaluation.php b/app/Model/OrderEvaluation.php new file mode 100644 index 0000000..b9d5fc5 --- /dev/null +++ b/app/Model/OrderEvaluation.php @@ -0,0 +1,66 @@ + '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; + } +} diff --git a/app/Model/OrderInquiry.php b/app/Model/OrderInquiry.php new file mode 100644 index 0000000..1e97ac8 --- /dev/null +++ b/app/Model/OrderInquiry.php @@ -0,0 +1,105 @@ + '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(); + } +} diff --git a/app/Model/OrderInquiryCase.php b/app/Model/OrderInquiryCase.php new file mode 100644 index 0000000..d2083f6 --- /dev/null +++ b/app/Model/OrderInquiryCase.php @@ -0,0 +1,116 @@ + '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); + } +} diff --git a/app/Model/OrderPrescription.php b/app/Model/OrderPrescription.php new file mode 100644 index 0000000..b0ef021 --- /dev/null +++ b/app/Model/OrderPrescription.php @@ -0,0 +1,86 @@ + '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; + } + +} diff --git a/app/Model/PatientFamily.php b/app/Model/PatientFamily.php new file mode 100644 index 0000000..2b70e47 --- /dev/null +++ b/app/Model/PatientFamily.php @@ -0,0 +1,106 @@ + '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); + } +} diff --git a/app/Model/PatientFollow.php b/app/Model/PatientFollow.php new file mode 100644 index 0000000..a6ff316 --- /dev/null +++ b/app/Model/PatientFollow.php @@ -0,0 +1,48 @@ + '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(); + } +} diff --git a/app/Model/PatientHistoryInquiry.php b/app/Model/PatientHistoryInquiry.php new file mode 100644 index 0000000..b3c6c88 --- /dev/null +++ b/app/Model/PatientHistoryInquiry.php @@ -0,0 +1,134 @@ + '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); + } +} diff --git a/app/Model/PharmacistAuditStatistic.php b/app/Model/PharmacistAuditStatistic.php new file mode 100644 index 0000000..f59b22b --- /dev/null +++ b/app/Model/PharmacistAuditStatistic.php @@ -0,0 +1,61 @@ + '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(); + } +} diff --git a/app/Model/Product.php b/app/Model/Product.php new file mode 100644 index 0000000..6bd4d21 --- /dev/null +++ b/app/Model/Product.php @@ -0,0 +1,89 @@ + '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); + } +} diff --git a/app/Model/ProductPlatformAmount.php b/app/Model/ProductPlatformAmount.php new file mode 100644 index 0000000..3db79b0 --- /dev/null +++ b/app/Model/ProductPlatformAmount.php @@ -0,0 +1,41 @@ + 'integer', 'product_platform_id' => 'integer', 'real_stock' => 'integer', 'stock' => 'integer', 'lock_stock' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime']; + + protected string $primaryKey = "amount_id"; +} diff --git a/app/Model/SystemInquiryConfig.php b/app/Model/SystemInquiryConfig.php new file mode 100644 index 0000000..25337f4 --- /dev/null +++ b/app/Model/SystemInquiryConfig.php @@ -0,0 +1,67 @@ + '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); + } +} diff --git a/app/Model/TbHospitalMy.php b/app/Model/TbHospitalMy.php new file mode 100644 index 0000000..5178a93 --- /dev/null +++ b/app/Model/TbHospitalMy.php @@ -0,0 +1,77 @@ + '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); + } + +} diff --git a/app/Model/User.php b/app/Model/User.php new file mode 100644 index 0000000..7155087 --- /dev/null +++ b/app/Model/User.php @@ -0,0 +1,82 @@ + '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); + } +} diff --git a/app/Model/UserCoupon.php b/app/Model/UserCoupon.php new file mode 100644 index 0000000..2bb7103 --- /dev/null +++ b/app/Model/UserCoupon.php @@ -0,0 +1,91 @@ + '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); + } +} diff --git a/app/Model/UserDoctor.php b/app/Model/UserDoctor.php new file mode 100644 index 0000000..e3a0853 --- /dev/null +++ b/app/Model/UserDoctor.php @@ -0,0 +1,282 @@ + '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:在线 + * 6:5个 + * @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; + } +} diff --git a/app/Model/UserDoctorInfo.php b/app/Model/UserDoctorInfo.php new file mode 100644 index 0000000..82ee57d --- /dev/null +++ b/app/Model/UserDoctorInfo.php @@ -0,0 +1,80 @@ + '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); + } +} diff --git a/app/Model/UserPatient.php b/app/Model/UserPatient.php new file mode 100644 index 0000000..663e076 --- /dev/null +++ b/app/Model/UserPatient.php @@ -0,0 +1,79 @@ + '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); + } +} diff --git a/app/Model/UserPharmacist.php b/app/Model/UserPharmacist.php new file mode 100644 index 0000000..1b3f9ec --- /dev/null +++ b/app/Model/UserPharmacist.php @@ -0,0 +1,69 @@ + '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); + } +} diff --git a/app/Process/AsyncQueueConsumer.php b/app/Process/AsyncQueueConsumer.php new file mode 100644 index 0000000..e211939 --- /dev/null +++ b/app/Process/AsyncQueueConsumer.php @@ -0,0 +1,20 @@ + ['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), + ]; + } +} diff --git a/app/Request/BasicDataRequest.php b/app/Request/BasicDataRequest.php new file mode 100644 index 0000000..3ca16e7 --- /dev/null +++ b/app/Request/BasicDataRequest.php @@ -0,0 +1,49 @@ + [ // 获取医院数据 + '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' => "请选择城市", + ]; + } +} diff --git a/app/Request/CodeRequest.php b/app/Request/CodeRequest.php new file mode 100644 index 0000000..1871f57 --- /dev/null +++ b/app/Request/CodeRequest.php @@ -0,0 +1,47 @@ + ['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), + ]; + } +} diff --git a/app/Request/DiseaseRequest.php b/app/Request/DiseaseRequest.php new file mode 100644 index 0000000..b00474c --- /dev/null +++ b/app/Request/DiseaseRequest.php @@ -0,0 +1,45 @@ + [ // 搜索疾病分类 + '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), + ]; + } +} diff --git a/app/Request/DoctorAuthRequest.php b/app/Request/DoctorAuthRequest.php new file mode 100644 index 0000000..35ceb63 --- /dev/null +++ b/app/Request/DoctorAuthRequest.php @@ -0,0 +1,105 @@ + [ // 新增实名认证 + '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), + ]; + } +} diff --git a/app/Request/LoginRequest.php b/app/Request/LoginRequest.php new file mode 100644 index 0000000..ef5efce --- /dev/null +++ b/app/Request/LoginRequest.php @@ -0,0 +1,56 @@ + ['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), + ]; + } +} diff --git a/app/Request/OrderInquiryRequest.php b/app/Request/OrderInquiryRequest.php new file mode 100644 index 0000000..7d1008d --- /dev/null +++ b/app/Request/OrderInquiryRequest.php @@ -0,0 +1,81 @@ + [ + '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), + ]; + } +} diff --git a/app/Request/PatientDoctorRequest.php b/app/Request/PatientDoctorRequest.php new file mode 100644 index 0000000..3846b5e --- /dev/null +++ b/app/Request/PatientDoctorRequest.php @@ -0,0 +1,45 @@ + ['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), + ]; + } +} diff --git a/app/Request/PatientFamilyRequest.php b/app/Request/PatientFamilyRequest.php new file mode 100644 index 0000000..6eb1de1 --- /dev/null +++ b/app/Request/PatientFamilyRequest.php @@ -0,0 +1,88 @@ + [ // 新增家庭成员 + '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' => "婚姻状况错误", + ]; + } +} diff --git a/app/Request/SafeRequest.php b/app/Request/SafeRequest.php new file mode 100644 index 0000000..32d4135 --- /dev/null +++ b/app/Request/SafeRequest.php @@ -0,0 +1,46 @@ + ['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), + ]; + } +} diff --git a/app/Request/UserDoctorRequest.php b/app/Request/UserDoctorRequest.php new file mode 100644 index 0000000..0640827 --- /dev/null +++ b/app/Request/UserDoctorRequest.php @@ -0,0 +1,76 @@ + [ // 获取医生问诊配置 + '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), + ]; + } +} diff --git a/app/Request/UserRequest.php b/app/Request/UserRequest.php new file mode 100644 index 0000000..9700a7e --- /dev/null +++ b/app/Request/UserRequest.php @@ -0,0 +1,50 @@ + ['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), + ]; + } +} diff --git a/app/Services/AreaService.php b/app/Services/AreaService.php new file mode 100644 index 0000000..a7bbf40 --- /dev/null +++ b/app/Services/AreaService.php @@ -0,0 +1,114 @@ +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()); + } +} \ No newline at end of file diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php new file mode 100644 index 0000000..ceac0d9 --- /dev/null +++ b/app/Services/BaseService.php @@ -0,0 +1,21 @@ +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()); + } +} \ No newline at end of file diff --git a/app/Services/CodeService.php b/app/Services/CodeService.php new file mode 100644 index 0000000..31319a9 --- /dev/null +++ b/app/Services/CodeService.php @@ -0,0 +1,68 @@ +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(); + } +} \ No newline at end of file diff --git a/app/Services/CouponService.php b/app/Services/CouponService.php new file mode 100644 index 0000000..5b56e45 --- /dev/null +++ b/app/Services/CouponService.php @@ -0,0 +1,96 @@ +',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; + } +} \ No newline at end of file diff --git a/app/Services/DiseaseService.php b/app/Services/DiseaseService.php new file mode 100644 index 0000000..2c9f63c --- /dev/null +++ b/app/Services/DiseaseService.php @@ -0,0 +1,53 @@ +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()) ; + } +} \ No newline at end of file diff --git a/app/Services/DoctorAuthService.php b/app/Services/DoctorAuthService.php new file mode 100644 index 0000000..501364e --- /dev/null +++ b/app/Services/DoctorAuthService.php @@ -0,0 +1,646 @@ +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(); + } +} \ No newline at end of file diff --git a/app/Services/DoctorInquiryService.php b/app/Services/DoctorInquiryService.php new file mode 100644 index 0000000..0254046 --- /dev/null +++ b/app/Services/DoctorInquiryService.php @@ -0,0 +1,335 @@ +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(); + } +} \ No newline at end of file diff --git a/app/Services/IndexService.php b/app/Services/IndexService.php new file mode 100644 index 0000000..0952c0e --- /dev/null +++ b/app/Services/IndexService.php @@ -0,0 +1,325 @@ +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); + } +} \ No newline at end of file diff --git a/app/Services/LoginService.php b/app/Services/LoginService.php new file mode 100644 index 0000000..cf3bbb3 --- /dev/null +++ b/app/Services/LoginService.php @@ -0,0 +1,378 @@ +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()); + } + } +} \ No newline at end of file diff --git a/app/Services/MyDoctorService.php b/app/Services/MyDoctorService.php new file mode 100644 index 0000000..c489fcf --- /dev/null +++ b/app/Services/MyDoctorService.php @@ -0,0 +1,48 @@ +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(); + + } +} \ No newline at end of file diff --git a/app/Services/OrderInquiryService.php b/app/Services/OrderInquiryService.php new file mode 100644 index 0000000..478b84a --- /dev/null +++ b/app/Services/OrderInquiryService.php @@ -0,0 +1,257 @@ +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; + } +} \ No newline at end of file diff --git a/app/Services/OrderPrescriptionService.php b/app/Services/OrderPrescriptionService.php new file mode 100644 index 0000000..7adb914 --- /dev/null +++ b/app/Services/OrderPrescriptionService.php @@ -0,0 +1,59 @@ +request->input('page', 1); + $per_page = $this->request->input('per_page', 10); + return OrderPrescription::getPage($params,$fields); + } +} \ No newline at end of file diff --git a/app/Services/PatientCaseService.php b/app/Services/PatientCaseService.php new file mode 100644 index 0000000..cefe17d --- /dev/null +++ b/app/Services/PatientCaseService.php @@ -0,0 +1,70 @@ +request->route('family_id'); + + $user_info = $this->request->getAttribute("userInfo") ?? []; + + // 查询该家庭成员是否存在问诊记录 + $order_inquiry_params = array(); + $order_inquiry_params['patient_id'] = $user_info['client_user_id']; + $order_inquiry_params['family_id'] = $family_id; + $order_inquiry_params['inquiry_status'] = 6;// 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) + $order_inquiry_params['inquiry_refund_status'] = 0; + + // 查询该家庭成员最后一次已完成的问诊病例 + $params = array(); + $params['patient_id'] = $user_info['client_user_id']; + $params['family_id'] = $family_id; + $params['status'] = 1; + $order_inquiry_case = OrderInquiryCase::getEndOrderInquiryCaseOne($params,$order_inquiry_params); + + if (!empty($order_inquiry_case)){ + if (!empty($order_inquiry_case['OrderInquiry'])){ + if ($order_inquiry_case['OrderInquiry']['inquiry_type'] == 4){ + // 问诊购药存在用药意向 + $params = array(); + $params['inquiry_case_id'] = $order_inquiry_case['inquiry_case_id']; + $inquiry_case_product = InquiryCaseProduct::getWithProductList($params); + if (!empty($inquiry_case_product)){ + foreach ($inquiry_case_product as &$item){ + if (!empty($item['Product'])){ + $item['product_name'] = $item['Product']['product_name']; + $item['product_price'] = $item['Product']['product_price']; + $item['product_type'] = $item['Product']['product_type']; + $item['product_cover_img'] = $item['Product']['product_cover_img']; + $item['product_spec'] = $item['Product']['product_spec']; + $item['license_number'] = $item['Product']['license_number']; + $item['manufacturer'] = $item['Product']['manufacturer']; + $item['packaging_unit'] = $item['Product']['packaging_unit']; + + unset($item['Product']); + } + } + } + } + unset($order_inquiry_case['OrderInquiry']); + } + } + + $order_inquiry_case['Product'] = $inquiry_case_product ?? []; + + return empty($order_inquiry_case) ? success() : success($order_inquiry_case->toArray()); + } +} \ No newline at end of file diff --git a/app/Services/PatientDoctorService.php b/app/Services/PatientDoctorService.php new file mode 100644 index 0000000..03ddb16 --- /dev/null +++ b/app/Services/PatientDoctorService.php @@ -0,0 +1,371 @@ +request->input('expertise_id'); + $province_id = $this->request->input('province_id'); + $city_id = $this->request->input('city_id'); + $sort_order = $this->request->input('sort_order'); + $keyword = $this->request->input('keyword'); + + // 组合条件 + $hospital_params = array();// 医院搜索 + $doctor_params = array();// 医生搜索 + $doctor_expertise_params = array();// 医生专长搜索 + + // 省市区 + if (!empty($province_id) ){ + if (empty($city_id)){ + // 省份存在时需和城市在一块 + return fail(HttpEnumCode::CLIENT_HTTP_ERROR); + } + $hospital_params[] = ['province_id','=',$province_id]; + $hospital_params[] = ['city_id','=',$city_id]; + } + + // 医生专长 + if (!empty($expertise_id)){ + $doctor_expertise_params['expertise_id'] = $expertise_id; + } + + // 固定医生查询条件 + $doctor_params['status'] = 1; // 状态(0:禁用 1:正常 2:删除) + + $doctor_params["iden_auth_status"] = 1;// 身份认证状态(0:未认证 1:认证通过 2:审核中 3:认证失败) + + $doctor_params["is_online"] = 1;// 是否在线(0:不在线 1:在线) + + $doctor_params["is_img_expert_reception"] = 1;// 是否参加专家图文接诊(0:否 1:是) + + $fields = [ + "doctor_id", + "user_id", + "user_name", + "open_id", + "status", + "iden_auth_status", + "multi_point_status", + "is_bind_bank", + "is_recommend", + "sex", + "age", + "avatar", + "doctor_title", + "department_custom_id", + "department_custom_name", + "hospital_id", + "hospital_name", + "served_patients_num", + "praise_rate", + "avg_response_time", + "number_of_fans", + "is_online", + "is_img_expert_reception", + "is_img_welfare_reception", + "is_platform_deep_cooperation", + "be_good_at", + ]; + + $user_doctors = UserDoctor::getInquiryDoctorPage($keyword,$hospital_params,$doctor_params,$doctor_expertise_params,$sort_order,$fields); + + // 处理数据 + if (!empty($user_doctors['data'])){ + foreach ($user_doctors['data'] as &$user_doctor){ + $user_doctor['doctor_title_name'] = empty($user_doctor['doctor_title']) ? "" : DoctorTitleCode::getMessage($user_doctor['doctor_title']); + + // 医生专长 + if (!empty($user_doctor['DoctorExpertise'])){ + foreach ($user_doctor['DoctorExpertise'] as &$data){ + if (!empty($data['DiseaseClassExpertise'])){ + $data['expertise_name'] = $data['DiseaseClassExpertise']['expertise_name']; + } + unset($data['DiseaseClassExpertise']); + } + } + + // 问诊价格 + $user_doctor['price'] = 0; + $user_doctor['free_clinic_price'] = 0; + if (!empty($user_doctor['DoctorInquiryConfig'])){ + foreach ($user_doctor['DoctorInquiryConfig'] as $doctor_inquiry_config) { + if ($doctor_inquiry_config['inquiry_mode'] == 1){ + if ($doctor_inquiry_config['inquiry_type'] == 1) { + // 专家 + $user_doctor['price'] = $doctor_inquiry_config['inquiry_price'] ?? 0; + } + if ($doctor_inquiry_config['inquiry_type'] == 3) { + // 公益 + $user_doctor['free_clinic_price'] = $doctor_inquiry_config['inquiry_price']; + } + } + } + unset($user_doctor['DoctorInquiryConfig']); + } + + // 好评率-超过5个已结束的订单后展示 + $user_doctor['praise_rate'] = ceil($user_doctor['praise_rate'] * 0.05 * 100) / 100; + // 响应时间-超过5个已结束的订单后展示 + $user_doctor['avg_response_time'] = ceil($user_doctor['avg_response_time'] * 0.05 * 100) / 100 * 60; + + // 获取医生订单数 + $params = array(); + $params['doctor_id'] = $user_doctor['doctor_id']; + $params['inquiry_status'] = 6; // 已结束 + $inquiry_order_count = OrderInquiry::getCount($params); + if (empty($inquiry_order_count) || $inquiry_order_count == 0){ + $user_doctor['is_display_score'] = false; + }else{ + $user_doctor['is_display_score'] = true; + } + } + } + return success($user_doctors); + } + + /** + * 获取问诊医生详情 + * @return array + */ + public function getInquiryDoctorInfo(): array + { + $doctor_id = $this->request->route('doctor_id'); + + $user_info = $this->request->getAttribute("userInfo") ?? []; + + $result = array(); + $result['hospital'] = []; + $result['days'] = 0; + $result['doctor_inquiry_config'] = []; + + $fields = [ + "doctor_id", + "user_id", + "user_name", + "open_id", + "status", + "iden_auth_status", + "multi_point_status", + "is_bind_bank", + "is_recommend", + "sex", + "age", + "avatar", + "doctor_title", + "department_custom_id", + "department_custom_name", + "hospital_id", + "served_patients_num", + "praise_rate", + "avg_response_time", + "number_of_fans", + "is_online", + "is_img_expert_reception", + "is_img_welfare_reception", + "is_platform_deep_cooperation", + "be_good_at", + ]; + + $params = array(); + $params['doctor_id'] = $doctor_id; + $params['status'] = 1; // 状态(0:禁用 1:正常 2:删除) + $params["iden_auth_status"] = 1;// 身份认证状态(0:未认证 1:认证通过 2:审核中 3:认证失败) + $user_doctor = UserDoctor::getOne($params,$fields); + if (empty($user_doctor)){ + return fail(HttpEnumCode::HTTP_SUCCESS,"医生错误"); + } + + $result = $user_doctor->toArray(); + + $result['doctor_title_name'] = empty($user_doctor['doctor_title']) ? "" : DoctorTitleCode::getMessage($user_doctor['doctor_title']); + + $result['hospital'] = []; + $result['days'] = 0; + $result['doctor_inquiry_config'] = 0; + + // 获取医生医院数据 + $fields = [ + 'hospital_id', + 'hospital_name', + 'hospital_level_name', + ]; + + $params = array(); + $params['hospital_id'] = $user_doctor['hospital_id']; + $hospital = Hospital::getOne($params,$fields); + if (!empty($hospital)){ + $result['hospital'] = $hospital; + } + + // 获取服务天数 + $params = array(); + $params['patient_id'] = $user_info['client_user_id']; + $params['doctor_id'] = $doctor_id; + $params['history_status'] = 1; + $patient_history_doctor = PatientHistoryInquiryModel::getOne($params); + // 按照天来计算,当日为1,前一天为2 未服务过为0 + if (!empty($patient_history_doctor['created_at'])) { + $result['days'] = ceil((strtotime(date('Y-m-d', strtotime('+1 day'))) - strtotime($patient_history_doctor['created_at'])) / 86400); + } + + // 获取关注状态 + $params = array(); + $params['patient_id'] = $user_info['client_user_id']; + $params['doctor_id'] = $doctor_id; + $result['follow'] = PatientFollow::getExists($params); + + // 获取问诊价格 + // 专家-公益 + $params = array(); + $params[] = ['doctor_id','=',$doctor_id]; + $params[] = ['inquiry_mode','=',1];// 接诊方式(1:图文 2:视频 3:语音 4:电话 5:会员) + $doctor_inquiry_config = DoctorInquiryConfigModel::getInquiryConfigList($params); + if (!empty($doctor_inquiry_config)){ + foreach ($doctor_inquiry_config as &$value){ + // 获取医生当日已付款的全部订单 + $params = array(); + $params[] = ['doctor_id','=',$doctor_id]; + $params[] = ['inquiry_type','=',$value['inquiry_type']]; + $params[] = ['inquiry_mode','=',1]; + $params[] = ['inquiry_status','=',3]; + $params[] = ['inquiry_refund_status','=',0]; + $value['order_inquiry_count'] = OrderInquiry::getCount($params); + + unset($value['SystemInquiryConfig']); + } + $result['doctor_inquiry_config'] = $doctor_inquiry_config; + } + + // 好评率-超过5个已结束的订单后展示 + $result['praise_rate'] = ceil($user_doctor['praise_rate'] * 0.05 * 100) / 100; + // 响应时间-超过5个已结束的订单后展示 + $result['avg_response_time'] = ceil($user_doctor['avg_response_time'] * 0.05 * 100) / 100 * 60; + + $params = array(); + $params['doctor_id'] = $user_doctor['doctor_id']; + $params['inquiry_status'] = 6; // 已结束 + $inquiry_order_count = OrderInquiry::getCount($params); + if (empty($inquiry_order_count) || $inquiry_order_count == 0){ + $result['is_display_score'] = false; + }else{ + $result['is_display_score'] = true; + } + + return success($result); + } + + /** + * 获取医生评价 + * @return array + */ + public function getDoctorEvaluationList(): array + { + $doctor_id = $this->request->input('doctor_id'); + $page = $this->request->input('page', 1); + $per_page = $this->request->input('per_page', 10); + + $user_info = $this->request->getAttribute("userInfo") ?? []; + + $params = array(); + $params['doctor_id'] = $doctor_id; + $params['status'] = 1; // 状态(0:禁用 1:正常 2:删除) + $params["iden_auth_status"] = 1;// 身份认证状态(0:未认证 1:认证通过 2:审核中 3:认证失败) + $user_doctor = UserDoctor::getOne($params); + if (empty($user_doctor)){ + return fail(HttpEnumCode::CLIENT_HTTP_ERROR); + } + + $params = array(); + $params['doctor_id'] = $doctor_id; + $order_evaluation = OrderEvaluation::getPage($params); + + if (!empty($order_evaluation['data'])){ + foreach ($order_evaluation['data'] as &$data){ + // 处理综合评分 + if ($data['avg_score'] != 0){ + $data['avg_score'] = ceil($data['avg_score'] * 0.05 * 100) / 100; + } + } + } + + return $order_evaluation; + } + + /** + * 医生详情简介-详情中的简介 + * @return array + */ + public function getDoctorProfile(): array + { + $doctor_id = $this->request->route('doctor_id'); + + $user_info = $this->request->getAttribute("userInfo") ?? []; + + $fields = [ + "doctor_id", + "user_id", + "user_name", + "status", + "iden_auth_status", + "avatar", + "doctor_title", + "department_custom_name", + "hospital_id", + "hospital_name", + "be_good_at", + "brief_introduction", + ]; + + $params = array(); + $params['doctor_id'] = $doctor_id; + $params['status'] = 1; // 状态(0:禁用 1:正常 2:删除) + $params["iden_auth_status"] = 1;// 身份认证状态(0:未认证 1:认证通过 2:审核中 3:认证失败) + $user_doctor = UserDoctor::getOne($params,$fields); + if (empty($user_doctor)){ + return fail(HttpEnumCode::CLIENT_HTTP_ERROR); + } + + $user_doctor = $user_doctor->toArray(); + + $user_doctor['doctor_title_name'] = empty($user_doctor['doctor_title']) ? "" : DoctorTitleCode::getMessage($user_doctor['doctor_title']); + + // 获取医生医院数据 + $fields = [ + 'hospital_id', + 'hospital_name', + 'hospital_level_name', + ]; + + $params = array(); + $params['hospital_id'] = $user_doctor['hospital_id']; + $hospital = Hospital::getOne($params,$fields); + if (!empty($hospital)){ + $user_doctor['hospital'] = $hospital; + } + + // 获取医生已选择专长 + $UserDoctorService = new UserDoctorService(); + $user_doctor['doctor_expertise'] = $UserDoctorService->getDoctorSelectedExpertise($doctor_id); + + return success($user_doctor); + } +} \ No newline at end of file diff --git a/app/Services/PatientFamilyService.php b/app/Services/PatientFamilyService.php new file mode 100644 index 0000000..db8d334 --- /dev/null +++ b/app/Services/PatientFamilyService.php @@ -0,0 +1,215 @@ +request->getAttribute("userInfo") ?? []; + + $params = array(); + $params['patient_id'] = $user_info['client_user_id']; + $params['status'] = 1; + + $field = [ + 'family_id', + 'patient_id', + 'relation', + 'is_default', + 'card_name', + 'card_name_mask', + 'sex', + 'age', + ]; + $patient_familys = PatientFamilyModel::getList($params, $field); + + return empty($patient_familys) ? success() : success($patient_familys->toArray()); + } + + /** + * 新增家庭成员 + * @return array + */ + public function addFamily(): array + { + + $user_info = $this->request->getAttribute("userInfo") ?? []; + + $request_params = $this->request->all(); + + // 获取全部家庭成员 + $params = array(); + $params['patient_id'] = $user_info['client_user_id']; + $params['status'] = 1; + $patient_familys = PatientFamilyModel::getList($params); + if (!empty($patient_familys)) { + foreach ($patient_familys as $patient_family) { + // 检测该家庭成员是否已存在 + if ($patient_family['type'] == $request_params['type'] && $patient_family['id_number'] == $request_params['id_number']) { + return fail(HttpEnumCode::HTTP_ERROR, "证件号码重复"); + } + + // 检测姓名是否重复 + if ($patient_family['card_name'] == $request_params['card_name']) { + return fail(HttpEnumCode::HTTP_ERROR, "姓名重复"); + } + + // 检测是否默认字段是否重复 + if (isset($request_params['is_default'])) { + if ($request_params['is_default'] == 1 && $patient_family['is_default'] == 1) { + // 记录原默认id + $is_default_id = $patient_family['family_id']; + } + } + } + } + + // 检测省市区 + if (!empty($request_params['county_id']) ){ + if (empty($request_params['city_id']) || empty($request_params['province_id'])){ + // 区县存在时需和城市、省份在一块 + return fail(HttpEnumCode::CLIENT_HTTP_ERROR); + } + } + + if (!empty($request_params['city_id']) ){ + if (empty($request_params['province_id'])){ + // 城市存在时需和省份在一块 + return fail(HttpEnumCode::CLIENT_HTTP_ERROR); + } + } + + if (!empty($request_params['province_id'])){ + $areaService = new AreaService(); + $req = $areaService->checkAreaById($request_params['province_id'],$request_params['city_id'],$request_params['county_id']); + if(empty($req)){ + return fail(HttpEnumCode::HTTP_ERROR,"地区选择错误"); + } + } + + if ($request_params['type'] == 1) { + // 解析年龄、性别字段 + $age = getIdCardAge($this->request->input('id_number')); + + $sex = getIdCardSex($this->request->input('id_number')); + } + + // 民族 + if (!empty($request_params['nation_id'])){ + $params = array(); + $params['nation_id'] = $request_params['nation_id']; + $nation = BasicNation::getOne($params); + if (empty($nation)){ + return fail(HttpEnumCode::HTTP_ERROR,"民族选择错误"); + } + } + + // 职业 + if (!empty($request_params['job_id'])){ + $params = array(); + $params['job_id'] = $request_params['job_id']; + $job = BasicJob::getOne($params); + if (empty($job)){ + return fail(HttpEnumCode::HTTP_ERROR,"职位选择错误"); + } + } + + // 实人认证-生产环境开启 + if (env("APP_ENV") == "prod"){ + $IdCard = new IdCard(); + + $params =array(); + $params['name'] = $request_params['card_name']; + $params['cardNo'] = $request_params['id_number']; + $res = $IdCard->checkIdCard($params); + if (!empty($res)){ + return fail(HttpEnumCode::HTTP_ERROR,$res); + } + } + + Db::beginTransaction(); + + try { + // 修改是否默认 + if (isset($is_default_id)) { + $params = array(); + $params['family_id'] = $is_default_id; + + $data = array(); + $data['is_default'] = 0; + $data['updated_at'] = date('Y-m-d H:i:s', time()); + $res = PatientFamilyModel::edit($params, $data); + if (!$res) { + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR); + } + } + + // 新增 患者家庭成员信息表-基本信息(patient_family) + $data = array(); + $data['patient_id'] = $user_info['client_user_id']; + $data['relation'] = $request_params['relation']; + $data['status'] = 1; + $data['is_default'] = empty($request_params['is_default']) ? 0 : 1; + $data['card_name'] = $request_params['card_name']; + $data['card_name_mask'] = Mask::maskNameStr($request_params['card_name']); + $data['mobile'] = $request_params['mobile']; + $data['mobile_mask'] = Mask::maskPhoneStr($request_params['mobile']); + $data['type'] = $request_params['type']; + $data['id_number'] = $request_params['id_number']; + $data['sex'] = $sex ?? 0; + $data['age'] = empty($age) ? null : $age; + + if (isset($area)) { + $data['province_id'] = $request_params['province_id']; + $data['province'] = $area['province']['area_name']; + + $data['city_id'] = $request_params['city_id']; + $data['city'] = $area['city']['area_name']; + + $data['county_id'] = $request_params['county_id']; + $data['county'] = $area['county']['area_name']; + } + + $data['marital_status'] = $request_params['marital_status'] ?? 0; + $data['nation_id'] = $request_params['nation_id'] ?? null; + $data['nation_name'] = $nation['nation_name'] ?? ""; + $data['job_id'] = $request_params['job_id'] ?? null; + $data['job_name'] = $job['job_name'] ?? ""; + + $patient_family = PatientFamilyModel::addPatientFamily($data); + if (empty($patient_family)) { + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR); + } + + Db::commit(); + } catch (\Exception $e) { + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage()); + } + + $result = array(); + $result['family_id'] = $patient_family['family_id']; + return success($result); + } + + +} \ No newline at end of file diff --git a/app/Services/SafeService.php b/app/Services/SafeService.php new file mode 100644 index 0000000..25cf863 --- /dev/null +++ b/app/Services/SafeService.php @@ -0,0 +1,50 @@ +request->input('user_type'); + $user_info = $this->request->getAttribute("userInfo") ?? []; + + if (empty($user_info)){ + return fail(); + } + + if ($user_type == 1){ + $dir = "applet/patient/"; + }elseif ($user_type == 2){ + $dir = "applet/doctor/"; + }elseif ($user_type == 3){ + $dir = "applet/pharmacist/"; + } + + // 获取用户数据 + $params = array(); + $params['user_id'] = $user_info['user_id']; + $user = UserModel::getOne($params); + if (empty($user)){ + return fail(); + } + + if ($user['user_type'] != $user_info['user_type']){ + return fail(); + } + + $oss = new Oss(); + + return success($oss->signature($dir)); + } +} \ No newline at end of file diff --git a/app/Services/UserDoctorService.php b/app/Services/UserDoctorService.php new file mode 100644 index 0000000..b9d7e42 --- /dev/null +++ b/app/Services/UserDoctorService.php @@ -0,0 +1,76 @@ +request->getAttribute("userInfo") ?? []; + + // 获取医生已选择专长 + $doctor_selected_expertise = $this->getDoctorSelectedExpertise($user_info['client_user_id']); + + $expertise_ids = []; + + if (!empty($doctor_selected_expertise)){ + $expertise_ids = array_column($doctor_selected_expertise,'expertise_id'); + } + + // 获取全部专长 + $fields = [ + 'expertise_id', + 'expertise_name', + 'expertise_sort', + ]; + $disease_class_expertise = DiseaseClassExpertise::getOrderList([],$fields); + + foreach ($disease_class_expertise as &$item){ + $item['is_selected'] = 0; + if (in_array($item['expertise_id'],$expertise_ids)){ + $item['is_selected'] = 1; + } + } + + return success($disease_class_expertise); + } + + + /** + * 获取医生已选择专长 + * @param string $doctor_id + * @return array + */ + public function getDoctorSelectedExpertise(string $doctor_id): array + { + if (empty($doctor_id)){ + throw new BusinessException("缺少医生id"); + } + + $params = array(); + $params['doctor_id'] = $doctor_id; + $doctor_expertise = DoctorExpertise::getDiseaseClassExpertiseList($params); + if (!empty($doctor_expertise)){ + foreach ($doctor_expertise as &$data){ + if (!empty($data['DiseaseClassExpertise'])){ + $data['expertise_name'] = $data['DiseaseClassExpertise']['expertise_name']; + } + unset($data['DiseaseClassExpertise']); + } + } + + return $doctor_expertise->toArray(); + } +} \ No newline at end of file diff --git a/app/Services/UserPatientService.php b/app/Services/UserPatientService.php new file mode 100644 index 0000000..5c74521 --- /dev/null +++ b/app/Services/UserPatientService.php @@ -0,0 +1,10 @@ +whiteApi = [ + "/" => "*", + "/patient/index" => "get", + "/login/wechat_mobile_login" => "post", + "/login/mobile_login" => "post", + "/code/phone" => "post", + "/disease/expertise" => "get", + "/area/province" => "get", + "/area/city" => "get", + "/area/county" => "get", + ]; + } + + /** + * 检测接口白名单 + * @param string $path_info 请求地址 /v1/user/info + * @param string $method 请求方式 POST + * @return bool true:在白名单 false:不在白名单 + */ + public function checkApiWhiteList(string $path_info,string $method): bool + { + // 版本白名单-app使用 + /*$version_white_list = config('jwt.version_white_list', []); + if (!empty($version_white_list)) { + foreach ($version_white_list as $value) { + $req = substr_compare($path_info,"/" . $value,0,strlen($value)); + if ($req === 0){ + return true; + } + } + }*/ + + if(!empty($this->whiteApi)){ + if (array_key_exists($path_info, $this->whiteApi)) { + if ($this->whiteApi[$path_info] == '*') { + return true; + } + if (stristr($this->whiteApi[$path_info], $method)) { + return true; + } + } + } + + return false; + } + + /** + * 检测token的快过期时间. + * @param array $token token + */ + public function checkTokenExpTime(array $token): bool + { + $time_difference = $token['exp'] - time(); + + // 设定24小时过期时间 + if ($time_difference < (3600 * 24)) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/app/Utils/Data.php b/app/Utils/Data.php new file mode 100644 index 0000000..1f9e29c --- /dev/null +++ b/app/Utils/Data.php @@ -0,0 +1,125 @@ +container->get(IdGeneratorInterface::class); + + $params = array(); + $params['prov_name'] = "贵州省"; + $hospital = TbHospitalMy::getList($params); + foreach ($hospital as $key => $value) { + $params = array(); + $params['hospital_name'] = $value['name']; + $params['province'] = $value['prov_name']; + $params['city'] = $value['city_name']; + $res = Hospital::getOne($params); + if(!empty($res)){ + dump("重复-跳过-".$value['name']); + $params = array(); + $params['id'] = $value['id']; + $res = Db::table('tb_hospital_my')->where($params)->delete(); + if (!$res) { + return "删除错误"; + } + continue; + } + + $data = array(); + $data['hospital_id'] = $generator->generate();; + $data['hospital_name'] = $value['name']; + $data['hospital_status'] = 1; + + if ($value['level'] == 0){ + $data['hospital_level_name'] = "未知"; + }elseif ($value['level'] == 1){ + $data['hospital_level_name'] = "三甲"; + }elseif ($value['level'] == 2){ + $data['hospital_level_name'] = "三级"; + }elseif ($value['level'] == 3){ + $data['hospital_level_name'] = "二级"; + }elseif ($value['level'] == 4){ + $data['hospital_level_name'] = "其他"; + }else{ + continue; + } + + $data['post_code'] = $value['postcode']; + $data['tele_phone'] = $value['office_phone']; + $data['lat'] = $value['lat']; + $data['lng'] = $value['lng']; + $data['desc'] = $value['info']; + $data['created_at'] = date('Y-m-d H:i:s',time()); + $data['updated_at'] = date('Y-m-d H:i:s',time()); + + // 省 + $params = array(); + $params['area_name'] = $value['prov_name']; + $province = Area::getOne($params); + if(empty($province)){ + dump("省份-未知-".$value['prov_name']); + continue; + }else{ + $data['province_id'] = $province['area_id']; + $data['province'] = $province['area_name']; + } + + // 市 + $params = array(); + $params['area_name'] = $value['city_name']; + $params['parent_id'] = $province['area_id']; + $city = Area::getOne($params); + if(empty($city)){ + dump("市区-未知-".$value['city_name']); + continue; + }else{ + $data['city_id'] = $city['area_id']; + $data['city'] = $city['area_name']; + } + + $params = array(); + $params['area_name'] = $value['county_name']; + $params['parent_id'] = $city['area_id']; + $county = Area::getOne($params); + if(empty($county)){ + dump("区县-未知-".$value['county_name']); + continue; + }else{ + $data['county_id'] = $county['area_id']; + $data['county'] = $county['area_name']; + } + + $data['address'] = $value['address']; + + $res = Hospital::addHospital($data); + if (empty($res)) { + dump("添加-失败-跳过"); + continue; + } + + $params = array(); + $params['id'] = $value['id']; + $res = Db::table('tb_hospital_my')->where($params)->delete(); + if (!$res) { + return "删除错误"; + } + } + + return success(); + } +} \ No newline at end of file diff --git a/app/Utils/Http.php b/app/Utils/Http.php new file mode 100644 index 0000000..893f5de --- /dev/null +++ b/app/Utils/Http.php @@ -0,0 +1,33 @@ +request->getServerParams(); + if (isset($res['http_client_ip'])) { + return $res['http_client_ip']; + } elseif (isset($res['http_x_real_ip'])) { + return $res['http_x_real_ip']; + } elseif (isset($res['http_x_forwarded_for'])) { + //部分CDN会获取多层代理IP,所以转成数组取第一个值 + $arr = explode(',', $res['http_x_forwarded_for']); + return $arr[0]; + } else { + return $res['remote_addr']; + } + } +} \ No newline at end of file diff --git a/app/Utils/HttpRequest.php b/app/Utils/HttpRequest.php new file mode 100644 index 0000000..b317795 --- /dev/null +++ b/app/Utils/HttpRequest.php @@ -0,0 +1,37 @@ +client->post($path, $option); + + if ($response->getStatusCode() != '200'){ + // 请求失败 + throw new BusinessException(HttpEnumCode::SERVER_ERROR,$response->getBody()->getContents()); + } + + return json_decode($response->getBody(),true); + } +} \ No newline at end of file diff --git a/app/Utils/Jwt.php b/app/Utils/Jwt.php new file mode 100644 index 0000000..681e23a --- /dev/null +++ b/app/Utils/Jwt.php @@ -0,0 +1,60 @@ + 'gdxz', + 'iat' => $time, + 'nbf' => $time, + 'exp' => $time + $expire, + 'userInfo' => $data, + ]; + // token_type:bearer + return \Firebase\JWT\JWT::encode($payload, $secret, $algo); + } + + /** + * 解码jwttoken + * @param string $token token数据,不卸载bearer + * @return array + */ + public function decode(string $token): array + { + $secret = config('jwt.secret'); + try { + $jwt = json_decode(json_encode(\Firebase\JWT\JWT::decode($token, new Key($secret, 'HS256'))), true); // 解密jwt + + } catch (SignatureInvalidException $e) { + // 签名不正确 + throw new BusinessException( $e->getMessage(),HttpEnumCode::TOKEN_ERROR); + + } catch (ExpiredException|\UnexpectedValueException|\InvalidArgumentException $e) { + // token过期 + throw new BusinessException( $e->getMessage(),HttpEnumCode::TOKEN_EXPTIRED); + + } catch (\Throwable $e) { + // 其他错误: + throw new BusinessException( $e->getMessage()); + } + + return $jwt; + } +} \ No newline at end of file diff --git a/app/Utils/Log.php b/app/Utils/Log.php new file mode 100644 index 0000000..e9a4033 --- /dev/null +++ b/app/Utils/Log.php @@ -0,0 +1,32 @@ +{$name}(...$arguments); + } + + public static function getInstance(string $name = 'app'): LoggerInterface + { + return ApplicationContext::getContainer()->get(LoggerFactory::class)->get($name); + } +} diff --git a/app/Utils/Mask.php b/app/Utils/Mask.php new file mode 100644 index 0000000..799c889 --- /dev/null +++ b/app/Utils/Mask.php @@ -0,0 +1,106 @@ += 3){ + //三个字符或三个字符以上掐头取尾,中间用*代替 + $str = mb_substr($str, 0, 1, 'UTF-8') . '*' . mb_substr($str, -1, 1, 'UTF-8'); + } elseif($len == 2) { + //两个字符 + $str = mb_substr($str, 0, 1, 'UTF-8') . '*'; + } + } elseif(preg_match("/[A-Za-z]/", $str)) { + //按照英文字串计算长度 + $len = mb_strlen($str); + //echo 'English'; + if($len >= 3) { + //三个字符或三个字符以上掐头取尾,中间用*代替 + $str = mb_substr($str, 0, 1) . '*' . mb_substr($str, -1); + } elseif($len == 2) { + //两个字符 + $str = mb_substr($str, 0, 1) . '*'; + } + } + return $str; + } + /* + * 手机号、固话加密 + * 示例: + * 固话:0510-89754815 0510-8****815 + * 手机号:18221234158 18*******58 + * */ + public static function maskPhoneStr($phone) + { + if (empty($phone)){ + return $phone; + } + + $IsWhat = preg_match('/(0[0-9]{2,3}[\-]?[2-9][0-9]{6,7}[\-]?[0-9]?)/i',$phone); //固定电话 + if($IsWhat == 1){ + return preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i','$1****$2',$phone); + }else{ + return preg_replace('/(1[0-9]{1})[0-9]{7}([0-9]{2})/i','$1*******$2',$phone); + } + } + /* + * 地址中夹带数字加密 + * 示例: + * 北京市124Ff:北京市***Ff + * */ + public static function maskAddressStr($address) + { + if (empty($address)){ + return $address; + } + + $address = mb_convert_encoding( $address , 'UTF-8', 'auto' ); + $pattern = '/[0-9]/'; + if(preg_match_all($pattern, $address, $match)){ + return str_replace($match[0],'*',$address); + }else{ + return $address; + } + } + + /** + * 身份证掩码 + * 示例: + * 372929199610075411:372929****5411 + * @param string $card_num + * @return string + */ + public static function maskIdCard(string $card_num): string + { + if (empty($card_num)){ + return $card_num; + } + + $result = preg_replace('/(\\w{6})(\\w+)(\\w{4})/','$1****$3',$card_num); + if (empty($result)){ + return $card_num; + } + + return $result; + } +} \ No newline at end of file diff --git a/app/Utils/PcreMatch.php b/app/Utils/PcreMatch.php new file mode 100644 index 0000000..827bbe6 --- /dev/null +++ b/app/Utils/PcreMatch.php @@ -0,0 +1,64 @@ +redis = $container->get(Redis::class); + + // 请求地址 + $this->api_url = "http://49.233.3.200:6304/api/thridapi/"; + $this->client_id = "ZD-004"; + $this->client_secret = "0baa5927164710b9f800bf33546b6da3"; + + // 启动时redis已注入,此处不会出现问题。 + $this->access_token = $this->redis->get("prescription_token"); + if (empty($access_token)){ + $this->access_token = $this->getToken(); + } + + $this->header = [ + "Authorization" => "Bearer " . $this->access_token + ]; + } + + /** + * 获取token接口 + * @return string token数据 + */ + protected function getToken(): string + { + $option = [ + "json" => array( + "clientId" => $this->client_id, + "clientSecret" => $this->client_secret, + ) + ]; + + try { + $response = $this->httpRequest($this->api_url . $this->version . '/user_thrid/token', $option); + + if (empty($response['result'])){ + // 返回值为空 + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); + } + + if (empty($response['result']['token'])){ + // 返回值为空 + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); + } + + } catch (GuzzleException $e) { + throw new BusinessException($e->getMessage()); + } + + return $response['result']['token']; + } + + // 获取药品 + public function getProd(){ + $option = [ + "json" => array( + "page" => 1, + "pageSize" => 1, + ), + "headers" => $this->header + ]; + + try { + $response = $this->httpRequest($this->api_url . $this->version . '/drug/syncDrugCatalogue', $option); + if (empty($response['result'])){ + // 返回值为空 + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); + } + + if (empty($response['result']['rows'])){ + return true; + } + dump($response); + // 获取总数 +// $count + } catch (GuzzleException $e) { + throw new BusinessException($e->getMessage()); + } + +// return $response['token']; + } + + // 查询商品库存 + public function getProdStock(){ + $option = [ + "json" => array( + "pharmacyCode" => "JG-10009", + "drugCode" => "105860", + ), + "headers" => $this->header + ]; + + try { + $response = $this->httpRequest($this->api_url . $this->version . '/pharmacy/pharmacyInventory', $option); + dump($response); + + } catch (GuzzleException $e) { + throw new BusinessException($e->getMessage()); + } + } + + // 获取运费 + public function getExpressPrice(){ + $option = [ + "json" => array( + "pharmacyCode" => "JG-10009", + ), + "headers" => $this->header + ]; + + try { + $response = $this->httpRequest($this->api_url . $this->version . '/pharmacy/transportationExpenses', $option); + dump($response); + + } catch (GuzzleException $e) { + throw new BusinessException($e->getMessage()); + } + } + + /** + * 请求封装 + * @param string $path + * @param array $option + * @return array + * @throws GuzzleException + */ + protected function httpRequest(string $path,array $option = []): array + { + $response = $this->client->post($path, $option); + + if ($response->getStatusCode() != '200'){ + // 请求失败 + throw new BusinessException($response->getBody()->getContents()); + } + + $body = json_decode($response->getBody(),true); + if (empty($body)){ + // 返回值为空 + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); + } + dump($body); + + if (empty($body['data'])){ + // 返回值为空 + if (!empty($body['message'])){ + throw new BusinessException($body['message']); + } + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); + } + + return $body['data']; + } +} \ No newline at end of file diff --git a/app/Utils/WeChat.php b/app/Utils/WeChat.php new file mode 100644 index 0000000..fa5135c --- /dev/null +++ b/app/Utils/WeChat.php @@ -0,0 +1,135 @@ +config = config("easy_we_chat"); + + try { + // 获取WeChat客户端 + $this->app = new Application($this->config); + + // 替换缓存 + $this->app->setCache(ApplicationContext::getContainer()->get(CacheInterface::class)); + + $this->client = $this->app->getClient(); + + } catch (InvalidArgumentException $e) { + throw new BusinessException('实例化EasyWeChat类失败:' . $e->getMessage(), HttpEnumCode::SERVER_ERROR); + } + } + + /** + * 根据 jsCode 获取用户 session 信息 + * @param string $code code + * @return array + * @throws ClientExceptionInterface + * @throws DecodingExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ServerExceptionInterface + * @throws TransportExceptionInterface + * @throws \Exception + */ + public function codeToSession(string $code): array + { + try { + $utils = $this->app->getUtils(); + return $utils->codeToSession($code); + } catch (\Exception $e) { + throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR); + } + } + + /** + * 解密微信会话信息 + * @param string $sessionKey 会话密钥 + * @param string $iv 加密算法的初始向量 + * @param string $encryptedData 用户信息的加密数据 + * @return array + */ + public function decryptSession(string $sessionKey, string $iv, string $encryptedData): array + { + try { + $utils = $this->app->getUtils(); + return $utils->decryptSession($sessionKey, $iv, $encryptedData); + } catch (\Exception $e) { + throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR); + } + } + + /** + * 获取 access_token + * @return string + */ + public function getAccessToken(): string + { + try { + $accessToken = $this->app->getAccessToken(); + return $accessToken->getToken(); + } catch (\Exception $e) { + throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR); + } + } + + /** + * 获取手机号 + * @param string $code + * @return array + * @throws ClientExceptionInterface + * @throws DecodingExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ServerExceptionInterface + * @throws TransportExceptionInterface|BadResponseException + */ + public function getPhone(string $code): array + { + $options = [ + "code" => $code, + ]; + $response = $this->client->postJson('wxa/business/getuserphonenumber', $options); + if ($response->isFailed()) { + // 出错了,处理异常 + $result = $response->toArray(); + if(empty($result)){ + throw new BusinessException( $response->toJson(false),HttpEnumCode::GET_WX_ERROR); + } + if (isset($result['errcode'])){ + if ($result['errcode'] == "40029"){ + // code过期 + throw new BusinessException( HttpEnumCode::getMessage(HttpEnumCode::GET_WX_ERROR),HttpEnumCode::WX_CODE_ERROR); + } + } + throw new BusinessException( $response->toJson(false),HttpEnumCode::GET_WX_ERROR); + } + return $response->toArray(false); + } +} \ No newline at end of file diff --git a/bin/hyperf.php b/bin/hyperf.php new file mode 100644 index 0000000..b89f93a --- /dev/null +++ b/bin/hyperf.php @@ -0,0 +1,30 @@ +#!/usr/bin/env php +get(Hyperf\Contract\ApplicationInterface::class); + $application->run(); +})(); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..33b8815 --- /dev/null +++ b/composer.json @@ -0,0 +1,92 @@ +{ + "name": "hyperf/hyperf-skeleton", + "type": "project", + "keywords": [ + "php", + "swoole", + "framework", + "hyperf", + "microservice", + "middleware" + ], + "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.", + "license": "Apache-2.0", + "require": { + "php": ">=8.0", + "alibabacloud/dysmsapi-20170525": "2.0.23", + "aliyuncs/oss-sdk-php": "^2.6", + "firebase/php-jwt": "^6.3", + "hyperf/amqp": "~3.0.0", + "hyperf/async-queue": "~3.0.0", + "hyperf/cache": "~3.0.0", + "hyperf/command": "~3.0.0", + "hyperf/config": "~3.0.0", + "hyperf/constants": "~3.0.0", + "hyperf/database": "~3.0.0", + "hyperf/db-connection": "~3.0.0", + "hyperf/framework": "~3.0.0", + "hyperf/guzzle": "^3.0", + "hyperf/http-server": "~3.0.0", + "hyperf/logger": "~3.0.0", + "hyperf/memory": "~3.0.0", + "hyperf/paginator": "^3.0", + "hyperf/process": "~3.0.0", + "hyperf/redis": "~3.0.0", + "hyperf/snowflake": "^3.0", + "hyperf/validation": "^3.0", + "w7corp/easywechat": "^6.7" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "hyperf/devtool": "~3.0.0", + "hyperf/testing": "~3.0.0", + "mockery/mockery": "^1.0", + "phpstan/phpstan": "^1.0", + "swoole/ide-helper": "^5.0" + }, + "suggest": { + "ext-openssl": "Required to use HTTPS.", + "ext-json": "Required to use JSON.", + "ext-pdo": "Required to use MySQL Client.", + "ext-pdo_mysql": "Required to use MySQL Client.", + "ext-redis": "Required to use Redis Client." + }, + "autoload": { + "psr-4": { + "App\\": "app/", + "Utils\\": "app/Utils", + "Extend\\": "extend/" + }, + "files": [] + }, + "autoload-dev": { + "psr-4": { + "HyperfTest\\": "./test/" + }, + "files": [ + "app/Common/Common.php" + ] + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, + "extra": [], + "scripts": { + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-autoload-dump": [ + "rm -rf runtime/container" + ], + "test": "co-phpunit --prepend test/bootstrap.php -c phpunit.xml --colors=always", + "cs-fix": "php-cs-fixer fix $1", + "analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config", + "start": [ + "Composer\\Config::disableProcessTimeout", + "php ./bin/hyperf.php start" + ] + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..68e2ab8 --- /dev/null +++ b/composer.lock @@ -0,0 +1,9097 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "92f639e766460b0a3fdd041d550e5010", + "packages": [ + { + "name": "adbario/php-dot-notation", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/adbario/php-dot-notation.git", + "reference": "081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/adbario/php-dot-notation/2.5.0/adbario-php-dot-notation-2.5.0.zip", + "reference": "081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Adbar\\": "src" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Riku Särkinen", + "email": "riku@adbar.io" + } + ], + "description": "PHP dot notation access to arrays", + "homepage": "https://github.com/adbario/php-dot-notation", + "keywords": [ + "ArrayAccess", + "dotnotation" + ], + "time": "2022-10-14T20:31:46+00:00" + }, + { + "name": "alibabacloud/credentials", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/aliyun/credentials-php.git", + "reference": "e79d4151ad8924c0cf79d4fe0ec151b8d7663a25" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/credentials/1.1.4/alibabacloud-credentials-1.1.4.zip", + "reference": "e79d4151ad8924c0cf79d4fe0ec151b8d7663a25", + "shasum": "" + }, + "require": { + "adbario/php-dot-notation": "^2.2", + "alibabacloud/tea": "^3.0", + "ext-curl": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "ext-xmlwriter": "*", + "guzzlehttp/guzzle": "^6.3|^7.0", + "php": ">=5.6" + }, + "require-dev": { + "composer/composer": "^1.8", + "drupal/coder": "^8.3", + "ext-dom": "*", + "ext-pcre": "*", + "ext-sockets": "*", + "ext-spl": "*", + "mikey179/vfsstream": "^1.6", + "monolog/monolog": "^1.24", + "phpunit/phpunit": "^4.8.35|^5.4.3", + "psr/cache": "^1.0", + "symfony/dotenv": "^3.4", + "symfony/var-dumper": "^3.4" + }, + "suggest": { + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "autoload": { + "psr-4": { + "AlibabaCloud\\Credentials\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com", + "homepage": "http://www.alibabacloud.com" + } + ], + "description": "Alibaba Cloud Credentials for PHP", + "homepage": "https://www.alibabacloud.com/", + "keywords": [ + "alibaba", + "alibabacloud", + "aliyun", + "client", + "cloud", + "credentials", + "library", + "sdk", + "tool" + ], + "time": "2021-06-08T10:49:34+00:00" + }, + { + "name": "alibabacloud/darabonba-openapi", + "version": "0.2.8", + "source": { + "type": "git", + "url": "https://github.com/alibabacloud-sdk-php/darabonba-openapi.git", + "reference": "aabc61b3049caed6442ca332cf45d3b51af633ef" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/darabonba-openapi/0.2.8/alibabacloud-darabonba-openapi-0.2.8.zip", + "reference": "aabc61b3049caed6442ca332cf45d3b51af633ef", + "shasum": "" + }, + "require": { + "alibabacloud/credentials": "^1.1", + "alibabacloud/gateway-spi": "^1", + "alibabacloud/openapi-util": "^0.1.10", + "alibabacloud/tea-utils": "^0.2.16", + "alibabacloud/tea-xml": "^0.2", + "php": ">5.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Darabonba\\OpenApi\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com" + } + ], + "description": "Alibaba Cloud OpenApi Client", + "time": "2022-11-14T03:38:23+00:00" + }, + { + "name": "alibabacloud/dysmsapi-20170525", + "version": "2.0.23", + "source": { + "type": "git", + "url": "https://github.com/alibabacloud-sdk-php/Dysmsapi-20170525.git", + "reference": "f743fce2182cb503962c37cba2ce4ba71642e89e" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/dysmsapi-20170525/2.0.23/alibabacloud-dysmsapi-20170525-2.0.23.zip", + "reference": "f743fce2182cb503962c37cba2ce4ba71642e89e", + "shasum": "" + }, + "require": { + "alibabacloud/darabonba-openapi": "^0.2.8", + "alibabacloud/endpoint-util": "^0.1.0", + "alibabacloud/openapi-util": "^0.1.10|^0.2.0", + "alibabacloud/tea-utils": "^0.2.17", + "php": ">5.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "AlibabaCloud\\SDK\\Dysmsapi\\V20170525\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com" + } + ], + "description": "Alibaba Cloud Dysmsapi (20170525) SDK Library for PHP", + "time": "2022-11-29T07:24:48+00:00" + }, + { + "name": "alibabacloud/endpoint-util", + "version": "0.1.1", + "source": { + "type": "git", + "url": "https://github.com/alibabacloud-sdk-php/endpoint-util.git", + "reference": "f3fe88a25d8df4faa3b0ae14ff202a9cc094e6c5" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/endpoint-util/0.1.1/alibabacloud-endpoint-util-0.1.1.zip", + "reference": "f3fe88a25d8df4faa3b0ae14ff202a9cc094e6c5", + "shasum": "" + }, + "require": { + "php": ">5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.4.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "AlibabaCloud\\Endpoint\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com" + } + ], + "description": "Alibaba Cloud Endpoint Library for PHP", + "time": "2020-06-04T10:57:15+00:00" + }, + { + "name": "alibabacloud/gateway-spi", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/alibabacloud-sdk-php/alibabacloud-gateway-spi.git", + "reference": "7440f77750c329d8ab252db1d1d967314ccd1fcb" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/gateway-spi/1.0.0/alibabacloud-gateway-spi-1.0.0.zip", + "reference": "7440f77750c329d8ab252db1d1d967314ccd1fcb", + "shasum": "" + }, + "require": { + "alibabacloud/credentials": "^1.1", + "php": ">5.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Darabonba\\GatewaySpi\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com" + } + ], + "description": "Alibaba Cloud Gateway SPI Client", + "time": "2022-07-14T05:31:35+00:00" + }, + { + "name": "alibabacloud/openapi-util", + "version": "0.1.13", + "source": { + "type": "git", + "url": "https://github.com/alibabacloud-sdk-php/openapi-util.git", + "reference": "870e59984f05e104aa303c85b8214e339ba0a0ac" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/openapi-util/0.1.13/alibabacloud-openapi-util-0.1.13.zip", + "reference": "870e59984f05e104aa303c85b8214e339ba0a0ac", + "shasum": "" + }, + "require": { + "alibabacloud/tea": "^3.1", + "alibabacloud/tea-utils": "^0.2", + "lizhichao/one-sm": "^1.5", + "php": ">5.5" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "AlibabaCloud\\OpenApiUtil\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com" + } + ], + "description": "Alibaba Cloud OpenApi Util", + "time": "2022-11-06T05:49:55+00:00" + }, + { + "name": "alibabacloud/tea", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/aliyun/tea-php.git", + "reference": "f2bfe50b810f598e1a48e85ee94b7164049d5184" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/tea/3.2.0/alibabacloud-tea-3.2.0.zip", + "reference": "f2bfe50b810f598e1a48e85ee94b7164049d5184", + "shasum": "" + }, + "require": { + "adbario/php-dot-notation": "^2.4", + "ext-curl": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "ext-xmlwriter": "*", + "guzzlehttp/guzzle": "^6.3|^7.0", + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "*", + "symfony/dotenv": "^3.4", + "symfony/var-dumper": "^3.4" + }, + "suggest": { + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "autoload": { + "psr-4": { + "AlibabaCloud\\Tea\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com", + "homepage": "http://www.alibabacloud.com" + } + ], + "description": "Client of Tea for PHP", + "homepage": "https://www.alibabacloud.com/", + "keywords": [ + "alibabacloud", + "client", + "cloud", + "tea" + ], + "time": "2022-10-20T06:58:05+00:00" + }, + { + "name": "alibabacloud/tea-utils", + "version": "0.2.17", + "source": { + "type": "git", + "url": "https://github.com/alibabacloud-sdk-php/tea-utils.git", + "reference": "dad2f3e1791998d573ef2d9ebad01e7e0f053866" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/tea-utils/0.2.17/alibabacloud-tea-utils-0.2.17.zip", + "reference": "dad2f3e1791998d573ef2d9ebad01e7e0f053866", + "shasum": "" + }, + "require": { + "alibabacloud/tea": "^3.1", + "php": ">5.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "AlibabaCloud\\Tea\\Utils\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com" + } + ], + "description": "Alibaba Cloud Tea Utils for PHP", + "time": "2022-11-16T09:28:02+00:00" + }, + { + "name": "alibabacloud/tea-xml", + "version": "0.2.3", + "source": { + "type": "git", + "url": "https://github.com/alibabacloud-sdk-php/tea-xml.git", + "reference": "4bd2303d71c968cb7ae4e487c5fa3023aed3ff3b" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/alibabacloud/tea-xml/0.2.3/alibabacloud-tea-xml-0.2.3.zip", + "reference": "4bd2303d71c968cb7ae4e487c5fa3023aed3ff3b", + "shasum": "" + }, + "require": { + "php": ">5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.4.3", + "symfony/var-dumper": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "AlibabaCloud\\Tea\\XML\\": "src" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com" + } + ], + "description": "Alibaba Cloud Tea XML Library for PHP", + "time": "2021-12-08T06:43:00+00:00" + }, + { + "name": "aliyuncs/oss-sdk-php", + "version": "v2.6.0", + "source": { + "type": "git", + "url": "https://github.com/aliyun/aliyun-oss-php-sdk.git", + "reference": "572d0f8e099e8630ae7139ed3fdedb926c7a760f" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/aliyuncs/oss-sdk-php/v2.6.0/aliyuncs-oss-sdk-php-v2.6.0.zip", + "reference": "572d0f8e099e8630ae7139ed3fdedb926c7a760f", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "*", + "satooshi/php-coveralls": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "OSS\\": "src/OSS" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aliyuncs", + "homepage": "http://www.aliyun.com" + } + ], + "description": "Aliyun OSS SDK for PHP", + "homepage": "http://www.aliyun.com/product/oss/", + "time": "2022-08-03T08:06:01+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/doctrine/deprecations/v1.0.0/doctrine-deprecations-v1.0.0.zip", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "time": "2022-05-02T15:47:09+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/doctrine/inflector/2.0.6/doctrine-inflector-2.0.6.zip", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2022-10-20T09:10:12+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/doctrine/instantiator/1.5.0/doctrine-instantiator-1.5.0.zip", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, + { + "name": "doctrine/lexer", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/doctrine/lexer/2.1.0/doctrine-lexer-2.1.0.zip", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-12-14T08:49:07+00:00" + }, + { + "name": "egulias/email-validator", + "version": "3.2.5", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "b531a2311709443320c786feb4519cfaf94af796" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/egulias/email-validator/3.2.5/egulias-email-validator-3.2.5.zip", + "reference": "b531a2311709443320c786feb4519cfaf94af796", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.2|^2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2023-01-02T17:26:14+00:00" + }, + { + "name": "fig/http-message-util", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message-util.git", + "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/fig/http-message-util/1.1.5/fig-http-message-util-1.1.5.zip", + "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "suggest": { + "psr/http-message": "The package containing the PSR-7 interfaces" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Fig\\Http\\Message\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Utility classes and constants for use with PSR-7 (psr/http-message)", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2020-11-24T22:02:12+00:00" + }, + { + "name": "firebase/php-jwt", + "version": "v6.3.2", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "ea7dda77098b96e666c5ef382452f94841e439cd" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/firebase/php-jwt/v6.3.2/firebase-php-jwt-v6.3.2.zip", + "reference": "ea7dda77098b96e666c5ef382452f94841e439cd", + "shasum": "" + }, + "require": { + "php": "^7.1||^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^1.1", + "phpunit/phpunit": "^7.5||^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "time": "2022-12-19T17:10:46+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/graham-campbell/result-type/v1.1.0/graham-campbell-result-type-v1.1.0.zip", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.28 || ^9.5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2022-07-30T15:56:11+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/guzzlehttp/guzzle/7.5.0/guzzlehttp-guzzle-7.5.0.zip", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-08-28T15:39:27+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/guzzlehttp/promises/1.5.2/guzzlehttp-promises-1.5.2.zip", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2022-08-28T14:55:35+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "67c26b443f348a51926030c83481b85718457d3d" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/guzzlehttp/psr7/2.4.3/guzzlehttp-psr7-2.4.3.zip", + "reference": "67c26b443f348a51926030c83481b85718457d3d", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2022-10-26T14:07:24+00:00" + }, + { + "name": "hyperf/amqp", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/amqp.git", + "reference": "20d4d9265003437557d567e02bd3b07ca1c40dbc" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/amqp/v3.0.0/hyperf-amqp-v3.0.0.zip", + "reference": "20d4d9265003437557d567e02bd3b07ca1c40dbc", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2.0", + "hyperf/contract": "~3.0.0", + "hyperf/pool": "~3.0.0", + "hyperf/process": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "php-amqplib/php-amqplib": "^3.1", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.0|^2.0|^3.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations.", + "hyperf/event": "Declare queue and start consumers automatically." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Amqp\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Amqp\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A amqplib for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "AMQP", + "hyperf", + "php" + ], + "time": "2022-12-10T13:24:37+00:00" + }, + { + "name": "hyperf/async-queue", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/async-queue.git", + "reference": "a436290438d5767ed78b9448cf2fc130caf818b3" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/async-queue/v3.0.0/hyperf-async-queue-v3.0.0.zip", + "reference": "a436290438d5767ed78b9448cf2fc130caf818b3", + "shasum": "" + }, + "require": { + "hyperf/command": "~3.0.0", + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations.", + "hyperf/event": "Required to dispatch a event.", + "hyperf/logger": "Required to use QueueHandleListener.", + "hyperf/process": "Auto register the consumer process for server." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\AsyncQueue\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\AsyncQueue\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A async queue component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "async-queue", + "hyperf", + "php" + ], + "time": "2022-11-16T02:16:48+00:00" + }, + { + "name": "hyperf/cache", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/cache.git", + "reference": "bba789fc11d7ca2a20ae76cf87d9476be2011344" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/cache/v3.0.0/hyperf-cache-v3.0.0.zip", + "reference": "bba789fc11d7ca2a20ae76cf87d9476be2011344", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0" + }, + "suggest": { + "hyperf/di": "Use cache annotations.", + "hyperf/event": "Use listener to delete annotation cache." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Cache\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Cache\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A cache component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "cache", + "hyperf", + "php" + ], + "time": "2022-11-22T04:45:19+00:00" + }, + { + "name": "hyperf/command", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/command.git", + "reference": "3bb67fd9e776b2987e2b2daf47f55987ad322122" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/command/v3.0.0/hyperf-command-v3.0.0.zip", + "reference": "3bb67fd9e776b2987e2b2daf47f55987ad322122", + "shasum": "" + }, + "require": { + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/event-dispatcher": "^1.0", + "symfony/console": "^5.0|^6.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Command\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "Command for hyperf", + "keywords": [ + "command", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/config", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/config.git", + "reference": "dbab570287af7b7d79967446b7f4703c4ffaba8e" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/config/v3.0.0/hyperf-config-v3.0.0.zip", + "reference": "dbab570287af7b7d79967446b7f4703c4ffaba8e", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "symfony/finder": "^5.0|^6.0" + }, + "suggest": { + "hyperf/di": "Allows using @Value annotation", + "hyperf/event": "Allows using @Value annotation", + "hyperf/framework": "Allows using @Value annotation", + "vlucas/phpdotenv": "Allows using enviroment value to override the config" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Config\\ConfigProvider" + } + }, + "autoload": { + "files": [ + "./src/Functions.php" + ], + "psr-4": { + "Hyperf\\Config\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "An independent component that provides configuration container.", + "homepage": "https://hyperf.io", + "keywords": [ + "config", + "configuration", + "hyperf", + "php", + "swoole" + ], + "time": "2022-08-30T06:33:36+00:00" + }, + { + "name": "hyperf/constants", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/constants.git", + "reference": "561a5e509cfdc08323b21f8d6fd4e9f11b941906" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/constants/v3.0.0/hyperf-constants-v3.0.0.zip", + "reference": "561a5e509cfdc08323b21f8d6fd4e9f11b941906", + "shasum": "" + }, + "require": { + "hyperf/di": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0" + }, + "suggest": { + "hyperf/translation": "Required to use translation." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Constants\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Constants\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A constants component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "constants", + "hyperf", + "php" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/context", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/context.git", + "reference": "95cd634ece12f1f4898d10815060090191d59527" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/context/v3.0.0/hyperf-context-v3.0.0.zip", + "reference": "95cd634ece12f1f4898d10815060090191d59527", + "shasum": "" + }, + "require": { + "hyperf/engine": "^1.2|^2.0", + "php": ">=8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Context\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A coroutine context library.", + "homepage": "https://hyperf.io", + "keywords": [ + "Context", + "hyperf", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/contract", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/contract.git", + "reference": "ec465d74f94341ff9b979cc4a3f0e2ededc05040" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/contract/v3.0.0/hyperf-contract-v3.0.0.zip", + "reference": "ec465d74f94341ff9b979cc4a3f0e2ededc05040", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Contract\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "The contracts of Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/coordinator", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/coordinator.git", + "reference": "5759dd9153ea3789f0d8de0baf53d732016266cd" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/coordinator/v3.0.0/hyperf-coordinator-v3.0.0.zip", + "reference": "5759dd9153ea3789f0d8de0baf53d732016266cd", + "shasum": "" + }, + "require": { + "hyperf/engine": "^1.2|^2.0", + "php": ">=8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Coordinator\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "Hyperf Coordinator", + "homepage": "https://hyperf.io", + "keywords": [ + "Coordinator", + "hyperf", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/database", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/hyperf/database.git", + "reference": "bf78e28913cb05b4d4e6ce2dc29c4a4b7d806a56" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/database/v3.0.2/hyperf-database-v3.0.2.zip", + "reference": "bf78e28913cb05b4d4e6ce2dc29c4a4b7d806a56", + "shasum": "" + }, + "require": { + "hyperf/macroable": "~3.0.0", + "hyperf/utils": "~3.0.0", + "nesbot/carbon": "^2.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "doctrine/dbal": "Required to rename columns (^3.0).", + "nikic/php-parser": "Required to use ModelCommand. (^4.0)", + "php-di/phpdoc-reader": "Required to use ModelCommand. (^2.2)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Database\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A flexible database library.", + "homepage": "https://hyperf.io", + "keywords": [ + "database", + "hyperf", + "php" + ], + "time": "2023-01-09T08:28:48+00:00" + }, + { + "name": "hyperf/db-connection", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/hyperf/db-connection.git", + "reference": "d74360fc38d8f2abf0303faf32a2b1b3bc6003e5" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/db-connection/v3.0.2/hyperf-db-connection-v3.0.2.zip", + "reference": "d74360fc38d8f2abf0303faf32a2b1b3bc6003e5", + "shasum": "" + }, + "require": { + "hyperf/database": "~3.0.0", + "hyperf/di": "~3.0.0", + "hyperf/framework": "~3.0.0", + "hyperf/model-listener": "~3.0.0", + "hyperf/pool": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\DbConnection\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\DbConnection\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A hyperf db connection handler for hyperf/database.", + "homepage": "https://hyperf.io", + "keywords": [ + "Connection", + "database", + "hyperf", + "php" + ], + "time": "2023-01-09T08:49:03+00:00" + }, + { + "name": "hyperf/di", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/di.git", + "reference": "1cb7161eb6366d0c23f75eee749ca29286f2bd6e" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/di/v3.0.0/hyperf-di-v3.0.0.zip", + "reference": "1cb7161eb6366d0c23f75eee749ca29286f2bd6e", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0", + "nikic/php-parser": "^4.1", + "php": ">=8.0", + "php-di/phpdoc-reader": "^2.2", + "psr/container": "^1.0|^2.0", + "symfony/finder": "^5.0|^6.0", + "vlucas/phpdotenv": "^5.0" + }, + "suggest": { + "ext-pcntl": "Required to scan annotations.", + "hyperf/config": "Require this component for annotation scan progress to retrieve the scan path." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Di\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Di\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A DI for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "annotation", + "di", + "hyperf", + "php", + "swoole" + ], + "time": "2023-01-01T05:13:29+00:00" + }, + { + "name": "hyperf/dispatcher", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/dispatcher.git", + "reference": "f506c5102583d69b7225fc7045ee707a65d2b4d0" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/dispatcher/v3.0.0/hyperf-dispatcher-v3.0.0.zip", + "reference": "f506c5102583d69b7225fc7045ee707a65d2b4d0", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/http-message": "^1.0", + "psr/http-server-middleware": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Dispatcher\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Dispatcher\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A HTTP Server for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "dispatcher", + "filter", + "hyperf", + "middleware", + "php", + "swoole" + ], + "time": "2022-08-30T06:33:36+00:00" + }, + { + "name": "hyperf/engine", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/engine.git", + "reference": "3e56f0fefbb56e65558762261d06f1543ef9d2bf" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/engine/v1.5.0/hyperf-engine-v1.5.0.zip", + "reference": "3e56f0fefbb56e65558762261d06f1543ef9d2bf", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "hyperf/guzzle": "^2.2", + "hyperf/http-message": " ^2.0", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^9.4", + "swoole/ide-helper": "dev-master" + }, + "suggest": { + "ext-swoole": ">=4.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + }, + "hyperf": { + "config": "Hyperf\\Engine\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Engine\\": "src/" + } + }, + "license": [ + "MIT" + ], + "keywords": [ + "hyperf", + "php" + ], + "time": "2023-01-11T02:51:39+00:00" + }, + { + "name": "hyperf/event", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/event.git", + "reference": "e10cd5e8b7f02bad9c542c3592b495debba9a39a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/event/v3.0.0/hyperf-event-v3.0.0.zip", + "reference": "e10cd5e8b7f02bad9c542c3592b495debba9a39a", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "php": ">=8.0", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use annotatioins." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Event\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Event\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "an event manager that implements PSR-14.", + "homepage": "https://hyperf.io", + "keywords": [ + "event", + "hyperf", + "php", + "swoole" + ], + "time": "2022-10-13T02:40:13+00:00" + }, + { + "name": "hyperf/exception-handler", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/exception-handler.git", + "reference": "2c7506e82f81e8c60a8e83168b5af4b9eed05efd" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/exception-handler/v3.0.0/hyperf-exception-handler-v3.0.0.zip", + "reference": "2c7506e82f81e8c60a8e83168b5af4b9eed05efd", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/dispatcher": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\ExceptionHandler\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\ExceptionHandler\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "Exception handler for hyperf", + "homepage": "https://hyperf.io", + "keywords": [ + "exception-handler", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/framework", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/framework.git", + "reference": "20e0fd40e200285cb5da73c9c8da6669efd7c789" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/framework/v3.0.0/hyperf-framework-v3.0.0.zip", + "reference": "20e0fd40e200285cb5da73c9c8da6669efd7c789", + "shasum": "" + }, + "require": { + "fig/http-message-util": "^1.1.2", + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.0|^2.0|^3.0" + }, + "suggest": { + "ext-swoole": "Required to use swoole engine.", + "hyperf/command": "Required to use Command annotation.", + "hyperf/di": "Required to use Command annotation.", + "hyperf/dispatcher": "Required to use BootApplication event.", + "symfony/event-dispatcher": "Required to use symfony event dispatcher (^5.0|^6.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Framework\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Framework\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.", + "homepage": "https://hyperf.io", + "keywords": [ + "Microservice", + "framework", + "hyperf", + "middleware", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/guzzle", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/guzzle.git", + "reference": "1df78150253171695324216a34558a182095dd0c" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/guzzle/v3.0.0/hyperf-guzzle-v3.0.0.zip", + "reference": "1df78150253171695324216a34558a182095dd0c", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.3|^7.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/http-message": "^1.0" + }, + "suggest": { + "hyperf/pool": "Required to use pool handler." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Guzzle\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Guzzle\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "Swoole coroutine handler for guzzle", + "keywords": [ + "Guzzle", + "handler", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/http-message", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/hyperf/http-message.git", + "reference": "2f6f4e5079cb445d3c7c6518678cefcd726eaa52" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/http-message/v3.0.1/hyperf-http-message-v3.0.1.zip", + "reference": "2f6f4e5079cb445d3c7c6518678cefcd726eaa52", + "shasum": "" + }, + "require": { + "hyperf/utils": "~3.0.0", + "laminas/laminas-mime": "^2.7", + "php": ">=8.0", + "psr/http-message": "^1.0" + }, + "suggest": { + "psr/container": "Required to replace RequestParserInterface." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\HttpMessage\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\HttpMessage\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "microservice framework base on swoole", + "keywords": [ + "http-message", + "hyperf", + "php", + "swoole" + ], + "time": "2023-01-04T11:57:10+00:00" + }, + { + "name": "hyperf/http-server", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/hyperf/http-server.git", + "reference": "192bed0596d36cb04c38695067e8c60078006109" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/http-server/v3.0.1/hyperf-http-server-v3.0.1.zip", + "reference": "192bed0596d36cb04c38695067e8c60078006109", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/dispatcher": "~3.0.0", + "hyperf/event": "~3.0.0", + "hyperf/exception-handler": "~3.0.0", + "hyperf/http-message": "~3.0.0", + "hyperf/macroable": "~3.0.0", + "hyperf/server": "~3.0.0", + "hyperf/utils": "~3.0.0", + "nikic/fast-route": "^1.3", + "php": ">=8.0", + "psr/container": "^1.0|^2.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\HttpServer\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\HttpServer\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A HTTP Server for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "http", + "http-server", + "hyperf", + "php", + "swoole" + ], + "time": "2023-01-04T11:57:10+00:00" + }, + { + "name": "hyperf/logger", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/logger.git", + "reference": "c8de4bc7cd9ccca7c27faf3ebe4e5cfd7380c894" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/logger/v3.0.0/hyperf-logger-v3.0.0.zip", + "reference": "c8de4bc7cd9ccca7c27faf3ebe4e5cfd7380c894", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "monolog/monolog": "^2.7|^3.1", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/log": "^1.0|^2.0|^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Logger\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Logger\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A logger component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "logger", + "php" + ], + "time": "2022-12-11T04:49:47+00:00" + }, + { + "name": "hyperf/macroable", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/macroable.git", + "reference": "822de69ba0c75aa9767a9cea487b84bf31d5240a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/macroable/v3.0.0/hyperf-macroable-v3.0.0.zip", + "reference": "822de69ba0c75aa9767a9cea487b84bf31d5240a", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Macroable\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "Hyperf Macroable package which come from illuminate/macroable", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "macroable", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/memory", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/memory.git", + "reference": "c7217c9b5177562329074d332f9e13b40693bdfe" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/memory/v3.0.0/hyperf-memory-v3.0.0.zip", + "reference": "c7217c9b5177562329074d332f9e13b40693bdfe", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Memory\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Memory\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "An independent component that use to operate and manage memory.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "memory", + "php", + "swoole" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/model-listener", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/model-listener.git", + "reference": "50c7bffdbab5eb3828d6314b3d1de427c0e80704" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/model-listener/v3.0.0/hyperf-model-listener-v3.0.0.zip", + "reference": "50c7bffdbab5eb3828d6314b3d1de427c0e80704", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/database": "~3.0.0", + "hyperf/di": "~3.0.0", + "hyperf/event": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\ModelListener\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\ModelListener\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A model listener for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "model-listener", + "php", + "swoole" + ], + "time": "2022-05-30T02:16:40+00:00" + }, + { + "name": "hyperf/paginator", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/paginator.git", + "reference": "45acff6623c65769949665d61e7af145082aea09" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/paginator/v3.0.0/hyperf-paginator-v3.0.0.zip", + "reference": "45acff6623c65769949665d61e7af145082aea09", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=7.2" + }, + "suggest": { + "hyperf/event": "Reqiured to use PageResolverListener.", + "hyperf/framework": "Reqiured to use PageResolverListener.", + "hyperf/http-server": "Reqiured to use PageResolverListener." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Paginator\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Paginator\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A paginator component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "paginator", + "php" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/pool", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/pool.git", + "reference": "6a937ff363b84208c26cf918490a07d38ab0c987" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/pool/v3.0.0/hyperf-pool-v3.0.0.zip", + "reference": "6a937ff363b84208c26cf918490a07d38ab0c987", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Pool\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Pool\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "An independent universal connection pool component.", + "homepage": "https://hyperf.io", + "keywords": [ + "connection-pool", + "hyperf", + "php", + "swoole" + ], + "time": "2022-11-26T11:47:54+00:00" + }, + { + "name": "hyperf/process", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/process.git", + "reference": "a8f7589cdde9037b313626c4d34012c8ee5be263" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/process/v3.0.0/hyperf-process-v3.0.0.zip", + "reference": "a8f7589cdde9037b313626c4d34012c8ee5be263", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations.", + "hyperf/event": "Required to dump the message before and after process.", + "hyperf/framework": "Required to use BootProcessListener." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Process\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Process\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A process component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "process" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/redis", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/hyperf/redis.git", + "reference": "b5e59c2612bf3f6b6fd5d024e25c973a72f62fbe" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/redis/v3.0.2/hyperf-redis-v3.0.2.zip", + "reference": "b5e59c2612bf3f6b6fd5d024e25c973a72f62fbe", + "shasum": "" + }, + "require": { + "ext-redis": "*", + "hyperf/contract": "~3.0.0", + "hyperf/pool": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0" + }, + "suggest": { + "ext-redis": "Required to use sentinel mode (>=5.2).", + "hyperf/di": "Create the RedisPool via dependency injection." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Redis\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Redis\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A redis component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "pool", + "redis" + ], + "time": "2023-01-09T08:49:03+00:00" + }, + { + "name": "hyperf/server", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/hyperf/server.git", + "reference": "86bbb65dece6dab5638b57fa0a1154686dd0f089" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/server/v3.0.1/hyperf-server-v3.0.1.zip", + "reference": "86bbb65dece6dab5638b57fa0a1154686dd0f089", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.0|^2.0|^3.0", + "symfony/console": "^5.0|^6.0" + }, + "suggest": { + "hyperf/event": "Dump the info after server start.", + "hyperf/framework": "Dump the info after server start." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Server\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Server\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A base server library for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "server", + "swoole" + ], + "time": "2023-01-06T07:51:18+00:00" + }, + { + "name": "hyperf/snowflake", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/snowflake.git", + "reference": "03c21f4be91dead4d9c0bc1a74000ce13986191b" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/snowflake/v3.0.0/hyperf-snowflake-v3.0.0.zip", + "reference": "03c21f4be91dead4d9c0bc1a74000ce13986191b", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "php": ">=8.0" + }, + "suggest": { + "hyperf/config": "Required to read snowflake config.", + "hyperf/redis": "Required to use RedisMilliSecondMetaGenerator or RedisSecondMetaGenerator.", + "psr/container": "Required to use MetaGeneratorFactory." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Snowflake\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Snowflake\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A snowflake library", + "homepage": "https://hyperf.io", + "keywords": [ + "php", + "snowflake" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/translation", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/translation.git", + "reference": "72c264dc92750732c456b6b9bc057d25440e4393" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/translation/v3.0.0/hyperf-translation-v3.0.0.zip", + "reference": "72c264dc92750732c456b6b9bc057d25440e4393", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/macroable": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Translation\\ConfigProvider" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Translation\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "An independent translation component, forked by illuminate/translation.", + "keywords": [ + "hyperf", + "translation" + ], + "time": "2022-11-01T02:50:54+00:00" + }, + { + "name": "hyperf/utils", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/hyperf/utils.git", + "reference": "3955bd117bb04579f1fe5644682a4e4c207521d4" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/utils/v3.0.1/hyperf-utils-v3.0.1.zip", + "reference": "3955bd117bb04579f1fe5644682a4e4c207521d4", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^2.0", + "hyperf/context": "~3.0.0", + "hyperf/contract": "~3.0.0", + "hyperf/coordinator": "~3.0.0", + "hyperf/engine": "^1.2|^2.0", + "hyperf/macroable": "~3.0.0", + "php": ">=7.2" + }, + "suggest": { + "ext-swoole": "Required to use methods related to swoole (>=4.5).", + "hyperf/di": "Required to use ExceptionNormalizer", + "nikic/php-parser": "Required to use PhpParser. (^4.0)", + "symfony/property-access": "Required to use SymfonyNormalizer (^5.0|^6.0)", + "symfony/serializer": "Required to use SymfonyNormalizer (^5.0|^6.0)", + "symfony/var-dumper": "Required to use the dd function (^5.0|^6.0)." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Utils\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Utils\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A tools package that could help developer solved the problem quickly.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "swoole", + "utils" + ], + "time": "2023-01-04T11:57:10+00:00" + }, + { + "name": "hyperf/validation", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/validation.git", + "reference": "082ad0f0b2fc55d909a88e50cde9e56f0424e2ce" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/validation/v3.0.0/hyperf-validation-v3.0.0.zip", + "reference": "082ad0f0b2fc55d909a88e50cde9e56f0424e2ce", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^3.0", + "hyperf/contract": "~3.0.0", + "hyperf/database": "~3.0.0", + "hyperf/di": "~3.0.0", + "hyperf/framework": "~3.0.0", + "hyperf/http-server": "~3.0.0", + "hyperf/macroable": "~3.0.0", + "hyperf/translation": "~3.0.0", + "hyperf/utils": "~3.0.0", + "nesbot/carbon": "^2.21", + "php": ">=8.0", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Validation\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Validation\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "hyperf validation", + "keywords": [ + "hyperf", + "validation" + ], + "time": "2022-12-22T08:23:24+00:00" + }, + { + "name": "laminas/laminas-mime", + "version": "2.11.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-mime.git", + "reference": "60ec04b755821c79c1987ce291b44e69f2c0831f" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/laminas/laminas-mime/2.11.0/laminas-laminas-mime-2.11.0.zip", + "reference": "60ec04b755821c79c1987ce291b44e69f2c0831f", + "shasum": "" + }, + "require": { + "laminas/laminas-stdlib": "^2.7 || ^3.0", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0" + }, + "conflict": { + "zendframework/zend-mime": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~2.4.0", + "laminas/laminas-mail": "^2.19.0", + "phpunit/phpunit": "~9.5.25" + }, + "suggest": { + "laminas/laminas-mail": "Laminas\\Mail component" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Mime\\": "src/" + } + }, + "license": [ + "BSD-3-Clause" + ], + "description": "Create and parse MIME messages and parts", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "mime" + ], + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2022-10-18T08:38:15+00:00" + }, + { + "name": "laminas/laminas-stdlib", + "version": "3.16.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-stdlib.git", + "reference": "f4f773641807c7ccee59b758bfe4ac4ba33ecb17" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/laminas/laminas-stdlib/3.16.1/laminas-laminas-stdlib-3.16.1.zip", + "reference": "f4f773641807c7ccee59b758bfe4ac4ba33ecb17", + "shasum": "" + }, + "require": { + "php": "~8.0.0 || ~8.1.0 || ~8.2.0" + }, + "conflict": { + "zendframework/zend-stdlib": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "^2.4.0", + "phpbench/phpbench": "^1.2.7", + "phpunit/phpunit": "^9.5.26", + "psalm/plugin-phpunit": "^0.18.0", + "vimeo/psalm": "^5.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Stdlib\\": "src/" + } + }, + "license": [ + "BSD-3-Clause" + ], + "description": "SPL extensions, array utilities, error handlers, and more", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "stdlib" + ], + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2022-12-03T18:48:01+00:00" + }, + { + "name": "lizhichao/one-sm", + "version": "1.10", + "source": { + "type": "git", + "url": "https://github.com/lizhichao/sm.git", + "reference": "687a012a44a5bfd4d9143a0234e1060543be455a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/lizhichao/one-sm/1.10/lizhichao-one-sm-1.10.zip", + "reference": "687a012a44a5bfd4d9143a0234e1060543be455a", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "OneSm\\": "src/" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "tanszhe", + "email": "1018595261@qq.com" + } + ], + "description": "国密sm3", + "keywords": [ + "php", + "sm3" + ], + "funding": [ + { + "url": "https://www.vicsdf.com/img/w.jpg", + "type": "custom" + }, + { + "url": "https://www.vicsdf.com/img/z.jpg", + "type": "custom" + } + ], + "time": "2021-05-26T06:19:22+00:00" + }, + { + "name": "monolog/monolog", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/monolog/monolog/2.8.0/monolog-monolog-2.8.0.zip", + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpspec/prophecy": "^1.15", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5.14", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2022-07-24T11:55:47+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.65.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "09acf64155c16dc6f580f36569ae89344e9734a3" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/nesbot/carbon/2.65.0/nesbot-carbon-2.65.0.zip", + "reference": "09acf64155c16dc6f580f36569ae89344e9734a3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.1.4", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2023-01-06T15:55:01+00:00" + }, + { + "name": "nikic/fast-route", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/nikic/fast-route/v1.3.0/nikic-fast-route-v1.3.0.zip", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|~5.7" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "FastRoute\\": "src/" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ], + "time": "2018-02-13T20:26:39+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/nikic/php-parser/v4.15.2/nikic-php-parser-v4.15.2.zip", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2022-11-12T15:38:23+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "f734364e38a876a23be4d906a2a089e1315be18a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/nyholm/psr7/1.5.1/nyholm-psr7-1.5.1.zip", + "reference": "f734364e38a876a23be4d906a2a089e1315be18a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "php-http/message-factory": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || 8.5 || 9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2022-06-22T07:13:36+00:00" + }, + { + "name": "nyholm/psr7-server", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7-server.git", + "reference": "b846a689844cef114e8079d8c80f0afd96745ae3" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/nyholm/psr7-server/1.0.2/nyholm-psr7-server-1.0.2.zip", + "reference": "b846a689844cef114e8079d8c80f0afd96745ae3", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "nyholm/nsa": "^1.1", + "nyholm/psr7": "^1.3", + "phpunit/phpunit": "^7.0 || ^8.5 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nyholm\\Psr7Server\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "Helper classes to handle PSR-7 server requests", + "homepage": "http://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2021-05-12T11:11:27+00:00" + }, + { + "name": "overtrue/socialite", + "version": "4.8.0", + "source": { + "type": "git", + "url": "https://github.com/overtrue/socialite.git", + "reference": "e55fdf50f8003be8f03a85a7e5a5b7c5716f4c9a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/overtrue/socialite/4.8.0/overtrue-socialite-4.8.0.zip", + "reference": "e55fdf50f8003be8f03a85a7e5a5b7c5716f4c9a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^7.0", + "php": ">=8.0.2", + "symfony/http-foundation": "^6.0", + "symfony/psr-http-message-bridge": "^2.1" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.0", + "laravel/pint": "^1.2", + "mockery/mockery": "^1.3", + "phpstan/phpstan": "^1.7", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Contracts/FactoryInterface.php", + "src/Contracts/UserInterface.php", + "src/Contracts/ProviderInterface.php" + ], + "psr-4": { + "Overtrue\\Socialite\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "A collection of OAuth 2 packages.", + "keywords": [ + "Feishu", + "login", + "oauth", + "qcloud", + "qq", + "social", + "wechat", + "weibo" + ], + "funding": [ + { + "url": "https://github.com/overtrue", + "type": "github" + } + ], + "time": "2023-01-10T14:29:55+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/paragonie/constant_time_encoding/v2.6.3/paragonie-constant_time_encoding-v2.6.3.zip", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "time": "2022-06-14T06:56:20+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/paragonie/random_compat/v9.99.100/paragonie-random_compat-v9.99.100.zip", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "php-amqplib/php-amqplib", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-amqplib/php-amqplib.git", + "reference": "5c537cb724f2e181183c202e63f4303935344c5f" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/php-amqplib/php-amqplib/v3.4.0/php-amqplib-php-amqplib-v3.4.0.zip", + "reference": "5c537cb724f2e181183c202e63f4303935344c5f", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-sockets": "*", + "php": "^7.1||^8.0", + "phpseclib/phpseclib": "^2.0|^3.0" + }, + "conflict": { + "php": "7.4.0 - 7.4.1" + }, + "replace": { + "videlalvaro/php-amqplib": "self.version" + }, + "require-dev": { + "ext-curl": "*", + "nategood/httpful": "^0.2.20", + "phpunit/phpunit": "^7.5|^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpAmqpLib\\": "PhpAmqpLib/" + } + }, + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Alvaro Videla", + "role": "Original Maintainer" + }, + { + "name": "Raúl Araya", + "email": "nubeiro@gmail.com", + "role": "Maintainer" + }, + { + "name": "Luke Bakken", + "email": "luke@bakken.io", + "role": "Maintainer" + }, + { + "name": "Ramūnas Dronga", + "email": "github@ramuno.lt", + "role": "Maintainer" + } + ], + "description": "Formerly videlalvaro/php-amqplib. This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", + "homepage": "https://github.com/php-amqplib/php-amqplib/", + "keywords": [ + "message", + "queue", + "rabbitmq" + ], + "time": "2022-10-18T20:52:02+00:00" + }, + { + "name": "php-di/phpdoc-reader", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PhpDocReader.git", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/php-di/phpdoc-reader/2.2.1/php-di-phpdoc-reader-2.2.1.zip", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "mnapoli/hard-mode": "~0.3.0", + "phpunit/phpunit": "^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpDocReader\\": "src/PhpDocReader" + } + }, + "license": [ + "MIT" + ], + "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)", + "keywords": [ + "phpdoc", + "reflection" + ], + "time": "2020-10-12T12:39:22+00:00" + }, + { + "name": "php-http/message-factory", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message-factory.git", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/php-http/message-factory/v1.0.2/php-http-message-factory-v1.0.2.zip", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "stream", + "uri" + ], + "time": "2015-12-19T14:08:53+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpoption/phpoption/1.9.0/phpoption-phpoption-1.9.0.zip", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8", + "phpunit/phpunit": "^8.5.28 || ^9.5.21" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2022-07-30T15:51:26+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.18", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "f28693d38ba21bb0d9f0c411ee5dae2b178201da" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpseclib/phpseclib/3.0.18/phpseclib-phpseclib-3.0.18.zip", + "reference": "f28693d38ba21bb0d9f0c411ee5dae2b178201da", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2022-12-17T18:26:50+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/cache/3.0.0/psr-cache-3.0.0.zip", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/container/2.0.2/psr-container-2.0.2.zip", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/event-dispatcher/1.0.0/psr-event-dispatcher-1.0.0.zip", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/http-client/1.0.1/psr-http-client-1.0.1.zip", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/http-factory/1.0.1/psr-http-factory-1.0.1.zip", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/http-message/1.0.1/psr-http-message-1.0.1.zip", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/http-server-handler", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/http-server-handler/1.0.1/psr-http-server-handler-1.0.1.zip", + "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "time": "2018-10-30T16:46:14+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/http-server-middleware/1.0.1/psr-http-server-middleware-1.0.1.zip", + "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "time": "2018-10-30T17:12:04+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/log/3.0.0/psr-log-3.0.0.zip", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/psr/simple-cache/3.0.0/psr-simple-cache-3.0.0.zip", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/ralouphie/getallheaders/3.0.3/ralouphie-getallheaders-3.0.3.zip", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/cache", + "version": "v6.0.18", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "079ec0afe323fdcd5ac1f16e3ffdb4991fb5d4c9" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/cache/v6.0.18/symfony-cache-v6.0.18.zip", + "reference": "079ec0afe323fdcd5ac1f16e3ffdb4991fb5d4c9", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^1.1.7|^2|^3", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/var-exporter": "^5.4|^6.0" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/var-dumper": "<5.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^2.13.1|^3.0", + "predis/predis": "^1.1", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-29T16:27:58+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "1c0a181c9ee221afe4fa55b2d13fc63c5ae14348" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/cache-contracts/v3.0.2/symfony-cache-contracts-v3.0.2.zip", + "reference": "1c0a181c9ee221afe4fa55b2d13fc63c5ae14348", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/cache": "^3.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/console", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "2ab307342a7233b9a260edd5ef94087aaca57d18" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/console/v6.0.17/symfony-console-v6.0.17.zip", + "reference": "2ab307342a7233b9a260edd5ef94087aaca57d18", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-28T14:21:34+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/deprecation-contracts/v3.0.2/symfony-deprecation-contracts-v3.0.2.zip", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "d467d625fc88f7cebf96f495e588a7196a669db1" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/finder/v6.0.17/symfony-finder-v6.0.17.zip", + "reference": "d467d625fc88f7cebf96f495e588a7196a669db1", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-22T17:53:58+00:00" + }, + { + "name": "symfony/http-client", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "d104286d135d29a17ead777888087e7f0fd11771" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/http-client/v6.0.17/symfony-http-client-v6.0.17.zip", + "reference": "d104286d135d29a17ead777888087e7f0fd11771", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/log": "^1|^2|^3", + "symfony/http-client-contracts": "^3", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-14T15:52:41+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "4184b9b63af1edaf35b6a7974c6f1f9f33294129" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/http-client-contracts/v3.0.2/symfony-http-client-contracts-v3.0.2.zip", + "reference": "4184b9b63af1edaf35b6a7974c6f1f9f33294129", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-04-12T16:11:42+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "22fe17e40b0481d39212e7165e004eb26422085d" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/http-foundation/v6.0.17/symfony-http-foundation-v6.0.17.zip", + "reference": "22fe17e40b0481d39212e7165e004eb26422085d", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-14T15:52:41+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "3e6a7ba15997020778312ed576ad01ab60dc2336" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/mime/v6.0.17/symfony-mime-v6.0.17.zip", + "reference": "3e6a7ba15997020778312ed576ad01ab60dc2336", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4", + "symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/serializer": "^5.4.14|~6.0.14|^6.1.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-14T16:19:02+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-ctype/v1.27.0/symfony-polyfill-ctype-v1.27.0.zip", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-intl-grapheme/v1.27.0/symfony-polyfill-intl-grapheme-v1.27.0.zip", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-intl-idn/v1.27.0/symfony-polyfill-intl-idn-v1.27.0.zip", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-intl-normalizer/v1.27.0/symfony-polyfill-intl-normalizer-v1.27.0.zip", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-mbstring/v1.27.0/symfony-polyfill-mbstring-v1.27.0.zip", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-php72/v1.27.0/symfony-polyfill-php72-v1.27.0.zip", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-php80/v1.27.0/symfony-polyfill-php80-v1.27.0.zip", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/polyfill-php81/v1.27.0/symfony-polyfill-php81-v1.27.0.zip", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.1.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "a125b93ef378c492e274f217874906fb9babdebb" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/psr-http-message-bridge/v2.1.4/symfony-psr-http-message-bridge-v2.1.4.zip", + "reference": "a125b93ef378c492e274f217874906fb9babdebb", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0 || ^6.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", + "symfony/config": "^4.4 || ^5.0 || ^6.0", + "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0", + "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4@dev || ^6.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-main": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-28T22:46:34+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/service-contracts/v3.0.2/symfony-service-contracts-v3.0.2.zip", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-30T19:17:58+00:00" + }, + { + "name": "symfony/string", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "3f57003dd8a67ed76870cc03092f8501db7788d9" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/string/v6.0.17/symfony-string-v6.0.17.zip", + "reference": "3f57003dd8a67ed76870cc03092f8501db7788d9", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-14T15:52:41+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.0.14", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "6f99eb179aee4652c0a7cd7c11f2a870d904330c" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/translation/v6.0.14/symfony-translation-v6.0.14.zip", + "reference": "6f99eb179aee4652c0a7cd7c11f2a870d904330c", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.3|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-07T08:02:12+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/translation-contracts/v3.0.2/symfony-translation-contracts-v3.0.2.zip", + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:10:44+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "d87c15d59421d38fe5eb4f6724eb75891479e3da" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/var-exporter/v6.0.17/symfony-var-exporter-v6.0.17.zip", + "reference": "d87c15d59421d38fe5eb4f6724eb75891479e3da", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "require-dev": { + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-22T17:53:58+00:00" + }, + { + "name": "thenorthmemory/xml", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/TheNorthMemory/xml.git", + "reference": "6f50c63450a0b098772423f8bdc3c4ad2c4c30bb" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/thenorthmemory/xml/1.1.1/thenorthmemory-xml-1.1.1.zip", + "reference": "6f50c63450a0b098772423f8bdc3c4ad2c4c30bb", + "shasum": "" + }, + "require": { + "ext-libxml": "*", + "ext-simplexml": "*", + "php": ">=7.1.2" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.89 || ^1.0", + "phpunit/phpunit": "^7.5 || ^8.5.16 || ^9.3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "TheNorthMemory\\Xml\\": "src/" + } + }, + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "James ZHANG", + "homepage": "https://github.com/TheNorthMemory" + } + ], + "description": "A wrapper of the XML parser and builder", + "homepage": "https://github.com/TheNorthMemory/xml", + "keywords": [ + "xml-builder", + "xml-parser" + ], + "time": "2023-01-15T06:01:13+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.5.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/vlucas/phpdotenv/v5.5.0/vlucas-phpdotenv-v5.5.0.zip", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.5-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2022-10-16T01:01:54+00:00" + }, + { + "name": "w7corp/easywechat", + "version": "6.10.0", + "source": { + "type": "git", + "url": "https://github.com/w7corp/easywechat.git", + "reference": "558a58fd37e961027a5f81164feddc13b60362a3" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/w7corp/easywechat/6.10.0/w7corp-easywechat-6.10.0.zip", + "reference": "558a58fd37e961027a5f81164feddc13b60362a3", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-fileinfo": "*", + "ext-libxml": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "ext-sodium": "*", + "monolog/monolog": "^2.2", + "nyholm/psr7": "^1.5", + "nyholm/psr7-server": "^1.0", + "overtrue/socialite": "^3.5.4|^4.0.1", + "php": ">=8.0.2", + "psr/http-client": "^1.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/cache": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/polyfill-php81": "^1.25", + "symfony/psr-http-message-bridge": "^2.1.2", + "thenorthmemory/xml": "^1.0" + }, + "require-dev": { + "brainmaestro/composer-git-hooks": "^2.8", + "jetbrains/phpstorm-attributes": "^1.0", + "laravel/pint": "^1.2", + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.4.4", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/var-dumper": "^5.2" + }, + "type": "library", + "extra": { + "hooks": { + "pre-commit": [ + "composer check-style", + "composer phpstan", + "composer test" + ], + "pre-push": [ + "composer check-style" + ], + "config": { + "stop-on-failure": [ + "pre-commit", + "pre-push" + ] + } + } + }, + "autoload": { + "psr-4": { + "EasyWeChat\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "微信SDK", + "keywords": [ + "easywechat", + "sdk", + "wechat", + "weixin", + "weixin-sdk" + ], + "funding": [ + { + "url": "https://github.com/overtrue", + "type": "github" + } + ], + "time": "2022-11-28T14:35:59+00:00" + } + ], + "packages-dev": [ + { + "name": "composer/pcre", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/composer/pcre/3.1.0/composer-pcre-3.1.0.zip", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-11-17T09:50:14+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/composer/semver/3.3.2/composer-semver-3.3.2.zip", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/composer/xdebug-handler/3.0.3/composer-xdebug-handler-3.0.3.zip", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.14.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/doctrine/annotations/1.14.2/doctrine-annotations-1.14.2.zip", + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1 || ^2", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2022-12-15T06:48:22+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.13.2", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/friendsofphp/php-cs-fixer/v3.13.2/friendsofphp-php-cs-fixer-v3.13.2.zip", + "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496", + "shasum": "" + }, + "require": { + "composer/semver": "^3.2", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^1.13", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.23", + "symfony/polyfill-php80": "^1.25", + "symfony/polyfill-php81": "^1.25", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" + }, + "require-dev": { + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.0", + "mikey179/vfsstream": "^1.6.10", + "php-coveralls/php-coveralls": "^2.5.2", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.15", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", + "symfony/phpunit-bridge": "^6.0", + "symfony/yaml": "^5.4 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2023-01-02T23:53:50+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hamcrest/hamcrest-php/v2.0.1/hamcrest-hamcrest-php-v2.0.1.zip", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "hyperf/devtool", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/devtool.git", + "reference": "715167d5160261c5f87ef82def1298ad6edb19ad" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/devtool/v3.0.0/hyperf-devtool-v3.0.0.zip", + "reference": "715167d5160261c5f87ef82def1298ad6edb19ad", + "shasum": "" + }, + "require": { + "hyperf/command": "~3.0.0", + "hyperf/contract": "~3.0.0", + "hyperf/di": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "hyperf": { + "config": "Hyperf\\Devtool\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Devtool\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "A Devtool for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "devtool", + "hyperf", + "php", + "swoole" + ], + "time": "2022-12-10T13:24:37+00:00" + }, + { + "name": "hyperf/testing", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/hyperf/testing.git", + "reference": "b4e9ed466a192e5af72b3d456d11da1d54304c54" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/hyperf/testing/v3.0.1/hyperf-testing-v3.0.1.zip", + "reference": "b4e9ed466a192e5af72b3d456d11da1d54304c54", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.0.0", + "hyperf/http-message": "~3.0.0", + "hyperf/http-server": "~3.0.0", + "hyperf/utils": "~3.0.0", + "php": ">=8.0", + "phpunit/phpunit": "^9.5", + "psr/container": "^1.0|^2.0" + }, + "bin": [ + "co-phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Testing\\": "src/" + } + }, + "license": [ + "MIT" + ], + "description": "Testing for hyperf", + "keywords": [ + "php", + "swoole", + "testing" + ], + "time": "2023-01-04T11:57:10+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/mockery/mockery/1.5.1/mockery-mockery-1.5.1.zip", + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2022-09-07T15:32:08+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/myclabs/deep-copy/1.11.0/myclabs-deep-copy-1.11.0.zip", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phar-io/manifest/2.0.3/phar-io-manifest-2.0.3.zip", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phar-io/version/3.2.1/phar-io-version-3.2.1.zip", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.9.8", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "45411d15bf85a33b4a8ee9b75a6e82998c9adb97" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpstan/phpstan/1.9.8/phpstan-phpstan-1.9.8.zip", + "reference": "45411d15bf85a33b4a8ee9b75a6e82998c9adb97", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2023-01-08T21:26:18+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.23", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpunit/php-code-coverage/9.2.23/phpunit-php-code-coverage-9.2.23.zip", + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.14", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-12-28T12:41:10+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpunit/php-file-iterator/3.0.6/phpunit-php-file-iterator-3.0.6.zip", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpunit/php-invoker/3.1.1/phpunit-php-invoker-3.1.1.zip", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpunit/php-text-template/2.0.4/phpunit-php-text-template-2.0.4.zip", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpunit/php-timer/5.0.3/phpunit-php-timer-5.0.3.zip", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.27", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/phpunit/phpunit/9.5.27/phpunit-phpunit-9.5.27.zip", + "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2022-12-09T07:31:23+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/cli-parser/1.0.1/sebastian-cli-parser-1.0.1.zip", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/code-unit/1.0.8/sebastian-code-unit-1.0.8.zip", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/code-unit-reverse-lookup/2.0.3/sebastian-code-unit-reverse-lookup-2.0.3.zip", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/comparator/4.0.8/sebastian-comparator-4.0.8.zip", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/complexity/2.0.2/sebastian-complexity-2.0.2.zip", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/diff/4.0.4/sebastian-diff-4.0.4.zip", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/environment/5.1.4/sebastian-environment-5.1.4.zip", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/exporter/4.0.5/sebastian-exporter-4.0.5.zip", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/global-state/5.0.5/sebastian-global-state-5.0.5.zip", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/lines-of-code/1.0.3/sebastian-lines-of-code-1.0.3.zip", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/object-enumerator/4.0.4/sebastian-object-enumerator-4.0.4.zip", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/object-reflector/2.0.4/sebastian-object-reflector-2.0.4.zip", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/recursion-context/4.0.4/sebastian-recursion-context-4.0.4.zip", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/resource-operations/3.0.3/sebastian-resource-operations-3.0.3.zip", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/type/3.2.0/sebastian-type-3.2.0.zip", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-12T14:47:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/sebastian/version/3.0.2/sebastian-version-3.0.2.zip", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "swoole/ide-helper", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "f9cdf7bfb70ef3a8a2b8e9eb14ce3d09c02524fa" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/swoole/ide-helper/5.0.1/swoole-ide-helper-5.0.1.zip", + "reference": "f9cdf7bfb70ef3a8a2b8e9eb14ce3d09c02524fa", + "shasum": "" + }, + "type": "library", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Team Swoole", + "email": "team@swoole.com" + } + ], + "description": "IDE help files for Swoole.", + "funding": [ + { + "url": "https://gitee.com/swoole/swoole?donate=true", + "type": "custom" + }, + { + "url": "https://github.com/swoole", + "type": "github" + } + ], + "time": "2022-11-08T07:13:40+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.0.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "42b3985aa07837c9df36013ec5b965e9f2d480bc" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/event-dispatcher/v6.0.17/symfony-event-dispatcher-v6.0.17.zip", + "reference": "42b3985aa07837c9df36013ec5b965e9f2d480bc", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/event-dispatcher-contracts": "^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-14T15:52:41+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/event-dispatcher-contracts/v3.0.2/symfony-event-dispatcher-contracts-v3.0.2.zip", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.0.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "3adca49133bd055ebe6011ed1e012be3c908af79" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/filesystem/v6.0.13/symfony-filesystem-v6.0.13.zip", + "reference": "3adca49133bd055ebe6011ed1e012be3c908af79", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-21T20:25:27+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "51f7006670febe4cbcbae177cbffe93ff833250d" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/options-resolver/v6.0.3/symfony-options-resolver-v6.0.3.zip", + "reference": "51f7006670febe4cbcbae177cbffe93ff833250d", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/process", + "version": "v6.0.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "44270a08ccb664143dede554ff1c00aaa2247a43" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/process/v6.0.11/symfony-process-v6.0.11.zip", + "reference": "44270a08ccb664143dede554ff1c00aaa2247a43", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:10:44+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.0.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "7554fde6848af5ef1178f8ccbdbdb8ae1092c70a" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/symfony/stopwatch/v6.0.13/symfony-stopwatch-v6.0.13.zip", + "reference": "7554fde6848af5ef1178f8ccbdbdb8ae1092c70a", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/service-contracts": "^1|^2|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-28T15:52:47+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://mirrors.huaweicloud.com/repository/php/theseer/tokenizer/1.2.1/theseer-tokenizer-1.2.1.zip", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=8.0" + }, + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/config/autoload/amqp.php b/config/autoload/amqp.php new file mode 100644 index 0000000..934cf4b --- /dev/null +++ b/config/autoload/amqp.php @@ -0,0 +1,40 @@ + [ + 'host' => env('AMQP_HOST', 'localhost'), + 'port' => (int) env('AMQP_PORT', 5672), + 'user' => env('AMQP_USER', 'guest'), + 'password' => env('AMQP_PASSWORD', 'guest'), + 'vhost' => env('AMQP_VHOST', '/'), + 'concurrent' => [ + 'limit' => 1, + ], + 'pool' => [ + 'connections' => 2, + ], + 'params' => [ + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'connection_timeout' => 3, + 'read_write_timeout' => 6, + 'context' => null, + 'keepalive' => true, + 'heartbeat' => 3, + 'channel_rpc_timeout' => 0.0, + 'close_on_destruct' => false, + 'max_idle_channels' => 10, + ], + ], +]; diff --git a/config/autoload/annotations.php b/config/autoload/annotations.php new file mode 100644 index 0000000..1423a25 --- /dev/null +++ b/config/autoload/annotations.php @@ -0,0 +1,21 @@ + [ + 'paths' => [ + BASE_PATH . '/app', + ], + 'ignore_annotations' => [ + 'mixin', + ], + ], +]; diff --git a/config/autoload/aspects.php b/config/autoload/aspects.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/config/autoload/aspects.php @@ -0,0 +1,13 @@ + [ + 'driver' => Hyperf\AsyncQueue\Driver\RedisDriver::class, + 'redis' => [ + 'pool' => 'default', + ], + 'channel' => '{queue}', + 'timeout' => 2, + 'retry_seconds' => 5, + 'handle_timeout' => 10, + 'processes' => 1, + 'concurrent' => [ + 'limit' => 10, + ], + ], +]; diff --git a/config/autoload/cache.php b/config/autoload/cache.php new file mode 100644 index 0000000..def82eb --- /dev/null +++ b/config/autoload/cache.php @@ -0,0 +1,18 @@ + [ + 'driver' => Hyperf\Cache\Driver\RedisDriver::class, + 'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class, + 'prefix' => 'c:', + ], +]; diff --git a/config/autoload/commands.php b/config/autoload/commands.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/config/autoload/commands.php @@ -0,0 +1,13 @@ + [ + 'driver' => env('DB_DRIVER', 'mysql'), + 'host' => env('DB_HOST', 'localhost'), + 'database' => env('DB_DATABASE', 'hyperf'), + 'port' => env('DB_PORT', 3306), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'collation' => env('DB_COLLATION', 'utf8_unicode_ci'), + 'prefix' => env('DB_PREFIX', ''), + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + 'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60), + ], + 'commands' => [ + 'gen:model' => [ + 'path' => 'app/Model', //模型路径 + 'force_casts' => true, //是否强制重置 casts 参数 + 'inheritance' => 'Model', //父类 + 'uses' => '', //配合 inheritance 使用 + 'refresh_fillable' => true, //是否刷新 fillable 参数 + 'table_mapping' => [], //为表名 -> 模型增加映射关系 比如 ['users:Account'] + 'with_comments' => true, //是否增加字段注释 + 'property_case' => ModelOption::PROPERTY_SNAKE_CASE, + ], + ], + 'options' => [ + // 框架默认配置 + PDO::ATTR_CASE => PDO::CASE_NATURAL, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => true, + // 如果使用的为非原生 MySQL 或云厂商提供的 DB 如从库/分析型实例等不支持 MySQL prepare 协议的, 将此项设置为 true + PDO::ATTR_EMULATE_PREPARES => false, + ], + ], +]; diff --git a/config/autoload/dependencies.php b/config/autoload/dependencies.php new file mode 100644 index 0000000..434781b --- /dev/null +++ b/config/autoload/dependencies.php @@ -0,0 +1,14 @@ + App\Middleware\CoreMiddleware::class, +]; diff --git a/config/autoload/devtool.php b/config/autoload/devtool.php new file mode 100644 index 0000000..3c2f607 --- /dev/null +++ b/config/autoload/devtool.php @@ -0,0 +1,44 @@ + [ + 'amqp' => [ + 'consumer' => [ + 'namespace' => 'App\\Amqp\\Consumer', + ], + 'producer' => [ + 'namespace' => 'App\\Amqp\\Producer', + ], + ], + 'aspect' => [ + 'namespace' => 'App\\Aspect', + ], + 'command' => [ + 'namespace' => 'App\\Command', + ], + 'controller' => [ + 'namespace' => 'App\\Controller', + ], + 'job' => [ + 'namespace' => 'App\\Job', + ], + 'listener' => [ + 'namespace' => 'App\\Listener', + ], + 'middleware' => [ + 'namespace' => 'App\\Middleware', + ], + 'Process' => [ + 'namespace' => 'App\\Processes', + ], + ], +]; diff --git a/config/autoload/exceptions.php b/config/autoload/exceptions.php new file mode 100644 index 0000000..824dea8 --- /dev/null +++ b/config/autoload/exceptions.php @@ -0,0 +1,24 @@ + [ + 'http' => [ + App\Exception\Handler\ValidationExceptionHandler::class, // 自定义验证器异常接管 + App\Exception\Handler\BusinessExceptionHandler::class, // 自定义http异常接管 + Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class, + App\Exception\Handler\AppExceptionHandler::class, + ], + ], +]; diff --git a/config/autoload/listeners.php b/config/autoload/listeners.php new file mode 100644 index 0000000..8a2c7a2 --- /dev/null +++ b/config/autoload/listeners.php @@ -0,0 +1,15 @@ + Monolog\Formatter\LineFormatter::class, + 'constructor' => [ + 'format' => null, + 'dateFormat' => 'Y-m-d H:i:s', + 'allowInlineLineBreaks' => true, + 'includeStacktraces' => true, + ], + ]; +}else{ + $formatter = [ + 'class' => Monolog\Formatter\JsonFormatter::class, + 'constructor' => [], + ]; +} +return [ + 'default' => [ + 'handler' => [ + 'class' => Monolog\Handler\StreamHandler::class, + 'constructor' => [ + 'stream' => BASE_PATH . '/runtime/logs/hyperf.log', + 'level' => Monolog\Logger::DEBUG, + ], + ], + 'formatter' => $formatter, + ] +]; diff --git a/config/autoload/middlewares.php b/config/autoload/middlewares.php new file mode 100644 index 0000000..4735baa --- /dev/null +++ b/config/autoload/middlewares.php @@ -0,0 +1,28 @@ + [ + // 跨域 + CorssMiddleware::class, + + // token验证 + AuthMiddleware::class, + + // 数组内配置您的全局中间件,顺序根据该数组的顺序 + ValidationMiddleware::class + ], +]; diff --git a/config/autoload/processes.php b/config/autoload/processes.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/config/autoload/processes.php @@ -0,0 +1,13 @@ + [ + 'host' => env('REDIS_HOST', 'localhost'), + 'auth' => env('REDIS_AUTH', null), + 'port' => (int) env('REDIS_PORT', 6379), + 'db' => (int) env('REDIS_DB', 0), + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + 'max_idle_time' => (float) env('REDIS_MAX_IDLE_TIME', 60), + ], + ], +]; diff --git a/config/autoload/server.php b/config/autoload/server.php new file mode 100644 index 0000000..56f6afb --- /dev/null +++ b/config/autoload/server.php @@ -0,0 +1,46 @@ + SWOOLE_PROCESS, + 'servers' => [ + [ + 'name' => 'http', + 'type' => Server::SERVER_HTTP, + 'host' => '0.0.0.0', + 'port' => 9501, + 'sock_type' => SWOOLE_SOCK_TCP, + 'callbacks' => [ + Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'], + ], + ], + ], + 'settings' => [ + Constant::OPTION_ENABLE_COROUTINE => true, + Constant::OPTION_WORKER_NUM => swoole_cpu_num(), + Constant::OPTION_PID_FILE => BASE_PATH . '/runtime/hyperf.pid', + Constant::OPTION_OPEN_TCP_NODELAY => true, + Constant::OPTION_MAX_COROUTINE => 100000, + Constant::OPTION_OPEN_HTTP2_PROTOCOL => true, + Constant::OPTION_MAX_REQUEST => 100000, + Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024, + Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024, + ], + 'callbacks' => [ + Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], + Event::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], + Event::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'], + ], +]; diff --git a/config/autoload/snowflake.php b/config/autoload/snowflake.php new file mode 100644 index 0000000..40abc01 --- /dev/null +++ b/config/autoload/snowflake.php @@ -0,0 +1,30 @@ + MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, + RedisMilliSecondMetaGenerator::class => [ + 'pool' => 'default', + // 用于计算 WorkerId 的 Key 键 + 'key' => RedisMetaGenerator::DEFAULT_REDIS_KEY + ], + RedisSecondMetaGenerator::class => [ + 'pool' => 'default', + // 用于计算 WorkerId 的 Key 键 + 'key' => RedisMetaGenerator::DEFAULT_REDIS_KEY + ], +]; diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..5050112 --- /dev/null +++ b/config/config.php @@ -0,0 +1,75 @@ + env('APP_NAME', 'gdxz'), + 'app_env' => env('APP_ENV', 'dev'), + 'scan_cacheable' => env('SCAN_CACHEABLE', false), + StdoutLoggerInterface::class => [ + 'log_level' => [ + LogLevel::ALERT, + LogLevel::CRITICAL, + LogLevel::EMERGENCY, + LogLevel::ERROR, + LogLevel::INFO, + LogLevel::NOTICE, + LogLevel::WARNING, + ], + ], + 'jwt' => [ + "secret" => env('JWT_SECRET', ''),// 密钥 + "ttl" => env('JWT_TTL', '3600 * 24 * 70'),// 过期时间 + 'algo' => env('JWT_ALGO', 'HS256'), + ], + "easy_we_chat" => [ // 微信配置 + // 测试 + "app_id" => env('WE_CHAT_APP_ID', 'wxc83296720404aa7b'), + "secret" => env('WE_CHAT_APP_SECRET', '817665d3763637fe66d56548f8484622'), + 'http' => [ + 'throw' => false, // 状态码非 200、300 时是否抛出异常,默认为开启 + 'timeout' => 5.0, + // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri + + 'retry' => true, // 使用默认重试配置 + // 'retry' => [ + // // 仅以下状态码重试 + // 'http_codes' => [429, 500] + // // 最大重试次数 + // 'max_retries' => 3, + // // 请求间隔 (毫秒) + // 'delay' => 1000, + // // 如果设置,每次重试的等待时间都会增加这个系数 + // // (例如. 首次:1000ms; 第二次: 3 * 1000ms; etc.) + // 'multiplier' => 3 + // ], + ], + ], + "alibaba" => [// 阿里 + "dysms" => [// 阿里云大鱼短信 + "accessKey" => "LTAI4GGygjsKhyBwvvC3CghV", + "accessKeySecret" => "rcx7lO9kQxG10m8NqNPEfEtT9IS8EI", + ], + "oss" => [// 阿里云对象存储 + "accessKey" => "LTAI5tKmFrVCghcxX7yHyGhm", + "accessKeySecret" => "q1aiIZCJJuf92YbKk2cSXnPES4zx26", + "bucket" => "gdxz-hospital", + "endpoint" => "oss-cn-chengdu.aliyuncs.com", + ], + ], + 'verify_dun' =>[ // 网易易盾 + "secretId" => "a0efb0a735ca5f833d9c50075d3bd673", + "secretKey" => "bc5fc333fec0f16973bb4600cebf8f32", + "busunessId" => "", + ], +]; diff --git a/config/container.php b/config/container.php new file mode 100644 index 0000000..beb3368 --- /dev/null +++ b/config/container.php @@ -0,0 +1,21 @@ + $accessKeyId, + // 必填,您的 AccessKey Secret + "accessKeySecret" => $accessKeySecret + ]); + // 访问的域名 + $config->endpoint = "dysmsapi.aliyuncs.com"; + return new OpenApiClient($config); + } + + /** + * API 相关 + * @return Params OpenApi.Params + */ + public static function createApiInfo(): Params + { + $params = new Params([ + // 接口名称 + "action" => "SendSms", + // 接口版本 + "version" => "2017-05-25", + // 接口协议 + "protocol" => "HTTPS", + // 接口 HTTP 方法 + "method" => "POST", + "authType" => "AK", + "style" => "RPC", + // 接口 PATH + "pathname" => "/", + // 接口请求体内容格式 + "reqBodyType" => "json", + // 接口响应体内容格式 + "bodyType" => "json" + ]); + return $params; + } + + /** + * 发送短信 + * @param string $phone_numbers 手机号 + * @param array $template_param 参数 + * @param string $template_code 短信模版编码 + * @param int $scene 场景 + */ + public static function sendSms(string $phone_numbers,array $template_param,string $template_code,int $scene): void + { + $config = config("alibaba.dysms"); + + $client = self::createClient($config['accessKey'], $config['accessKeySecret']); + $params = self::createApiInfo(); + + // query params + $queries = []; + $queries["PhoneNumbers"] = $phone_numbers; + $queries["SignName"] = "肝胆相照"; + $queries["TemplateCode"] = $template_code; + $queries["TemplateParam"] = json_encode($template_param,JSON_UNESCAPED_UNICODE); + // runtime options + $runtime = new RuntimeOptions([]); + $request = new OpenApiRequest([ + "query" => OpenApiUtilClient::query($queries) + ]); + // 复制代码运行请自行打印 API 的返回值 + // 返回值为 Map 类型,可从 Map 中获得三类数据:响应体 body、响应头 headers、HTTP 返回的状态码 statusCode + $result = $client->callApi($params, $request, $runtime); + + if (empty($result)){ + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::CODE_FAIL)); + } + + if (empty($result['body'])){ + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::CODE_FAIL)); + } + + if ($result['body']['Code'] != "OK"){ + throw new BusinessException($result['body']['Message'],HttpEnumCode::CODE_FAIL); + } + + if (empty($result['body']['RequestId'])){ + // 无唯一值 + throw new BusinessException($result['body']['Message'],HttpEnumCode::CODE_FAIL); + } + + // 记录log + $data = array(); + $data['type'] = 1; + $data['status'] = 1; + $data['scene'] = $scene; + $data['phone'] = $phone_numbers; + $data['code'] = $template_code; + $data['third_code'] = $result['body']['RequestId']; + $data['remarks'] = json_encode($template_param,JSON_UNESCAPED_UNICODE); + $res = CodeLog::addCodeLog($data); + if (empty($res)){ + // 发送成功,记录失败 + throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::CODE_FAIL)); + } + } +} \ No newline at end of file diff --git a/extend/Alibaba/Oss.php b/extend/Alibaba/Oss.php new file mode 100644 index 0000000..e55d06a --- /dev/null +++ b/extend/Alibaba/Oss.php @@ -0,0 +1,82 @@ +config = config("alibaba.oss"); + } + + /** + * 创建客户端 + * @return OssClient + */ + public function createClient(): OssClient + { + try { + return new OssClient($this->config['accessKey'], $this->config['accessKeySecret'], $this->config['endpoint']); + } catch (OssException $e) { + throw new BusinessException($e->getMessage()); + } + } + + /** + * 获取签名 + * @param string $dir 用户上传文件时指定的前缀。 + * @return array + */ + public function signature(string $dir): array + { + try { + $now = time(); + $expire = 30; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。 + $end = $now + $expire; + $expiration = $this->gmt_iso8601($end); + + $start = array(0 => 'starts-with', 1 => '$key', 2 => $dir); + $conditions[] = $start; + + $arr = array('expiration' => $expiration, 'conditions' => $conditions); + $policy = json_encode($arr); + $base64_policy = base64_encode($policy); + $string_to_sign = $base64_policy; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->config['accessKeySecret'], true)); + + $response = array(); + $response['accessid'] = $this->config['accessKey']; + $response['host'] = $this->config['bucket'] . '.' . $this->config['endpoint']; + $response['policy'] = $base64_policy; + $response['signature'] = $signature; + $response['expire'] = $end; + $response['callback'] = ""; + $response['dir'] = $dir; // 这个参数是设置用户上传文件时指定的前缀。 + return $response; + + } catch (\Exception $e) { + throw new BusinessException($e->getMessage()); + } + } + + /** + * @param $time + * @return string + * @throws \Exception + */ + protected function gmt_iso8601($time): string + { + return str_replace('+00:00', '.000Z', gmdate('c', $time)); + } +} \ No newline at end of file diff --git a/extend/VerifyDun/Base.php b/extend/VerifyDun/Base.php new file mode 100644 index 0000000..d1aa891 --- /dev/null +++ b/extend/VerifyDun/Base.php @@ -0,0 +1,81 @@ +config = config("verify_dun"); + + $this->options['headers'] = [ + "Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8" + ]; + + $this->params['secretId'] = $this->config['secretId']; + $this->params['version'] = $this->version; + $this->params['timestamp'] = time() * 1000; + $this->params['nonce'] = sprintf("%d", rand()); + $this->params = $this->toUtf8($this->params); + + + + $container = ApplicationContext::getContainer(); + $this->httpRuest = $container->get(HttpRequest::class); + } + + /** + * 计算签名 + * @return string + */ + protected function gen_signature(): string + { + ksort($this->params); + $buff=""; + foreach($this->params as $key=>$value){ + if($value !== null) { + $buff .=$key; + $buff .=$value; + } + } + $buff .= $this->config['secretKey']; + return md5($buff); + } + + /** + * 将输入数据的编码统一转换成utf8 + * @param array $params 输入的参数 + * @return array + */ + function toUtf8(array $params): array + { + $utf8s = array(); + foreach ($params as $key => $value) { + $utf8s[$key] = is_string($value) ? mb_convert_encoding($value, "utf8", 'auto') : $value; + } + return $utf8s; + } +} \ No newline at end of file diff --git a/extend/VerifyDun/IdCard.php b/extend/VerifyDun/IdCard.php new file mode 100644 index 0000000..7a498ab --- /dev/null +++ b/extend/VerifyDun/IdCard.php @@ -0,0 +1,76 @@ +api_url . $this->version . '/idcard/check'; + + $this->params['businessId'] = "f7262b91aac1448a848d29c0800b109a"; + + $this->params = array_merge($this->params,$params); + + // 获取签名 + $this->params['signature'] = $this->gen_signature(); + + $this->options["form_params"] = $this->params; + + $result = $this->httpRuest->getRequest($api_url,$this->options); + + if (empty($result)){ + return "身份证认证失败"; + } + + if ($result['code'] != "200"){ + throw new BusinessException("姓名与身份证号不一致"); + } + + if (empty($result['result'])){ + return "身份证认证失败"; + } + + // 处理不通过情况 + if ($result['result']['status'] == 2){ + switch ($result['result']['reasonType']) { + case 2: + return "输入姓名和身份证号不一致"; + break; + case 3: + return "查无此身份证"; + break; + case 4: + return "身份证照片信息与输入信息不一致"; + break; + + default: + return "身份证认证失败"; + break; + } + } + + // 处理status为其他情况 + if ($result['result']['status'] != 1){ + return "身份证认证失败"; + } + + return ""; + } +} \ No newline at end of file diff --git a/hospital-deploy.sh b/hospital-deploy.sh new file mode 100644 index 0000000..470fbe8 --- /dev/null +++ b/hospital-deploy.sh @@ -0,0 +1,104 @@ +#!/bin/bash +#进入项目目录 +#cd /Users/wucongxing/Desktop/work/php/hospital-applets-api || exit +cd /data/www/hospital-applets-api || exit + +#构建env +echo " +APP_NAME=gdxz +APP_ENV=dev +DB_DRIVER=mysql +DB_HOST=123.57.91.25 +DB_PORT=3306 +DB_DATABASE=internet_hospital +DB_USERNAME=root +DB_PASSWORD=Wucongxing1.. +DB_CHARSET=utf8mb4 +DB_COLLATION=utf8mb4_unicode_ci +DB_PREFIX=gdxz_ +REDIS_HOST=123.57.91.25 +REDIS_AUTH=Wucongxing1.. +REDIS_PORT=6379 +REDIS_DB=0 +# jwt +JWT_SECRET=X8p44RvrFDlnrvHLN2juwK1sSAlFtfvdZJLLKt97DLf50W7TPOzCKDUZdVkW+PZzWIqPT8fyoXGBAcBK2faHiA== +">.env + +#nginx_upstrame="/Users/wucongxing/Desktop/test/hospital-upstream.conf" +nginx_upstrame="/etc/nginx/upstream/hospital-upstream.conf" +#echo nginx_upstrame + +#确定可使用端口 +online_port=0 +reload_port=0 + +ports_list=(9508 9509) + +for i in "${ports_list[@]}"; +do + ports_count=$(lsof -i:$i | wc -l) + if [[ $ports_count -eq 0 ]]; then + # 未占用 可使用 + reload_port=$i + fi + + if [[ $ports_count -ne 0 ]]; then + # 占用 需重启 + online_port=$i + fi +done + +if [[ $online_port == 0 ]]; then + reload_port=${ports_list[1]} +else + echo "当前端口 $online_port 使用中" + echo "重启使用端口 $reload_port" +fi + +if [[ $reload_port == 0 ]]; then + echo '部署失败, 未获取到可用端口' + exit 1; +fi + +# 定义负载 +upstrame=" +upstream hospital { + server 127.0.0.1:$reload_port; +} +" + +echo "$upstrame" > $nginx_upstrame + +#获取可用端口镜像数量 +image=$(docker images "hospital-applets-api-$reload_port" | wc -l) +if [[ $image -eq 1 ]];then + # 无可用端口镜像 + # 可用端口构建镜像 + echo '可用端口构建镜像' + docker build -t "hospital-applets-api-$reload_port" . +else + # 存在可用端口镜像,删除镜像容器 + docker rm "hospital-applets-api-$reload_port" + + echo '可用端口构建镜像' + docker build -t "hospital-applets-api-$reload_port" . +fi + +echo '启动新端口容器' +docker run --name "hospital-applets-api-$reload_port" -d -p "$reload_port":9501 "hospital-applets-api-$reload_port":latest + +echo '重启nginx' +nginx -s reload + +if [[ $online_port -ne 0 ]]; then + echo '停止原端口容器' + docker stop "hospital-applets-api-$online_port" + + echo '删除原端口容器' + docker rm "hospital-applets-api-$online_port" + + echo '删除原端口镜像' + docker rmi "hospital-applets-api-$online_port" +fi + +echo "构建成功" \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..e1d971f --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +# Magic behaviour with __get, __set, __call and __callStatic is not exactly static analyser-friendly :) +# Fortunately, You can ignore it by the following config. +# +# vendor/bin/phpstan analyse app --memory-limit 200M -l 0 +# +parameters: + reportUnmatchedIgnoredErrors: false + ignoreErrors: + - '#Static call to instance method Hyperf\\HttpServer\\Router\\Router::[a-zA-Z0-9\\_]+\(\)#' + - '#Static call to instance method Hyperf\\DbConnection\\Db::[a-zA-Z0-9\\_]+\(\)#' diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..2e5c039 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,21 @@ + + + + + ./test + + + + + ./app + + + diff --git a/test/Cases/ExampleTest.php b/test/Cases/ExampleTest.php new file mode 100644 index 0000000..6f28d24 --- /dev/null +++ b/test/Cases/ExampleTest.php @@ -0,0 +1,27 @@ +assertTrue(true); + $this->assertTrue(is_array($this->get('/'))); + } +} diff --git a/test/HttpTestCase.php b/test/HttpTestCase.php new file mode 100644 index 0000000..cabfcbf --- /dev/null +++ b/test/HttpTestCase.php @@ -0,0 +1,42 @@ +client = make(Client::class); + } + + public function __call($name, $arguments) + { + return $this->client->{$name}(...$arguments); + } +} diff --git a/test/bootstrap.php b/test/bootstrap.php new file mode 100644 index 0000000..8396ecb --- /dev/null +++ b/test/bootstrap.php @@ -0,0 +1,29 @@ +get(Hyperf\Contract\ApplicationInterface::class);