作者 燕梦迪

1111

正在显示 46 个修改的文件 包含 4763 行增加0 行删除

要显示太多修改。

为保证性能只显示 46 of 46+ 个文件。

  1 +APP_DEBUG = false
  2 +
  3 +[APP]
  4 +DEFAULT_TIMEZONE = Asia/Shanghai
  5 +
  6 +[DATABASE]
  7 +TYPE = mysql
  8 +HOSTNAME = 127.0.0.1
  9 +DATABASE = test
  10 +USERNAME = test
  11 +PASSWORD = test
  12 +HOSTPORT = 3306
  13 +CHARSET = utf8mb4
  14 +DEBUG = true
  15 +
  16 +[LANG]
  17 +default_lang = zh-cn
  1 +/.idea
  2 +/.vscode
  3 +*.log
  4 +/public/storage
  5 +/.DS_Store
  1 +sudo: false
  2 +
  3 +language: php
  4 +
  5 +branches:
  6 + only:
  7 + - stable
  8 +
  9 +cache:
  10 + directories:
  11 + - $HOME/.composer/cache
  12 +
  13 +before_install:
  14 + - composer self-update
  15 +
  16 +install:
  17 + - composer install --no-dev --no-interaction --ignore-platform-reqs
  18 + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
  19 + - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
  20 + - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
  21 + - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
  22 + - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
  23 + - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
  24 + - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
  25 + - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
  26 + - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
  27 + - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
  28 + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
  29 +
  30 +script:
  31 + - php think unit
  32 +
  33 +deploy:
  34 + provider: releases
  35 + api_key:
  36 + secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
  37 + file:
  38 + - ThinkPHP_Core.zip
  39 + - ThinkPHP_Full.zip
  40 + skip_cleanup: true
  41 + on:
  42 + tags: true
  1 + Apache License
  2 + Version 2.0, January 2004
  3 + http://www.apache.org/licenses/
  4 +
  5 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
  6 +
  7 + 1. Definitions.
  8 +
  9 + "License" shall mean the terms and conditions for use, reproduction,
  10 + and distribution as defined by Sections 1 through 9 of this document.
  11 +
  12 + "Licensor" shall mean the copyright owner or entity authorized by
  13 + the copyright owner that is granting the License.
  14 +
  15 + "Legal Entity" shall mean the union of the acting entity and all
  16 + other entities that control, are controlled by, or are under common
  17 + control with that entity. For the purposes of this definition,
  18 + "control" means (i) the power, direct or indirect, to cause the
  19 + direction or management of such entity, whether by contract or
  20 + otherwise, or (ii) ownership of fifty percent (50%) or more of the
  21 + outstanding shares, or (iii) beneficial ownership of such entity.
  22 +
  23 + "You" (or "Your") shall mean an individual or Legal Entity
  24 + exercising permissions granted by this License.
  25 +
  26 + "Source" form shall mean the preferred form for making modifications,
  27 + including but not limited to software source code, documentation
  28 + source, and configuration files.
  29 +
  30 + "Object" form shall mean any form resulting from mechanical
  31 + transformation or translation of a Source form, including but
  32 + not limited to compiled object code, generated documentation,
  33 + and conversions to other media types.
  34 +
  35 + "Work" shall mean the work of authorship, whether in Source or
  36 + Object form, made available under the License, as indicated by a
  37 + copyright notice that is included in or attached to the work
  38 + (an example is provided in the Appendix below).
  39 +
  40 + "Derivative Works" shall mean any work, whether in Source or Object
  41 + form, that is based on (or derived from) the Work and for which the
  42 + editorial revisions, annotations, elaborations, or other modifications
  43 + represent, as a whole, an original work of authorship. For the purposes
  44 + of this License, Derivative Works shall not include works that remain
  45 + separable from, or merely link (or bind by name) to the interfaces of,
  46 + the Work and Derivative Works thereof.
  47 +
  48 + "Contribution" shall mean any work of authorship, including
  49 + the original version of the Work and any modifications or additions
  50 + to that Work or Derivative Works thereof, that is intentionally
  51 + submitted to Licensor for inclusion in the Work by the copyright owner
  52 + or by an individual or Legal Entity authorized to submit on behalf of
  53 + the copyright owner. For the purposes of this definition, "submitted"
  54 + means any form of electronic, verbal, or written communication sent
  55 + to the Licensor or its representatives, including but not limited to
  56 + communication on electronic mailing lists, source code control systems,
  57 + and issue tracking systems that are managed by, or on behalf of, the
  58 + Licensor for the purpose of discussing and improving the Work, but
  59 + excluding communication that is conspicuously marked or otherwise
  60 + designated in writing by the copyright owner as "Not a Contribution."
  61 +
  62 + "Contributor" shall mean Licensor and any individual or Legal Entity
  63 + on behalf of whom a Contribution has been received by Licensor and
  64 + subsequently incorporated within the Work.
  65 +
  66 + 2. Grant of Copyright License. Subject to the terms and conditions of
  67 + this License, each Contributor hereby grants to You a perpetual,
  68 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable
  69 + copyright license to reproduce, prepare Derivative Works of,
  70 + publicly display, publicly perform, sublicense, and distribute the
  71 + Work and such Derivative Works in Source or Object form.
  72 +
  73 + 3. Grant of Patent License. Subject to the terms and conditions of
  74 + this License, each Contributor hereby grants to You a perpetual,
  75 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable
  76 + (except as stated in this section) patent license to make, have made,
  77 + use, offer to sell, sell, import, and otherwise transfer the Work,
  78 + where such license applies only to those patent claims licensable
  79 + by such Contributor that are necessarily infringed by their
  80 + Contribution(s) alone or by combination of their Contribution(s)
  81 + with the Work to which such Contribution(s) was submitted. If You
  82 + institute patent litigation against any entity (including a
  83 + cross-claim or counterclaim in a lawsuit) alleging that the Work
  84 + or a Contribution incorporated within the Work constitutes direct
  85 + or contributory patent infringement, then any patent licenses
  86 + granted to You under this License for that Work shall terminate
  87 + as of the date such litigation is filed.
  88 +
  89 + 4. Redistribution. You may reproduce and distribute copies of the
  90 + Work or Derivative Works thereof in any medium, with or without
  91 + modifications, and in Source or Object form, provided that You
  92 + meet the following conditions:
  93 +
  94 + (a) You must give any other recipients of the Work or
  95 + Derivative Works a copy of this License; and
  96 +
  97 + (b) You must cause any modified files to carry prominent notices
  98 + stating that You changed the files; and
  99 +
  100 + (c) You must retain, in the Source form of any Derivative Works
  101 + that You distribute, all copyright, patent, trademark, and
  102 + attribution notices from the Source form of the Work,
  103 + excluding those notices that do not pertain to any part of
  104 + the Derivative Works; and
  105 +
  106 + (d) If the Work includes a "NOTICE" text file as part of its
  107 + distribution, then any Derivative Works that You distribute must
  108 + include a readable copy of the attribution notices contained
  109 + within such NOTICE file, excluding those notices that do not
  110 + pertain to any part of the Derivative Works, in at least one
  111 + of the following places: within a NOTICE text file distributed
  112 + as part of the Derivative Works; within the Source form or
  113 + documentation, if provided along with the Derivative Works; or,
  114 + within a display generated by the Derivative Works, if and
  115 + wherever such third-party notices normally appear. The contents
  116 + of the NOTICE file are for informational purposes only and
  117 + do not modify the License. You may add Your own attribution
  118 + notices within Derivative Works that You distribute, alongside
  119 + or as an addendum to the NOTICE text from the Work, provided
  120 + that such additional attribution notices cannot be construed
  121 + as modifying the License.
  122 +
  123 + You may add Your own copyright statement to Your modifications and
  124 + may provide additional or different license terms and conditions
  125 + for use, reproduction, or distribution of Your modifications, or
  126 + for any such Derivative Works as a whole, provided Your use,
  127 + reproduction, and distribution of the Work otherwise complies with
  128 + the conditions stated in this License.
  129 +
  130 + 5. Submission of Contributions. Unless You explicitly state otherwise,
  131 + any Contribution intentionally submitted for inclusion in the Work
  132 + by You to the Licensor shall be under the terms and conditions of
  133 + this License, without any additional terms or conditions.
  134 + Notwithstanding the above, nothing herein shall supersede or modify
  135 + the terms of any separate license agreement you may have executed
  136 + with Licensor regarding such Contributions.
  137 +
  138 + 6. Trademarks. This License does not grant permission to use the trade
  139 + names, trademarks, service marks, or product names of the Licensor,
  140 + except as required for reasonable and customary use in describing the
  141 + origin of the Work and reproducing the content of the NOTICE file.
  142 +
  143 + 7. Disclaimer of Warranty. Unless required by applicable law or
  144 + agreed to in writing, Licensor provides the Work (and each
  145 + Contributor provides its Contributions) on an "AS IS" BASIS,
  146 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  147 + implied, including, without limitation, any warranties or conditions
  148 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
  149 + PARTICULAR PURPOSE. You are solely responsible for determining the
  150 + appropriateness of using or redistributing the Work and assume any
  151 + risks associated with Your exercise of permissions under this License.
  152 +
  153 + 8. Limitation of Liability. In no event and under no legal theory,
  154 + whether in tort (including negligence), contract, or otherwise,
  155 + unless required by applicable law (such as deliberate and grossly
  156 + negligent acts) or agreed to in writing, shall any Contributor be
  157 + liable to You for damages, including any direct, indirect, special,
  158 + incidental, or consequential damages of any character arising as a
  159 + result of this License or out of the use or inability to use the
  160 + Work (including but not limited to damages for loss of goodwill,
  161 + work stoppage, computer failure or malfunction, or any and all
  162 + other commercial damages or losses), even if such Contributor
  163 + has been advised of the possibility of such damages.
  164 +
  165 + 9. Accepting Warranty or Additional Liability. While redistributing
  166 + the Work or Derivative Works thereof, You may choose to offer,
  167 + and charge a fee for, acceptance of support, warranty, indemnity,
  168 + or other liability obligations and/or rights consistent with this
  169 + License. However, in accepting such obligations, You may act only
  170 + on Your own behalf and on Your sole responsibility, not on behalf
  171 + of any other Contributor, and only if You agree to indemnify,
  172 + defend, and hold each Contributor harmless for any liability
  173 + incurred by, or claims asserted against, such Contributor by reason
  174 + of your accepting any such warranty or additional liability.
  175 +
  176 + END OF TERMS AND CONDITIONS
  177 +
  178 + APPENDIX: How to apply the Apache License to your work.
  179 +
  180 + To apply the Apache License to your work, attach the following
  181 + boilerplate notice, with the fields enclosed by brackets "[]"
  182 + replaced with your own identifying information. (Don't include
  183 + the brackets!) The text should be enclosed in the appropriate
  184 + comment syntax for the file format. We also recommend that a
  185 + file or class name and description of purpose be included on the
  186 + same "printed page" as the copyright notice for easier
  187 + identification within third-party archives.
  188 +
  189 + Copyright [yyyy] [name of copyright owner]
  190 +
  191 + Licensed under the Apache License, Version 2.0 (the "License");
  192 + you may not use this file except in compliance with the License.
  193 + You may obtain a copy of the License at
  194 +
  195 + http://www.apache.org/licenses/LICENSE-2.0
  196 +
  197 + Unless required by applicable law or agreed to in writing, software
  198 + distributed under the License is distributed on an "AS IS" BASIS,
  199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  200 + See the License for the specific language governing permissions and
  201 + limitations under the License.
  1 +![介绍](https://kt8logo.oss-cn-beijing.aliyuncs.com/ktadminbg.jpg)
  2 +
  3 +[官网](http://www.ktadmin.cn) | [GPT开发教程](https://www.showdoc.com.cn/gpt1) | [安装教程](https://www.showdoc.com.cn/ktadmin/9320271198492681) | [开发文档](https://www.showdoc.com.cn/ktadmin/) | [应用开发](https://www.showdoc.com.cn/ktadmin/9324421497854622) | [GPTCMS](https://gitee.com/kt8cn/gptcms) | [API文档](https://www.showdoc.com.cn/2032412156402378/9297860525650426/) | [使用手册](https://kqv9wk0r7t.feishu.cn/wiki/I93BwE1raisNfqkekf0ctS98nhc)
  4 +
  5 +
  6 +#### :star: KtAdmin无偿供大家使用,您的 :star: star是我们前进的动力
  7 +
  8 +
  9 +### **开发者交流QQ群:670057597 (群内会提供技术指导)**
  10 +
  11 +
  12 +
  13 +# 系统推荐:GPTCMS-ChatGPT(5分钟搭建GPT智能聊天SAAS系统)
  14 +
  15 +直达链接: https://gitee.com/kt8cn/gptcms
  16 +
  17 +### **KtAdmin用户(开发者)交流群 **
  18 +
  19 +![输入图片说明](https://kt8logo.oss-cn-beijing.aliyuncs.com/gptcms-free.png)
  20 +
  21 +
  22 +### **系统介绍**
  23 +
  24 +[狂团(kt8.cn)](http://www.kt8.cn)旗下[ KtAdmin ]是为独立版SAAS系统而生的快速开发框架!
  25 +
  26 +KtAdmin 基于当前流行的ThinkPHP6.x+Vue3+Elementui++Vite 开发 , 是一款免费开源的多用户,多应用的独立版SAAS系统开发框架。
  27 +
  28 +[KtAdmin]遵循较为宽松的Apache2.0开源协议,支持免费商用。
  29 +
  30 +### **重磅公告一(密码为kt8.cn)!!**
  31 +
  32 +狂团KtAdmin底层已封装ChatGPT、gpt-3.5、gpt-4、文心一言、百度文本审核、文字转语音、语音转文字等人工智能API,支持快速调用。开发好的成品应用可上架至狂团软件商城[www.kt8.cn](http://www.kt8.cn)获取丰厚收入!
  33 +
  34 +使用api调用方式,只需配置key与api域名即可快速调用,秒级响应,支持流输出、连续对话,文本审核等强大功能!
  35 +
  36 + **GPT使用教程:** http://x.kt8.cn/question/33.html
  37 +
  38 +
  39 +### **重磅公告二!!**
  40 +
  41 +基于KtAdmin框架的免费GPT极速版应用已上线,框架已默认集成,部署框架即可使用( **如果需要访问密码,默认为 kt8.cn 也可以自行修改** )。
  42 +
  43 +
  44 +部署完成后,登录admin后台,配置key和接口地址即可使用,配置后应用访问路径为: 域名/chat
  45 +
  46 +![输入图片说明](https://xcx-diy.oss-cn-beijing.aliyuncs.com/chatnew.png)
  47 +
  48 +
  49 +
  50 +### **应用市场-商业变现**
  51 +
  52 +狂团平台拥有数量庞大的商业用户群体,基于KtAdmin开发的系统可以上架至平台,快速变现,优质应用平台可协助推广分发!访问[狂团](http://www.kt8.cn)首页,第一个新独立版类目即为KtAdmin应用市场,可在线安装免费和付费应用。
  53 +
  54 +
  55 +### 微信与抖音及其他生态插件
  56 +
  57 +KtAdmin目前已通过免费应用形式提供了企业微信底层(服务商代自建应用模式)、微信小程序在线提审发布底层、微信开放平台底层,可直接在KtAdmin应用市场在线免费安装,并长期免费更新。后续还将视情况免费提供抖音底层、快手底层、B站底层、阿里云剪辑底层、TikTok底层、字节巨量广告底层等各种必要的生态底层应用(大部分已完成开发),帮助各位开发者提升研发效率,避免重复造轮子。
  58 +
  59 +### 代理商功能
  60 +
  61 +代理商OEM系统将以插件的形式对外提供,内含多项核心技术,敬请期待(已完成开发)!
  62 +
  63 +### 主要特性
  64 +
  65 +1.为独立版SAAS系统而生的快速开发框架,可大量节省SAAS系统开发周期,快速完成交付。
  66 +
  67 +2.天然saas底层,支持无限账号,无需重复部署安装,高效管理多个用户,多个应用。
  68 +
  69 +3.天然支持多应用,多插件,一个域名即可统一化管理多套系统,多个插件,同时支持共享一套账户余额套餐系统。
  70 +
  71 +4.秉承“每个系统都是一个生态“的开放共赢理念,帮助每一套建立合作的独立系统构建自己的插件生态,共生共荣。
  72 +
  73 +5.后端使用tp6原生底层,无改动,无额外学习成本,易开发,易上手,效率极高。
  74 +
  75 +6.前端无限制,可按喜好使用VUE2,VUE3,JQ等。
  76 +
  77 +7.自带用户管理,应用市场,阿里云oss,腾讯云cos,七牛云存储,阿里云短信,等诸多实用功能,开箱即用,无需重复开发。
  78 +
  79 +8.KtAdmin搭载狂团成熟的在线更新解决方案,可统一化管理主系统及各种插件的在线安装,在线更新。
  80 +
  81 +9.支持开发者生态,并为开发者提供成熟的主系统在线更新,插件在线安装,在线更新等基础设施服务,同时以狂团平台及数万精准源码用户为依托,为开发者提供精准的系统分发及流量支持。
  82 +
  83 +
  84 +### **系统下载**
  85 +
  86 + :point_right: 本仓库是面向技术开发者群体的开发版
  87 +
  88 + :point_right: 如果您是非技术用户或者需要稳定的标准版,可直接下载[https://www.kt8.cn/item/view1520.html](https://www.kt8.cn/item/view1520.html)
  89 +
  90 +(我们面向非技术群体提供标准版安装包,直接上传到服务器,按安装教程安装即可,并免费提供在线一键更新系统)
  91 +
  92 +
  93 +### .env
  94 +根目录会自带一个.example.env文件,你可以直接更名为.env文件并根据你的要求进行修改
  95 +
  96 +
  97 +### 软件架构
  98 +
  99 +1.后端目录结构和thinkphp6常用结构一致
  100 +
  101 +2.框架前端代码放在VUE目录下,user是用户后台项目(打包后上传至public/app/base目录下),admin是管理后台项目(打包后上传至public/app/base/admin目录下
  102 +
  103 +### 应用开发
  104 +
  105 +KtAdmin的应用开发简单到不用去熟悉框架。简单来说就是根据tp6的多应用模式在 app 目录下新建一个应用, 然后按标准把应用封装成一个插件包。这个插件包是完全独立的,以至于我们一直在说前端可以按需使用JQ,VUE等,而并不是非得跟框架一样使用VUE3。我们一直建议,尽量不用动框架里面base应用的代码,甚至都不用去看他,只需要简单看下应用开发流程文档(和TP6官方的多应用模式文档),就可以开始开发应用。
  106 +
  107 +### 开发者交流群(联系客服拉群)
  108 +
  109 +![联系客服](https://www.kt8.cn/config/ueditor/php/upload/image/20211020/1634724501157966.png)
  110 +
  111 +### 在线演示
  112 +
  113 +
  114 + **用户后台** http://demo.kt8.cn 账号123456 密码123456
  115 +
  116 + **管理后台** http://demo.kt8.cn/app/base/admin
  117 +
  118 + 账号admin 密码123456
  119 +
  120 +### 功能截图
  121 +
  122 +![管理后台](https://kt8logo.oss-cn-beijing.aliyuncs.com/ktadmin.png)
  123 +
  124 +![用户后台](https://kt8logo.oss-cn-beijing.aliyuncs.com/kt1.png)
  125 +
  126 +
  127 +### 插件下载
  128 +
  129 +后续免费/付费插件均发布至[狂团软件商城 www.kt8.cn](http://www.kt8.cn),可自行下载
  130 +
  131 +### 关于我们
  132 +
  133 +我们在SAAS系统行业深耕了八年,曾研发出了多套在行业内有一定知名度的系统,也帮助不少客户实现了千万级收入。我们非常了解这个行业,了解行业痛点,了解客户需求。如今,希望KtAdmin这套凝聚了我们八年SAAS行业研发经验的系统能帮到更多有需要的人。
  134 +
  135 +### 版权信息
  136 +
  137 +KtAdmin遵循Apache2.0开源协议发布,并提供免费使用。
  138 +
  139 +本项目包含的第三方源码和二进制文件之版权信息另行标注。
  140 +
  141 +版权所有Copyright © 2022 by KtAdmin (http://www.ktadmin.cn)
  142 +
  143 +All rights reserved。
  144 +
  145 +### 允许行为
  146 +
  147 +1.允许商用
  148 +
  149 +2.允许基于框架开发应用并作为独立系统出售
  150 +
  151 +3.允许修改代码以满足自身需求
  152 +
  153 +### 禁止行为
  154 +
  155 +1.禁止修改框架代码并再次发布框架衍生版等与Ktadmin产生恶意竞争或对抗的行为
  156 +
  157 +2.禁止任意删除修改代码注释版权或页面版权等任何违反Apache2.0开源协议及《中华人民共和国著作权法》的行为
  1 +deny from all
  1 +<?php
  2 +declare (strict_types = 1);
  3 +
  4 +namespace app;
  5 +
  6 +use think\Service;
  7 +
  8 +/**
  9 + * 应用服务类
  10 + */
  11 +class AppService extends Service
  12 +{
  13 + public function register()
  14 + {
  15 + // 服务注册
  16 + }
  17 +
  18 + public function boot()
  19 + {
  20 + // 服务启动
  21 + }
  22 +}
  1 +<?php
  2 +declare (strict_types = 1);
  3 +
  4 +namespace app;
  5 +
  6 +use think\App;
  7 +use think\exception\ValidateException;
  8 +use think\Validate;
  9 +
  10 +/**
  11 + * 控制器基础类
  12 + */
  13 +abstract class BaseController
  14 +{
  15 + /**
  16 + * Request实例
  17 + * @var \think\Request
  18 + */
  19 + protected $request;
  20 +
  21 + /**
  22 + * 应用实例
  23 + * @var \think\App
  24 + */
  25 + protected $app;
  26 +
  27 + /**
  28 + * 是否批量验证
  29 + * @var bool
  30 + */
  31 + protected $batchValidate = false;
  32 +
  33 + /**
  34 + * 控制器中间件
  35 + * @var array
  36 + */
  37 + protected $middleware = [];
  38 +
  39 + /**
  40 + * 构造方法
  41 + * @access public
  42 + * @param App $app 应用对象
  43 + */
  44 + public function __construct(App $app)
  45 + {
  46 + $this->app = $app;
  47 + $this->request = $this->app->request;
  48 +
  49 + // 控制器初始化
  50 + $this->initialize();
  51 + }
  52 +
  53 + // 初始化
  54 + protected function initialize()
  55 + {}
  56 +
  57 + /**
  58 + * 验证数据
  59 + * @access protected
  60 + * @param array $data 数据
  61 + * @param string|array $validate 验证器名或者验证规则数组
  62 + * @param array $message 提示信息
  63 + * @param bool $batch 是否批量验证
  64 + * @return array|string|true
  65 + * @throws ValidateException
  66 + */
  67 + protected function validate(array $data, $validate, array $message = [], bool $batch = false)
  68 + {
  69 + if (is_array($validate)) {
  70 + $v = new Validate();
  71 + $v->rule($validate);
  72 + } else {
  73 + if (strpos($validate, '.')) {
  74 + // 支持场景
  75 + [$validate, $scene] = explode('.', $validate);
  76 + }
  77 + $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
  78 + $v = new $class();
  79 + if (!empty($scene)) {
  80 + $v->scene($scene);
  81 + }
  82 + }
  83 +
  84 + $v->message($message);
  85 +
  86 + // 是否批量验证
  87 + if ($batch || $this->batchValidate) {
  88 + $v->batch(true);
  89 + }
  90 +
  91 + return $v->failException(true)->check($data);
  92 + }
  93 +
  94 +}
  1 +<?php
  2 +namespace app;
  3 +
  4 +use think\db\exception\DataNotFoundException;
  5 +use think\db\exception\ModelNotFoundException;
  6 +use think\exception\Handle;
  7 +use think\exception\HttpException;
  8 +use think\exception\HttpResponseException;
  9 +use think\exception\ValidateException;
  10 +use think\Response;
  11 +use Throwable;
  12 +
  13 +/**
  14 + * 应用异常处理类
  15 + */
  16 +class ExceptionHandle extends Handle
  17 +{
  18 + /**
  19 + * 不需要记录信息(日志)的异常类列表
  20 + * @var array
  21 + */
  22 + protected $ignoreReport = [
  23 + HttpException::class,
  24 + HttpResponseException::class,
  25 + ModelNotFoundException::class,
  26 + DataNotFoundException::class,
  27 + ValidateException::class,
  28 + ];
  29 +
  30 + /**
  31 + * 记录异常信息(包括日志或者其它方式记录)
  32 + *
  33 + * @access public
  34 + * @param Throwable $exception
  35 + * @return void
  36 + */
  37 + public function report(Throwable $exception): void
  38 + {
  39 + // 使用内置的方式记录异常日志
  40 + parent::report($exception);
  41 + }
  42 +
  43 + /**
  44 + * Render an exception into an HTTP response.
  45 + *
  46 + * @access public
  47 + * @param \think\Request $request
  48 + * @param Throwable $e
  49 + * @return Response
  50 + */
  51 + public function render($request, Throwable $e): Response
  52 + {
  53 + // 添加自定义异常处理机制
  54 +
  55 + // 其他错误交给系统处理
  56 + return parent::render($request, $e);
  57 + }
  58 +}
  1 +<?php
  2 +namespace app;
  3 +
  4 +// 应用请求对象类
  5 +class Request extends \think\Request
  6 +{
  7 +
  8 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +/**
  11 + * 这是管理后台的菜单文件
  12 + */
  13 +return [
  14 + //系统
  15 + [
  16 + "path" => "/system/site",
  17 + "redirect" => "/system/site",
  18 + "meta" => ['title'=>'系统设置', 'icon'=>'Setting'],
  19 + "component" => "MyLayout",
  20 + "children" => [
  21 + [
  22 + "path" => "/system/site",
  23 + "name" => "system",
  24 + "meta" => ['title'=>'系统设置', 'icon'=>'Setting', 'alwaysShow'=>true],
  25 + "redirect" => "/system/site",
  26 + "component" => "RouterView",
  27 + "children" => [
  28 + [
  29 + "path" => "/system/site",
  30 + "name" => "systemsite",
  31 + "meta" => ['title'=>'站点设置'],
  32 + "component" => "() => import('@/pages/admin/system/site.vue')",
  33 + ],
  34 + [
  35 + "path" => "/system/loginsetup",
  36 + "name" => "systemloginsetup",
  37 + "meta" => ['title'=>'登录设置'],
  38 + "component" => "() => import('@/pages/admin/system/login.vue')",
  39 + ],
  40 + [
  41 + "path" => "/system/oss",
  42 + "name" => "systemoss",
  43 + "meta" => ['title'=>'存储设置'],
  44 + "component" => "() => import('@/pages/admin/system/oss.vue')",
  45 + ],
  46 + [
  47 + "path" => "/system/sms",
  48 + "name" => "systemsms",
  49 + "meta" => ['title'=>'短信设置'],
  50 + "component" => "() => import('@/pages/admin/system/sms.vue')",
  51 + ],
  52 + [
  53 + "path" => "/wxpay/config",
  54 + "name" => "wxpayconfig",
  55 + "meta" => ['title'=>'支付配置'],
  56 + "component" => "() => import('@/pages/admin/wxpay/wxpayconfig.vue')",
  57 + ],
  58 + [
  59 + "path" => "/system/aiconfig",
  60 + "name" => "systemaiconfig",
  61 + "meta" => ['title'=>'AI接口设置'],
  62 + "component" => "() => import('@/pages/admin/system/aiconfig.vue')",
  63 + ],
  64 + [
  65 + "path" => "/system/gptconfig",
  66 + "name" => "systemgptconfig",
  67 + "meta" => ['title'=>'GPT接口设置'],
  68 + "component" => "() => import('@/pages/admin/system/gptconfig.vue')",
  69 + ],
  70 + [
  71 + "path" => "/system/cs",
  72 + "name" => "systemcs",
  73 + "meta" => ['title'=>'内容安全'],
  74 + "component" => "() => import('@/pages/admin/system/contentsecurity.vue')",
  75 + ],
  76 + ]
  77 + ],
  78 + [
  79 + "path" => "/kt/config",
  80 + "name" => "kt",
  81 + "meta" => ['title'=>'狂团对接', 'icon'=>'HelpFilled', 'alwaysShow'=>true],
  82 + "redirect" => "/kt/config",
  83 + "component" => "RouterView",
  84 + "children" => [
  85 + [
  86 + "path" => "/kt/config",
  87 + "name" => "ktconfig",
  88 + "meta" => ['title'=>'在线更新'],
  89 + "component" => "() => import('@/pages/admin/kt/ktconfig.vue')",
  90 + ],
  91 + [
  92 + "path" => "/kt/app",
  93 + "name" => "ktapp",
  94 + "meta" => ['title'=>'应用列表'],
  95 + "component" => "() => import('@/pages/admin/kt/ktapp.vue')",
  96 + ],
  97 + [
  98 + "path" => "/kt/appstore",
  99 + "name" => "appstore",
  100 + "meta" => ['title'=>'应用商店'],
  101 + "component" => "() => import('@/pages/admin/kt/appstore.vue')",
  102 + ],
  103 + [
  104 + "path" => "/kt/dockset",
  105 + "name" => "ktdockset",
  106 + "meta" => ['title'=>'对接设置'],
  107 + "component" => "() => import('@/pages/admin/kt/dockset.vue')",
  108 + ],
  109 + ]
  110 + ],
  111 + ]
  112 + ],
  113 + //用户
  114 + [
  115 + "path" => "/user/list",
  116 + "redirect" => "/user/list",
  117 + "meta" => ['title'=>'用户管理', 'icon'=>'User'],
  118 + "component" => "MyLayout",
  119 + "children" => [
  120 + [
  121 + "path" => "/user/list",
  122 + "name" => "user",
  123 + "meta" => ['title'=>'用户管理', 'icon'=>'User', 'alwaysShow'=>true],
  124 + "redirect" => "/user/list",
  125 + "component" => "RouterView",
  126 + "children" => [
  127 + [
  128 + "path" => "/user/list",
  129 + "name" => "userlist",
  130 + "meta" => ['title'=>'用户列表'],
  131 + "component" => "() => import('@/pages/admin/user/list.vue')",
  132 + ],
  133 + [
  134 + "path" => "/user/add",
  135 + "name" => "useradd",
  136 + "meta" => ['title'=>'新增用户'],
  137 + "component" => "() => import('@/pages/admin/user/add.vue')",
  138 + ],
  139 + [
  140 + "path" => "/user/edit",
  141 + "name" => "useredit",
  142 + "meta" => ['title'=>'编辑用户', 'hiddenInSideMenu'=>true],
  143 + "component" => "() => import('@/pages/admin/user/edit.vue')",
  144 + ],
  145 + ]
  146 + ]
  147 + ]
  148 + ],
  149 + //应用套餐
  150 + [
  151 + "path" => "/package/list",
  152 + "redirect" => "/package/list",
  153 + "meta" => ['title'=>'套餐管理', 'icon'=>'Coin'],
  154 + "component" => "MyLayout",
  155 + "children" => [
  156 + [
  157 + "path" => "/package/list",
  158 + "name" => "package",
  159 + "meta" => ['title'=>'应用套餐', 'icon'=>'Coin', 'alwaysShow'=>true],
  160 + "redirect" => "/package/list",
  161 + "component" => "RouterView",
  162 + "children" => [
  163 + [
  164 + "path" => "/package/list",
  165 + "name" => "paskagelist",
  166 + "meta" => ['title'=>'套餐列表'],
  167 + "component" => "() => import('@/pages/admin/package/list.vue')",
  168 + ],
  169 + [
  170 + "path" => "/package/add",
  171 + "name" => "paskageadd",
  172 + "meta" => ['title'=>'新增套餐'],
  173 + "component" => "() => import('@/pages/admin/package/add.vue')",
  174 + ]
  175 + ]
  176 + ],
  177 + ]
  178 + ],
  179 + //应用
  180 + [
  181 + "path" => "/app/mainapp",
  182 + "redirect" => "/app/mainapp",
  183 + "meta" => ['title'=>'应用设置', 'icon'=>'Menu'],
  184 + "component" => "MyLayout",
  185 + "children" => [
  186 + [
  187 + "path" => "/app/mainapp",
  188 + "name" => "apps",
  189 + "meta" => ['title'=>'应用管理', 'icon'=>'Menu', 'alwaysShow'=>true],
  190 + "redirect" => "/app/mainapp",
  191 + "component" => "RouterView",
  192 + "children" => [
  193 + [
  194 + "path" => "/app/mainapp",
  195 + "name" => "appmainapp",
  196 + "meta" => ['title'=>'应用设置'],
  197 + "component" => "() => import('@/pages/admin/app/mainapp.vue')"
  198 + ],
  199 + [
  200 + "path" => "/app/plugin",
  201 + "name" => "appplugin",
  202 + "meta" => ['title'=>'插件设置'],
  203 + "component" => "() => import('@/pages/admin/app/plugin.vue')"
  204 + ],
  205 + [
  206 + "path" => "/app/tools",
  207 + "name" => "apptools",
  208 + "meta" => ['title'=>'工具应用'],
  209 + "component" => "() => import('@/pages/admin/app/tools.vue')"
  210 + ],
  211 + [
  212 + "path" => "/app/template",
  213 + "name" => "apptemplate",
  214 + "meta" => ['title'=>'模板应用'],
  215 + "component" => "() => import('@/pages/admin/app/template.vue')"
  216 + ],
  217 + ]
  218 + ],
  219 + ]
  220 + ],
  221 + //市场
  222 + [
  223 + "path" => "/market/index",
  224 + "redirect" => "/market/index",
  225 + "meta" => ['title'=>'自营市场', 'icon'=>'Goods'],
  226 + "component" => "MyLayout",
  227 + "children" => [
  228 + [
  229 + "path" => "/market/index",
  230 + "name" => "market",
  231 + "meta" => ['title'=>'应用市场', 'icon'=>'Goods', 'alwaysShow'=>true],
  232 + "redirect" => "/market/index",
  233 + "component" => "RouterView",
  234 + "children" => [
  235 + [
  236 + "path" => "/market/index",
  237 + "name" => "marketindex",
  238 + "meta" => ['title'=>'应用管理'],
  239 + "component" => "() => import('@/pages/admin/market/index.vue')"
  240 + ],
  241 + [
  242 + "path" => "/market/edit",
  243 + "name" => "marketedit",
  244 + "meta" => ['title'=>'市场编辑', 'hiddenInSideMenu'=>true],
  245 + "component" => "() => import('@/pages/admin/market/edit.vue')"
  246 + ],
  247 + [
  248 + "path" => "/market/classification",
  249 + "name" => "marketclassification",
  250 + "meta" => ['title'=>'分类管理'],
  251 + "component" => "() => import('@/pages/admin/market/classification.vue')"
  252 + ],
  253 + ]
  254 + ],
  255 + [
  256 + "path" => "/market/openuse",
  257 + "name" => "marketopenuse",
  258 + "meta" => ['title'=>'已购应用', 'icon'=>'Present', 'alwaysShow'=>true],
  259 + "redirect" => "/market/openuse",
  260 + "component" => "RouterView",
  261 + "children" => [
  262 + [
  263 + "path" => "/market/openuse",
  264 + "name" => "marketopenuse",
  265 + "meta" => ['title'=>'应用管理'],
  266 + "component" => "() => import('@/pages/admin/market/openuse.vue')"
  267 + ],
  268 + ]
  269 + ],
  270 + // [
  271 + // "path" => "/market/order",
  272 + // "name" => "marketorder",
  273 + // "meta" => ['title'=>'市场订单', 'icon'=>'Tickets', 'alwaysShow'=>true],
  274 + // "redirect" => "/market/order",
  275 + // "component" => "RouterView",
  276 + // "children" => [
  277 + // [
  278 + // "path" => "/market/order",
  279 + // "name" => "marketorder",
  280 + // "meta" => ['title'=>'订单列表'],
  281 + // "component" => "() => import('@/pages/admin/market/order.vue')"
  282 + // ],
  283 + // ]
  284 + // ],
  285 + ]
  286 + ],
  287 +
  288 +];
  289 +
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +// 这是系统自动生成的公共文件
  11 +/**
  12 + * 执行sql 保证sql执行完
  13 + * @param $content
  14 + * @return array
  15 + * @throws \Exception
  16 + */
  17 +function updateRunSql($content){
  18 + // error_reporting(0);
  19 + //遍历执行sql语句
  20 + //去除空行和注释
  21 + $content=removeBom($content);//自动去除bom头
  22 + // $content = preg_replace("/[\/\*][\s\S\r\n]*[\*\/]/", '', $content);
  23 + // $content = preg_replace("/[--]+(.+)(\r\n)+/", '', $content);
  24 + $content = preg_replace("/\/\*[\s\S\r\n]*\*\//", '', $content);
  25 + $content = preg_replace("/--+(.+)(\r\n)+/", '', $content);
  26 + $sqlArr = preg_split("/;[\r\n]*/", $content);
  27 + $error_message = '';
  28 + foreach ($sqlArr as $v) {
  29 + $v = str_replace( "\r\n",' ',$v);
  30 + if (empty($v)) continue;
  31 + try {
  32 + think\facade\Db::execute($v);
  33 + } catch (\Exception $e) {
  34 + // $error_message .= $e->getMessage() . ' ';
  35 + // \Log::error('sql执行错误:' . $e->getMessage());
  36 + $error_message = $v;
  37 + }
  38 + }
  39 + if ($error_message) {
  40 + return ['status'=>'error','msg'=> $error_message];
  41 + } else {
  42 + return ['status'=>'success','msg'=>'执行成功'];
  43 + }
  44 +}
  45 +
  46 +
  47 +/**
  48 + * 自动找到内容bom头并去除
  49 + * @param $content
  50 + * @return bool|string
  51 + */
  52 +function removeBom($content){
  53 + $contents=$content;
  54 + $charset[1]=substr($contents,0,1);
  55 + $charset[2]=substr($contents,1,1);
  56 + $charset[3]=substr($contents,2,1);
  57 + if(ord($charset[1])==239 && ord($charset[2])==187 && ord($charset[3])==191){
  58 +
  59 + $content=substr($content,3);
  60 + }
  61 + return $content;
  62 +}
  63 +
  64 +/**
  65 + *
  66 + * 清空文件夹
  67 + * @param $dirName
  68 + * @param $oldtime 小于的时间
  69 + * @param $newtime 大于的时间
  70 + */
  71 +function clear_dir($dirName){
  72 + if(is_dir($dirName)){//如果传入的参数不是目录,则为文件,应将其删除
  73 + //如果传入的参数是目录
  74 + $handle = @opendir($dirName);
  75 + while(($file = @readdir($handle)) !== false){
  76 + if($file!='.'&&$file!='..'){
  77 + $dir = $dirName . '/' . $file; //当前文件$dir为文件目录+文件
  78 + remove_dir($dir);
  79 + }
  80 + }
  81 + remove_dir($dirName);
  82 + }
  83 +}
  84 +
  85 +/**
  86 + *
  87 + * 清空并删除文件夹
  88 + * @param $dirName
  89 + * @param $oldtime 小于的时间
  90 + * @param $newtime 大于的时间
  91 + */
  92 +function remove_dir($dirName,$oldtime=null,$newtime=null){
  93 + if(!is_dir($dirName)){//如果传入的参数不是目录,则为文件,应将其删除
  94 + $mtime = filectime($dirName);
  95 + if($oldtime===null&&$newtime===null){
  96 + @unlink($dirName);
  97 + }else{
  98 + if(isset($oldtime)){
  99 + if($mtime<$oldtime){
  100 + @unlink($dirName);
  101 + }
  102 + }
  103 + if(isset($newtime)){
  104 + if($mtime>$newtime){
  105 + @unlink($dirName);
  106 + }
  107 + }
  108 + }
  109 + return false;
  110 + }
  111 + //如果传入的参数是目录
  112 + $handle = @opendir($dirName);
  113 + while(($file = @readdir($handle)) !== false){
  114 + if($file!='.'&&$file!='..'){
  115 + $dir = $dirName . '/' . $file; //当前文件$dir为文件目录+文件
  116 + remove_dir($dir,$oldtime,$newtime);
  117 + }
  118 + }
  119 + closedir($handle);
  120 + return @rmdir($dirName) ;
  121 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +return [
  11 + // 默认磁盘
  12 + 'default' => env('filesystem.driver', 'public'),
  13 + // 磁盘列表
  14 + 'disks' => [
  15 + 'local' => [
  16 + 'type' => 'local',
  17 + 'root' => app()->getRuntimePath() . 'storage',
  18 + ],
  19 + 'public' => [
  20 + // 磁盘类型
  21 + 'type' => 'local',
  22 + // 磁盘路径
  23 + 'root' => app()->getRootPath() . 'public/storage',
  24 + // 磁盘路径对应的外部URL路径
  25 + 'url' => '/storage',
  26 + // 可见性
  27 + 'visibility' => 'public',
  28 + ],
  29 + // 更多的磁盘配置信息
  30 + ],
  31 +];
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +// +----------------------------------------------------------------------
  11 +// | 路由设置
  12 +// +----------------------------------------------------------------------
  13 +
  14 +return [
  15 + // pathinfo分隔符
  16 + 'pathinfo_depr' => '/',
  17 + // URL伪静态后缀
  18 + 'url_html_suffix' => 'html',
  19 + // URL普通方式参数 用于自动生成
  20 + 'url_common_param' => true,
  21 + // 是否开启路由延迟解析
  22 + 'url_lazy_route' => false,
  23 + // 是否强制使用路由
  24 + 'url_route_must' => false,
  25 + // 合并路由规则
  26 + 'route_rule_merge' => false,
  27 + // 路由是否完全匹配
  28 + 'route_complete_match' => false,
  29 + // 访问控制器层名称
  30 + 'controller_layer' => 'controller',
  31 + // 空控制器名
  32 + 'empty_controller' => 'Error',
  33 + // 是否使用控制器后缀
  34 + 'controller_suffix' => false,
  35 + // 默认的路由变量规则
  36 + 'default_route_pattern' => '[\w\.]+',
  37 + // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
  38 + 'request_cache_key' => false,
  39 + // 请求缓存有效期
  40 + 'request_cache_expire' => null,
  41 + // 全局请求缓存排除规则
  42 + 'request_cache_except' => [],
  43 + // 默认控制器名
  44 + 'default_controller' => 'Index',
  45 + // 默认操作名
  46 + 'default_action' => 'index',
  47 + // 操作方法后缀
  48 + 'action_suffix' => '',
  49 + // 默认JSONP格式返回的处理方法
  50 + 'default_jsonp_handler' => 'jsonpReturn',
  51 + // 默认JSONP处理方法
  52 + 'var_jsonp_handler' => 'callback',
  53 + // 'middleware' => [
  54 + // // app\base\middleware\check::class,
  55 + // ],
  56 +];
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller;
  11 +
  12 +use app\BaseController;
  13 +use think\facade\Db;
  14 +use think\Request;
  15 +use think\facade\Session;
  16 +use app\base\model\admin\system\SmsModel;
  17 +use app\kt_agent\model\admin\agent\ManageModel;
  18 +use app\base\model\BaseModel;
  19 +use think\facade\Cache;
  20 +use think\facade\Log;
  21 +
  22 +class BaseAdmin extends BaseController
  23 +{
  24 + protected $req;
  25 + protected $admin;
  26 + protected $uid;
  27 + protected $token;
  28 + protected $host;
  29 + protected $appName;
  30 + protected $Jssdk;
  31 +
  32 + public function __construct(Request $request){
  33 + // $url = strtolower($request->controller().'/'.$request->action());
  34 + if(Session::has('uid')) Session::delete('uid');
  35 + $this->req = $request;
  36 + $this->host = $request->host();
  37 + $this->token = $this->req->header('UserToken');
  38 + $this->admin = Db::table('kt_base_agent')->where([['agency_token', '=', $this->token], ['expire_time', '>',time()]])->find();
  39 + // var_dump(time());
  40 + // var_dump($this->admin);die;
  41 + if($this->admin){
  42 + $this->uid = $this->admin['id'];
  43 + Session::set('uid',$this->admin['id']);
  44 + }
  45 + // var_dump(request()->file()); die; // $this->Jssdk = \Wechat\Loader::get('Script',config('app.webchat'));
  46 +
  47 +
  48 + }
  49 +
  50 +
  51 + /**
  52 + * 发送短信验证码
  53 + * @return \think\Response
  54 + */
  55 + public function sendCode()
  56 + {
  57 + $phone = $this->req->post('phone');
  58 + if(!preg_match("/^1[3456789]\d{9}$/", $phone)) return error('手机号格式不正确');
  59 + $data = [
  60 + 'phone' => $phone,
  61 + 'bh' => '001', //验证码模板
  62 + 'param' => ['code'=>SmsModel::getCode()]
  63 + ];
  64 + $uid = SmsModel::getAdminId();
  65 + $res = SmsModel::sendSms($data,$uid);
  66 + if($res != 'ok') return error('发送失败');
  67 + return success('发送成功');
  68 + }
  69 +
  70 + /**
  71 + * 获取前端路由配置
  72 + */
  73 + public function getAdminRoutes(){
  74 + $adminRoutes = include app_path()."adminroutes.php";
  75 + $show = $this->req->param('show',0);
  76 + $agent = $this->admin;
  77 + if($agent['isadmin'] || $show==1){
  78 + return success('OK',$adminRoutes);
  79 + }
  80 + $auths = ManageModel::authInfo($agent['level'])['auths']??[];//获取代理权限
  81 + $noAuths = ['/market/index','/market/edit','/market/classification','/kt/config'];//代理不能有的权限
  82 + $auths = array_diff($auths,$noAuths);
  83 + $newRoutes = [];
  84 + foreach ($adminRoutes as $value) {
  85 + if($value['path'] == '/index'){
  86 + $newRoutes[] = $value;
  87 + continue;
  88 + }
  89 + $children1 = [];
  90 + if($value['children']){
  91 + foreach ($value['children'] as $cValue1) {
  92 + $children2 = [];
  93 + if($cValue1['children']){
  94 + foreach ($cValue1['children'] as $cValue2) {
  95 + if(in_array($cValue2['path'], $auths)){
  96 + $children2[] = $cValue2;
  97 + }
  98 + }
  99 + }
  100 + if($children2){
  101 + $cValue1['path'] = reset($children2)['path'];
  102 + $cValue1['children'] = $children2;
  103 + $children1[] = $cValue1;
  104 + }
  105 + }
  106 + }
  107 + if($children1){
  108 + $value['path'] = reset($children1)['path'];
  109 + $value['children'] = $children1;
  110 + $newRoutes[] = $value;
  111 + }
  112 + }
  113 + return success('OK',$newRoutes);
  114 + }
  115 +
  116 + /**
  117 + * 清理缓存
  118 + * @return \think\Response
  119 + */
  120 + public function clearCache()
  121 + {
  122 + $isadmin = BaseModel::isAdmin($this->uid);
  123 + if(!$isadmin) return error('该账户不是管理员');
  124 + Log::clear();
  125 + $this->logClear();
  126 + Cache::clear();
  127 + return success('清理成功');
  128 + }
  129 + /**
  130 + * 删除日志
  131 + * @return \think\Response
  132 + */
  133 + private function logClear(){
  134 + $white = [".","..","storage"];
  135 + $runtimeDir = root_path().'runtime';
  136 + $dirs = scandir($runtimeDir);
  137 + foreach ($dirs as $dir) {
  138 + if(in_array($dir, $white) || !is_dir(root_path().'runtime/'.$dir)) continue;
  139 + $this->delDir(root_path().'runtime/'.$dir);
  140 + }
  141 + return 'ok';
  142 + }
  143 + /**
  144 + *递归删除文件夹
  145 + * @return \think\Response
  146 + */
  147 + private function delDir($path){
  148 + if (!is_dir($path)) {
  149 + return false;
  150 + }
  151 + $content = scandir($path);
  152 + foreach ($content as $v) {
  153 + if ('.' == $v || '..' == $v) {
  154 + continue;
  155 + }
  156 + $item = $path . '/' . $v;
  157 + if (is_file($item)) {
  158 + unlink($item);
  159 + continue;
  160 + }
  161 + $this->delDir($item);
  162 + }
  163 + return rmdir($path);
  164 + }
  165 +
  166 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller;
  11 +
  12 +use app\BaseController;
  13 +use think\facade\Db;
  14 +use think\Request;
  15 +use app\base\model\BaseModel;
  16 +use think\facade\Session;
  17 +
  18 +class BaseUser extends BaseController
  19 +{
  20 + protected $req;
  21 + protected $user;
  22 + protected $wid;
  23 + protected $token;
  24 +
  25 +
  26 + public function __construct(Request $request){
  27 + // $url = strtolower($request->controller().'/'.$request->action());
  28 + $this->req = $request;
  29 + $this->host = $request->host();
  30 + $url = $request->url();
  31 + $this->token = $this->req->header('UserToken');
  32 + $this->user = Db::table('kt_base_user')->where([['token', '=', $this->token], ['expire_time', '>',time()]])->find();
  33 + // var_dump($this->user);
  34 + if($this->user){
  35 + $this->wid = $this->user['id'];
  36 + Session::set('wid',$this->user['id']);
  37 + Session::set('uid',$this->user['agid']);
  38 + }
  39 + }
  40 +
  41 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +declare (strict_types = 1);
  11 +
  12 +namespace app\base\controller;
  13 +use app\BaseController;
  14 +
  15 +class Index extends BaseController
  16 +{
  17 + public function index()
  18 + {
  19 + $domain = request()->domain();
  20 + return redirect($domain.'/app/base');
  21 + }
  22 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\BaseController;
  15 +use app\base\model\admin\system\KtModel;
  16 +use PclZip;
  17 +use think\facade\Log;
  18 +
  19 +/**
  20 +* 插件安装更新
  21 +*/
  22 +class AppInstall extends BaseController
  23 +{
  24 + public function index()
  25 + {
  26 + $orderbh = request()->get('orderbh');
  27 + $operation = request()->get('operation');
  28 + $uid = KtModel::getAdminId();
  29 + $config = Db::table('kt_base_ktconfig')->where('uid',$uid)->find();
  30 + if(!$config){
  31 + echo '配置错误';
  32 + exit;
  33 + }
  34 + $params = [
  35 + 'key' => $config['key'],
  36 + 'secret' => $config['secret'],
  37 + 'orderbh' => $orderbh,
  38 + ];
  39 + $detail = KtModel::getModuleDetailApi($params);
  40 + if(!$detail || !isset($detail['status'])){
  41 + echo '未知错误';
  42 + exit;
  43 + }
  44 + if($detail['status'] != 'success'){
  45 + echo $detail['msg'];
  46 + exit;
  47 + }
  48 +
  49 + $pulgin = $detail['data'];
  50 + $module = Db::table('kt_base_market_app')->where('code',$pulgin['name'])->find();
  51 + if($module && $operation == "uninstall"){
  52 + $res = Db::table('kt_base_market_app')->where('code',$pulgin['name'])->delete();
  53 + echo 'success';
  54 + exit;
  55 + }
  56 + $data = [];
  57 + if(!$module){
  58 + $data['create_time'] = date("Y-m-d H:i:s");
  59 + $operation = 'install';
  60 + }else{
  61 + $data['id'] = $module['id'];
  62 + if(!$module['version']){
  63 + $operation = 'install';
  64 + }
  65 + if($operation == 'upgrade' && $module['version'] == $pulgin['version']){
  66 + echo '已更新到最新版本';
  67 + exit;
  68 + }
  69 + }
  70 +
  71 + $data['version'] = $pulgin['version'];
  72 + $data['orderbh'] = $orderbh;
  73 + $data['has_applets'] = $pulgin['has_applets'];
  74 + $data['expire_date'] = $pulgin['expire_date'];
  75 +
  76 + $params = [
  77 + 'key' => $config['key'],
  78 + 'secret' => $config['secret'],
  79 + 'orderbh' => $orderbh,
  80 + ];
  81 + $downPlugin = KtModel::downModuleApi($params);
  82 + if($downPlugin['status'] != 'success'){
  83 + echo $downPlugin['msg'];
  84 + exit;
  85 + }
  86 + //资源文件名
  87 + $file_name = $downPlugin['data']['filename'];
  88 + $resource = $downPlugin['data']['resource'];
  89 + $path = root_path().'public/static/temp/module/';
  90 + is_dir($path) or mkdir($path, 0777, true);
  91 + $file_path = $path.'/'.$file_name;
  92 + $res = file_put_contents($file_path, base64_decode($resource));
  93 + $zipName = $file_name;
  94 + if(!file_exists($file_path)) exit('写入失败');
  95 + $zipArc = new PclZip($file_path);
  96 + //插件目录
  97 + // $nameIndex = $zipArc->getNameIndex(0);
  98 + // $zipArc->close();
  99 + // $nameIndexArr = explode('/', $nameIndex);
  100 + // $name = $nameIndexArr[0];
  101 +
  102 + $nameIndex = $zipArc->listContent();
  103 + $nameIndexArr = explode('/', $nameIndex[0]['filename']);
  104 + $name = $nameIndexArr[0];
  105 +
  106 + try {
  107 + $re = $zipArc->extract(PCLZIP_OPT_PATH, root_path().'app', PCLZIP_OPT_REPLACE_NEWER);
  108 + if (!$re){echo '解压失败';exit;}
  109 + } catch (\Exception $e) {
  110 + echo '解压失败';exit;
  111 + }
  112 +
  113 +
  114 + //public目录移动
  115 + $appPublicPath = root_path().'app'.'/'.$name.'/public';
  116 + if(file_exists($appPublicPath)){
  117 + if(file_exists($appPublicPath.'/static/'.$name)){
  118 + if(file_exists(root_path().'public/static/'.$name)){
  119 + clear_dir(root_path().'public/static/'.$name);
  120 + }
  121 + if(file_exists(root_path().'public/static/'.$name)){
  122 + echo '请检查前端目录 public/static权限';exit;
  123 + }
  124 + rename($appPublicPath.'/static/'.$name,root_path().'public/static/'.$name);
  125 + }
  126 + if($name == 'gptcms'){
  127 + if(file_exists($appPublicPath.'/app/kt_ai')){
  128 + if(file_exists(root_path().'public/app/kt_ai')){
  129 + clear_dir(root_path().'public/app/kt_ai');
  130 + }
  131 + if(file_exists(root_path().'public/app/kt_ai')){
  132 + echo '请检查前端文件public/app权限';exit;
  133 + }
  134 + rename($appPublicPath.'/app/kt_ai',root_path().'public/app/kt_ai');
  135 + }
  136 + }else{
  137 + if(file_exists($appPublicPath.'/app/'.$name)){
  138 + if(file_exists(root_path().'public/app/'.$name)){
  139 + clear_dir(root_path().'public/app/'.$name);
  140 + }
  141 + if(file_exists(root_path().'public/app/'.$name)){
  142 + echo '请检查前端文件public/app权限';exit;
  143 + }
  144 + rename($appPublicPath.'/app/'.$name,root_path().'public/app/'.$name);
  145 + }
  146 + }
  147 + }
  148 +
  149 + $xmlfilepath = root_path().'app/'.$name.'/mainfest.xml';
  150 + if(!file_exists($xmlfilepath)) $xmlfilepath = root_path().'app/'.$name.'/manifest.xml';
  151 +
  152 + $xml = simplexml_load_file($xmlfilepath,'SimpleXMLElement', LIBXML_NOCDATA);
  153 +
  154 + $xml_arr = json_decode(json_encode($xml), 1);
  155 + $data['user_link'] = $xml_arr['application']['userindex'] ?? '';
  156 + $data['admin_link'] = $xml_arr['application']['adminindex'] ?? '';
  157 + $data['target'] = $xml_arr['application']['target'] ?? 2;
  158 + $data['describe'] = $xml_arr['application']['describe'] ?? '';
  159 + $data['app_type'] = $xml_arr['application']['type'] ?? 1;
  160 + $data['author'] = $xml_arr['application']['author'] ?? '';
  161 +
  162 + if($data['app_type'] == 2){
  163 + $nameArr = explode('_', $xmlArr['application']['code']);
  164 + if($data['app_type']=2 && in_array('plugin', $nameArr)){
  165 + $key = array_keys($nameArr,'plugin');
  166 + $panmeArr = array_slice($nameArr, 0,$key);
  167 + $pname = implode('_', $panmeArr);
  168 + $data['pid'] = Db::table("kt_base_market_app")->where(["code"=>$pname])->value('id') ?: 0;
  169 + }
  170 + }
  171 + $sqla = '';
  172 + $upgradePath = root_path().'/app/'.$name.'/upgrade';
  173 + if($operation == 'install'){
  174 + $data['code'] = $xml_arr['application']['code'];
  175 + $data['name'] = $xml_arr['application']['name'];
  176 + $data['logo'] = $xml_arr['application']['logo'];
  177 + if(is_dir($upgradePath)){
  178 + $versionDirs = scandir($upgradePath);
  179 + sort($versionDirs);
  180 + if($versionDirs){
  181 + foreach ($versionDirs as $versionDir) {
  182 + if($versionDir == "." || $versionDir == ".." ) continue;
  183 + if(!is_dir($upgradePath.'/'.$versionDir)) continue;
  184 + $sqla = '';
  185 + if(file_exists($upgradePath.'/'.$versionDir.'/up.sql')){
  186 + $sqla = file_get_contents($upgradePath.'/'.$versionDir.'/up.sql');
  187 + // $sqlArr = include($upgradePath.'/'.$versionDir.'/up.sql');
  188 + // foreach ((array)$sqlArr as $val) {
  189 + // $sqla .= $val;
  190 + // }
  191 + }
  192 + if($sqla){
  193 + try{
  194 + $resRunSql = $this->updateRunSql($sqla);
  195 + if($resRunSql) {
  196 + // echo "版本:".$versionDir." sql:".$resRunSql['msg'];
  197 + // exit;
  198 + }else{
  199 + Log::error($resRunSql);
  200 + }
  201 +
  202 + }catch(Exception $r){
  203 + Log::error($r);
  204 + // \Log::error('sql执行错误:' . $resRunSql['msg']);
  205 + // echo "版本:".$versionDir." sql:".$resRunSql['msg'];
  206 + // exit;
  207 + }
  208 + }
  209 +
  210 + $data['version'] = $versionDir;
  211 + }
  212 + }
  213 + }
  214 + }else if($operation == 'upgrade'){
  215 + if(is_dir($upgradePath)){
  216 + $versionDirs = scandir($upgradePath);
  217 + foreach ($versionDirs as $key => $value) {
  218 + if($value == "." || $value == ".." ) unset($versionDirs[$key]);
  219 + }
  220 + sort($versionDirs);
  221 + if($versionDirs){
  222 + // arsort($versionDirs);
  223 + $versionDirKey = array_keys($versionDirs,$module['version'])[0];
  224 + for ($i=$versionDirKey + 1; $i < count($versionDirs); $i++) {
  225 + if(!is_dir($upgradePath.'/'.$versionDirs[$i])) continue;
  226 + $sqla = '';
  227 + if(file_exists($upgradePath.'/'.$versionDirs[$i].'/up.sql')){
  228 + $sqla = file_get_contents($upgradePath.'/'.$versionDirs[$i].'/up.sql');
  229 + // $sqlArr = include($upgradePath.'/'.$versionDirs[$i].'/up.sql');
  230 + // foreach ((array)$sqlArr as $k => $val) {
  231 + // $sqla .= $val;
  232 + // }
  233 + }
  234 + if($sqla){
  235 + try{
  236 + $resRunSql = $this->updateRunSql($sqla);
  237 + if($resRunSql) {
  238 + // echo "版本:".$versionDirs[$i]." sql:".$resRunSql['msg'];
  239 + // exit;
  240 + }else{
  241 + Log::error($resRunSql);
  242 + }
  243 + }catch(Exception $r){
  244 + Log::error($resRunSql);
  245 + // echo "版本:".$versionDirs[$i]." sql:".$resRunSql['msg'];
  246 + // exit;
  247 + }
  248 + }
  249 + $data['version'] = $versionDirs[$i];
  250 + }
  251 + }
  252 + }
  253 + }
  254 + $data['install_type'] = 2;
  255 + $data['uid'] = KtModel::getAdminId();
  256 + // $data['can_update'] = 0;
  257 + Db::table('kt_base_market_app')->save($data);
  258 + unlink($file_path);
  259 + echo 'success';
  260 + exit;
  261 + }
  262 +
  263 + private function updateRunSql($content){
  264 + // error_reporting(0);
  265 + //遍历执行sql语句
  266 + //去除空行和注释
  267 + $content=removeBom($content);//自动去除bom头
  268 + // $content = preg_replace("/[\/\*][\s\S\r\n]*[\*\/]/", '', $content);
  269 + // $content = preg_replace("/[--]+(.+)(\r\n)+/", '', $content);
  270 + $content = preg_replace("/\/\*[\s\S\r\n]*\*\//", '', $content);
  271 + $content = preg_replace("/--+(.+)(\r\n)+/", '', $content);
  272 + $sqlArr = preg_split("/;[\r\n]*/", $content);
  273 + $error_message = '';
  274 + foreach ($sqlArr as $v) {
  275 + $v = str_replace( "\r\n",' ',$v);
  276 + if (empty($v)) continue;
  277 + try {
  278 + Db::execute($v);
  279 + } catch (\Exception $e) {
  280 + // $error_message .= $e->getMessage() . ' ';
  281 + // \Log::error('sql执行错误:' . $e->getMessage());
  282 + $error_message = $v;
  283 + }
  284 + }
  285 + // if ($error_message) {
  286 + // return ['status'=>'error','msg'=> $error_message];
  287 + // } else {
  288 + // return ['status'=>'success','msg'=>'执行成功'];
  289 + // }
  290 + return $error_message;
  291 + }
  292 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\BaseController;
  15 +use app\base\model\admin\system\KtModel;
  16 +use PclZip;
  17 +
  18 +/**
  19 +* 系统更新
  20 +*/
  21 +class BaseInstall extends BaseController
  22 +{
  23 + private $param=[];
  24 + public function index()
  25 + {
  26 + $u = $_SERVER['HTTP_HOST'];
  27 + $a = 'download';
  28 + $b = "all"; //每次请求安装全部版本,参数填 all, 每次安装一个版本 one
  29 +
  30 + //下载当前已安装的下一版本
  31 +
  32 + $param = [
  33 + 'a' => $a,
  34 + 'u' => $u,
  35 + ];
  36 +
  37 + //获取key
  38 + $uid = KtModel::getAdminId();
  39 + $config = Db::table('kt_base_ktconfig')->where('uid',$uid)->find();
  40 + if(!$config || !$config['key'] || !$config['secret']) exit('config error');
  41 + $param['webkey'] = $config['key'];
  42 + $param['sign'] = KtModel::makeSignApi($param,$config['secret']);
  43 + $this->param = $param;
  44 + $url = 'https://www.kt8.cn/cloud/apiauthsys/index?'.http_build_query($param);
  45 + if($b == 'one'){
  46 + $res = $this->insta($url,$param);
  47 + exit($res);
  48 + }else if($b == 'all'){
  49 + $msg = '';
  50 + while (1) {
  51 + $res = $this->insta($url);
  52 + if($res!="success"){
  53 + $msg = $res;
  54 + break;
  55 + }
  56 + }
  57 + if($msg=="newest"){
  58 + exit('success');
  59 + }else{
  60 + exit($msg);
  61 + }
  62 +
  63 + }
  64 + }
  65 +
  66 + private function insta($url)
  67 + {
  68 + //如果存在sql文件,则删除
  69 + $sqlPath = root_path() . 'update.sql';
  70 + if (file_exists($sqlPath)){
  71 + unlink($sqlPath);
  72 + }
  73 + $ch = curl_init();
  74 + curl_setopt($ch, CURLOPT_URL, $url);
  75 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  76 + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  77 + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  78 + $output = curl_exec($ch);
  79 + curl_close($ch);
  80 + $res = json_decode($output,1);
  81 + if($res && $res['status'] == 'success'){
  82 + $resource = $res['data']['resource'];
  83 + $file_name = $res['data']['filename'];
  84 +
  85 + $path = root_path().'public/temp/module/';
  86 + is_dir($path) or mkdir($path, 0777, true);
  87 +
  88 + $file_path = $path.'/'.$file_name;
  89 + file_put_contents($file_path, base64_decode($resource));
  90 + KtModel::makelog($this->param,$file_name);
  91 + // $zipArc = new \ZipArchive();
  92 + $zipArc = new PclZip($file_path);
  93 + // if (!$zipArc->open($file_path)) exit('更新失败');
  94 + // if (!$zipArc->extractTo(root_path())) {
  95 + // $zipArc->close();
  96 + // exit('更新失败');
  97 + // }
  98 + try {
  99 + $re = $zipArc->extract(PCLZIP_OPT_PATH, root_path(), PCLZIP_OPT_REPLACE_NEWER);
  100 + // if (!$re) return $zipArc->error_string;
  101 + if (!$re) return '解压失败';
  102 +
  103 + } catch (\Exception $e) {
  104 + // \Log::error('插件解压失败,错误信息:' . $e->getMessage());
  105 + return '解压失败';
  106 + }
  107 + unlink($file_path);
  108 + //去项目根目录找update.sql文件,执行sql
  109 +
  110 + if (file_exists($sqlPath)) {
  111 + $sqlContent = file_get_contents($sqlPath);
  112 + $sqlArr=preg_split("/;[\r\n]+/", $sqlContent);
  113 + foreach($sqlArr as $v){
  114 + Db::execute($v);
  115 + }
  116 + unlink($sqlPath);
  117 + }
  118 + return 'success';
  119 + }
  120 + return $res['msg'];
  121 + }
  122 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin;
  11 +use think\facade\Db;
  12 +use app\base\controller\BaseAdmin;
  13 +use Ramsey\Uuid\Uuid;
  14 +use think\facade\Session;
  15 +
  16 +class Login extends BaseAdmin
  17 +{
  18 + /*
  19 + * 登录
  20 + */
  21 + public function index()
  22 + {
  23 + $username = $this->req->param('username');
  24 + $password = $this->req->param('password');
  25 + if(!$username) return error('缺少参数username');
  26 + if(!$password) return error('缺少参数password');
  27 + $where = [
  28 + ['un', '=', $username],
  29 + ['telephone', '=', $username]
  30 + ];
  31 + $userAgency = Db::table('kt_base_agent')->whereOr($where)->find();
  32 + if(!$userAgency) return error('账户不存在');
  33 + if($userAgency['pwd'] != md5($password) && $userAgency['pwd'] != ktEncrypt($password)) return error('帐号或密码错误');
  34 + if($userAgency['isstop'] != 1 ) return error('账户已经被停用或作废');
  35 + $token = $userAgency['agency_token'] && $userAgency['expire_time'] > time() ? $userAgency['agency_token'] : Uuid::uuid1();
  36 + Db::table('kt_base_agent')->where('id',$userAgency['id'])->update(['agency_token'=>"{$token}",'expire_time'=> time() + (7*24*3600),'lasttime'=>date("Y-m-d H:i:s") ]);
  37 + Db::table('kt_base_loginlog')->insert([
  38 + 'admin' => 1,
  39 + 'wid' => $userAgency['id'],
  40 + 'uip' => $this->req->ip(),
  41 + 'create_time' => date("Y-m-d H:i:s")
  42 + ]);
  43 + return success('登录成功',['token'=>$token]);
  44 + }
  45 +
  46 + /*
  47 + * 修改密码
  48 + */
  49 + public function forgotPassword()
  50 + {
  51 + $uid = Session::get('uid');
  52 + $agent = Db::table('kt_base_agent')->find($uid);
  53 + $password = $this->req->post('password');
  54 + if($agent['pwd'] != md5($password) && $agent['pwd'] != ktEncrypt($password)) return error('当前密码错误');
  55 + $new_password = $this->req->post('new_password');
  56 + $confirm_password = $this->req->post('confirm_password');
  57 + if(!$new_password || !$confirm_password) return error('请输入新密码');
  58 + if($new_password != $confirm_password) return error('两次输入的新密码不一致');
  59 + if($agent['pwd'] == ktEncrypt($new_password)) return error('新旧密码一致');
  60 + $res = Db::table('kt_base_agent')->where('id',$uid)->update([
  61 + "pwd" => ktEncrypt($new_password),
  62 + ]);
  63 + if($res) return success('修改成功');
  64 + return error('修改失败');
  65 + }
  66 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\BaseController;
  15 +use think\facade\Queue;
  16 +
  17 +/**
  18 + * 统一定时任务类
  19 + */
  20 +class Task extends BaseController
  21 +{
  22 + /*
  23 + *入口
  24 + */
  25 + public function index()
  26 + {
  27 + $tasks = Db::table('kt_base_timed_task')->where('status',1)->select();
  28 + if($tasks->isEmpty()) return 'ok';
  29 + foreach ($tasks as $task) {
  30 + if($task['last_time'] + $task['interval_time'] > time()){
  31 + $jobHandlerClassName = $task['class_ame'];
  32 + $isPushed = Queue::push($jobHandlerClassName, array('time'=>time()), 'timed_task');
  33 + Db::table('kt_base_timed_task')->where('id',$task['id']->update([
  34 + 'last_time' => time(),
  35 + ]);
  36 + }
  37 + }
  38 + return success('执行成功');
  39 + }
  40 +
  41 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\app;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\base\controller\BaseAdmin;
  15 +use app\base\model\admin\app\AppManageModel;
  16 +
  17 +class AppManage extends BaseAdmin
  18 +{
  19 + /**
  20 + * 主应用
  21 + */
  22 + public function mainapp()
  23 + {
  24 + $uid = Session::get('uid');
  25 + // return error(base_path());
  26 + $res = AppManageModel::mainapp($this->req);
  27 + return success('应用列表',$res);
  28 + }
  29 +
  30 + /**
  31 + * 子应用(主应用插件)
  32 + */
  33 + public function plugin()
  34 + {
  35 + $uid = Session::get('uid');
  36 + // return error(base_path());
  37 + $res = AppManageModel::plugin($this->req);
  38 + return success('应用列表',$res);
  39 + }
  40 +
  41 + /**
  42 + * 工具应用
  43 + */
  44 + public function tools()
  45 + {
  46 + $uid = Session::get('uid');
  47 + // return error(base_path());
  48 + $res = AppManageModel::tools($this->req);
  49 + return success('应用列表',$res);
  50 + }
  51 +
  52 + /**
  53 + * 模板应用
  54 + */
  55 + public function template()
  56 + {
  57 + $uid = Session::get('uid');
  58 + // return error(base_path());
  59 + $res = AppManageModel::template($this->req);
  60 + return success('模板应用',$res);
  61 + }
  62 +
  63 + /**
  64 + * 使用模板
  65 + */
  66 + public function useTemplate()
  67 + {
  68 + $code = $this->req->param("code");
  69 + if(!$code) return error("应用编码不可为空");
  70 + $res = AppManageModel::useTemplate($code);
  71 + return success('设置成功',$res);
  72 + }
  73 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\market;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\base\controller\BaseAdmin;
  15 +use app\base\model\admin\market\AppManageModel;
  16 +
  17 +class AppManage extends BaseAdmin
  18 +{
  19 + public function index()
  20 + {
  21 + $uid = Session::get('uid');
  22 + // return error(base_path());
  23 + $res = AppManageModel::list($this->req);
  24 + return success('应用列表',$res);
  25 + }
  26 + /**
  27 + * 删除
  28 + */
  29 + public function delete()
  30 + {
  31 + $uid = Session::get('uid');
  32 + // return error(base_path());
  33 + return AppManageModel::delete($this->req);
  34 + }
  35 +
  36 + /**
  37 + * 应用信息
  38 + */
  39 + public function appInfo()
  40 + {
  41 + $code = $this->req->param("code");
  42 + if(!$code) return error("应用编码不可为空");
  43 + $info = AppManageModel::appInfo($code);
  44 + return success("操作成功",$info);
  45 + }
  46 +
  47 + /**
  48 + * 设置应用信息
  49 + */
  50 + public function setApp()
  51 + {
  52 + $data = [];
  53 + $data['code'] = $this->req->param("code");
  54 + $data['name'] = $this->req->param("name");
  55 + $data['logo'] = $this->req->param("logo");
  56 + $data['sort'] = $this->req->param("sort",0);
  57 + $data['try_days'] = $this->req->param("try_days",7);
  58 + $data['scene'] = $this->req->param("scene");
  59 + $data['type'] = $this->req->param("type");
  60 + $data['describe'] = $this->req->param("describe");
  61 + $data['shelves'] = $this->req->param("shelves",0);
  62 + $data['label'] = $this->req->param("label",[]);
  63 + $data['specs'] = $this->req->param("specs",[]);
  64 + if(!$data['code']) return error("应用编码不可为空");
  65 + if(!$data['name']) return error("应用名称不可为空");
  66 + if(!$data['type']) return error("类别不可为空");
  67 + if(!$data['specs']) return error("规格不可为空");
  68 + $label = $data['label'];
  69 + if(count($label)>3) return error('最多三个标签');
  70 + foreach ($label as $l) {
  71 + if(mb_strlen($l) > 4) return error('标签不合法,最多4个字');
  72 + }
  73 + AppManageModel::setApp($data);
  74 + return success("修改成功");
  75 + }
  76 +
  77 + /**
  78 + * 分类列表
  79 + */
  80 + public function types()
  81 + {
  82 + $page = $this->req->param('page',1);
  83 + $size = $this->req->param('size',10);
  84 + $types = AppManageModel::types($page,$size);
  85 + return success('操作成功',$types);
  86 + }
  87 +
  88 + /**
  89 + * 分类信息
  90 + */
  91 + public function typeInfo(){
  92 + $id = $this->req->param("id");
  93 + if(!$id) return error("分类id不可为空");
  94 + $info = AppManageModel::typeInfo($id);
  95 + return success("操作成功",$info);
  96 + }
  97 +
  98 + /**
  99 + * 添加分类
  100 + */
  101 + public function addType()
  102 + {
  103 + $data = [];
  104 + $data['name'] = $this->req->param("name");
  105 + $data['sort'] = $this->req->param("sort",0);
  106 + $data['level'] = $this->req->param("level",1);
  107 + $data['pid'] = $this->req->param("pid",0);
  108 + if(!$data['name']) return error("分类名称不可为空");
  109 + $res = AppManageModel::addType($data);
  110 + if($res != 'ok') return error($res);
  111 + return success('操作成功');
  112 + }
  113 +
  114 + /**
  115 + * 编辑分类
  116 + */
  117 + public function editType()
  118 + {
  119 + $data = [];
  120 + $id = $this->req->param("id");
  121 + $data['name'] = $this->req->param("name");
  122 + $data['sort'] = $this->req->param("sort",0);
  123 + $data['level'] = $this->req->param("level",1);
  124 + $data['pid'] = $this->req->param("pid",0);
  125 + if(!$id) return error("分类id不可为空");
  126 + if(!$data['name']) return error("分类名称不可为空");
  127 + AppManageModel::editType($id,$data);
  128 + return success('操作成功');
  129 + }
  130 +
  131 + /**
  132 + * 删除分类
  133 + */
  134 + public function delType()
  135 + {
  136 + $id = $this->req->param("id");
  137 + if(!$id) return error("分类id不可为空");
  138 + $res = AppManageModel::delType($id);
  139 + if($res['status'] == 'error') return error($res['msg']);
  140 + return success('操作成功');
  141 + }
  142 +
  143 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\market;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\base\controller\BaseAdmin;
  15 +use app\base\model\admin\market\OpenuseModel;
  16 +
  17 +class Openuse extends BaseAdmin
  18 +{
  19 + /*
  20 + * 已购应用列表
  21 + */
  22 + public function allApp()
  23 + {
  24 + return OpenuseModel::allApp($this->req);
  25 + }
  26 + /*
  27 + * 已购应用列表
  28 + */
  29 + public function list()
  30 + {
  31 + return OpenuseModel::list($this->req);
  32 + }
  33 + /*
  34 + * 已购应用列表
  35 + */
  36 + public function updateStatus()
  37 + {
  38 + return OpenuseModel::updateStatus($this->req);
  39 + }
  40 + /*
  41 + * 获取代理折扣
  42 + */
  43 + public function discount()
  44 + {
  45 + return OpenuseModel::discount();
  46 + }
  47 + /*
  48 + * 续费和购买
  49 + */
  50 + public function buy()
  51 + {
  52 + return OpenuseModel::buy($this->req);
  53 + }
  54 + /*
  55 + * 用户订单列表(用户在用户后台购买)
  56 + */
  57 + public function userOrder()
  58 + {
  59 + return OpenuseModel::userOrderList($this->req);
  60 + }
  61 + /*
  62 + * 套餐的开通与购买
  63 + */
  64 + public function setmealBuy()
  65 + {
  66 + return OpenuseModel::setmealBuy($this->req);
  67 + }
  68 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\system;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\base\controller\BaseAdmin;
  15 +use app\base\model\admin\system\KtModel;
  16 +
  17 +class Kt extends BaseAdmin
  18 +{
  19 + /**
  20 + * 狂团配置
  21 + */
  22 + public function ktconfig()
  23 + {
  24 + return KtModel::getKtconfig($this->req);
  25 + }
  26 +
  27 + /**
  28 + * 应用列表
  29 + */
  30 + public function ktapp()
  31 + {
  32 + return KtModel::ktapp($this->req);
  33 + }
  34 + /**
  35 + * 删除应用
  36 + */
  37 + public function delete()
  38 + {
  39 + return KtModel::delete($this->req);
  40 + }
  41 + /**
  42 + * 应用列表
  43 + */
  44 + public function sync()
  45 + {
  46 + return KtModel::sync();
  47 + }
  48 +
  49 + /**
  50 + * 狂团配置
  51 + */
  52 + public function updateKtconfig()
  53 + {
  54 + return KtModel::updateKtconfig($this->req);
  55 + }
  56 + /**
  57 + * 狂团配置
  58 + */
  59 + public function ktinfo()
  60 + {
  61 + return KtModel::ktinfo();
  62 + }
  63 +
  64 + /**
  65 + * 应用商店
  66 + */
  67 + public function appStore()
  68 + {
  69 + $page = $this->req->param('page',1);
  70 + $size = $this->req->param('size',10);
  71 + return KtModel::appStore($page,$size);
  72 + }
  73 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\system;
  11 +use think\facade\Db;
  12 +use Ramsey\Uuid\Uuid;
  13 +use OSS\OssClient;
  14 +use OSS\Core\OssException;
  15 +use think\facade\Filesystem;
  16 +use think\facade\Session;
  17 +use app\base\model\BaseModel;
  18 +use app\base\controller\BaseAdmin;
  19 +use Qcloud\Cos\Client;
  20 +use Qiniu\Auth;
  21 +use Qiniu\Storage\UploadManager;
  22 +
  23 +/**
  24 +* 媒体类
  25 +**/
  26 +class Media extends BaseAdmin
  27 +{
  28 +
  29 + /**
  30 + * oss数据
  31 + * @return \think\Response
  32 + */
  33 + public function info()
  34 + {
  35 + $uid = Session::get('uid');
  36 + $res = BaseModel::storageInfo();
  37 + return success('云存储配置',$res);
  38 + }
  39 +
  40 + /**
  41 + * 云存储服务器配置保存
  42 + * @return \think\Response
  43 + */
  44 + public function save()
  45 + {
  46 + $uid = Session::get('uid');
  47 + $data = [];
  48 + $data = $this->req->post();
  49 + if($data['type'] == 2 && (!$data['oss_id'] || !$data['oss_secret'] || !$data['oss_endpoint'] || !$data['oss_bucket'])) return error('参数错误');
  50 + if($data['type'] == 3 && (!$data['cos_secretId'] || !$data['cos_secretKey'] || !$data['cos_bucket'] || !$data['cos_endpoint'])) return error('参数错误');
  51 + if($data['type'] == 4 && (!$data['kodo_key'] || !$data['kodo_secret'] || !$data['kodo_domain'] || !$data['kodo_bucket'])) return error('参数错误');
  52 + $res = BaseModel::storageUpdate($data);
  53 + if($res != 'ok') return error($res);
  54 + return success('更新成功');
  55 + }
  56 +
  57 + /**
  58 + * 上传文件
  59 + * @return \think\Response
  60 + */
  61 + public function upload()
  62 + {
  63 + $uid = Session::get("uid");
  64 + // 获取表单上传文件
  65 + $file = request()->file('file');
  66 + if(!$file) return error('未检测到上传资源');
  67 + $res = [];
  68 + $storage = BaseModel::getStorageInfo();
  69 + $type = $storage['type'] ?? 1;
  70 + switch ($type) {
  71 + case 1: //本地
  72 + $res = $this->uploadLocal($file);
  73 + break;
  74 + case 2: //阿里云
  75 + $res = $this->uploadOss($storage,$file);
  76 + break;
  77 + case 3: //腾讯云
  78 + $res = $this->uploadCos($storage,$file);
  79 + break;
  80 + case 4: //七牛
  81 + $res = $this->uploadKodo($storage,$file);
  82 + break;
  83 + }
  84 + if($res == 'error') return error('上传失败');
  85 + return success('上传成功',$res);
  86 + }
  87 + /**
  88 + * 上传到Oss
  89 + * @return \think\Response
  90 + */
  91 + public function uploadLocal($file)
  92 + {
  93 + $domain = $this->req->domain();
  94 + // $imgTruePath = $file->getPathname(); //获取临时地址
  95 + $ext = $file->extension(); //获取后缀
  96 + $minType = $file->getMime(); //获取文件类型
  97 + $fileName = $file->getOriginalName(); //获取上传名
  98 + $time = date('Y-m-d');
  99 + $res = Filesystem::putFile( 'upload/base/'.$time, $file, 'uniqid');
  100 + return $domain.'/storage/'.$res;
  101 + }
  102 +
  103 + /**
  104 + * 上传到Oss
  105 + * @return \think\Response
  106 + */
  107 + public function uploadOss($storage,$file)
  108 + {
  109 + $accessKeyId = $storage['oss_id'];
  110 + $accessKeySecret = $storage['oss_secret'];
  111 + $endpoint = $storage['oss_endpoint'];
  112 + $bucket = $storage['oss_bucket'];
  113 + try {
  114 + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
  115 + // 设置Socket层传输数据的超时时间
  116 + $ossClient->setTimeout(3600);
  117 + // 设置建立连接的超时时间,单位秒,默认10秒。
  118 + $ossClient->setConnectTimeout(10);
  119 +
  120 + // $bucketExist = $ossClient->doesBucketExist($bucket); //判断bucket是否存在
  121 + // if (!$bucketExist) {
  122 + // $ossClient->createBucket($bucketName, \OSS\OssClient::OSS_ACL_TYPE_PUBLIC_READ);
  123 + // }
  124 +
  125 + $imgTruePath = $file->getPathname(); //获取临时地址
  126 + $ext = $file->extension(); //获取后缀
  127 + $minType = $file->getMime(); //获取文件类型
  128 + $fileName = $file->getOriginalName();
  129 + $filePath = 'base/'.uniqid('base_').'.'.$ext;
  130 + $uploadOssRes = $ossClient->uploadFile($bucket, $filePath, $imgTruePath);
  131 + $url = $uploadOssRes['info']['url'];
  132 + return $url;
  133 + } catch (OssException $e) {
  134 + print $e->getDetails(); //调试时,打开,输出错误信息
  135 + return 'error';
  136 + }
  137 + }
  138 + /**
  139 + * 上传到Cos
  140 + * @return \think\Response
  141 + */
  142 + public function uploadCos($storage,$file)
  143 + {
  144 + $secretId = $storage['cos_secretId'];
  145 + $secretKey = $storage['cos_secretKey'];
  146 + $endpoint = $storage['cos_endpoint'];
  147 + $bucket = $storage['cos_bucket'];
  148 + $regionArr = explode('.', $endpoint);
  149 + $region = $regionArr[2];
  150 + $cosClient = new Client(
  151 + array(
  152 + 'region' => $region,
  153 + 'schema' => 'https', //协议头部,默认为http
  154 + 'credentials'=> array(
  155 + 'secretId' => $secretId ,
  156 + 'secretKey' => $secretKey)));
  157 + $imgTruePath = $file->getPathname(); //获取临时地址
  158 + $ext = $file->extension(); //获取后缀
  159 + $minType = $file->getMime(); //获取文件类型
  160 + $fileName = $file->getOriginalName();
  161 + $filePath = 'base/'.uniqid('base_').'.'.$ext;
  162 + try {
  163 + $result = $cosClient->putObject(
  164 + array(
  165 + 'Bucket' => $bucket,
  166 + 'Key' => $filePath,
  167 + 'Body' => fopen($imgTruePath, 'rb')
  168 + )
  169 + );
  170 + $url = "https://".$result['Location'];
  171 + return $url;
  172 + }catch (\Exception $e) {
  173 + return 'error';
  174 + }
  175 + }
  176 + /**
  177 + * 上传到kodo 七牛云
  178 + * @return \think\Response
  179 + */
  180 + public function uploadKodo($storage,$file)
  181 + {
  182 + $accessKey = $storage['kodo_key'];
  183 + $secretKey = $storage['kodo_secret'];
  184 + $bucket = $storage['kodo_bucket'];
  185 + $auth = new Auth($accessKey, $secretKey);
  186 + $token = $auth->uploadToken($bucket);
  187 + $imgTruePath = $file->getPathname(); //获取临时地址
  188 + $ext = $file->extension(); //获取后缀
  189 + $minType = $file->getMime(); //获取文件类型
  190 + $fileName = $file->getOriginalName();
  191 + $filePath = 'base/'.uniqid('base_').'.'.$ext;
  192 + $uploadMgr = new UploadManager();
  193 + list($ret, $err) = $uploadMgr->putFile($token, $filePath, $imgTruePath);
  194 + if ($err !== null) {
  195 + return 'error';
  196 + } else {
  197 + return 'http://' . $storage['kodo_domain'] . '/' . $ret['key'];
  198 + }
  199 + }
  200 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\system;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Session;
  14 +use app\base\controller\BaseAdmin;
  15 +use app\base\model\admin\system\SetModel;
  16 +
  17 +/**
  18 + * 接口配置
  19 + */
  20 +class Set extends BaseAdmin
  21 +{
  22 +
  23 + /**
  24 + * Baidu AI配置 获取
  25 + */
  26 + public function BaiduAi()
  27 + {
  28 + return SetModel::BaiduAi();
  29 + }
  30 +
  31 + /**
  32 + * Baidu AI配置 保存
  33 + */
  34 + public function BaiduAiSet()
  35 + {
  36 + return SetModel::BaiduAiSet($this->req);
  37 + }
  38 + /**
  39 + * Aliyun 语音合成配置 获取
  40 + */
  41 + public function Aliyun()
  42 + {
  43 + return SetModel::Aliyun();
  44 + }
  45 +
  46 + /**
  47 + * Aliyun 语音合成配置 保存
  48 + */
  49 + public function AliyunSet()
  50 + {
  51 + return SetModel::AliyunSet($this->req);
  52 + }
  53 +
  54 + /**
  55 + * 腾讯云 语音转合字幕配置 获取
  56 + */
  57 + public function Tencent()
  58 + {
  59 + return SetModel::Tencent();
  60 + }
  61 +
  62 + /**
  63 + * 腾讯云 语音转合字幕配置 保存
  64 + */
  65 + public function TencentSet()
  66 + {
  67 + return SetModel::TencentSet($this->req);
  68 + }
  69 +
  70 + /**
  71 + * GPT配置 获取
  72 + */
  73 + public function Gpt()
  74 + {
  75 + return SetModel::Gpt();
  76 + }
  77 +
  78 + /**
  79 + * GPT配置 保存
  80 + */
  81 + public function GptSet()
  82 + {
  83 + return SetModel::GptSet($this->req);
  84 + }
  85 + /**
  86 + * 内容审核 获取
  87 + */
  88 + public function review()
  89 + {
  90 + return SetModel::review();
  91 + }
  92 +
  93 + /**
  94 + * 提问审核 设置
  95 + */
  96 + public function questionSet()
  97 + {
  98 + return SetModel::questionSet($this->req);
  99 + }
  100 + /**
  101 + * 回复审核 设置
  102 + */
  103 + public function replySet()
  104 + {
  105 + return SetModel::replySet($this->req);
  106 + }
  107 + /**
  108 + * 敏感词库获取
  109 + */
  110 + public function sensitiveLexicon()
  111 + {
  112 + return SetModel::sensitiveLexicon();
  113 + }
  114 + /**
  115 + * 敏感词库保存
  116 + */
  117 + public function sensitiveLexiconSave()
  118 + {
  119 + return SetModel::sensitiveLexiconSave($this->req);
  120 + }
  121 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\system;
  11 +use think\facade\Db;
  12 +use app\base\controller\BaseAdmin;
  13 +use app\base\model\admin\system\BasicModel;
  14 +use Ramsey\Uuid\Uuid;
  15 +use think\facade\Session;
  16 +
  17 +/**
  18 +* 基础配置控制器 Site
  19 +*/
  20 +class Site extends BaseAdmin
  21 +{
  22 + /*
  23 + * 基本设置 拉取数据 初始化
  24 + */
  25 + public function index(){
  26 + $res = BasicModel::getSite();
  27 + return success("获取成功",$res);
  28 + }
  29 +
  30 + /*
  31 + * 修改基础配置
  32 + */
  33 + public function setSite(){
  34 + $domain = $this->req->param("domain");
  35 + if(!$domain) return error("站点域名不可为空");
  36 + $webname = $this->req->param("webname");
  37 + if(!$webname) return error("站点名称不可为空");
  38 + $webtitle = $this->req->param("webtitle");
  39 + $copyright = $this->req->param("copyright");
  40 + $register_check = $this->req->param("registerCheck");
  41 + $registration_audit = $this->req->param("registrationAudit");
  42 + $pc_official = $this->req->param("pcOfficial");
  43 + $debug = $this->req->param("debug",0);
  44 + $addSite = BasicModel::setSite($domain,$webname,$webtitle,$copyright,$register_check,$registration_audit,$pc_official,$debug);
  45 + return success("修改成功",$addSite);
  46 + }
  47 +
  48 + /*
  49 + * 修改logo信息
  50 + */
  51 + public function setLogo(){
  52 + $user_logo = $this->req->param("userLogo");
  53 + $login_logo = $this->req->param("loginLogo");
  54 + $pc_logo = $this->req->param("pcLogo");
  55 + $setLogo = BasicModel::setLogo($user_logo,$login_logo,$pc_logo);
  56 + return success("修改成功",$setLogo);
  57 + }
  58 +
  59 + /*
  60 + * 修改登录背景
  61 + */
  62 + public function setBackground(){
  63 + $login_background_status = $this->req->param("loginBackgroundStatus");
  64 + $login_background = $this->req->param("loginBackground");
  65 + $setBackground = BasicModel::setBackground($login_background,$login_background_status);
  66 + return success("修改成功",$setBackground);
  67 + }
  68 +
  69 + /*
  70 + * 修改其他信息
  71 + */
  72 + public function setAdditional(){
  73 + $kf_code = $this->req->param("kfCode");
  74 + $gzh_code = $this->req->param("gzhCode");
  75 + $company_name = $this->req->param("companyName");
  76 + $company_address = $this->req->param("companyAddress");
  77 + $telephone = $this->req->param("telephone");
  78 + $qq = $this->req->param("qq");
  79 + $record_number = $this->req->param("recordNumber");
  80 + $key_word = $this->req->param("keyWord");
  81 + $describe = $this->req->param("describe");
  82 + $setAdditional = BasicModel::setAdditional($kf_code,$gzh_code,$company_name,$company_address,$telephone,$qq,$record_number,$key_word,$describe);
  83 + return success("修改成功",$setAdditional);
  84 + }
  85 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\system;
  11 +use think\facade\Db;
  12 +use Ramsey\Uuid\Uuid;
  13 +use think\facade\Session;
  14 +use app\base\model\admin\system\SmsModel;
  15 +use app\base\controller\BaseAdmin;
  16 +
  17 +/**
  18 +* 短信
  19 +**/
  20 +class Sms extends BaseAdmin
  21 +{
  22 +
  23 + /**
  24 + * 短信配置
  25 + * @return \think\Response
  26 + */
  27 + public function index()
  28 + {
  29 + $res = SmsModel::SmsInfo();
  30 + return success('短信配置',$res);
  31 + }
  32 +
  33 + /**
  34 + * 短信配置保存
  35 + * @return \think\Response
  36 + */
  37 + public function save()
  38 + {
  39 + $data = [];
  40 + $data = $this->req->post();
  41 + $res = SmsModel::smsUpdate($data);
  42 + if($res != 'ok') return error($res);
  43 + return success('更新成功');
  44 + }
  45 + /**
  46 + * 短信验证码模板配置
  47 + * @return \think\Response
  48 + */
  49 + public function codeTemplateSave()
  50 + {
  51 + $data = [];
  52 + $data = $this->req->post();
  53 + $data['bh'] = '001';
  54 + $res = SmsModel::templateSave($data);
  55 + if($res != 'ok') return error($res);
  56 + return success('更新成功');
  57 + }
  58 + /**
  59 + * 获取短信验证码模板配置
  60 + * @return \think\Response
  61 + */
  62 + public function getCodeTemplate()
  63 + {
  64 + $where = [];
  65 + $where['bh'] = '001';
  66 + $where['uid'] = Session::get('uid');
  67 + $res = SmsModel::getTemplate($where);
  68 + return success('短信模板配置',$res);
  69 + }
  70 + /**
  71 + * 发送短信验证码
  72 + * @return \think\Response
  73 + */
  74 + public function sendCode()
  75 + {
  76 + $phone = $this->req->post('phone');
  77 + if(!preg_match("/^1[3456789]\d{9}$/", $phone)) return error('手机号格式不正确');
  78 + $data = [
  79 + 'phone' => $phone,
  80 + 'bh' => '001', //验证码模板
  81 + 'param' => ['code'=>SmsModel::getCode()]
  82 + ];
  83 + $res = SmsModel::sendSms($data);
  84 + if($res != 'ok') return error('发送失败');
  85 + return success('发送成功');
  86 + }
  87 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\system;
  11 +use think\facade\Db;
  12 +use app\base\controller\BaseAdmin;
  13 +use app\base\model\admin\system\WxpayConfingModel;
  14 +use Ramsey\Uuid\Uuid;
  15 +use think\facade\Session;
  16 +
  17 +/**
  18 +* 微信配置
  19 +*/
  20 +class WxpayConfing extends BaseAdmin{
  21 + /*
  22 + * 配置拉取数据
  23 + */
  24 + public function index(){
  25 + $res = WxpayConfingModel::info();
  26 + $data =[
  27 + 'appid' => isset($res[0]) ? $res[0] : null,
  28 + 'mch_id' => isset($res[1]) ? $res[1] : null,
  29 + 'key' => isset($res[2]) ? $res[2] : null,
  30 + 'appsecret' => isset($res[3]) ? $res[3] : null,
  31 + ];
  32 + return success("获取成功",$data);
  33 + }
  34 +
  35 + /*
  36 + * 添加修改配置
  37 + */
  38 + public function upd(){
  39 + $appid = $this->req->param("appid");
  40 + $mch_id = $this->req->param("mch_id");
  41 + $key = $this->req->param("key");
  42 + $appsecret = $this->req->param("appsecret");
  43 + if(!$appid || !$mch_id || !$key || !$appsecret)return error("缺少参数");
  44 + $res = WxpayConfingModel::upd(["config"=>$appid.",".$mch_id.",".$key.",".$appsecret]);
  45 +
  46 + return success("修改成功",$res);
  47 + }
  48 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\user;
  11 +use think\facade\Db;
  12 +use app\base\controller\BaseAdmin;
  13 +use app\base\model\admin\user\AppPackageModel;
  14 +use think\facade\Session;
  15 +
  16 +class AppPackage extends BaseAdmin
  17 +{
  18 + /**
  19 + * 套餐列表
  20 + */
  21 + public function packageList()
  22 + {
  23 + $uid = Session::get('uid');
  24 + $res = AppPackageModel::packageList();
  25 + return success('套餐列表',$res);
  26 + }
  27 +
  28 + /**
  29 + * 套餐详情
  30 + */
  31 + public function packageInfo()
  32 + {
  33 + $id = $this->req->param("id");
  34 + if(!$id) return error("套餐id不可为空");
  35 + $info = AppPackageModel::packageInfo($id);
  36 + return success("操作成功",$info);
  37 + }
  38 +
  39 + /**
  40 + * 新增套餐
  41 + */
  42 + public function addPackage()
  43 + {
  44 + $data = [];
  45 + $data['name'] = $this->req->param("name");
  46 + $data['specs'] = $this->req->param("specs",[]);
  47 + $data['apps'] = $this->req->param("apps",[]);
  48 + $data['sort'] = $this->req->param("sort",0);
  49 + if(!$data['name']) return error("套餐名称不可为空");
  50 + if(!$data['specs']) return error("套餐规格不可为空");
  51 + if(!$data['apps']) return error("包含应用不可为空");
  52 + $res = AppPackageModel::addPackage($data);
  53 + if($res != 'ok') return error($res);
  54 + return success("添加成功");
  55 + }
  56 +
  57 + /**
  58 + * 编辑套餐
  59 + */
  60 + public function editPackage()
  61 + {
  62 + $data = [];
  63 + $id = $this->req->param("id");
  64 + $data['name'] = $this->req->param("name");
  65 + $data['specs'] = $this->req->param("specs",[]);
  66 + $data['apps'] = $this->req->param("apps",[]);
  67 + $data['sort'] = $this->req->param("sort",0);
  68 + if(!$id) return error("套餐id不可为空");
  69 + if(!$data['name']) return error("套餐名称不可为空");
  70 + if(!$data['specs']) return error("套餐规格不可为空");
  71 + if(!$data['apps']) return error("包含应用不可为空");
  72 + $res = AppPackageModel::editPackage($id,$data);
  73 + if($res != 'ok') return error($res);
  74 + return success("修改成功");
  75 + }
  76 +
  77 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\admin\user;
  11 +use think\facade\Db;
  12 +use app\base\controller\BaseAdmin;
  13 +use app\base\model\admin\system\BasicModel;
  14 +use app\base\model\admin\user\UserModel;
  15 +use app\base\model\admin\plug\AppManageModel;
  16 +use app\base\model\BaseModel;
  17 +use Ramsey\Uuid\Uuid;
  18 +use think\facade\Session;
  19 +
  20 +class Manage extends BaseAdmin
  21 +{
  22 + /**
  23 + * 我的客户管理
  24 + */
  25 + public function index()
  26 + {
  27 + $page = $this->req->param('page')?:1;
  28 + $status = $this->req->param('status');
  29 + $un = $this->req->param('un');
  30 + $size = $this->req->param("size")?:10;
  31 + $agname = $this->req->param("agname");
  32 + $data = UserModel::info($page,$un,$status,$size,$agname);
  33 + return success('获取成功',$data);
  34 + }
  35 + /**
  36 + * 获取代理列表
  37 + */
  38 + public function getAgents()
  39 + {
  40 + $data = UserModel::getAgents();
  41 + return success('获取成功',$data);
  42 + }
  43 + /*
  44 + * 启用停用作废 1为启用,0为禁用,2为作废
  45 + */
  46 + public function switch()
  47 + {
  48 + $id = $this->req->param('id');
  49 + if(!$id) return error("请选择账户");
  50 + $status = $this->req->param('status');
  51 + $data = UserModel::switch($id,$status);
  52 + return success('更新成功',$data);
  53 + }
  54 +
  55 + /**
  56 + * username 账号
  57 + * password 密码
  58 + * telephone 手机号
  59 + * contacts 联系人
  60 + * remark 备注
  61 + * agid 上级代理id
  62 + * id 用户id
  63 + */
  64 + public function addUser()
  65 + {
  66 + $id = $this->req->param('id');
  67 + $username = $this->req->param('username');
  68 + if(!$username) return error("账号不可为空");
  69 + $password = $this->req->param('password');
  70 + if(!$password && !$id) return error("密码不可为空");
  71 + $telephone = $this->req->param('telephone');
  72 + // if(!$telephone) return error("手机号不可为空");
  73 + $contacts = $this->req->param('contacts');
  74 + // if(!$contacts) return error("联系人不可为空");
  75 + $remark = $this->req->param('remark');
  76 + $agid = $this->req->param('agid');
  77 + $set = UserModel::setUser($username,$id);
  78 + if($set) return error("用户名重复");
  79 + if($id) $user = UserModel::user($id);
  80 + if($password) $password = ktEncrypt($password);
  81 + if(!$password && $id) $password = $user["pwd"]?:ktEncrypt("123456");
  82 + $add = UserModel::addUser($username,$password,$telephone,$contacts,$remark,$agid,$id);
  83 +
  84 + return success('修改成功',$add);
  85 + }
  86 + /**
  87 + * 编辑拉取数据
  88 + */
  89 + public function getUser()
  90 + {
  91 + $id = $this->req->param('id');
  92 + if(!$id) return error("参数错误");
  93 + $data = UserModel::getUser($id);
  94 +
  95 + return success('获取成功',$data);
  96 + }
  97 + /*
  98 + * 充值
  99 + * 先获取客户余额
  100 + */
  101 + public function recharge()
  102 + {
  103 + $id = $this->req->param("id");
  104 + $type = $this->req->param("type");
  105 + if(!$id) return error("参数错误");
  106 + $money = $this->req->param("money");
  107 + $remark = $this->req->param("remark");
  108 + if($money <= 0) return error("充值金额不可小于1");
  109 + $user = UserModel::getUser($id);
  110 + $agent = UserModel::getAgent();
  111 + if($type == 1){
  112 + if($agent["balance"] < $money)return error("管理员余额不足,请重新选择");
  113 + $agent_balance = $agent["balance"] - $money;
  114 + $user_balance = $user["balance"] + $money;
  115 + }
  116 + if($type == 2){
  117 + if($user["balance"] < $money)return error("客户余额不足,请重新选择");
  118 + $agent_balance = $agent["balance"] + $money;
  119 + $user_balance = $user["balance"] - $money;
  120 + }
  121 + UserModel::updAgent($agent_balance);
  122 + UserModel::updUser($id,$user_balance);
  123 + $out_trade_no = date('YmdHis', time()) . time() . rand(10000, 99999);
  124 + $add = UserModel::addRecord($money,$out_trade_no,$type,$id,$remark);
  125 + return success('充值成功',$add);
  126 + }
  127 +
  128 +
  129 + /*
  130 + * 获取员工已开套餐及已购买应用
  131 + */
  132 + public function auth()
  133 + {
  134 + $id = $this->req->param("id");
  135 + if(!$id) return error("参数错误,id不可为空");
  136 + $auth = UserModel::auth($id);
  137 + $data["appauth"] = $auth;
  138 + return success('获取成功',$auth);
  139 + }
  140 +
  141 + // 引擎列表
  142 + public function engine()
  143 + {
  144 + $res = UserModel::list();
  145 + $agent = UserModel::getAgent();
  146 + $data["setmeal"] = $res;
  147 + $data["balance"] = $agent["balance"];
  148 + return success('获取成功',$data);
  149 + }
  150 +
  151 + //选择引擎拿到引擎对应的套餐
  152 + public function getMeal()
  153 + {
  154 + $name = $this->req->param("name");
  155 + $id = $this->req->param("id");
  156 + if(!$id) return error("参数错误");
  157 + if(!$name) return error("参数错误");
  158 + $user = UserModel::getUser($id);
  159 + $set_meal = UserModel::getSetmeal($user["agid"],$name);
  160 + $price = json_decode($set_meal["price"],1);
  161 + $set_meal = UserModel::setMeal($price,$name);
  162 + $appauth = UserModel::appauth($id,$name);
  163 + $res["setMealList"] = $set_meal;
  164 + $res["setMeal"]["set_meal"] = NULL;
  165 + $res["setMeal"]["mend_time"] = time();
  166 + if($appauth) $res["setMeal"] = $appauth;
  167 + if($appauth) $res["setMeal"]["mend_time"] = strtotime($appauth["mend_time"]);
  168 + return success('获取成功',$res);
  169 + }
  170 +
  171 +
  172 + /**
  173 + * 升级续费时的价格
  174 + */
  175 + public function prices()
  176 + {
  177 + $prices = 0;
  178 + $price_difference = 0;
  179 + $name = $this->req->param("name");
  180 + $id = $this->req->param("id");
  181 + $mend_time = $this->req->param("mendTime");
  182 + $title = $this->req->param("title");
  183 + $code = $this->req->param("code");
  184 + $setmeal_id = $this->req->param("setmealId");
  185 + if(!$id || !$mend_time || !$setmeal_id || !$name) return error("参数错误");
  186 + $user = UserModel::getUser($id);
  187 + $appauth = UserModel::appauth($id,$name);
  188 + //获取已配置套餐的代理
  189 + $set_meal = UserModel::getSetmeal($user["agid"],$name);
  190 + //选择套餐的价格
  191 + $price = json_decode($set_meal["price"],1)[$setmeal_id];
  192 + //当前套餐的价格
  193 + $user_price = 0;
  194 + if($appauth) $user_price = json_decode($set_meal["price"],1)[$appauth["set_meal"]];
  195 + if($appauth && $price != $user_price && strtotime($appauth["mend_time"]) >= time()){
  196 + //当前套餐剩日价格
  197 + $day_price = $user_price/365;//当前会员日价格
  198 + //当前套餐剩余天数
  199 + $day_time = floor((strtotime($appauth["mend_time"])-time())/86400);//当前会员剩余天数(省略小数)
  200 + //当前套餐剩余金额
  201 + $return_price = floor($day_time * $day_price);//当前会员折扣金钱数 套餐剩余金额
  202 + //新套餐日价格
  203 + $day_price_new = $price/365;//新会员日价格
  204 + //新套餐所需的金额
  205 + $return_price_new = floor($day_price_new * $day_price);//新会员折扣金钱数
  206 + //差价
  207 + $price_difference = $return_price_new - $return_price; //需要的差价
  208 + }
  209 + //获取到指定的时间有多少年多少天
  210 + $mend_times = self::getDateGap($appauth["mend_time"]??date("Y-m-d",time()),$mend_time);
  211 + //年价格
  212 + if($mend_times["year"]) $prices = $prices+$mend_times["year"]*$price;
  213 + //日价格 套餐所需金额,到指定日期的金额 prices
  214 + if($mend_times["day"]) $prices = $prices+floor($mend_times["day"]*($price/365));
  215 + return success('所需费用',$prices);
  216 + }
  217 + /*
  218 + * 升级续费
  219 + * "kt_".$name."_type" 套餐名称表
  220 + * "kt_".$name."_setmeal" 套餐设置表
  221 + * "kt_".$name."_setmeal_record" 记录表
  222 + */
  223 + public function upgrade()
  224 + {
  225 + $prices = 0;
  226 + $price_difference = 0;
  227 + $name = $this->req->param("name");
  228 + $id = $this->req->param("id");
  229 + $mend_time = $this->req->param("mendTime");
  230 + $title = $this->req->param("title");
  231 + $code = $this->req->param("code");
  232 + $setmeal_id = $this->req->param("setmealId");
  233 + if(!$id || !$mend_time || !$setmeal_id || !$name || !$title || !$code) return error("参数错误");
  234 + $user = UserModel::getUser($id);
  235 + // var_dump($id);die;
  236 + $appauth = UserModel::appauth($id,$name);
  237 + //获取已配置套餐的代理
  238 + $set_meal = UserModel::getSetmeal($user["agid"],$name);
  239 + //选择套餐的价格
  240 + $price = json_decode($set_meal["price"],1)[$setmeal_id];
  241 + //当前套餐的价格
  242 + $user_price = 0;
  243 + if($appauth) $user_price = json_decode($set_meal["price"],1)[$appauth["set_meal"]];
  244 + if($appauth && $price != $user_price && strtotime($appauth["mend_time"]) >= time()){
  245 + //当前套餐剩日价格
  246 + $day_price = $user_price/365;//当前会员日价格
  247 + //当前套餐剩余天数
  248 + $day_time = floor((strtotime($appauth["mend_time"])-time())/86400);//当前会员剩余天数(省略小数)
  249 + //当前套餐剩余金额
  250 + $return_price = floor($day_time * $day_price);//当前会员折扣金钱数 套餐剩余金额
  251 + //新套餐日价格
  252 + $day_price_new = $price/365;//新会员日价格
  253 + //新套餐所需的金额
  254 + $return_price_new = floor($day_price_new * $day_price);//新会员折扣金钱数
  255 + //差价
  256 + $price_difference = $return_price_new - $return_price; //需要的差价
  257 + }
  258 + //获取到指定的时间有多少年多少天
  259 + $mend_times = self::getDateGap($appauth["mend_time"]??date("Y-m-d",time()),$mend_time);
  260 + //年价格
  261 + if($mend_times["year"]) $prices = $prices+$mend_times["year"]*$price;
  262 + //日价格 套餐所需金额,到指定日期的金额 prices
  263 + if($mend_times["day"]) $prices = $prices+floor($mend_times["day"]*($price/365));
  264 + $money = $prices;
  265 + //套餐差价如果大于0的情况下补齐差价,如果小于0的情况下舍弃不要
  266 + if($prices && $price_difference > 0) $prices += $price_difference;
  267 + $agent = UserModel::getAgent();
  268 + if($agent["balance"] < $prices) return error("余额不足");
  269 + if($agent["isadmin"] != 1){
  270 + $agent_level = UserModel::getAgentLevel($agent["level"]);
  271 + if($agent_level) $prices = floor($prices*($agent_level["discount"]/10));
  272 + }
  273 + $add = UserModel::addSetmealRecord($id,$setmeal_id,$price_difference,$prices,$money,$mend_time,$mend_times["year"],$mend_times["day"],$name);
  274 + UserModel::updAppauth($id,$code,$title,$name,$mend_time,$setmeal_id);
  275 + if(!$add) return error("入库失败");
  276 + $balance = $agent["balance"] - $prices;
  277 + UserModel::updAgent($balance);
  278 + UserModel::updUsers($id,$setmeal_id,$mend_time);
  279 + return success('续费成功,已扣除',$prices);
  280 + }
  281 +
  282 + public function getDateGap($mendtime,$end)
  283 + {
  284 + $start = strtotime($mendtime);
  285 + $end = strtotime($end);
  286 + list($sy,$sm,$sd) = explode("-", date("Y-m-d", $start));
  287 + list($ey,$em,$ed) = explode("-", date("Y-m-d", $end));
  288 + $y = $ey - $sy;
  289 + $m = $em - $sm;
  290 + $w = date('W', $end) - date('W', $start);
  291 + $d = $ed - $sd;
  292 + if ($y > 0) { // 表示跨了年
  293 + $m += 12 * $y;
  294 + $startYear = date('Y', $start);
  295 + $endYear = date('Y', $end);
  296 + for ($i = $startYear; $i < $endYear; $i++) {
  297 + for ($j = 31;$j > 24;$j--) {
  298 + $tmpWeek = date('W', strtotime(sprintf("%s-12-%s", $i, $j)));
  299 + if (intval($tmpWeek) != 1) { // 不是第一周,则是当年的最后一周
  300 + $w += $tmpWeek; // 加上当年的周数量
  301 + break;
  302 + }
  303 + }
  304 + }
  305 + }
  306 + if ($m > 0) { // 表示跨了月
  307 + for($i = 1; $i <= $m; $i++) {
  308 + $d += date('t', strtotime("+{$i} month", $start)); // 跨了月
  309 + }
  310 + }
  311 + $years = floor($d/365);
  312 + $tian = $years * 365;
  313 + $days = $d-$tian;
  314 + return ["year"=>$years,"day"=>$days];
  315 + }
  316 +
  317 + /*
  318 + * 越权登录获取token
  319 + */
  320 + public function getToken(){
  321 + $id = $this->req->param('id');
  322 + if(!$id) return error("参数错误");
  323 + $res = UserModel::getToken($id);
  324 + return success('获取成功',["token"=>$res["token"]]);
  325 + }
  326 +
  327 + /*
  328 + * 拉取所属代理
  329 + */
  330 + public function getAdents(){
  331 + $uid = Session::get("uid");
  332 + $ids = BaseModel::getAdentIds($uid);
  333 + $data = UserModel::getAdents($ids);
  334 +
  335 + return success("获取成功",$data);
  336 + }
  337 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\user;
  11 +use think\facade\Db;
  12 +use think\facade\Cache;
  13 +use app\base\controller\BaseUser;
  14 +use think\facade\Session;
  15 +use app\base\model\BaseModel;
  16 +use app\base\model\user\AppModel;
  17 +
  18 +
  19 +class App extends BaseUser
  20 +{
  21 + /**
  22 + *获取 已购买应用
  23 + **/
  24 + public function openAppList()
  25 + {
  26 + $page = $this->req->get('page',1);
  27 + $size = $this->req->get('size',10);
  28 + $title = $this->req->get('title','');
  29 + $pid = $this->req->get('pid',0);
  30 + $where = [];
  31 + $where[] = ['pid','=',$pid];
  32 + if($title) $where[] = ['name','like',"%{$title}%"];
  33 + $res = AppModel::openAppList($where,$page,$size);
  34 + return success("已拥有引擎",$res);
  35 + }
  36 + /**
  37 + *获取 已购买应用
  38 + **/
  39 + public function updateOpenApp()
  40 + {
  41 + $data = [];
  42 + $data['id'] = $this->req->post('id');
  43 + $data['sequence'] = $this->req->post('sequence');
  44 + $data['self_title'] = $this->req->post('self_title');
  45 + if(!$data['id'] || !$data['sequence'] || !$data['self_title']) return error('参数错误');
  46 + $res = AppModel::save($data);
  47 + return success("更新成功");
  48 + }
  49 + /**
  50 + *获取 全部应用
  51 + **/
  52 + public function appList()
  53 + {
  54 + $page = $this->req->get('page',1);
  55 + $size = $this->req->get('size',10);
  56 + $type = $this->req->get('type',0);
  57 + $title = $this->req->get('title','');
  58 +
  59 + $where = [];
  60 + if($type) $where[] = ['type','=',$type];
  61 + if($title) $where[] = ['name','like',"%{$title}%"];
  62 + $res = AppModel::appList($where,$page,$size);
  63 + return success("全部引擎",$res);
  64 + }
  65 + /**
  66 + *获取详情
  67 + **/
  68 + public function appDetail()
  69 + {
  70 + $id = $this->req->get('id');
  71 + $res = AppModel::appDetail($id);
  72 + return success("引擎详情",$res);
  73 + }
  74 + /**
  75 + *获取 应用分类
  76 + **/
  77 + public function appType()
  78 + {
  79 + $res = AppModel::appType();
  80 + return success("引擎分类",$res);
  81 + }
  82 + /**
  83 + *试用
  84 + **/
  85 + public function tryout()
  86 + {
  87 + $id = $this->req->get('id');
  88 + if(!$id) return error('参数错误');
  89 + return AppModel::tryout($id);
  90 + }
  91 + /**
  92 + *立即使用
  93 + **/
  94 + public function openappUse()
  95 + {
  96 + return AppModel::openappUse($this->req);
  97 + }
  98 + /**
  99 + *购买
  100 + **/
  101 + public function buy()
  102 + {
  103 + // [{ "id":1,"duration": 1, "duration_type": 1, "old_price": 0.02, "price": 0.01 }]
  104 + $id = $this->req->post('id');
  105 + if(!$id) return error('请选择引擎');
  106 + $specsid = $this->req->post('specsid');
  107 + if(!$specsid) return error('请选择规格');
  108 + return AppModel::buy($id,$specsid);
  109 + }
  110 + /**
  111 + *购买结果
  112 + **/
  113 + public function getPayResult()
  114 + {
  115 + return AppModel::getPayResult($this->req);
  116 + }
  117 +
  118 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\user;
  11 +
  12 +use think\facade\Db;
  13 +use think\facade\Log;
  14 +use app\BaseController;
  15 +use paySDK\NewPay;
  16 +
  17 +
  18 +
  19 +/**
  20 + * 外部联系人回调
  21 + */
  22 +class CallbackWxPay extends BaseController
  23 +{
  24 + public function webchat(){
  25 + $post= file_get_contents("php://input");
  26 + if (!$post) $post = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
  27 + if (!$post) exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
  28 + libxml_disable_entity_loader(true);
  29 + $xml = simplexml_load_string($post,'SimpleXMLElement',LIBXML_NOCDATA);
  30 + $data = (array)$xml;
  31 + $out_trade_no = isset($data['out_trade_no']) && !empty($data['out_trade_no']) ? $data['out_trade_no'] : 0;
  32 + $order = Db::table('kt_base_recharge')->where('bh',$out_trade_no)->where('ifok',0)->find();
  33 + if($order){
  34 + $user = Db::table('kt_base_user')->where('id',$order['wid'])->find();
  35 + $config = Db::table('kt_base_pay_config')->where(['uid'=>$user['agid'],'type'=>'wx'])->find();
  36 + $wxKey = explode(',',$config['config'])[2] ?? null;
  37 +
  38 + // $oldSign = $data['sign'];
  39 + // $signA = "appid=".$data['appid']."&bank_type=".$data['bank_type']."&cash_fee=".$data['cash_fee']."&fee_type=".$data
  40 + // ['fee_type']."&is_subscribe=".$data['is_subscribe']."&mch_id=".$data['mch_id']."&nonce_str=".$data['nonce_str']."&openid=".
  41 + // $data['openid']."&out_trade_no=".$data['out_trade_no']."&result_code=".$data['result_code']."&return_code=".$data
  42 + // ['return_code']."&time_end=".$data['time_end']."&total_fee=".$data['total_fee']."&trade_type=".$data
  43 + // ['trade_type']."&transaction_id=".$data['transaction_id']."&key=".$wxKey;
  44 + // $newSign = strtoupper(MD5($signA));
  45 +
  46 + if($this->confirm_sign($data,$wxKey)){
  47 + Db::table('kt_base_user')->where('id',$user['id'])->update(['balance'=>$user['balance'] + $data['total_fee']/100 ]);
  48 + Db::table('kt_base_recharge')->where('bh',$out_trade_no)->update([
  49 + 'update_time'=> date('Y-m-d H:i:s'),
  50 + 'uip'=> request()->ip(),
  51 + 'status' => '交易成功',
  52 + 'ifok'=> 1,
  53 + 'jyh' => $data['transaction_id']
  54 + ]);
  55 + $this->buy($out_trade_no);
  56 + }
  57 + }
  58 + echo 'SUCCESS';
  59 + exit;
  60 + }
  61 +
  62 + public function confirm_sign($data,$key,$sign_key='sign'){
  63 + if (key_exists($sign_key, $data)) {
  64 + $sign = $data[$sign_key];
  65 + }
  66 + if (!$sign){
  67 + return false;
  68 + }
  69 + $data2=$data;
  70 + unset($data2['sign']);
  71 + ksort($data2);
  72 + $string = $this->array_to_string($data2);
  73 + $string = $string . "&key=" . $key;
  74 + $string = md5($string);
  75 + $sign2 = strtoupper($string);
  76 + return $sign==$sign2;
  77 + }
  78 +
  79 + public function array_to_string($params){
  80 + $string = '';
  81 + if (!empty($params)) {
  82 + $array = [];
  83 + foreach ($params as $key => $value) {
  84 + $array[] = $key . '=' . $value;
  85 + }
  86 + $string = implode("&", $array);
  87 + }
  88 + return $string;
  89 + }
  90 +
  91 + public function buy($bh)
  92 + {
  93 + $order = Db::table('kt_base_user_order')->where('bh',$bh)->find();
  94 + $app = Db::table("kt_base_market_app")->json(['specs'])->find($order['app_id']);
  95 + $specs = [];
  96 + foreach ($app['specs'] as $v) {
  97 + if($v['id'] == $order['specs_id']){
  98 + $specs = $v;
  99 + break;
  100 + }
  101 + }
  102 + $wid = $order['wid'];
  103 + $user = Db::table("kt_base_user")->find($wid);
  104 + $data = [
  105 + 'wid' => $wid,
  106 + 'name' => $app['name'],
  107 + 'code' => $app['code'],
  108 + 'logo' => $app['logo'],
  109 + 'version' => $app['version'],
  110 + // 'mend_time' => date("Y-m-d H:i:s",strtotime("+".$app['try_days']." day")),
  111 + 'update_time' => date("Y-m-d H:i:s"),
  112 + 'app_id' => $order['app_id'],
  113 + ];
  114 +
  115 + $has = Db::table("kt_base_user_openapp")->where('wid',$wid)->where('app_id',$order['app_id'])->find();
  116 + if($has){
  117 + $data['id'] = $has['id'];
  118 + if(strtotime($has['mend_time'] < time())){
  119 + $date = date("Y-m-d H:i:s");
  120 + }else{
  121 + $date = $has['mend_time'];
  122 + }
  123 + }else{
  124 + $date = date("Y-m-d H:i:s");
  125 + $data['create_time'] = date("Y-m-d H:i:s");
  126 + }
  127 + // [{ "id":1,"duration": 1, "duration_type": 1, "old_price": 0.02, "price": 0.01 }]
  128 + $content = '';
  129 + $day = 0;
  130 + switch ($specs['duration_type']) {
  131 + case 2:
  132 + $content = '用户购买规格时长'.$specs['duration'].'月的套餐';
  133 + $data['mend_time'] = date("Y-m-d H:i:s",strtotime("+".$specs['duration']." month",strtotime($date)));
  134 + break;
  135 + case 3:
  136 + $content = '用户购买规格时长'.$specs['duration'].'年的套餐';
  137 + $data['mend_time'] = date("Y-m-d H:i:s",strtotime("+".$specs['duration']." year",strtotime($date)));
  138 + break;
  139 + }
  140 + $pid = 0;
  141 + if ($app['pid'] != 0) {
  142 + $pApp = Db::table("kt_base_market_app")->find($app['pid']);
  143 + $pOpenapp = Db::table("kt_base_user_openapp")->where('wid',$wid)->where('app_id',$pApp['id'])->find();
  144 + $pid = $pOpenapp['id'];
  145 + }
  146 + $data['pid'] = $pid;
  147 + $res = Db::table("kt_base_user_openapp")->save($data);
  148 +
  149 + if($res){
  150 + Db::table("kt_base_user")->where('id',$wid)->update([
  151 + 'balance' => Db::raw('balance-'.$order['price']),
  152 + 'update_time'=>date("Y-m-d H:i:s"),
  153 + ]);
  154 + Db::table("kt_base_user_order")->where('id',$order['id'])->update([
  155 + 'status' => 2,
  156 + 'content' => $content
  157 + ]);
  158 + return 'ok';
  159 + }
  160 + return 'error';
  161 + }
  162 +
  163 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\user;
  11 +use think\facade\Db;
  12 +use Ramsey\Uuid\Uuid;
  13 +use think\facade\Session;
  14 +use app\base\model\BaseModel;
  15 +use app\base\controller\BaseUser;
  16 +
  17 +class Login extends BaseUser
  18 +{
  19 + public function index()
  20 + {
  21 + if(!$this->req->isPost()) return error('请使用POST请求');
  22 + $username = $this->req->param('username');
  23 + $password = $this->req->param('password');
  24 + if(!$username) return error('缺少参数username');
  25 + if(!$password) return error('缺少参数password');
  26 + $where = [
  27 + ['un', '=', $username],
  28 + ['telephone', '=', $username],
  29 + ['email','=',$username]
  30 + ];
  31 + $user = Db::table('kt_base_user')->whereOr($where)->find();
  32 + if(!$user) return error('用户不存在');
  33 + if($user['pwd'] != md5($password) && $user['pwd'] != ktEncrypt($password)) return error('帐号或密码错误');
  34 + if($user['isstop'] != 1 ) return error('账号审核中或已停用');
  35 + // if(strtotime($user['mendtime']) <= time()) return error('账号已到期');
  36 + $token = $user['token'] && $user['expire_time'] > time() ? $user['token'] : Uuid::uuid1();
  37 + Db::table('kt_base_user')->where('id',$user['id'])->inc('logtimes')->update(['token'=>"{$token}",'expire_time'=> time() + (7*24*3600),'lasttime'=>date("Y-m-d H:i:s")]);
  38 + Db::table('kt_base_loginlog')->insert([
  39 + 'admin' => 2 ,
  40 + 'wid' => $user['id'],
  41 + 'uip' => $this->req->ip(),
  42 + 'create_time' => date("Y-m-d H:i:s")
  43 + ]);
  44 + return success('登录成功',['token'=>$token]);
  45 + }
  46 +
  47 + /**
  48 + *获取登录页相关信息
  49 + **/
  50 + public function getLoginInfo(){
  51 + $res = BaseModel::getLoginInfo($this->host);
  52 + return success("登陆前相关信息",$res);
  53 + }
  54 +
  55 + /*
  56 + * 修改密码
  57 + */
  58 + public function updatePwd()
  59 + {
  60 + $wid = Session::get('wid');
  61 + $user = Db::table('kt_base_user')->find($wid);
  62 + $password = $this->req->post('password');
  63 + if($user['pwd'] != md5($password) && $user['pwd'] != ktEncrypt($password)) return error('当前密码错误');
  64 + $new_password = $this->req->post('new_password');
  65 + $confirm_password = $this->req->post('confirm_password');
  66 + if(!$new_password || !$confirm_password) return error('请输入新密码');
  67 + if($new_password != $confirm_password) return error('两次输入的新密码不一致');
  68 + if($user['pwd'] == ktEncrypt($new_password)) return error('新旧密码一致');
  69 + $res = Db::table('kt_base_user')->where('id',$wid)->update([
  70 + "pwd" => ktEncrypt($new_password),
  71 + ]);
  72 + if($res) return success('修改成功');
  73 + return error('修改失败');
  74 + }
  75 +
  76 +
  77 + /**
  78 + *忘记密码
  79 + **/
  80 + public function fogretpwd(){
  81 + $phone = $this->req->post('phone');
  82 + if(!preg_match("/^1[3456789]\d{9}$/", $phone)) return error('手机号格式不正确');
  83 + $user = Db::table('kt_base_user')->where('telephone',$phone)->find();
  84 + if(!$user) return error('账号不存在');
  85 + $code = $this->req->post('code');
  86 + $key = 'sms_'.$phone;
  87 + $cacheCode = Cache::get($key);
  88 + if(!$code || $code!=$cacheCode) return error('验证码不正确');
  89 + $password = trim($this->req->post('password'));
  90 + if(!$password) return error('请填写新密码');
  91 + Db::table('kt_base_user')->where('id',$user['id'])->update(['pwd'=>ktEncrypt($password)]);
  92 + Cache::delete($key);
  93 + return success('修改成功');
  94 + }
  95 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\controller\user;
  11 +use think\facade\Db;
  12 +use app\base\controller\BaseUser;
  13 +use Ramsey\Uuid\Uuid;
  14 +use think\facade\Session;
  15 +use app\base\model\BaseModel;
  16 +
  17 +class Register extends BaseUser
  18 +{
  19 + public function index()
  20 + {
  21 + $username = $this->req->param("username");
  22 + $password = $this->req->param("password");
  23 + $phone = $this->req->param("phone");
  24 + if(!$username) return error('缺少参数username');
  25 + if(!$password) return error('缺少参数password');
  26 + if(!$phone) return error('缺少参数phone');
  27 + if(!preg_match("/^1[23456789]\d{9}$/", $phone)) return error("手机号格式错误,请重新输入");
  28 + $where = [
  29 + ['un', '=', $username],
  30 + ['telephone', '=', $phone]
  31 + ];
  32 + $user = Db::table('kt_base_user')->whereOr($where)->find();
  33 + if($user) return error("账户已存在,请重新注册");
  34 + $res = BaseModel::getLoginInfo($this->host);
  35 + Db::table('kt_base_user')->insert([
  36 + 'un' => $username ,
  37 + 'pwd' => ktEncrypt($password),
  38 + 'telephone' => $phone,
  39 + 'agid' => $res["id"],
  40 + 'mendtime' => date('Y-m-d', strtotime('-7 days')),
  41 + 'create_time' => date("Y-m-d H:i:s",time())
  42 + ]);
  43 + return success("注册成功");
  44 + }
  45 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +// 这是系统自动生成的event定义文件
  11 +return [
  12 +
  13 +];
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +// 这是系统自动生成的middleware定义文件
  11 +return [
  12 + app\base\middleware\admincheck::class,
  13 +];
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +declare (strict_types = 1);
  11 +
  12 +namespace app\base\middleware;
  13 +use think\Response;
  14 +
  15 +/**
  16 + * 全局跨域请求处理
  17 + * Class CrossDomain
  18 + * @package app\middleware
  19 + */
  20 +class CrossDomain
  21 +{
  22 + public function handle($request, \Closure $next)
  23 + {
  24 + //header('Access-Control-Allow-Origin: *');
  25 + header('Access-Control-Max-Age: 1800');
  26 + header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
  27 + header('Access-Control-Allow-Headers: usertoken, Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With, Token, token, wid');
  28 + if (strtoupper($request->method()) == "OPTIONS") {
  29 + return Response::create()->send();
  30 + }
  31 +
  32 +
  33 + return $next($request);
  34 + }
  35 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +declare (strict_types = 1);
  11 +
  12 +namespace app\base\middleware;
  13 +use think\facade\Db;
  14 +use think\facade\Request;
  15 +
  16 +class admincheck
  17 +{
  18 + protected $whiteList = [
  19 + '/',
  20 + '/base/adminuser/login',
  21 + '/base/admin/login',
  22 + '/base/baseadmin/sendcode',
  23 + '/base/admin/appinstall',
  24 + '/base/admin/baseinstall',
  25 + ];
  26 + /**
  27 + * 处理请求
  28 + *
  29 + * @param \think\Request $request
  30 + * @param \Closure $next
  31 + * @return Response
  32 + */
  33 + public function handle($request, \Closure $next)
  34 + {
  35 + $token = $request->header('UserToken');
  36 + // echo app('http')->getName(); //获取应用名
  37 + $url = strtolower($request->baseUrl()); //获取url地址, 不带域名,然后小写,
  38 + // die();
  39 + if(in_array($url,$this->whiteList) || preg_match("/^\/base\/user/", $url)) return $next($request);
  40 + if(!$token) return error('缺少参数UserToken');
  41 + $admin = Db::table('kt_base_agent')->where([['agency_token', '=', $token],['expire_time','>',time()]])->find();
  42 + if(!$admin) return error('无效的UserToken');
  43 + Db::table('kt_base_agent')->where('id',$admin['id'])->update(['expire_time'=> time() + (7*24*3600)]);
  44 + return $next($request);
  45 + }
  46 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +declare (strict_types = 1);
  11 +
  12 +namespace app\base\middleware;
  13 +use think\facade\Db;
  14 +use think\facade\Request;
  15 +
  16 +class check
  17 +{
  18 + protected $whiteList = [
  19 + '/',
  20 + '/base/user/login',
  21 + '/base/user/logout',
  22 + '/base/user/register',
  23 + '/base/user/getlogininfo',
  24 + '/base/baseadmin/sendcode',
  25 + '/base/user/fogretpwd',
  26 + '/base/user/callbackwxpay',
  27 + ];
  28 + /**
  29 + * 处理请求
  30 + *
  31 + * @param \think\Request $request
  32 + * @param \Closure $next
  33 + * @return Response
  34 + */
  35 +
  36 + public function handle($request, \Closure $next)
  37 + {
  38 + $token = $request->header('UserToken');
  39 + // echo app('http')->getName(); //获取应用名
  40 + $url = strtolower($request->baseUrl()); //获取url地址, 不带域名,然后小写,
  41 + if(in_array($url,$this->whiteList)) return $next($request);
  42 + if(!$token) return error('缺少参数UserToken');
  43 + $user = Db::table('kt_base_user')->where([['token', '=', $token],['expire_time','>',time()]])->find();
  44 + if(!$user) return error('无效的UserToken');
  45 + Db::table('kt_base_user')->where('id',$user['id'])->update(['expire_time'=> time() + (7*24*3600) ]);
  46 + return $next($request);
  47 +
  48 + }
  49 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\model;
  11 +use think\facade\Db;
  12 +use think\facade\Session;
  13 +
  14 +/*
  15 +* 基础功能model
  16 +*/
  17 +class BaseModel
  18 +{
  19 + static protected $uid;
  20 + /**
  21 + * 获取应用下xml配置信息
  22 + * @param $app 应用目录
  23 + * @return
  24 + */
  25 + static public function getMainfest($app){
  26 + $path = base_path().'/'.$app.'/mainfest.xml';
  27 + if(!file_exists($path)) $path = base_path().'/'.$app.'/manifest.xml';
  28 + $xml = [];
  29 + if(is_file($path)) $xml = json_decode(json_encode(simplexml_load_file($path,'SimpleXMLElement', LIBXML_NOCDATA)), 1);
  30 + return $xml;
  31 + }
  32 + /**
  33 + * 获取 随机数
  34 + * @param leg 长度
  35 + * @return
  36 + */
  37 + static public function getCode(){
  38 + return rand(100000,999999);
  39 + }
  40 + /**
  41 + * 获取
  42 + * @param $host 域名,不带协议
  43 + * @return
  44 + */
  45 + static public function getLoginInfo($host){
  46 + $admin = Db::table('kt_base_agent')->field('id,key_word,describe,record_number,user_logo,login_logo,domain,webname,webtitle,login_background,register_check,registration_audit,company_name')->where('domain',$host)->find();
  47 + if(!$admin) $admin = Db::table('kt_base_agent')->field('id,key_word,record_number,describe,user_logo,login_logo,domain,webname,webtitle,login_background,register_check,registration_audit,company_name')->where('isadmin',1)->find();
  48 +
  49 + $gptcms_path = root_path().'/public/static/gptcms/hot/verify.txt';
  50 + $admin['gptcms_c_s'] = 0;
  51 + if(file_exists($gptcms_path) && filesize($gptcms_path) !== 0){
  52 + $admin['gptcms_c_s'] = 1;
  53 + }
  54 + return $admin;
  55 + }
  56 +
  57 + /**
  58 + * 判断当前代理是否是 管理员
  59 + *
  60 + * @return
  61 + */
  62 + static public function isAdmin($uid){
  63 + $res = Db::table('kt_base_agent')->where('id',$uid)->value('isadmin') ?: 0;
  64 + return $res;
  65 + }
  66 + /**
  67 + * 获取当前uid
  68 + *
  69 + * @return
  70 + */
  71 + static public function getUid(){
  72 + $uid = Session::get('uid');
  73 + if(!$uid) $uid = Db::table('kt_base_agent')->where('isadmin',1)->value('id');
  74 + return $uid;
  75 + }
  76 + /**
  77 + * 获取管理员id
  78 + *
  79 + * @return
  80 + */
  81 + static public function getAdminId(){
  82 + $res = Db::table('kt_base_agent')->where('isadmin',1)->value('id');
  83 + return $res;
  84 + }
  85 + /**
  86 + * 根据文件夹获取配置信息
  87 + * @return
  88 + */
  89 + static public function getMainfestByName($code){
  90 + $res = [];
  91 + $base = base_path();
  92 + $filePath = $base."/".$code."/mainfest.xml";
  93 + if(!file_exists($filePath)) $filePath = $base."/".$code."/manifest.xml";
  94 +
  95 + if(is_file($filePath)){
  96 + $xml=simplexml_load_file($filePath,'SimpleXMLElement', LIBXML_NOCDATA);
  97 + $xmlArr = json_decode(json_encode($xml), 1);
  98 + if(isset($xmlArr['application'])) $res = $xmlArr['application'];
  99 + }
  100 + return $res;
  101 + }
  102 +
  103 + /**
  104 + * 获取当前代理下所有代理id,包括下级的下级代理id
  105 + *
  106 + * @return $ids 代理id array()
  107 + */
  108 + static public function getAdentIds($uid){
  109 + $ids = [];
  110 + $ids[] = $uid;
  111 + self::getAdentId($uid,$ids);
  112 + return $ids;
  113 + }
  114 + static public function getAdentId($uid,&$ids){
  115 + $res = Db::table('kt_base_agent')->where('pid',$uid)->column('id');
  116 + if(count($res)>0){
  117 + foreach ($res as $id) {
  118 + $ids[] = $id;
  119 + self::getAdentId($id,$ids);
  120 + }
  121 + }
  122 + return $ids;
  123 + }
  124 +
  125 + /**
  126 + * 获取 云存储配置, 当前代理未设置自动获取上级代理配置
  127 + * @param $uid 账户id
  128 + * @return
  129 + */
  130 + static public function getStorageInfo($uid=''){
  131 + $uid = $uid ?: Session::get('uid');
  132 + $res = Db::table('kt_base_storage_config')->field('uid,type,oss_id,oss_secret,oss_endpoint,oss_bucket,cos_secretId,cos_secretKey,cos_bucket,cos_endpoint,kodo_key,kodo_secret,kodo_domain,kodo_bucket')->where('uid',$uid)->find();
  133 + if(!$res){
  134 + $user = Db::table('kt_base_agent')->find($uid);
  135 + if($user['isadmin'] == 1) return $res;
  136 + $res = self::getStorageInfo($user['pid']);
  137 + }
  138 + return $res;
  139 + }
  140 +
  141 + /**
  142 + * 获取 当前用户云存储配置
  143 + * @param $uid 账户id
  144 + * @return
  145 + */
  146 + static public function storageInfo(){
  147 + $uid = Session::get('uid');
  148 + $res = Db::table('kt_base_storage_config')->field('uid,type,oss_id,oss_secret,oss_endpoint,oss_bucket,cos_secretId,cos_secretKey,cos_bucket,cos_endpoint,kodo_key,kodo_secret,kodo_domain,kodo_bucket')->where('uid',$uid)->find();
  149 + return $res;
  150 + }
  151 +
  152 + /**
  153 + * 保存 云存储配置
  154 + * @param $data 更新数据 array
  155 + * @return
  156 + */
  157 + static public function storageUpdate($data){
  158 + $uid = Session::get('uid');
  159 + $config = Db::table('kt_base_storage_config')->where('uid',$uid)->find();
  160 + $param = [];
  161 + if($config) $param['id'] = $config['id'];
  162 + $param['uid'] = $uid;
  163 + $param['type'] = $data['type'];
  164 + switch ($data['type']) {
  165 + case '2':
  166 + $param['oss_id'] = $data['oss_id'];
  167 + $param['oss_secret'] = $data['oss_secret'];
  168 + $param['oss_endpoint'] = $data['oss_endpoint'];
  169 + $param['oss_bucket'] = $data['oss_bucket'];
  170 + break;
  171 + case '3':
  172 + $param['cos_secretId'] = $data['cos_secretId'];
  173 + $param['cos_secretKey'] = $data['cos_secretKey'];
  174 + $param['cos_bucket'] = $data['cos_bucket'];
  175 + $param['cos_endpoint'] = $data['cos_endpoint'];
  176 + break;
  177 + case '4':
  178 + $param['kodo_key'] = $data['kodo_key'];
  179 + $param['kodo_secret'] = $data['kodo_secret'];
  180 + $param['kodo_domain'] = $data['kodo_domain'];
  181 + $param['kodo_bucket'] = $data['kodo_bucket'];
  182 + break;
  183 + }
  184 + $res = Db::table('kt_base_storage_config')->save($param);
  185 + return 'ok';
  186 + }
  187 +
  188 + /**
  189 + * 初始化云存储数据
  190 + * @return
  191 + */
  192 + static private function inisetStorage(){
  193 + $uid = Session::get('uid');
  194 + $config = Db::table('kt_base_storage_config')->where('wid',$wid)->find();
  195 + if(!$config){
  196 + Db::table('kt_base_storage_config')->insert(
  197 + [
  198 + 'uid' => $uid,
  199 + 'type' => 1,
  200 + 'create_time'=>date("Y-m-d H:i:s"),
  201 + 'update_time'=>date("Y-m-d H:i:s"),
  202 + ]
  203 + );
  204 + }
  205 + }
  206 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\model\admin\app;
  11 +use think\facade\Db;
  12 +use think\facade\Session;
  13 +use app\base\model\BaseModel;
  14 +use think\facade\Cache;
  15 +
  16 +/*
  17 +* 应用管理
  18 +*/
  19 +class AppManageModel extends BaseModel
  20 +{
  21 + /**
  22 + * 获取 主应用列表
  23 + * @return
  24 + */
  25 + public static function mainapp($req)
  26 + {
  27 + $data = [];
  28 + // $page = $req->post('page',1);
  29 + // $size = $req->post('size',10);
  30 + $name = $req->post('name');
  31 + $installType = $req->post('install_type');
  32 + $where = [];
  33 + if($name) $where[] = ['name','like',"%{$name}%"];
  34 + if($installType) $where[] = ['install_type','=',$installType];
  35 + // $data['page'] = $page;
  36 + // $data['size'] = $size;
  37 + $res = Db::table('kt_base_market_app')->field('logo,code,name,app_type,describe,admin_link,install_type,author,target,version,c_time')->where('admin_link','<>','')->where('app_type',1);
  38 + if($where) $res->where($where);
  39 + // $data['count'] = $res->count();
  40 + // $data['item'] = $res->select();
  41 + $res = $res->select()->toArray();
  42 + foreach ($res as $key=>$value) {
  43 + $res[$key]['admin_link'] = $req->domain().$value['admin_link'];
  44 + }
  45 + return $res;
  46 + }
  47 +
  48 + /**
  49 + * 获取 子应用(主应用插件)
  50 + * @return
  51 + */
  52 + public static function plugin($req)
  53 + {
  54 + $data = [];
  55 + // $page = $req->post('page',1);
  56 + // $size = $req->post('size',10);
  57 + $name = $req->post('name');
  58 + $installType = $req->post('install_type');
  59 + $where = [];
  60 + if($name) $where[] = ['name','like',"%{$name}%"];
  61 + if($installType) $where[] = ['install_type','=',$installType];
  62 + // $data['page'] = $page;
  63 + // $data['size'] = $size;
  64 + $res = Db::table('kt_base_market_app')->field('logo,code,name,app_type,describe,admin_link,install_type,author,target,version,c_time')->where('admin_link','<>','')->where('app_type',2);
  65 + if($where) $res->where($where);
  66 + // $data['count'] = $res->count();
  67 + // $data['item'] = $res->select();
  68 + $res = $res->select()->toArray();
  69 + foreach ($res as $key=>$value) {
  70 + $res[$key]['admin_link'] = $req->domain().$value['admin_link'];
  71 + }
  72 + return $res;
  73 + }
  74 +
  75 + /**
  76 + * 获取 工具应用
  77 + * @return
  78 + */
  79 + public static function tools($req)
  80 + {
  81 + $data = [];
  82 + // $page = $req->post('page',1);
  83 + // $size = $req->post('size',10);
  84 + $name = $req->post('name');
  85 + $installType = $req->post('install_type');
  86 + $where = [];
  87 + if($name) $where[] = ['name','like',"%{$name}%"];
  88 + if($installType) $where[] = ['install_type','=',$installType];
  89 + // $data['page'] = $page;
  90 + // $data['size'] = $size;
  91 + $res = Db::table('kt_base_market_app')->field('logo,code,name,app_type,describe,admin_link,install_type,author,target,version,c_time')->where('admin_link','<>','')->where('app_type',3);
  92 + if($where) $res->where($where);
  93 + // $data['count'] = $res->count();
  94 + // $data['item'] = $res->select();
  95 + $res = $res->select()->toArray();
  96 + foreach ($res as $key=>$value) {
  97 + $res[$key]['admin_link'] = $req->domain().$value['admin_link'];
  98 + }
  99 + return $res;
  100 + }
  101 +
  102 + /**
  103 + * 获取 模板应用
  104 + * @return
  105 + */
  106 + public static function template($req)
  107 + {
  108 + $uid = Session::get('uid');
  109 + $data = [];
  110 + // $page = $req->post('page',1);
  111 + // $size = $req->post('size',10);
  112 + $name = $req->post('name');
  113 + $installType = $req->post('install_type');
  114 + $where = [];
  115 + if($name) $where[] = ['name','like',"%{$name}%"];
  116 + if($installType) $where[] = ['install_type','=',$installType];
  117 + // $data['page'] = $page;
  118 + // $data['size'] = $size;
  119 + $res = Db::table('kt_base_market_app')->field('logo,code,name,app_type,describe,admin_link,install_type,author,target,version,c_time')->where('admin_link','<>','')->where('app_type',4);
  120 + if($where) $res->where($where);
  121 + // $data['count'] = $res->count();
  122 + // $data['item'] = $res->select();
  123 + $res = $res->select()->toArray();
  124 + foreach ($res as $key=>$value) {
  125 + $res[$key]['admin_link'] = $req->domain().$value['admin_link'];
  126 + $isuse = Db::table('kt_base_user_template')->where(['uid'=>$uid,'code'=>$value['code']])->field('id')->find();
  127 + $res[$key]['isuse'] = $isuse?1:0;
  128 + }
  129 + return $res;
  130 + }
  131 +
  132 + /**
  133 + * 使用模板
  134 + * @return
  135 + */
  136 + public static function useTemplate($code)
  137 + {
  138 + $uid = Session::get('uid');
  139 + $template = Db::table('kt_base_user_template')->where(['uid'=>$uid])->find();
  140 + $data = [];
  141 + $data['uid'] = $uid;
  142 + $data['code'] = $code;
  143 + if(isset($template['id'])){
  144 + $data['utime'] = date('Y-m-d H:i:s');
  145 + $res = Db::table('kt_base_user_template')->where(['uid'=>$uid])->update($data);
  146 + }else{
  147 + $data['ctime'] = date('Y-m-d H:i:s');
  148 + $res = Db::table('kt_base_user_template')->insert($data);
  149 + }
  150 + return $res;
  151 + }
  152 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\model\admin\market;
  11 +use think\facade\Db;
  12 +use think\facade\Session;
  13 +use app\base\model\BaseModel;
  14 +use think\facade\Cache;
  15 +
  16 +/*
  17 +* 应用管理
  18 +*/
  19 +class AppManageModel extends BaseModel
  20 +{
  21 + /**
  22 + * 获取 应用列表
  23 + * @return
  24 + */
  25 + public static function list($req)
  26 + {
  27 + // $page = $req->post('page',1);
  28 + // $size = $req->post('size',10);
  29 + $name = $req->post('name');
  30 + $appType = $req->post('app_type');
  31 + $installType = $req->post('install_type');
  32 + $where = [];
  33 + if($name) $where[] = ['name','like',"%{$name}%"];
  34 + if($appType) $where[] = ['app_type','=',$appType];
  35 + if($installType) $where[] = ['install_type','=',$installType];
  36 + // $data['page'] = $page;
  37 + // $data['size'] = $size;
  38 + $res = Db::table('kt_base_market_app')->field('logo,code,name,app_type,describe,install_type,author,version,c_time')->where('app_type','<',3);
  39 + if($where) $res->where($where);
  40 + // $data['count'] = $res->count();
  41 + // $data['item'] = $res->page($page,$size)->select();
  42 + return $res->select();
  43 + }
  44 + /**
  45 + * 删除 应用
  46 + * @return
  47 + */
  48 + public static function delete($req)
  49 + {
  50 + $id = $req->post('id');
  51 + $app = Db::table('kt_base_market_app')->find($id);
  52 + if(!$app) return error('应用不存在');
  53 + $res = Db::table('kt_base_market_app')->delete($id);
  54 + if($res) return success('删除成功');
  55 + return error('删除失败');
  56 + }
  57 +
  58 + /**
  59 + * 应用信息
  60 + */
  61 + public static function appInfo($code)
  62 + {
  63 + $uid = Session::get("uid");
  64 + $info = Db::table("kt_base_market_app")->where(["code"=>$code,'uid'=>$uid])->json(['specs',"label"])->find();
  65 + //初始化数据
  66 + if(!$info){
  67 + $app = self::getMainfestByName($code);
  68 + if(!$app) return null;
  69 + $data = [
  70 + 'uid' => $uid,
  71 + 'code' => $code,
  72 + 'name' => $app['name'],
  73 + 'logo' => $app['logo'],
  74 + 'sort' => 0,
  75 + 'recom' => 0,
  76 + 'try_days' => 7,
  77 + 'scene' => $app['description'] ?? '',
  78 + 'version' => $app['version'] ?? '',
  79 + 'user_link' => $app['userindex'] ?? '',
  80 + 'admin_link' => $app['adminindex'] ?? '',
  81 + 'describe' => $app['description'] ?? '',
  82 + 'c_time' => date('Y-m-d H:i:s'),
  83 + ];
  84 + $nameArr = explode('_', $code);
  85 + if($app['type'] == 2 && in_array('plugin', $nameArr)){
  86 + $key = array_keys($nameArr,'plugin');
  87 + $panmeArr = array_slice($nameArr, 0,$key);
  88 + $pname = implode('_', $panmeArr);
  89 + $data['pid'] = Db::table("kt_base_market_app")->where(["code"=>$pname,'uid'=>$uid])->value('id') ?: 0;
  90 + }
  91 + $id = Db::table("kt_base_market_app")->insertGetId($data);
  92 + $info = Db::table("kt_base_market_app")->find($id);
  93 + }
  94 + if(isset($info['specs'])){
  95 + foreach ($info["specs"] as $key=>$value){
  96 + if(is_int($info["specs"][$key]["duration_type"]))$info["specs"][$key]["duration_type"] = (string)$info["specs"][$key]["duration_type"];
  97 + }
  98 + }
  99 +
  100 + return $info;
  101 + }
  102 +
  103 + /**
  104 + * 设置应用信息
  105 + */
  106 + public static function setApp($args)
  107 + {
  108 + $uid = Session::get("uid");
  109 + $args['uid'] = $uid;
  110 + $info = Db::table("kt_base_market_app")->where(["code"=>$args['code'],'uid'=>$uid])->find();
  111 + if($info){
  112 + $args['u_time'] = date('Y-m-d H:i:s');
  113 + $res = Db::table("kt_base_market_app")->where(["code"=>$args['code'],'uid'=>$uid])->json(['specs',"label"])->update($args);
  114 + }else{
  115 + $args['c_time'] = date('Y-m-d H:i:s');
  116 + $res = Db::table("kt_base_market_app")->json(['specs',"label"])->insert($args);
  117 + }
  118 + return $res;
  119 + }
  120 +
  121 + /**
  122 + * 分类列表
  123 + */
  124 + public static function types($page=1,$size=10)
  125 + {
  126 + $uid = Session::get("uid");
  127 + $res = Db::table('kt_base_market_type')->where(['uid'=>$uid]);
  128 + $data['count'] = $res->count();
  129 + $data['item'] = $res->page($page,$size)->select();
  130 + $data['page'] = $page;
  131 + $data['size'] = $size;
  132 + return $data;
  133 + }
  134 +
  135 + /**
  136 + * 分类信息
  137 + */
  138 + public static function typeInfo($id)
  139 + {
  140 + $uid = Session::get("uid");
  141 + $info = Db::table("kt_base_market_type")->where(['id'=>$id])->find();
  142 + return $info;
  143 + }
  144 +
  145 + /**
  146 + * 添加分类
  147 + */
  148 + public static function addType($args)
  149 + {
  150 + $uid = Session::get("uid");
  151 + $args['uid'] = $uid;
  152 + $args['c_time'] = date('Y-m-d H:i:s');
  153 + $info = Db::table("kt_base_market_type")->where(['name'=>$args['name'],'level'=>1])->find();
  154 + if($info) return '分类名称已存在';
  155 + $res = Db::table("kt_base_market_type")->insert($args);
  156 + return 'ok';
  157 + }
  158 +
  159 + /**
  160 + * 修改分类
  161 + */
  162 + public static function editType($id,$args)
  163 + {
  164 + $uid = Session::get("uid");
  165 + $args['uid'] = $uid;
  166 + $args['u_time'] = date('Y-m-d H:i:s');
  167 + $info = Db::table("kt_base_market_type")->find($id);
  168 + if($info['name'] != $args['name']){
  169 + $checkname = Db::table("kt_base_market_type")->where(['name'=>$args['name'],'level'=>1])->find();
  170 + if($checkname) return ['status'=>'error','msg'=>'分类名称已存在'];
  171 + }
  172 + $res = Db::table("kt_base_market_type")->where(['id'=>$id])->update($args);
  173 + return $res;
  174 + }
  175 +
  176 + /**
  177 + * 删除分类
  178 + */
  179 + public static function delType($id)
  180 + {
  181 + $app = Db::table("kt_base_market_app")->where(["type"=>$id])->find();
  182 + if($app) return ['status'=>'error','msg'=>'删除失败'];
  183 + $res = Db::table("kt_base_market_type")->where(['id'=>$id])->delete();
  184 + return $res;
  185 + }
  186 +
  187 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\model\admin\market;
  11 +use think\facade\Db;
  12 +use think\facade\Session;
  13 +use app\base\model\BaseModel;
  14 +use app\kt_agent\model\admin\agent\ManageModel;
  15 +use think\facade\Cache;
  16 +
  17 +/*
  18 +* 应用管理
  19 +*/
  20 +class OpenuseModel extends BaseModel
  21 +{
  22 + /*
  23 + * 获取所有应用列表
  24 + */
  25 + static public function allApp($req)
  26 + {
  27 + $keyword = $req->post('keyword');
  28 + $res = Db::table("kt_base_market_app")->where('shelves',1);
  29 + if($keyword) $res->where('name',"like","%{$keyword}%");
  30 + $res = $res->json(['specs'])->select();
  31 + return success('所用应用列表',$res);
  32 +
  33 + }
  34 + /*
  35 + * 已购应用列表
  36 + */
  37 + static public function list($req)
  38 + {
  39 + $data = [];
  40 + $uid = Session::get('uid');
  41 + $ids = Db::table('kt_base_user')->where('agid',$uid)->column('id');
  42 + $page = $req->post('page',1);
  43 + $size = $req->post('size',10);
  44 + $keyword = $req->post('keyword');
  45 + $expired_type = $req->post('expired_type');
  46 +
  47 + $res = Db::table("kt_base_user_openapp")
  48 + ->field('id,wid,name,self_title,app_id,code,mend_time,sequence,logo,version,status,create_time')
  49 + ->where('wid','in',$ids);
  50 + if($keyword) $res->where('name','like',"%{$keyword}%");
  51 + if($expired_type) {
  52 + switch ($expired_type) {
  53 + case '1':
  54 + $res->whereTime('mend_time','<=',date("Y-m-d H:i:s"));
  55 + break;
  56 + case '2':
  57 + $res->whereBetweenTime('mend_time',date("Y-m-d H:i:s"),date("Y-m-d H:i:s",strtotime("+7 day")));
  58 + break;
  59 + case '3':
  60 + $res->whereBetweenTime('mend_time',date("Y-m-d H:i:s"),date("Y-m-d H:i:s",strtotime("+30 day")));
  61 + break;
  62 + case '4':
  63 + $res->whereBetweenTime('mend_time',date("Y-m-d H:i:s"),date("Y-m-d H:i:s",strtotime("+90 day")));
  64 + break;
  65 + }
  66 + }
  67 + $data['count'] = $res->count();
  68 + $data['item'] = $res->order('create_time','desc')
  69 + ->page($page,$size)
  70 + ->filter(function($r){
  71 + if(!$r['self_title']) $r['self_title']=$r['name'].$r['wid'];
  72 + $r['username'] = Db::table('kt_base_user')->where('id',$r['wid'])->value('un');
  73 + $specs = Db::table('kt_base_market_app')->where('id',$r['app_id'])->json(['specs'])->find();
  74 + $r['specs'] = $specs ? $specs ['specs']: [];
  75 + $market_app = Db::table("kt_base_market_app")->where('id',$r['app_id'])->find();
  76 + $r['name'] = isset($market_app['name'])?$market_app['name']:$r['name'];
  77 + $r['logo'] = isset($market_app['logo'])?$market_app['logo']:$r['logo'];
  78 + return $r;
  79 + })
  80 + ->select();
  81 + $data['page'] = $page;
  82 + $data['size'] = $size;
  83 + return success('已购应用列表',$data);
  84 + }
  85 +
  86 + /*
  87 + * 开启停止
  88 + */
  89 + static public function updateStatus($req)
  90 + {
  91 + $uid = Session::get('uid');
  92 + $status = $req->post('status');
  93 + $id = $req->post('id');
  94 + if(!$id) return error('参数错误');
  95 + $res = Db::table("kt_base_user_openapp")->where('id',$id)->update([
  96 + 'status' => $status,
  97 + 'update_time' => date("Y-m-d H:i:s")
  98 + ]);
  99 + return success('修改成功');
  100 + }
  101 + /*
  102 + * 获取代理折扣
  103 + */
  104 + static public function discount()
  105 + {
  106 + $uid = Session::get('uid');
  107 + $discount = 10;
  108 + if(class_exists("app\kt_agent\model\admin\agent\ManageModel")){
  109 + $discount = ManageModel::discount($uid) ?: 10;
  110 + }
  111 + return success('代理折扣',$discount);
  112 + }
  113 + /*
  114 + * 续费和购买
  115 + */
  116 + static public function buy($req)
  117 + {
  118 + $uid = Session::get('uid');
  119 + $specsid = $req->post('specsid');
  120 + if(!$specsid) return error('缺少参数specsid');
  121 + $wid = $req->post('wid');
  122 + if(!$wid) return error('缺少参数wid');
  123 + $id = $req->post('app_id');//app_id
  124 + $app = Db::table("kt_base_market_app")->json(['specs'])->find($id);
  125 + if(!$app) return error('无此应用');
  126 + $pid = 0;
  127 + if($app['pid'] != 0){
  128 + $pApp = Db::table("kt_base_market_app")->find($app['pid']);
  129 + $pOpenapp = Db::table("kt_base_user_openapp")->where('wid',$wid)->where('app_id',$pApp['id'])->find();
  130 + if(!$pOpenapp) return error('请先购买主应用');
  131 + $pid = $pOpenapp['id'];
  132 + }
  133 + $specs = [];
  134 + foreach ($app['specs'] as $v) {
  135 + if($v['id'] == $specsid){
  136 + $specs = $v;
  137 + break;
  138 + }
  139 + }
  140 + if(!$specs) return error('此应用无此规格');
  141 + $agent = Db::table("kt_base_agent")->find($uid);
  142 + $bh = date('YmdHis').rand(1000,9999).'|'.$wid;
  143 + $discounty = 10;
  144 + if(class_exists("app\kt_agent\model\admin\agent\ManageModel")){
  145 + $discounty = ManageModel::discount($uid) ?: 10;
  146 + }
  147 + $discount = $discounty/10;
  148 + $discount_price = sprintf("%.2f",$specs['price']*$discount);
  149 + if($agent['balance'] < $discount_price) return error('余额不足');
  150 + $orderId = Db::table("kt_base_agent_apporder")->insertGetId([
  151 + 'uid' => $uid,
  152 + 'wid' => $wid,
  153 + 'app_id' => $id,
  154 + 'bh' => $bh,
  155 + 'specs_id' => $specs['id'],
  156 + 'specs_content' => json_encode($specs,320),
  157 + // 'content' => $content,
  158 + // 'openapp_id' => Db::table("kt_base_user_openapp")->where('wid',$wid)->where('app_id',$id)->value('id'),
  159 + 'price' => $specs['price'],
  160 + 'discount_price' => $discount_price,
  161 + 'create_time'=>date("Y-m-d H:i:s"),
  162 + ]);
  163 + if(!$orderId) return error('开通失败');
  164 + Db::table("kt_base_agent")->where('id',$uid)->update([
  165 + 'balance' => Db::raw('balance-'.$discount_price),
  166 + 'update_time'=>date("Y-m-d H:i:s"),
  167 + ]);
  168 +
  169 + $data = [
  170 + 'wid' => $wid,
  171 + 'name' => $app['name'],
  172 + 'code' => $app['code'],
  173 + 'logo' => $app['logo'],
  174 + 'version' => $app['version'],
  175 + // 'mend_time' => date("Y-m-d H:i:s",strtotime("+".$app['try_days']." day")),
  176 + 'update_time' => date("Y-m-d H:i:s"),
  177 + 'app_id' => $id,
  178 + 'pid' => $pid,
  179 + ];
  180 +
  181 + $has = Db::table("kt_base_user_openapp")->where('wid',$wid)->where('app_id',$id)->find();
  182 + if($has){
  183 + $data['id'] = $has['id'];
  184 + if(strtotime($has['mend_time'] < time())){
  185 + $date = time();
  186 + }else{
  187 + $date = strtotime($has['mend_time']);
  188 + }
  189 + }else{
  190 + $date = time();
  191 + $data['create_time'] = date("Y-m-d H:i:s");
  192 + }
  193 + $content = '';
  194 + switch ($specs['duration_type']) {
  195 + case 2:
  196 + $data['mend_time'] = date("Y-m-d H:i:s",strtotime("+".$specs['duration']." month",$date));
  197 + break;
  198 + case 3:
  199 + $data['mend_time'] = date("Y-m-d H:i:s",strtotime("+".$specs['duration']." year",$date));
  200 + break;
  201 + }
  202 + $res = Db::table("kt_base_user_openapp")->save($data);
  203 + if(!$res){
  204 + Db::table("kt_base_user")->where('id',$wid)->update([
  205 + 'balance' => Db::raw('balance+'.$discount_price)
  206 + ]);
  207 + return error('购买失败');
  208 + }
  209 + return success('购买成功');
  210 + }
  211 +
  212 + /*
  213 + * 用户订单列表(用户在用户后台购买)
  214 + */
  215 + static public function userOrderList($req)
  216 + {
  217 + $uid = Session::get('uid');
  218 + $ids = Db::table('kt_base_user')->where('agid',$uid)->column('id');
  219 + $page = $req->post('page',1);
  220 + $size = $req->post('size',10);
  221 + $keyword = $req->post('keyword');
  222 + $res = Db::table("kt_base_user_order")
  223 + ->alias('o')
  224 + ->field('o.id,o.wid,o.content,o.app_id,o.price,o.create_time,o.openapp_id,o.status,o.balance_pay,o.specs_id,o.bh,o.specs_content,a.name')
  225 + ->leftJoin("kt_base_market_app a","o.app_id=a.id")
  226 + ->json(['o.pecs_content'])
  227 + ->where('o.wid','in',$ids);
  228 + if($keyword) $res->where("a.name",'like',"%{$keyword}%");
  229 + $data['count'] = $res->count();
  230 + $data['item'] = $res->order('o.create_time','desc')
  231 + ->page($page,$size)
  232 + ->select();
  233 + $data['page'] = $page;
  234 + $data['size'] = $size;
  235 + return success('用户订单列表',$data);
  236 + }
  237 +
  238 + /*
  239 + * 开通套餐
  240 + */
  241 + static public function setmealBuy($req)
  242 + {
  243 + $uid = Session::get('uid');
  244 + $specsid = $req->post('specsid');
  245 + $packageid = $req->post('packageid');
  246 + if(!$packageid) return error('缺少参数packageid');
  247 + if(!$specsid) return error('缺少参数specsid');
  248 + $wid = $req->post('wid');
  249 + if(!$wid) return error('缺少参数wid');
  250 + $package = Db::table('kt_base_app_package')->json(['specs','apps'])->find($packageid);
  251 + if(!$package) return error("参数错误");
  252 + $specs = [];
  253 + foreach ($package['specs'] as $v) {
  254 + if($v['id'] == $specsid){
  255 + $specs = $v;
  256 + break;
  257 + }
  258 + }
  259 + if(!$specs) return error('不存在规格');
  260 +
  261 + $agent = Db::table("kt_base_agent")->find($uid);
  262 + $bh = date('YmdHis').rand(1000,9999).'|'.$wid;
  263 + $discounty = 10;
  264 + if(class_exists("app\kt_agent\model\admin\agent\ManageModel")){
  265 + $discounty = ManageModel::discount($uid) ?: 10;
  266 + }
  267 + $discount = $discounty/10;
  268 + $discount_price = sprintf("%.2f",$specs['price']*$discount);
  269 + if($agent['balance'] < $discount_price) return error('余额不足');
  270 + $orderData = [];
  271 +
  272 + foreach ($package['apps'] as $code) {
  273 + $app = Db::table("kt_base_market_app")->where('code',$code)->find();
  274 + $orderData[] = [
  275 + 'uid' => $uid,
  276 + 'wid' => $wid,
  277 + 'app_id' => $app['id'],
  278 + 'bh' => $bh,
  279 + 'specs_id' => $specs['id'],
  280 + 'specs_content' => json_encode($specs,320),
  281 + // 'content' => $content,
  282 + // 'openapp_id' => Db::table("kt_base_user_openapp")->where('wid',$wid)->where('app_id',$id)->value('id'),
  283 + 'price' => $specs['price'],
  284 + 'discount_price' => $discount_price,
  285 + 'create_time'=>date("Y-m-d H:i:s"),
  286 + 'setmeal_type' => 2,
  287 + ];
  288 + }
  289 + $orderRes = Db::table("kt_base_agent_apporder")->insertAll($orderData);
  290 + if(!$orderRes) return error('开通失败');
  291 + //套餐开通记录
  292 + Db::table("kt_base_user_package_recode")->insert([
  293 + "uid" => $uid,
  294 + "wid" => $wid,
  295 + "package_id" => $packageid,
  296 + "specs_id" => $specsid,
  297 + "app"=>json_encode($package['apps']),
  298 + "specs_content"=>json_encode($specs,320),
  299 + "create_time" => date("Y-m-d H:i:s"),
  300 + ]);
  301 + //扣款
  302 + Db::table("kt_base_agent")->where('id',$uid)->update([
  303 + 'balance' => Db::raw('balance-'.$discount_price),
  304 + 'update_time'=>date("Y-m-d H:i:s"),
  305 + ]);
  306 + foreach ($package['apps'] as $code) {
  307 + $app = Db::table("kt_base_market_app")->where('code',$code)->find();
  308 + $data = [
  309 + 'wid' => $wid,
  310 + 'name' => $app['name'],
  311 + 'code' => $app['code'],
  312 + 'logo' => $app['logo'],
  313 + 'version' => $app['version'],
  314 + // 'mend_time' => date("Y-m-d H:i:s",strtotime("+".$app['try_days']." day")),
  315 + 'update_time' => date("Y-m-d H:i:s"),
  316 + 'app_id' => $app['id'],
  317 + ];
  318 +
  319 + $has = Db::table("kt_base_user_openapp")->where('wid',$wid)->where('app_id',$app['id'])->find();
  320 + if($has){
  321 + $data['id'] = $has['id'];
  322 + if(strtotime($has['mend_time'] < time())){
  323 + $date = time();
  324 + }else{
  325 + $date = strtotime($has['mend_time']);
  326 + }
  327 + }else{
  328 + $date = time();
  329 + $data['create_time'] = date("Y-m-d H:i:s");
  330 + }
  331 + $content = '';
  332 + switch ($specs['duration_type']) {
  333 + case 2:
  334 + $data['mend_time'] = date("Y-m-d H:i:s",strtotime("+".$specs['duration']." month",$date));
  335 + break;
  336 + case 3:
  337 + $data['mend_time'] = date("Y-m-d H:i:s",strtotime("+".$specs['duration']." year",$date));
  338 + break;
  339 + }
  340 + $res = Db::table("kt_base_user_openapp")->save($data);
  341 + }
  342 + return success('开通成功');
  343 + }
  344 +
  345 +}
  1 +<?php
  2 +// +----------------------------------------------------------------------
  3 +// | 狂团[kt8.cn]旗下KtAdmin是为独立版SAAS系统而生的快速开发框架.
  4 +// +----------------------------------------------------------------------
  5 +// | [KtAdmin] Copyright (c) 2022 http://ktadmin.cn All rights reserved.
  6 +// +----------------------------------------------------------------------
  7 +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8 +// +----------------------------------------------------------------------
  9 +
  10 +namespace app\base\model\admin\system;
  11 +use think\facade\Db;
  12 +use think\facade\Session;
  13 +use app\base\model\BaseModel;
  14 +use think\facade\Env;
  15 +
  16 +/*
  17 +* 基础功能model
  18 +*/
  19 +class BasicModel extends BaseModel
  20 +{
  21 + /*
  22 + * 获取基本配置信息
  23 + * uid 登录时存储的uid 唯一
  24 + */
  25 + static public function getSite(){
  26 + $uid = Session::get("uid");
  27 + $res = Db::table("kt_base_agent")->where(["id"=>$uid])->find();
  28 + $res['isadmin'] = self::isAdmin($uid) ? true : false;
  29 + $res['debug'] = Env::get('APP_DEBUG') ? 1 : 0;
  30 + return $res;
  31 + }
  32 + /*
  33 + * 修改基本配置信息
  34 + * domain 站点域名
  35 + * webname 站点名称
  36 + * webtitle 站点标题
  37 + * copyright 版权设置
  38 + * register_check 注册验证码(开启,关闭)
  39 + * registration_audit 注册审核(开启,关闭)----目前不确定代理商是否可以设置此项
  40 + * pc_official PC官网(开启,关闭)
  41 + */
  42 + static public function setSite($domain,$webname,$webtitle,$copyright,$register_check,$registration_audit,$pc_official,$debug){
  43 + $uid = Session::get("uid");
  44 + $data["domain"] = $domain;
  45 + $data["webname"] = $webname;
  46 + $data["webtitle"] = $webtitle;
  47 + $data["copyright"] = $copyright;
  48 + $data["register_check"] = $register_check;
  49 + $data["registration_audit"] = $registration_audit;
  50 + $data["pc_official"] = (int)$pc_official?:2;
  51 + $res = Db::table("kt_base_agent")->where(["id"=>$uid])->save($data);
  52 + if(self::isAdmin($uid)){
  53 + $debugt = $debug ? 'true' : 'false';
  54 + self::setDebug($debugt);
  55 + }
  56 + return $res;
  57 + }
  58 + static public function setDebug($debugt){
  59 + $env = file_get_contents(root_path().'.env');
  60 + $envArr = explode("\n", $env);
  61 + foreach ($envArr as &$v) {
  62 + $vArr = explode('=', $v);
  63 + if(count($vArr)>0){
  64 + if(trim($vArr[0]) == "APP_DEBUG"){
  65 + $v = "APP_DEBUG = ".$debugt;
  66 + break;
  67 + }
  68 + }
  69 + }
  70 + $str = implode("\n", $envArr);
  71 + file_put_contents(root_path().'.env',$str);
  72 + return "ok";
  73 + }
  74 + /**
  75 + * logo设置
  76 + * user_logo 用户后台LOGO
  77 + * login_logo 登录页LOGO
  78 + * pc_logo PC官网LOGO
  79 + */
  80 + static public function setLogo($user_logo=NULL,$login_logo=NULL,$pc_logo=NULL){
  81 + $uid = Session::get("uid");
  82 + $data["user_logo"] = $user_logo;
  83 + $data["login_logo"] = $login_logo;
  84 + $data["pc_logo"] = $pc_logo;
  85 + $res = Db::table("kt_base_agent")->where(["id"=>$uid])->save($data);
  86 +
  87 + return $res;
  88 + }
  89 +
  90 +
  91 + /**
  92 + * login_background 背景图设置
  93 + */
  94 + static public function setBackground($login_background=NULL,$login_background_status){
  95 + $uid = Session::get("uid");
  96 + $data["login_background_status"] = $login_background_status;
  97 + $data["login_background"] = $login_background;
  98 + $res = Db::table("kt_base_agent")->where(["id"=>$uid])->save($data);
  99 +
  100 + return $res;
  101 + }
  102 +
  103 + /**
  104 + * 设置其他设置
  105 + * kf_code 客服二维码(上传图片)
  106 + * gzh_code 公众号二维码 (上传图片)
  107 + * company_name 公司名称
  108 + * company_address 公司地址
  109 + * telephone 联系电话
  110 + * qq 联系QQ
  111 + * record_number 备案号
  112 + * key_word seo关键词
  113 + * describe seo描述
  114 + */
  115 + static public function setAdditional($kf_code=NULL,$gzh_code=NULL,$company_name=NULL,$company_address=NULL,$telephone=NULL,$qq=NULL,$record_number=NULL,$key_word=NULL,$describe=NULL){
  116 + $uid = Session::get("uid");
  117 + $data["kf_code"] = $kf_code;
  118 + $data["gzh_code"] = $gzh_code;
  119 + $data["company_name"] = $company_name;
  120 + $data["company_address"] = $company_address;
  121 + $data["telephone"] = $telephone;
  122 + $data["qq"] = $qq;
  123 + $data["record_number"] = $record_number;
  124 + $data["key_word"] = $key_word;
  125 + $data["describe"] = $describe;
  126 + $res = Db::table("kt_base_agent")->where(["id"=>$uid])->save($data);
  127 +
  128 + return $res;
  129 + }
  130 +
  131 +
  132 +}