Full Code of putyy/chatgpt for AI

main 089b26b3f5ec cached
210 files
548.9 KB
168.2k tokens
510 symbols
1 requests
Download .txt
Showing preview only (640K chars total). Download the full file or copy to clipboard to get everything.
Repository: putyy/chatgpt
Branch: main
Commit: 089b26b3f5ec
Files: 210
Total size: 548.9 KB

Directory structure:
gitextract_w1gfey8a/

├── .gitignore
├── LICENSE
├── MineAdmin/
│   ├── php/
│   │   └── app/
│   │       └── Ai/
│   │           ├── Api/
│   │           │   ├── BaseApi.php
│   │           │   ├── Chat.php
│   │           │   ├── Common.php
│   │           │   ├── Login.php
│   │           │   ├── Order.php
│   │           │   ├── User.php
│   │           │   ├── Wallet.php
│   │           │   └── Websocket.php
│   │           ├── Command/
│   │           │   └── InitMenuCommand.php
│   │           ├── Constants/
│   │           │   ├── OrderConst.php
│   │           │   ├── RedisConst.php
│   │           │   ├── ResponseCodeConst.php
│   │           │   ├── UploadSceneConst.php
│   │           │   ├── VipConst.php
│   │           │   └── WalletConst.php
│   │           ├── Controller/
│   │           │   ├── AiChatMessageController.php
│   │           │   ├── AiChatSessionController.php
│   │           │   ├── AiChatgptPromptsController.php
│   │           │   ├── AiImageMaterialController.php
│   │           │   ├── AiMineMenuController.php
│   │           │   ├── AiMineMenuGroupController.php
│   │           │   ├── AiOpenaiKeyController.php
│   │           │   ├── AiOrderController.php
│   │           │   ├── AiPayKamiController.php
│   │           │   ├── AiQuickIssueController.php
│   │           │   ├── AiSettingController.php
│   │           │   └── AiUserController.php
│   │           ├── Crontab/
│   │           │   └── CheckVipOver.php
│   │           ├── Database/
│   │           │   ├── Migrations/
│   │           │   │   ├── 2023_05_04_145048_create_ai_user_table.php
│   │           │   │   ├── 2023_05_09_095456_create_ai_user_wallet_table.php
│   │           │   │   ├── 2023_05_09_095504_create_ai_user_wallet_log_table.php
│   │           │   │   ├── 2023_05_09_095525_create_ai_user_relation_table.php
│   │           │   │   ├── 2023_05_09_095540_create_ai_order_table.php
│   │           │   │   ├── 2023_05_09_095543_create_ai_order_vip_table.php
│   │           │   │   ├── 2023_05_09_102806_create_ai_mine_menu_group_table.php
│   │           │   │   ├── 2023_05_09_102817_create_ai_mine_menu_table.php
│   │           │   │   ├── 2023_05_09_154733_create_ai_chatgpt_prompts_table.php
│   │           │   │   ├── 2023_05_10_165842_create_ai_chat_message_table.php
│   │           │   │   ├── 2023_05_10_171603_create_ai_chat_session_table.php
│   │           │   │   ├── 2023_05_12_152504_create_ai_quick_issue_table.php
│   │           │   │   ├── 2023_05_19_164456_create_ai_pay_kami_table.php
│   │           │   │   ├── 2023_05_25_152855_create_ai_openai_key_table.php
│   │           │   │   ├── 2023_05_26_111034_create_ai_order_kami_table.php
│   │           │   │   └── 2023_06_14_141605_create_ai_image_material_table.php
│   │           │   └── Seeders/
│   │           │       ├── ai_chatgpt_prompts.php
│   │           │       ├── ai_mine_menu.php
│   │           │       ├── ai_mine_menu_group.php
│   │           │       └── ai_user.php
│   │           ├── Dto/
│   │           │   ├── AiChatMessageDto.php
│   │           │   ├── AiChatSessionDto.php
│   │           │   ├── AiChatgptPromptsDto.php
│   │           │   ├── AiImageMaterialDto.php
│   │           │   ├── AiMineMenuDto.php
│   │           │   ├── AiMineMenuGroupDto.php
│   │           │   ├── AiOpenaiKeyDto.php
│   │           │   ├── AiOrderDto.php
│   │           │   ├── AiPayKamiDto.php
│   │           │   ├── AiQuickIssueDto.php
│   │           │   └── AiUserDto.php
│   │           ├── Factory/
│   │           │   └── AiRedisFactory.php
│   │           ├── Mapper/
│   │           │   ├── AiChatMessageMapper.php
│   │           │   ├── AiChatSessionMapper.php
│   │           │   ├── AiChatgptPromptsMapper.php
│   │           │   ├── AiImageMaterialMapper.php
│   │           │   ├── AiMineMenuGroupMapper.php
│   │           │   ├── AiMineMenuMapper.php
│   │           │   ├── AiOpenaiKeyMapper.php
│   │           │   ├── AiOrderMapper.php
│   │           │   ├── AiPayKamiMapper.php
│   │           │   ├── AiQuickIssueMapper.php
│   │           │   └── AiUserMapper.php
│   │           ├── Middleware/
│   │           │   └── AuthMiddleware.php
│   │           ├── Model/
│   │           │   ├── AiChatMessage.php
│   │           │   ├── AiChatSession.php
│   │           │   ├── AiChatgptPrompts.php
│   │           │   ├── AiImageMaterial.php
│   │           │   ├── AiMineMenu.php
│   │           │   ├── AiMineMenuGroup.php
│   │           │   ├── AiOpenaiKey.php
│   │           │   ├── AiOrder.php
│   │           │   ├── AiOrderKami.php
│   │           │   ├── AiOrderVip.php
│   │           │   ├── AiPayKami.php
│   │           │   ├── AiQuickIssue.php
│   │           │   ├── AiUser.php
│   │           │   ├── AiUserRelation.php
│   │           │   ├── AiUserWallet.php
│   │           │   └── AiUserWalletLog.php
│   │           ├── Request/
│   │           │   ├── AiChatMessageRequest.php
│   │           │   ├── AiChatSessionRequest.php
│   │           │   ├── AiChatgptPromptsRequest.php
│   │           │   ├── AiImageMaterialRequest.php
│   │           │   ├── AiMineMenuGroupRequest.php
│   │           │   ├── AiMineMenuRequest.php
│   │           │   ├── AiOpenaiKeyRequest.php
│   │           │   ├── AiOrderRequest.php
│   │           │   ├── AiPayKamiRequest.php
│   │           │   ├── AiQuickIssueRequest.php
│   │           │   └── AiUserRequest.php
│   │           ├── Service/
│   │           │   ├── AiChatMessageService.php
│   │           │   ├── AiChatSessionService.php
│   │           │   ├── AiChatgptPromptsService.php
│   │           │   ├── AiImageMaterialService.php
│   │           │   ├── AiLoginService.php
│   │           │   ├── AiMineMenuGroupService.php
│   │           │   ├── AiMineMenuService.php
│   │           │   ├── AiOpenaiKeyService.php
│   │           │   ├── AiOrderService.php
│   │           │   ├── AiPayKamiService.php
│   │           │   ├── AiQuickIssueService.php
│   │           │   ├── AiSettingService.php
│   │           │   ├── AiUserService.php
│   │           │   ├── AiVipService.php
│   │           │   ├── AiWalletService.php
│   │           │   ├── HelperService.php
│   │           │   └── QiniuService.php
│   │           └── config.json
│   └── vue/
│       └── src/
│           ├── api/
│           │   └── ai/
│           │       ├── aiChatMessage.js
│           │       ├── aiChatSession.js
│           │       ├── aiChatgptPrompts.js
│           │       ├── aiImageMaterial.js
│           │       ├── aiMineMenu.js
│           │       ├── aiMineMenuGroup.js
│           │       ├── aiOpenaiKey.js
│           │       ├── aiOrder.js
│           │       ├── aiPayKami.js
│           │       ├── aiQuickIssue.js
│           │       ├── aiSetting.js
│           │       └── aiUser.js
│           ├── components/
│           │   └── putyy/
│           │       └── pt-upload.vue
│           ├── config/
│           │   ├── pt-const.js
│           │   └── pt-scene.js
│           ├── utils/
│           │   └── pt-upload.js
│           └── views/
│               └── ai/
│                   ├── chatMessage/
│                   │   └── index.vue
│                   ├── chatSession/
│                   │   └── index.vue
│                   ├── chatgptPrompts/
│                   │   └── index.vue
│                   ├── imageMaterial/
│                   │   └── index.vue
│                   ├── mineMenu/
│                   │   └── index.vue
│                   ├── mineMenuGroup/
│                   │   └── index.vue
│                   ├── openKey/
│                   │   ├── components/
│                   │   │   └── add.vue
│                   │   └── index.vue
│                   ├── order/
│                   │   └── index.vue
│                   ├── payKami/
│                   │   ├── components/
│                   │   │   └── add.vue
│                   │   └── index.vue
│                   ├── quickIssue/
│                   │   └── index.vue
│                   ├── setting/
│                   │   └── index.vue
│                   └── user/
│                       ├── components/
│                       │   └── openVip.vue
│                       └── index.vue
├── README.md
└── UniApp/
    ├── .gitignore
    ├── App.vue
    ├── README.md
    ├── androidPrivacy.json
    ├── common/
    │   ├── api.ts
    │   ├── const.ts
    │   ├── func.ts
    │   └── utils/
    │       ├── jump.ts
    │       ├── request.ts
    │       └── services.ts
    ├── components/
    │   ├── AgreementPopup.vue
    │   ├── FooterCommon.vue
    │   ├── Nothing.vue
    │   ├── OpenVipPopup.vue
    │   ├── QrCodePopup.vue
    │   └── Search.vue
    ├── config.example.ts
    ├── index.html
    ├── logic/
    │   └── user.ts
    ├── main.js
    ├── manifest.json
    ├── pages/
    │   ├── chatgpt/
    │   │   ├── channel.vue
    │   │   └── room.vue
    │   ├── login.vue
    │   ├── notice.vue
    │   └── user/
    │       ├── friend.vue
    │       ├── mine.vue
    │       ├── order.vue
    │       ├── perfect.vue
    │       ├── wallet.vue
    │       ├── walletList.vue
    │       └── withdrawalList.vue
    ├── pages.json
    ├── store/
    │   ├── index.ts
    │   └── websocket.ts
    ├── tsconfig.json
    ├── types/
    │   └── global.d.ts
    ├── uni.promisify.adaptor.js
    ├── uni.scss
    └── uni_modules/
        ├── bt-cropper_3.0.1/
        │   ├── changelog.md
        │   ├── components/
        │   │   └── bt-cropper/
        │   │       ├── bt-cropper.vue
        │   │       ├── iconfont.css
        │   │       ├── js/
        │   │       │   └── touchs.js
        │   │       ├── utils/
        │   │       │   └── tools.js
        │   │       └── {ages.json
        │   ├── package.json
        │   └── readme.md
        └── mp-html/
            ├── README.md
            ├── changelog.md
            ├── components/
            │   └── mp-html/
            │       ├── emoji/
            │       │   └── index.js
            │       ├── highlight/
            │       │   ├── config.js
            │       │   └── index.js
            │       ├── markdown/
            │       │   └── index.js
            │       ├── mp-html.vue
            │       ├── node/
            │       │   └── node.vue
            │       └── parser.js
            ├── package.json
            └── static/
                └── app-plus/
                    └── mp-html/
                        ├── js/
                        │   └── handler.js
                        └── local.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/.idea/
/.vscode/
/.hbuilderx/
/test

================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: MineAdmin/php/app/Ai/Api/BaseApi.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use Hyperf\DbConnection\Db;
use Mine\MineController;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;

class BaseApi extends MineController
{
    public function checkParameter(array $params, array $checkData = [], bool $is_set = false): bool
    {
        if (empty($checkData)) {
            return true;
        }

        if ($is_set) {
            foreach ($checkData as $v) {
                if (!isset($params[$v])) {
                    return false;
                }
            }
        } else {
            foreach ($checkData as $v) {
                if (empty($params[$v])) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * @throws ContainerExceptionInterface
     * @throws \Throwable
     * @throws NotFoundExceptionInterface
     */
    public function funCallbackRes(callable $callback): ResponseInterface
    {
        return $this->success($this->funCallback($callback));
    }

    public function funCallback(callable $callback)
    {
        Db::beginTransaction();
        try {
            $res = $callback();
            Db::commit();
        } catch (\Throwable $throwable) {
            Db::rollBack();
            throw $throwable;
        }
        return $res;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Api/Chat.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use App\Ai\Middleware\AuthMiddleware;
use App\Ai\Service\AiChatgptPromptsService;
use App\Ai\Service\AiChatMessageService;
use App\Ai\Service\AiChatSessionService;
use App\Ai\Service\AiLoginService;
use App\Ai\Service\AiOpenaiKeyService;
use App\Ai\Service\AiQuickIssueService;
use Hyperf\Context\ApplicationContext;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Engine\Http\EventStream;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Orhanerday\OpenAi\OpenAi;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: "ai/api/chat")]
#[Middleware(AuthMiddleware::class)]
class Chat extends BaseApi
{
    #[Inject]
    protected AiLoginService $loginService;

    #[Inject]
    protected AiChatgptPromptsService $chatgptPromptsService;

    #[Inject]
    protected AiChatSessionService $chatSessionService;

    #[Inject]
    protected AiChatMessageService $chatMessageService;

    #[Inject]
    protected AiQuickIssueService $quickIssueService;

    #[GetMapping("roles")]
    public function roles(): ResponseInterface
    {
        return $this->success([
            'list' => $this->chatgptPromptsService->getList([
                'select'    => 'id,act,prompt',
                'orderBy'   => 'sort',
                'orderType' => 'desc',
            ], false)
        ]);
    }

    #[GetMapping("model-list")]
    public function modelList(): ResponseInterface
    {
        return $this->success(AiChatgptPromptsService::MODEL_LIST);
    }

    #[GetMapping("session")]
    public function session(): ResponseInterface
    {
        return $this->success($this->chatSessionService->session($this->request->all()));
    }

    #[PostMapping("session-close")]
    public function sessionClose(): ResponseInterface
    {
        return $this->success([
            'sid' => $this->chatSessionService->sessionClose($this->request->all())
        ]);
    }

    #[GetMapping("messages")]
    public function messages(): ResponseInterface
    {
        // next、prev
        $sid     = $this->request->query('sid');
        $session = $this->chatSessionService->mapper->session([
            'id'  => $sid,
            'uid' => $this->loginService->getId()
        ]);
        if (empty($session)) {
            return $this->success([
                'list' => []
            ]);
        }
        return $this->success([
            'list' => $this->chatMessageService->messages($this->request->all())
        ]);
    }

    #[GetMapping("session-history")]
    public function sessionHistory(): ResponseInterface
    {
        return $this->success([
            'list' => $this->chatSessionService->sessionHistory($this->request->all())
        ]);
    }

    #[PostMapping("session-share")]
    public function sessionShare(): ResponseInterface
    {
        $model = $this->chatSessionService->mapper->session([
            'id'  => $this->request->post('id'),
            'uid' => $this->loginService->getId()
        ]);

        if (empty($model) || ($this->request->post('is_share', false) && $model->share === 2)) {
            return $this->success();
        }
        $model->share = $model->share === 1 ? 2 : 1;
        $model->save();
        return $this->success();
    }

    #[PostMapping("session-delete")]
    public function sessionDelete(): ResponseInterface
    {
        $model = $this->chatSessionService->mapper->session([
            'id'  => $this->request->post('id'),
            'uid' => $this->loginService->getId()
        ]);
        if (empty($model)) {
            return $this->success();
        }
        $model->delete();
        $this->chatMessageService->mapper->getModel()::where([
            'sid' => $this->request->post('id')
        ])->delete();
        return $this->success();
    }

    #[GetMapping("session-share-list")]
    public function sessionShareList(): ResponseInterface
    {
        return $this->success([
            'list' => $this->chatSessionService->sessionShareList($this->request->all())
        ]);
    }

    #[GetMapping("session-share-message-list")]
    public function sessionShareMessageList(): ResponseInterface
    {
        $sid     = (int)$this->request->query('sid');
        $session = $this->chatSessionService->read($sid);
        if (empty($session) || $session->share === 1) {
            return $this->success(['list' => []]);
        }
        return $this->success([
            'list' => $this->chatMessageService->shareMessageList($this->request->all())
        ]);
    }

    #[GetMapping("quick-issue")]
    public function quickIssue(): ResponseInterface
    {
        return $this->success([
            'list' => $this->quickIssueService->getList([
                'select'    => 'id,title,content',
                'orderBy'   => 'id',
                'orderType' => 'desc',
            ], false)
        ]);
    }

//    #[GetMapping("test")]
    public function test()
    {

        $token = $this->request->query('x-token', null);
        if ($token) {
            $token = 'Bearer ' . $token;
            //todo 验证
        }

        $opts = [
            'model'             => 'gpt-3.5-turbo',
            'messages'          => [],
            'temperature'       => 1.0,
            'max_tokens'        => 150,
            'frequency_penalty' => 0,
            'presence_penalty'  => 0,
            'stream'            => true,
        ];
        $opts['messages'][] = ['role' => 'system', 'content' => "你是一个AI助手,我需要你模拟一名温柔贴心的女朋友来回答我的问题。"];
        $opts['messages'][] = [
            'role'    => 'user',
            'content' => 'php如何计算1+1?',
        ];
        $response      = ApplicationContext::getContainer()->get(\Hyperf\HttpServer\Contract\ResponseInterface::class);
        $eventStream   = new EventStream($response->getConnection(), $response);
        $openAiService = ApplicationContext::getContainer()->get(AiOpenaiKeyService::class);
        $key           = $openAiService->openAiKey();
        $openAI        = new OpenAi($key);
        $baseUrl       = $openAiService->openaiProxy();
        $baseUrl && $openAI->setBaseURL($baseUrl);
        $openAI->setHeader(["Content-Type" => "text/event-stream"]);
        // 本次所有结果
        $replyContent = '';
        $openAI->chat($opts, function ($curl_info, $data) use ($eventStream, &$replyContent) {
            $datas = explode('data: ', $data);
            foreach ($datas as $dataStr) {
                $arrayData = json_decode($dataStr, true);
                if ($arrayData) {
                    if (isset($arrayData['choices'][0]['delta']['content'])) {
                        $replyContent .= ($content = $arrayData['choices'][0]['delta']['content'] ?? '');
                        $eventStream->write("data: " . json_encode([
                                'status' => 1,
                                'content' => $content,
                            ]) . PHP_EOL . PHP_EOL
                        );
                    } elseif (!empty($arrayData['choices'][0]['finish_reason'])) {
                        $eventStream->write("data: " . json_encode([
                                'status' => 2,
                                'content' => '',
                            ]) . PHP_EOL . PHP_EOL
                        );
                    } elseif (isset($arrayData['error'])) {
                        $eventStream->write("data: " . json_encode([
                                'status' => 0,
                                'content' => $arrayData['error']['message'],
                            ]) . PHP_EOL . PHP_EOL
                        );
                    }
                }
            }
            return \strlen($data);
        });
        return "data: " . PHP_EOL . PHP_EOL;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Api/Common.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use App\Ai\Constants\VipConst;
use App\Ai\Service\AiLoginService;
use App\Ai\Service\AiSettingService;
use App\Ai\Service\AiVipService;
use App\Ai\Middleware\AuthMiddleware;
use App\Ai\Constants\UploadSceneConst;
use App\Ai\Service\QiniuService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: "ai/api/public")]
#[Middleware(AuthMiddleware::class)]
class Common extends BaseApi
{
    #[Inject]
    protected QiniuService $qiniuService;

    #[Inject]
    protected AiLoginService $loginService;

    #[Inject]
    protected AiVipService $vipService;

    #[Inject]
    protected AiSettingService $settingService;

    /**
     * 全局场景值
     */
    #[GetMapping("init")]
    public function init(): ResponseInterface
    {
        $data = [];
        // 图片资源上传
        $data['scene'] = [
            'upload' => [
                'image'  => array_filter(UploadSceneConst::ImageScene, function ($key) {
                    return str_starts_with($key, 'ai_');
                }, ARRAY_FILTER_USE_KEY),
                // 远端访问主域名, 用于前端上传时判断是否本地文件
                'domain' => config('file.storage.qiniu.host'),
            ],
            'tutorials' => [],
            'agreement' => [
                'user' => $this->settingService->agreementUser(),
            ],
            'ads' => [],
        ];

        $data['other'] = [
            'copyright'     => 'Copyright © 1999 - ' . date('Y') . ' ByAi',
            'version'       => Login::VERSIONS,
            'customer_info' => $this->settingService->customer(),
        ];
        return $this->success($data);
    }

    #[GetMapping("upload-token")]
    public function uploadToken(): ResponseInterface
    {
        return $this->success($this->qiniuService->token($this->request->query('scenes')));
    }

    #[GetMapping("vip-config")]
    public function vipConfig(): ResponseInterface
    {
        [$config, $user] = $this->vipService->config($this->loginService->getId());
        $configCp = array_column(VipConst::config(), null, 'level');
        $data = [
            'equity' => [
                [
                    [
                        'text'  => '特权',
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP]['name'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_ONE]['name'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_TWO]['name'],
                        'color' => '',
                    ],
                ],
                [
                    [
                        'text'  => '使用时长(月)',
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP]['length'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_ONE]['length'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_TWO]['length'],
                        'color' => 'red',
                    ],
                ],
                [
                    [
                        'text'  => 'VIP抵扣包',
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP]['wrap_vip'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_ONE]['wrap_vip'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_TWO]['wrap_vip'],
                        'color' => 'red',
                    ],
                ],
                [
                    [
                        'text'  => '推广赚(%)',
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP]['income'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_ONE]['income'],
                        'color' => '',
                    ],
                    [
                        'text'  => $configCp[VipConst::VIP_TWO]['income'],
                        'color' => 'red',
                    ],
                ],
                [
                    [
                        'text'  => '聊天上下文',
                        'color' => '',
                    ],
                    [
                        'text'  => '不支持',
                        'color' => '',
                    ],
                    [
                        'text'  => '支持',
                        'color' => '',
                    ],
                    [
                        'text'  => '支持',
                        'color' => 'red',
                    ],
                ],
                [
                    [
                        'text'  => '每日次数',
                        'color' => '',
                    ],
                    [
                        'text'  => '19',
                        'color' => '',
                    ],
                    [
                        'text'  => '无限',
                        'color' => '',
                    ],
                    [
                        'text'  => '无限',
                        'color' => 'red',
                    ],
                ],
                [
                    [
                        'text'  => '总价值',
                        'color' => '',
                    ],
                    [
                        'text'  => '1000+',
                        'color' => '',
                    ],
                    [
                        'text'  => '3000+',
                        'color' => '',
                    ],
                    [
                        'text'  => '5000+',
                        'color' => 'red',
                    ],
                ],
            ],
            'config' => $config,
            'user'   => $user->toArray(),
        ];

        return $this->success($data);
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Api/Login.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use App\Ai\Model\AiUser;
use App\Ai\Model\AiUserRelation;
use App\Ai\Model\AiUserWallet;
use App\Ai\Service\AiLoginService;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;

#[Controller(prefix: "ai/api/login")]
class Login extends BaseApi
{
    public const VERSIONS = '0.0.1';

    #[Inject]
    protected AiLoginService $loginService;

    #[GetMapping("index")]
    public function index()
    {
        try {
            $user_name = $this->request->query('user_name');
            $vid       = (int)$this->request->query('vid');
            $password  = $this->request->query('password');
            if (!$user_name || !$password){
                return $this->error('参数错误!');
            }
            /**
             * @var AiUser $user
             */
            $user     = AiUser::where(['mobile'=>$user_name, 'is_lock'=>1])->first();
            $password = md5($password);
            if (!empty($user) && $password !== $user->password){
                return $this->error('密码错误!');
            }

            if (empty($user)){
                if (empty($vid)) {
                    return $this->error('账号不存在!');
                }else{
                    /**
                     * @var AiUser $pUser
                     */
                    $pUser = AiUser::where(['id'=>$vid, 'is_lock'=>1])->select(['id'])->first();
                    if (empty($pUser)) {
                        return $this->error('邀请用户有误!');
                    }
                    // 注册
                    Db::beginTransaction();
                    try {
                        $user            = new AiUser();
                        $user->nick_name = '';
                        $user->head_img  = '';
                        $user->mobile    = $user_name;
                        $user->password  = $password;
                        $user->save();
                        AiUserRelation::insert([
                            'uid'       => $user->id,
                            'from_uid' => $pUser->id,
                        ]);
                        AiUserWallet::insert([
                            'uid' => $user->id,
                        ]);
                        Db::commit();
                    }catch (\Throwable $exception){
                        Db::rollBack();
                        return $this->error('注册失败!');
                    }
                }
            }

            $data            = [];
            $data['version'] = self::VERSIONS;
            $data['id']      = $user->id;
            $data['vip']     = $user->vip;
            $token           = $this->loginService->getToken($data);
            return $this->success([
                'token'        => $token,
                'version'      => self::VERSIONS,
                'check_status' => false,
                'login_time'   => time(),
            ]);
        }catch (\Throwable $exception){
            return $this->error($exception->getMessage());
        }
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Api/Order.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use App\Ai\Constants\OrderConst;
use App\Ai\Middleware\AuthMiddleware;
use App\Ai\Service\AiOrderService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: "ai/api/order")]
#[Middleware(AuthMiddleware::class)]
class Order extends BaseApi
{
    #[Inject]
    protected AiOrderService $orderService;

    #[GetMapping("list")]
    public function index(): ResponseInterface
    {
        $param = $this->request->all();
        $param['ord_type'] = [OrderConst::OPEN_VIP, OrderConst::MARKET];
        return $this->success([
            'list' => $this->orderService->orderList($param)
        ]);
    }

    #[PostMapping("kami-open-vip")]
    public function kamiOpenVip(): ResponseInterface
    {
        $this->orderService->kamiOpenVip($this->request->all());
        return $this->success();
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Api/User.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use App\Ai\Constants\ResponseCodeConst;
use App\Ai\Constants\VipConst;
use App\Ai\Model\AiUser;
use App\Ai\Service\AiImageMaterialService;
use App\Ai\Service\AiLoginService;
use App\Ai\Middleware\AuthMiddleware;
use App\Ai\Service\AiMineMenuGroupService;
use App\Ai\Service\AiUserService;
use App\Ai\Service\HelperService;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Mine\Exception\NormalStatusException;
use Mine\Helper\MineCode;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: "ai/api/user")]
#[Middleware(AuthMiddleware::class)]
class User extends BaseApi
{
    #[Inject]
    protected AiLoginService $loginService;

    #[Inject]
    protected AiUserService $userService;

    #[Inject]
    protected AiMineMenuGroupService $mineMenuGroupService;

    #[Inject]
    protected AiImageMaterialService $imageMaterialService;

    #[GetMapping("mine")]
    public function mine()
    {
        /**
         * @var AiUser $user
         */
        $user  = $this->userService->read($this->loginService->getId());
        return $this->success([
            'head_img'   => $user->head_img,
            'nick_name'  => $user->nick_name,
            'uid'        => $user->id,
            'mobile'     => $user->mobile,
            'vip'        => $user->vip,
            'vip_name'   => VipConst::getDesc($user->vip),
            'vip_ent_at' => $user->vip_ent_at ? strtotime($user->vip_ent_at) : 0,
            'amount'     => $user->wallet->balance ? HelperService::decode100($user->wallet->balance) : 0,
            'friend_num' => $this->userService->friendNum($user->id),
            'menus'      => $this->mineMenuGroupService->mineMenus(),
            'banner'     => $this->imageMaterialService->mine(1),
        ]);
    }

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws \Throwable
     */
    #[PostMapping("edit")]
    public function edit(): ResponseInterface
    {
        $post = $this->request->post();
        if (!$this->checkParameter($post, ['mobile', 'head_img', 'nick_name'])) {
            throw new NormalStatusException('参数错误', ResponseCodeConst::PARAM_FAILED);
        }
        return $this->funCallbackRes(function () use ($post) {
            $this->userService->update($this->loginService->getId(), [
                'nick_name' => $post['nick_name'],
                'head_img' => HelperService::buildSavePath($post['head_img']),
                'mobile' => $post['mobile'],
            ]);
            return '';
        });
    }

    #[GetMapping("friends")]
    public function friends(): ResponseInterface
    {
        return $this->success([
            'list'=>$this->userService->friendList($this->request->all())
        ]);
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Api/Wallet.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use App\Ai\Constants\OrderConst;
use App\Ai\Middleware\AuthMiddleware;
use App\Ai\Service\AiOrderService;
use App\Ai\Service\AiWalletService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: "ai/api/wallet")]
#[Middleware(AuthMiddleware::class)]
class Wallet extends BaseApi
{
    #[Inject]
    protected AiWalletService $walletService;

    #[Inject]
    protected AiOrderService $orderService;

    #[GetMapping("index")]
    public function index(){
        return $this->success($this->walletService->info());
    }

    #[GetMapping("change-log-list")]
    public function changeLogList(): ResponseInterface
    {
        return $this->success([
            'list'=>$this->walletService->changeLogList($this->request->all())
        ]);
    }

    #[GetMapping("withdrawal-list")]
    public function withdrawalList(): ResponseInterface
    {
        $param = $this->request->all();
        $param['ord_type'] = [OrderConst::WITHDRAWAL];
        return $this->success([
            'list'=>$this->orderService->orderList($param)
        ]);
    }

    #[PostMapping("withdrawal")]
    public function withdrawal(): ResponseInterface
    {
        $this->walletService->withdrawal($this->request->all());
        return $this->success();
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Api/Websocket.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Api;

use App\Ai\Constants\RedisConst;
use App\Ai\Constants\VipConst;
use App\Ai\Factory\AiRedisFactory;
use App\Ai\Service\AiChatgptPromptsService;
use App\Ai\Service\AiChatMessageService;
use App\Ai\Service\AiLoginService;
use App\Ai\Service\AiOpenaiKeyService;
use App\Ai\Service\AiSettingService;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Engine\WebSocket\Opcode;
use Hyperf\Server\ServerFactory;
use Orhanerday\OpenAi\OpenAi;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\WebSocket\Server;
use Swoole\WebSocket\Server as WebSocketServer;
use Psr\Container\ContainerInterface;

class Websocket implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{
    #[Inject]
    protected AiLoginService $loginService;

    #[Inject]
    protected ContainerInterface $container;

    #[Inject]
    protected AiRedisFactory $redis;

    #[Inject]
    protected AiOpenaiKeyService $openAiService;

    #[Inject]
    protected AiSettingService $settingService;

    #[Inject]
    protected AiChatgptPromptsService $chatgptPromptsService;

    #[Inject]
    protected AiChatMessageService $chatMessageService;

    public function onMessage($server, $frame): void
    {
        if($frame->opcode == Opcode::PING) {
            // 如果使用协程 Server,在判断是 PING 帧后,需要手动处理,返回 PONG 帧。
            // 异步风格 Server,可以直接通过 Swoole 配置处理,详情请见 https://wiki.swoole.com/#/websocket_server?id=open_websocket_ping_frame
            $server->push('', Opcode::PONG);
            return;
        }
        $data = \json_decode($frame->data);
        // todo {model: "1:gpt3.5问答模式 2文心一言问答模式 3通义千问问答模式", role_id: 1, message:"",}
        switch ($data->type){
            case 'ping':
                $server->push($frame->fd, '{"type":"ping","content":"ok"}');
                break;
            case 'message':
                $this->messageHandle($frame->fd, $data);
                break;
        }
    }

    public function messageHandle($fd, $data)
    {
        switch ($data->model->index){
            case 0:
            case 1:
                // chatgpt 3.5
                // todo 存入消息,请求openapi 返回结果 结果入表
                \Hyperf\Coroutine\go(function () use($fd, $data){
                    $this->chatgpt($fd, $data);
                });
                break;
        }

    }

    protected function chatgpt($fd, $data){
        try {
            /**
             * @var WebSocketServer $server
             */
            $server  = $this->container->get(ServerFactory::class)->getServer()->getServer();
            // todo 验证会话id是否属于当前用户uid
            if (mb_strlen($data->content) > 2048) {
                $server->push($fd, '{"type":"error","content":"您输入的内容过长","status":true}');
                return;
            }
            $user = $this->redis->hGetAll(RedisConst::FD_TO_USER . $fd);
            // 免费会员限制会话
            $time = time();
            $todayKey = RedisConst::USER_SPOKE_TODAY . date('Ymd');
            $incr = $this->redis->zIncrBy($todayKey, 1, $user['uid']);
            $this->redis->expire($todayKey, 86400);
            if ($user['vip'] === VipConst::FREE && $incr > 10) {
                $server->push($fd, '{"type":"error","content":"您今日已经超过免费会员次数了哦!","status":true}');
                return;
            }

            $prompt = $this->chatgptPromptsService->mapper->first(['id'=>$data->prompt_id], ['id', 'act', 'prompt']);

            $opts = [
                'model'             => AiChatgptPromptsService::MODEL_LIST[$data->model->index]['text'],
                'messages'          => [],
                'temperature'       => $data->model->temperature,
                'frequency_penalty' => $data->model->frequency_penalty,
                'presence_penalty'  => $data->model->presence_penalty,
                'stream'            => true,
            ];

            if (AiChatgptPromptsService::MODEL_LIST[$data->model->index]['is_vip'] && !$user['vip']) {
                $opts['model'] = AiChatgptPromptsService::MODEL_LIST[0]['text'];
                $opts['max_tokens'] = 2048;
            } else if (!$user['vip']) {
                $opts['max_tokens'] = 2048;
            }

            $opts['messages'][] = ['role' => 'system', 'content' => $prompt->prompt];

            if (!empty($data->context) && $user['vip'] > VipConst::FREE){
                $i = 0;
                foreach ($data->context as $msg) {
                    $opts['messages'][] = [
                        'role'    => 'user',
                        'content' => $msg->content,
                    ];
                    $opts['messages'][] = [
                        'role'    => 'assistant',
                        'content' => $msg->reply_content,
                    ];
                    if (++$i > 6) {
                        break;
                    }
                }
            }

            $opts['messages'][] = [
                'role'    => 'user',
                'content' => $data->content,
            ];
            $key     = $this->openAiService->openAiKey();
            $openAI  = new OpenAi($key);
            $baseUrl = $this->settingService->openaiProxy();
            $baseUrl && $openAI->setBaseURL($baseUrl);
            $openAI->setHeader(["Content-Type"=>"text/event-stream"]);
            // 本次所有结果
            $replyContent = '';
            $openAI->chat($opts, function ($curl_info, $data) use ($fd, $server, &$replyContent) {
                $datas = explode('data: ', $data);
                foreach ($datas as $dataStr) {
                    $arrayData = json_decode($dataStr, true);
                    if ($arrayData) {
                        if (isset($arrayData['choices'][0]['delta']['content'])) {
                            $replyContent .= ($content = $arrayData['choices'][0]['delta']['content'] ?? '');
                            $server->push($fd, json_encode([
                                'type'    => 'message',
                                'content' => $content,
                                'status'  => false,
                            ], JSON_UNESCAPED_UNICODE));
                        } elseif (!empty($arrayData['choices'][0]['finish_reason'])) {
                            $server->push($fd, '{"type":"message","content":"","status":true}');
                        } elseif (isset($arrayData['error'])) {
                            $server->push($fd, '{"type":"error","content":"' . ($arrayData['error']['message'] ?? '') . '","status":true}');
                        }
                    }
                }
                return \strlen($data);
            });

            $date = date('Y-m-d H:i:s', $time);
            $this->chatMessageService->save([
                'role'             => 2,
                'sid'              => $data->sid ?: 1,
                'content'          => htmlspecialchars($data->content),
                'reply_content'    => $replyContent  ? htmlspecialchars($replyContent) : '',
                'reply_at'         => $date,
                'created_at'       => $date,
            ]);

            $server->push($fd, '{"type":"message","content":"","status":true}');
        }catch (\Throwable $exception){
            $server->push($fd, '{"type":"error","content":"'.$exception->getMessage().'","status":true}');
        }
    }

    public function onClose($server, int $fd, int $reactorId): void
    {
        try {
            // 解除绑定fd
            $user = $this->redis->hGetAll(RedisConst::FD_TO_USER . $fd);
            if (!empty($user['uid'])) {
                $this->redis->zRem(RedisConst::USER_TO_FD, $user['uid']);
            }
            $this->redis->del(RedisConst::FD_TO_USER . $fd);
        }catch (\Throwable $exception){

        }
    }

    /**
     * @param Response|Server $server
     * @param Request $request
     * @throws \RedisException
     */
    public function onOpen($server, $request): void
    {
        try {

            $token = $request->get['token'] ?? '';
            if (empty($token)){
                $server->push($request->fd, '{"type":"login","content":"token无效1"}');
                $server->close();
                return;
            }

            if (false === $this->loginService->check($token, 'ai')) {
                $server->push($request->fd, '{"type":"login","content":"token无效2"}');
                $server->close();
                return;
            }

            $userInfo = $this->loginService->getInfo($token);
            if (empty($userInfo['id'])){
                $server->push($request->fd, '{"type":"login","content":"token无效3"}');
                $server->close();
                return;
            }

            $this->redis->zAdd(RedisConst::USER_TO_FD, $request->fd, $userInfo['id']);
            $this->redis->hMSet(RedisConst::FD_TO_USER . $request->fd, [
                'uid' => $userInfo['id'],
                'vip' => $userInfo['vip'] ?? 0,
            ]);
            $this->redis->expire(RedisConst::USER_TO_FD, 86400);
            $this->redis->expire(RedisConst::FD_TO_USER . $request->fd, 86400);
            $server->push($request->fd, '{"type":"opened","content":"ok"}');
        } catch (\Throwable $exception) {
            $server->push($request->fd, '{"type":"error","content":"' . $exception->getMessage() . '"}');
        }
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Command/InitMenuCommand.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Command;

use App\System\Model\SystemMenu;
use Hyperf\Command\Command as HyperfCommand;
use Hyperf\Command\Annotation\Command;
use Hyperf\DbConnection\Db;

#[Command]
class InitMenuCommand extends HyperfCommand
{

    /**
     * 执行的命令行
     */
    protected ?string $name = 'ai:init-menu';

    public function handle()
    {
        // TODO: Implement handle() method.
        $isInit = SystemMenu::where(['parent_id' => 0, 'level' => 0, 'code' => 'aiapp',])->first();
        if (!empty($isInit)) {
            $this->line('已经执行过了', 'info');
            return;
        }
        $tableName = env('DB_PREFIX') . SystemMenu::getModel()->getTable();

        $sql = "INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (0, '0', 'AI系统', 'aiapp', 'IconFire', 'ai', NULL, NULL, 2, 'M', 1, 96, 1, 1, now(), now(), NULL, NULL);
SET @topid := LAST_INSERT_ID();
SET @toplevel := CONCAT('0', ',', @topid);

-- chatgptPrompts --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, 'chatgpt角色', 'ai:chatgptPrompts', 'IconUser', 'ai/chatgptPrompts', 'ai/chatgptPrompts/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'chatgpt角色列表', 'ai:chatgptPrompts:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'chatgpt角色更新', 'ai:chatgptPrompts:update', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'chatgpt角色保存', 'ai:chatgptPrompts:save', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'chatgpt角色读取', 'ai:chatgptPrompts:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'chatgpt角色删除', 'ai:chatgptPrompts:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);

-- chatMessage --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '聊天数据', 'ai:chatMessage', 'IconNotification', 'ai/chatMessage', 'ai/chatMessage/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '聊天数据列表', 'ai:chatMessage:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '聊天数据读取', 'ai:chatMessage:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '聊天数据删除', 'ai:chatMessage:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);

-- chatSession -- 
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '问答会话', 'ai:chatSession', 'IconSend', 'ai/chatSession', 'ai/chatSession/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '问答会话列表', 'ai:chatSession:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '问答会话读取', 'ai:chatSession:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '问答会话删除', 'ai:chatSession:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);

-- mineMenuGroup --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, 'Mine菜单分组', 'ai:mineMenuGroup', 'IconMenuUnfold', 'ai/mineMenuGroup', 'ai/mineMenuGroup/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单分组列表', 'ai:mineMenuGroup:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单分组保存', 'ai:mineMenuGroup:save', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单分组更新', 'ai:mineMenuGroup:update', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单分组读取', 'ai:mineMenuGroup:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单分组删除', 'ai:mineMenuGroup:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);

-- mineMenu --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, 'Mine菜单', 'ai:mineMenu', 'IconSelectAll', 'ai/mineMenu', 'ai/mineMenu/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单列表', 'ai:mineMenu:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单保存', 'ai:mineMenu:save', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单更新', 'ai:mineMenu:update', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单读取', 'ai:mineMenu:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '个人中心菜单删除', 'ai:mineMenu:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);

-- order --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '订单列表', 'ai:order', 'icon-home', 'ai/order', 'ai/order/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '订单表列表', 'ai:order:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '订单表读取', 'ai:order:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '订单表删除', 'ai:order:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);

-- quickIssue --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '快捷问题', 'ai:quickIssue', 'IconExclamationCircle', 'ai/quickIssue', 'ai/quickIssue/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '快捷问题列表', 'ai:quickIssue:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '快捷问题更新', 'ai:quickIssue:update', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '快捷问题保存', 'ai:quickIssue:save', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '快捷问题读取', 'ai:quickIssue:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '快捷问题删除', 'ai:quickIssue:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);

-- user --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '用户列表', 'ai:user', 'IconUserGroup', 'ai/user', 'ai/user/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '用户主表列表', 'ai:user:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '用户主表更新', 'ai:user:update', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '用户主表读取', 'ai:user:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '用户主表删除', 'ai:user:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '用户开通VIP', 'ai:user:open-vip', NULL, NULL, NULL, NULL, 2, 'B', 1, 1, 1, 1, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '用户锁定', 'ai:user:lock', NULL, NULL, NULL, NULL, 2, 'B', 1, 1, 1, 1, now(), now(), NULL, NULL);

-- payKami --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '卡密', 'ai:payKami', 'icon-home', 'ai/payKami', 'ai/payKami/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '卡密列表', 'ai:payKami:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '卡密读取', 'ai:payKami:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '卡密更新', 'ai:payKami:update', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '卡密删除', 'ai:payKami:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, '创建卡密', 'ai:payKami:add', NULL, NULL, NULL, NULL, 2, 'B', 1, 1, 1, 1, now(), now(), NULL, NULL);

-- setting --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '设置', 'ai:setting', 'IconSettings', 'ai/setting', 'ai/setting/index', NULL, 2, 'M', 1, 0, 1, 1, now(), now(), NULL, NULL);

-- openKey --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, 'openai_key', 'ai:openKey', 'icon-home', 'ai/openKey', 'ai/openKey/index', NULL, 2, 'M', 1, 0, 1, NULL, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'openai_key列表', 'ai:openKey:index', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'openai_key保存', 'ai:openKey:save', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'openai_key更新', 'ai:openKey:update', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'openai_key读取', 'ai:openKey:read', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'openai_key删除', 'ai:openKey:delete', NULL, NULL, NULL, NULL, 2, 'B', 1, 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'openai_key刷新缓存', 'ai:openKey:refresh-cache-list', NULL, NULL, NULL, NULL, 2, 'B', 1, 1, 1, 1, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, 'openai_key批量添加', 'ai:openKey:batch-add', NULL, NULL, NULL, NULL, 2, 'B', 1, 1, 1, 1, now(), now(), NULL, NULL);

-- imageMaterial --
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@topid, @toplevel, '图片素材', 'ai:imageMaterial', 'icon-home', 'ai/imageMaterial', 'ai/imageMaterial/index', NULL, '2', 'M', '1', 0, 1, NULL, now(), now(), NULL, NULL);
SET @id := LAST_INSERT_ID();
SET @level := CONCAT('0',',', @topid, ',', @id);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, CONCAT('图片素材', '列表'), CONCAT('ai:imageMaterial',':index'), NULL, NULL, NULL, NULL, '2', 'B', '1', 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, CONCAT('图片素材', '保存'), CONCAT('ai:imageMaterial',':save'), NULL, NULL, NULL, NULL, '2', 'B', '1', 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, CONCAT('图片素材', '更新'), CONCAT('ai:imageMaterial',':update'), NULL, NULL, NULL, NULL, '2', 'B', '1', 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, CONCAT('图片素材', '读取'), CONCAT('ai:imageMaterial',':read'), NULL, NULL, NULL, NULL, '2', 'B', '1', 0, 1, NULL, now(), now(), NULL, NULL);
INSERT INTO `{$tableName}`(`parent_id`, `level`, `name`, `code`, `icon`, `route`, `component`, `redirect`, `is_hidden`, `type`, `status`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (@id, @level, CONCAT('图片素材', '删除'), CONCAT('ai:imageMaterial',':delete'), NULL, NULL, NULL, NULL, '2', 'B', '1', 0, 1, NULL, now(), now(), NULL, NULL);
";
        Db::unprepared($sql);
        $this->line('大功告成', 'info');
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Constants/OrderConst.php
================================================
<?php

namespace App\Ai\Constants;

use Pt\Constants\DescConst;

class OrderConst extends DescConst
{
    /**
     * @Desc("购买VIP")
     * @Group("ord_type")
     */
    const OPEN_VIP = 1;

    /**
     * @Desc("提现")
     * @Group("ord_type")
     */
    const WITHDRAWAL = 2;

    /**
     * @Desc("成为营销部")
     * @Group("ord_type")
     */
    const MARKET = 3;

    /**
     * @Desc("微信支付")
     * @Group("pay_type")
     */
    const WX_PAY = 1;

    /**
     * @Desc("后台免费")
     * @Group("pay_type")
     */
    const ADMIN_FREE = 2;

    /**
     * @Desc("后台付费")
     * @Group("pay_type")
     */
    const ADMIN_PAY = 3;

    /**
     * @Desc("免费卡密")
     * @Group("pay_type")
     */
    const KAMI_FREE = 4;

    /**
     * @Desc("付费卡密")
     * @Group("pay_type")
     */
    const KAMI_PAY = 5;

    /**
     * @Desc("待支付-待处理")
     * @Group("status")
     */
    const WAIT_PAY = 1;

    /**
     * @Desc("已支付-已完成")
     * @Group("status")
     */
    const SUCCESS_PAY = 2;

    /**
     * @Desc("支付失败-失败")
     * @Group("status")
     */
    const SUCCESS_ERR = 3;
}

================================================
FILE: MineAdmin/php/app/Ai/Constants/RedisConst.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Constants;

class RedisConst
{
    /**
     * 用户uid绑定fd
     */
    const USER_TO_FD = 'ai_user_fd';

    /**
     * fa 绑定用户信息
     */
    const FD_TO_USER = 'ai_fd_user:';

    /**
     * 用户今天发言了多少次
     */
    const USER_SPOKE_TODAY = 'ai_user_spoke_today:';
}

================================================
FILE: MineAdmin/php/app/Ai/Constants/ResponseCodeConst.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Constants;

class ResponseCodeConst
{
    const INVALID_TOKEN   = 10001; // token 无效
    const ACCOUNT_LOCK    = 10002; // 账号被锁定
    const REDIRECT_LOGIN  = 10003; // 跳转到登录页
    const APP_CLOSE       = 10004; // 关站维护
    const CLEAR_ALL_CACHE = 10005; // 清空所有缓存数据
    const PARAM_FAILED   = 10006; // 参数错误
}

================================================
FILE: MineAdmin/php/app/Ai/Constants/UploadSceneConst.php
================================================
<?php
namespace App\Ai\Constants;

class UploadSceneConst
{
    // 1开头,例如 1001 1002
    const ImageScene = [
        'ai_head_img'          => '1010',
        'ai_mine_menu_icon'    => '1011',
        'ai_customer_wx_img'   => '1012',
        'ai_customer_head_img' => '1013',
        'ai_image_materialg'   => '1014',
    ];

    // 2开头,例如 2001 2002
    const AudioScene = [
    ];

    // 3开头,例如 3001 3002
    const VideoScene = [
    ];

    public static function hasScene(string $scene): bool
    {
        if (in_array($scene, self::ImageScene) || in_array($scene, self::AudioScene) || in_array($scene, self::VideoScene)) {
            return true;
        }
        return false;
    }

    public static function isOnly(string $scene): bool
    {
        return in_array($scene, ['1010']);
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Constants/VipConst.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Constants;

use Pt\Constants\DescConst;

class VipConst extends DescConst
{
    /**
     * @Desc("免费会员")
     */
    const FREE = 0;

    /**
     * @Desc("VIP")
     */
    const VIP = 10;

    /**
     * @Desc("1星VIP")
     */
    const VIP_ONE = 20;

    /**
     * @Desc("2星VIP")
     */
    const VIP_TWO = 30;

    public static function config(): array
    {
        return [
            [
                'name' => 'VIP', // VIP名称
                'price' => '199', // 现价
                'price_pay' => '199', // 支付金额
                'price_old' => '198', // 原价
                'level' => 10, // 等级
                'length' => 12, // 时长(月)
                'income' => 0, // 收益%
                'wrap_vip' => 0, // VIP抵扣包
                'is_default' => false,// 默认选中
                'is_choose' => false,// 是否可选
                'btn_text' => '立即开通',
            ], [
                'name' => '一星',
                'price' => '299',
                'price_pay' => '299',
                'price_old' => '1198',
                'level' => 20,
                'length' => 36,
                'income' => 35,
                'wrap_vip' => 10,
                'is_default' => false,
                'is_choose' => false,
                'btn_text' => '立即开通',
            ], [
                'name' => '二星',
                'price' => '399',
                'price_pay' => '399',
                'price_old' => '2198',
                'level' => 30,
                'length' => 60,
                'income' => 50,
                'wrap_vip' => 20,
                'is_default' => false,
                'is_choose' => false,
                'btn_text' => '立即开通',
            ],
        ];
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Constants/WalletConst.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Constants;

use Pt\Constants\DescConst;

class WalletConst extends DescConst
{
    /**
     * @Desc("收入")
     * @Group("direction")
     */
    const IN = 1;

    /**
     * @Desc("支出")
     * @Group("direction")
     */
    const OUT = 2;

    /**
     * @Desc("推广获益")
     * @Group("scene")
     */
    const PROMOTION = 1;

    /**
     * @Desc("提现")
     * @Group("scene")
     */
    const WITHDRAWAL = 2;
}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiChatMessageController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiChatMessageService;
use App\Ai\Request\AiChatMessageRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 聊天数据控制器
 * Class AiChatMessageController
 */
#[Controller(prefix: "ai/chatMessage"), Auth]
class AiChatMessageController extends MineController
{
    /**
     * 业务处理服务
     * AiChatMessageService
     */
    #[Inject]
    protected AiChatMessageService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:chatMessage, ai:chatMessage:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:chatMessage:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:chatMessage:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiChatSessionController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiChatSessionService;
use App\Ai\Request\AiChatSessionRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 问答会话控制器
 * Class AiChatSessionController
 */
#[Controller(prefix: "ai/chatSession"), Auth]
class AiChatSessionController extends MineController
{
    /**
     * 业务处理服务
     * AiChatSessionService
     */
    #[Inject]
    protected AiChatSessionService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:chatSession, ai:chatSession:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:chatSession:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:chatSession:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiChatgptPromptsController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiChatgptPromptsService;
use App\Ai\Request\AiChatgptPromptsRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * chatgpt角色控制器
 * Class AiChatgptPromptsController
 */
#[Controller(prefix: "ai/chatgptPrompts"), Auth]
class AiChatgptPromptsController extends MineController
{
    /**
     * 业务处理服务
     * AiChatgptPromptsService
     */
    #[Inject]
    protected AiChatgptPromptsService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:chatgptPrompts, ai:chatgptPrompts:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 更新
     * @param int $id
     * @param AiChatgptPromptsRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:chatgptPrompts:update"), OperationLog]
    public function update(int $id, AiChatgptPromptsRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 新增
     * @param AiChatgptPromptsRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("save"), Permission("ai:chatgptPrompts:save"), OperationLog]
    public function save(AiChatgptPromptsRequest $request): ResponseInterface
    {
        return $this->success(['id' => $this->service->save($request->all())]);
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:chatgptPrompts:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:chatgptPrompts:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        $ids = $this->request->input('ids', []);
        if (in_array(1, $ids)) {
            $this->error('id为1的角色不能删除!');
        }
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiImageMaterialController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiImageMaterialService;
use App\Ai\Request\AiImageMaterialRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 图片素材控制器
 * Class AiImageMaterialController
 */
#[Controller(prefix: "ai/imageMaterial"), Auth]
class AiImageMaterialController extends MineController
{
    /**
     * 业务处理服务
     * AiImageMaterialService
     */
    #[Inject]
    protected AiImageMaterialService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:imageMaterial, ai:imageMaterial:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 新增
     * @param AiImageMaterialRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("save"), Permission("ai:imageMaterial:save"), OperationLog]
    public function save(AiImageMaterialRequest $request): ResponseInterface
    {
        return $this->success(['id' => $this->service->save($request->all())]);
    }

    /**
     * 更新
     * @param int $id
     * @param AiImageMaterialRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:imageMaterial:update"), OperationLog]
    public function update(int $id, AiImageMaterialRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:imageMaterial:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:imageMaterial:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiMineMenuController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiMineMenuService;
use App\Ai\Request\AiMineMenuRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 个人中心菜单控制器
 * Class AiMineMenuController
 */
#[Controller(prefix: "ai/mineMenu"), Auth]
class AiMineMenuController extends MineController
{
    /**
     * 业务处理服务
     * AiMineMenuService
     */
    #[Inject]
    protected AiMineMenuService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:mineMenu, ai:mineMenu:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 新增
     * @param AiMineMenuRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("save"), Permission("ai:mineMenu:save"), OperationLog]
    public function save(AiMineMenuRequest $request): ResponseInterface
    {
        return $this->success(['id' => $this->service->save($request->all())]);
    }

    /**
     * 更新
     * @param int $id
     * @param AiMineMenuRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:mineMenu:update"), OperationLog]
    public function update(int $id, AiMineMenuRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:mineMenu:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:mineMenu:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiMineMenuGroupController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiMineMenuGroupService;
use App\Ai\Request\AiMineMenuGroupRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 个人中心菜单分组控制器
 * Class AiMineMenuGroupController
 */
#[Controller(prefix: "ai/mineMenuGroup"), Auth]
class AiMineMenuGroupController extends MineController
{
    /**
     * 业务处理服务
     * AiMineMenuGroupService
     */
    #[Inject]
    protected AiMineMenuGroupService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:mineMenuGroup, ai:mineMenuGroup:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 新增
     * @param AiMineMenuGroupRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("save"), Permission("ai:mineMenuGroup:save"), OperationLog]
    public function save(AiMineMenuGroupRequest $request): ResponseInterface
    {
        return $this->success(['id' => $this->service->save($request->all())]);
    }

    /**
     * 更新
     * @param int $id
     * @param AiMineMenuGroupRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:mineMenuGroup:update"), OperationLog]
    public function update(int $id, AiMineMenuGroupRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:mineMenuGroup:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:mineMenuGroup:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiOpenaiKeyController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiOpenaiKeyService;
use App\Ai\Request\AiOpenaiKeyRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * openai_key控制器
 * Class AiOpenaiKeyController
 */
#[Controller(prefix: "ai/openKey"), Auth]
class AiOpenaiKeyController extends MineController
{
    /**
     * 业务处理服务
     * AiOpenaiKeyService
     */
    #[Inject]
    protected AiOpenaiKeyService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:openKey, ai:openKey:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 新增
     * @param AiOpenaiKeyRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("save"), Permission("ai:openKey:save"), OperationLog]
    public function save(AiOpenaiKeyRequest $request): ResponseInterface
    {
        return $this->success(['id' => $this->service->save($request->all())]);
    }

    /**
     * 更新
     * @param int $id
     * @param AiOpenaiKeyRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:openKey:update"), OperationLog]
    public function update(int $id, AiOpenaiKeyRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:openKey:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:openKey:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

    /**
     * 批量添加
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("batch-add"), Permission("ai:openKey:batch-add"), OperationLog]
    public function batchAdd(): ResponseInterface
    {
        return $this->service->batchAdd($this->request->all()) ? $this->success() : $this->error();
    }

    /**
     * 缓存列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("refresh-cache-list"), Permission("ai:openKey:refresh-cache-list"), OperationLog]
    public function refreshCache(): ResponseInterface
    {
        return $this->service->cacheAll() ? $this->success() : $this->error();
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiOrderController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiOrderService;
use App\Ai\Request\AiOrderRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 订单表控制器
 * Class AiOrderController
 */
#[Controller(prefix: "ai/order"), Auth]
class AiOrderController extends MineController
{
    /**
     * 业务处理服务
     * AiOrderService
     */
    #[Inject]
    protected AiOrderService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:order, ai:order:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:order:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:order:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiPayKamiController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiPayKamiService;
use App\Ai\Request\AiPayKamiRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 卡密控制器
 * Class AiPayKamiController
 */
#[Controller(prefix: "ai/payKami"), Auth]
class AiPayKamiController extends MineController
{
    /**
     * 业务处理服务
     * AiPayKamiService
     */
    #[Inject]
    protected AiPayKamiService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:payKami, ai:payKami:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:payKami:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 更新
     * @param int $id
     * @param AiPayKamiRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:payKami:update"), OperationLog]
    public function update(int $id, AiPayKamiRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:payKami:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("add"), Permission("ai:payKami:add"), OperationLog]
    public function add(): ResponseInterface
    {
        $this->service->add($this->request->all());
        return $this->success();
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiQuickIssueController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiQuickIssueService;
use App\Ai\Request\AiQuickIssueRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 快捷问题
控制器
 * Class AiQuickIssueController
 */
#[Controller(prefix: "ai/quickIssue"), Auth]
class AiQuickIssueController extends MineController
{
    /**
     * 业务处理服务
     * AiQuickIssueService
     */
    #[Inject]
    protected AiQuickIssueService $service;

    
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:quickIssue, ai:quickIssue:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->getPageList($this->request->all()));
    }

    /**
     * 更新
     * @param int $id
     * @param AiQuickIssueRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:quickIssue:update"), OperationLog]
    public function update(int $id, AiQuickIssueRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 新增
     * @param AiQuickIssueRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("save"), Permission("ai:quickIssue:save"), OperationLog]
    public function save(AiQuickIssueRequest $request): ResponseInterface
    {
        return $this->success(['id' => $this->service->save($request->all())]);
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:quickIssue:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:quickIssue:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiSettingController.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Controller;

use App\Ai\Service\AiSettingService;
use App\Ai\Service\QiniuService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: "ai/setting"), Auth]
class AiSettingController extends MineController
{
    #[Inject]
    protected AiSettingService $settingService;

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:setting, ai:setting:index")]
    public function index(): ResponseInterface
    {
        return $this->success(array_merge([
            'app_close_message' => $this->settingService->appClose(),
            'agreement_user' => $this->settingService->agreementUser(),
            'openai_proxy' => $this->settingService->openaiProxy(),

        ], $this->settingService->customer()));
    }

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[PostMapping("save"), Permission("ai:setting, ai:setting:save")]
    public function save(): ResponseInterface
    {
        $this->settingService->setAppClose($this->request->post('app_close_message', ''));
        $this->settingService->setAgreementUser($this->request->post('agreement_user', ''));
        $this->settingService->setCustomer($this->request->post('customer'));
        $this->settingService->setOpenaiProxy($this->request->post('openai_proxy'));
        return $this->success();
    }

    #[Inject]
    protected QiniuService $qiniuService;

    #[GetMapping("upload-token")]
    public function uploadToken(): ResponseInterface
    {
        return $this->success($this->qiniuService->token($this->request->query('scenes')));
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Controller/AiUserController.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Controller;

use App\Ai\Service\AiOrderService;
use App\Ai\Service\AiUserService;
use App\Ai\Request\AiUserRequest;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Mine\Annotation\Auth;
use Mine\Annotation\OperationLog;
use Mine\Annotation\Permission;
use Mine\MineController;
use Psr\Http\Message\ResponseInterface;

/**
 * 用户主表控制器
 * Class AiUserController
 */
#[Controller(prefix: "ai/user"), Auth]
class AiUserController extends MineController
{
    /**
     * 业务处理服务
     * AiUserService
     */
    #[Inject]
    protected AiUserService $service;

    #[Inject]
    protected AiOrderService $orderService;
    /**
     * 列表
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("index"), Permission("ai:user, ai:user:index")]
    public function index(): ResponseInterface
    {
        return $this->success($this->service->userList($this->request->all()));
    }

    /**
     * 更新
     * @param int $id
     * @param AiUserRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PutMapping("update/{id}"), Permission("ai:user:update"), OperationLog]
    public function update(int $id, AiUserRequest $request): ResponseInterface
    {
        return $this->service->update($id, $request->all()) ? $this->success() : $this->error();
    }

    /**
     * 读取数据
     * @param int $id
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[GetMapping("read/{id}"), Permission("ai:user:read")]
    public function read(int $id): ResponseInterface
    {
        return $this->success($this->service->read($id));
    }

    /**
     * 单个或批量删除数据到回收站
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[DeleteMapping("delete"), Permission("ai:user:delete"), OperationLog]
    public function delete(): ResponseInterface
    {
        return $this->service->delete((array) $this->request->input('ids', [])) ? $this->success() : $this->error();
    }

    /**
     * 更新
     * @param int $id
     * @param AiUserRequest $request
     * @return ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping("open-vip/{id}"), Permission("ai:user:open-vip"), OperationLog]
    public function openVip(): ResponseInterface
    {
        $this->orderService->adminOpenVip($this->request->all());
        return $this->success();
    }

    #[PostMapping("lock/{id}"), Permission("ai:user:lock"), OperationLog]
    public function lock(int $id): ResponseInterface
    {
        $this->service->lock($id);
        return $this->success();
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Crontab/CheckVipOver.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Crontab;

use App\Ai\Model\AiUser;
use Mine\Annotation\Transaction;

class CheckVipOver
{
    #[Transaction]
    public function execute(): string
    {
        // todo
        try {
            $lastId = 0;
            $time = time();
            while (true){
                $userList = AiUser::where('id', '>', $lastId)->where('vip','>', 0)->limit(1000)->get();
                /**
                 * @var AiUser $user
                 */
                $uidArr = [];
                foreach ($userList as $user) {
                    if ($user->vip_ent_at && $time > strtotime($user->vip_ent_at)) {
                        $uidArr[] = $user->id;
                    }
                    $lastId = $user->id;
                }
                $uidArr && AiUser::whereIn('id', $uidArr)->update([
                    'vip' => 0
                ]);
                if (count($userList) < 1000) {
                    break;
                }
            }
        } catch (\Throwable $exception){

        }
        return 'success';
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_04_145048_create_ai_user_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiUserTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_user', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('用户主表');
            $table->increments('id')->comment('主键');
            $table->addColumn('string', 'nick_name', ['length' => 50, 'comment' => '昵称'])->default('')->nullable(false);
            $table->addColumn('string', 'head_img', ['length' => 100, 'comment' => '头像'])->default('')->nullable(false);
            $table->addColumn('string', 'mobile', ['length' => 20, 'comment' => '手机号'])->default('')->nullable(false);
            $table->addColumn('tinyInteger', 'vip', ['length' => 1, 'comment' => 'vip等级'])->index()->default(0)->nullable(false);
            $table->addColumn('timestamp', 'vip_ent_at', ['precision' => 0, 'comment' => 'vip到期时间'])->nullable();
            $table->addColumn('tinyInteger', 'is_lock', ['length' => 1, 'comment' => '是否锁定:1正常,2锁定'])->default(1)->nullable(false);
            $table->addColumn('string', 'password', ['length' => 32, 'comment' => '密码'])->default('')->nullable(false);
            $table->addColumn('integer', 'updated_by', ['comment' => '更新者'])->default(0)->nullable();
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_user');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095456_create_ai_user_wallet_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiUserWalletTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_user_wallet', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('用户钱包');
            $table->addColumn('integer', 'uid')->primary()->comment('用户UID');
            $table->addColumn('integer', 'balance')->comment('余额')->unsigned()->default(0)->nullable(false);
            $table->addColumn('integer', 'balance_total')->comment('总收入')->unsigned()->default(0)->nullable(false);
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_user_wallet');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095504_create_ai_user_wallet_log_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiUserWalletLogTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_user_wallet_log', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('钱包变动记录');
            $table->increments('id')->comment('主键');
            $table->addColumn('integer', 'uid')->index()->comment('用户UID')->nullable(false);
            $table->addColumn('integer', 'oid')->comment('订单ID')->index()->default(0)->nullable(false);
            $table->addColumn('tinyInteger', 'direction', ['length' => 1, 'comment' => '类型:1收入,2支出'])->default(1)->nullable(false);
            $table->addColumn('integer', 'balance')->comment('金额')->default(0)->nullable(false);
            $table->addColumn('tinyInteger', 'scene', ['length' => 1, 'comment' => '变动场景: 1推广获益'])->default(1)->nullable(false);
            $table->addColumn('string', 'remark', ['length' => 255, 'comment' => '备注'])->default("")->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_user_wallet_log');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095525_create_ai_user_relation_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiUserRelationTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_user_relation', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('用户关系');
            $table->addColumn('integer', 'uid')->primary()->comment('用户UID');
            $table->addColumn('integer', 'from_uid', ['comment' => '上级'])->index()->default(1)->nullable(false);
            $table->addColumn('integer', 'market_uid', ['comment' => '上级营销部'])->index()->default(0)->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_user_relation');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095540_create_ai_order_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiOrderTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_order', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('订单表');
            $table->increments('id')->comment('主键');
            $table->addColumn('integer', 'uid', ['comment' => '用户UID'])->index()->default(0)->nullable(false);
            $table->addColumn('integer', 'from_uid', ['comment' => '上级UID'])->default(0)->nullable(false);
            $table->addColumn('integer', 'market_uid', ['comment' => '营销部UID'])->default(0)->nullable(false);
            $table->addColumn('string', 'ord_sn', ['length' => 32, 'comment' => '订单号'])->unique()->default('')->nullable(false);
            $table->addColumn('tinyInteger', 'ord_type', ['length' => 1, 'comment' => '订单类型: 1开通VIP 2提现 3成为营销部'])->default(1)->nullable(false);
            $table->addColumn('tinyInteger', 'pay_type', ['length' => 1, 'comment' => '支付方式: 1微信 2后台付费'])->default(1)->nullable(false);
            $table->addColumn('tinyInteger', 'status', ['length' => 1, 'comment' => '订单状态 1未支付(待处理) 2已支付(已完成) 3失败'])->default(1)->nullable(false);
            $table->addColumn('integer', 'total_price', ['length' => 8, 'comment' => '总金额'])->default(0)->nullable(false);
            $table->addColumn('integer', 'amount_price', ['length' => 8, 'comment' => '实际金额'])->default(0)->nullable(false);
            $table->addColumn('string', 'content', ['length' => 255, 'comment' => '订单描述'])->default('')->nullable(false);
            $table->addColumn('string', 'remark', ['length' => 255, 'comment' => '备注'])->default("")->nullable(false);
            $table->addColumn('bigInteger', 'created_by', ['comment' => '创建者'])->default(0)->nullable();
            $table->addColumn('bigInteger', 'updated_by', ['comment' => '更新者'])->default(0)->nullable();
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'pay_at', ['precision' => 0, 'comment' => '订单完成时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_order');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095543_create_ai_order_vip_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiOrderVipTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_order_vip', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('vip订单');
            $table->integer('oid')->primary()->comment('订单ID');
            $table->addColumn('tinyInteger', 'vip_level', ['length'=>1, 'comment' => 'vip等级'])->default(1)->nullable(false);
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_order_vip');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_102806_create_ai_mine_menu_group_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiMineMenuGroupTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_mine_menu_group', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('个人中心菜单分组');
            $table->bigIncrements('id')->comment('主键');
            $table->addColumn('string', 'name', ['length' => 100, 'comment' => '分组名称'])->default('')->nullable(false);
            $table->addColumn('integer', 'sort', ['comment' => '排序'])->default(0)->nullable(false);
            $table->addColumn('tinyInteger', 'is_lock', ['length' => 1, 'comment' => '是否锁定:1正常,锁定'])->default(1)->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_mine_menu_group');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_102817_create_ai_mine_menu_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiMineMenuTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_mine_menu', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('个人中心菜单');
            $table->bigIncrements('id')->comment('主键');
            $table->addColumn('integer', 'gid', ['comment' => '分组ID'])->index()->default(0)->nullable(false);
            $table->addColumn('string', 'name', ['length' => 50, 'comment' => '菜单名称'])->default('')->nullable(false);
            $table->addColumn('integer', 'sort', ['comment' => '排序'])->default(0)->nullable(false);
            $table->addColumn('tinyInteger', 'use_vip', ['length' => 2, 'comment' => '使用权限限制 0全部'])->default(0)->nullable(false);
            $table->addColumn('tinyInteger', 'click_type', ['length' => 1, 'comment' => '点击类型 1跳转 2调用函数'])->default(1)->nullable(false);
            $table->addColumn('string', 'click_func', ['length' => 50, 'comment' => '函数标识 小程序端提前封装'])->default('')->nullable(false);
            $table->addColumn('string', 'path', ['length' => 100, 'comment' => '打开的页面路径'])->default('')->nullable(false);
            $table->addColumn('string', 'app_id', ['length' => 100, 'comment' => '小程序appid'])->default('')->nullable(false);
            $table->addColumn('string', 'extra_data', ['length' => 100, 'comment' => '需要传递给目标小程序的数据 json'])->default('')->nullable(false);
            $table->addColumn('string', 'env_version', ['length' => 100, 'comment' => '要打开的小程序版本'])->default('')->nullable(false);
            $table->addColumn('string', 'short_link', ['length' => 100, 'comment' => '小程序链接'])->default('')->nullable(false);
            $table->addColumn('string', 'icon', ['length' => 255, 'comment' => '菜单图标'])->default('')->nullable(false);
            $table->addColumn('tinyInteger', 'is_lock', ['length' => 1, 'comment' => '是否锁定:1正常,2锁定'])->default(1)->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_mine_menu');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_154733_create_ai_chatgpt_prompts_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiChatgptPromptsTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_chatgpt_prompts', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('chatgpt角色');
            $table->increments('id')->comment('主键');
            $table->addColumn('string', 'act', ['length'=>100, 'comment' => '角色名称'])->default('')->nullable(false);
            $table->addColumn('text', 'prompt', ['comment' => '角色说明'])->nullable(false);
            $table->addColumn('integer', 'sort', ['comment' => '排序'])->default(0)->nullable(false);
            $table->addColumn('string', 'remark', ['length' => 255, 'comment' => '备注'])->default('')->nullable(false);
            $table->addColumn('integer', 'created_by', ['comment' => '创建者'])->default(0)->nullable(false);
            $table->addColumn('integer', 'updated_by', ['comment' => '更新者'])->default(0)->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_chatgpt_prompts');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_10_165842_create_ai_chat_message_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiChatMessageTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_chat_message', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('聊天数据');
            $table->bigIncrements('id')->comment('主键');
            $table->addColumn('integer', 'sid', ['comment' => '会话ID'])->index()->default(0)->nullable(false);
            $table->addColumn('text', 'content', ['comment' => '内容'])->nullable(false);
            $table->addColumn('text', 'reply_content', ['comment' => '回复内容'])->nullable(false);
            $table->addColumn('timestamp', 'reply_at', ['precision' => 0, 'comment' => '回复时间'])->nullable();
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_chat_message');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_10_171603_create_ai_chat_session_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiChatSessionTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_chat_session', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('问答会话');
            $table->increments('id')->comment('主键');
            $table->addColumn('integer', 'uid', ['comment' => '用户uid'])->index()->default(0)->nullable(false);
            $table->addColumn('integer', 'prompt_id', ['comment' => '模型ID'])->index()->default(0)->nullable(false);
            $table->addColumn('tinyInteger', 'close', ['length' => 1, 'comment' => '是否关闭:1正常,2关闭'])->default(1)->nullable(false);
            $table->addColumn('tinyInteger', 'share', ['length' => 1, 'comment' => '是否分享:1关闭,2公开'])->default(1)->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_chat_session');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_12_152504_create_ai_quick_issue_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiQuickIssueTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_quick_issue', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('快捷问题');
            $table->increments('id')->comment('主键');
            $table->addColumn('string', 'title', ['length' => 100, 'comment' => '问题标题'])->default('')->nullable(false);
            $table->addColumn('string', 'content', ['length' => 255, 'comment' => '问题描述'])->default('')->nullable(false);
            $table->addColumn('integer', 'sort', ['comment' => '排序'])->default(0)->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();

        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_quick_issue');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_19_164456_create_ai_pay_kami_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiPayKamiTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_pay_kami', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('卡密');
            $table->increments('id')->comment('主键');
            $table->addColumn('integer', 'uid', ['comment' => '绑定用户'])->default(0)->nullable(false);
            $table->addColumn('integer', 'price', ['comment' => '价格'])->default(0)->nullable(false);
            $table->addColumn('string', 'code', ['length' => 32, 'comment' => '卡密号'])->unique()->default('')->nullable(false);
            $table->addColumn('tinyInteger', 'status', ['length' => 1, 'comment' => '状态 1未使用 2已使用'])->default(1)->nullable(false);
            $table->addColumn('string', 'remark', ['length' => 255, 'comment' => '备注'])->default('')->nullable(false);
            $table->addColumn('bigInteger', 'created_by', ['comment' => '创建者'])->default(0)->nullable(false);
            $table->addColumn('bigInteger', 'updated_by', ['comment' => '更新者'])->default(0)->nullable(false);
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'use_at', ['precision' => 0, 'comment' => '使用时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_pay_carmi');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_25_152855_create_ai_openai_key_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiOpenaiKeyTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_openai_key', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('openai_key');
            $table->increments('id')->comment('主键');
            $table->addColumn('string', 'openai_key', ['length' => 255, 'comment' => 'openai_key'])->nullable();
            $table->addColumn('string', 'remark', ['length' => 255, 'comment' => '备注'])->nullable();
            $table->addColumn('bigInteger', 'created_by', ['comment' => '创建者'])->nullable();
            $table->addColumn('bigInteger', 'updated_by', ['comment' => '更新者'])->nullable();
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_openai_key');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_26_111034_create_ai_order_kami_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiOrderKamiTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_order_kami', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('订单关联卡密');
            $table->integer('oid')->primary()->comment('订单ID');
            $table->integer('kid')->comment('卡密ID');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_order_kami');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_06_14_141605_create_ai_image_material_table.php
================================================
<?php


use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

class CreateAiImageMaterialTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('ai_image_material', function (Blueprint $table) {
            $table->engine = 'Innodb';
            $table->comment('图片素材');
            $table->increments('id')->comment('主键');
            $table->addColumn('tinyInteger', 'scene', ['length' => 1, 'comment' => '使用场景'])->default(1)->nullable(false);
            $table->addColumn('string', 'img_url', ['length' => 255, 'comment' => '图片地址'])->default('')->nullable(false);
            $table->addColumn('string', 'url', ['length' => 255, 'comment' => '跳转地址'])->default('')->nullable(false);
            $table->addColumn('string', 'remark', ['length' => 255, 'comment' => '备注'])->default('')->nullable(false);
            $table->addColumn('integer', 'sort', ['comment' => '排序'])->default(0)->nullable(false);
            $table->addColumn('integer', 'created_by', ['comment' => '创建者'])->default(0)->nullable(false);
            $table->addColumn('integer', 'updated_by', ['comment' => '更新者'])->default(0)->nullable(false);
            $table->addColumn('timestamp', 'start_at', ['precision' => 0, 'comment' => '使用开始时间'])->nullable();
            $table->addColumn('timestamp', 'end_at', ['precision' => 0, 'comment' => '使用结束时间'])->nullable();
            $table->addColumn('timestamp', 'created_at', ['precision' => 0, 'comment' => '创建时间'])->nullable();
            $table->addColumn('timestamp', 'updated_at', ['precision' => 0, 'comment' => '更新时间'])->nullable();
            $table->addColumn('timestamp', 'deleted_at', ['precision' => 0, 'comment' => '删除时间'])->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('ai_image_material');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_chatgpt_prompts.php
================================================
<?php
declare(strict_types=1);

use Hyperf\Database\Seeders\Seeder;
use Hyperf\DbConnection\Db;

class AiChatgptPrompts extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $isInit = \App\Ai\Model\AiChatgptPrompts::where(['id'=>1])->first();
        if (!empty($isInit)){
            echo '大功告成'.PHP_EOL;
            return;
        }

        $tableName = env('DB_PREFIX') . \App\Ai\Model\AiChatgptPrompts::getModel()->getTable();
        $sql = [
            "INSERT INTO `{$tableName}`(`id`, `act`, `prompt`, `sort`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`, `remark`) VALUES (1, 'Ai助手', '你是一个Ai智能助手,我需要你模拟一名温柔贴心的女朋友来回答我的问题。', 0, 1, 1, now(), now(), NULL, '')",
        ];
        foreach ($sql as $item) {
            Db::insert($item);
        }
        echo '大功告成'.PHP_EOL;
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_mine_menu.php
================================================
<?php
declare(strict_types=1);

use Hyperf\Database\Seeders\Seeder;
use Hyperf\DbConnection\Db;

class AiMineMenu extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Db::table('ai_mine_menu')->truncate();
        $tableName = env('DB_PREFIX') . \App\Ai\Model\AiMineMenu::getModel()->getTable();
        $sql = [
            "INSERT INTO `{$tableName}`(`id`, `gid`, `name`, `sort`, `use_vip`, `click_type`, `click_func`, `path`, `app_id`, `extra_data`, `env_version`, `short_link`, `icon`, `is_lock`, `created_at`, `updated_at`, `deleted_at`) VALUES (1, 1, '会员特权', 4, 0, 2, '1002', '', '', '', '', '', 'https://www.putyy.com/uploads/images/vip.png', 1, now(), now(), NULL);",
            "INSERT INTO `{$tableName}`(`id`, `gid`, `name`, `sort`, `use_vip`, `click_type`, `click_func`, `path`, `app_id`, `extra_data`, `env_version`, `short_link`, `icon`, `is_lock`, `created_at`, `updated_at`, `deleted_at`) VALUES (2, 1, '联系客服', 3, 0, 2, '1001', '', '', '', '', '', 'https://www.putyy.com/uploads/images/kf.png', 2, now(), now(), NULL);",
            "INSERT INTO `{$tableName}`(`id`, `gid`, `name`, `sort`, `use_vip`, `click_type`, `click_func`, `path`, `app_id`, `extra_data`, `env_version`, `short_link`, `icon`, `is_lock`, `created_at`, `updated_at`, `deleted_at`) VALUES (3, 1, '清空缓存', 0, 0, 2, '1003', '', '', '', '', '', 'https://www.putyy.com/uploads/images/clear.png', 1, now(), now(), NULL);",
            "INSERT INTO `{$tableName}`(`id`, `gid`, `name`, `sort`, `use_vip`, `click_type`, `click_func`, `path`, `app_id`, `extra_data`, `env_version`, `short_link`, `icon`, `is_lock`, `created_at`, `updated_at`, `deleted_at`) VALUES (4, 1, '订单列表', 0, 0, 1, '', '/pages/user/order', '', '', '', '', 'https://www.putyy.com/uploads/images/list.png', 1, now(), now(), NULL);",
        ];
        foreach ($sql as $item){
            Db::insert($item);
        }
        echo '大功告成'.PHP_EOL;
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_mine_menu_group.php
================================================
<?php
declare(strict_types=1);

use Hyperf\Database\Seeders\Seeder;
use Hyperf\DbConnection\Db;

class AiMineMenuGroup extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Db::table('ai_mine_menu_group')->truncate();
        $tableName = env('DB_PREFIX') . \App\Ai\Model\AiMineMenuGroup::getModel()->getTable();
        Db::insert("INSERT INTO `$tableName`(`id`, `name`, `sort`, `is_lock`, `created_at`, `updated_at`) VALUES (1, '会员服务', 1, 1, now(), now());");
        echo '大功告成'.PHP_EOL;
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_user.php
================================================
<?php
/**
 * MineAdmin is committed to providing solutions for quickly building web applications
 * Please view the LICENSE file that was distributed with this source code,
 * For the full copyright and license information.
 * Thank you very much for using MineAdmin.
 *
 * @Author X.Mo<root@imoi.cn>
 * @Link   https://gitee.com/xmo/MineAdmin
 */

declare(strict_types=1);

use Hyperf\Database\Seeders\Seeder;
use Hyperf\DbConnection\Db;

class AiUser extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $isInit = \App\Ai\Model\AiUser::where(['id'=>1])->first();
        if (!empty($isInit)){
            echo '大功告成'.PHP_EOL;
            return;
        }

        $tableName = env('DB_PREFIX') . \App\Ai\Model\AiUser::getModel()->getTable();

        Db::insert("INSERT INTO `{$tableName}`(`id`, `nick_name`, `head_img`, `mobile`, `vip`, `vip_ent_at`, `password`, `is_lock`, `updated_by`, `created_at`, `updated_at`, `deleted_at`) VALUES (1, 'ChatGPT', '', '123456789', 30, '2036-03-11 16:02:58', 'e10adc3949ba59abbe56e057f20f883e', 1, 1, now(), now(), NULL);");

        \App\Ai\Model\AiUserRelation::insert([
            'uid'       => 1,
            'from_uid'  => 1,
        ]);

        \App\Ai\Model\AiUserWallet::insert([
            'uid' => 1,
        ]);
        echo '大功告成'.PHP_EOL;
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Dto/AiChatMessageDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 聊天数据Dto (导入导出)
 */
#[ExcelData]
class AiChatMessageDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "会话ID", index: 1)]
    public string $sid;

    #[ExcelProperty(value: "内容", index: 2)]
    public string $content;

    #[ExcelProperty(value: "回复内容", index: 3)]
    public string $reply_content;

    #[ExcelProperty(value: "回复时间", index: 4)]
    public string $reply_at;

    #[ExcelProperty(value: "创建时间", index: 4)]
    public string $created_at;

    #[ExcelProperty(value: "删除时间", index: 5)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiChatSessionDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 问答会话Dto (导入导出)
 */
#[ExcelData]
class AiChatSessionDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "用户uid", index: 1)]
    public string $uid;

    #[ExcelProperty(value: "模型ID", index: 2)]
    public string $prompt_id;

    #[ExcelProperty(value: "是否关闭:1正常,2关闭", index: 3)]
    public string $close;

    #[ExcelProperty(value: "是否分享:1关闭,2公开", index: 4)]
    public string $share;

    #[ExcelProperty(value: "创建时间", index: 5)]
    public string $created_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiChatgptPromptsDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * chatgpt角色Dto (导入导出)
 */
#[ExcelData]
class AiChatgptPromptsDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "角色名称", index: 1)]
    public string $act;

    #[ExcelProperty(value: "角色说明", index: 2)]
    public string $prompt;

    #[ExcelProperty(value: "排序", index: 3)]
    public string $sort;

    #[ExcelProperty(value: "创建者", index: 4)]
    public string $created_by;

    #[ExcelProperty(value: "更新者", index: 5)]
    public string $updated_by;

    #[ExcelProperty(value: "创建时间", index: 6)]
    public string $created_at;

    #[ExcelProperty(value: "更新时间", index: 7)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 8)]
    public string $deleted_at;

    #[ExcelProperty(value: "备注", index: 9)]
    public string $remark;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiImageMaterialDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 图片素材Dto (导入导出)
 */
#[ExcelData]
class AiImageMaterialDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "使用场景", index: 1)]
    public string $scene;

    #[ExcelProperty(value: "图片地址", index: 2)]
    public string $img_url;

    #[ExcelProperty(value: "跳转地址", index: 3)]
    public string $url;

    #[ExcelProperty(value: "备注", index: 4)]
    public string $remark;

    #[ExcelProperty(value: "排序", index: 5)]
    public string $sort;

    #[ExcelProperty(value: "创建者", index: 6)]
    public string $created_by;

    #[ExcelProperty(value: "更新者", index: 7)]
    public string $updated_by;

    #[ExcelProperty(value: "使用开始时间", index: 8)]
    public string $start_at;

    #[ExcelProperty(value: "使用结束时间", index: 9)]
    public string $end_at;

    #[ExcelProperty(value: "创建时间", index: 10)]
    public string $created_at;

    #[ExcelProperty(value: "更新时间", index: 11)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 12)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiMineMenuDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 个人中心菜单Dto (导入导出)
 */
#[ExcelData]
class AiMineMenuDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "分组ID", index: 1)]
    public string $gid;

    #[ExcelProperty(value: "分组名称", index: 2)]
    public string $name;

    #[ExcelProperty(value: "排序", index: 3)]
    public string $sort;

    #[ExcelProperty(value: "使用权限限制 0全部", index: 4)]
    public string $use_vip;

    #[ExcelProperty(value: "点击类型 1跳转 2调用函数", index: 5)]
    public string $click_type;

    #[ExcelProperty(value: "函数标识 小程序端提前封装", index: 6)]
    public string $click_func;

    #[ExcelProperty(value: "打开的页面路径", index: 7)]
    public string $path;

    #[ExcelProperty(value: "小程序appid", index: 8)]
    public string $app_id;

    #[ExcelProperty(value: "需要传递给目标小程序的数据 json", index: 9)]
    public string $extra_data;

    #[ExcelProperty(value: "要打开的小程序版本", index: 10)]
    public string $env_version;

    #[ExcelProperty(value: "小程序链接", index: 11)]
    public string $short_link;

    #[ExcelProperty(value: "icon", index: 12)]
    public string $icon;

    #[ExcelProperty(value: "是否锁定:1正常,2锁定", index: 13)]
    public string $is_lock;

    #[ExcelProperty(value: "创建时间", index: 14)]
    public string $created_at;

    #[ExcelProperty(value: "更新时间", index: 15)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 16)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiMineMenuGroupDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 个人中心菜单分组Dto (导入导出)
 */
#[ExcelData]
class AiMineMenuGroupDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "分组名称", index: 1)]
    public string $name;

    #[ExcelProperty(value: "排序", index: 2)]
    public string $sort;

    #[ExcelProperty(value: "是否锁定:1正常,锁定", index: 3)]
    public string $is_lock;

    #[ExcelProperty(value: "创建时间", index: 4)]
    public string $created_at;

    #[ExcelProperty(value: "更新时间", index: 5)]
    public string $updated_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiOpenaiKeyDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * openai_keyDto (导入导出)
 */
#[ExcelData]
class AiOpenaiKeyDto implements MineModelExcel
{
    #[ExcelProperty(value: "openai_key", index: 0)]
    public string $openai_key;

    #[ExcelProperty(value: "备注", index: 1)]
    public string $remark;

    #[ExcelProperty(value: "主键", index: 2)]
    public string $id;

    #[ExcelProperty(value: "创建者", index: 3)]
    public string $created_by;

    #[ExcelProperty(value: "更新者", index: 4)]
    public string $updated_by;

    #[ExcelProperty(value: "创建时间", index: 5)]
    public string $created_at;

    #[ExcelProperty(value: "更新时间", index: 6)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 7)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiOrderDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 订单表Dto (导入导出)
 */
#[ExcelData]
class AiOrderDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "用户UID", index: 1)]
    public string $uid;

    #[ExcelProperty(value: "上级UID", index: 2)]
    public string $from_uid;

    #[ExcelProperty(value: "营销部UID", index: 3)]
    public string $market_uid;

    #[ExcelProperty(value: "订单号", index: 4)]
    public string $ord_sn;

    #[ExcelProperty(value: "订单类型: 1开通VIP 2提现 3成为营销部", index: 5)]
    public string $ord_type;

    #[ExcelProperty(value: "支付方式: 1微信 2后台付费", index: 6)]
    public string $pay_type;

    #[ExcelProperty(value: "订单状态 1未支付(待处理) 2已支付(已完成) 3失败", index: 7)]
    public string $status;

    #[ExcelProperty(value: "总金额", index: 8)]
    public string $total_price;

    #[ExcelProperty(value: "实际金额", index: 9)]
    public string $amount_price;

    #[ExcelProperty(value: "订单描述", index: 10)]
    public string $content;

    #[ExcelProperty(value: "备注", index: 11)]
    public string $remark;

    #[ExcelProperty(value: "创建者", index: 12)]
    public string $created_by;

    #[ExcelProperty(value: "更新者", index: 13)]
    public string $updated_by;

    #[ExcelProperty(value: "创建时间", index: 14)]
    public string $created_at;

    #[ExcelProperty(value: "订单完成时间", index: 15)]
    public string $pay_at;

    #[ExcelProperty(value: "更新时间", index: 16)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 17)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiPayKamiDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 卡密Dto (导入导出)
 */
#[ExcelData]
class AiPayKamiDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "绑定用户", index: 1)]
    public string $uid;

    #[ExcelProperty(value: "价格", index: 2)]
    public string $price;

    #[ExcelProperty(value: "卡密号", index: 3)]
    public string $code;

    #[ExcelProperty(value: "状态 1未使用 2已使用", index: 4)]
    public string $status;

    #[ExcelProperty(value: "备注", index: 5)]
    public string $remark;

    #[ExcelProperty(value: "创建者", index: 6)]
    public string $created_by;

    #[ExcelProperty(value: "更新者", index: 7)]
    public string $updated_by;

    #[ExcelProperty(value: "创建时间", index: 8)]
    public string $created_at;

    #[ExcelProperty(value: "使用时间", index: 9)]
    public string $use_at;

    #[ExcelProperty(value: "更新时间", index: 10)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 11)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiQuickIssueDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 快捷问题
Dto (导入导出)
 */
#[ExcelData]
class AiQuickIssueDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "问题标题", index: 1)]
    public string $title;

    #[ExcelProperty(value: "问题描述", index: 2)]
    public string $content;

    #[ExcelProperty(value: "sort", index: 3)]
    public string $sort;

    #[ExcelProperty(value: "创建时间", index: 4)]
    public string $created_at;

    #[ExcelProperty(value: "更新时间", index: 5)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 6)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Dto/AiUserDto.php
================================================
<?php
namespace App\Ai\Dto;

use Mine\Interfaces\MineModelExcel;
use Mine\Annotation\ExcelData;
use Mine\Annotation\ExcelProperty;

/**
 * 用户主表Dto (导入导出)
 */
#[ExcelData]
class AiUserDto implements MineModelExcel
{
    #[ExcelProperty(value: "主键", index: 0)]
    public string $id;

    #[ExcelProperty(value: "昵称", index: 1)]
    public string $nick_name;

    #[ExcelProperty(value: "头像", index: 2)]
    public string $head_img;

    #[ExcelProperty(value: "手机号", index: 3)]
    public string $mobile;

    #[ExcelProperty(value: "vip等级", index: 4)]
    public string $vip;

    #[ExcelProperty(value: "vip到期时间", index: 5)]
    public string $vip_ent_at;

    #[ExcelProperty(value: "password", index: 6)]
    public string $password;

    #[ExcelProperty(value: "是否锁定:1正常,2锁定", index: 7)]
    public string $is_lock;

    #[ExcelProperty(value: "更新者", index: 8)]
    public string $updated_by;

    #[ExcelProperty(value: "创建时间", index: 9)]
    public string $created_at;

    #[ExcelProperty(value: "更新时间", index: 10)]
    public string $updated_at;

    #[ExcelProperty(value: "删除时间", index: 11)]
    public string $deleted_at;


}

================================================
FILE: MineAdmin/php/app/Ai/Factory/AiRedisFactory.php
================================================
<?php
declare(strict_types=1);

namespace App\Ai\Factory;

use Hyperf\Redis\Redis;

class AiRedisFactory extends Redis
{
    protected string $poolName = 'default';
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiChatMessageMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiChatMessage;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 聊天数据Mapper类
 */
class AiChatMessageMapper extends AbstractMapper
{
    /**
     * @var AiChatMessage
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiChatMessage::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 会话ID
        if (isset($params['sid']) && $params['sid'] !== '') {
            $query->where('sid', '=', $params['sid']);
        }

        // 内容
        if (isset($params['content']) && $params['content'] !== '') {
            $query->where('content', 'like', "%{$params['content']}%");
        }

        // 内容
        if (isset($params['reply_content']) && $params['reply_content'] !== '') {
            $query->where('reply_content', 'like', "%{$params['reply_content']}%");
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiChatSessionMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiChatSession;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Mine\Abstracts\AbstractMapper;

/**
 * 问答会话Mapper类
 */
class AiChatSessionMapper extends AbstractMapper
{
    /**
     * @var AiChatSession
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiChatSession::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 主键
        if (isset($params['id']) && $params['id'] !== '') {
            $query->where('id', '=', $params['id']);
        }

        // 用户uid
        if (isset($params['uid']) && $params['uid'] !== '') {
            $query->where('uid', '=', $params['uid']);
        }

        // 模型ID
        if (isset($params['prompt_id']) && $params['prompt_id'] !== '') {
            $query->where('prompt_id', '=', $params['prompt_id']);
        }

        // 是否关闭:1正常,2关闭
        if (isset($params['close']) && $params['close'] !== '') {
            $query->where('close', '=', $params['close']);
        }

        // 是否分享:1关闭,2公开
        if (isset($params['share']) && $params['share'] !== '') {
            $query->where('share', '=', $params['share']);
        }

        return $query;
    }

    public function session($where): Model|Builder|null
    {
        return $this->model::where($where)->orderBy('id', 'desc')->first();
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiChatgptPromptsMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiChatgptPrompts;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * chatgpt角色Mapper类
 */
class AiChatgptPromptsMapper extends AbstractMapper
{
    /**
     * @var AiChatgptPrompts
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiChatgptPrompts::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 角色名称
        if (isset($params['act']) && $params['act'] !== '') {
            $query->where('act', 'like', '%'.$params['act'].'%');
        }

        // 角色说明
        if (isset($params['prompt']) && $params['prompt'] !== '') {
            $query->where('prompt', 'like', '%'.$params['prompt'].'%');
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiImageMaterialMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiImageMaterial;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 图片素材Mapper类
 */
class AiImageMaterialMapper extends AbstractMapper
{
    /**
     * @var AiImageMaterial
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiImageMaterial::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 使用场景
        if (isset($params['scene']) && $params['scene'] !== '') {
            $query->where('scene', '=', $params['scene']);
        }

        // 备注
        if (isset($params['remark']) && $params['remark'] !== '') {
            $query->where('remark', 'like', '%'.$params['remark'].'%');
        }

        // 使用开始时间
        if (isset($params['start_at']) && is_array($params['start_at']) && count($params['start_at']) == 2) {
            $query->whereBetween(
                'start_at',
                [ $params['start_at'][0], $params['start_at'][1] ]
            );
        }

        // 使用结束时间
        if (isset($params['end_at']) && is_array($params['end_at']) && count($params['end_at']) == 2) {
            $query->whereBetween(
                'end_at',
                [ $params['end_at'][0], $params['end_at'][1] ]
            );
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiMineMenuGroupMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiMineMenuGroup;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 个人中心菜单分组Mapper类
 */
class AiMineMenuGroupMapper extends AbstractMapper
{
    /**
     * @var AiMineMenuGroup
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiMineMenuGroup::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 分组名称
        if (isset($params['name']) && $params['name'] !== '') {
            $query->where('name', 'like', '%'.$params['name'].'%');
        }

        // 排序
        if (isset($params['sort']) && $params['sort'] !== '') {
            $query->where('sort', '=', $params['sort']);
        }

        // 是否锁定:1正常,锁定
        if (isset($params['is_lock']) && $params['is_lock'] !== '') {
            $query->where('is_lock', '=', $params['is_lock']);
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        // 更新时间
        if (isset($params['updated_at']) && is_array($params['updated_at']) && count($params['updated_at']) == 2) {
            $query->whereBetween(
                'updated_at',
                [ $params['updated_at'][0], $params['updated_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiMineMenuMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiMineMenu;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 个人中心菜单Mapper类
 */
class AiMineMenuMapper extends AbstractMapper
{
    /**
     * @var AiMineMenu
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiMineMenu::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 分组名称
        if (isset($params['name']) && $params['name'] !== '') {
            $query->where('name', 'like', '%'.$params['name'].'%');
        }

        // 是否锁定:1正常,2锁定
        if (isset($params['is_lock']) && $params['is_lock'] !== '') {
            $query->where('is_lock', '=', $params['is_lock']);
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        // 更新时间
        if (isset($params['updated_at']) && is_array($params['updated_at']) && count($params['updated_at']) == 2) {
            $query->whereBetween(
                'updated_at',
                [ $params['updated_at'][0], $params['updated_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiOpenaiKeyMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiOpenaiKey;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * openai_keyMapper类
 */
class AiOpenaiKeyMapper extends AbstractMapper
{
    /**
     * @var AiOpenaiKey
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiOpenaiKey::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // openai_key
        if (isset($params['openai_key']) && $params['openai_key'] !== '') {
            $query->where('openai_key', 'like', '%'.$params['openai_key'].'%');
        }

        // 备注
        if (isset($params['remark']) && $params['remark'] !== '') {
            $query->where('remark', 'like', '%'.$params['remark'].'%');
        }

        // 主键
        if (isset($params['id']) && $params['id'] !== '') {
            $query->where('id', '=', $params['id']);
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        // 更新时间
        if (isset($params['updated_at']) && is_array($params['updated_at']) && count($params['updated_at']) == 2) {
            $query->whereBetween(
                'updated_at',
                [ $params['updated_at'][0], $params['updated_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiOrderMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiOrder;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 订单表Mapper类
 */
class AiOrderMapper extends AbstractMapper
{
    /**
     * @var AiOrder
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiOrder::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 用户UID
        if (isset($params['uid']) && $params['uid'] !== '') {
            $query->where('uid', '=', $params['uid']);
        }

        // 订单号
        if (isset($params['ord_sn']) && $params['ord_sn'] !== '') {
            $query->where('ord_sn', 'like', '%'.$params['ord_sn'].'%');
        }

        // 订单类型: 1开通VIP 2提现 3成为营销部
        if (isset($params['ord_type']) && $params['ord_type'] !== '') {
            $query->where('ord_type', '=', $params['ord_type']);
        }

        // 支付方式: 1微信 2后台付费
        if (isset($params['pay_type']) && $params['pay_type'] !== '') {
            $query->where('pay_type', '=', $params['pay_type']);
        }

        // 订单状态 1未支付(待处理) 2已支付(已完成) 3失败
        if (isset($params['status']) && $params['status'] !== '') {
            $query->where('status', '=', $params['status']);
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        // 订单完成时间
        if (isset($params['pay_at']) && is_array($params['pay_at']) && count($params['pay_at']) == 2) {
            $query->whereBetween(
                'pay_at',
                [ $params['pay_at'][0], $params['pay_at'][1] ]
            );
        }

        // 更新时间
        if (isset($params['updated_at']) && is_array($params['updated_at']) && count($params['updated_at']) == 2) {
            $query->whereBetween(
                'updated_at',
                [ $params['updated_at'][0], $params['updated_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiPayKamiMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiPayKami;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 卡密Mapper类
 */
class AiPayKamiMapper extends AbstractMapper
{
    /**
     * @var AiPayKami
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiPayKami::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 主键
        if (isset($params['id']) && $params['id'] !== '') {
            $query->where('id', '=', $params['id']);
        }

        // 绑定用户
        if (isset($params['uid']) && $params['uid'] !== '') {
            $query->where('uid', '=', $params['uid']);
        }

        // 卡密号
        if (isset($params['code']) && $params['code'] !== '') {
            $query->where('code', 'like', '%'.$params['code'].'%');
        }

        // 状态 1未使用 2已使用
        if (isset($params['status']) && $params['status'] !== '') {
            $query->where('status', '=', $params['status']);
        }

        // 备注
        if (isset($params['remark']) && $params['remark'] !== '') {
            $query->where('remark', 'like', '%'.$params['remark'].'%');
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        // 使用时间
        if (isset($params['use_at']) && is_array($params['use_at']) && count($params['use_at']) == 2) {
            $query->whereBetween(
                'use_at',
                [ $params['use_at'][0], $params['use_at'][1] ]
            );
        }

        // 更新时间
        if (isset($params['updated_at']) && is_array($params['updated_at']) && count($params['updated_at']) == 2) {
            $query->whereBetween(
                'updated_at',
                [ $params['updated_at'][0], $params['updated_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiQuickIssueMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiQuickIssue;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 快捷问题
Mapper类
 */
class AiQuickIssueMapper extends AbstractMapper
{
    /**
     * @var AiQuickIssue
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiQuickIssue::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        
        // 问题标题
        if (isset($params['title']) && $params['title'] !== '') {
            $query->where('title', 'like', '%'.$params['title'].'%');
        }

        // 问题描述
        if (isset($params['content']) && $params['content'] !== '') {
            $query->where('content', 'like', '%'.$params['content'].'%');
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Mapper/AiUserMapper.php
================================================
<?php
declare(strict_types=1);


namespace App\Ai\Mapper;

use App\Ai\Model\AiUser;
use App\Ai\Model\AiUserRelation;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 用户主表Mapper类
 */
class AiUserMapper extends AbstractMapper
{
    /**
     * @var AiUser
     */
    public $model;

    public function assignModel()
    {
        $this->model = AiUser::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {

        // 昵称
        if (isset($params['nick_name']) && $params['nick_name'] !== '') {
            $query->where('nick_name', 'like', '%'.$params['nick_name'].'%');
        }

        // 手机号
        if (isset($params['mobile']) && $params['mobile'] !== '') {
            $query->where('mobile', 'like', '%'.$params['mobile'].'%');
        }

        // vip等级
        if (isset($params['vip']) && $params['vip'] !== '') {
            $query->where('vip', '=', $params['vip']);
        }

        // vip到期时间
        if (isset($params['vip_ent_at']) && is_array($params['vip_ent_at']) && count($params['vip_ent_at']) == 2) {
            $query->whereBetween(
                'vip_ent_at',
                [ $params['vip_ent_at'][0], $params['vip_ent_at'][1] ]
            );
        }

        // 是否锁定:1正常,2锁定
        if (isset($params['is_lock']) && $params['is_lock'] !== '') {
            $query->where('is_lock', '=', $params['is_lock']);
        }

        // 创建时间
        if (isset($params['created_at']) && is_array($params['created_at']) && count($params['created_at']) == 2) {
            $query->whereBetween(
                'created_at',
                [ $params['created_at'][0], $params['created_at'][1] ]
            );
        }

        // 更新时间
        if (isset($params['updated_at']) && is_array($params['updated_at']) && count($params['updated_at']) == 2) {
            $query->whereBetween(
                'updated_at',
                [ $params['updated_at'][0], $params['updated_at'][1] ]
            );
        }
        return $query;
    }
}

================================================
FILE: MineAdmin/php/app/Ai/Middleware/AuthMiddleware.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Middleware;

use App\Ai\Service\AiLoginService;
use App\Ai\Api\Login;
use App\Ai\Constants\ResponseCodeConst;
use App\Ai\Service\AiSettingService;
use App\Ai\Service\AiUserService;
use Hyperf\Context\Context;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Mine\Exception\NormalStatusException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class AuthMiddleware implements MiddlewareInterface
{
    protected ContainerInterface $container;

    protected RequestInterface $request;

    protected HttpResponse $response;

    protected StdoutLoggerInterface $logger;

    protected AiLoginService $loginService;

    protected AiSettingService $settingService;

    protected AiUserService $userService;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
        $this->loginService = $container->get(AiLoginService::class);
        $this->settingService = $container->get(AiSettingService::class);
        $this->logger = $container->get(StdoutLoggerInterface::class);
        $this->userService = $container->get(AiUserService::class);
    }

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        if (false === $this->loginService->check(null, 'ai')) {
            throw new NormalStatusException('error', ResponseCodeConst::INVALID_TOKEN);
        }

        $data = $this->loginService->getInfo();
        if (($data['version'] ?? '') != Login::VERSIONS) {
            throw new NormalStatusException('error', ResponseCodeConst::CLEAR_ALL_CACHE);
        }

        // 检测系统是否关站
        if ($closeMsg = $this->settingService->appClose()) {
            throw new NormalStatusException($closeMsg, ResponseCodeConst::APP_CLOSE);
        }

        // 拦截刚删除的用户、锁定的账户
        if ($this->userService->isJustDelete($data['id'])) {
            throw new NormalStatusException('账号不存在', ResponseCodeConst::CLEAR_ALL_CACHE);
        }

        if ($this->userService->isJustLock($data['id'])) {
            throw new NormalStatusException('账号被锁定', ResponseCodeConst::ACCOUNT_LOCK);
        }

        Context::set(self::class . '_login_data', $data);
        return $handler->handle($request);
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiChatMessage.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property int $sid 会话ID
 * @property string $content 内容
 * @property string $reply_content 内容
 * @property string $reply_at 回复时间
 * @property string $created_at 创建时间
 * @property string $deleted_at 删除时间
 */
class AiChatMessage extends MineModel
{
    use SoftDeletes;
    public bool $timestamps = false;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_chat_message';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'sid', 'content', 'reply_content', 'reply_at', 'created_at', 'deleted_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'sid' => 'integer'];
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiChatSession.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Hyperf\Database\Model\Relations\HasOne;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property int $uid 用户uid
 * @property int $prompt_id 模型ID
 * @property int $close 是否关闭:1正常,2关闭
 * @property int $share 是否分享:1关闭,2公开
 * @property string $created_at 创建时间
 * @property-read AiChatgptPrompts $prompt
 * @property-read AiChatMessage $firstMessage 
 * @property-read AiUser $user 
 */
class AiChatSession extends MineModel
{
    public bool $timestamps = false;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_chat_session';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'uid', 'prompt_id', 'close', 'share', 'created_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'uid' => 'integer', 'prompt_id' => 'integer', 'close' => 'integer', 'share' => 'integer'];

    public function prompt(): HasOne
    {
        return $this->hasOne(AiChatgptPrompts::class, 'id', 'prompt_id');
    }

    public function firstMessage(): HasOne
    {
        return $this->hasOne(AiChatMessage::class, 'sid', 'id');
    }

    public function user(): HasOne
    {
        return $this->hasOne(AiUser::class, 'id', 'uid');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiChatgptPrompts.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property string $act 角色名称
 * @property string $prompt 角色说明
 * @property int $sort 排序
 * @property int $created_by 创建者
 * @property int $updated_by 更新者
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 * @property string $remark 备注
 */
class AiChatgptPrompts extends MineModel
{
    use SoftDeletes;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_chatgpt_prompts';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'act', 'prompt', 'sort', 'created_by', 'updated_by', 'created_at', 'updated_at', 'deleted_at', 'remark'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'sort' => 'integer', 'created_by' => 'integer', 'updated_by' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiImageMaterial.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use App\Ai\Service\HelperService;
use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property int $scene 使用场景
 * @property string $img_url 图片地址
 * @property string $url 跳转地址
 * @property string $remark 备注
 * @property int $sort 排序
 * @property int $created_by 创建者
 * @property int $updated_by 更新者
 * @property string $start_at 使用开始时间
 * @property string $end_at 使用结束时间
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 */
class AiImageMaterial extends MineModel
{
    use SoftDeletes;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_image_material';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'scene', 'img_url', 'url', 'remark', 'sort', 'created_by', 'updated_by', 'start_at', 'end_at', 'created_at', 'updated_at', 'deleted_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'scene' => 'integer', 'sort' => 'integer', 'created_by' => 'integer', 'updated_by' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];

    public function setImgUrlAttribute($value)
    {
        $this->attributes['img_url'] = HelperService::buildSavePath($value);
    }

    public function getImgUrlAttribute($value)
    {
        return HelperService::buildSourceUrl($value);
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiMineMenu.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use App\Ai\Service\HelperService;
use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property int $gid 分组ID
 * @property string $name 分组名称
 * @property int $sort 排序
 * @property int $use_vip 使用权限限制 0全部
 * @property int $click_type 点击类型 1跳转 2调用函数
 * @property string $click_func 函数标识 小程序端提前封装
 * @property string $path 打开的页面路径
 * @property string $app_id 小程序appid
 * @property string $extra_data 需要传递给目标小程序的数据 json
 * @property string $env_version 要打开的小程序版本
 * @property string $short_link 小程序链接
 * @property int $is_lock 是否锁定:1正常,2锁定
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 * @property mixed $icon 
 */
class AiMineMenu extends MineModel
{
    use SoftDeletes;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_mine_menu';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'gid', 'name', 'sort', 'use_vip', 'click_type', 'click_func', 'path', 'app_id', 'extra_data', 'env_version', 'short_link', 'icon', 'is_lock', 'created_at', 'updated_at', 'deleted_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'gid' => 'integer', 'sort' => 'integer', 'use_vip' => 'integer', 'click_type' => 'integer', 'is_lock' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];

    public function setIconAttribute($value)
    {
        $this->attributes['icon'] = HelperService::buildSavePath($value);
    }

    public function getIconAttribute($value)
    {
        return HelperService::buildSourceUrl($value);
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiMineMenuGroup.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use \App\Ai\Model\AiMineMenu;
use Hyperf\Database\Model\Relations\HasMany;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property string $name 分组名称
 * @property int $sort 排序
 * @property int $is_lock 是否锁定:1正常,锁定
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property-read \Hyperf\Database\Model\Collection|AiMineMenu[] $menus 
 */
class AiMineMenuGroup extends MineModel
{
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_mine_menu_group';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'name', 'sort', 'is_lock', 'created_at', 'updated_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'sort' => 'integer', 'is_lock' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];


    public function menus(): HasMany
    {
        return $this->hasMany(AiMineMenu::class, 'gid', 'id');
    }
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiOpenaiKey.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property string $openai_key openai_key
 * @property string $remark 备注
 * @property int $id 主键
 * @property int $created_by 创建者
 * @property int $updated_by 更新者
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 */
class AiOpenaiKey extends MineModel
{
    use SoftDeletes;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_openai_key';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['openai_key', 'remark', 'id', 'created_by', 'updated_by', 'created_at', 'updated_at', 'deleted_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'created_by' => 'integer', 'updated_by' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiOrder.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property int $uid 用户UID
 * @property int $from_uid 上级UID
 * @property int $market_uid 营销部UID
 * @property string $ord_sn 订单号
 * @property int $ord_type 订单类型: 1开通VIP 2提现 3成为营销部
 * @property int $pay_type 支付方式: 1微信 2后台付费
 * @property int $status 订单状态 1未支付(待处理) 2已支付(已完成) 3失败
 * @property int $total_price 总金额
 * @property int $amount_price 实际金额
 * @property string $content 订单描述
 * @property string $remark 备注
 * @property int $created_by 创建者
 * @property int $updated_by 更新者
 * @property \Carbon\Carbon $created_at 创建时间
 * @property string $pay_at 订单完成时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 */
class AiOrder extends MineModel
{
    use SoftDeletes;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_order';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'uid', 'from_uid', 'market_uid', 'ord_sn', 'ord_type', 'pay_type', 'status', 'total_price', 'amount_price', 'content', 'remark', 'created_by', 'updated_by', 'created_at', 'pay_at', 'updated_at', 'deleted_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'uid' => 'integer', 'from_uid' => 'integer', 'market_uid' => 'integer', 'ord_type' => 'integer', 'pay_type' => 'integer', 'status' => 'integer', 'total_price' => 'integer', 'amount_price' => 'integer', 'created_by' => 'integer', 'updated_by' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiOrderKami.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Mine\MineModel;

/**
 * @property int $oid 订单ID
 * @property int $kid 卡密ID
 */
class AiOrderKami extends MineModel
{
    public bool $incrementing = false;
    protected string $primaryKey = 'oid';
    public bool $timestamps = false;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_order_kami';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['oid', 'kid'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['oid' => 'integer', 'kid' => 'integer'];
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiOrderVip.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Mine\MineModel;

/**
 * @property int $oid 订单ID
 * @property int $vip_level vip等级
 * @property string $wx_sn 微信订单号
 * @property string $mch_id 商户ID
 * @property \Carbon\Carbon $created_at 创建时间
 */
class AiOrderVip extends MineModel
{
    public bool $incrementing = false;
    protected string $primaryKey = 'oid';
    public bool $timestamps = false;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_order_vip';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['oid', 'vip_level', 'wx_sn', 'mch_id', 'created_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['oid' => 'integer', 'vip_level' => 'integer', 'created_at' => 'datetime'];
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiPayKami.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property int $uid 绑定用户
 * @property int $price 价格
 * @property string $code 卡密号
 * @property int $status 状态 1未使用 2已使用
 * @property string $remark 备注
 * @property int $created_by 创建者
 * @property int $updated_by 更新者
 * @property \Carbon\Carbon $created_at 创建时间
 * @property string $use_at 使用时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 */
class AiPayKami extends MineModel
{
    use SoftDeletes;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_pay_kami';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'uid', 'price', 'code', 'status', 'remark', 'created_by', 'updated_by', 'created_at', 'use_at', 'updated_at', 'deleted_at'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'uid' => 'integer', 'price' => 'integer', 'status' => 'integer', 'created_by' => 'integer', 'updated_by' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
}


================================================
FILE: MineAdmin/php/app/Ai/Model/AiQuickIssue.php
================================================
<?php

declare(strict_types=1);

namespace App\Ai\Model;

use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property string $title 问题标题
 * @property string $content 问题描述
 * @property int $sort 
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 */
class AiQuickIssue extends MineModel
{
    use SoftDeletes;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ai_quick_issue';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'title', 'content', 'sort', 'created_at', 'updated_at', 'de
Download .txt
gitextract_w1gfey8a/

├── .gitignore
├── LICENSE
├── MineAdmin/
│   ├── php/
│   │   └── app/
│   │       └── Ai/
│   │           ├── Api/
│   │           │   ├── BaseApi.php
│   │           │   ├── Chat.php
│   │           │   ├── Common.php
│   │           │   ├── Login.php
│   │           │   ├── Order.php
│   │           │   ├── User.php
│   │           │   ├── Wallet.php
│   │           │   └── Websocket.php
│   │           ├── Command/
│   │           │   └── InitMenuCommand.php
│   │           ├── Constants/
│   │           │   ├── OrderConst.php
│   │           │   ├── RedisConst.php
│   │           │   ├── ResponseCodeConst.php
│   │           │   ├── UploadSceneConst.php
│   │           │   ├── VipConst.php
│   │           │   └── WalletConst.php
│   │           ├── Controller/
│   │           │   ├── AiChatMessageController.php
│   │           │   ├── AiChatSessionController.php
│   │           │   ├── AiChatgptPromptsController.php
│   │           │   ├── AiImageMaterialController.php
│   │           │   ├── AiMineMenuController.php
│   │           │   ├── AiMineMenuGroupController.php
│   │           │   ├── AiOpenaiKeyController.php
│   │           │   ├── AiOrderController.php
│   │           │   ├── AiPayKamiController.php
│   │           │   ├── AiQuickIssueController.php
│   │           │   ├── AiSettingController.php
│   │           │   └── AiUserController.php
│   │           ├── Crontab/
│   │           │   └── CheckVipOver.php
│   │           ├── Database/
│   │           │   ├── Migrations/
│   │           │   │   ├── 2023_05_04_145048_create_ai_user_table.php
│   │           │   │   ├── 2023_05_09_095456_create_ai_user_wallet_table.php
│   │           │   │   ├── 2023_05_09_095504_create_ai_user_wallet_log_table.php
│   │           │   │   ├── 2023_05_09_095525_create_ai_user_relation_table.php
│   │           │   │   ├── 2023_05_09_095540_create_ai_order_table.php
│   │           │   │   ├── 2023_05_09_095543_create_ai_order_vip_table.php
│   │           │   │   ├── 2023_05_09_102806_create_ai_mine_menu_group_table.php
│   │           │   │   ├── 2023_05_09_102817_create_ai_mine_menu_table.php
│   │           │   │   ├── 2023_05_09_154733_create_ai_chatgpt_prompts_table.php
│   │           │   │   ├── 2023_05_10_165842_create_ai_chat_message_table.php
│   │           │   │   ├── 2023_05_10_171603_create_ai_chat_session_table.php
│   │           │   │   ├── 2023_05_12_152504_create_ai_quick_issue_table.php
│   │           │   │   ├── 2023_05_19_164456_create_ai_pay_kami_table.php
│   │           │   │   ├── 2023_05_25_152855_create_ai_openai_key_table.php
│   │           │   │   ├── 2023_05_26_111034_create_ai_order_kami_table.php
│   │           │   │   └── 2023_06_14_141605_create_ai_image_material_table.php
│   │           │   └── Seeders/
│   │           │       ├── ai_chatgpt_prompts.php
│   │           │       ├── ai_mine_menu.php
│   │           │       ├── ai_mine_menu_group.php
│   │           │       └── ai_user.php
│   │           ├── Dto/
│   │           │   ├── AiChatMessageDto.php
│   │           │   ├── AiChatSessionDto.php
│   │           │   ├── AiChatgptPromptsDto.php
│   │           │   ├── AiImageMaterialDto.php
│   │           │   ├── AiMineMenuDto.php
│   │           │   ├── AiMineMenuGroupDto.php
│   │           │   ├── AiOpenaiKeyDto.php
│   │           │   ├── AiOrderDto.php
│   │           │   ├── AiPayKamiDto.php
│   │           │   ├── AiQuickIssueDto.php
│   │           │   └── AiUserDto.php
│   │           ├── Factory/
│   │           │   └── AiRedisFactory.php
│   │           ├── Mapper/
│   │           │   ├── AiChatMessageMapper.php
│   │           │   ├── AiChatSessionMapper.php
│   │           │   ├── AiChatgptPromptsMapper.php
│   │           │   ├── AiImageMaterialMapper.php
│   │           │   ├── AiMineMenuGroupMapper.php
│   │           │   ├── AiMineMenuMapper.php
│   │           │   ├── AiOpenaiKeyMapper.php
│   │           │   ├── AiOrderMapper.php
│   │           │   ├── AiPayKamiMapper.php
│   │           │   ├── AiQuickIssueMapper.php
│   │           │   └── AiUserMapper.php
│   │           ├── Middleware/
│   │           │   └── AuthMiddleware.php
│   │           ├── Model/
│   │           │   ├── AiChatMessage.php
│   │           │   ├── AiChatSession.php
│   │           │   ├── AiChatgptPrompts.php
│   │           │   ├── AiImageMaterial.php
│   │           │   ├── AiMineMenu.php
│   │           │   ├── AiMineMenuGroup.php
│   │           │   ├── AiOpenaiKey.php
│   │           │   ├── AiOrder.php
│   │           │   ├── AiOrderKami.php
│   │           │   ├── AiOrderVip.php
│   │           │   ├── AiPayKami.php
│   │           │   ├── AiQuickIssue.php
│   │           │   ├── AiUser.php
│   │           │   ├── AiUserRelation.php
│   │           │   ├── AiUserWallet.php
│   │           │   └── AiUserWalletLog.php
│   │           ├── Request/
│   │           │   ├── AiChatMessageRequest.php
│   │           │   ├── AiChatSessionRequest.php
│   │           │   ├── AiChatgptPromptsRequest.php
│   │           │   ├── AiImageMaterialRequest.php
│   │           │   ├── AiMineMenuGroupRequest.php
│   │           │   ├── AiMineMenuRequest.php
│   │           │   ├── AiOpenaiKeyRequest.php
│   │           │   ├── AiOrderRequest.php
│   │           │   ├── AiPayKamiRequest.php
│   │           │   ├── AiQuickIssueRequest.php
│   │           │   └── AiUserRequest.php
│   │           ├── Service/
│   │           │   ├── AiChatMessageService.php
│   │           │   ├── AiChatSessionService.php
│   │           │   ├── AiChatgptPromptsService.php
│   │           │   ├── AiImageMaterialService.php
│   │           │   ├── AiLoginService.php
│   │           │   ├── AiMineMenuGroupService.php
│   │           │   ├── AiMineMenuService.php
│   │           │   ├── AiOpenaiKeyService.php
│   │           │   ├── AiOrderService.php
│   │           │   ├── AiPayKamiService.php
│   │           │   ├── AiQuickIssueService.php
│   │           │   ├── AiSettingService.php
│   │           │   ├── AiUserService.php
│   │           │   ├── AiVipService.php
│   │           │   ├── AiWalletService.php
│   │           │   ├── HelperService.php
│   │           │   └── QiniuService.php
│   │           └── config.json
│   └── vue/
│       └── src/
│           ├── api/
│           │   └── ai/
│           │       ├── aiChatMessage.js
│           │       ├── aiChatSession.js
│           │       ├── aiChatgptPrompts.js
│           │       ├── aiImageMaterial.js
│           │       ├── aiMineMenu.js
│           │       ├── aiMineMenuGroup.js
│           │       ├── aiOpenaiKey.js
│           │       ├── aiOrder.js
│           │       ├── aiPayKami.js
│           │       ├── aiQuickIssue.js
│           │       ├── aiSetting.js
│           │       └── aiUser.js
│           ├── components/
│           │   └── putyy/
│           │       └── pt-upload.vue
│           ├── config/
│           │   ├── pt-const.js
│           │   └── pt-scene.js
│           ├── utils/
│           │   └── pt-upload.js
│           └── views/
│               └── ai/
│                   ├── chatMessage/
│                   │   └── index.vue
│                   ├── chatSession/
│                   │   └── index.vue
│                   ├── chatgptPrompts/
│                   │   └── index.vue
│                   ├── imageMaterial/
│                   │   └── index.vue
│                   ├── mineMenu/
│                   │   └── index.vue
│                   ├── mineMenuGroup/
│                   │   └── index.vue
│                   ├── openKey/
│                   │   ├── components/
│                   │   │   └── add.vue
│                   │   └── index.vue
│                   ├── order/
│                   │   └── index.vue
│                   ├── payKami/
│                   │   ├── components/
│                   │   │   └── add.vue
│                   │   └── index.vue
│                   ├── quickIssue/
│                   │   └── index.vue
│                   ├── setting/
│                   │   └── index.vue
│                   └── user/
│                       ├── components/
│                       │   └── openVip.vue
│                       └── index.vue
├── README.md
└── UniApp/
    ├── .gitignore
    ├── App.vue
    ├── README.md
    ├── androidPrivacy.json
    ├── common/
    │   ├── api.ts
    │   ├── const.ts
    │   ├── func.ts
    │   └── utils/
    │       ├── jump.ts
    │       ├── request.ts
    │       └── services.ts
    ├── components/
    │   ├── AgreementPopup.vue
    │   ├── FooterCommon.vue
    │   ├── Nothing.vue
    │   ├── OpenVipPopup.vue
    │   ├── QrCodePopup.vue
    │   └── Search.vue
    ├── config.example.ts
    ├── index.html
    ├── logic/
    │   └── user.ts
    ├── main.js
    ├── manifest.json
    ├── pages/
    │   ├── chatgpt/
    │   │   ├── channel.vue
    │   │   └── room.vue
    │   ├── login.vue
    │   ├── notice.vue
    │   └── user/
    │       ├── friend.vue
    │       ├── mine.vue
    │       ├── order.vue
    │       ├── perfect.vue
    │       ├── wallet.vue
    │       ├── walletList.vue
    │       └── withdrawalList.vue
    ├── pages.json
    ├── store/
    │   ├── index.ts
    │   └── websocket.ts
    ├── tsconfig.json
    ├── types/
    │   └── global.d.ts
    ├── uni.promisify.adaptor.js
    ├── uni.scss
    └── uni_modules/
        ├── bt-cropper_3.0.1/
        │   ├── changelog.md
        │   ├── components/
        │   │   └── bt-cropper/
        │   │       ├── bt-cropper.vue
        │   │       ├── iconfont.css
        │   │       ├── js/
        │   │       │   └── touchs.js
        │   │       ├── utils/
        │   │       │   └── tools.js
        │   │       └── {ages.json
        │   ├── package.json
        │   └── readme.md
        └── mp-html/
            ├── README.md
            ├── changelog.md
            ├── components/
            │   └── mp-html/
            │       ├── emoji/
            │       │   └── index.js
            │       ├── highlight/
            │       │   ├── config.js
            │       │   └── index.js
            │       ├── markdown/
            │       │   └── index.js
            │       ├── mp-html.vue
            │       ├── node/
            │       │   └── node.vue
            │       └── parser.js
            ├── package.json
            └── static/
                └── app-plus/
                    └── mp-html/
                        ├── js/
                        │   └── handler.js
                        └── local.html
Download .txt
SYMBOL INDEX (510 symbols across 143 files)

FILE: MineAdmin/php/app/Ai/Api/BaseApi.php
  class BaseApi (line 12) | class BaseApi extends MineController
    method checkParameter (line 14) | public function checkParameter(array $params, array $checkData = [], b...
    method funCallbackRes (line 41) | public function funCallbackRes(callable $callback): ResponseInterface
    method funCallback (line 46) | public function funCallback(callable $callback)

FILE: MineAdmin/php/app/Ai/Api/Chat.php
  class Chat (line 23) | #[Controller(prefix: "ai/api/chat")]
    method roles (line 42) | #[GetMapping("roles")]
    method modelList (line 54) | #[GetMapping("model-list")]
    method session (line 60) | #[GetMapping("session")]
    method sessionClose (line 66) | #[PostMapping("session-close")]
    method messages (line 74) | #[GetMapping("messages")]
    method sessionHistory (line 93) | #[GetMapping("session-history")]
    method sessionShare (line 101) | #[PostMapping("session-share")]
    method sessionDelete (line 117) | #[PostMapping("session-delete")]
    method sessionShareList (line 134) | #[GetMapping("session-share-list")]
    method sessionShareMessageList (line 142) | #[GetMapping("session-share-message-list")]
    method quickIssue (line 155) | #[GetMapping("quick-issue")]
    method test (line 168) | public function test()

FILE: MineAdmin/php/app/Ai/Api/Common.php
  class Common (line 19) | #[Controller(prefix: "ai/api/public")]
    method init (line 38) | #[GetMapping("init")]
    method uploadToken (line 66) | #[GetMapping("upload-token")]
    method vipConfig (line 72) | #[GetMapping("vip-config")]

FILE: MineAdmin/php/app/Ai/Api/Login.php
  class Login (line 15) | #[Controller(prefix: "ai/api/login")]
    method index (line 23) | #[GetMapping("index")]

FILE: MineAdmin/php/app/Ai/Api/Order.php
  class Order (line 16) | #[Controller(prefix: "ai/api/order")]
    method index (line 23) | #[GetMapping("list")]
    method kamiOpenVip (line 33) | #[PostMapping("kami-open-vip")]

FILE: MineAdmin/php/app/Ai/Api/User.php
  class User (line 27) | #[Controller(prefix: "ai/api/user")]
    method mine (line 43) | #[GetMapping("mine")]
    method edit (line 70) | #[PostMapping("edit")]
    method friends (line 87) | #[GetMapping("friends")]

FILE: MineAdmin/php/app/Ai/Api/Wallet.php
  class Wallet (line 17) | #[Controller(prefix: "ai/api/wallet")]
    method index (line 27) | #[GetMapping("index")]
    method changeLogList (line 32) | #[GetMapping("change-log-list")]
    method withdrawalList (line 40) | #[GetMapping("withdrawal-list")]
    method withdrawal (line 50) | #[PostMapping("withdrawal")]

FILE: MineAdmin/php/app/Ai/Api/Websocket.php
  class Websocket (line 27) | class Websocket implements OnMessageInterface, OnOpenInterface, OnCloseI...
    method onMessage (line 50) | public function onMessage($server, $frame): void
    method messageHandle (line 70) | public function messageHandle($fd, $data)
    method chatgpt (line 85) | protected function chatgpt($fd, $data){
    method onClose (line 193) | public function onClose($server, int $fd, int $reactorId): void
    method onOpen (line 212) | public function onOpen($server, $request): void

FILE: MineAdmin/php/app/Ai/Command/InitMenuCommand.php
  class InitMenuCommand (line 11) | #[Command]
    method handle (line 20) | public function handle()

FILE: MineAdmin/php/app/Ai/Constants/OrderConst.php
  class OrderConst (line 7) | class OrderConst extends DescConst

FILE: MineAdmin/php/app/Ai/Constants/RedisConst.php
  class RedisConst (line 6) | class RedisConst

FILE: MineAdmin/php/app/Ai/Constants/ResponseCodeConst.php
  class ResponseCodeConst (line 6) | class ResponseCodeConst

FILE: MineAdmin/php/app/Ai/Constants/UploadSceneConst.php
  class UploadSceneConst (line 4) | class UploadSceneConst
    method hasScene (line 23) | public static function hasScene(string $scene): bool
    method isOnly (line 31) | public static function isOnly(string $scene): bool

FILE: MineAdmin/php/app/Ai/Constants/VipConst.php
  class VipConst (line 8) | class VipConst extends DescConst
    method config (line 30) | public static function config(): array

FILE: MineAdmin/php/app/Ai/Constants/WalletConst.php
  class WalletConst (line 8) | class WalletConst extends DescConst

FILE: MineAdmin/php/app/Ai/Controller/AiChatMessageController.php
  class AiChatMessageController (line 25) | #[Controller(prefix: "ai/chatMessage"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:chatMessage, ai:chatMessage:inde...
    method read (line 55) | #[GetMapping("read/{id}"), Permission("ai:chatMessage:read")]
    method delete (line 67) | #[DeleteMapping("delete"), Permission("ai:chatMessage:delete"), Operat...

FILE: MineAdmin/php/app/Ai/Controller/AiChatSessionController.php
  class AiChatSessionController (line 25) | #[Controller(prefix: "ai/chatSession"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:chatSession, ai:chatSession:inde...
    method read (line 55) | #[GetMapping("read/{id}"), Permission("ai:chatSession:read")]
    method delete (line 67) | #[DeleteMapping("delete"), Permission("ai:chatSession:delete"), Operat...

FILE: MineAdmin/php/app/Ai/Controller/AiChatgptPromptsController.php
  class AiChatgptPromptsController (line 25) | #[Controller(prefix: "ai/chatgptPrompts"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:chatgptPrompts, ai:chatgptPrompt...
    method update (line 56) | #[PutMapping("update/{id}"), Permission("ai:chatgptPrompts:update"), O...
    method save (line 69) | #[PostMapping("save"), Permission("ai:chatgptPrompts:save"), Operation...
    method read (line 82) | #[GetMapping("read/{id}"), Permission("ai:chatgptPrompts:read")]
    method delete (line 94) | #[DeleteMapping("delete"), Permission("ai:chatgptPrompts:delete"), Ope...

FILE: MineAdmin/php/app/Ai/Controller/AiImageMaterialController.php
  class AiImageMaterialController (line 25) | #[Controller(prefix: "ai/imageMaterial"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:imageMaterial, ai:imageMaterial:...
    method save (line 55) | #[PostMapping("save"), Permission("ai:imageMaterial:save"), OperationLog]
    method update (line 69) | #[PutMapping("update/{id}"), Permission("ai:imageMaterial:update"), Op...
    method read (line 82) | #[GetMapping("read/{id}"), Permission("ai:imageMaterial:read")]
    method delete (line 94) | #[DeleteMapping("delete"), Permission("ai:imageMaterial:delete"), Oper...

FILE: MineAdmin/php/app/Ai/Controller/AiMineMenuController.php
  class AiMineMenuController (line 25) | #[Controller(prefix: "ai/mineMenu"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:mineMenu, ai:mineMenu:index")]
    method save (line 55) | #[PostMapping("save"), Permission("ai:mineMenu:save"), OperationLog]
    method update (line 69) | #[PutMapping("update/{id}"), Permission("ai:mineMenu:update"), Operati...
    method read (line 82) | #[GetMapping("read/{id}"), Permission("ai:mineMenu:read")]
    method delete (line 94) | #[DeleteMapping("delete"), Permission("ai:mineMenu:delete"), Operation...

FILE: MineAdmin/php/app/Ai/Controller/AiMineMenuGroupController.php
  class AiMineMenuGroupController (line 25) | #[Controller(prefix: "ai/mineMenuGroup"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:mineMenuGroup, ai:mineMenuGroup:...
    method save (line 55) | #[PostMapping("save"), Permission("ai:mineMenuGroup:save"), OperationLog]
    method update (line 69) | #[PutMapping("update/{id}"), Permission("ai:mineMenuGroup:update"), Op...
    method read (line 82) | #[GetMapping("read/{id}"), Permission("ai:mineMenuGroup:read")]
    method delete (line 94) | #[DeleteMapping("delete"), Permission("ai:mineMenuGroup:delete"), Oper...

FILE: MineAdmin/php/app/Ai/Controller/AiOpenaiKeyController.php
  class AiOpenaiKeyController (line 25) | #[Controller(prefix: "ai/openKey"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:openKey, ai:openKey:index")]
    method save (line 55) | #[PostMapping("save"), Permission("ai:openKey:save"), OperationLog]
    method update (line 69) | #[PutMapping("update/{id}"), Permission("ai:openKey:update"), Operatio...
    method read (line 82) | #[GetMapping("read/{id}"), Permission("ai:openKey:read")]
    method delete (line 94) | #[DeleteMapping("delete"), Permission("ai:openKey:delete"), OperationLog]
    method batchAdd (line 106) | #[PostMapping("batch-add"), Permission("ai:openKey:batch-add"), Operat...
    method refreshCache (line 118) | #[PostMapping("refresh-cache-list"), Permission("ai:openKey:refresh-ca...

FILE: MineAdmin/php/app/Ai/Controller/AiOrderController.php
  class AiOrderController (line 25) | #[Controller(prefix: "ai/order"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:order, ai:order:index")]
    method read (line 55) | #[GetMapping("read/{id}"), Permission("ai:order:read")]
    method delete (line 67) | #[DeleteMapping("delete"), Permission("ai:order:delete"), OperationLog]

FILE: MineAdmin/php/app/Ai/Controller/AiPayKamiController.php
  class AiPayKamiController (line 25) | #[Controller(prefix: "ai/payKami"), Auth]
    method index (line 42) | #[GetMapping("index"), Permission("ai:payKami, ai:payKami:index")]
    method read (line 55) | #[GetMapping("read/{id}"), Permission("ai:payKami:read")]
    method update (line 69) | #[PutMapping("update/{id}"), Permission("ai:payKami:update"), Operatio...
    method delete (line 81) | #[DeleteMapping("delete"), Permission("ai:payKami:delete"), OperationLog]
    method add (line 93) | #[PostMapping("add"), Permission("ai:payKami:add"), OperationLog]

FILE: MineAdmin/php/app/Ai/Controller/AiQuickIssueController.php
  class AiQuickIssueController (line 26) | #[Controller(prefix: "ai/quickIssue"), Auth]
    method index (line 43) | #[GetMapping("index"), Permission("ai:quickIssue, ai:quickIssue:index")]
    method update (line 57) | #[PutMapping("update/{id}"), Permission("ai:quickIssue:update"), Opera...
    method save (line 70) | #[PostMapping("save"), Permission("ai:quickIssue:save"), OperationLog]
    method read (line 83) | #[GetMapping("read/{id}"), Permission("ai:quickIssue:read")]
    method delete (line 95) | #[DeleteMapping("delete"), Permission("ai:quickIssue:delete"), Operati...

FILE: MineAdmin/php/app/Ai/Controller/AiSettingController.php
  class AiSettingController (line 19) | #[Controller(prefix: "ai/setting"), Auth]
    method index (line 29) | #[GetMapping("index"), Permission("ai:setting, ai:setting:index")]
    method save (line 44) | #[PostMapping("save"), Permission("ai:setting, ai:setting:save")]
    method uploadToken (line 57) | #[GetMapping("upload-token")]

FILE: MineAdmin/php/app/Ai/Controller/AiUserController.php
  class AiUserController (line 26) | #[Controller(prefix: "ai/user"), Auth]
    method index (line 44) | #[GetMapping("index"), Permission("ai:user, ai:user:index")]
    method update (line 58) | #[PutMapping("update/{id}"), Permission("ai:user:update"), OperationLog]
    method read (line 71) | #[GetMapping("read/{id}"), Permission("ai:user:read")]
    method delete (line 83) | #[DeleteMapping("delete"), Permission("ai:user:delete"), OperationLog]
    method openVip (line 97) | #[PostMapping("open-vip/{id}"), Permission("ai:user:open-vip"), Operat...
    method lock (line 104) | #[PostMapping("lock/{id}"), Permission("ai:user:lock"), OperationLog]

FILE: MineAdmin/php/app/Ai/Crontab/CheckVipOver.php
  class CheckVipOver (line 9) | class CheckVipOver
    method execute (line 11) | #[Transaction]

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_04_145048_create_ai_user_table.php
  class CreateAiUserTable (line 8) | class CreateAiUserTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 36) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095456_create_ai_user_wallet_table.php
  class CreateAiUserWalletTable (line 8) | class CreateAiUserWalletTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 27) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095504_create_ai_user_wallet_log_table.php
  class CreateAiUserWalletLogTable (line 8) | class CreateAiUserWalletLogTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 33) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095525_create_ai_user_relation_table.php
  class CreateAiUserRelationTable (line 8) | class CreateAiUserRelationTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 29) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095540_create_ai_order_table.php
  class CreateAiOrderTable (line 8) | class CreateAiOrderTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 42) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095543_create_ai_order_vip_table.php
  class CreateAiOrderVipTable (line 8) | class CreateAiOrderVipTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 26) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_102806_create_ai_mine_menu_group_table.php
  class CreateAiMineMenuGroupTable (line 8) | class CreateAiMineMenuGroupTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 30) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_102817_create_ai_mine_menu_table.php
  class CreateAiMineMenuTable (line 8) | class CreateAiMineMenuTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 41) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_154733_create_ai_chatgpt_prompts_table.php
  class CreateAiChatgptPromptsTable (line 8) | class CreateAiChatgptPromptsTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 34) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_10_165842_create_ai_chat_message_table.php
  class CreateAiChatMessageTable (line 8) | class CreateAiChatMessageTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 31) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_10_171603_create_ai_chat_session_table.php
  class CreateAiChatSessionTable (line 8) | class CreateAiChatSessionTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 30) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_12_152504_create_ai_quick_issue_table.php
  class CreateAiQuickIssueTable (line 8) | class CreateAiQuickIssueTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 32) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_19_164456_create_ai_pay_kami_table.php
  class CreateAiPayKamiTable (line 8) | class CreateAiPayKamiTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 36) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_25_152855_create_ai_openai_key_table.php
  class CreateAiOpenaiKeyTable (line 8) | class CreateAiOpenaiKeyTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 32) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_05_26_111034_create_ai_order_kami_table.php
  class CreateAiOrderKamiTable (line 8) | class CreateAiOrderKamiTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 26) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Migrations/2023_06_14_141605_create_ai_image_material_table.php
  class CreateAiImageMaterialTable (line 8) | class CreateAiImageMaterialTable extends Migration
    method up (line 13) | public function up(): void
    method down (line 37) | public function down(): void

FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_chatgpt_prompts.php
  class AiChatgptPrompts (line 7) | class AiChatgptPrompts extends Seeder
    method run (line 14) | public function run()

FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_mine_menu.php
  class AiMineMenu (line 7) | class AiMineMenu extends Seeder
    method run (line 14) | public function run()

FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_mine_menu_group.php
  class AiMineMenuGroup (line 7) | class AiMineMenuGroup extends Seeder
    method run (line 14) | public function run()

FILE: MineAdmin/php/app/Ai/Database/Seeders/ai_user.php
  class AiUser (line 17) | class AiUser extends Seeder
    method run (line 24) | public function run()

FILE: MineAdmin/php/app/Ai/Dto/AiChatMessageDto.php
  class AiChatMessageDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiChatSessionDto.php
  class AiChatSessionDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiChatgptPromptsDto.php
  class AiChatgptPromptsDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiImageMaterialDto.php
  class AiImageMaterialDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiMineMenuDto.php
  class AiMineMenuDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiMineMenuGroupDto.php
  class AiMineMenuGroupDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiOpenaiKeyDto.php
  class AiOpenaiKeyDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiOrderDto.php
  class AiOrderDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiPayKamiDto.php
  class AiPayKamiDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiQuickIssueDto.php
  class AiQuickIssueDto (line 12) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Dto/AiUserDto.php
  class AiUserDto (line 11) | #[ExcelData]

FILE: MineAdmin/php/app/Ai/Factory/AiRedisFactory.php
  class AiRedisFactory (line 8) | class AiRedisFactory extends Redis

FILE: MineAdmin/php/app/Ai/Mapper/AiChatMessageMapper.php
  class AiChatMessageMapper (line 14) | class AiChatMessageMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiChatSessionMapper.php
  class AiChatSessionMapper (line 15) | class AiChatSessionMapper extends AbstractMapper
    method assignModel (line 22) | public function assignModel()
    method handleSearch (line 33) | public function handleSearch(Builder $query, array $params): Builder
    method session (line 64) | public function session($where): Model|Builder|null

FILE: MineAdmin/php/app/Ai/Mapper/AiChatgptPromptsMapper.php
  class AiChatgptPromptsMapper (line 14) | class AiChatgptPromptsMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiImageMaterialMapper.php
  class AiImageMaterialMapper (line 14) | class AiImageMaterialMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiMineMenuGroupMapper.php
  class AiMineMenuGroupMapper (line 14) | class AiMineMenuGroupMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiMineMenuMapper.php
  class AiMineMenuMapper (line 14) | class AiMineMenuMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiOpenaiKeyMapper.php
  class AiOpenaiKeyMapper (line 14) | class AiOpenaiKeyMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiOrderMapper.php
  class AiOrderMapper (line 14) | class AiOrderMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiPayKamiMapper.php
  class AiPayKamiMapper (line 14) | class AiPayKamiMapper extends AbstractMapper
    method assignModel (line 21) | public function assignModel()
    method handleSearch (line 32) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiQuickIssueMapper.php
  class AiQuickIssueMapper (line 15) | class AiQuickIssueMapper extends AbstractMapper
    method assignModel (line 22) | public function assignModel()
    method handleSearch (line 33) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Mapper/AiUserMapper.php
  class AiUserMapper (line 15) | class AiUserMapper extends AbstractMapper
    method assignModel (line 22) | public function assignModel()
    method handleSearch (line 33) | public function handleSearch(Builder $query, array $params): Builder

FILE: MineAdmin/php/app/Ai/Middleware/AuthMiddleware.php
  class AuthMiddleware (line 25) | class AuthMiddleware implements MiddlewareInterface
    method __construct (line 41) | public function __construct(ContainerInterface $container, HttpRespons...
    method process (line 56) | public function process(ServerRequestInterface $request, RequestHandle...

FILE: MineAdmin/php/app/Ai/Model/AiChatMessage.php
  class AiChatMessage (line 19) | class AiChatMessage extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiChatSession.php
  class AiChatSession (line 21) | class AiChatSession extends MineModel
    method prompt (line 39) | public function prompt(): HasOne
    method firstMessage (line 44) | public function firstMessage(): HasOne
    method user (line 49) | public function user(): HasOne

FILE: MineAdmin/php/app/Ai/Model/AiChatgptPrompts.php
  class AiChatgptPrompts (line 22) | class AiChatgptPrompts extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiImageMaterial.php
  class AiImageMaterial (line 26) | class AiImageMaterial extends MineModel
    method setImgUrlAttribute (line 44) | public function setImgUrlAttribute($value)
    method getImgUrlAttribute (line 49) | public function getImgUrlAttribute($value)

FILE: MineAdmin/php/app/Ai/Model/AiMineMenu.php
  class AiMineMenu (line 30) | class AiMineMenu extends MineModel
    method setIconAttribute (line 48) | public function setIconAttribute($value)
    method getIconAttribute (line 53) | public function getIconAttribute($value)

FILE: MineAdmin/php/app/Ai/Model/AiMineMenuGroup.php
  class AiMineMenuGroup (line 20) | class AiMineMenuGroup extends MineModel
    method menus (line 38) | public function menus(): HasMany

FILE: MineAdmin/php/app/Ai/Model/AiOpenaiKey.php
  class AiOpenaiKey (line 20) | class AiOpenaiKey extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiOrder.php
  class AiOrder (line 30) | class AiOrder extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiOrderKami.php
  class AiOrderKami (line 13) | class AiOrderKami extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiOrderVip.php
  class AiOrderVip (line 16) | class AiOrderVip extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiPayKami.php
  class AiPayKami (line 24) | class AiPayKami extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiQuickIssue.php
  class AiQuickIssue (line 19) | class AiQuickIssue extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiUser.php
  class AiUser (line 28) | class AiUser extends MineModel
    method parentRelation (line 46) | public function parentRelation(): HasOne
    method wallet (line 51) | public function wallet(): HasOne
    method setHeadImgAttribute (line 56) | public function setHeadImgAttribute($value)
    method getHeadImgAttribute (line 61) | public function getHeadImgAttribute($value)

FILE: MineAdmin/php/app/Ai/Model/AiUserRelation.php
  class AiUserRelation (line 16) | class AiUserRelation extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiUserWallet.php
  class AiUserWallet (line 14) | class AiUserWallet extends MineModel

FILE: MineAdmin/php/app/Ai/Model/AiUserWalletLog.php
  class AiUserWalletLog (line 21) | class AiUserWalletLog extends MineModel

FILE: MineAdmin/php/app/Ai/Request/AiChatMessageRequest.php
  class AiChatMessageRequest (line 11) | class AiChatMessageRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 48) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiChatSessionRequest.php
  class AiChatSessionRequest (line 11) | class AiChatSessionRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 48) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiChatgptPromptsRequest.php
  class AiChatgptPromptsRequest (line 11) | class AiChatgptPromptsRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 42) | public function updateRules(): array
    method attributes (line 60) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiImageMaterialRequest.php
  class AiImageMaterialRequest (line 11) | class AiImageMaterialRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 50) | public function updateRules(): array
    method attributes (line 76) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiMineMenuGroupRequest.php
  class AiMineMenuGroupRequest (line 11) | class AiMineMenuGroupRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 48) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiMineMenuRequest.php
  class AiMineMenuRequest (line 11) | class AiMineMenuRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 48) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiOpenaiKeyRequest.php
  class AiOpenaiKeyRequest (line 11) | class AiOpenaiKeyRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 48) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiOrderRequest.php
  class AiOrderRequest (line 11) | class AiOrderRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 48) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiPayKamiRequest.php
  class AiPayKamiRequest (line 11) | class AiPayKamiRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 48) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiQuickIssueRequest.php
  class AiQuickIssueRequest (line 12) | class AiQuickIssueRequest extends MineFormRequest
    method commonRules (line 17) | public function commonRules(): array
    method saveRules (line 27) | public function saveRules(): array
    method updateRules (line 43) | public function updateRules(): array
    method attributes (line 61) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Request/AiUserRequest.php
  class AiUserRequest (line 11) | class AiUserRequest extends MineFormRequest
    method commonRules (line 16) | public function commonRules(): array
    method saveRules (line 26) | public function saveRules(): array
    method updateRules (line 36) | public function updateRules(): array
    method attributes (line 56) | public function attributes(): array

FILE: MineAdmin/php/app/Ai/Service/AiChatMessageService.php
  class AiChatMessageService (line 13) | class AiChatMessageService extends AbstractService
    method __construct (line 20) | public function __construct(AiChatMessageMapper $mapper)
    method messages (line 25) | public function messages(array $param): array
    method shareMessageList (line 44) | public function shareMessageList(array $param): array

FILE: MineAdmin/php/app/Ai/Service/AiChatSessionService.php
  class AiChatSessionService (line 16) | class AiChatSessionService extends AbstractService
    method __construct (line 25) | public function __construct(AiChatSessionMapper $mapper, AiLoginServic...
    method session (line 36) | public function session(array $param): array
    method sessionClose (line 68) | public function sessionClose(array $param): int
    method sessionHistory (line 84) | public function sessionHistory(array $param): array
    method sessionShareList (line 96) | public function sessionShareList(array $param): array

FILE: MineAdmin/php/app/Ai/Service/AiChatgptPromptsService.php
  class AiChatgptPromptsService (line 12) | class AiChatgptPromptsService extends AbstractService
    method __construct (line 49) | public function __construct(AiChatgptPromptsMapper $mapper)

FILE: MineAdmin/php/app/Ai/Service/AiImageMaterialService.php
  class AiImageMaterialService (line 13) | class AiImageMaterialService extends AbstractService
    method __construct (line 20) | public function __construct(AiImageMaterialMapper $mapper)
    method mine (line 25) | public function mine(int $scene): array

FILE: MineAdmin/php/app/Ai/Service/AiLoginService.php
  class AiLoginService (line 10) | class AiLoginService
    method __construct (line 21) | public function __construct()
    method getToken (line 33) | public function getToken(array $claims): string
    method check (line 44) | public function check(?string $token = null, string $scene = 'default'...
    method getJwt (line 65) | public function getJwt(): Jwt
    method getInfo (line 75) | public function getInfo(?string $token = null): array
    method getId (line 90) | public function getId(): int
    method refresh (line 99) | public function refresh(): string

FILE: MineAdmin/php/app/Ai/Service/AiMineMenuGroupService.php
  class AiMineMenuGroupService (line 14) | class AiMineMenuGroupService extends AbstractService
    method __construct (line 21) | public function __construct(AiMineMenuGroupMapper $mapper)
    method mineMenus (line 26) | public function mineMenus(): array

FILE: MineAdmin/php/app/Ai/Service/AiMineMenuService.php
  class AiMineMenuService (line 13) | class AiMineMenuService extends AbstractService
    method __construct (line 20) | public function __construct(AiMineMenuMapper $mapper)

FILE: MineAdmin/php/app/Ai/Service/AiOpenaiKeyService.php
  class AiOpenaiKeyService (line 15) | class AiOpenaiKeyService extends AbstractService
    method __construct (line 24) | public function __construct(AiOpenaiKeyMapper $mapper, AiRedisFactory ...
    method batchAdd (line 30) | public function batchAdd(array $data): bool
    method cacheAll (line 49) | public function cacheAll(): bool
    method openAiKey (line 62) | public function openAiKey()

FILE: MineAdmin/php/app/Ai/Service/AiOrderService.php
  class AiOrderService (line 26) | class AiOrderService extends AbstractService
    method __construct (line 37) | public function __construct(AiOrderMapper $mapper, AiVipService $vipSe...
    method orderList (line 44) | public function orderList(array $param): array
    method kamiOpenVip (line 87) | public function kamiOpenVip(array $param)
    method adminOpenVip (line 192) | public function adminOpenVip(array $data)

FILE: MineAdmin/php/app/Ai/Service/AiPayKamiService.php
  class AiPayKamiService (line 16) | class AiPayKamiService extends AbstractService
    method __construct (line 23) | public function __construct(AiPayKamiMapper $mapper)
    method add (line 28) | public function add(array $data){

FILE: MineAdmin/php/app/Ai/Service/AiQuickIssueService.php
  class AiQuickIssueService (line 14) | class AiQuickIssueService extends AbstractService
    method __construct (line 21) | public function __construct(AiQuickIssueMapper $mapper)

FILE: MineAdmin/php/app/Ai/Service/AiSettingService.php
  class AiSettingService (line 8) | class AiSettingService
    method __construct (line 12) | public function __construct(AiRedisFactory $redis){
    method customer (line 27) | public function customer(): array
    method setCustomer (line 37) | public function setCustomer($data): array
    method appClose (line 43) | public function appClose()
    method setAppClose (line 48) | public function setAppClose(string $v)
    method agreementUser (line 54) | public function agreementUser()
    method setAgreementUser (line 59) | public function setAgreementUser($v)
    method openaiProxy (line 64) | public function openaiProxy()
    method setOpenaiProxy (line 69) | public function setOpenaiProxy($v)

FILE: MineAdmin/php/app/Ai/Service/AiUserService.php
  class AiUserService (line 21) | class AiUserService extends AbstractService
    method __construct (line 34) | public function __construct(AiUserMapper $mapper, AiRedisFactory $redi...
    method userList (line 42) | public function userList(array $params): array
    method update (line 123) | public function update(mixed $id, array $data): bool
    method delete (line 140) | public function delete(array $ids): bool
    method isJustDelete (line 152) | public function isJustDelete(int $id): bool
    method lock (line 157) | public function lock(int $id)
    method isJustLock (line 172) | public function isJustLock(int $id): bool
    method friendNum (line 177) | public function friendNum(int $uid): int
    method friendList (line 182) | public function friendList(array $param){

FILE: MineAdmin/php/app/Ai/Service/AiVipService.php
  class AiVipService (line 11) | class AiVipService
    method config (line 13) | public function config(int $uid): array

FILE: MineAdmin/php/app/Ai/Service/AiWalletService.php
  class AiWalletService (line 16) | class AiWalletService
    method __construct (line 20) | public function __construct(AiLoginService $loginService)
    method info (line 25) | public function info(): array
    method withdrawal (line 34) | public function withdrawal(array $param): void
    method changeLogList (line 78) | public function changeLogList(array $param): array

FILE: MineAdmin/php/app/Ai/Service/HelperService.php
  class HelperService (line 9) | class HelperService
    method buildSavePath (line 11) | public static function buildSavePath(string $url, $needle = 'upload'):...
    method makeFileName (line 27) | public static function makeFileName(string $scene, string $suffix, int...
    method buildSourceUrl (line 39) | public static function buildSourceUrl(?string $filename): string
    method isMini (line 65) | public static function isMini(): bool
    method decode100 (line 70) | public static function decode100(string|int $price, string $percent = ...
    method encode100 (line 75) | public static function encode100(string|int|float $price, string $hund...
    method createOrderCode (line 80) | public static function createOrderCode(string|int $uid=0) : string
    method randStrArr (line 86) | public static function randStrArr(int $len = 6, int $number = 1): array

FILE: MineAdmin/php/app/Ai/Service/QiniuService.php
  class QiniuService (line 14) | class QiniuService
    method __construct (line 16) | public function __construct(){
    method token (line 21) | public function token(string $scenes): array

FILE: MineAdmin/vue/src/api/ai/aiChatMessage.js
  method getList (line 13) | getList (params = {}) {
  method read (line 25) | read (data = {}) {
  method deletes (line 37) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiChatSession.js
  method getList (line 13) | getList (params = {}) {
  method read (line 25) | read (data = {}) {
  method deletes (line 37) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiChatgptPrompts.js
  method getList (line 13) | getList (params = {}) {
  method update (line 25) | update (id, data = {}) {
  method save (line 37) | save (data = {}) {
  method read (line 49) | read (data = {}) {
  method deletes (line 61) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiImageMaterial.js
  method getList (line 13) | getList (params = {}) {
  method save (line 25) | save (data = {}) {
  method update (line 37) | update (id, data = {}) {
  method read (line 49) | read (data = {}) {
  method deletes (line 61) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiMineMenu.js
  method getList (line 13) | getList (params = {}) {
  method save (line 25) | save (data = {}) {
  method update (line 37) | update (id, data = {}) {
  method read (line 49) | read (data = {}) {
  method deletes (line 61) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiMineMenuGroup.js
  method getList (line 13) | getList (params = {}) {
  method save (line 25) | save (data = {}) {
  method update (line 37) | update (id, data = {}) {
  method read (line 49) | read (data = {}) {
  method deletes (line 61) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiOpenaiKey.js
  method getList (line 13) | getList (params = {}) {
  method save (line 25) | save (data = {}) {
  method update (line 37) | update (id, data = {}) {
  method read (line 49) | read (data = {}) {
  method deletes (line 61) | deletes (data) {
  method batchAdd (line 69) | batchAdd (data) {
  method refreshCache (line 77) | refreshCache () {

FILE: MineAdmin/vue/src/api/ai/aiOrder.js
  method getList (line 13) | getList (params = {}) {
  method read (line 25) | read (data = {}) {
  method deletes (line 37) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiPayKami.js
  method getList (line 13) | getList (params = {}) {
  method read (line 25) | read (data = {}) {
  method update (line 37) | update (id, data = {}) {
  method deletes (line 49) | deletes (data) {
  method add (line 61) | add (data) {

FILE: MineAdmin/vue/src/api/ai/aiQuickIssue.js
  method getList (line 15) | getList (params = {}) {
  method update (line 28) | update (id, data = {}) {
  method save (line 41) | save (data = {}) {
  method read (line 54) | read (data = {}) {
  method deletes (line 67) | deletes (data) {

FILE: MineAdmin/vue/src/api/ai/aiSetting.js
  method getList (line 13) | getList (params = {}) {
  method save (line 25) | save (data = {}) {
  method getQiniuToken (line 33) | getQiniuToken(scenes= "") {

FILE: MineAdmin/vue/src/api/ai/aiUser.js
  method getList (line 13) | getList (params = {}) {
  method update (line 25) | update (id, data = {}) {
  method read (line 37) | read (data = {}) {
  method deletes (line 49) | deletes (data) {
  method openVip (line 62) | openVip(id, data) {
  method lock (line 74) | lock(id) {

FILE: MineAdmin/vue/src/utils/pt-upload.js
  method next (line 9) | next (res) {
  method error (line 11) | error (err) {
  method complete (line 14) | complete (data) {

FILE: UniApp/common/api.ts
  function getLogin (line 3) | function getLogin(data: ptAny) {
  function getInit (line 7) | function getInit() {
  function getMine (line 11) | function getMine() {
  function getFriends (line 15) | function getFriends(data: ptAny) {
  function postUserDataInfo (line 19) | function postUserDataInfo(data: ptAny) {
  function getQiniuToken (line 23) | function getQiniuToken(scenes: string) {
  function getAiRoles (line 27) | function getAiRoles() {
  function getAiModelList (line 31) | function getAiModelList() {
  function getAiSession (line 35) | function getAiSession(data: ptAny) {
  function getAiSessionHistory (line 39) | function getAiSessionHistory(data: ptAny) {
  function postAiSessionClose (line 43) | function postAiSessionClose(data: ptAny) {
  function postAiSessionShare (line 47) | function postAiSessionShare(data: ptAny) {
  function postAiSessionDelete (line 51) | function postAiSessionDelete(data: ptAny) {
  function getAiSessionShareList (line 55) | function getAiSessionShareList(data: ptAny) {
  function getAiSessionShareMessageList (line 59) | function getAiSessionShareMessageList(data: ptAny) {
  function getAiMessages (line 63) | function getAiMessages(data: ptAny) {
  function getAiQuickIssue (line 67) | function getAiQuickIssue() {
  function getVipConfig (line 71) | function getVipConfig() {
  function getOrderList (line 75) | function getOrderList(data: ptAny) {
  function postKamiOpenVip (line 79) | function postKamiOpenVip(data: ptAny) {
  function getWalletInfo (line 83) | function getWalletInfo() {
  function getChangeLogList (line 87) | function getChangeLogList(data: ptAny) {
  function getWithdrawalList (line 91) | function getWithdrawalList(data: ptAny) {
  function postWithdrawal (line 95) | function postWithdrawal(data: ptAny) {

FILE: UniApp/common/func.ts
  function uploadQiniu (line 8) | function uploadQiniu(qiniuInfo: utilsType.qiniuInfo, filePath: string) {

FILE: UniApp/common/utils/request.ts
  class RequestService (line 1) | class RequestService {
    method constructor (line 5) | constructor() {
    method handleIntercept (line 11) | static handleIntercept(handles: ptAny, data: utilsType.requestConfig |...
    method use (line 17) | use(before: ptAny, after: ptAny) {
    method get (line 22) | get(url: ptAny, data?: ptAny) {
    method post (line 30) | post(url: ptAny, data?: ptAny) {
    method request (line 38) | request(config: utilsType.requestConfig) {

FILE: UniApp/logic/user.ts
  function userService (line 4) | function userService() {

FILE: UniApp/main.js
  function createApp (line 17) | function createApp() {

FILE: UniApp/types/global.d.ts
  type ptAny (line 1) | type ptAny = any
  type result (line 4) | interface result{
  type requestConfig (line 10) | interface requestConfig {
  type qiniuInfo (line 17) | interface qiniuInfo {

FILE: UniApp/uni.promisify.adaptor.js
  method returnValue (line 2) | returnValue (res) {

FILE: UniApp/uni_modules/bt-cropper_3.0.1/components/bt-cropper/js/touchs.js
  method imageStyle (line 17) | imageStyle() {
  method cropperStyle (line 30) | cropperStyle() {
  method touchStart (line 45) | touchStart() {
  method touchMove (line 81) | touchMove(ev) {
  method touchEnd (line 170) | touchEnd(ev) {
  method imageScale (line 214) | imageScale(scaleRate) {

FILE: UniApp/uni_modules/bt-cropper_3.0.1/components/bt-cropper/utils/tools.js
  function getTouchPoints (line 1) | function getTouchPoints(touchs) {
  function debounce (line 7) | function debounce(fn, wait = 200) {
  function sleep (line 21) | function sleep(time = 200) {
  function parseUnit (line 28) | function parseUnit(size){

FILE: UniApp/uni_modules/mp-html/components/mp-html/emoji/index.js
  function Emoji (line 185) | function Emoji () {

FILE: UniApp/uni_modules/mp-html/components/mp-html/highlight/index.js
  function Highlight (line 9) | function Highlight (vm) {

FILE: UniApp/uni_modules/mp-html/components/mp-html/markdown/index.js
  function Markdown (line 9) | function Markdown (vm) {

FILE: UniApp/uni_modules/mp-html/components/mp-html/parser.js
  function makeMap (line 102) | function makeMap (str) {
  function decodeEntity (line 117) | function decodeEntity (str, amp) {
  function mergeNodes (line 145) | function mergeNodes (nodes) {
  function Parser (line 165) | function Parser (vm) {
  function Lexer (line 1137) | function Lexer (handler) {

FILE: UniApp/uni_modules/mp-html/static/app-plus/mp-html/js/handler.js
  function t (line 1) | function t(t){for(var e=Object.create(null),n=t.attributes.length;n--;)e...
  function e (line 1) | function e(){a[1]&&(this.src=a[1],this.onerror=null),this.onclick=null,t...
  function n (line 1) | function n(){window.unloadimgs-=1,0===window.unloadimgs&&uni.postMessage...
  function o (line 1) | function o(r,s,c){for(var d=0;d<r.length;d++)!function(d){var u=r[d],l=v...
Condensed preview — 210 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (647K chars).
[
  {
    "path": ".gitignore",
    "chars": 36,
    "preview": "/.idea/\n/.vscode/\n/.hbuilderx/\n/test"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/BaseApi.php",
    "chars": 1410,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse Hyperf\\DbConnection\\Db;\nuse Mine\\MineController;\nuse Psr\\Cont"
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/Chat.php",
    "chars": 7902,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse App\\Ai\\Middleware\\AuthMiddleware;\nuse App\\Ai\\Service\\AiChatgp"
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/Common.php",
    "chars": 6633,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse App\\Ai\\Constants\\VipConst;\nuse App\\Ai\\Service\\AiLoginService;"
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/Login.php",
    "chars": 3140,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse App\\Ai\\Model\\AiUser;\nuse App\\Ai\\Model\\AiUserRelation;\nuse App"
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/Order.php",
    "chars": 1084,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse App\\Ai\\Constants\\OrderConst;\nuse App\\Ai\\Middleware\\AuthMiddle"
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/User.php",
    "chars": 3094,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse App\\Ai\\Constants\\ResponseCodeConst;\nuse App\\Ai\\Constants\\VipC"
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/Wallet.php",
    "chars": 1531,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse App\\Ai\\Constants\\OrderConst;\nuse App\\Ai\\Middleware\\AuthMiddle"
  },
  {
    "path": "MineAdmin/php/app/Ai/Api/Websocket.php",
    "chars": 9465,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Api;\n\nuse App\\Ai\\Constants\\RedisConst;\nuse App\\Ai\\Constants\\VipConst;\nu"
  },
  {
    "path": "MineAdmin/php/app/Ai/Command/InitMenuCommand.php",
    "chars": 25497,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Command;\n\nuse App\\System\\Model\\SystemMenu;\nuse Hyperf\\Command\\Command a"
  },
  {
    "path": "MineAdmin/php/app/Ai/Constants/OrderConst.php",
    "chars": 1081,
    "preview": "<?php\n\nnamespace App\\Ai\\Constants;\n\nuse Pt\\Constants\\DescConst;\n\nclass OrderConst extends DescConst\n{\n    /**\n     * @De"
  },
  {
    "path": "MineAdmin/php/app/Ai/Constants/RedisConst.php",
    "chars": 311,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Constants;\n\nclass RedisConst\n{\n    /**\n     * 用户uid绑定fd\n     */\n    con"
  },
  {
    "path": "MineAdmin/php/app/Ai/Constants/ResponseCodeConst.php",
    "chars": 356,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Constants;\n\nclass ResponseCodeConst\n{\n    const INVALID_TOKEN   = 10001"
  },
  {
    "path": "MineAdmin/php/app/Ai/Constants/UploadSceneConst.php",
    "chars": 805,
    "preview": "<?php\nnamespace App\\Ai\\Constants;\n\nclass UploadSceneConst\n{\n    // 1开头,例如 1001 1002\n    const ImageScene = [\n        'ai"
  },
  {
    "path": "MineAdmin/php/app/Ai/Constants/VipConst.php",
    "chars": 1747,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Constants;\n\nuse Pt\\Constants\\DescConst;\n\nclass VipConst extends DescCon"
  },
  {
    "path": "MineAdmin/php/app/Ai/Constants/WalletConst.php",
    "chars": 462,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Constants;\n\nuse Pt\\Constants\\DescConst;\n\nclass WalletConst extends Desc"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiChatMessageController.php",
    "chars": 2071,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiChatMessageService;\nuse App\\Ai\\Reque"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiChatSessionController.php",
    "chars": 2071,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiChatSessionService;\nuse App\\Ai\\Reque"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiChatgptPromptsController.php",
    "chars": 3243,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiChatgptPromptsService;\nuse App\\Ai\\Re"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiImageMaterialController.php",
    "chars": 3087,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiImageMaterialService;\nuse App\\Ai\\Req"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiMineMenuController.php",
    "chars": 3004,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiMineMenuService;\nuse App\\Ai\\Request\\"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiMineMenuGroupController.php",
    "chars": 3091,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiMineMenuGroupService;\nuse App\\Ai\\Req"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiOpenaiKeyController.php",
    "chars": 3853,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiOpenaiKeyService;\nuse App\\Ai\\Request"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiOrderController.php",
    "chars": 2004,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiOrderService;\nuse App\\Ai\\Request\\AiO"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiPayKamiController.php",
    "chars": 2930,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiPayKamiService;\nuse App\\Ai\\Request\\A"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiQuickIssueController.php",
    "chars": 3037,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiQuickIssueService;\nuse App\\Ai\\Reques"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiSettingController.php",
    "chars": 2068,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiSettingService;\nuse App\\Ai\\Service\\Qi"
  },
  {
    "path": "MineAdmin/php/app/Ai/Controller/AiUserController.php",
    "chars": 3261,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Controller;\n\nuse App\\Ai\\Service\\AiOrderService;\nuse App\\Ai\\Service\\AiU"
  },
  {
    "path": "MineAdmin/php/app/Ai/Crontab/CheckVipOver.php",
    "chars": 1092,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Crontab;\n\nuse App\\Ai\\Model\\AiUser;\nuse Mine\\Annotation\\Transaction;\n\ncl"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_04_145048_create_ai_user_table.php",
    "chars": 1887,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095456_create_ai_user_wallet_table.php",
    "chars": 865,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095504_create_ai_user_wallet_log_table.php",
    "chars": 1524,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095525_create_ai_user_relation_table.php",
    "chars": 1099,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095540_create_ai_order_table.php",
    "chars": 2622,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_095543_create_ai_order_vip_table.php",
    "chars": 746,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_102806_create_ai_mine_menu_group_table.php",
    "chars": 1205,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_102817_create_ai_mine_menu_table.php",
    "chars": 2569,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_09_154733_create_ai_chatgpt_prompts_table.php",
    "chars": 1603,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_10_165842_create_ai_chat_message_table.php",
    "chars": 1246,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_10_171603_create_ai_chat_session_table.php",
    "chars": 1216,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_12_152504_create_ai_quick_issue_table.php",
    "chars": 1291,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_19_164456_create_ai_pay_kami_table.php",
    "chars": 1844,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_25_152855_create_ai_openai_key_table.php",
    "chars": 1351,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_05_26_111034_create_ai_order_kami_table.php",
    "chars": 678,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Migrations/2023_06_14_141605_create_ai_image_material_table.php",
    "chars": 1972,
    "preview": "<?php\n\n\nuse Hyperf\\Database\\Schema\\Schema;\nuse Hyperf\\Database\\Schema\\Blueprint;\nuse Hyperf\\Database\\Migrations\\Migratio"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Seeders/ai_chatgpt_prompts.php",
    "chars": 894,
    "preview": "<?php\ndeclare(strict_types=1);\n\nuse Hyperf\\Database\\Seeders\\Seeder;\nuse Hyperf\\DbConnection\\Db;\n\nclass AiChatgptPrompts "
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Seeders/ai_mine_menu.php",
    "chars": 1980,
    "preview": "<?php\ndeclare(strict_types=1);\n\nuse Hyperf\\Database\\Seeders\\Seeder;\nuse Hyperf\\DbConnection\\Db;\n\nclass AiMineMenu extend"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Seeders/ai_mine_menu_group.php",
    "chars": 576,
    "preview": "<?php\ndeclare(strict_types=1);\n\nuse Hyperf\\Database\\Seeders\\Seeder;\nuse Hyperf\\DbConnection\\Db;\n\nclass AiMineMenuGroup e"
  },
  {
    "path": "MineAdmin/php/app/Ai/Database/Seeders/ai_user.php",
    "chars": 1383,
    "preview": "<?php\n/**\n * MineAdmin is committed to providing solutions for quickly building web applications\n * Please view the LICE"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiChatMessageDto.php",
    "chars": 749,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiChatSessionDto.php",
    "chars": 681,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiChatgptPromptsDto.php",
    "chars": 975,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiImageMaterialDto.php",
    "chars": 1200,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiMineMenuDto.php",
    "chars": 1564,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiMineMenuGroupDto.php",
    "chars": 678,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiOpenaiKeyDto.php",
    "chars": 840,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiOrderDto.php",
    "chars": 1644,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiPayKamiDto.php",
    "chars": 1117,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiQuickIssueDto.php",
    "chars": 746,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Dto/AiUserDto.php",
    "chars": 1136,
    "preview": "<?php\nnamespace App\\Ai\\Dto;\n\nuse Mine\\Interfaces\\MineModelExcel;\nuse Mine\\Annotation\\ExcelData;\nuse Mine\\Annotation\\Exce"
  },
  {
    "path": "MineAdmin/php/app/Ai/Factory/AiRedisFactory.php",
    "chars": 166,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Factory;\n\nuse Hyperf\\Redis\\Redis;\n\nclass AiRedisFactory extends Redis\n{"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiChatMessageMapper.php",
    "chars": 1412,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiChatMessage;\nuse Hyperf\\Database\\Model\\Bui"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiChatSessionMapper.php",
    "chars": 1566,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiChatSession;\nuse Hyperf\\Database\\Model\\Bui"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiChatgptPromptsMapper.php",
    "chars": 956,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiChatgptPrompts;\nuse Hyperf\\Database\\Model\\"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiImageMaterialMapper.php",
    "chars": 1789,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiImageMaterial;\nuse Hyperf\\Database\\Model\\B"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiMineMenuGroupMapper.php",
    "chars": 1687,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiMineMenuGroup;\nuse Hyperf\\Database\\Model\\B"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiMineMenuMapper.php",
    "chars": 1520,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiMineMenu;\nuse Hyperf\\Database\\Model\\Builde"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiOpenaiKeyMapper.php",
    "chars": 1693,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiOpenaiKey;\nuse Hyperf\\Database\\Model\\Build"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiOrderMapper.php",
    "chars": 2298,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiOrder;\nuse Hyperf\\Database\\Model\\Builder;\n"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiPayKamiMapper.php",
    "chars": 2223,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiPayKami;\nuse Hyperf\\Database\\Model\\Builder"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiQuickIssueMapper.php",
    "chars": 1241,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiQuickIssue;\nuse Hyperf\\Database\\Model\\Buil"
  },
  {
    "path": "MineAdmin/php/app/Ai/Mapper/AiUserMapper.php",
    "chars": 2151,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Mapper;\n\nuse App\\Ai\\Model\\AiUser;\nuse App\\Ai\\Model\\AiUserRelation;\nuse"
  },
  {
    "path": "MineAdmin/php/app/Ai/Middleware/AuthMiddleware.php",
    "chars": 2871,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Middleware;\n\nuse App\\Ai\\Service\\AiLoginService;\nuse App\\Ai\\Api\\Login;\n"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiChatMessage.php",
    "chars": 892,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\SoftDeletes;\nuse Mine\\MineModel;\n\n/*"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiChatSession.php",
    "chars": 1362,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\Relations\\HasOne;\nuse Mine\\MineModel"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiChatgptPrompts.php",
    "chars": 1109,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\SoftDeletes;\nuse Mine\\MineModel;\n\n/*"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiImageMaterial.php",
    "chars": 1548,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse App\\Ai\\Service\\HelperService;\nuse Hyperf\\Database\\Model\\So"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiMineMenu.php",
    "chars": 1788,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse App\\Ai\\Service\\HelperService;\nuse Hyperf\\Database\\Model\\So"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiMineMenuGroup.php",
    "chars": 1102,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse \\App\\Ai\\Model\\AiMineMenu;\nuse Hyperf\\Database\\Model\\Relati"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiOpenaiKey.php",
    "chars": 1021,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\SoftDeletes;\nuse Mine\\MineModel;\n\n/*"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiOrder.php",
    "chars": 1702,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\SoftDeletes;\nuse Mine\\MineModel;\n\n/*"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiOrderKami.php",
    "chars": 667,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Mine\\MineModel;\n\n/**\n * @property int $oid 订单ID\n * @proper"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiOrderVip.php",
    "chars": 856,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Mine\\MineModel;\n\n/**\n * @property int $oid 订单ID\n * @proper"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiPayKami.php",
    "chars": 1224,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\SoftDeletes;\nuse Mine\\MineModel;\n\n/*"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiQuickIssue.php",
    "chars": 916,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\SoftDeletes;\nuse Mine\\MineModel;\n\n/*"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiUser.php",
    "chars": 1857,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse App\\Ai\\Service\\HelperService;\nuse Hyperf\\Database\\Model\\Re"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiUserRelation.php",
    "chars": 902,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Mine\\MineModel;\n\n/**\n * @property int $uid 用户UID\n * @prope"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiUserWallet.php",
    "chars": 709,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Mine\\MineModel;\n\n/**\n * @property int $uid 用户UID\n * @prope"
  },
  {
    "path": "MineAdmin/php/app/Ai/Model/AiUserWalletLog.php",
    "chars": 1093,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Model;\n\nuse Hyperf\\Database\\Model\\SoftDeletes;\nuse Mine\\MineModel;\n\n/*"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiChatMessageRequest.php",
    "chars": 725,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 聊天数据验证数据类\n */\nclass AiChatM"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiChatSessionRequest.php",
    "chars": 671,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 问答会话验证数据类\n */\nclass AiChatS"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiChatgptPromptsRequest.php",
    "chars": 1128,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * chatgpt角色验证数据类\n */\nclass Ai"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiImageMaterialRequest.php",
    "chars": 1796,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 图片素材验证数据类\n */\nclass AiImage"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiMineMenuGroupRequest.php",
    "chars": 703,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 个人中心菜单分组验证数据类\n */\nclass AiM"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiMineMenuRequest.php",
    "chars": 696,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 个人中心菜单验证数据类\n */\nclass AiMin"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiOpenaiKeyRequest.php",
    "chars": 701,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * openai_key验证数据类\n */\nclass A"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiOrderRequest.php",
    "chars": 690,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 订单表验证数据类\n */\nclass AiOrderR"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiPayKamiRequest.php",
    "chars": 691,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 卡密验证数据类\n */\nclass AiPayKami"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiQuickIssueRequest.php",
    "chars": 1123,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 快捷问题\n验证数据类\n */\nclass AiQuic"
  },
  {
    "path": "MineAdmin/php/app/Ai/Request/AiUserRequest.php",
    "chars": 1044,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Request;\n\nuse Mine\\MineFormRequest;\n\n/**\n * 用户主表验证数据类\n */\nclass AiUserR"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiChatMessageService.php",
    "chars": 1451,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Mapper\\AiChatMessageMapper;\nuse App\\Ai\\Model\\AiCha"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiChatSessionService.php",
    "chars": 3279,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Constants\\ResponseCodeConst;\nuse App\\Ai\\Mapper\\Ai"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiChatgptPromptsService.php",
    "chars": 1418,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Mapper\\AiChatgptPromptsMapper;\nuse Mine\\Abstracts\\"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiImageMaterialService.php",
    "chars": 902,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Mapper\\AiImageMaterialMapper;\nuse Mine\\Abstracts\\"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiLoginService.php",
    "chars": 2105,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse Hyperf\\Context\\Context;\nuse Psr\\SimpleCache\\InvalidArgume"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiMineMenuGroupService.php",
    "chars": 770,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Mapper\\AiMineMenuGroupMapper;\nuse App\\Ai\\Model\\Ai"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiMineMenuService.php",
    "chars": 374,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Mapper\\AiMineMenuMapper;\nuse Mine\\Abstracts\\Abstr"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiOpenaiKeyService.php",
    "chars": 1685,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Factory\\AiRedisFactory;\nuse App\\Ai\\Mapper\\AiOpena"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiOrderService.php",
    "chars": 11268,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Constants\\OrderConst;\nuse App\\Ai\\Constants\\Respon"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiPayKamiService.php",
    "chars": 1529,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Constants\\ResponseCodeConst;\nuse App\\Ai\\Mapper\\Ai"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiQuickIssueService.php",
    "chars": 381,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Mapper\\AiQuickIssueMapper;\nuse Mine\\Abstracts\\Abs"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiSettingService.php",
    "chars": 1754,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Factory\\AiRedisFactory;\n\nclass AiSettingService\n{\n"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiUserService.php",
    "chars": 7725,
    "preview": "<?php\ndeclare(strict_types=1);\n\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Constants\\ResponseCodeConst;\nuse App\\Ai\\Constants"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiVipService.php",
    "chars": 2009,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Constants\\OrderConst;\nuse App\\Ai\\Model\\AiUser;\nuse"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/AiWalletService.php",
    "chars": 4215,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Constants\\OrderConst;\nuse App\\Ai\\Constants\\Respons"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/HelperService.php",
    "chars": 3246,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Middleware\\AuthMiddleware;\nuse Hyperf\\Context\\Cont"
  },
  {
    "path": "MineAdmin/php/app/Ai/Service/QiniuService.php",
    "chars": 2488,
    "preview": "<?php\ndeclare(strict_types=1);\n\nnamespace App\\Ai\\Service;\n\nuse App\\Ai\\Constants\\ResponseCodeConst;\nuse App\\Ai\\Middleware"
  },
  {
    "path": "MineAdmin/php/app/Ai/config.json",
    "chars": 148,
    "preview": "{\n    \"name\": \"Ai\",\n    \"label\": \"ai\",\n    \"description\": \"ai\",\n    \"installed\": true,\n    \"enabled\": true,\n    \"version"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiChatMessage.js",
    "chars": 595,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 聊天数据 API JS\n */\n\nexport default {\n\n  /**\n   * 获取聊天数据分页列表\n   * @retu"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiChatSession.js",
    "chars": 595,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 问答会话 API JS\n */\n\nexport default {\n\n  /**\n   * 获取问答会话分页列表\n   * @retu"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiChatgptPrompts.js",
    "chars": 975,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * chatgpt角色 API JS\n */\n\nexport default {\n\n  /**\n   * 获取chatgpt角色分页列表\n"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiImageMaterial.js",
    "chars": 940,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 图片素材 API JS\n */\n\nexport default {\n\n  /**\n   * 获取图片素材分页列表\n   * @retu"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiMineMenu.js",
    "chars": 927,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 个人中心菜单 API JS\n */\n\nexport default {\n\n  /**\n   * 获取个人中心菜单分页列表\n   * @"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiMineMenuGroup.js",
    "chars": 964,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 个人中心菜单分组 API JS\n */\n\nexport default {\n\n  /**\n   * 获取个人中心菜单分组分页列表\n  "
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiOpenaiKey.js",
    "chars": 1186,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * openai_key API JS\n */\n\nexport default {\n\n  /**\n   * 获取openai_key分页列"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiOrder.js",
    "chars": 573,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 订单表 API JS\n */\n\nexport default {\n\n  /**\n   * 获取订单表分页列表\n   * @return"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiPayKami.js",
    "chars": 1092,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 卡密 API JS\n */\n\nexport default {\n\n    /**\n     * 获取卡密分页列表\n     * @re"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiQuickIssue.js",
    "chars": 931,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 快捷问题\n API JS\n */\n\nexport default {\n\n  /**\n   * 获取快捷问题\n分页列表\n   * @re"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiSetting.js",
    "chars": 692,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 用户主表 API JS\n */\n\nexport default {\n\n    /**\n     * 获取用户主表分页列表\n     *"
  },
  {
    "path": "MineAdmin/vue/src/api/ai/aiUser.js",
    "chars": 1060,
    "preview": "import { request } from '@/utils/request.js'\n\n/**\n * 用户主表 API JS\n */\n\nexport default {\n\n  /**\n   * 获取用户主表分页列表\n   * @retu"
  },
  {
    "path": "MineAdmin/vue/src/components/putyy/pt-upload.vue",
    "chars": 2954,
    "preview": "<template>\n  <a-space direction=\"vertical\" :style=\"{ width: '100%' }\">\n    <a-upload v-if=\"uploadType === 'image'\" :cust"
  },
  {
    "path": "MineAdmin/vue/src/config/pt-const.js",
    "chars": 452,
    "preview": "export default {\n    is_lock: [\n        {\n            label: \"正常\",\n            value: 1\n        },\n        {\n           "
  },
  {
    "path": "MineAdmin/vue/src/config/pt-scene.js",
    "chars": 173,
    "preview": "export default {\n    ai_head_img: '1010',\n    ai_mine_menu_icon: '1011',\n    ai_customer_wx_img: '1012',\n    ai_customer"
  },
  {
    "path": "MineAdmin/vue/src/utils/pt-upload.js",
    "chars": 1240,
    "preview": "import ai from \"@/api/ai/aiSetting\";\nimport * as qiniu from \"qiniu-js\";\n\n\nlet uploadQiniu  = (blob,key,token)=>{\n    ret"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/chatMessage/index.vue",
    "chars": 2066,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/chatSession/index.vue",
    "chars": 2234,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/chatgptPrompts/index.vue",
    "chars": 2891,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/imageMaterial/index.vue",
    "chars": 4623,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/mineMenu/index.vue",
    "chars": 4705,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/mineMenuGroup/index.vue",
    "chars": 2054,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/openKey/components/add.vue",
    "chars": 1080,
    "preview": "<template>\n  <a-modal v-model:visible=\"visible\" :footer=\"false\" draggable width=\"600px\">\n    <template #title>批量添加openai"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/openKey/index.vue",
    "chars": 2871,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/order/index.vue",
    "chars": 4320,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/payKami/components/add.vue",
    "chars": 1247,
    "preview": "<template>\n  <a-modal v-model:visible=\"visible\" :footer=\"false\" draggable width=\"600px\">\n    <template #title>生成卡密</temp"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/payKami/index.vue",
    "chars": 3089,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/quickIssue/index.vue",
    "chars": 2223,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/setting/index.vue",
    "chars": 3018,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <ma-form v-model=\"form\" v-model:columns=\"col"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/user/components/openVip.vue",
    "chars": 1978,
    "preview": "<template>\n  <a-modal v-model:visible=\"visible\" :footer=\"false\" draggable width=\"600px\">\n    <template #title>开通VIP</tem"
  },
  {
    "path": "MineAdmin/vue/src/views/ai/user/index.vue",
    "chars": 5819,
    "preview": "<template>\n  <div class=\"ma-content-block lg:flex justify-between p-4\">\n    <!-- CRUD 组件 -->\n    <ma-crud :options=\"opti"
  },
  {
    "path": "README.md",
    "chars": 6593,
    "preview": "# uniapp、hyperf MineAdmin 实现的 chatgpt应用,支持小程序、H5、App!\n## 效果图\n#### App\n![](images/1.jpg)\n\n![](images/2.jpg)\n\n![](images/3"
  },
  {
    "path": "UniApp/.gitignore",
    "chars": 153,
    "preview": "/.idea/\n/.vscode/\n/.hbuilderx/\n/uni_modules/*\n!/uni_modules/bt-cropper_3.0.1/\n!/uni_modules/mp-html/\n/node_modules/\n/unp"
  },
  {
    "path": "UniApp/App.vue",
    "chars": 542,
    "preview": "<script>\r\n\timport {AppInitOptionCacheKey} from \"./common/const\"\r\n\timport {useIndexStore} from './store/index'\r\n\texport d"
  },
  {
    "path": "UniApp/README.md",
    "chars": 17,
    "preview": "# chatGPT UniApp\n"
  },
  {
    "path": "UniApp/androidPrivacy.json",
    "chars": 30,
    "preview": "{\n    \"prompt\" : \"template\"\n}\n"
  },
  {
    "path": "UniApp/common/api.ts",
    "chars": 2304,
    "preview": "import request from './utils/services'\n\nexport function getLogin(data: ptAny) {\n    return request.get('login/index', da"
  },
  {
    "path": "UniApp/common/const.ts",
    "chars": 682,
    "preview": "export const xTokenCacheKey = \"app-x-token\"; // 缓存登录token\nexport const AppNoticeCacheKey = \"app-notice\"; // 缓存提示信息\nexpor"
  },
  {
    "path": "UniApp/common/func.ts",
    "chars": 726,
    "preview": "/**\n * uploadCos.\n * 上传到七牛云\n * @param {any} qiniuInfo 七牛云预生成的信息\n * @param {String} filePath 文件的临时路径\n * @returns {Promise"
  },
  {
    "path": "UniApp/common/utils/jump.ts",
    "chars": 624,
    "preview": "export const byNavigateTo = (page: string, params?: ptAny) => {\n    // @ts-ignore\n    uni.navigateTo({\n        url: page"
  },
  {
    "path": "UniApp/common/utils/request.ts",
    "chars": 1791,
    "preview": "class RequestService {\n    private before: ptAny[];\n    private after: ptAny[];\n\n    constructor() {\n        // @ts-igno"
  },
  {
    "path": "UniApp/common/utils/services.ts",
    "chars": 1392,
    "preview": "import Request from './request'\nimport {AppNoticeCacheKey, xTokenCacheKey} from \"../const\";\nimport {useIndexStore} from "
  },
  {
    "path": "UniApp/components/AgreementPopup.vue",
    "chars": 1471,
    "preview": "<template lang=\"pug\">\nuni-popup(ref=\"popupObj\" type=\"bottom\")\n  scroll-view.agreement_container(scroll-y=\"true\")\n    vie"
  },
  {
    "path": "UniApp/components/FooterCommon.vue",
    "chars": 1496,
    "preview": "<template lang=\"pug\">\ndiv.footer\n  div.item(v-for=\"(item, key) in footer\"\n    :class=\"{active: footerIndex === key}\"\n   "
  },
  {
    "path": "UniApp/components/Nothing.vue",
    "chars": 929,
    "preview": "<template lang=\"pug\">\ndiv.nothing\n  div.tips {{config.tips}}\n  div.entry(v-if=\"config.entry\" @tap=\"emit('entry', config)"
  },
  {
    "path": "UniApp/components/OpenVipPopup.vue",
    "chars": 5976,
    "preview": "<template lang=\"pug\">\nuni-popup(ref=\"popupObj\" type=\"bottom\" @change=\"change\")\n  scroll-view.open_vip_popup(scroll-y=\"tr"
  },
  {
    "path": "UniApp/components/QrCodePopup.vue",
    "chars": 2324,
    "preview": "<template lang=\"pug\">\nuni-popup(ref=\"popupObj\" :mask-click=\"false\")\n  div.code\n    div.code_content\n      div.code_middl"
  },
  {
    "path": "UniApp/components/Search.vue",
    "chars": 5549,
    "preview": "<template lang=\"pug\">\ndiv.container\n  div.search_box\n    div.top(v-if=\"props.columns.length >= 0\")\n      template(v-for="
  },
  {
    "path": "UniApp/config.example.ts",
    "chars": 347,
    "preview": "let config = [\n    {\n        wsUrl: 'ws://开发环境的域名ws/ws-chat',\n        baseURL: 'https://开发环境的域名/api/ai/api/'\n    },\n    "
  },
  {
    "path": "UniApp/index.html",
    "chars": 672,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <script>\n      var coverSupport = 'CSS' in wi"
  },
  {
    "path": "UniApp/logic/user.ts",
    "chars": 994,
    "preview": "import {UserMineCacheKey} from \"../common/const\"\nimport {getMine} from \"../common/api\"\n\nexport function userService() {\n"
  },
  {
    "path": "UniApp/main.js",
    "chars": 424,
    "preview": "import App from './App'\n\n// #ifndef VUE3\nimport Vue from 'vue'\nimport './uni.promisify.adaptor'\nVue.config.productionTip"
  },
  {
    "path": "UniApp/manifest.json",
    "chars": 4929,
    "preview": "{\n    \"name\" : \"ChatGPT\",\n    \"appid\" : \"\",\n    \"description\" : \"ChatGPT AI问答\",\n    \"versionName\" : \"1.0.3\",\n    \"versio"
  },
  {
    "path": "UniApp/pages/chatgpt/channel.vue",
    "chars": 4935,
    "preview": "<template lang=\"pug\">\ndiv.sessions\n  div.item(v-for=\"item in sessions\")\n    div.user\n      image.head(:src=\"item.user?.h"
  },
  {
    "path": "UniApp/pages/chatgpt/room.vue",
    "chars": 29343,
    "preview": "<template lang=\"pug\">\ndiv.room\n  div.message_list\n    template(v-for=\"item in messageList\" )\n      div.content_box.user\n"
  },
  {
    "path": "UniApp/pages/login.vue",
    "chars": 4429,
    "preview": "<template lang=\"pug\">\r\ndiv.login\r\n  div.header\r\n    div.hello\r\n      text {{type === \"login\" ? \"Hi,欢迎使用\" : \"Hi,欢迎注册\"}}\r\n"
  },
  {
    "path": "UniApp/pages/notice.vue",
    "chars": 491,
    "preview": "<template lang=\"pug\">\nview {{content}}\n</template>\n\n<script setup lang=\"ts\">\n// @ts-ignore\nimport {ref, onMounted} from "
  },
  {
    "path": "UniApp/pages/user/friend.vue",
    "chars": 3064,
    "preview": "<template lang=\"pug\">\nSearch(ref=\"searchCps\" :columns=\"columns\" :options=\"options\")\n  template(v-slot=\"{result}\")\n    di"
  },
  {
    "path": "UniApp/pages/user/mine.vue",
    "chars": 7012,
    "preview": "<template lang=\"pug\">\ndiv.mine(v-show=\"personal.userUid > 0\")\n  div.mine_personal\n    image.head(:src=\"personal.head ? p"
  },
  {
    "path": "UniApp/pages/user/order.vue",
    "chars": 2103,
    "preview": "<template lang=\"pug\">\nSearch(ref=\"searchCps\" :columns=\"columns\" :options=\"options\")\n  template(v-slot=\"{result}\")\n    di"
  },
  {
    "path": "UniApp/pages/user/perfect.vue",
    "chars": 6609,
    "preview": "<template lang=\"pug\">\ndiv.edit(v-show=\"!showCrop\" )\n  div.edit_top\n    div.head_box(@click=\"chooseImage(0)\")\n      image"
  },
  {
    "path": "UniApp/pages/user/wallet.vue",
    "chars": 3806,
    "preview": "<template lang=\"pug\">\ndiv.wallet\n  div.back_box\n    div.top\n    div.bottom\n  div.info_box\n    div.prices\n      div.can\n "
  },
  {
    "path": "UniApp/pages/user/walletList.vue",
    "chars": 1739,
    "preview": "<template lang=\"pug\">\nSearch(ref=\"searchCps\" :columns=\"columns\" :options=\"options\")\n  template(v-slot=\"{result}\")\n    di"
  },
  {
    "path": "UniApp/pages/user/withdrawalList.vue",
    "chars": 2273,
    "preview": "<template lang=\"pug\">\nSearch(ref=\"searchCps\" :columns=\"columns\" :options=\"options\")\n  template(v-slot=\"{result}\")\n    di"
  },
  {
    "path": "UniApp/pages.json",
    "chars": 1500,
    "preview": "{\n\t\"pages\": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages\n\t\t{\n\t\t\t\"path\": \"pages/user/mine\",\n\t\t\t\"s"
  },
  {
    "path": "UniApp/store/index.ts",
    "chars": 2424,
    "preview": "// @ts-ignore\nimport {defineStore} from 'pinia'\n// @ts-ignore\nimport {ref} from \"vue\"\nimport {\n    getInit\n} from \"../co"
  },
  {
    "path": "UniApp/store/websocket.ts",
    "chars": 2690,
    "preview": "// @ts-ignore\nimport {defineStore} from 'pinia'\n// @ts-ignore\nimport {ref} from \"vue\"\nimport {getConfig} from '../common"
  },
  {
    "path": "UniApp/tsconfig.json",
    "chars": 572,
    "preview": "// tsconfig.json\n{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"module\": \"esnext\",\n    \"strict\": true,\n    \"jsx\":"
  },
  {
    "path": "UniApp/types/global.d.ts",
    "chars": 467,
    "preview": "type ptAny = any\n\ndeclare namespace utilsType {\n    interface result{\n        code: number;\n        data: any;\n        m"
  },
  {
    "path": "UniApp/uni.promisify.adaptor.js",
    "chars": 309,
    "preview": "uni.addInterceptor({\n  returnValue (res) {\n    if (!(!!res && (typeof res === \"object\" || typeof res === \"function\") && "
  },
  {
    "path": "UniApp/uni.scss",
    "chars": 1715,
    "preview": "/**\r\n * 这里是uni-app内置的常用样式变量\r\n *\r\n * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量\r\n * 如果你是插件开发者,建议你使用s"
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/changelog.md",
    "chars": 700,
    "preview": "\r\n## 3.0.1(2022-11-03)\n修复 撤销和重做不生效的问题\n## 3.0.0(2022-11-03)\r\n使用wxs重构代码,性能大提升\r\n新增 支持蒙版裁剪,可以裁剪任何形状的图形(详情见demo示例)\r\n新增 支持在弹窗中"
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/components/bt-cropper/bt-cropper.vue",
    "chars": 27789,
    "preview": "<template>\r\n\t<view class=\"bt-container\" :style=\"[containerStyle]\">\r\n\t\t<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 --"
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/components/bt-cropper/iconfont.css",
    "chars": 634,
    "preview": "@font-face {\r\n  font-family: \"iconfont\"; /* Project id 3311610 */\r\n  src: url('//at.alicdn.com/t/font_3311610_7wh8injedp"
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/components/bt-cropper/js/touchs.js",
    "chars": 6777,
    "preview": "var startTouchs = [];\r\nvar touchType = ''\r\nvar startDistance = 0;\r\nvar touchCenter = [];\r\nvar cropperRect = null;\r\nvar i"
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/components/bt-cropper/utils/tools.js",
    "chars": 1078,
    "preview": "export function getTouchPoints(touchs) {\r\n\treturn Array.from(touchs).map(ev => {\r\n\t\treturn [ev.clientX, ev.clientY]\r\n\t})"
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/components/bt-cropper/{ages.json",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/package.json",
    "chars": 1339,
    "preview": "{\r\n\t\"id\": \"bt-cropper\",\r\n\t\"displayName\": \"bt-cropper图片裁剪插件\",\r\n\t\"version\": \"3.0.1\",\r\n\t\"description\": \"一款好用的图片裁剪插件\",\r\n\t\"ke"
  },
  {
    "path": "UniApp/uni_modules/bt-cropper_3.0.1/readme.md",
    "chars": 2609,
    "preview": "\r\n\r\n## bt-cropper 图片裁切\r\n> **组件名:bt-cropper**\r\n\r\n图片裁切组件,在页面中裁切图片,输出裁切后的图片,支持app,小程序,H5\r\n### [在线体验](https://static-a3b890b"
  },
  {
    "path": "UniApp/uni_modules/mp-html/README.md",
    "chars": 5848,
    "preview": "## 为减小组件包的大小,默认组件包中不包含编辑、latex 公式等扩展功能,需要使用扩展功能的请参考下方的 插件扩展 栏的说明\n\n## 功能介绍\n- 全端支持(含 `v3、NVUE`)\n- 支持丰富的标签(包括 `table`、`vide"
  },
  {
    "path": "UniApp/uni_modules/mp-html/changelog.md",
    "chars": 9309,
    "preview": "## v2.4.2(2023-05-14)\n1. `A` `editable` 插件支持修改文字颜色 [详细](https://github.com/jin-yufeng/mp-html/issues/254)\n2. `F` 修复了 `sv"
  }
]

// ... and 10 more files (download for full content)

About this extraction

This page contains the full source code of the putyy/chatgpt GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 210 files (548.9 KB), approximately 168.2k tokens, and a symbol index with 510 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!