From 10eb7d07dfac3c1b70cc21dcf51069de38a2bd44 Mon Sep 17 00:00:00 2001 From: wh <382379437@qq.com> Date: Wed, 10 Jul 2024 23:52:13 +0800 Subject: [PATCH] test --- .../vendor/wanghua/general-utility-tools-php | 1 - .../general-utility-tools-php/.gitignore | 6 + .../general-utility-tools-php/README.en.md | 37 + .../general-utility-tools-php/README.md | 142 + .../general-utility-tools-php/composer.json | 25 + .../general-utility-tools-php/src/Date.php | 396 ++ .../general-utility-tools-php/src/Mmodel.php | 125 + .../general-utility-tools-php/src/PinYin.php | 94 + .../src/SundryConfig.php | 50 + .../src/Validate.php | 360 ++ .../src/alipay/AlipayLogic.php | 82 + .../src/alipay/pay/AlipayScanPay.php | 195 + .../src/alipay/transfer/AlipayTransfer.php | 143 + .../src/alipay/transfer/TransferConfig.php | 63 + .../general-utility-tools-php/src/api/Api.php | 425 ++ .../src/api/ApiDocument.php | 264 + .../src/api/BaseApi.php | 230 + .../src/api/BaseLibApi.php | 54 + .../src/api/BaseUserLogic.php | 193 + .../general-utility-tools-php/src/apk/Apk.php | 79 + .../src/apk/ApkParser.php | 421 ++ .../src/coin/Coin.php | 103 + .../src/db/DbCacheUtility.php | 390 ++ .../src/db/RedisUtility.php | 109 + .../src/db/SqlOperateLog.php | 55 + .../src/db/es/Elasticsearch.php | 262 + .../src/db/es/README.md | 1340 +++++ .../src/db/mysql/README.MD | 6 + .../src/db/mysql/lib/Field.php | 304 ++ .../src/db/mysql/lib/Table.php | 162 + .../src/douyin/BaseDouYin.php | 15 + .../src/douyin/DouYinMiniGame.php | 193 + .../src/encrypt/TripleDES.php | 88 + .../src/errorcode/AuthError.php | 20 + .../src/errorcode/Code.php | 84 + .../src/errorcode/DbError.php | 30 + .../src/errorcode/EmailError.php | 19 + .../src/errorcode/FileUploadError.php | 29 + .../src/errorcode/LoginError.php | 19 + .../src/errorcode/RequestError.php | 27 + .../src/errorcode/SmsError.php | 26 + .../src/errorcode/SystemError.php | 15 + .../src/es/Elasticsearch.php | 264 + .../src/es/README.md | 1340 +++++ .../src/exception/BaseException.php | 16 + .../src/exception/README.md | 27 + .../src/exception/SystemException.php | 60 + .../src/exception/api/ApiException.php | 21 + .../exception/request/RequestException.php | 18 + .../exception/response/ResponseException.php | 19 + .../src/fastadmin/FastadminTools.php | 53 + .../src/file/File.php | 236 + .../src/file/README.MD | 5 + .../src/file/upload/FileUpload.php | 764 +++ .../src/file/upload/README.MD | 1 + .../src/framework/BaseController.php | 210 + .../src/framework/README.MD | 1 + .../src/framework/base/BaseAuthController.php | 80 + .../framework/base/BasePublicController.php | 29 + .../base/BaseWechatAuthController.php | 194 + .../general-utility-tools-php/src/ftp/Ftp.php | 213 + .../src/ftp/README.md | 21 + .../src/gpt/chat/BaseChat.php | 35 + .../C62239E6C0F995AE1FDC00D18B7905EAC.php | 1 + .../src/gpt/chat/ChatGPT.php | 175 + .../F37A49CDED4199801B05D5FFFAF78E010.php | 141 + .../src/gpt/chat/FastGPT.php | 146 + .../src/html/Html.php | 224 + .../src/html/Htmlcontent.php | 126 + .../src/http/Curl.php | 575 ++ .../src/image/Image.php | 47 + .../src/log/BaseLog.php | 82 + .../src/log/Driver.php | 134 + .../src/log/File.php | 41 + .../general-utility-tools-php/src/log/Log.php | 21 + .../src/log/Logger.php | 158 + .../src/log/Mysql.php | 41 + .../src/log/driver/Base.php | 90 + .../src/log/driver/Email.php | 206 + .../src/log/driver/File.php | 157 + .../src/log/driver/Mysql.php | 158 + .../src/log/example/Logger.php | 168 + .../src/log/example/LoggerBehavior.php | 54 + .../src/log/example/README.MD | 70 + .../src/log/example/SundryConfigModel.php | 30 + .../src/log/example/tags.php | 56 + .../src/md5rsa/Md5RSA.php | 119 + .../src/mysql/README.MD | 6 + .../src/mysql/lib/Field.php | 314 ++ .../src/mysql/lib/Table.php | 181 + .../src/oss/alicloud/AliyunOSS.php | 140 + .../src/oss/alicloud/Bucket.php | 101 + .../src/oss/alicloud/Objects.php | 318 ++ .../src/oss/huawei/obs/Config.php | 29 + .../src/oss/huawei/obs/InitObs.php | 52 + .../src/oss/huawei/obs/README.md | 4 + .../src/oss/huawei/obs/service/BaseObs.php | 40 + .../oss/huawei/obs/service/BucketManage.php | 288 + .../src/oss/huawei/obs/service/Cors.php | 87 + .../src/oss/huawei/obs/service/Download.php | 79 + .../oss/huawei/obs/service/ObjectManage.php | 231 + .../src/oss/huawei/obs/service/Upload.php | 125 + .../oss/huawei/obs/service/VersionControl.php | 80 + .../src/pay/README.md | 41 + .../src/pay/shoudanpay/BasePay.php | 78 + .../src/pay/shoudanpay/ReceiveOrderPay.php | 52 + .../pay/shouyinbaopay/ShouYinBaoUnifyPay.php | 258 + .../src/phpmailer/AliYunEmail.php | 112 + .../src/phpmailer/Exception.php | 39 + .../src/phpmailer/Mail.php | 220 + .../src/phpmailer/PHPMailer.php | 4770 +++++++++++++++++ .../src/phpmailer/README.md | 95 + .../src/phpmailer/SMTP.php | 1370 +++++ .../src/tool/Bank.php | 249 + .../src/tool/EmailTool.php | 357 ++ .../general-utility-tools-php/src/tool/Ip.php | 229 + .../src/tool/KuaidiTools.php | 232 + .../src/tool/MySqlTools.php | 78 + .../src/tool/Qrcode.php | 55 + .../src/tool/Tools.php | 2327 ++++++++ .../src/tool/Video.php | 123 + .../src/twitter/Twitter.php | 106 + .../src/wechat/Applet.php | 164 + .../src/wechat/TmpWexinauth.php | 101 + .../src/wechat/UserAuth.php | 323 ++ .../src/wechat/WechatLogic.php | 307 ++ .../src/wechat/WechatMsgPush.php | 129 + .../src/wechat/WechatMsgPushLogicDemo.php | 161 + .../src/wechat/WechatPayLogic.php | 135 + .../vendor/wanghua/general-utility-tools-php | 1 - .../general-utility-tools-php/.gitignore | 6 + .../general-utility-tools-php/README.en.md | 37 + .../general-utility-tools-php/README.md | 142 + .../general-utility-tools-php/composer.json | 25 + .../general-utility-tools-php/src/Date.php | 396 ++ .../general-utility-tools-php/src/Mmodel.php | 125 + .../general-utility-tools-php/src/PinYin.php | 94 + .../src/SundryConfig.php | 50 + .../src/Validate.php | 360 ++ .../src/alipay/AlipayLogic.php | 82 + .../src/alipay/pay/AlipayScanPay.php | 195 + .../src/alipay/transfer/AlipayTransfer.php | 143 + .../src/alipay/transfer/TransferConfig.php | 63 + .../general-utility-tools-php/src/api/Api.php | 425 ++ .../src/api/ApiDocument.php | 264 + .../src/api/BaseApi.php | 230 + .../src/api/BaseLibApi.php | 54 + .../src/api/BaseUserLogic.php | 193 + .../general-utility-tools-php/src/apk/Apk.php | 79 + .../src/apk/ApkParser.php | 421 ++ .../src/coin/Coin.php | 103 + .../src/db/DbCacheUtility.php | 390 ++ .../src/db/RedisUtility.php | 109 + .../src/db/SqlOperateLog.php | 55 + .../src/db/es/Elasticsearch.php | 262 + .../src/db/es/README.md | 1340 +++++ .../src/db/mysql/README.MD | 6 + .../src/db/mysql/lib/Field.php | 304 ++ .../src/db/mysql/lib/Table.php | 162 + .../src/douyin/BaseDouYin.php | 15 + .../src/douyin/DouYinMiniGame.php | 193 + .../src/encrypt/TripleDES.php | 88 + .../src/errorcode/AuthError.php | 20 + .../src/errorcode/Code.php | 84 + .../src/errorcode/DbError.php | 30 + .../src/errorcode/EmailError.php | 19 + .../src/errorcode/FileUploadError.php | 29 + .../src/errorcode/LoginError.php | 19 + .../src/errorcode/RequestError.php | 27 + .../src/errorcode/SmsError.php | 26 + .../src/errorcode/SystemError.php | 15 + .../src/es/Elasticsearch.php | 264 + .../src/es/README.md | 1340 +++++ .../src/exception/BaseException.php | 16 + .../src/exception/README.md | 27 + .../src/exception/SystemException.php | 60 + .../src/exception/api/ApiException.php | 21 + .../exception/request/RequestException.php | 18 + .../exception/response/ResponseException.php | 19 + .../src/fastadmin/FastadminTools.php | 53 + .../src/file/File.php | 236 + .../src/file/README.MD | 5 + .../src/file/upload/FileUpload.php | 764 +++ .../src/file/upload/README.MD | 1 + .../src/framework/BaseController.php | 210 + .../src/framework/README.MD | 1 + .../src/framework/base/BaseAuthController.php | 80 + .../framework/base/BasePublicController.php | 29 + .../base/BaseWechatAuthController.php | 194 + .../general-utility-tools-php/src/ftp/Ftp.php | 213 + .../src/ftp/README.md | 21 + .../src/gpt/chat/BaseChat.php | 35 + .../C62239E6C0F995AE1FDC00D18B7905EAC.php | 1 + .../src/gpt/chat/ChatGPT.php | 175 + .../F37A49CDED4199801B05D5FFFAF78E010.php | 141 + .../src/gpt/chat/FastGPT.php | 146 + .../src/html/Html.php | 224 + .../src/html/Htmlcontent.php | 126 + .../src/http/Curl.php | 575 ++ .../src/image/Image.php | 47 + .../src/log/BaseLog.php | 82 + .../src/log/Driver.php | 134 + .../src/log/File.php | 41 + .../general-utility-tools-php/src/log/Log.php | 21 + .../src/log/Logger.php | 158 + .../src/log/Mysql.php | 41 + .../src/log/driver/Base.php | 90 + .../src/log/driver/Email.php | 206 + .../src/log/driver/File.php | 157 + .../src/log/driver/Mysql.php | 158 + .../src/log/example/Logger.php | 168 + .../src/log/example/LoggerBehavior.php | 54 + .../src/log/example/README.MD | 70 + .../src/log/example/SundryConfigModel.php | 30 + .../src/log/example/tags.php | 56 + .../src/md5rsa/Md5RSA.php | 119 + .../src/mysql/README.MD | 6 + .../src/mysql/lib/Field.php | 314 ++ .../src/mysql/lib/Table.php | 181 + .../src/oss/alicloud/AliyunOSS.php | 140 + .../src/oss/alicloud/Bucket.php | 101 + .../src/oss/alicloud/Objects.php | 318 ++ .../src/oss/huawei/obs/Config.php | 29 + .../src/oss/huawei/obs/InitObs.php | 52 + .../src/oss/huawei/obs/README.md | 4 + .../src/oss/huawei/obs/service/BaseObs.php | 40 + .../oss/huawei/obs/service/BucketManage.php | 288 + .../src/oss/huawei/obs/service/Cors.php | 87 + .../src/oss/huawei/obs/service/Download.php | 79 + .../oss/huawei/obs/service/ObjectManage.php | 231 + .../src/oss/huawei/obs/service/Upload.php | 125 + .../oss/huawei/obs/service/VersionControl.php | 80 + .../src/pay/README.md | 41 + .../src/pay/shoudanpay/BasePay.php | 78 + .../src/pay/shoudanpay/ReceiveOrderPay.php | 52 + .../pay/shouyinbaopay/ShouYinBaoUnifyPay.php | 258 + .../src/phpmailer/AliYunEmail.php | 112 + .../src/phpmailer/Exception.php | 39 + .../src/phpmailer/Mail.php | 220 + .../src/phpmailer/PHPMailer.php | 4770 +++++++++++++++++ .../src/phpmailer/README.md | 95 + .../src/phpmailer/SMTP.php | 1370 +++++ .../src/tool/Bank.php | 249 + .../src/tool/EmailTool.php | 357 ++ .../general-utility-tools-php/src/tool/Ip.php | 229 + .../src/tool/KuaidiTools.php | 232 + .../src/tool/MySqlTools.php | 78 + .../src/tool/Qrcode.php | 55 + .../src/tool/Tools.php | 2327 ++++++++ .../src/tool/Video.php | 123 + .../src/twitter/Twitter.php | 106 + .../src/wechat/Applet.php | 164 + .../src/wechat/TmpWexinauth.php | 101 + .../src/wechat/UserAuth.php | 323 ++ .../src/wechat/WechatLogic.php | 307 ++ .../src/wechat/WechatMsgPush.php | 129 + .../src/wechat/WechatMsgPushLogicDemo.php | 161 + .../src/wechat/WechatPayLogic.php | 135 + 258 files changed, 54986 insertions(+), 2 deletions(-) delete mode 160000 digital_doctor/vendor/wanghua/general-utility-tools-php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/.gitignore create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/README.en.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/composer.json create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/Date.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/Mmodel.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/PinYin.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/SundryConfig.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/Validate.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/AlipayLogic.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/pay/AlipayScanPay.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/AlipayTransfer.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/TransferConfig.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/Api.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/ApiDocument.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseApi.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseLibApi.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseUserLogic.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/Apk.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/ApkParser.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/coin/Coin.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/DbCacheUtility.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/RedisUtility.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/SqlOperateLog.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/Elasticsearch.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/README.MD create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Field.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Table.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/douyin/BaseDouYin.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/douyin/DouYinMiniGame.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/encrypt/TripleDES.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/AuthError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/Code.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/DbError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/EmailError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/FileUploadError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/LoginError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/RequestError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/SmsError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/SystemError.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/es/Elasticsearch.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/es/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/BaseException.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/SystemException.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/api/ApiException.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/request/RequestException.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/response/ResponseException.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/fastadmin/FastadminTools.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/File.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/README.MD create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/FileUpload.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/README.MD create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/BaseController.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/README.MD create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BaseAuthController.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BasePublicController.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BaseWechatAuthController.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/Ftp.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/BaseChat.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/C62239E6C0F995AE1FDC00D18B7905EAC.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/ChatGPT.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/F37A49CDED4199801B05D5FFFAF78E010.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/FastGPT.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/html/Html.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/html/Htmlcontent.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/http/Curl.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/image/Image.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/BaseLog.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/Driver.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/File.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/Log.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/Logger.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/Mysql.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/driver/Base.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/driver/Email.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/driver/File.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/driver/Mysql.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/example/Logger.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/example/LoggerBehavior.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/example/README.MD create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/example/SundryConfigModel.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/log/example/tags.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/md5rsa/Md5RSA.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/mysql/README.MD create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/mysql/lib/Field.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/mysql/lib/Table.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/alicloud/AliyunOSS.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/alicloud/Bucket.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/alicloud/Objects.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/Config.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/InitObs.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/BaseObs.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/BucketManage.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/Cors.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/Download.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/ObjectManage.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/Upload.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/VersionControl.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/pay/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/pay/shoudanpay/BasePay.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/pay/shoudanpay/ReceiveOrderPay.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/pay/shouyinbaopay/ShouYinBaoUnifyPay.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/phpmailer/AliYunEmail.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/phpmailer/Exception.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/phpmailer/Mail.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/phpmailer/PHPMailer.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/phpmailer/README.md create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/phpmailer/SMTP.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/Bank.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/EmailTool.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/Ip.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/KuaidiTools.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/MySqlTools.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/Qrcode.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/Tools.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/tool/Video.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/twitter/Twitter.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/wechat/Applet.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/wechat/TmpWexinauth.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/wechat/UserAuth.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/wechat/WechatLogic.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/wechat/WechatMsgPush.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/wechat/WechatMsgPushLogicDemo.php create mode 100644 digital_doctor/vendor/wanghua/general-utility-tools-php/src/wechat/WechatPayLogic.php delete mode 160000 digital_doctor_admin/vendor/wanghua/general-utility-tools-php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/.gitignore create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/README.en.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/composer.json create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/Date.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/Mmodel.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/PinYin.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/SundryConfig.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/Validate.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/alipay/AlipayLogic.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/alipay/pay/AlipayScanPay.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/AlipayTransfer.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/TransferConfig.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/api/Api.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/api/ApiDocument.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/api/BaseApi.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/api/BaseLibApi.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/api/BaseUserLogic.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/apk/Apk.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/apk/ApkParser.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/coin/Coin.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/DbCacheUtility.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/RedisUtility.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/SqlOperateLog.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/es/Elasticsearch.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/es/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/mysql/README.MD create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Field.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Table.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/douyin/BaseDouYin.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/douyin/DouYinMiniGame.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/encrypt/TripleDES.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/AuthError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/Code.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/DbError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/EmailError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/FileUploadError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/LoginError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/RequestError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/SmsError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/errorcode/SystemError.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/es/Elasticsearch.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/es/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/exception/BaseException.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/exception/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/exception/SystemException.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/exception/api/ApiException.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/exception/request/RequestException.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/exception/response/ResponseException.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/fastadmin/FastadminTools.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/file/File.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/file/README.MD create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/file/upload/FileUpload.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/file/upload/README.MD create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/framework/BaseController.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/framework/README.MD create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/framework/base/BaseAuthController.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/framework/base/BasePublicController.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/framework/base/BaseWechatAuthController.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/ftp/Ftp.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/ftp/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/gpt/chat/BaseChat.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/gpt/chat/C62239E6C0F995AE1FDC00D18B7905EAC.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/gpt/chat/ChatGPT.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/gpt/chat/F37A49CDED4199801B05D5FFFAF78E010.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/gpt/chat/FastGPT.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/html/Html.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/html/Htmlcontent.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/http/Curl.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/image/Image.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/BaseLog.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/Driver.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/File.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/Log.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/Logger.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/Mysql.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/driver/Base.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/driver/Email.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/driver/File.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/driver/Mysql.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/example/Logger.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/example/LoggerBehavior.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/example/README.MD create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/example/SundryConfigModel.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/log/example/tags.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/md5rsa/Md5RSA.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/mysql/README.MD create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/mysql/lib/Field.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/mysql/lib/Table.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/alicloud/AliyunOSS.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/alicloud/Bucket.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/alicloud/Objects.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/Config.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/InitObs.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/BaseObs.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/BucketManage.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/Cors.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/Download.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/ObjectManage.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/Upload.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/oss/huawei/obs/service/VersionControl.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/pay/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/pay/shoudanpay/BasePay.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/pay/shoudanpay/ReceiveOrderPay.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/pay/shouyinbaopay/ShouYinBaoUnifyPay.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/phpmailer/AliYunEmail.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/phpmailer/Exception.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/phpmailer/Mail.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/phpmailer/PHPMailer.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/phpmailer/README.md create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/phpmailer/SMTP.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/Bank.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/EmailTool.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/Ip.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/KuaidiTools.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/MySqlTools.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/Qrcode.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/Tools.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/tool/Video.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/twitter/Twitter.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/wechat/Applet.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/wechat/TmpWexinauth.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/wechat/UserAuth.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/wechat/WechatLogic.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/wechat/WechatMsgPush.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/wechat/WechatMsgPushLogicDemo.php create mode 100644 digital_doctor_admin/vendor/wanghua/general-utility-tools-php/src/wechat/WechatPayLogic.php diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php b/digital_doctor/vendor/wanghua/general-utility-tools-php deleted file mode 160000 index f31ce1f..0000000 --- a/digital_doctor/vendor/wanghua/general-utility-tools-php +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f31ce1f3910b7522d37a796759722f7f4c785dfe diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/.gitignore b/digital_doctor/vendor/wanghua/general-utility-tools-php/.gitignore new file mode 100644 index 0000000..a5a8472 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/.gitignore @@ -0,0 +1,6 @@ +.idea +.git + +/.git +/.idea +/composer.lock diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/README.en.md b/digital_doctor/vendor/wanghua/general-utility-tools-php/README.en.md new file mode 100644 index 0000000..4c9c21a --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/README.en.md @@ -0,0 +1,37 @@ +# general_utility_tools_php + +#### Description +php常用工具箱 +general utility tool for php + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/README.md b/digital_doctor/vendor/wanghua/general-utility-tools-php/README.md new file mode 100644 index 0000000..f1bee76 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/README.md @@ -0,0 +1,142 @@ +# general_utility_tools_php + +#### 介绍 + +[PHP常用通用工具库] + +一、常用验证类库 +1. 验证手机号是否正确 +2. 验证邮箱 +3. 验证身份证号码 +4. 是否字母或数字 +5. 是否是小数格式 +6. 更多功能请参考代码 + +二、PHP日期处理工具 +1. 日期加上N年、月、日、时、分、秒,得到计算后的时间 +2. 两个日期相减得到天、时、分、秒(没有两个日期相加一说) +3. 更多更完善功能敬请期待...... + +三、更多类库参考本类库目录 +1. 每个目录都有使用说明. + +#### 软件架构 + +每一种工具独立为一个功能类库。 +#### 软件要求 + thinkphp5.0+,PHP7.1+ + + +#### 安装教程 + composer require wanghua/general-utility-tools-php dev-master + +###### 注意:如果总是安装失败,可切换国内或者国外源;如果是找不到版本则加上dev-master尝试 +###### 注意:如果总是安装失败,可卸载此包重新安装,卸载指令:composer remove wanghua/general-utility-tools-php +###### 注意:如果总是不能提交 vendor下面的一个文件夹(或文件),请参考这篇文章解决:https://blog.csdn.net/qq_15941409/article/details/113184021 + +### 一、常用验证类库使用说明 +##### 初始化 + + //静态方法无需实例化直接调用 + +##### 验证参数是否是小数格式 + $str = '1.223'; + var_dump(Validate::is_float_number($str)); + +##### 验证参数是否字母或数字 + $str = 'qwer#199'; + var_dump(Validate::is_letter_or_number($str)); + +###### 注: 更多功能请参考源码 + +### 二、PHP日期处理工具使用说明 + +##### 初始化 + $date = (new Date()); + $date->date_format = 'Y-m-d H:i:s';//设置格式,默认Y-m-d H:i:s + +##### 日期类型参数(第2个参数)可选项: + //分、时、天、周、月、年 + protected $data_type = [ + 'm' =>'minute',//分钟 + 'minute' =>'minute',//分钟 + 'h' =>'hour',//小时 + 'hour' =>'hour',//小时 + 'd' =>'day',//天 + 'day' =>'day',//天 + 'w' =>'week',//周 + 'week' =>'week',//周 + 'M' =>'month',//月 + 'month' =>'month',//月 + 'y' =>'year',//年 + 'year' =>'year',//年 + ]; + + +##### 在当前时间基础上加3天(第三个参数不传默认使用当前时间) + $res = $date->addTime(3, 'd');//支持单词和字母,例如:d表示天,day也表示天 + dump($res); + +##### 在当前时间基础上加1小时(第三个参数不传默认使用当前时间) + $res = $date->addTime(1, 'h');//支持单词和字母,例如:h表示小时,hour也表示小时 + dump($res); + +##### 在指定时间基础上加1小时 + $res = $date->addTime(1, 'h', strtotime('2010-10-01 12:00:10')); + dump($res); + +##### 在指定时间基础上减1个月 (注意:月是大写M字母,分钟是小写m字母) + $res = $date->reduceTime(1, 'M', strtotime('2010-10-01 12:00:10')); + dump($res); + +##### 在指定时间基础上减20分钟 (注意:分钟是小写m字母) + $res = $date->reduceTime(20, 'm', strtotime('2010-10-01 12:00:10')); + dump($res); + +##### 在指定时间基础上减1年 + $res = $date->reduceTime(1, 'y', strtotime('2010-10-01 12:00:10')); + dump($res); + +### 日期时间相减 + + //时间相减返回的时间类型 秒、分、时、天 默认返回秒 + protected $time_type = [ + 's' =>1,//秒 + 'second' =>1,//秒 + 'm' =>60,//分钟 + 'minute' =>60,//分钟 + 'h' =>3600,//小时 + 'hour' =>3600,//小时 + 'd' =>86400,//天 + 'day' =>86400,//天 + ]; + + $start_time = '2010-05-01 12:30:00'; + $end_time = '2010-10-28 12:30:00'; + + //结束时间减去开始时间得到秒数 (返回类型参考上方配置) + $res = $date->timeReduceTime($end_time, $start_time); + dump($res); + + //结束时间减去开始时间得到天数 (返回类型参考上方配置) + $res = $date->timeReduceTime($end_time, $start_time, 'day'); + dump($res); + +###### 注: 更多功能请参考源码 + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 +5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/composer.json b/digital_doctor/vendor/wanghua/general-utility-tools-php/composer.json new file mode 100644 index 0000000..510c7cb --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/composer.json @@ -0,0 +1,25 @@ +{ + "type": "library", + "name": "wanghua/general-utility-tools-php", + "homepage": "https://gitee.com/drop_drop/general_utility_tools_php.git", + "description": "general utility tools for thinkPHP", + "license": "Apache-2.0", + "version":"1.0.1", + "keywords": ["general-utility-tools","php tool","common tool"], + "authors": [ + { + "name": "wanghua", + "email": "wanghua@qq.com", + "homepage": "https://blog.csdn.net/qq_15941409" + } + ], + "minimum-stability": "stable", + "require": { + "ext-json": "*" + }, + "autoload": { + "psr-4": { + "wanghua\\general_utility_tools_php\\": "src/" + } + } +} diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Date.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Date.php new file mode 100644 index 0000000..072cfb9 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Date.php @@ -0,0 +1,396 @@ +'minute',//分钟 + 'minute' =>'minute',//分钟 + 'h' =>'hour',//小时 + 'hour' =>'hour',//小时 + 'd' =>'day',//天 + 'day' =>'day',//天 + 'w' =>'week',//周 + 'week' =>'week',//周 + 'M' =>'month',//月 + 'month' =>'month',//月 + 'y' =>'year',//年 + 'year' =>'year',//年 + ]; + //秒、分、时、天 + protected $time_type = [ + 's' =>1,//秒 + 'second' =>1,//秒 + 'm' =>60,//分钟 + 'minute' =>60,//分钟 + 'h' =>3600,//小时 + 'hour' =>3600,//小时 + 'd' =>86400,//天 + 'day' =>86400,//天 + ]; + /** + * desc:日期时间加N + * + * 【注意】 + * 请在计算月时使用$date->date_format = 'Y-m'防止跳月份 + * 例如:2020-03-31月基础上加一个月,在默认$date->date_format='Y-m-d H:i:s'时,会跳到2020-05-01 + * + * author:wh + * @param int $times 相加的时间数量 整型 + * @param string $date_type 要相加的时间类型 可选值:m 分钟;h 小时;d 天;w 周;M 月;y 年 + * @param int $default_time 时间戳,默认当前时间 + * @return false|string 返回$this->date_format格式,可根据需要设定格式 + */ + function addTime(int $times, string $date_type, int $default_time=0){ + return date($this->date_format, strtotime("+{$times} {$this->data_type[$date_type]}", $default_time?$default_time:time())); + } + + /** + * desc:日期时间减N + * + * 【注意】 + * 请在计算月时使用$date->date_format = 'Y-m'防止跳月份 + * 例如:2020-03-31月基础上加一个月,在默认$date->date_format='Y-m-d H:i:s'时,会跳到2020-05-01 + * + * author:wh + * @param int $times 减去的时间数量 整型 + * @param string $date_type 要相减的时间类型 可选值:m 分钟;h 小时;d 天;w 周;M 月;y 年 + * @param int $default_time 时间戳,默认当前时间 + * @return false|string 返回$this->date_format格式,可根据需要设定格式 + */ + function reduceTime(int $times, string $date_type, int $default_time=0){ + return date($this->date_format, strtotime("-{$times} {$this->data_type[$date_type]}", $default_time?$default_time:time())); + } + + /** + * desc:日期时间相减,通常结束时间大于开始时间 + * author:wh + * @param string $end_time 结束时间 + * @param string $start_time 开始时间 + * @param string $return_type 日期时间相减后得到的时间类型,可能是小数。可选值:s 秒;m 分钟;h 小时;d;天 + * @return float|int 返回计算后的天、时、分、秒数 + */ + function timeReduceTime(string $end_time, string $start_time, string $return_type='s'){ + return (strtotime($end_time) - strtotime($start_time)) / $this->time_type[$return_type]; + } + + /** + * desc:日期减日期, 返回月数或年数 + * + * author:wh + * @param string $start_time 开始时间 + * @param string $end_time 结束时间 + * @param string $return_type M 返回一共有多少个月,y 返回有多少个年 + * @return float|int + */ + function dateCutDate(string $start_time, string $end_time, string $return_type='M'){ + $e = date_create($end_time); + + $s = date_create($start_time); + + $diff = date_diff($e, $s); + + //计算月份 + if ($diff->y > 0) { + $m = $diff->y * 12 + $diff->m; + }else{ + $m = $diff->m; + } + return $return_type=='M'?$m:$diff->y; + } + + /** + * desc:日期相减得到月数 + * 注意:不是计算的时间戳,而是计算的月份差值 + * author:wh + * @param string $start_time + * @param string $end_time + * @return false|float|int|string + */ + function dateCutMonth(string $start_time, string $end_time){ + $start_y = date('Y', strtotime($start_time)); + $end_y = date('Y', strtotime($end_time)); + $start_m = date('m', strtotime($start_time)); + $end_m = date('m', strtotime($end_time)); + $ym = ($end_y-$start_y) * 12; + return $ym - $start_m + $end_m; + } + /** + * desc:日期相减得到年数 + * 注意:不是计算的时间戳,而是计算的年份差值 + * author:wh + * @param string $start_time + * @param string $end_time + * @return false|float|int|string + */ + function dateCutYear(string $start_time, string $end_time){ + $start_y = date('Y', strtotime($start_time)); + $end_y = date('Y', strtotime($end_time)); + return ($end_y-$start_y) * 12; + } + /** + * desc:返回年中第几天 + * author:wh + * @param string $month 指定月份 + * @param string $day 指定日 + * @param string $year 指定年份 + * @return false|string + */ + function get_day_Year(string $month, string $day, string $year){ + return date('z',mktime(0,0,0,$month,$day,$year)); + } + + /** + * desc:今天的开始时间 + * author:wh + * @return false|string + */ + function beginToday(){ + return date('Y-m-d').' 00:00:00'; + } + /** + * desc:今天的结束时间 + * author:wh + * @return false|string + */ + function endToday(){ + return date('Y-m-d').' 23:59:59'; + } + + /** + * desc:昨天的开始时间 + * author:wh + * @return string + */ + function beginYesterday(){ + return date('Y-m-d', strtotime('-1 day')).' 00:00:00'; + } + + /** + * desc:昨天的结束时间 + * author:wh + * @return string + */ + function endYesterday(){ + return date('Y-m-d', strtotime('-1 day')).' 23:59:59'; + } + + /** + * desc:前天的开始时间 + * author:wh + * @return string + */ + function beginBeforeYesterday(){ + return date('Y-m-d', strtotime('-2 day')).' 00:00:00'; + } + + /** + * desc:前天的结束时间 + * author:wh + * @return string + */ + function endBeforeYesterday(){ + return date('Y-m-d', strtotime('-2 day')).' 23:59:59'; + } + + /** + * 本周的开始日期 + * + * @param bool $His 是否展示时分秒 默认true + * + * @return false|string + */ + function beginWeek($His = true) + { + //此代码会跳周、月、年 + //$timestamp = mktime(0, 0, 0, date('m'), date('d') - date('w') + 1, date('Y')); + //return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp); + + //改进 + //$first =1 表示每周星期一为开始日期 0表示每周日为开始日期 + $first=1; + $sdefaultDate = date("Y-m-d"); + //获取当前周的第几天 周日是 0 周一到周六是 1 - 6 + $w=date('w',strtotime($sdefaultDate)); + //是否展示时分秒 + $week_start = date('Y-m-d',strtotime("$sdefaultDate -".($w ? $w - $first : 6).' days')); + //是否展示时分秒 + if($His){ + //$week_start + return $week_start.' 00:00:00'; + } + //$week_start + return $week_start; + } + + /** + * 本周的结束日期 + * + * @param bool $His 是否展示时分秒 默认true + * + * @return false|string + */ + function endWeek($His = true) + { + //此代码会跳周、月、年 + //$timestamp = mktime(23, 59, 59, date('m'), date('d') - date('w') + 7, date('Y')); + //return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp); + + //改进 + //$first =1 表示每周星期一为开始日期 0表示每周日为开始日期 + $first=1; + $sdefaultDate = date("Y-m-d"); + //获取当前周的第几天 周日是 0 周一到周六是 1 - 6 + $w=date('w',strtotime($sdefaultDate)); + //是否展示时分秒 + $week_start = date('Y-m-d',strtotime("$sdefaultDate -".($w ? $w - $first : 6).' days')); + $week_end=date('Y-m-d',strtotime("$week_start +6 days")); + //是否展示时分秒 + return $His?$week_end.' 23:59:59':$week_end; + } + + /** + * desc:上周开始 + * author:wh + * @return false|string + */ + function beginBeforeWeek(){ + $week = $this->beginWeek(); + $this->date_format = 'Y-m-d'; + return $this->reduceTime(7,'d',strtotime($week)) . ' 00:00:00'; + + //此代码会跳周、月、年 + //return date('Y-m-d', strtotime('-1 monday', time())).' 00:00:00';//上周一,无论今天几号,-1 monday为上一个有效周未 + } + + /** + * desc:上周结束 + * author:wh + * @return false|string + */ + function endBeforeWeek(){ + + $week = $this->beginWeek(); + $this->date_format = 'Y-m-d'; + return $this->reduceTime(1,'d',strtotime($week)) . ' 23:59:59'; + + //此代码会跳周、月、年 + //return date('Y-m-d', strtotime('-1 sunday', time())).' 23:59:59'; //上一个有效周日,同样适用于其它星期 + } + + /** + * 本月的开始日期 + * + * @param bool $His 是否展示时分秒 默认true + * + * @return false|string + */ + function beginMonth($His = true) + { + return $His ? date('Y-m-').'01 00:00:00' : date('Y-m-').'01'; + } + /** + * 本月的结束日期 + * + * @param bool $His 是否展示时分秒 默认true + * + * @return false|string + */ + function endMonth($His = true) + { + $timestamp = mktime(23, 59, 59, date('m'), date('t'), date('Y')); + return $His ? date('Y-m-d H:i:s', $timestamp) : date('Y-m-d', $timestamp); + } + + /** + * desc:上月开始时间(上月一日) + * author:wh + * @return false|string + */ + function beginBeforeMonth(){ + return date('Y-m-d', strtotime('-1 month', strtotime(date('Y-m', time()) . '-01 00:00:00'))).' 00:00:00'; //本月一日直接strtotime上减一个月 + } + /** + * desc:上月结束时间(上月最后一日) + * author:wh + * @return false|string + */ + function endBeforeMonth(){ + return date('Y-m-d', strtotime(date('Y-m', time()) . '-01 00:00:00') - 86400).' 23:59:59'; //本月一日减一天即是上月最后一日 + } + + /** + * desc:七天(一周)以内 + * author:wh + * @return false|string + */ + function innerWeekDay(){ + $time = time(); + //当前时间减去30天 + $second = $time - 7 * 86400; + return date('Y-m-d', $second); + } + /** + * desc:一月以内 + * author:wh + * @return false|string + */ + function innerMonth(){ + $time = time(); + //当前时间减去30天 + $second = $time - 30 * 86400; + return date('Y-m-d', $second); + } + /** + * desc:一年以内 + * author:wh + * @return false|string + */ + function innerYear(){ + $time = time(); + //当前时间减去30天 + $second = $time - 365 * 86400; + return date('Y-m-d', $second); + } + + /** + * 几年的开始日期 + * + * @param bool $His 是否展示时分秒 默认true + * + * @return false|string + */ + function beginYear($His = true) + { + $timestamp = date('Y'); + return $His ? $timestamp.'-01-01 00:00:00' : $timestamp.'-01-01'; + } + + /** + * 几年的结束日期 + * + * @param bool $His 是否展示时分秒 默认true + * + * @return false|string + */ + function endYear($His = true) + { + $timestamp = date('Y'); + return $His ? $timestamp.'-12-31 23:59:59' : $timestamp.'-12-31'; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Mmodel.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Mmodel.php new file mode 100644 index 0000000..d2931ee --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Mmodel.php @@ -0,0 +1,125 @@ +insertGetId($data); + } + $res = Db::table($table) + ->where($where) + ->find(); + if($res){ + Db::table($table) + ->where($where) + ->data($data) + ->update(); + return $res['id']; + } + return Db::table($table)->insertGetId($data); + } + + + /** + * desc:捕获式函数块 + * + * 无事务处理 + * + * author:wh + * @param $fn + */ + static function catch($fn){ + try{ + Tools::log_to_write_txt(['input'=>input()]); + return $fn(); + }catch (\Exception $e){ + Tools::error_txt_log($e); + return Tools::set_fail('操作失败.',$e->getMessage()); + } + } + /** + * desc:捕获式函数块 + * + * 无事务处理 + * + * author:wh + * @param $fn + */ + static function catchJson($fn){ + try{ + Tools::log_to_write_txt(['input'=>input()]); + $res = $fn(); + return json($res); + }catch (\Exception $e){ + Tools::error_txt_log($e); + return json(Tools::set_fail('操作失败.',$e->getMessage())); + } + } + /** + * desc:捕获式函数块 + * + * 自动事务处理 + * + * author:wh + * @param $fn + */ + static function catchTrans($fn){ + Db::startTrans(); + try{ + Tools::log_to_write_txt(['input'=>input()]); + $res = $fn(); + Db::commit(); + return $res; + }catch (\Exception $e){ + Db::rollback(); + Tools::error_txt_log($e); + return Tools::set_fail('操作失败.',$e->getMessage()); + } + } + /** + * desc:捕获式函数块 + * + * 自动事务处理 + * + * author:wh + * @param $fn + */ + static function catchTransJson($fn){ + Db::startTrans(); + try{ + Tools::log_to_write_txt(['input'=>input()]); + $res = $fn(); + Db::commit(); + return json($res); + }catch (\Exception $e){ + Db::rollback(); + Tools::error_txt_log($e); + return json(Tools::set_fail('操作失败.',$e->getMessage())); + } + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/PinYin.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/PinYin.php new file mode 100644 index 0000000..91b032a --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/PinYin.php @@ -0,0 +1,94 @@ +where('key',$key); + $obj->data(['val'=>$val]); + return $obj->update(); + } + $obj = Db::table($tabname); + return $obj->where(['key'=>$key]) + ->cache($tabname.'_'.$key,0,$tabname) + ->value('val'); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Validate.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Validate.php new file mode 100644 index 0000000..14e9507 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/Validate.php @@ -0,0 +1,360 @@ +2){ + //返回false,表示非严格的2位数金额 + return false; + } + + + return $r; + } + + /** + * desc:是否是小数格式 + * author:wh + * @param string $num + * @return bool + */ + static function is_float_number(string $num){ + return preg_match('/^[0-9]+.[0-9]+$/', $num)?true:false; + } + + /** + * desc:是否是数字 + * author:wh + * @param string $num + * @return bool + */ + static function is_number(string $num){ + return preg_match('/^\d+$/', $num)?true:false; + } + + /** + * desc:是否是字母 + * author: wh + * @param string $str + * @return bool + */ + static function is_letter(string $str){ + return preg_match('/^[a-zA-Z]+$/', $str) ? true : false; + } + + /** + * desc:是否字母或数字 + * author:wh + * @param string $str + * @return bool + */ + static function is_letter_or_number(string $str){ + return preg_match('/^[a-zA-Z|0-9]+$/', $str) ? true : false; + } + + /** + * desc:验证数组是否存在空值 + * 仅针对基本数据类型 + * 仅针对一维数组 + * author:wh + * @param $array + * @return bool + */ + static function check_array_val_empty($array){ + $is_empty = false; + foreach ($array as $value){ + if(($value!==0 && $value !=='0') && empty($value)){ + $is_empty = true; + break; + } + if(is_int($value) && empty(1*$value)){ + $is_empty = true; + break; + } + } + return $is_empty; + } + + /** + * desc:是否是url + * author:wh + * @param $v + * @return bool + */ + static function is_url($v){ + $pattern="#(http|https)://(.*\.)?.*\..*#i"; + return preg_match($pattern,$v)?true:false; + } + + + /** + * [是否全部大写] + * + * @param $str + * @return bool + * @example + * @see + * @link + */ + static function is_upper($str){ + return preg_match('/^[A-Z]+$/', $str)?true:false; + } + + /** + * [是否全部小写] + * + * @param $str + * @return bool + * @example + * @see + * @link + */ + static function is_lower($str){ + return preg_match('/^[a-z]+$/', $str)?true:false; + } + + + /** + * desc:验证是微信内还是微信外 + * + * 是否在微信内,是否在微信中 + * + * author:wh + * @return bool + */ + static function is_weixin(){ + return strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false; + } + + /** + * desc:是否包含特殊字符 + * author:wh + * @param string $str + * @return bool + */ + static function is_special_character(string $str){ + $res = preg_match ( '/[\Q~!@#$%^&*()+-_=.:?<>\E]/', $str ); + return $res ? true : false; + } + + /** + * desc:验证字符串是否全部是中文 + * + * 返回 true表示全部是中文,false表示部分是中文或没有中文 + * + * author:wh + * @param string $str + * @return bool + */ + static function is_all_chinese(string $str){ + return preg_match("/^[\x{4e00}-\x{9fa5}]+$/u",$str)?true:false; + } + + /** + * desc:验证两个浮点数值是否相等 + * + * 例如: + * $num1 = 0.1; + $num2 = 0.7; + + $res = $num1 + $num2; + + var_dump($res); + + var_dump($res == 0.8);//false 不相等 + + var_dump(intval(strval($res)) == intval(strval(0.8)));//true 相等 + * + * author:wh + * @param $float_num1 + * @param $float_num2 + * @return bool + */ + static function is_equal_num_val($float_num1, $float_num2){ + + return intval(strval($float_num1)) == intval(strval($float_num2)); + } + + /** + * desc:是否包含给定的主域名 + * author:wh + * @param $domain + * @param $main_domain + * @return bool + */ + static function is_main_domain($domain,$main_domain){ + $exp_arr = explode('.',$domain); + $str = $exp_arr[count($exp_arr)-2] .'.'. $exp_arr[count($exp_arr)-1]; + return $str==$main_domain; + } + + /** + * desc:国内国外IP校验,校验IP来源 + * + * author:wh + * @param $ip + * @return bool + */ + static function validate_ip($ip) { + $chinaStart = ip2long('1.0.1.0'); // 中国大陆起始IP + $chinaEnd = ip2long('254.254.254.254'); // 中国大陆结束IP + + $hongKongStart = ip2long('8.36.0.0'); // 香港起始IP + $hongKongEnd = ip2long('8.37.255.255'); // 香港结束IP + + $taiwanStart = ip2long('192.168.0.0'); // 台湾起始IP + $taiwanEnd = ip2long('192.168.255.255'); // 台湾结束IP + + $ipLong = ip2long($ip); + + if ($ipLong >= $chinaStart && $ipLong <= $chinaEnd || + $ipLong >= $hongKongStart && $ipLong <= $hongKongEnd || + $ipLong >= $taiwanStart && $ipLong <= $taiwanEnd) { + return true; // IP属于国内 + } else { + return false; // IP不属于国内 + } + } + + + /** + * 是否移动端访问访问 + * + * @return bool + */ + static function is_mobile_client() + { + // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 + if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) { + return true; + } + +//如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息 + if (isset($_SERVER['HTTP_VIA'])) { + //找不到为flase,否则为true + return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false; + } + +//判断手机发送的客户端标志 + if (isset($_SERVER['HTTP_USER_AGENT'])) { + $clientkeywords = [ + 'nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', + 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', + 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', + 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile','alipay' + ]; + +// 从HTTP_USER_AGENT中查找手机浏览器的关键字 + if (preg_match("/(".implode('|', $clientkeywords).")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) { + return true; + } + } + +//协议法,因为有可能不准确,放到最后判断 + if (isset($_SERVER['HTTP_ACCEPT'])) { + // 如果只支持wml并且不支持html那一定是移动设备 + // 如果支持wml和html但是wml在html之前则是移动设备 + if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) { + return true; + } + } + + return false; + } + + /** + * 判断是否微信内置浏览器访问 + * @return bool + */ + static function is_wx_client() + { + return strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false; + } + + /** + * 判断是否支付宝内置浏览器访问 + * @return bool + */ + static function is_ali_client() + { + return strpos($_SERVER['HTTP_USER_AGENT'], 'Alipay') !== false; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/AlipayLogic.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/AlipayLogic.php new file mode 100644 index 0000000..4669e48 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/AlipayLogic.php @@ -0,0 +1,82 @@ +setBody($order['goods_name']); + //$payRequestBuilder->setSubject($order['goods_name']); + //$payRequestBuilder->setOutTradeNo($out_trade_no); + //$payRequestBuilder->setTotalAmount($order['goods_price']); + //$payRequestBuilder->setTimeExpress($timeout_express); + // + //$payResponse = new \AlipayTradeService($config); + + + //$result = $payResponse->wapPay($payRequestBuilder,$return_url,$notify_url); + //return $result; + //} +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/pay/AlipayScanPay.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/pay/AlipayScanPay.php new file mode 100644 index 0000000..87bcabb --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/pay/AlipayScanPay.php @@ -0,0 +1,195 @@ +config = $config; + } + + /** + * desc:面对面扫码支付-(扫用户的付款码) + * + * 注意: + * 免密支付是同步返回支付结果,输入密码支付是异步通知支付结果, + * 所以需要处理异步支付结果通知。 + * @param array $order 订单信息 + * @param string $auth_code 扫码枪扫描后的授权码 + * @return array 返回支付结果(一维数组) + */ + function scanPay($order,$auth_code){ + if(empty($auth_code)){ + return Tools::set_res(500,'授权码错误'); + } + try { + //1. 设置参数(全局只需设置一次) + Factory::setOptions($this->getOptions()); + //2. 发起API调用(以支付能力下的统一收单交易创建接口为例) + $result = Factory::payment()->faceToFace() + ->optional('scene','bar_code') + ->pay($order['title'], $order['orderid'], $order['real_amount'], $auth_code); + + if($result->code == 10003){ + return Tools::set_res(230,'交易进行中(提示用户输入密码)'.$result->msg); + } + //必须解析json + $resp = json_decode($result->httpBody, true); + //支付宝面对面扫码支付后续流程 + return Tools::set_ok('ok',$resp['alipay_trade_pay_response']);//返回支付结果(一维数组) + } catch (\Exception $e) { + $err_data = [ + 'error'=>'支付宝付款码支付错误'.$e->getMessage(), + 'error_info'=>$e->getTraceAsString() + ]; + Tools::log_to_write_txt($err_data); + return Tools::set_fail('错误.'.$e->getMessage()); + } + } + + + /** + * desc:获取支付配置 + * author:wh + * @return Config + * @throws Exception + */ + private function getOptions() + { + if(empty($this->config)){ + throw new Exception('支付宝配置错误'); + } + if(empty($this->config['notifyUrl'])){ + throw new Exception('支付宝配置错误:notifyUrl通知地址字段必须配置(免密支付是同步返回支付结果,输入密码支付是异步通知支付结果)'); + } + $config = $this->config; + $options = new Config(); + $options->protocol = 'https'; + $options->gatewayHost = 'openapi.alipay.com'; + $options->signType = $config['sign_type']; + + $options->appId = $config['app_id'];//'<-- 请填写您的AppId,例如:2019022663440152 -->'; + + // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中 + $options->merchantPrivateKey = $config['alipay_app_private_key'];//'<-- 请填写您的应用私钥,例如:MIIEvQIBADANB ... ... -->'; + + $options->alipayCertPath = Tools::get_root_path().$config['cert_path_alipayCertPublicKey_RSA2'];//'<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->'; + $options->alipayRootCertPath = Tools::get_root_path().$config['cert_path_alipayRootCert'];//'<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt" -->'; + $options->merchantCertPath = Tools::get_root_path().$config['appCertPublicKey'];//'<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->'; + + //注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可 + // $options->alipayPublicKey = '<-- 请填写您的支付宝公钥,例如:MIIBIjANBg... -->'; + + //可设置异步通知接收服务地址(可选) + $options->notifyUrl = $this->config['notifyUrl'];//request()->domain().'/index/alipay/notify';//"<-- 请填写您的支付类接口异步通知接收服务地址,例如:https://www.test.com/callback -->"; + + return $options; + } + + + /** + * desc:支付宝扫码异步通知 + * + * 【通知结果是一维数组】 + * + * {"gmt_create":"2024-06-10 11:53:37","charset":"UTF-8","seller_email":"15023017325", + * "subject":"购物消费", + * "sign":"oCR3X0ViRrydigLMeOCTrMBNx7O8bSZnEflT0qZYo0gXk2jTI2OVB9mG2UPCkGuSND3wq/pMRFN + * ljuz+2r3KMha9a6ArD/ey8w1am3yCKI+FMqUMQSv9TJqfpWdAsc8B45egtr+txBBOA1NMfN41hPnTxM3QzQ82cm + * 7VYw6pnYpxJVj/3AsqYxY+wcyMq5+v25eC4TgBo+YJ9pfb3rqaAV91cJBoHRq1Cwh0XEnOzm9zpv7b5cu3r+V0oeW + * wTCCi8S1TXW2dfE4H8o63xgASYfJO2fgGIu19YICQdUONkDhu9Tfbf3fFf9SHw3RIw8zrQRqkwAXC32NwfUv4Ru5NqQ==", + * "buyer_id":"2088612757425274","invoice_amount":"3258.60","notify_id":"2024061001222115350025271439748729", + * "fund_bill_list":"[{\"amount\":\"3258.60\",\"fundChannel\":\"ALIPAYACCOUNT\"}]", + * "notify_type":"trade_status_sync","trade_status":"TRADE_SUCCESS","receipt_amount":"3258.60", + * "app_id":"2021004136614333","buyer_pay_amount":"3258.60","sign_type":"RSA2", + * "seller_id":"2088642975857443","gmt_payment":"2024-06-10 11:53:50", + * "notify_time":"2024-06-10 12:07:40","version":"1.0","out_trade_no":"cs25obpv1717991615660", + * "total_amount":"3258.60","trade_no":"2024061022001425271426453509","auth_app_id":"2021004136614333", + * "buyer_logon_id":"146***@qq.com","point_amount":"0.00"} + * + * author:wh + * param function $fn 传入订单处理逻辑函数 要求返回success、fail + * @return string + */ + function scanPayNotify($fn){ + Tools::log_to_write_txt([ + '支付宝异步通知', + 'input'=>input() + ]); + + $out_trade_no = input('out_trade_no'); + if(empty($out_trade_no)){ + Tools::log_to_write_txt(['error'=>'out_trade_no为空,文件:'.__FILE__.',line:'.__LINE__]); + return ''; + } + //$order = Db::table(TabConf::$fa_order) + // ->where('orderid',$out_trade_no) + // ->find(); + //if(empty($order)){ + // Tools::log_to_write_txt(['error'=>'订单不存在,文件:'.__FILE__.',line:'.__LINE__]); + // return ''; + //} + //该字段用于判断成功、失败 + $trade_status = input('trade_status'); + if(empty($trade_status)){ + Tools::log_to_write_txt(['error'=>'trade_status为空,文件:'.__FILE__.',line:'.__LINE__]); + return ''; + } + if(empty($this->config['seller_id'])){ + Tools::log_to_write_txt(['error'=>'卖家seller_id为空,文件:'.__FILE__.',line:'.__LINE__]); + return ''; + } + + //判断来源 + $seller_id = input('seller_id'); + if($seller_id != $this->config['seller_id']){ + Tools::log_to_write_txt(['error'=>'支付通知来源错误','seller_id'=>$seller_id,'config'=>$this->config['seller_id']]); + return 'fail'; + } + //支付宝面对面扫码支付后续流程 + $result = input(); + //异步通知 + //$res = CheckstandLogic::alipayScanSuccessFlow($result,$order); + //if($res['code'] == 200 || $res['code'] == 230){//成功或进行中 + // return 'success'; + //} + return $fn($result);//要求返回success、fail + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/AlipayTransfer.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/AlipayTransfer.php new file mode 100644 index 0000000..efc924d --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/AlipayTransfer.php @@ -0,0 +1,143 @@ +cert_path_alipayCertPublicKey_RSA2 = Tools::get_root_path().$alipayConfig['cert_path_alipayCertPublicKey_RSA2'];//'<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->'; + $trans_config->cert_path_alipayRootCert = Tools::get_root_path().$alipayConfig['cert_path_alipayRootCert'];//'<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt" -->'; + $trans_config->appCertPublicKey = Tools::get_root_path().$alipayConfig['appCertPublicKey'];//'<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->' + + + $order_prefix = 'trs'; + $order_id = Tools::to_create_order_no($order_prefix); + $trans_config->order_id = $order_id;//订单号 必须 + $trans_config->timestamp = Tools::get_now_date();//请求时间 eg:2020-01-08 10:12:50 + $trans_config->trans_amount = $trans_data['trans_amount'];//转账金额 必须 且为字符串 最低0.1元 取值范围[0.1,100000000] + $trans_config->order_title = $trans_data['order_title'];//订单标题 可选 + $trans_config->phone = $trans_data['phone'];//支付宝登录手机号 必须 + $trans_config->name = $trans_data['name'];//支付宝真实姓名 必须 + $trans_config->remark = $trans_data['remark'];//支付备注 可选 + + + $trans = new AlipayTransfer(); + Tools::log_to_write_txt(['转账到支付宝,入参:'=>input(), 'trans_config'=>$trans_config]); + $pay_res = $trans->alitransfer($alipayConfig, $trans_config); + Tools::log_to_write_txt(['转账到支付宝,出参:'=>$pay_res]); + //直接返回转账结果,自主验证成功失败的status。code=10000表示操作成功,status=SUCCESS表示转账成功 + //由于是同步响应,所以不需要对结果验签 + return $pay_res; + } + * + */ + function alitransfer(array $alipayConfig, $transferConfig){ + //$transferConfig = new TransferConfig(); + Factory::setOptions($this->getAlipayOptions($alipayConfig, $transferConfig)); + + $method = 'alipay.fund.trans.uni.transfer'; + //公共参数 + $textParams = [ + 'app_id'=>$alipayConfig['app_id'], + 'charset'=>'utf-8', + 'sign_type'=>'RSA2', + 'timestamp'=>$transferConfig->timestamp, + 'version'=>'1.0', + ]; + + //请求参数 + //订单号前缀 + $biz_content = [ + 'out_biz_no'=>$transferConfig->order_id,//商家支付订单号 + 'trans_amount'=>$transferConfig->trans_amount, + 'product_code'=>'TRANS_ACCOUNT_NO_PWD', + 'biz_scene'=>'DIRECT_TRANSFER', + 'order_title'=>$transferConfig->order_title, + 'payee_info'=>[ + 'identity'=>$transferConfig->phone,//手机号 + 'identity_type'=>'ALIPAY_LOGON_ID', + 'name'=>$transferConfig->name,//参与方真实姓名,如果非空,将校验收款支付宝账号姓名一致性。当identity_type=ALIPAY_LOGON_ID时,本字段必填。 + ], + 'remark'=>$transferConfig->remark, + ]; + $pay_res = Factory::util()->generic()->execute($method,$textParams,$biz_content); + + return $pay_res; + } + + /** + * desc:证书模式参数(非证书模式参数需单独获取) + * author:wh + * @param array $alipayConfig 支付宝转账配置(非支付配置) + * @return Config + */ + protected function getAlipayOptions(array $alipayConfig, $transferConfig) + { + $options = new Config(); + $options->protocol = 'https'; + $options->gatewayHost = 'openapi.alipay.com'; + $options->signType = 'RSA2'; + + //'<-- 请填写您的AppId,例如:2019022663440152 -->' + $options->appId = $alipayConfig['app_id'];//'2021002103639985'; + + // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中 + $options->merchantPrivateKey = $alipayConfig['alipay_app_private_key'];//'<-- 请填写您的应用私钥,例如:MIIEvQIBADANB ... ... -->'; + + $options->alipayCertPath = $transferConfig->cert_path_alipayCertPublicKey_RSA2;//'<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->'; + $options->alipayRootCertPath = $transferConfig->cert_path_alipayRootCert;//'<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt" -->'; + $options->merchantCertPath = $transferConfig->appCertPublicKey;//'<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->'; + + //注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可 + // $options->alipayPublicKey = $alipayConfig['alipay_public_key'];//'<-- 请填写您的支付宝公钥,例如:MIIBIjANBg... -->'; + + //可设置异步通知接收服务地址(可选) + $options->notifyUrl = $transferConfig->notifyUrl;//"<-- 请填写您的支付类接口异步通知接收服务地址,例如:https://www.test.com/callback -->"; + + //可设置AES密钥,调用AES加解密相关接口时需要(可选) + //$options->encryptKey = "<-- 请填写您的AES密钥,例如:aa4BtZ4tspm2wnXLb1ThQA== -->"; + + return $options; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/TransferConfig.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/TransferConfig.php new file mode 100644 index 0000000..e10a4b3 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/alipay/transfer/TransferConfig.php @@ -0,0 +1,63 @@ +cert_path_alipayCertPublicKey_RSA2 = Tools::get_root_path().$alipayConfig['cert_path_alipayCertPublicKey_RSA2'];//'<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->'; + $trans_config->cert_path_alipayRootCert = Tools::get_root_path().$alipayConfig['cert_path_alipayRootCert'];//'<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt" -->'; + $trans_config->appCertPublicKey = Tools::get_root_path().$alipayConfig['appCertPublicKey'];//'<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->' + + + $order_prefix = 'trs'; + $order_id = Tools::to_create_order_no($order_prefix); + $trans_config->order_id = $order_id;//订单号 必须 + $trans_config->timestamp = Tools::get_now_date();//请求时间 eg:2020-01-08 10:12:50 + $trans_config->trans_amount = '0.21';//转账金额 必须 且为字符串 最低0.1元 取值范围[0.1,100000000] + $trans_config->order_title = '代理提现';//订单标题 可选 + $trans_config->phone = '18290416033';//支付宝登录手机号 必须 + $trans_config->name = '王华';//支付宝真实姓名 必须 + $trans_config->remark = '代理提现到支付宝';//支付备注 可选 + + $trans = new AlipayTransfer(); + $pay_res = $trans->alitransfer($alipayConfig, $trans_config); + + dump($pay_res); + * + */ +class TransferConfig +{ + //'<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->'; + public $cert_path_alipayCertPublicKey_RSA2 = '';//必须 + //'<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt" -->'; + public $cert_path_alipayRootCert = '';//必须 + //'<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->' + public $appCertPublicKey = '';//必须 + + public $notifyUrl = '';//接收异步通知(可选) + + + //业务参数 + public $order_id = '';//订单号 必须 + public $timestamp = '';//请求时间 必须 eg:2020-01-08 10:12:50 + public $trans_amount = '';//转账金额 必须 且为字符串 最低0.1元 取值范围[0.1,100000000] + public $order_title = '';//订单标题 可选 + public $phone = '';//支付宝登录手机号 必须 + public $name = '';//支付宝真实姓名 必须 + public $remark = '';//支付备注 可选 + + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/Api.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/Api.php new file mode 100644 index 0000000..7f48139 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/Api.php @@ -0,0 +1,425 @@ +apidir = Tools::get_root_path().'application/api/controller/'; + if(!$this->table_obj) + $this->table_obj = new Table(); + } + + /** + * desc:api目录 + * author:wh + * @param string $dir api创建目录,格式必须按照例子填写 eg: application/api/controller/ + */ + function setapidir(string $dir){ + $this->apidir = $dir; + $nsp = str_replace('application','app',substr($dir,0,strlen($dir)-2)); + $this->namespace = str_replace('/','\\',$nsp); + } + + /** + * desc:替换表前缀 + * author:wh + * @param $tablename + * @return false|string + */ + function replaceTablePrefix($tablename){ + $prefix = config('database.prefix'); + if($prefix){ + return substr($tablename,strlen($prefix)); + } + $tmp_prefix = 't_'; + if(false !== strpos($tablename,$tmp_prefix)){ + return substr($tablename,strlen($tmp_prefix)); + } + return $tablename; + } + + /** + * desc:设置方法名称 + * + * author:wh + * @param array $functions_arr + */ + function setApiFunctionsName(array $functions_arr){ + $this->functions_arr = array_merge($functions_arr,$this->functions_arr); + } + + /** + * desc:动态创建方法 + * + * author:wh + */ + private function syncCreateFunction(array $func_name_arr){ + $code = ''; + foreach ($func_name_arr as $func_name=>$func_remark){ //接口方法公共代码模块 + $commonFunctionCodeModule = $this->commonFunctionCodeModule($func_remark); + $code .= <<, <, >=, <=, != + * between + * in + * + * author:wh + * @param array $select_in_params eg: + * [ + * 'gameid'=>['and'], + * 'nickname'=>['like%'], + * 'reg_time'=>['between'],//时间区间查询 + * 'audit_time'=>['2015-01-3','eq'],//时间区间查询 + * ] + * + */ + function setQueryCodeBody(array $select_in_params){ + $code = ''; + + return $code; + } + + /** + * desc:写入查询接口的代码体 + * + * author:wh + * @param array $insert_params + * @return string + */ + function setInsertCodeBody(array $insert_params){ + $code = ''; + + return $code; + } + + /** + * desc:快速构建api代码 + * + * 本方法不验证接口名称是否重复 + * + * author:wh + * @param string $tablename 数据表名称 + * @param array $func_name_arr 方法名称数组 eg:['getData'=>'获取数据','function_aaa'=>'function_注释aaa'] + */ + function buildApi(string $tablename, array $func_name_arr){ + //deal table name + $tablename = $this->replaceTablePrefix($tablename); + + //基础 start + //create base controller + $this->buildBaseApiPublicController();//开放控制器 + $this->buildBaseApiAuthController();//权限控制器 + $this->errController();//错误控制器 + //基础 end + + //接口类名 + $classname = ucfirst(Tools::convertUnderLine($tablename)); + //接口注释 + $comment = $this->table_obj->getTableComment($tablename); + + //批量构建方法代码 + $build_functions_code = $this->syncCreateFunction($func_name_arr); + + //PHP文件名,不含物理路径 + $file_name = $classname.$this->ext(); + + //PHP文件路径和文件名 + $php_file = $this->apidir.$file_name; + + if(file_exists($php_file)){ + //追加代码 + //读取并删除最后的“}” + $php_code_str = file_get_contents($php_file); + $sub_php_code_str = mb_substr($php_code_str,0,mb_strlen($php_code_str)-2); + //追加新的代码 + $sub_php_code_str .= $build_functions_code ."\n }"; + //清空代码 + file_put_contents($php_file,''); + //追加 + $this->createFileExists($php_file,$sub_php_code_str); + }else{ + //创建代码文件 + $use_tpl = $this->useTpl(); + $php = <<namespace}; +{$use_tpl} + +/** + * {$comment} + * Class {$classname} + * @package {$this->namespace} + */ +class {$classname} extends BaseApiPublicController +{ + + + + {$build_functions_code} + +} +EOF; + + $this->createDir($this->apidir); + + + $this->createFile($php_file,$php); + } + } + + /** + * desc:公共方法模块 + * + * author:wh + * @param $comment + * @return string + */ + private function commonFunctionCodeModule($comment){ + $php = <<'{$comment},__IN:','INPUT'=>input()]); + //region 校验区 start + + //endregion 校验区 end + + + + + //region 业务逻辑区 start + + //endregion 业务逻辑区 end + + + + + //响应结果处理 + Tools::log_to_write_txt(['title'=>'{$comment},__OUT:','OUTPUT'=>[]]); + return json(Tools::set_res(200,'ok')); + }catch (\Exception \$e){ + Tools::log_to_write_txt([ + 'error'=>'{$comment},API异常。'.\$e->getMessage(), + '入参'=>input(), + 'error_info'=>\$e->getTraceAsString() + ]); + return json(Tools::set_res(500,'系统繁忙')); + } +EOF; + + return $php; + } + + /** + * desc:api基础开放控制器 + * + * 如果存在则不创建 + * + * author:wh + */ + private function buildBaseApiPublicController(){ + $file_name = 'BaseApiPublicController'; + $php = <<namespace}; + +use think\Controller; + + +/** + * desc:api基础开放架构 + * + * 所有开放接口继承此父类 + * + * author: + */ +class {$file_name} extends Controller +{ + +} +EOF; + + $php_file = $this->apidir.$file_name.$this->ext(); + + $this->createDir($this->apidir); + + $this->createFile($php_file,$php); + } + + /** + * desc:api基础权限控制器 + * + * 如果存在则不创建 + * + * author:wh + */ + private function buildBaseApiAuthController(){ + $file_name = 'BaseApiAuthController'; + $php = <<namespace}; + +use think\Controller; + + +/** + * desc:api基础权限架构 + * + * 所有权限接口继承此父类 + * + * author: + */ +class {$file_name} extends Controller +{ + +} +EOF; + + $php_file = $this->apidir.$file_name.$this->ext(); + + $this->createDir($this->apidir); + + $this->createFile($php_file,$php); + } + + /** + * desc:api底层基础控制器架构 + * + * [按需创建][可单独调用] + * + * 如果存在则不创建 + * + * author:wh + */ + function buildBaseApiController(){ + $file_name = 'BaseApiController'; + $php = <<namespace}; + +use think\Controller; + + +/** + * desc:api底层基础控制器架构 + * + * author: + */ +class {$file_name} extends Controller +{ + + +} +EOF; + + $php_file = $this->apidir.$file_name.$this->ext(); + + $this->createDir($this->apidir); + + $this->createFile($php_file,$php); + } + + /** + * desc:use模块 + * + * author:wh + * @return string + */ + private function useTpl(){ + $php = <<namespace}; + + +use wanghua\general_utility_tools_php\\framework\\base\PublicController; +use wanghua\general_utility_tools_php\\tool\Tools; + + +/** + * + * 错误(异常)中转架构 + * + * Class Err + * @package app\index\controller + */ +class {$file_name} extends BaseApiPublicController +{ + /** + * desc:校验失败中转 + * + * 场景:内网端口验证未通过时跳转; + * + * author:wh + * @return \\think\\response\\Json + */ + function checkfailed(){ + + return json(Tools::set_res(500,'Permission denied',input())); + } +} +EOF; + + $php_file = $this->apidir.$file_name.$this->ext(); + + $this->createDir($this->apidir); + + $this->createFile($php_file,$php); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/ApiDocument.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/ApiDocument.php new file mode 100644 index 0000000..a806b82 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/ApiDocument.php @@ -0,0 +1,264 @@ +buildDoc(); + * Class ApiDocument + */ +class ApiDocument +{ + private $api_cache_arr = [];//缓存所有接口 + public $api_domain = 'http://127.0.0.1:8080/';//接口域名/ip + /** + * @var string 接口控制器命名空间 + */ + public $namespace = 'app\\api\\controller'; + /** + * @var string 接口控制器基类,精确到类名,如:app\\common\\controller\\Api + * 注意:如果同级目录存在多个基类,则设置直接基类,如果同级目录没有基类,则设置底层基类 + */ + public $extends_base_class = ''; + //控制器目录物理路径 + public $controllerDirectory = ''; + /** + * @var string 接口文档保存路径 + */ + public $api_docs_save_dir = 'public/api_docs/'; + //设置过滤类 + private $filterClassArr = []; + //设置过滤方法 + private $filterFunctionArr = []; + + public function __construct($api_domain='',$controllerDirectory='') + { + //默认,如果是tp6,那application就要改为app了,自行传参吧 + $this->controllerDirectory = Tools::get_root_path().'application/api/controller'; + if($api_domain){ + $this->api_domain = $api_domain; + } + if($controllerDirectory){ + $this->controllerDirectory = $controllerDirectory; + } + } + + /** + * desc:设置过滤类(类名) + * 过滤场景: + * 1、基类 + * 2、测试类 + * 3、定时任务类 + * 4、其它非必要类 + * author:wh + * @param array $filterClassArr + */ + function setFilterClass(array $filterClassArr=[]){ + $this->filterClassArr = $filterClassArr; + } + function setFilterFunction(array $filterArr=[]){ + $this->filterFunctionArr = $filterArr; + } + /** + * desc:构建接口文档,支持同步到在线文档 + * author:wh + */ + function buildDoc(){ + if(empty($this->extends_base_class)){ + throw new Exception('请设置接口控制器基类,精确到类名,如:app\\common\\controller\\Api'); + } + $out_path = Tools::get_root_path().$this->api_docs_save_dir; + if(!file_exists($out_path)){ + mkdir($out_path,0777,true); + } + $outputFile = $out_path.'api_list.md'; + $controllerClasses = []; + + // 搜索控制器目录下的所有PHP文件 + foreach (glob($this->controllerDirectory . '/*.php') as $filename) { + // 获取文件中的类名 + $class = basename($filename, '.php'); + if(in_array($class,$this->filterClassArr)){ + continue; + } + // 构建完整的命名空间类名 + $fullClassName = $this->namespace . '\\' . $class; + foreach (explode(',',$this->extends_base_class) as $base_class){ + // 检查类是否有效并且是think\Controller的子类 + if (class_exists($fullClassName) && is_subclass_of($fullClassName, $base_class)) { + $controllerClasses[] = $fullClassName; + } + } + } + + // 创建Markdown文件 + $file = fopen($outputFile, 'w') or die('无法创建文件'); + + $head_text = <<api_domain} +##### 请求方式:POST(默认) + +EOF; + // 写入Markdown文件头部 + fwrite($file, $head_text); + + foreach ($controllerClasses as $controllerClass) { + $reflector = new \ReflectionClass($controllerClass); + // 遍历控制器中的公共方法 + $methods = $reflector->getMethods(\ReflectionMethod::IS_PUBLIC); + foreach ($methods as $method) { + //过滤方法 + if(in_array($method->name, $this->filterFunctionArr)){ + continue; + } + $exp_class = explode('\\',$controllerClass); + //过滤类 + if(in_array($exp_class[count($exp_class)-1],$this->filterClassArr)){ + continue; + } + $comments = $method->getDocComment(); + if ($comments) { + $this->processMethodComment($comments, $controllerClass, $method->name, $outputFile); + } + } + } + fclose($file); + + //缓存所有接口 + cache('api_doc_cache_arr',$this->api_cache_arr); + } + + + /** + * desc:解析方法注释并写入Markdown文件 + * author:wh + * @param $comments + * @param $className + * @param $methodName + * @param $savepath + */ + private function processMethodComment($comments, $className, $methodName, $savepath) { + if($methodName == '__construct'){ + return ''; + } + $api_url = "/api/{$className}/{$methodName}"; + $js_api_func_name = "api_{$className}_{$methodName}"; + $str = <<camelCaseToUnderscore($className); + + + $api_name = "api/{$className}/{$methodName}"; + $doc_txt = <<api_cache_arr[] = ['api_name'=>$api_name,'doc_txt'=>$doc_txt]; + file_put_contents($savepath,$doc_txt, FILE_APPEND); + } + + /** + * desc:驼峰转下划线 + * author:wh + * @param $string + * @return string + */ + private function camelCaseToUnderscore($string) { + $str = strtolower(preg_replace('/(? +
{$doc_txt}
+
+ 按需填写其它接口参数: + + 测试 +
+
+ + +EOF; + $script_str.=<< + + + + 接口文档 + + +
+ {$htm_str} +
+ + + + + +EOF; + return $html; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseApi.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseApi.php new file mode 100644 index 0000000..ad763cb --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseApi.php @@ -0,0 +1,230 @@ +post_url = $url; + if(empty($this->post_url)) { + Tools::log_to_write_txt(['error'=>'API OPERATE: '.ApiException::EMPTY_URL_ERROR], $this->getLogFileName()); + throw new \Exception(ApiException::EMPTY_URL_ERROR); + } + } + + /** + * desc:设置api请求日志文件名称 + * + * 日志保存在runtime中 + * + * author:wh + * @param string $log_file_name + */ + function setLogFileName(string $log_file_name=''){ + if($log_file_name)$this->log_file_name = $log_file_name; + } + + /** + * desc 获取记录日志的文件名 + * author:wh + * @return string + */ + function getLogFileName(){ + return $this->prefix.$this->log_file_name; + } + + /** + * desc:设置调用位置 + * author:wh + * @param $__file__ + * @param $__line__ + */ + function setFileDir($__file__, $__line__){ + $this->__sit__ = $__file__.' > '.$__line__; + } + + /** + * desc:错误位置 + * author:wh + * @return string + */ + function getErrorSit(){ + return $this->__sit__; + } + + /** + * desc: + * + * author:wh + * @param array $params + */ + private function mergeAuthParams(array &$params){ + $params['nonce'] = Tools::rand_str(10); + $params['timestamp'] = time(); + $token = config('service_framework_config.sign_token'); + $params['sign'] = Tools::signature($params, $token); + } + /** + * desc:执行post请求, 带权限参数 + * + * 同框架、内部系统推荐 + * + * 返回结果由code 错误码和msg 错误信息组成 + * + * author:wh + * @param $param 以表单格式提交数据 + * @return array|bool|int|mixed|string + * @throws ApiException + * @throws \think\Exception + */ + function apiPost($param){ + $this->mergeAuthParams($param); + + Tools::log_to_write_txt(['API OPERATE, IN',$this->post_url,$param], $this->getLogFileName()); + $res = Tools::curl_post($this->post_url, $param); + Tools::log_to_write_txt(['API OPERATE, OUT',$this->post_url, $res], $this->getLogFileName()); + + if(empty($res['data'])) return $res; + + $data = json_decode($res['data'], true); + if(empty($data['code'])) { + Tools::log_to_write_txt([ + 'error: api操作,错误', + 'post_url'=>$this->post_url, + 'error_info'=>ApiException::API_RESPONSE_FORMAT_ERROR, + 'error_sit'=>$this->getErrorSit(), + 'result'=>$res, + ], $this->getLogFileName()); + throw new \Exception(ApiException::API_RESPONSE_FORMAT_ERROR); + } + return $data; + } + + /** + * + * desc:执行post请求 + * + * 返回结果由code 错误码和msg 错误信息组成 + * + * author:wh + * @param $param 以json格式提交数据 + * @return array|bool|int|mixed|string + * @throws ApiException + * @throws \think\Exception + */ + function do($param){ + + Tools::log_to_write_txt(['API OPERATE, IN',$this->post_url,$param], $this->getLogFileName()); + $res = Tools::curl_post($this->post_url, json_encode($param)); + Tools::log_to_write_txt(['API OPERATE, OUT',$this->post_url, $res], $this->getLogFileName()); + + if(empty($res['data'])) return $res; + + $data = json_decode($res['data'], true); + if(empty($data['code'])) { + Tools::log_to_write_txt([ + 'error: api操作,错误', + 'post_url'=>$this->post_url, + 'error_info'=>ApiException::API_RESPONSE_FORMAT_ERROR, + 'error_sit'=>$this->getErrorSit(), + 'result'=>$res, + ], $this->getLogFileName()); + throw new \Exception(ApiException::API_RESPONSE_FORMAT_ERROR.$this->post_url); + } + return $data; + } + + /** + * + * desc:执行请求 + * + * do 方法的改版,返回结果由state 错误码和err 错误信息组成 + * + * author:wh + * @param $param 以json格式提交数据 + * @return array|bool|int|mixed|string + * @throws ApiException + * @throws \think\Exception + */ + function apiDo($param){ + + Tools::log_to_write_txt(['API OPERATE, IN',$this->post_url,$param], $this->getLogFileName()); + $res = Tools::curl_post($this->post_url, json_encode($param)); + Tools::log_to_write_txt(['API OPERATE, OUT',$this->post_url, $res], $this->getLogFileName()); + if(empty($res['data'])) return $res; + + + $data = json_decode($res['data'], true); + + if(is_null($data['state'])) { + Tools::log_to_write_txt([ + 'error: api操作,错误', + 'post_url'=>$this->post_url, + 'error_info'=>ApiException::API_RESPONSE_FORMAT_ERROR, + 'error_sit'=>$this->getErrorSit(), + 'result'=>$res, + ], $this->getLogFileName()); + throw new \Exception(ApiException::API_RESPONSE_FORMAT_ERROR); + } + $data['code'] = isset($data['state'])&&$data['state']==0?200:$data['state']; + $data['msg'] = isset($data['err'])?$data['err']:'api接口错误'; + return $data; + } + + /** + * + * desc:执行请求 + * + * 同框架、内部系统推荐 + * + * author:wh + * @param $param 以表单方式提交数据 + * @return array|bool|int|mixed|string + * @throws ApiException + * @throws \think\Exception + */ + function doPost($param){ + + Tools::log_to_write_txt(['API OPERATE, IN',$this->post_url,$param], $this->getLogFileName()); + $res = Tools::curl_post($this->post_url, $param); + Tools::log_to_write_txt(['API OPERATE, OUT',$this->post_url, $res], $this->getLogFileName()); + + if(empty($res['data'])) return $res; + + $data = json_decode($res['data'], true); + if(empty($data['code'])) { + Tools::log_to_write_txt([ + 'error: api操作,错误', + 'post_url'=>$this->post_url, + 'error_info'=>ApiException::API_RESPONSE_FORMAT_ERROR, + 'error_sit'=>$this->getErrorSit(), + 'result'=>$res, + ], $this->getLogFileName()); + throw new \Exception(ApiException::API_RESPONSE_FORMAT_ERROR); + } + return $data; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseLibApi.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseLibApi.php new file mode 100644 index 0000000..739b4b3 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/api/BaseLibApi.php @@ -0,0 +1,54 @@ +isPost()){ + return Tools::set_fail('错误'); + } + Tools::log_to_write_txt(['登录入参:'=>input()]); + $input_data = input(); + if(empty($input_data)){ + return Tools::set_fail('请求参数错误'); + } + if(empty($input_data['username'])){ + return Tools::set_fail('用户名或密码错误'); + } + if(empty($input_data['password'])){ + return Tools::set_fail('用户名或密码错误.'); + } + // start 这段代码可放在请求合法性里面校验 Tools::signature + if(empty($input_data['timestamp'])){ + return Tools::set_fail('请求错误..'); + } + if(empty($input_data['noncestr'])){ + return Tools::set_fail('请求错误...'); + } + if(empty($input_data['sign'])){ + return Tools::set_fail('请求错误。'); + } + + $sign = $input_data['sign'];//md5后的字符串 + unset($input_data['sign']); + //验签 + $signstr = Tools::signature($input_data); + //Tools::log_to_write_txt([ + // '签名日志:', + // $signstr, + // $sign, + // 'input'=>input(), + //]); + if($signstr != $sign){ + return Tools::set_fail('非法请求'); + } + + //请求时间超过有效期 N分钟内有效 + if(time()-5*60 > strtotime($input_data['timestamp'])){ + return Tools::set_fail('请求失效'); + } + // end 这段代码可放在请求合法性里面校验 Tools::signature + + $username = $input_data['username']; + $user = Db::table($this->user_table)->where('username',$username)->find(); + if(empty($user)){ + return Tools::set_fail('账号密码错误!'); + } + //校验密码 + if($user['password'] != $input_data['password']){ + return Tools::set_fail('账号密码错误!!'); + } + + $expires = time()+12*60*60; + + + + //返回票据 + $ticketstr = md5($user['username'].$user['expires']); + //保存ticket + $user[$ticketstr] = $expires;//N秒后过期 + //修改有效期 + Db::table($this->user_table) + ->data([ + 'ticket'=>$ticketstr, + 'expires'=>7*86400+time(),//7天 + ]) + ->where('username',$username) + ->update(); + session('api_user',$user);//备用(跨环境情况下session不生效) + + return Tools::set_ok('登录成功',['ticket'=>$ticketstr]); + } + + /** + * desc:验证登录,根据提交的ticket来校验是否登录,适用于跨环境登录 + * + * author:wh + * @return bool + */ + function isLogin(){ + + $ticket = input('ticket'); + if(empty($ticket)){ + Tools::log_to_write_txt(['title'=>'业务ticket字段不存在','input'=>input()]); + return false; + } + $user = Db::table(TabConf::$fa_users) + ->where('ticket',$ticket) + ->find(); + if(empty($user)){ + Tools::log_to_write_txt(['title'=>'用户未登录']); + return false; + } + //无效票据 + //if(empty($user[$ticket])){ + // Tools::log_to_write_txt(['title'=>'未获取到用户ticket',$ticket=>$user]); + // + // return false; + //} + //已过期 + if(time() > $user['expires']){ + Tools::log_to_write_txt(['title'=>'ticket已过期',$ticket=>$user]); + return false; + } + return true; + } + /** + * desc:用户注册 + * + * 此模块通用性不高,按需使用 + * + * author:wh + */ + function reg($input_data){ + try { + if(empty($input_data['username'])){ + return Tools::set_fail('用户名错误'); + } + if(empty($input_data['password'])){ + return Tools::set_fail('密码错误.'); + } + if(empty($input_data['password2'])){ + return Tools::set_fail('密码错误!'); + } + if($input_data['password'] != $input_data['password2']){ + return Tools::set_fail('密码不一致!'); + } + $insert_data = [ + 'username'=>$input_data['username'], + 'password'=>$input_data['password'], + ]; + if(!empty($input_data['phone'])){ + $insert_data['phone'] = $input_data['phone']; + } + Db::table($this->user_table) + ->data($insert_data) + ->insert(); + return Tools::set_ok(); + }catch (\Exception $e){ + Tools::error_txt_log($e); + return Tools::set_fail(); + } + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/Apk.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/Apk.php new file mode 100644 index 0000000..5da7d81 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/Apk.php @@ -0,0 +1,79 @@ +'',// 应用名称 + 'package'=>'',// 应用包名 + 'version_name'=>'',// 版本名称 + 'version_code'=>'',// 版本代码 + ]; + + dump($targetFile);die; + if(!is_file($targetFile)){ + return $result; + } + $appObj->open($targetFile);//$res + + $result = [ + 'app_name'=>$appObj->getAppName(),// 应用名称 + 'package'=>$appObj->getPackage(),// 应用包名 + 'version_name'=>$appObj->getVersionName(),// 版本名称 + 'version_code'=>$appObj->getVersionCode(),// 版本代码 + ]; + return $result; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/ApkParser.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/ApkParser.php new file mode 100644 index 0000000..a3f0cfa --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/apk/ApkParser.php @@ -0,0 +1,421 @@ +open($apk_file) === TRUE) { + $xml = $zip->getFromName($xml_file); + $zip->close(); + if ($xml){ + try { + return $this->parseString($xml); + }catch (Exception $e){ + } + } + } + return false; + } + + public function parseString($xml){ + $this->xml = $xml; + $this->length = strlen($xml); + + $this->root = $this->parseBlock(self::AXML_FILE); + return true; + } + + public function getXML($node=NULL, $lv=-1){ + if ($lv == -1) $node = $this->root; + if (!$node) return ''; + + if ($node['type'] == self::END_TAG) $lv--; + $xml = @($node['line'] == 0 || $node['line'] == $this->line) ? '' : "\n".str_repeat(' ', $lv); + $xml .= $node['tag']; + $this->line = @$node['line']; + foreach ($node['child'] as $c){ + $xml .= $this->getXML($c, $lv+1); + } + return $xml; + } + + public function getPackage(){ + return $this->getAttribute('manifest', 'package'); + } + + public function getVersionName(){ + return $this->getAttribute('manifest', 'android:versionName'); + } + + public function getVersionCode(){ + return $this->getAttribute('manifest', 'android:versionCode'); + } + + public function getAppName(){ + return $this->getAttribute('manifest/application', 'android:name'); + } + + public function getMainActivity(){ + for ($id=0; true; $id++){ + $act = $this->getAttribute("manifest/application/activity[{$id}]/intent-filter/action", 'android:name'); + if (!$act) break; + if ($act == 'android.intent.action.MAIN') return $this->getActivity($id); + } + return NULL; + } + + public function getActivity($idx=0){ + $idx = intval($idx); + return $this->getAttribute("manifest/application/activity[{$idx}]", 'android:name'); + } + + public function getAttribute($path, $name){ + $r = $this->getElement($path); + if (is_null($r)) return NULL; + + if (isset($r['attrs'])){ + foreach ($r['attrs'] as $a){ + if ($a['ns_name'] == $name) return $this->getAttributeValue($a); + } + } + return NULL; + } + + //---------------------- + // 类型常量定义 + //---------------------- + const AXML_FILE = 0x00080003; + const STRING_BLOCK = 0x001C0001; + const RESOURCEIDS = 0x00080180; + const START_NAMESPACE = 0x00100100; + const END_NAMESPACE = 0x00100101; + const START_TAG = 0x00100102; + const END_TAG = 0x00100103; + const TEXT = 0x00100104; + + const TYPE_NULL =0; + const TYPE_REFERENCE =1; + const TYPE_ATTRIBUTE =2; + const TYPE_STRING =3; + const TYPE_FLOAT =4; + const TYPE_DIMENSION =5; + const TYPE_FRACTION =6; + const TYPE_INT_DEC =16; + const TYPE_INT_HEX =17; + const TYPE_INT_BOOLEAN =18; + const TYPE_INT_COLOR_ARGB8 =28; + const TYPE_INT_COLOR_RGB8 =29; + const TYPE_INT_COLOR_ARGB4 =30; + const TYPE_INT_COLOR_RGB4 =31; + + const UNIT_MASK = 15; + private static $RADIX_MULTS = array(0.00390625, 3.051758E-005, 1.192093E-007, 4.656613E-010); + private static $DIMENSION_UNITS = array("px","dip","sp","pt","in","mm","",""); + private static $FRACTION_UNITS = array("%","%p","","","","","",""); + + private $xml=''; + private $length = 0; + private $stringCount = 0; + private $styleCount = 0; + private $stringTab = array(); + private $styleTab = array(); + private $resourceIDs = array(); + private $ns = array(); + private $cur_ns = NULL; + private $root = NULL; + private $line = 0; + + //---------------------- + // 内部私有函数 + //---------------------- + private function getElement($path){ + if (!$this->root) return NULL; + $ps = explode('/', $path); + $r = $this->root; + foreach ($ps as $v){ + if (preg_match('/([^\[]+)\[([0-9]+)\]$/', $v, $ms)){ + $v = $ms[1]; + $off = $ms[2]; + }else { + $off = 0; + } + foreach ($r['child'] as $c){ + if ($c['type'] == self::START_TAG && $c['ns_name'] == $v){ + if ($off == 0){ + $r = $c; continue 2; + }else { + $off--; + } + } + } + // 没有找到节点 + return NULL; + } + return $r; + } + + private function parseBlock($need = 0){ + $o = 0; + $type = $this->get32($o); + if ($need && $type != $need) throw new Exception('Block Type Error', 1); + $size = $this->get32($o); + if ($size < 8 || $size > $this->length) throw new Exception('Block Size Error', 2); + $left = $this->length - $size; + + $props = false; + switch ($type){ + case self::AXML_FILE: + $props = array( + 'line' => 0, + 'tag' => '' + ); + break; + case self::STRING_BLOCK: + $this->stringCount = $this->get32($o); + $this->styleCount = $this->get32($o); + $o += 4; + $strOffset = $this->get32($o); + $styOffset = $this->get32($o); + $strListOffset = $this->get32array($o, $this->stringCount); + $styListOffset = $this->get32array($o, $this->styleCount); + $this->stringTab = $this->stringCount > 0 ? $this->getStringTab($strOffset, $strListOffset) : array(); + $this->styleTab = $this->styleCount > 0 ? $this->getStringTab($styOffset, $styListOffset) : array(); + $o = $size; + break; + case self::RESOURCEIDS: + $count = $size / 4 - 2; + $this->resourceIDs = $this->get32array($o, $count); + break; + case self::START_NAMESPACE: + $o += 8; + $prefix = $this->get32($o); + $uri = $this->get32($o); + + if (empty($this->cur_ns)){ + $this->cur_ns = array(); + $this->ns[] = &$this->cur_ns; + } + $this->cur_ns[$uri] = $prefix; + break; + case self::END_NAMESPACE: + $o += 8; + $prefix = $this->get32($o); + $uri = $this->get32($o); + + if (empty($this->cur_ns)) break; + unset($this->cur_ns[$uri]); + break; + case self::START_TAG: + $line = $this->get32($o); + + $o += 4; + $attrs = array(); + $props = array( + 'line' => $line, + 'ns' => $this->getNameSpace($this->get32($o)), + 'name' => $this->getString($this->get32($o)), + 'flag' => $this->get32($o), + 'count' => $this->get16($o), + 'id' => $this->get16($o)-1, + 'class' => $this->get16($o)-1, + 'style' => $this->get16($o)-1, + 'attrs' => &$attrs + ); + $props['ns_name'] = $props['ns'].$props['name']; + for ($i=0; $i < $props['count']; $i++){ + $a = array( + 'ns' => $this->getNameSpace($this->get32($o)), + 'name' => $this->getString($this->get32($o)), + 'val_str' => $this->get32($o), + 'val_type' => $this->get32($o), + 'val_data' => $this->get32($o) + ); + $a['ns_name'] = $a['ns'].$a['name']; + $a['val_type'] >>= 24; + $attrs[] = $a; + } + // 处理TAG字符串 + $tag = "<{$props['ns_name']}"; + foreach ($this->cur_ns as $uri => $prefix){ + $uri = $this->getString($uri); + $prefix = $this->getString($prefix); + $tag .= " xmlns:{$prefix}=\"{$uri}\""; + } + foreach ($props['attrs'] as $a){ + $tag .= " {$a['ns_name']}=\"". + $this->getAttributeValue($a). + '"'; + } + $tag .= '>'; + $props['tag'] = $tag; + + unset($this->cur_ns); + $this->cur_ns = array(); + $this->ns[] = &$this->cur_ns; + $left = -1; + break; + case self::END_TAG: + $line = $this->get32($o); + $o += 4; + $props = array( + 'line' => $line, + 'ns' => $this->getNameSpace($this->get32($o)), + 'name' => $this->getString($this->get32($o)) + ); + $props['ns_name'] = $props['ns'].$props['name']; + $props['tag'] = ""; + if (count($this->ns) > 1){ + array_pop($this->ns); + unset($this->cur_ns); + $this->cur_ns = array_pop($this->ns); + $this->ns[] = &$this->cur_ns; + } + break; + case self::TEXT: + $o += 8; + $props = array( + 'tag' => $this->getString($this->get32($o)) + ); + $o += 8; + break; + default: + throw new Exception('Block Type Error', 3); + break; + } + + $this->skip($o); + $child = array(); + while ($this->length > $left){ + $c = $this->parseBlock(); + if ($props && $c) $child[] = $c; + if ($left == -1 && $c['type'] == self::END_TAG){ + $left = $this->length; + break; + } + } + if ($this->length != $left) throw new Exception('Block Overflow Error', 4); + if ($props){ + $props['type'] = $type; + $props['size'] = $size; + $props['child'] = $child; + return $props; + }else { + return false; + } + } + + private function getAttributeValue($a){ + $type = &$a['val_type']; + $data = &$a['val_data']; + switch ($type){ + case self::TYPE_STRING: + return $this->getString($a['val_str']); + case self::TYPE_ATTRIBUTE: + return sprintf('?%s%08X', self::_getPackage($data), $data); + case self::TYPE_REFERENCE: + return sprintf('@%s%08X', self::_getPackage($data), $data); + case self::TYPE_INT_HEX: + return sprintf('0x%08X', $data); + case self::TYPE_INT_BOOLEAN: + return ($data != 0 ? 'true' : 'false'); + case self::TYPE_INT_COLOR_ARGB8: + case self::TYPE_INT_COLOR_RGB8: + case self::TYPE_INT_COLOR_ARGB4: + case self::TYPE_INT_COLOR_RGB4: + return sprintf('#%08X', $data); + case self::TYPE_DIMENSION: + return $this->_complexToFloat($data).self::$DIMENSION_UNITS[$data & self::UNIT_MASK]; + case self::TYPE_FRACTION: + return $this->_complexToFloat($data).self::$FRACTION_UNITS[$data & self::UNIT_MASK]; + case self::TYPE_FLOAT: + return $this->_int2float($data); + } + if ($type >=self::TYPE_INT_DEC && $type < self::TYPE_INT_COLOR_ARGB8){ + return (string)$data; + } + return sprintf('<0x%X, type 0x%02X>', $data, $type); + } + + private function _complexToFloat($data){ + return (float)($data & 0xFFFFFF00) * self::$RADIX_MULTS[($data>>4) & 3]; + } + private function _int2float($v) { + $x = ($v & ((1 << 23) - 1)) + (1 << 23) * ($v >> 31 | 1); + $exp = ($v >> 23 & 0xFF) - 127; + return $x * pow(2, $exp - 23); + } + private static function _getPackage($data){ + return ($data >> 24 == 1) ? 'android:' : ''; + } + + private function getStringTab($base, $list){ + $tab = array(); + foreach ($list as $off){ + $off += $base; + $len = $this->get16($off); + $mask = ($len >> 0x8) & 0xFF; + $len = $len & 0xFF; + if ($len == $mask){ + if ($off + $len > $this->length) throw new Exception('String Table Overflow', 11); + $tab[] = substr($this->xml, $off, $len); + }else { + if ($off + $len * 2 > $this->length) throw new Exception('String Table Overflow', 11); + $str = substr($this->xml, $off, $len * 2); + $tab[] = mb_convert_encoding($str, 'UTF-8', 'UCS-2LE'); + } + } + return $tab; + } + private function getString($id){ + if ($id > -1 && $id < $this->stringCount){ + return $this->stringTab[$id]; + }else { + return ''; + } + } + private function getNameSpace($uri){ + for ($i=count($this->ns); $i > 0; ){ + $ns = $this->ns[--$i]; + if (isset($ns[$uri])){ + $ns = $this->getString($ns[$uri]); + if (!empty($ns)) $ns .= ':'; + return $ns; + } + } + return ''; + } + private function get32(&$off){ + $int = unpack('V', substr($this->xml, $off, 4)); + $off += 4; + return array_shift($int); + } + private function get32array(&$off, $size){ + if ($size <= 0) return NULL; + $arr = unpack('V*', substr($this->xml, $off, 4 * $size)); + if (count($arr) != $size) throw new Exception('Array Size Error', 10); + $off += 4 * $size; + return $arr; + } + private function get16(&$off){ + $int = unpack('v', substr($this->xml, $off, 2)); + $off += 2; + return array_shift($int); + } + private function skip($size){ + $this->xml = substr($this->xml, $size); + $this->length -= $size; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/coin/Coin.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/coin/Coin.php new file mode 100644 index 0000000..0c8cf2b --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/coin/Coin.php @@ -0,0 +1,103 @@ +'1000', + 'sort'=>'market_cap', + 'sort_dir'=>'desc', + * @param array $params + * @return array|bool|int|string + */ + function getAll(array $params){ + $params_str = http_build_query($params); + $url = $this->url.'?'.$params_str; + + $header = [ + 'X-CMC_PRO_API_KEY:'.$this->apiKey, + 'accept: application/json', + ]; + + return Curl::curl_get($url,10,$header); + } + + + /** + * desc: + * + *https://coinmarketcap.com/api/documentation/v1/#section/Introduction + * 'https://pro-api.coinmarketcap.com/v2/cryptocurrency/ohlcv/historical' + * author:wh + */ + function k(){ + $url = $this->url; + $time_start = input('time_start'); + $time_end = input('time_end'); + $type = input('type'); + + $header = [ + 'X-CMC_PRO_API_KEY:'.$this->apiKey, + ]; + + $arr = explode('=',$type); + $params = [ + $arr[0]=>$arr[1],//币种 + 'time_start'=>$time_start, + 'time_end'=>$time_end, + 'count'=>7, + ]; + + $url = $url.'?'.http_build_query($params); + + return Curl::curl_get($url,10,$header); + } + + private function curl_request($url, $method = 'GET',$data=null,$header=array(),$call_back=null) + { + set_time_limit(30); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + if($header){ + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + } + if($method == 'POST'){ + if($data) curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + } + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + if($call_back){ + curl_setopt($ch, CURLOPT_WRITEFUNCTION, $call_back); + } + $result = curl_exec($ch); + if (curl_errno($ch)) { + return [ + 'status' => 'error', + 'message' => 'curl 错误信息: ' . curl_error($ch) + ]; + } + curl_close($ch); + return $result; + } + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/DbCacheUtility.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/DbCacheUtility.php new file mode 100644 index 0000000..34d4c5f --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/DbCacheUtility.php @@ -0,0 +1,390 @@ +table)->whereIn("id",$ids)->where(["is_deleted"=>0]); + return DbCacheUtility::getAll($obj); + } + * Class DbCacheUtility + * @package libraries + */ +class DbCacheUtility +{ + const NoCacheTime = 0; + const LowCacheTime = 60 * 1; + const NormalCacheTime = 60 * 10; + const HighCacheTime = 60 * 60; + const LongCacheTime = 60 * 60 * 24; + + /** + * desc: + * author:wh + * @param $object 查询对象 + * @param int $cacheDuration + * @param bool $is_log + * @return mixed + */ + public static function getOne($object, $cacheDuration = self::NoCacheTime, $is_log = true) + { + $begin_time = Tools::getMillisecond(); + + $is_cache = 0; + + $last_sql = $object->fetchSql(true)->find(); + + $md5_name = md5($last_sql); + + $key = 'get_one:' . $md5_name; + + if ($cacheDuration == 0) { + if(cache($key)){ + cache($key, null); + } + } + + if (!(cache($key))) { + $result = $object->fetchSql(false)->find(); + if ($cacheDuration != 0) { + cache($key, $result, $cacheDuration); + } + } else { + $is_cache = 1; + $result = cache($key); + } + + $end_time = Tools::getMillisecond(); + + if($is_log){ + SqlOperateLog::add($last_sql, $end_time, $begin_time, $md5_name, 'get_one', $is_cache); + } + + return $result; + } + + /** + * desc: + * author:wh + * @param $object 查询对象 + * @param int $cacheDuration + * @param bool $is_log + * @return mixed + */ + public static function getAll($object, $cacheDuration = self::NoCacheTime, $is_log = true) + { + + $begin_time = Tools::getMillisecond(); + + $is_cache = 0; + + $last_sql = $object->fetchSql(true)->select(); + + $md5_name = md5($last_sql); + + $key = 'get_all:' . $md5_name; + + if ($cacheDuration == 0) { + if(cache($key)){ + cache($key, null); + } + } + + if (!(cache($key))) { + $result = $object->fetchSql(false)->select(); + if ($cacheDuration != 0) { + cache($key, $result, $cacheDuration); + } + } else { + $is_cache = 1; + $result = cache($key); + } + + $end_time = Tools::getMillisecond(); + + if($is_log){ + SqlOperateLog::add($last_sql, $end_time, $begin_time, $md5_name, 'get_all', $is_cache); + } + return $result; + } + + /** + * desc: + * author:wh + * @param $object + * @param int $page + * @param int $listRows + * @param bool $simple + * @param array $config + * @param int $cacheDuration + * @param bool $is_log + * @return mixed + */ + static function paginates($object, $page=1, $listRows = null, $simple = false, $config = [], $cacheDuration = self::NoCacheTime, $is_log = true){ + + $begin_time = Tools::getMillisecond(); + + $is_cache = 0; + + $last_sql = $object->limit(abs(1*$page-1) * $listRows, $listRows)->fetchSql(true)->select(); + + $md5_name = md5($last_sql); + + $key = 'paginates:' . $md5_name; + + if ($cacheDuration == 0) { + if(cache($key)){ + cache($key, null); + } + } + + if (!(cache($key))) { + $result = $object->fetchSql(false)->paginate($listRows, $simple, $config); + if ($cacheDuration != 0) { + cache($key, $result, $cacheDuration); + } + } else { + $is_cache = 1; + $result = cache($key); + } + + $end_time = Tools::getMillisecond(); + + if($is_log){ + SqlOperateLog::add($last_sql, $end_time, $begin_time, $md5_name, 'paginates', $is_cache); + } + return $result; + } + + /** + * desc: + * author:wh + * @param $sql + * @param array $bind + * @return mixed + * @throws \think\db\exception\BindParamException + * @throws \think\exception\PDOException + */ + static function queryScalar($sql, $bind = [], $field, $cacheDuration = self::NoCacheTime, $is_log = true) + { + $begin_time = Tools::getMillisecond(); + + $is_cache = 0; + + $last_sql = self::presetBind($sql, $bind); + + $md5_name = md5($last_sql); + + $key = 'query_scalar:' . $md5_name; + + if ($cacheDuration == 0) { + if(cache($key)){ + cache($key, null); + } + } + + if (!(cache($key))) { + $result = Db::query($sql, $bind); + if ($cacheDuration != 0) { + cache($key, $result, $cacheDuration); + } + } else { + $is_cache = 1; + $result = cache($key); + } + + $end_time = Tools::getMillisecond(); + + if($is_log){ + SqlOperateLog::add($last_sql, $end_time, $begin_time, $md5_name, 'query_scalar', $is_cache); + } + + return $result ? $result[0][$field] : []; + } + + /** + * desc: + * author:wh + * @param $sql + * @param array $bind + * @return mixed + * @throws \think\db\exception\BindParamException + * @throws \think\exception\PDOException + */ + static function queryOne($sql, $bind = [], $cacheDuration = self::NoCacheTime, $is_log = true) + { + $begin_time = Tools::getMillisecond(); + + $is_cache = 0; + + $last_sql = self::presetBind($sql, $bind); + + $md5_name = md5($last_sql); + + $key = 'query_one:' . $md5_name; + + if ($cacheDuration == 0) { + if(cache($key)){ + cache($key, null); + } + } + + if (!(cache($key))) { + $result = Db::query($sql, $bind); + if ($cacheDuration != 0) { + cache($key, $result, $cacheDuration); + } + } else { + $is_cache = 1; + $result = cache($key); + } + + $end_time = Tools::getMillisecond(); + + if($is_log){ + SqlOperateLog::add($last_sql, $end_time, $begin_time, $md5_name, 'query_one', $is_cache); + } + + return $result ? $result[0] : []; + } + /** + * desc: + * author:wh + * @param $sql + * @param array $bind + * @return mixed + * @throws \think\db\exception\BindParamException + * @throws \think\exception\PDOException + */ + static function queryAll($sql, $bind = [], $cacheDuration = self::NoCacheTime, $is_log = true) + { + $begin_time = Tools::getMillisecond(); + + $is_cache = 0; + + $last_sql = self::presetBind($sql, $bind); +//echo $last_sql;die; + $md5_name = md5($last_sql); + + $key = 'query_all:' . $md5_name; + + if ($cacheDuration == 0) { + if(cache($key)){ + cache($key, null); + } + } + + if (!(cache($key))) { + $result = Db::query($sql, $bind); + if ($cacheDuration != 0) { + cache($key, $result, $cacheDuration); + } + } else { + $is_cache = 1; + $result = cache($key); + } + + $end_time = Tools::getMillisecond(); + + if($is_log){ + SqlOperateLog::add($last_sql, $end_time, $begin_time, $md5_name, 'query_all', $is_cache); + } + + return $result; + } + + /** + * desc: + * author:wh + * @param $sql + * @param array $bind + * @return int + * @throws \think\db\exception\BindParamException + * @throws \think\exception\PDOException + */ + static function execute($sql, $bind = []){ + return Db::execute($sql, $bind); + } + + /** + * desc: + * author:wh + * @param $sql + * @param array $bind + * @return mixed + */ + static function presetBind($sql, $bind = []){ + if($bind){ + foreach ($bind as $key=>$val){ + $sql = str_replace(':'.$key, $val, $sql); + } + } + return $sql; + } + + static function paginate($sql, $bind, $total, $listRows = null, $simple = false, $config = []) + { + //if (is_int($simple)) { + // $total = $simple; + // $simple = false; + //} + + $paginate = Container::get('config')->pull('paginate'); + + if (is_array($listRows)) { + $config = array_merge($paginate, $listRows); + $listRows = $config['list_rows']; + } else { + $config = array_merge($paginate, $config); + $listRows = $listRows ?: $config['list_rows']; + } + + /** @var Paginator $class */ + $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']); + $page = isset($config['page']) ? (int) $config['page'] : call_user_func([ + $class, + 'getCurrentPage', + ], $config['var_page']); + + $page = $page < 1 ? 1 : $page; + + $config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']); + + //if (!isset($total) && !$simple) { + // + // + // unset($this->options['order'], $this->options['limit'], $this->options['page'], $this->options['field']); + // + // $bind = $this->bind; + // $total = $this->count(); + // $results = $this->options($options)->bind($bind)->page($page, $listRows)->select(); + //} elseif ($simple) { + // $results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select(); + // $total = null; + //} else { + // $results = $this->page($page, $listRows)->select(); + //} + + $results = DbCacheUtility::queryAll($sql, $bind); + + return $class::make($results, $listRows, $page, $total, $simple, $config); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/RedisUtility.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/RedisUtility.php new file mode 100644 index 0000000..b8f4125 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/RedisUtility.php @@ -0,0 +1,109 @@ +handler(); + } + return self::$redisHandle; + } + /** + * desc:设置 0 永久有效 + * author:wh + * @param $key_name 键名 + * @param $value 值 json数据 + * @return bool + */ + static function set($key_name, $value){ + return Cache::store('redis')->set($key_name, json_encode($value, JSON_UNESCAPED_UNICODE)); + } + + /** + * desc:重置 + * author:wh + * @param $key_name + * @return bool + */ + static function reset($key_name){ + return Cache::store('redis')->set($key_name, null); + } + + /** + * desc:设置过期时间 + * author:wh + * @param $key_name 键名 + * @param $value 值 json数据 + * @param int $expire 过期时间 0 永久有效 + * @return bool + */ + static function setExpire($key_name, $value, $expire=0){ + return Cache::store('redis')->set($key_name, json_encode($value), $expire); + } + + /** + * desc:存储hash类型 + * author:wh + * @param $key + * @param $field + * @param $value + */ + static function hSet($key, $field, $value){ + return self::redisObject()->hSet($key, $field, json_encode($value, JSON_UNESCAPED_UNICODE)); + } + + /** + * desc:删除指定的键。 + * author:wh + * @param $key + * @return mixed + */ + static function delete($key){ + return self::redisObject()->delete($key); + } + + /** + * desc:从存储在键上的哈希中移除一个值。 + * 如果哈希表不存在,或者键不存在,则返回 FALSE 。 + * author:wh + * @param $key + * @param $hashKey1 + * @return mixed + */ + static function hDel($key, $hashKey1){ + return self::redisObject()->hDel($key, $hashKey1); + } + + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/SqlOperateLog.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/SqlOperateLog.php new file mode 100644 index 0000000..8bce713 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/SqlOperateLog.php @@ -0,0 +1,55 @@ +request()->baseUrl(), + 'duration_time'=>$end_time - $begin_time, + 'type'=>$type, + 'is_cache'=>$is_cache?1:0, + 'sql'=>$sql, + 'md5_name'=>$md5_name, + ]; + try{ + if(config('app.is_sql_slow_log') && ($end_time - $begin_time) >= config('app.is_sql_slow_log')){ + Db::table('log_sql_operate')->insert($data); + } + }catch (\Exception $e){ + //DATABASE BOOM + //tp6 + //Log::error('========[数据库异常:DATABASE BOOM]========'.$e->getTraceAsString()); + //Log::close(); + //tp5.1 + Log::write('========[DATABASE ERROR:DATABASE BOOM]========【'.$e->getMessage().'】'.$e->getTraceAsString()); + } + } + + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/Elasticsearch.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/Elasticsearch.php new file mode 100644 index 0000000..592c5ea --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/Elasticsearch.php @@ -0,0 +1,262 @@ +ip = false===strpos($ip_port,'http')?'http://'.$ip_port:$ip_port; + $this->index_sign = $index_sign; + } + + /** + * desc:设置查询方法,默认_search + * author:wh + * @param $method_name + */ + function setQueryMethod($method_name){ + $this->query_method = $method_name; + } + + + /** + * desc:根据日期索引查询文档 + * 注:默认一个月 + * + * eg:'qa-stat-2021.01'; + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * author:wh + */ + function setIndexDefault(){ + $this->setRequestIndex(date('Y'.$this->doc_date_sign.'m')); + } + + /** + * desc:设置要查询的日期文档索引 + * + * 1、按年检索文档[建议5年左右] + * + * eg: qa-stat-2018.*,qa-stat-2019.*,qa-stat-2020.*,qa-stat-2021.* + * + * 注意:当索引过长,es会抛出索引太长异常 + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * + * author:wh + * @param string $start_time 开始时间 eg:2010-01-01 08:05:55 + * @param string $end_time 结束时间 eg:2021-12-31 12:05:00 + * @return string + */ + function setIndexYearDate(string $start_time, string $end_time){ + + //默认查询索引 + $index = date('Y'.$this->doc_date_sign.'*', strtotime($start_time)); + + $sign = ',';//分隔符 + + $m = date('Y', strtotime($end_time)) - date('Y', strtotime($start_time)); + + //拼装查询索引 + for ($i=0; $i<$m; $i++){ + + $index .= $sign.($this->index_sign.(date('Y', strtotime($start_time))+$i).$this->doc_date_sign.'*'); + } + + $this->setRequestIndex($index); + } + + /** + * desc:设置日期索引 + * + * 检索全部日期索引文档 + * + * 例如es设置的索引为: + * qa-stat-2021.01 + qa-stat-2021.02 + qa-stat-2021.03 + qa-stat-2021.04 + * + * 实际查询自动设置为:qa-stat-* + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * + * author:wh + * @return string + */ + function setIndexAllDate(){ + + $this->setRequestIndex('*'); + } + + /** + * desc:设置普通索引 + * + * 调用此方法,请在初始化时,设置索引前缀index_sign为""空字符串 + * + * author:wh + * @param string $index + */ + function setIndexNormal(string $index){ + $this->setRequestIndex($index); + } + + /** + * desc:设置跨月份索引 + * + * eg: qa-stat-2021.01,qa-stat-2021.02 + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * + * author:wh + * @param string $start_time eg:'2020-11' + * @param string $end_time eg:'2021-01' + * @return string eg: qa-stat-2020.11,qa-stat-2020.12,qa-stat-2021.01 + */ + function setIndexDate(string $start_time, string $end_time){ + $date = new Date(); + + //计算月份 + $m = $date->dateCutMonth($start_time, $end_time); + ////解决跨年且不足1个月时,索引设置错误问题 + //if($m == 0 && (date('Y', strtotime($end_time)) > date('Y', strtotime($start_time)))){ + // $m = 1; + //} + //格式 + $date->date_format = 'Y-m'; + + //默认查询索引 + $index = date('Y'.$this->doc_date_sign.'m', strtotime($start_time)); + + $tmp_time = $start_time; + $sign = ',';//分隔符 + + //拼装查询索引 + for ($i=0; $i<$m; $i++){ + $tmp_time = $date->addTime(1, 'M', strtotime($tmp_time)); + $index .= $sign.$this->index_sign.(date('Y'.$this->doc_date_sign.'m', strtotime($tmp_time))); + } + + $this->setRequestIndex($index); + } + + + /** + * desc:设置查询参数 + * author:wh + * @param string $query_param_json + */ + function setQueryParam(string $query_param_json){ + $this->query_param = $query_param_json; + $this->post_url = $this->ip.'/'.$this->index.'/'.$this->query_method; + } + + /** + * desc:获取查询参数,用于调试 + * author:wh + * @return array + */ + function getQueryParam(){ + return [ + 'ip'=>$this->ip, + 'index_sign'=>$this->index_sign, + 'index'=>$this->index, + 'query_method'=>$this->query_method, + 'post_url'=>$this->post_url, + 'query_param'=>$this->query_param, + ]; + } + + /** + * desc:执行es查询 + * author:wh + * @return array|bool|int|string + * @throws \Exception + */ + function execute(){ + if(empty($this->ip)) throw new \Exception('请设置ip'); + //if(empty($this->index_sign)) throw new \Exception('请设置索引前缀'); + if(empty($this->index)) throw new \Exception('请设置索引'); + if(empty($this->query_method)) throw new \Exception('请设置查询方法'); + if(empty($this->query_param)) throw new \Exception('请设置查询参数'); + + + + + Tools::log_to_write_txt(['exe_func'=>$this->exe_func,'request_url'=>$this->post_url,'IN'=>" | IN: ",'query_params'=>$this->query_param, 'input'=>input()], $this->es_log_file); + $result = Tools::curl_post($this->post_url, $this->query_param); + Tools::log_to_write_txt(['exe_func'=>$this->exe_func,'OUT'=>" | OUT: ", 'result'=>$result], $this->es_log_file); + + return $result; + } + + /** + * desc:设置是哪个方法调用本es库,用于日志记录 + * author:wh + * @param string $function + */ + function setExecuteFunction(string $function){ + $this->exe_func = $function; + } + + /** + * desc:设置请求文档索引 + * author:wh + * @param string $index + */ + protected function setRequestIndex(string $index){ + $this->index = $this->index_sign.$index; + } + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/README.md b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/README.md new file mode 100644 index 0000000..ea56d61 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/es/README.md @@ -0,0 +1,1340 @@ +##### Elasticsearch数据库操作类库使用教程 + +#### 一、Elasticsearch原生cUrl查询库 +##### 说明:该库只提供查询请求,开发者只需要关注查询参数怎么写,请求之后会把结果按原样返回,不会有任何修改。 + +**** + +###### 【查询参数案例:查询一条数据】 +###### 只需要简单的查询条件即可;from=0,size=1表示从第0条数据查询1条,from可省略,等于mysql的limit 1。 +###### 这里unixtime和statFunc为数据结构(表)中的字段名称,gt大于,lt小于,gte大于等于,lte小于等于 +###### 这里register是字段statFunc的值,而unixtime存的是毫秒时间戳 +###### 注:数据字段尽量不存小数,小数太小的时候,在内存中计算时会出现误差,比如0.001+0.001=0 + +#### 代码使用示例: +``` + +//======【有规律的日期索引】【特殊】======= +$query_params = "{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1623254400000, + "lt": 2623340800000 + } + } + }, + { + "terms": { + "statFunc": [ + "signup", + "returncard" + ] + } + }, + { + "term": { + "matchTypeNum": 3 + } + } + ] + } + }, + "size": 1, + "aggs": { + "group_by_day": { + "date_histogram": { + "field": "@timestamp", + "interval": "day", + "min_doc_count": 0, + "order": { + "_key": "asc" + }, + "time_zone": "+08:00", + "format": "yyyy-MM-dd" + }, + "aggs": { + "item1000_sum": { + "sum": { + "field": "item1000" + } + } + } + } + } + }"; +$es = new Elasticsearch('http://49.4.3.4:3201','qa-item-'); +$es->setIndexAllDate(); +$es->setQueryParam($query_params); +dump($es->execute()); + +dump('=================================================================='); + +//======【无规律的普通索引】【推荐】======= +$query_params = "{ + 'query': { + 'bool': { + 'must': [ + { + 'range': { + 'unixtime': { + 'gt': 1617206400000, + 'lt': 1619712000000 + } + } + }, + { + 'term': { + 'statFunc': 'register' + } + } + ] + } + }, + 'size': 1 + }"; +dump($query_params); +$es = new Elasticsearch('http://49.4.3.4:3201',''); +$es->setIndexNormal('qa-item-2021.06.*'); +$es->setQueryParam($query_params); +dump($es->execute()); + + +//以上都经过测试 + +``` + +#### 查询参数示例 +###### 示例1: 这里展示了must查询 +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "statFunc": "register" + } + } + ] + } + }, + "size": 1 +} +``` +###### 示例2: 这里展示了混合查询 +###### must表示必须,等于mysql的and; +###### should表示应该,等于mysql的or; +###### 模糊查询用missing,等于mysql的like,但是不用%%通配符; +###### must_not表示必须不是,等于mysql的!=; +###### 它们可以一起使用。 +###### 仔细观察发现,query,bool基本是固定的,而里面的参数写法都差不多。 + +``` +{ + "query": { + "bool": { + "must": [ + { + "match": { + "statFunc": "signup" + } + } + ], + "must_not": [], + "should": [ + { + "term": { + "gameTagNum": "210" + } + }, + { + "term": { + "gameTagNum": "300" + } + } + ] + } + }, + "size": 1 +} +``` + +**** + +###### 【查询参数案例:查询多条数据】 +###### 只需要简单的查询条件即可,这里只改变了size字段值。 +###### eg: +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "statFunc": "register" + } + } + ] + } + }, + "size": 10 +} +``` + +**** + +###### 【查询参数案例:简单聚合】 +###### 根据时间和某个字段查询数据,并且基于查询结果再次按时间分组,分组段按天分段,同时基于查询结果再次聚合某个字段 +###### 为了便于演示,这里查询条件改为容易理解的字段:"统计张三一段时间内已下单的订单总金额" +###### order_money_sum是自定义名称,等于mysql的别名 +###### eg: +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "order_time": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "name": "张三" + } + } + ] + } + }, + "size": 0, + "aggs": { + "order_money_sum": { + "sum": { + "field": "order_money" + } + } + } +} +``` + +###### 【查询参数案例:复杂聚合】 +###### aggs可以嵌套,嵌套时的含义表示基于上一个聚合结果再次聚合 +###### 这里表示先按day(天)分组,再统计字段名为item1000的字段,day可以改为月(month)年(year) +###### eg: +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "statFunc": "register" + } + } + ] + } + }, + "size": 0, + "aggs": { + "group_by_day": { + "date_histogram": { + "field": "@timestamp", + "interval": "day", + "min_doc_count": 0, + "order": { + "_key": "desc" + }, + "time_zone": "+08:00", + "format": "yyyy-MM-dd" + }, + "aggs": { + "item1000_sum": { + "sum": { + "field": "item1000" + } + } + } + } + } +} +``` + + +**** + +#### 二、Elasticsearch助手库(不推荐,因为不灵活。掌握了一的查询参数,其它都是小问题) + +##### 说明: + +##### 通用es查询多条数据 +* (这一种方式可实现大部分列表查询功能) +* (where条件跟随业务需要修改) +* (多条件组合查询满足不同查询业务) + +#### 查询列表: +``` + //获取分页数据 + $offset = input('offset', 5); + $limit = input('limit', 5); + + + //获取数据 + $input_data = $_POST; + 初始化es + $es = new BaseElasticsearch(); + + + //(必须)判断时间查询设置索引 + if(!empty($input_data['sign_time'])){ + $start_time = explode(' - ', $input_data['sign_time'])[0]; + $end_time = explode(' - ', $input_data['sign_time'])[1]; + //这里动态生成索引 + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + //设置默认索引 + $es->index = $es->setDefaultDate();//默认一个月 + } + + + //设置查询的文档类型 + $es->type = 'logs';//本例是查询日志类型的数据 + + //分页计算得到当前页码(可根据自身情况设置) + $es->current_page = $offset/$limit; + $es->limit = $limit; + + + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'draw' + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['sign_time'])){ + //这里将字符串日期转换为unix时间戳(精确到毫秒) + $date_arr = $es->strtounixtime($input_data['sign_time']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //排序 + $es->order('unixtime', 'desc'); + + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must、must_not、should方法必须在一起使用] + $es->must($where); + + + //执行查询 + $res = $es->query(); + dump($res); + +``` + +#### 查询一条数据(完全可以用查询列表功能,组合多条件筛选出一条数据): + +``` + //根据id查询一条数据 + //初始化es + $es = new BaseElasticsearch(); + + $es->index_sign = 'qa-item-';//设置index标识 + + $es->index = $es->setDefaultDate();//设置文档索引 + + $es->type = 'logs';//设置文档类型 + $res = $es->getById('AXbaw_CGbqvMMYZl-lOz'); + dump($res); +``` + + +#### 查询案例 + +``` +index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + $es->type = 'logs'; + $es->current_page = $limit ? intval($offset / $limit) + 1 : 1; + $es->limit = $limit; + //关键步骤 + //设置查询条件 + + //帐变类型:4=后台赠送,6首充奖励,7=报名,8=充值 + $change_type_arr = ['backsend'=>4,'firstprize'=>6,'signup'=>7,'recharge'=>8]; + //必须 + $where = [ + [ + 'range' => [ + $amount_field => ['gt' => -999999] + ] + ] + ]; + + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //帐变类型 + if(!empty($input_data['change_type'])){ + $where[] = [ + 'term' => [ + 'statType' => array_flip($change_type_arr)[$input_data['change_type']] + ] + ]; + } + //帐变时间 + if(!empty($input_data['change_time'])){ + $date_arr = $es->strtounixtime($input_data['change_time']); + + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + //排序 + $es->order('unixtime', 'desc'); + + //昵称查询要先查uid 再去es查昵称 + + //$es->queryRange('unixtime', [ + // 'gt' => 1609750662180, + // 'lt' => 1609750662184 + //]); + //$es->queryFieldExist($amount_field); + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + + //执行查询 + Tools::log_to_write_txt(['执行查询,入参:',$es->params], 'es_player_ticket_change_record'); + $res = $es->query(); + Tools::log_to_write_txt(['执行查询,出参:',$res], 'es_player_ticket_change_record'); + + //删除本地临时数据 + Db::execute('truncate table fa_zc_player_ticket_change_record'); + + if(empty($res['hits']['hits'])) return set_result(500, '未查询到相关数据.'); + + $lists = $res['hits']['hits']; + $this->total = $res['hits']['total']; + + //组装入库字段 + $items = []; + foreach ($lists as $list){ + $item = []; + $item['gameid'] = empty($list['_source']['uid'])?'':$list['_source']['uid']; + $item['nickname'] = empty($list['_source']['nickname'])?'':$list['_source']['nickname']; + $item['change_type'] = empty($change_type_arr[$list['_source']['statType']])?'0':$change_type_arr[$list['_source']['statType']].''; + + $item['amount'] = empty($list['_source'][$amount_field])?0:$list['_source'][$amount_field];//帐变额 + + $after_amount = empty($list['_source'][$after_amount_field])?0:$list['_source'][$after_amount_field]; + $item['after_amount'] = $after_amount; + $item['before_amount'] = $item['after_amount']-$item['amount'];//帐变前=帐变后-帐变额 + $item['change_time'] = floor($list['_source']['unixtime']/1000); + $item['api_key'] = $list['_id']; + $items[] = $item; + } + + //记录入库数据 + Tools::log_to_write_txt('记录入库数据 | '.json_encode($items, JSON_UNESCAPED_UNICODE), 'es_player_ticket_change_record'); + + //入库 + Db::table('fa_zc_player_ticket_change_record')->insertAll($items); + return set_result(200, 'ok'); + }catch (Exception $exception){ + Tools::log_to_write_txt('未查询到相关数据. error: '.$exception->getMessage().' | '.$exception->getTraceAsString(), 'es_player_ticket_change_record'); + return set_result(500, '未查询到相关数据.'.$exception->getMessage()); + } + } + + //现金 + function money(){ + try{ + //帐变前数额字段 + $amount_field = 'item1002';//现金帐变 只能是字符 + //帐变后数额字段 + $after_amount_field = 'package1002';//现金帐变 只能是字符 + + $input_data = json_decode(input('filter'), true); + $offset = input('offset', 5); + $limit = input('limit', 5); + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['change_time'])){ + $start_time = explode(' - ', $input_data['change_time'])[0]; + $end_time = explode(' - ', $input_data['change_time'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + $es->type = 'logs'; + $es->current_page = $limit ? intval($offset / $limit) + 1 : 1; + $es->limit = $limit; + //关键步骤 + //设置查询条件 + //帐变类型:3=比赛奖励,4=后台赠送 99暂定提现 + $change_type_arr = [ + //账变来源大分类 (draw:抽奖,exchange:兑换,winprize:比赛奖励,backsend:后台赠送,sign:签到,firstprize:首充奖励,signup:报名,recharge:充值,useprop:使用道具,cashout:提现,regsend:注册赠送) + 'winprize'=>3, + 'backsend'=>4, + 'cashout'=>99 + ]; + //必须 + $where = [ + [ + 'range' => [ + $amount_field => ['gt' => -999999] + ] + ], + ]; + + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //帐变类型 + if(!empty($input_data['change_type'])){ + $where[] = [ + 'term' => [ + 'statType' => array_flip($change_type_arr)[$input_data['change_type']] + ] + ]; + } + //帐变时间 + if(!empty($input_data['change_time'])){ + $date_arr = $es->strtounixtime($input_data['change_time']); + + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + //排序 + $es->order('unixtime', 'desc'); + + //$es->queryRange('unixtime', [ + // 'gt' => 1609750662180, + // 'lt' => 1609750662184 + //]); + //$es->queryFieldExist($amount_field); + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + + //执行查询 + Tools::log_to_write_txt(['执行查询,入参:',$es->params], 'es_player_cash_change_record'); + $res = $es->query(); + Tools::log_to_write_txt(['执行查询,出参:',$res], 'es_player_cash_change_record'); + + //删除本地临时数据 + Db::execute('truncate table fa_zc_player_cash_change_record'); + + if(empty($res['hits']['hits'])) return set_result(500, '未查询到相关数据.'); + + $lists = $res['hits']['hits']; + $this->total = $res['hits']['total']; + //组装入库字段 + $items = []; + foreach ($lists as $list){ + $item = []; + $item['gameid'] = empty($list['_source']['uid'])?'':$list['_source']['uid']; + $item['nickname'] = empty($list['_source']['nickname'])?'':$list['_source']['nickname']; + $item['change_type'] = empty($change_type_arr[$list['_source']['statType']])?'0':$change_type_arr[$list['_source']['statType']].''; + + $item['amount'] = empty($list['_source'][$amount_field])?'0':$list['_source'][$amount_field].'';//帐变额 + + $after_amount = empty($list['_source'][$after_amount_field])?0:$list['_source'][$after_amount_field]; + $item['after_amount'] = $after_amount; + $item['before_amount'] = $item['after_amount']-$item['amount'];//帐变前=帐变后-帐变额 + $item['change_time'] = floor($list['_source']['unixtime']/1000); + $item['api_key'] = $list['_id']; + $items[] = $item; + } + //记录入库数据 + Tools::log_to_write_txt('记录入库数据 | '.json_encode($items, JSON_UNESCAPED_UNICODE), 'es_player_cash_change_record'); + + //入库 + Db::table('fa_zc_player_cash_change_record')->insertAll($items); + return set_result(200, 'ok'); + }catch (Exception $exception){ + Tools::log_to_write_txt('未查询到相关数据. error: '.$exception->getMessage().' | '.$exception->getTraceAsString(), 'es_player_cash_change_record'); + return set_result(500, '未查询到相关数据.'.$exception->getMessage()); + } + } + + //礼券 + function gift(){ + try{ + //帐变前数额字段 + $amount_field = 'item1001';//只能是字符 + //帐变后数额字段 + $after_amount_field = 'package1001';//只能是字符 + + $input_data = json_decode(input('filter'), true); + $offset = input('offset', 5); + + $limit = input('limit', 5); + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['change_time'])){ + $start_time = explode(' - ', $input_data['change_time'])[0]; + $end_time = explode(' - ', $input_data['change_time'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + $es->type = 'logs'; + $es->current_page = $limit ? intval($offset / $limit) + 1 : 1; + $es->limit = $limit; + //关键步骤 + //设置查询条件 + //帐变类型:1=抽奖,2=兑换,3=比赛奖励,4=后台赠送,5=签到 + $change_type_arr = ['draw'=>1,'exchange'=>2,'winprize'=>3,'backsend'=>4,'sign'=>5]; + //必须 + $where = [ + [ + 'range' => [ + $amount_field => ['gt' => -999999] + ] + ], + ]; + + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //帐变类型 + if(!empty($input_data['change_type'])){ + $where[] = [ + 'term' => [ + 'statType' => array_flip($change_type_arr)[$input_data['change_type']] + ] + ]; + } + //帐变时间 + if(!empty($input_data['change_time'])){ + $date_arr = $es->strtounixtime($input_data['change_time']); + + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + //排序 + $es->order('unixtime', 'desc'); + + //$es->queryRange('unixtime', [ + // 'gt' => 1609750662180, + // 'lt' => 1609750662184 + //]); + //$es->queryFieldExist($amount_field); + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + + //执行查询 + Tools::log_to_write_txt(['执行查询,入参:'], 'es_player_gift_change_record'); + $res = $es->query(); + + Tools::log_to_write_txt(['执行查询,出参:', $es->params, $res], 'es_player_gift_change_record'); + + //删除本地临时数据 + Db::execute('truncate table fa_zc_player_gift_change_record'); + + if(empty($res['hits']['hits'])) return set_result(500, '未查询到相关数据.'); + + $lists = $res['hits']['hits']; + + $this->total = $res['hits']['total']; + //组装入库字段 + $items = []; + foreach ($lists as $list){ + $item = []; + $item['gameid'] = empty($list['_source']['uid'])?'':$list['_source']['uid']; + $item['nickname'] = empty($list['_source']['nickname'])?'':$list['_source']['nickname']; + $item['change_type'] = empty($change_type_arr[$list['_source']['statType']])?'0':$change_type_arr[$list['_source']['statType']].''; + + $item['amount'] = empty($list['_source'][$amount_field])?'0':$list['_source'][$amount_field].'';//帐变额 + + $after_amount = empty($list['_source'][$after_amount_field])?0:$list['_source'][$after_amount_field]; + $item['after_amount'] = $after_amount; + $item['before_amount'] = $item['after_amount']-$item['amount'];//帐变前=帐变后-帐变额 + $item['change_time'] = floor($list['_source']['unixtime']/1000); + $item['api_key'] = $list['_id']; + $items[] = $item; + } + //记录入库数据 + Tools::log_to_write_txt(['记录入库数据',$items], 'es_player_gift_change_record'); + + //入库 + Db::table('fa_zc_player_gift_change_record')->insertAll($items); + return set_result(200, 'ok', $res); + }catch (Exception $exception){ + Tools::log_to_write_txt('未查询到相关数据. error: '.$exception->getMessage().' | '.$exception->getTraceAsString(), 'es_player_gift_change_record'); + return set_result(500, '未查询到相关数据.'.$exception->getMessage()); + } + + } + +} +``` + +#### 聚合案例 + +##### sum求和 +``` +index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + if(!empty($input_data['order_status'])){ + $where[] = [ + 'term' => [ + 'status' => $input_data['order_status'] + ] + ]; + } + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + + + /** + * desc:查询本月总充值 + * author:wh + * @return array|\think\response\Json + */ + function month(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['order_itme'])){ + $start_time = explode(' - ', $input_data['order_itme'])[0]; + $end_time = explode(' - ', $input_data['order_itme'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'unixtime' => [ + 'gt' => strtotime(date('Y-m').'-01').'000', + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //订单状态(es的充值记录都是充值成功的数据) + //if(!empty($input_data['order_status'])){ + // $where[] = [ + // 'term' => [ + // 'status' => $input_data['order_status'] + // ] + // ]; + //} + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + /** + * desc:查询本周总充值 + * author:wh + * @return array|\think\response\Json + */ + function week(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['order_itme'])){ + $start_time = explode(' - ', $input_data['order_itme'])[0]; + $end_time = explode(' - ', $input_data['order_itme'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ], + [ + 'range' => [ + //本周 + 'unixtime' => [ + 'gte' => strtotime((new Date())->beginWeek()).'000', + 'lte' => strtotime((new Date())->endWeek()).'000', + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //订单状态(es的充值记录都是充值成功的数据) + //if(!empty($input_data['order_status'])){ + // $where[] = [ + // 'term' => [ + // 'status' => $input_data['order_status'] + // ] + // ]; + //} + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + /** + * desc:查询今日总充值 + * author:wh + * @return array|\think\response\Json + */ + function today(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['order_itme'])){ + $start_time = explode(' - ', $input_data['order_itme'])[0]; + $end_time = explode(' - ', $input_data['order_itme'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ], + [ + 'range' => [ + //今日 + 'unixtime' => [ + 'gt' => strtotime(date('Y-m-d')).'000', + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //订单状态(es的充值记录都是充值成功的数据) + //if(!empty($input_data['order_status'])){ + // $where[] = [ + // 'term' => [ + // 'status' => $input_data['order_status'] + // ] + // ]; + //} + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + + + + + +} +``` + +#### 或查询(相当于mysql or查询) +``` +/** + * desc:或查询(相当于mysql or查询) + * author:wh + * @return array|\think\response\Json + */ + function total(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['conversion_time'])){ + $start_time = explode(' - ', $input_data['conversion_time'])[0]; + $end_time = explode(' - ', $input_data['conversion_time'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + //$es->index = $es->setDefaultDate();//默认一个月 + //默认查询所有历史记录 + $es->index = $es->setIndexAllDate(); + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 999999999; + //关键步骤 + //设置查询条件 + // + $where = [ + [ + 'term' => [ + 'statType' => 'exchange'//兑换类型 + ] + ], + + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //昵称 + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //时间 + if(!empty($input_data['conversion_time'])){ + $date_arr = $es->strtounixtime($input_data['conversion_time']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + $should_where = [ + [ + "range"=> [ + "item2001"=> [ + "gte"=> -9999999 + ] + ] + ], + [ + "range"=> [ + "item2002"=> [ + "gte"=> -9999999 + ] + ] + ], + [ + "range"=> [ + "item2005"=> [ + "gte"=> -9999999 + ] + ] + ], + [ + "range"=> [ + "item2010"=> [ + "gte"=> -9999999 + ] + ] + ] + ]; + + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->should($should_where); + $es->setAggs('item1001', 1); + //执行查询 + $res = $es->sum(); + + return $res['aggregations']['sum']['value']; + } +``` \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/README.MD b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/README.MD new file mode 100644 index 0000000..1960d4c --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/README.MD @@ -0,0 +1,6 @@ +## 仅适用于tp5+, php7+ + + +## 表管理 + +## 字段管理 \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Field.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Field.php new file mode 100644 index 0000000..2bab4c9 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Field.php @@ -0,0 +1,304 @@ +getTableFields(); + if(in_array($table['fields_name'], $f)){ + //枚举类型 + if ($table['type'] == 'enum'){ + $enum_str = ''; + $enum_default = ''; + //组合枚举值 + if($table['default']){ + $enum_str.='ENUM('.$table['default'].')'; + $enum_default = explode(',', $table['default'])[0]; + } + $sql2 = "ALTER TABLE {$table_name} MODIFY {$table['fields_name']} {$enum_str} NOT NULL DEFAULT {$enum_default} COMMENT '{$table['title']}';"; + }else{ + $sql2 = "ALTER TABLE {$table_name} MODIFY COLUMN {$table['fields_name']} {$table['type']}(".$table['size'].$dec_num.") {$is_unsigned} DEFAULT {$table['default']} COMMENT '{$table['title']}';"; + } + }else{ + + if(in_array($table['type'], ['text','longtext'])){ + $sql2 = "ALTER TABLE {$table_name} ADD COLUMN {$table['fields_name']} {$table['type']} COMMENT '{$table['title']}' AFTER id;"; + }elseif ($table['type'] == 'enum'){//枚举类型 + $enum_str = ''; + $enum_default = ''; + //组合枚举值 + if($table['default']){ + $enum_str.='ENUM('.$table['default'].')'; + $enum_default = explode(',', $table['default'])[0]; + } + $sql2 = "ALTER TABLE {$table_name} ADD {$table['fields_name']} {$enum_str} NOT NULL DEFAULT {$enum_default} COMMENT '{$table['title']}' AFTER id;"; + }else{ + $sql2 = "ALTER TABLE {$table_name} ADD COLUMN {$table['fields_name']} {$table['type']}(".$table['size'].$dec_num.") {$is_unsigned} DEFAULT {$table['default']} COMMENT '{$table['title']}' AFTER id;"; + } + } + + DB::execute($sql2); + } + + /** + * desc:删除字段 + * author:wh + * @param $tablename + * @param $fieldname + */ + function dropFieldName($tablename, $fieldname){ + $sql = "ALTER TABLE {$tablename} DROP COLUMN {$fieldname};"; + DB::execute($sql); + } + + /** + * desc:改注释 + * author:wh + * @param $tablename + * @param $comment + * @return bool + */ + function updateComment($tablename,$field, $comment){ + + $sql = "ALTER TABLE {$tablename} MODIFY COLUMN {$field} INT COMMENT '{$comment}';"; + Db::execute($sql); + } + + /** + * desc:获取数据表中所有字段的数据类型(含其它属性) + * + * 查询结果字段名说明 + * + * F_FIELD:字段名称 + * F_DATATYPE:数据类型 + * F_DATALENGTH:数据长度(int类型默认为null,业务处理时默认为10即可) + * F_PRECISION:精度 + * F_DECIMAL_DIGITS:小数位数 + * F_ALLOWNULL:是否允许为null值(1是,0否) + * F_FIELDNAME:字段名称 + * F_PRIMARYKEY:是否主键(1是,0否) + * F_DEFAULTS:字段默认值 + * + * author:wh + * @param string $dbname + * @param string $tablename + * @param string $fieldname + * @return mixed + */ + function getFieldsDataType(string $dbname,string $tablename){ + $sql = "SELECT + COLUMN_NAME F_FIELD, + data_type F_DATATYPE, + CHARACTER_MAXIMUM_LENGTH F_DATALENGTH, + NUMERIC_PRECISION F_PRECISION, + NUMERIC_SCALE F_DECIMAL_DIGITS, +IF + ( IS_NULLABLE = 'YES', '1', '0' ) F_ALLOWNULL, + COLUMN_COMMENT F_FIELDNAME, +IF + ( COLUMN_KEY = 'PRI', '1', '0' ) F_PRIMARYKEY, + column_default F_DEFAULTS, + CONCAT( upper( COLUMN_NAME ), '(', COLUMN_COMMENT, ')' ) AS 'F_DESCRIPTION' +FROM + INFORMATION_SCHEMA.COLUMNS +WHERE + TABLE_NAME = '$tablename' + AND TABLE_SCHEMA = '$dbname'"; + return Db::query($sql); + } + + + /** + * desc:获取数据表中某个字段的数据类型(含这个字段的其它属性) + * + * 查询结果字段名说明 + * + * F_FIELD:字段名称 + * F_DATATYPE:数据类型 + * F_DATALENGTH:数据长度(int类型默认为null,业务处理时默认为10即可) + * F_PRECISION:精度 + * F_DECIMAL_DIGITS:小数位数 + * F_ALLOWNULL:是否允许为null值(1是,0否) + * F_FIELDNAME:字段名称 + * F_PRIMARYKEY:是否主键(1是,0否) + * F_DEFAULTS:字段默认值 + * + * author:wh + * @param string $dbname + * @param string $tablename + * @param string $fieldname + * @return mixed + */ + function getFieldDataType(string $dbname,string $tablename,string $fieldname){ + $sql = "SELECT + COLUMN_NAME F_FIELD, + data_type F_DATATYPE, + CHARACTER_MAXIMUM_LENGTH F_DATALENGTH, + NUMERIC_PRECISION F_PRECISION, + NUMERIC_SCALE F_DECIMAL_DIGITS, +IF + ( IS_NULLABLE = 'YES', '1', '0' ) F_ALLOWNULL, + COLUMN_COMMENT F_FIELDNAME, +IF + ( COLUMN_KEY = 'PRI', '1', '0' ) F_PRIMARYKEY, + column_default F_DEFAULTS, + CONCAT( upper( COLUMN_NAME ), '(', COLUMN_COMMENT, ')' ) AS 'F_DESCRIPTION' +FROM + INFORMATION_SCHEMA.COLUMNS +WHERE + TABLE_NAME = '$tablename' + AND TABLE_SCHEMA = '$dbname' + AND COLUMN_NAME='$fieldname' + "; + $ar = Db::query($sql); + return $ar[0]; + } + + + /** + * desc:获取数据表中某个字段的数据类型 + * + * 不含这个字段的其它属性 + * + * + * 查询结果字段名说明 + * + * F_FIELD:字段名称 + * F_DATATYPE:数据类型 + * F_DATALENGTH:数据长度(int类型默认为null,业务处理时默认为10即可) + * F_PRECISION:精度 + * F_DECIMAL_DIGITS:小数位数 + * F_ALLOWNULL:是否允许为null值(1是,0否) + * F_FIELDNAME:字段名称 + * F_PRIMARYKEY:是否主键(1是,0否) + * F_DEFAULTS:字段默认值 + * + * author:wh + * @param string $dbname + * @param string $tablename + * @param string $fieldname + * @return mixed + */ + function getFieldDataTypeVal(string $dbname,string $tablename,string $fieldname){ + $sql = "SELECT + COLUMN_NAME F_FIELD, + data_type F_DATATYPE, + CHARACTER_MAXIMUM_LENGTH F_DATALENGTH, + NUMERIC_PRECISION F_PRECISION, + NUMERIC_SCALE F_DECIMAL_DIGITS, +IF + ( IS_NULLABLE = 'YES', '1', '0' ) F_ALLOWNULL, + COLUMN_COMMENT F_FIELDNAME, +IF + ( COLUMN_KEY = 'PRI', '1', '0' ) F_PRIMARYKEY, + column_default F_DEFAULTS, + CONCAT( upper( COLUMN_NAME ), '(', COLUMN_COMMENT, ')' ) AS 'F_DESCRIPTION' +FROM + INFORMATION_SCHEMA.COLUMNS +WHERE + TABLE_NAME = '$tablename' + AND TABLE_SCHEMA = '$dbname' + AND COLUMN_NAME='$fieldname' + "; + $ar = Db::query($sql); + return $ar[0]['F_DATATYPE']; + } + + /** + * desc:获取数据表中某个字段的属性 + * + * 查询结果字段名说明 + * + * F_FIELD:字段名称 + * F_DATATYPE:数据类型 + * F_DATALENGTH:数据长度(int类型默认为null,业务处理时默认为10即可) + * F_PRECISION:精度 + * F_DECIMAL_DIGITS:小数位数 + * F_ALLOWNULL:是否允许为null值(1是,0否) + * F_FIELDNAME:字段名称 + * F_PRIMARYKEY:是否主键(1是,0否) + * F_DEFAULTS:字段默认值 + * + * author:wh + * @param string $dbname + * @param string $tablename + * @param string $fieldname + * @return mixed + */ + function getFieldAttrVal(string $dbname,string $tablename,string $fieldname,string $attr){ + $sql = "SELECT + COLUMN_NAME F_FIELD, + data_type F_DATATYPE, + CHARACTER_MAXIMUM_LENGTH F_DATALENGTH, + NUMERIC_PRECISION F_PRECISION, + NUMERIC_SCALE F_DECIMAL_DIGITS, +IF + ( IS_NULLABLE = 'YES', '1', '0' ) F_ALLOWNULL, + COLUMN_COMMENT F_FIELDNAME, +IF + ( COLUMN_KEY = 'PRI', '1', '0' ) F_PRIMARYKEY, + column_default F_DEFAULTS, + CONCAT( upper( COLUMN_NAME ), '(', COLUMN_COMMENT, ')' ) AS 'F_DESCRIPTION' +FROM + INFORMATION_SCHEMA.COLUMNS +WHERE + TABLE_NAME = '$tablename' + AND TABLE_SCHEMA = '$dbname' + AND COLUMN_NAME='$fieldname' + "; + $ar = Db::query($sql); + return $ar[0][$attr]; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Table.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Table.php new file mode 100644 index 0000000..0456999 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/db/mysql/lib/Table.php @@ -0,0 +1,162 @@ +$this->appid, + 'secret'=>$this->secret, + 'grant_type'=>'client_credential', + ]; + $header = [ + 'Accept: application/json', + 'content-type: application/json' + ]; + $res = Curl::curl_request($url,$method,json_encode($params),$header); + + $json_arr = json_decode($res, true); + if($json_arr['err_no']){ + return Tools::set_res($json_arr['err_no'],$json_arr['err_tips']); + } + //保存 + session('ses_dou_yin_access_token',$json_arr['data']); + return Tools::set_ok('ok',$json_arr['data']); + } + + /** + * desc:实时获取token + * author:wh + * @return array + */ + function realTimeGetAccessToken(){ + $json_arr = session('ses_dou_yin_access_token'); + if(empty($json_arr)){ + return $this->getAccessToken(); + } + if(time() >= $json_arr['expiresAt']){ + //过期 + return $this->getAccessToken(); + } + return Tools::set_ok('ok',$json_arr); + } + + /** + * desc:前端tt.login触发调用 + * + * author:wh + */ + function jscode2session($code='',$anonymous_code=''){ + $url = 'https://minigame.zijieapi.com/mgplatform/api/apps/jscode2session'; + //$Scope = 'open.ttgame.mgplatform'; + $method = 'GET'; + + if(empty($code) && empty($anonymous_code)){ + return Tools::set_fail('tt.login 接口返回的匿名登录凭证(code 和 anonymous_code 至少要有一个)'); + } + $params = [ + 'appid'=>$this->appid, + 'secret'=>$this->secret, + ]; + if($code){ + $params['code'] = $code; + } + if($anonymous_code){ + $params['anonymous_code'] = $anonymous_code; + } + $header = [ + 'Accept: application/json', + 'content-type: application/json' + ]; + $url .= '?'.http_build_query($params); + //dump($url); + Tools::log_to_write_txt(['input'=>$url]); + $res = Curl::curl_request($url,$method,[],$header); + Tools::log_to_write_txt(['output'=>$res]); + //dump($res); + $json_arr = json_decode($res, true); + //dump($json_arr);die; + if($json_arr['error']){ + return Tools::set_res($json_arr['errcode'],$json_arr['errmsg']); + } + //保存 + session('ses_dou_yin_js_code_2_session',$json_arr); + return Tools::set_ok('ok',$json_arr); + } + + /** + * desc:创建二维码 + * 接口说明 + * 获取小程序/小游戏的二维码。该二维码可通过任意 app 扫码打开, + * 能跳转到开发者指定的对应字节系 app 内拉起小程序/小游戏,并传入开发者指定的参数。 + * 通过该接口生成的二维码,永久有效,暂无数量限制。 + * + * ⚠ Tip:在使用该功能之前请记得先配置您的默认分享文案和图片,配置方式可参考论坛。 + * ⚠ Tip:小程序的 path 要 encode 一次,如 pages%3fparam%3dtrue,小游戏的 path 为 JSON 字符串, + * 如{"param":true},否则会导致取不到。 + * + * 参数: + * code和anonymous_code二选一 必须 + * appname 可选,目标打开应用名称 默认douyin + * background 可选,背景色,rgb格式,英文逗号隔开,默认透明色 + * path 可选,小程序/小游戏启动参数,小程序则格式为 encode({path}?{query}),小游戏则格式为 JSON 字符串,默认为空 + * width 宽度 可选,二维码宽度,单位 px,最小 280px,最大 1280px,默认为 430px + * line_color 可选,二维码线条颜色,默认为黑色,rgb格式,英文逗号隔开,默认黑色 + * set_icon 可选,是否展示小程序/小游戏 icon,默认不展示,传yes展示,no不展示,默认no + * + * author:wh + */ + function createQRCode($path='',$appname='',$width='',$background='',$line_color='',$set_icon='no'){ + try { + $url = 'https://minigame.zijieapi.com/mgplatform/api/apps/qrcode'; + //$Scope = 'open.ttgame.mgplatform'; + $method = 'POST'; + + $json_arr = $this->realTimeGetAccessToken(); + if(empty($json_arr)){ + return Tools::set_fail('请重新授权'); + } + + $params = [ + 'access_token'=>$json_arr['data']['access_token'], + ]; + if($appname){ + $params['appname'] = $appname; + } + if($width){ + $params['width'] = $width; + } + //if($path){ + //小程序/小游戏启动参数,小程序则格式为 encode({path}?{query}),小游戏则格式为 JSON 字符串,默认为空 + $params['path'] = $path; + //} + //英文逗号隔开,r,g,b格式 + if($background){ + $background_rgb = explode(',',$background); + $params['r'] = $background_rgb[0]; + $params['g'] = $background_rgb[1]; + $params['b'] = $background_rgb[2]; + } + if($line_color){ + $line_color_rgb = explode(',',$line_color); + $params['r'] = $line_color_rgb[0]; + $params['g'] = $line_color_rgb[1]; + $params['b'] = $line_color_rgb[2]; + } + $params['set_icon'] = $set_icon=='yes'; + + $header = [ + 'Accept: application/json', + 'content-type: application/json' + ]; + + Tools::log_to_write_txt(['input'=>input(),'$params'=>$params]); + $res = Curl::curl_request($url,$method,json_encode($params),$header); + Tools::log_to_write_txt(['output'=>$res]); + + //流 + return $res; + }catch (\Exception $e){ + Tools::error_txt_log($e); + return Tools::set_fail(); + } + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/encrypt/TripleDES.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/encrypt/TripleDES.php new file mode 100644 index 0000000..664daa6 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/encrypt/TripleDES.php @@ -0,0 +1,88 @@ + strlen($text)) { + return false; + } + if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) { + return false; + } + return substr($text, 0, -1 * $pad); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/AuthError.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/AuthError.php new file mode 100644 index 0000000..1ad249e --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/errorcode/AuthError.php @@ -0,0 +1,20 @@ +ip = false===strpos($ip_port,'http')?'http://'.$ip_port:$ip_port; + $this->index_sign = $index_sign; + } + + /** + * desc:设置查询方法,默认_search + * author:wh + * @param $method_name + */ + function setQueryMethod($method_name){ + $this->query_method = $method_name; + } + + + /** + * desc:根据日期索引查询文档 + * 注:默认一个月 + * + * eg:'qa-stat-2021.01'; + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * author:wh + */ + function setIndexDefault(){ + $this->setRequestIndex(date('Y'.$this->doc_date_sign.'m')); + } + + /** + * desc:设置要查询的日期文档索引 + * + * 1、按年检索文档[建议5年左右] + * + * eg: qa-stat-2018.*,qa-stat-2019.*,qa-stat-2020.*,qa-stat-2021.* + * + * 注意:当索引过长,es会抛出索引太长异常 + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * + * author:wh + * @param string $start_time 开始时间 eg:2010-01-01 08:05:55 + * @param string $end_time 结束时间 eg:2021-12-31 12:05:00 + * @return string + */ + function setIndexYearDate(string $start_time, string $end_time){ + + //默认查询索引 + $index = date('Y'.$this->doc_date_sign.'*', strtotime($start_time)); + + $sign = ',';//分隔符 + + $m = date('Y', strtotime($end_time)) - date('Y', strtotime($start_time)); + + //拼装查询索引 + for ($i=0; $i<$m; $i++){ + + $index .= $sign.($this->index_sign.(date('Y', strtotime($start_time))+$i).$this->doc_date_sign.'*'); + } + + $this->setRequestIndex($index); + } + + /** + * desc:设置日期索引 + * + * 检索全部日期索引文档 + * + * 例如es设置的索引为: + * qa-stat-2021.01 + qa-stat-2021.02 + qa-stat-2021.03 + qa-stat-2021.04 + * + * 实际查询自动设置为:qa-stat-* + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * + * author:wh + * @return string + */ + function setIndexAllDate(){ + + $this->setRequestIndex('*'); + } + + /** + * desc:设置普通索引 + * + * 调用此方法,请在初始化时,设置索引前缀index_sign为""空字符串 + * + * author:wh + * @param string $index + */ + function setIndexNormal(string $index){ + $this->setRequestIndex($index); + } + + /** + * desc:设置跨月份索引 + * + * eg: qa-stat-2021.01,qa-stat-2021.02 + * + * 注:如果es设置的索引没有规律也不是日期作为索引,请设置普通索引setIndexNormal,且请在初始化时,设置索引前缀index_sign为""字符串 + * + * author:wh + * @param string $start_time eg:'2020-11' + * @param string $end_time eg:'2021-01' + * @return string eg: qa-stat-2020.11,qa-stat-2020.12,qa-stat-2021.01 + */ + function setIndexDate(string $start_time, string $end_time){ + $date = new Date(); + + //计算月份 + $m = $date->dateCutMonth($start_time, $end_time); + ////解决跨年且不足1个月时,索引设置错误问题 + //if($m == 0 && (date('Y', strtotime($end_time)) > date('Y', strtotime($start_time)))){ + // $m = 1; + //} + //格式 + $date->date_format = 'Y-m'; + + //默认查询索引 + $index = date('Y'.$this->doc_date_sign.'m', strtotime($start_time)); + + $tmp_time = $start_time; + $sign = ',';//分隔符 + + //拼装查询索引 + for ($i=0; $i<$m; $i++){ + $tmp_time = $date->addTime(1, 'M', strtotime($tmp_time)); + $index .= $sign.$this->index_sign.(date('Y'.$this->doc_date_sign.'m', strtotime($tmp_time))); + } + + $this->setRequestIndex($index); + } + + + /** + * desc:设置查询参数 + * author:wh + * @param string $query_param_json + */ + function setQueryParam(string $query_param_json){ + $this->query_param = $query_param_json; + $this->post_url = $this->ip.'/'.$this->index.'/'.$this->query_method; + } + + /** + * desc:获取查询参数,用于调试 + * author:wh + * @return array + */ + function getQueryParam(){ + return [ + 'ip'=>$this->ip, + 'index_sign'=>$this->index_sign, + 'index'=>$this->index, + 'query_method'=>$this->query_method, + 'post_url'=>$this->post_url, + 'query_param'=>$this->query_param, + ]; + } + + /** + * desc:执行es查询 + * author:wh + * @return array|bool|int|string + * @throws \Exception + */ + function execute(){ + if(empty($this->ip)) throw new \Exception('请设置ip'); + //if(empty($this->index_sign)) throw new \Exception('请设置索引前缀'); + if(empty($this->index)) throw new \Exception('请设置索引'); + if(empty($this->query_method)) throw new \Exception('请设置查询方法'); + if(empty($this->query_param)) throw new \Exception('请设置查询参数'); + + + + + Tools::log_to_write_txt(['exe_func'=>$this->exe_func,'request_url'=>$this->post_url,'IN'=>" | IN: ",'query_params'=>$this->query_param, 'input'=>input()], $this->es_log_file); + $result = Tools::curl_post($this->post_url, $this->query_param); + Tools::log_to_write_txt(['exe_func'=>$this->exe_func,'OUT'=>" | OUT: ", 'result'=>$result], $this->es_log_file); + + return $result; + } + + /** + * desc:设置是哪个方法调用本es库,用于日志记录 + * author:wh + * @param string $function + */ + function setExecuteFunction(string $function){ + $this->exe_func = $function; + } + + /** + * desc:设置请求文档索引 + * author:wh + * @param string $index + */ + protected function setRequestIndex(string $index){ + $this->index = $this->index_sign.$index; + } + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/es/README.md b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/es/README.md new file mode 100644 index 0000000..ea56d61 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/es/README.md @@ -0,0 +1,1340 @@ +##### Elasticsearch数据库操作类库使用教程 + +#### 一、Elasticsearch原生cUrl查询库 +##### 说明:该库只提供查询请求,开发者只需要关注查询参数怎么写,请求之后会把结果按原样返回,不会有任何修改。 + +**** + +###### 【查询参数案例:查询一条数据】 +###### 只需要简单的查询条件即可;from=0,size=1表示从第0条数据查询1条,from可省略,等于mysql的limit 1。 +###### 这里unixtime和statFunc为数据结构(表)中的字段名称,gt大于,lt小于,gte大于等于,lte小于等于 +###### 这里register是字段statFunc的值,而unixtime存的是毫秒时间戳 +###### 注:数据字段尽量不存小数,小数太小的时候,在内存中计算时会出现误差,比如0.001+0.001=0 + +#### 代码使用示例: +``` + +//======【有规律的日期索引】【特殊】======= +$query_params = "{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1623254400000, + "lt": 2623340800000 + } + } + }, + { + "terms": { + "statFunc": [ + "signup", + "returncard" + ] + } + }, + { + "term": { + "matchTypeNum": 3 + } + } + ] + } + }, + "size": 1, + "aggs": { + "group_by_day": { + "date_histogram": { + "field": "@timestamp", + "interval": "day", + "min_doc_count": 0, + "order": { + "_key": "asc" + }, + "time_zone": "+08:00", + "format": "yyyy-MM-dd" + }, + "aggs": { + "item1000_sum": { + "sum": { + "field": "item1000" + } + } + } + } + } + }"; +$es = new Elasticsearch('http://49.4.3.4:3201','qa-item-'); +$es->setIndexAllDate(); +$es->setQueryParam($query_params); +dump($es->execute()); + +dump('=================================================================='); + +//======【无规律的普通索引】【推荐】======= +$query_params = "{ + 'query': { + 'bool': { + 'must': [ + { + 'range': { + 'unixtime': { + 'gt': 1617206400000, + 'lt': 1619712000000 + } + } + }, + { + 'term': { + 'statFunc': 'register' + } + } + ] + } + }, + 'size': 1 + }"; +dump($query_params); +$es = new Elasticsearch('http://49.4.3.4:3201',''); +$es->setIndexNormal('qa-item-2021.06.*'); +$es->setQueryParam($query_params); +dump($es->execute()); + + +//以上都经过测试 + +``` + +#### 查询参数示例 +###### 示例1: 这里展示了must查询 +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "statFunc": "register" + } + } + ] + } + }, + "size": 1 +} +``` +###### 示例2: 这里展示了混合查询 +###### must表示必须,等于mysql的and; +###### should表示应该,等于mysql的or; +###### 模糊查询用missing,等于mysql的like,但是不用%%通配符; +###### must_not表示必须不是,等于mysql的!=; +###### 它们可以一起使用。 +###### 仔细观察发现,query,bool基本是固定的,而里面的参数写法都差不多。 + +``` +{ + "query": { + "bool": { + "must": [ + { + "match": { + "statFunc": "signup" + } + } + ], + "must_not": [], + "should": [ + { + "term": { + "gameTagNum": "210" + } + }, + { + "term": { + "gameTagNum": "300" + } + } + ] + } + }, + "size": 1 +} +``` + +**** + +###### 【查询参数案例:查询多条数据】 +###### 只需要简单的查询条件即可,这里只改变了size字段值。 +###### eg: +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "statFunc": "register" + } + } + ] + } + }, + "size": 10 +} +``` + +**** + +###### 【查询参数案例:简单聚合】 +###### 根据时间和某个字段查询数据,并且基于查询结果再次按时间分组,分组段按天分段,同时基于查询结果再次聚合某个字段 +###### 为了便于演示,这里查询条件改为容易理解的字段:"统计张三一段时间内已下单的订单总金额" +###### order_money_sum是自定义名称,等于mysql的别名 +###### eg: +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "order_time": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "name": "张三" + } + } + ] + } + }, + "size": 0, + "aggs": { + "order_money_sum": { + "sum": { + "field": "order_money" + } + } + } +} +``` + +###### 【查询参数案例:复杂聚合】 +###### aggs可以嵌套,嵌套时的含义表示基于上一个聚合结果再次聚合 +###### 这里表示先按day(天)分组,再统计字段名为item1000的字段,day可以改为月(month)年(year) +###### eg: +``` +{ + "query": { + "bool": { + "must": [ + { + "range": { + "unixtime": { + "gt": 1617206400000, + "lt": 1619712000000 + } + } + }, + { + "term": { + "statFunc": "register" + } + } + ] + } + }, + "size": 0, + "aggs": { + "group_by_day": { + "date_histogram": { + "field": "@timestamp", + "interval": "day", + "min_doc_count": 0, + "order": { + "_key": "desc" + }, + "time_zone": "+08:00", + "format": "yyyy-MM-dd" + }, + "aggs": { + "item1000_sum": { + "sum": { + "field": "item1000" + } + } + } + } + } +} +``` + + +**** + +#### 二、Elasticsearch助手库(不推荐,因为不灵活。掌握了一的查询参数,其它都是小问题) + +##### 说明: + +##### 通用es查询多条数据 +* (这一种方式可实现大部分列表查询功能) +* (where条件跟随业务需要修改) +* (多条件组合查询满足不同查询业务) + +#### 查询列表: +``` + //获取分页数据 + $offset = input('offset', 5); + $limit = input('limit', 5); + + + //获取数据 + $input_data = $_POST; + 初始化es + $es = new BaseElasticsearch(); + + + //(必须)判断时间查询设置索引 + if(!empty($input_data['sign_time'])){ + $start_time = explode(' - ', $input_data['sign_time'])[0]; + $end_time = explode(' - ', $input_data['sign_time'])[1]; + //这里动态生成索引 + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + //设置默认索引 + $es->index = $es->setDefaultDate();//默认一个月 + } + + + //设置查询的文档类型 + $es->type = 'logs';//本例是查询日志类型的数据 + + //分页计算得到当前页码(可根据自身情况设置) + $es->current_page = $offset/$limit; + $es->limit = $limit; + + + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'draw' + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['sign_time'])){ + //这里将字符串日期转换为unix时间戳(精确到毫秒) + $date_arr = $es->strtounixtime($input_data['sign_time']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //排序 + $es->order('unixtime', 'desc'); + + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must、must_not、should方法必须在一起使用] + $es->must($where); + + + //执行查询 + $res = $es->query(); + dump($res); + +``` + +#### 查询一条数据(完全可以用查询列表功能,组合多条件筛选出一条数据): + +``` + //根据id查询一条数据 + //初始化es + $es = new BaseElasticsearch(); + + $es->index_sign = 'qa-item-';//设置index标识 + + $es->index = $es->setDefaultDate();//设置文档索引 + + $es->type = 'logs';//设置文档类型 + $res = $es->getById('AXbaw_CGbqvMMYZl-lOz'); + dump($res); +``` + + +#### 查询案例 + +``` +index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + $es->type = 'logs'; + $es->current_page = $limit ? intval($offset / $limit) + 1 : 1; + $es->limit = $limit; + //关键步骤 + //设置查询条件 + + //帐变类型:4=后台赠送,6首充奖励,7=报名,8=充值 + $change_type_arr = ['backsend'=>4,'firstprize'=>6,'signup'=>7,'recharge'=>8]; + //必须 + $where = [ + [ + 'range' => [ + $amount_field => ['gt' => -999999] + ] + ] + ]; + + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //帐变类型 + if(!empty($input_data['change_type'])){ + $where[] = [ + 'term' => [ + 'statType' => array_flip($change_type_arr)[$input_data['change_type']] + ] + ]; + } + //帐变时间 + if(!empty($input_data['change_time'])){ + $date_arr = $es->strtounixtime($input_data['change_time']); + + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + //排序 + $es->order('unixtime', 'desc'); + + //昵称查询要先查uid 再去es查昵称 + + //$es->queryRange('unixtime', [ + // 'gt' => 1609750662180, + // 'lt' => 1609750662184 + //]); + //$es->queryFieldExist($amount_field); + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + + //执行查询 + Tools::log_to_write_txt(['执行查询,入参:',$es->params], 'es_player_ticket_change_record'); + $res = $es->query(); + Tools::log_to_write_txt(['执行查询,出参:',$res], 'es_player_ticket_change_record'); + + //删除本地临时数据 + Db::execute('truncate table fa_zc_player_ticket_change_record'); + + if(empty($res['hits']['hits'])) return set_result(500, '未查询到相关数据.'); + + $lists = $res['hits']['hits']; + $this->total = $res['hits']['total']; + + //组装入库字段 + $items = []; + foreach ($lists as $list){ + $item = []; + $item['gameid'] = empty($list['_source']['uid'])?'':$list['_source']['uid']; + $item['nickname'] = empty($list['_source']['nickname'])?'':$list['_source']['nickname']; + $item['change_type'] = empty($change_type_arr[$list['_source']['statType']])?'0':$change_type_arr[$list['_source']['statType']].''; + + $item['amount'] = empty($list['_source'][$amount_field])?0:$list['_source'][$amount_field];//帐变额 + + $after_amount = empty($list['_source'][$after_amount_field])?0:$list['_source'][$after_amount_field]; + $item['after_amount'] = $after_amount; + $item['before_amount'] = $item['after_amount']-$item['amount'];//帐变前=帐变后-帐变额 + $item['change_time'] = floor($list['_source']['unixtime']/1000); + $item['api_key'] = $list['_id']; + $items[] = $item; + } + + //记录入库数据 + Tools::log_to_write_txt('记录入库数据 | '.json_encode($items, JSON_UNESCAPED_UNICODE), 'es_player_ticket_change_record'); + + //入库 + Db::table('fa_zc_player_ticket_change_record')->insertAll($items); + return set_result(200, 'ok'); + }catch (Exception $exception){ + Tools::log_to_write_txt('未查询到相关数据. error: '.$exception->getMessage().' | '.$exception->getTraceAsString(), 'es_player_ticket_change_record'); + return set_result(500, '未查询到相关数据.'.$exception->getMessage()); + } + } + + //现金 + function money(){ + try{ + //帐变前数额字段 + $amount_field = 'item1002';//现金帐变 只能是字符 + //帐变后数额字段 + $after_amount_field = 'package1002';//现金帐变 只能是字符 + + $input_data = json_decode(input('filter'), true); + $offset = input('offset', 5); + $limit = input('limit', 5); + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['change_time'])){ + $start_time = explode(' - ', $input_data['change_time'])[0]; + $end_time = explode(' - ', $input_data['change_time'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + $es->type = 'logs'; + $es->current_page = $limit ? intval($offset / $limit) + 1 : 1; + $es->limit = $limit; + //关键步骤 + //设置查询条件 + //帐变类型:3=比赛奖励,4=后台赠送 99暂定提现 + $change_type_arr = [ + //账变来源大分类 (draw:抽奖,exchange:兑换,winprize:比赛奖励,backsend:后台赠送,sign:签到,firstprize:首充奖励,signup:报名,recharge:充值,useprop:使用道具,cashout:提现,regsend:注册赠送) + 'winprize'=>3, + 'backsend'=>4, + 'cashout'=>99 + ]; + //必须 + $where = [ + [ + 'range' => [ + $amount_field => ['gt' => -999999] + ] + ], + ]; + + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //帐变类型 + if(!empty($input_data['change_type'])){ + $where[] = [ + 'term' => [ + 'statType' => array_flip($change_type_arr)[$input_data['change_type']] + ] + ]; + } + //帐变时间 + if(!empty($input_data['change_time'])){ + $date_arr = $es->strtounixtime($input_data['change_time']); + + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + //排序 + $es->order('unixtime', 'desc'); + + //$es->queryRange('unixtime', [ + // 'gt' => 1609750662180, + // 'lt' => 1609750662184 + //]); + //$es->queryFieldExist($amount_field); + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + + //执行查询 + Tools::log_to_write_txt(['执行查询,入参:',$es->params], 'es_player_cash_change_record'); + $res = $es->query(); + Tools::log_to_write_txt(['执行查询,出参:',$res], 'es_player_cash_change_record'); + + //删除本地临时数据 + Db::execute('truncate table fa_zc_player_cash_change_record'); + + if(empty($res['hits']['hits'])) return set_result(500, '未查询到相关数据.'); + + $lists = $res['hits']['hits']; + $this->total = $res['hits']['total']; + //组装入库字段 + $items = []; + foreach ($lists as $list){ + $item = []; + $item['gameid'] = empty($list['_source']['uid'])?'':$list['_source']['uid']; + $item['nickname'] = empty($list['_source']['nickname'])?'':$list['_source']['nickname']; + $item['change_type'] = empty($change_type_arr[$list['_source']['statType']])?'0':$change_type_arr[$list['_source']['statType']].''; + + $item['amount'] = empty($list['_source'][$amount_field])?'0':$list['_source'][$amount_field].'';//帐变额 + + $after_amount = empty($list['_source'][$after_amount_field])?0:$list['_source'][$after_amount_field]; + $item['after_amount'] = $after_amount; + $item['before_amount'] = $item['after_amount']-$item['amount'];//帐变前=帐变后-帐变额 + $item['change_time'] = floor($list['_source']['unixtime']/1000); + $item['api_key'] = $list['_id']; + $items[] = $item; + } + //记录入库数据 + Tools::log_to_write_txt('记录入库数据 | '.json_encode($items, JSON_UNESCAPED_UNICODE), 'es_player_cash_change_record'); + + //入库 + Db::table('fa_zc_player_cash_change_record')->insertAll($items); + return set_result(200, 'ok'); + }catch (Exception $exception){ + Tools::log_to_write_txt('未查询到相关数据. error: '.$exception->getMessage().' | '.$exception->getTraceAsString(), 'es_player_cash_change_record'); + return set_result(500, '未查询到相关数据.'.$exception->getMessage()); + } + } + + //礼券 + function gift(){ + try{ + //帐变前数额字段 + $amount_field = 'item1001';//只能是字符 + //帐变后数额字段 + $after_amount_field = 'package1001';//只能是字符 + + $input_data = json_decode(input('filter'), true); + $offset = input('offset', 5); + + $limit = input('limit', 5); + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['change_time'])){ + $start_time = explode(' - ', $input_data['change_time'])[0]; + $end_time = explode(' - ', $input_data['change_time'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + $es->type = 'logs'; + $es->current_page = $limit ? intval($offset / $limit) + 1 : 1; + $es->limit = $limit; + //关键步骤 + //设置查询条件 + //帐变类型:1=抽奖,2=兑换,3=比赛奖励,4=后台赠送,5=签到 + $change_type_arr = ['draw'=>1,'exchange'=>2,'winprize'=>3,'backsend'=>4,'sign'=>5]; + //必须 + $where = [ + [ + 'range' => [ + $amount_field => ['gt' => -999999] + ] + ], + ]; + + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //帐变类型 + if(!empty($input_data['change_type'])){ + $where[] = [ + 'term' => [ + 'statType' => array_flip($change_type_arr)[$input_data['change_type']] + ] + ]; + } + //帐变时间 + if(!empty($input_data['change_time'])){ + $date_arr = $es->strtounixtime($input_data['change_time']); + + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + //排序 + $es->order('unixtime', 'desc'); + + //$es->queryRange('unixtime', [ + // 'gt' => 1609750662180, + // 'lt' => 1609750662184 + //]); + //$es->queryFieldExist($amount_field); + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + + //执行查询 + Tools::log_to_write_txt(['执行查询,入参:'], 'es_player_gift_change_record'); + $res = $es->query(); + + Tools::log_to_write_txt(['执行查询,出参:', $es->params, $res], 'es_player_gift_change_record'); + + //删除本地临时数据 + Db::execute('truncate table fa_zc_player_gift_change_record'); + + if(empty($res['hits']['hits'])) return set_result(500, '未查询到相关数据.'); + + $lists = $res['hits']['hits']; + + $this->total = $res['hits']['total']; + //组装入库字段 + $items = []; + foreach ($lists as $list){ + $item = []; + $item['gameid'] = empty($list['_source']['uid'])?'':$list['_source']['uid']; + $item['nickname'] = empty($list['_source']['nickname'])?'':$list['_source']['nickname']; + $item['change_type'] = empty($change_type_arr[$list['_source']['statType']])?'0':$change_type_arr[$list['_source']['statType']].''; + + $item['amount'] = empty($list['_source'][$amount_field])?'0':$list['_source'][$amount_field].'';//帐变额 + + $after_amount = empty($list['_source'][$after_amount_field])?0:$list['_source'][$after_amount_field]; + $item['after_amount'] = $after_amount; + $item['before_amount'] = $item['after_amount']-$item['amount'];//帐变前=帐变后-帐变额 + $item['change_time'] = floor($list['_source']['unixtime']/1000); + $item['api_key'] = $list['_id']; + $items[] = $item; + } + //记录入库数据 + Tools::log_to_write_txt(['记录入库数据',$items], 'es_player_gift_change_record'); + + //入库 + Db::table('fa_zc_player_gift_change_record')->insertAll($items); + return set_result(200, 'ok', $res); + }catch (Exception $exception){ + Tools::log_to_write_txt('未查询到相关数据. error: '.$exception->getMessage().' | '.$exception->getTraceAsString(), 'es_player_gift_change_record'); + return set_result(500, '未查询到相关数据.'.$exception->getMessage()); + } + + } + +} +``` + +#### 聚合案例 + +##### sum求和 +``` +index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + if(!empty($input_data['order_status'])){ + $where[] = [ + 'term' => [ + 'status' => $input_data['order_status'] + ] + ]; + } + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + + + /** + * desc:查询本月总充值 + * author:wh + * @return array|\think\response\Json + */ + function month(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['order_itme'])){ + $start_time = explode(' - ', $input_data['order_itme'])[0]; + $end_time = explode(' - ', $input_data['order_itme'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'unixtime' => [ + 'gt' => strtotime(date('Y-m').'-01').'000', + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //订单状态(es的充值记录都是充值成功的数据) + //if(!empty($input_data['order_status'])){ + // $where[] = [ + // 'term' => [ + // 'status' => $input_data['order_status'] + // ] + // ]; + //} + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + /** + * desc:查询本周总充值 + * author:wh + * @return array|\think\response\Json + */ + function week(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['order_itme'])){ + $start_time = explode(' - ', $input_data['order_itme'])[0]; + $end_time = explode(' - ', $input_data['order_itme'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ], + [ + 'range' => [ + //本周 + 'unixtime' => [ + 'gte' => strtotime((new Date())->beginWeek()).'000', + 'lte' => strtotime((new Date())->endWeek()).'000', + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //订单状态(es的充值记录都是充值成功的数据) + //if(!empty($input_data['order_status'])){ + // $where[] = [ + // 'term' => [ + // 'status' => $input_data['order_status'] + // ] + // ]; + //} + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + /** + * desc:查询今日总充值 + * author:wh + * @return array|\think\response\Json + */ + function today(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['order_itme'])){ + $start_time = explode(' - ', $input_data['order_itme'])[0]; + $end_time = explode(' - ', $input_data['order_itme'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + $es->index = $es->setDefaultDate();//默认一个月 + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 99999999; + //关键步骤 + //设置查询条件 + $where = [ + [ + 'term' => [ + 'statType' => 'recharge'//充值类型 + ] + ], + [ + 'range' => [ + //参赛券 + 'item1000' => [ + 'gte' => 0,//不可能是负数 + ] + ] + ], + [ + 'range' => [ + //参赛券 + 'item1002' => [ + 'lt' => 0,//item1002(奖励金)<0 + ] + ] + ], + [ + 'range' => [ + //今日 + 'unixtime' => [ + 'gt' => strtotime(date('Y-m-d')).'000', + ] + ] + ] + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //时间 + if(!empty($input_data['order_itme'])){ + $date_arr = $es->strtounixtime($input_data['order_itme']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + //订单状态(es的充值记录都是充值成功的数据) + //if(!empty($input_data['order_status'])){ + // $where[] = [ + // 'term' => [ + // 'status' => $input_data['order_status'] + // ] + // ]; + //} + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->setAggs('item1000', 0); + //执行查询 + $res = $es->sum(); + + + return $res['aggregations']['sum']['value']; + } + + + + + +} +``` + +#### 或查询(相当于mysql or查询) +``` +/** + * desc:或查询(相当于mysql or查询) + * author:wh + * @return array|\think\response\Json + */ + function total(){ + + $input_data = json_decode(input('filter'), true); + + $es = new BaseElasticsearch(); + //判断时间查询,动态生成索引 + if(!empty($input_data['conversion_time'])){ + $start_time = explode(' - ', $input_data['conversion_time'])[0]; + $end_time = explode(' - ', $input_data['conversion_time'])[1]; + $es->index = $es->setIndexDate($start_time, $end_time); + }else{ + //$es->index = $es->setDefaultDate();//默认一个月 + //默认查询所有历史记录 + $es->index = $es->setIndexAllDate(); + } + + $es->type = 'logs'; + $es->current_page = 1; + $es->limit = 999999999; + //关键步骤 + //设置查询条件 + // + $where = [ + [ + 'term' => [ + 'statType' => 'exchange'//兑换类型 + ] + ], + + ]; + //可选 + if(!empty($input_data['gameid'])){ + $where[] = [ + 'term' => [ + 'uid' => $input_data['gameid'] + ] + ]; + } + //昵称 + if(!empty($input_data['nickname'])){ + $where[] = [ + 'term' => [ + 'nickname' => $input_data['nickname'] + ] + ]; + } + //时间 + if(!empty($input_data['conversion_time'])){ + $date_arr = $es->strtounixtime($input_data['conversion_time']); + $where[] = [ + 'range' => [ + 'unixtime' => [ + 'gte' => $date_arr['start_time'], + 'lte' => $date_arr['end_time'], + ] + ] + ]; + } + + $should_where = [ + [ + "range"=> [ + "item2001"=> [ + "gte"=> -9999999 + ] + ] + ], + [ + "range"=> [ + "item2002"=> [ + "gte"=> -9999999 + ] + ] + ], + [ + "range"=> [ + "item2005"=> [ + "gte"=> -9999999 + ] + ] + ], + [ + "range"=> [ + "item2010"=> [ + "gte"=> -9999999 + ] + ] + ] + ]; + + + //排序 + //$es->order('unixtime', 'desc'); + //设置bool查询模式 + $es->setQueryBool(); + //必须[setQueryBool & must,must_not, should必须在一起使用] + $es->must($where); + $es->should($should_where); + $es->setAggs('item1001', 1); + //执行查询 + $res = $es->sum(); + + return $res['aggregations']['sum']['value']; + } +``` \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/BaseException.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/BaseException.php new file mode 100644 index 0000000..6d73165 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/BaseException.php @@ -0,0 +1,16 @@ +200, 'msg'=>'操作成功', 'data'=>[]] + if(is_null($result['code'])){ + //无code字段,抛出响应格式错误 + throw new ResponseException(ResponseException::RESPONSE_FORMAT_ERROR); + } \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/SystemException.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/SystemException.php new file mode 100644 index 0000000..0681132 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/SystemException.php @@ -0,0 +1,60 @@ +getError(), 422); + //} + + // 请求异常 + //if ($e instanceof HttpException && request()->isAjax()) { + // return response($e->getMessage(), $e->getStatusCode()); + //} + + Tools::log_to_write_txt([ + 'error'=>'系统错误.'.$e->getMessage(), + 'input'=>Request::instance()->input(), + 'error_info'=>$e->getTraceAsString() + ]); + + $title = '新的【系统异常】,请立即处理'; + //邮件通知管理员 + $mail_content = '

error:'.$e->getMessage().'

'; + $mail_content .= '

url:'.request()->url(true).'

'; + $mail_content .= '

ip:'.request()->ip().'

'; + $mail_content .= '

详情请登录宝塔查看日志

'; + + $emails = SundryConfig::val('admin_error_log_email'); + if(config('sys_env') == 'PROD'){//线上环境才发错误邮件 + EmailTool::email_to_person($title,$mail_content,$emails); + } + + if(request()->LogObj){ + request()->LogObj->flush(); + } + if(request()->ServeLogObj){ + request()->ServeLogObj->flush(); + } + + //可以在此交由系统处理 + return parent::render($e); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/api/ApiException.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/api/ApiException.php new file mode 100644 index 0000000..f2b795c --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/exception/api/ApiException.php @@ -0,0 +1,21 @@ +where('name',$menu_name)->data(['status'=>'normal'])->update(); + }else{ + Db::table('fa_auth_rule')->where('name',$menu_name)->data(['status'=>'hidden'])->update(); + } + } + return true; + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/File.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/File.php new file mode 100644 index 0000000..3e45098 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/File.php @@ -0,0 +1,236 @@ + array(1) { + // ["path"] => string(25) "D:\wanghua\test_files/111" + // } + // [1] => array(1) { + // ["path"] => string(25) "D:\wanghua\test_files/222" + // } + //} + * + * + * + * + * @param $file_name_arr 存储文件路径、文件名称 + * + //array(64) { + // [0] => array(3) { + // ["path"] => string(25) "D:\wanghua\test_files/111" + // ["path_file"] => string(33) "D:\wanghua\test_files/111/111.txt" + // ["filename"] => string(7) "111.txt" + // } + // [1] => array(3) { + // ["path"] => string(25) "D:\wanghua\test_files/111" + // ["path_file"] => string(37) "D:\wanghua\test_files/111/1111111.txt" + // ["filename"] => string(11) "1111111.txt" + // } + //} + */ + function read_folder($folderPath,&$dirs,&$file_name_arr) { + // 获取指定目录下所有文件和文件夹 + $files = scandir($folderPath); + foreach ($files as $file) { + // 如果当前项为文件夹且不是"."或者".." + if (is_dir("$folderPath/$file") && !in_array($file, array('.', '..'))) { + $dirs[] = ['path'=>$folderPath.'/'.$file];//此时的$file是文件夹名称 + // 调用自身进行递归操作 + $this->read_folder("$folderPath/$file",$dirs,$file_name_arr); + } elseif (!in_array($file, array('.', '..'))){ // 如果当前项为文件而非"."或者".." + $file_name_arr[] = ['path'=>$folderPath,'path_file'=>"$folderPath/$file",'filename'=>$file]; + } + } + } + + /** + * desc:复制文件 + * + * author:wh + * @param array $sourceFileArr 源文件路径数组 path,path_file,filename + * + * @param string $destination_path 目标存放路径 D:\wanghua\test_files\new_files + * + * @param array $cp_type_arr 允许复制的文件后缀 eg:['jpg','png,'spine'] + * + * @param bool $is_cover 是否覆盖 默认false,不覆盖会以源文件名+微秒时间戳格式作为新的文件名 + * + * @param bool $is_continue 相同文件是否跳过复制 默认 true + * + * 实战案例: + * + function testcopy(){ + $source_dir = 'D:\wanghua\test_files';//源文件路径 + $destination_path = 'D:\wanghua\test_files\new_files';//目标文件路径 + + $dirs = [];//存储文件路径 + $file_name_arr = [];//含文件路径、名称 + $file_obj = new File(); + $file_obj->read_folder($source_dir,$dirs,$file_name_arr); + //dump($dirs); + //dump($file_name_arr);die; + $file_obj->copy($file_name_arr,$destination_path,['jpg','png,'spine']); + } + * + */ + function copy(array $sourceFileArr, string $destination_path, $cp_type_arr=['jpg','png'], $is_cover=false, $is_continue=false){ + //设置不超时 + set_time_limit(0); + //源文件路径 => 目标文件路径 + foreach ($sourceFileArr as $key=>$file_arr){ + if(!file_exists($file_arr['path_file'])){ + continue; + } + //验证目标文件夹路径 + if(!file_exists($destination_path)){ + mkdir($destination_path,0777,true); + } + $name_arr = explode('.',$file_arr['filename']); + //验证符合条件的文件类型 + if(!in_array($name_arr[1],$cp_type_arr)){ + continue; + } + if(file_exists($destination_path.'/'.$file_arr['filename'])){ + if($is_continue){ + continue;//相同文件跳过复制 + } + //覆盖 + if($is_cover){ + copy($file_arr['path_file'], $destination_path.'/'.$file_arr['filename']); + }else{ + //不覆盖,名称区分 + $microsecond = Tools::getMicrosecond(); + copy($file_arr['path_file'], $destination_path.'/'.$name_arr[0].'('.$microsecond.').'.$name_arr[1]); + } + }else{ + copy($file_arr['path_file'], $destination_path.'/'.$file_arr['filename']); + } + } + } + + /** + * desc:递归删除目录 + * + * $dir 物理路径 + * + * author:wh + */ + function recursive_delete($dir) { + if (!is_dir($dir)) { + return unlink($dir); + } + + $handle = opendir($dir); + while (($file = readdir($handle)) !== false) { + if ($file === '.' || $file === '..') { + continue; + } + $path = $dir . DIRECTORY_SEPARATOR . $file; + if (is_dir($path)) { + $this->recursive_delete($path); + } else { + unlink($path); + } + } + closedir($handle); + rmdir($dir); + } + + + /** + * desc:解压ZIP文件并存储在本地 + * author:wh + * @param resource $file_stream 文件流 + * 例如:$response = $client->request('POST', $url, [ + 'headers' => $headers, + 'body' => $body, + ]); + // 处理响应 + //$file_stream = $response->getBody(); + * @param string $save_path 存储路径 + * @return array + * @throws \Exception + */ + function unzip($file_stream,$save_path){ + $zpi_file_name = 'zip_tmp_file_'.Tools::rand_str(20).'.zip'; + //这个目录将会在结束时删除 + $zipTempPath = $save_path.'/tmp_zip_files/'; // 临时存放ZIP文件的路径 + //压缩文件保存目录 + if(!file_exists($zipTempPath)){ + mkdir($zipTempPath,0777,true); + } + $zpi_file = $zipTempPath.$zpi_file_name; + // 保存ZIP文件到临时路径 + file_put_contents($zpi_file, $file_stream); + + $this->unzip_path = $zipTempPath.'unzip_files/'; + //解压目录 + if(!file_exists( $this->unzip_path)){ + mkdir( $this->unzip_path,0777,true); + } + // 解压ZIP文件 + $zip = new \ZipArchive(); + if ($zip->open($zpi_file) === TRUE) { + $zip->extractTo( $this->unzip_path);//移动到临时解压目录 + $zip->close(); + //遍历所有文件(file_ext后缀自行指定),遍历部分文件,如:*.json,*.zip,*.mp4,*.mp3等 + $wavFiles = $this->glob_by_ext( $this->unzip_path.$this->file_ext); + + //$urls = []; + //// 遍历解压后的文件,生成URL + //foreach ($wavFiles as $wavFilePath) { + // // 生成外部访问的URL + // $downloadUrl = request()->domain() . explode('public',$wavFilePath)[1]; + // $urls[] = $downloadUrl; + //} + //// 返回所有WAV文件的URL + //return ['wav_urls' => $urls]; + return $wavFiles; + } else { + throw new \Exception('Failed to open ZIP file.'); + } + } + + /** + * desc:获取指定扩展类型的文件列表 + * + * author:wh + * @param string $file_ext 如: wav,pm4,mp3,json,zip + * @return array|false + */ + function glob_by_ext($file_ext='*'){ + return glob( $this->unzip_path.'*.'.$file_ext); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/README.MD b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/README.MD new file mode 100644 index 0000000..8459022 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/README.MD @@ -0,0 +1,5 @@ +## 文件处理 + +#### 文件夹读取,文件复制 + +#### 文件上传 \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/FileUpload.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/FileUpload.php new file mode 100644 index 0000000..228e91e --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/FileUpload.php @@ -0,0 +1,764 @@ +file_dir = $file_dir; + } + /** + * desc:单图 + * + * 【!!!必须确认php.ini中upload_max_filesize的配置足够大,否则上传失败但不会报错!!!】 + * + * author:wh + * @param string $file_upload_name 表单文件元素name值 + * @param int $size 大小,默认2M + * @param string $ext 允许的扩展 + * @return array + */ + function image($file_upload_name = 'file_upload', $size=10, $ext=''){ + if(!$this->uploadMaxFilesizeCheck($size)){ + return Tools::set_res(1, '上传文件受限'); + } + // 获取表单上传文件 例如上传了001.jpg + $file = request()->file($file_upload_name); + if(empty($file)){ + return Tools::set_fail('请上传文件'); + } + // 移动到框架应用根目录/uploads/ 目录下 + $outer_req_url = $this->file_dir.'/image'; + $physics_path = 'public'.$outer_req_url; + $root_path = explode('vendor',__DIR__)[0]; + $upload_dir = $root_path.$physics_path; + if(!is_dir($upload_dir)){ + mkdir($upload_dir, 0777, true); + } + if(empty($file)){ + return Tools::set_res(1, '上传文件不存在'); + } + + if(empty($ext)) $ext = $this->img_ext; + + $info = $file->validate(['size'=>$size * 1024 * 1024, 'ext'=>$ext])->move($upload_dir); + if($info){ + //原文件名 + $source_file_name = $info->getInfo('name'); + + //文件类型 + $file_type = $info->getInfo('type'); + + // 输出扩展名 jpg + $extension = $info->getExtension(); + + // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg + $save_name = $info->getSaveName(); + + // 输出 42a79759f284b767dfcb2a0197904287.jpg + $new_filename = $info->getFilename(); + + $relative_url = $outer_req_url.'/'.str_replace('\\', '/', $save_name); + $result = [ + 'prefix'=>request()->domain().$outer_req_url,//访问前缀 + 'source_file_name'=>$source_file_name, + 'file_type'=>$file_type, + 'extension'=>$extension, + 'save_name'=>str_replace('\\', '/', $save_name), + 'new_filename'=>$new_filename, + 'real_path'=>$this->dealPath($root_path.'public'.$relative_url),//物理路径 + 'outer_req_url'=>request()->domain().$relative_url, + 'outer_req_relative_url'=>$relative_url, + 'size'=>$info->getSize(), + ]; + return Tools::set_res(0, '上传成功', $result); + }else{ + // 上传失败获取错误信息 + return Tools::set_res(1, $file->getError()); + } + } + + /** + * desc:多图 + * + * 【!!!必须确认php.ini中upload_max_filesize的配置足够大,否则上传失败但不会报错!!!】 + * + * author:wh + * @param string $file_upload_name 表单文件元素name值 + * @param int $size 大小,默认2M + * @param string $ext 允许的扩展 + * @return array + */ + function images($file_upload_name = 'file_upload', $size=10, $ext=''){ + if(!$this->uploadMaxFilesizeCheck($size)){ + return Tools::set_res(1, '上传文件受限'); + } + // 获取表单上传文件 + $files = request()->file($file_upload_name); + if(empty($files)){ + return Tools::set_fail('请上传文件'); + } + $outer_req_url = $this->file_dir.'/image'; + $physics_path = 'public'.$outer_req_url; + $root_path = explode('vendor',__DIR__)[0]; + $upload_dir = $root_path.$physics_path; + if(!is_dir($upload_dir)){ + mkdir($upload_dir, 0777, true); + } + + if(empty($ext)) $ext = $this->img_ext; + + $result = []; + $error = []; + foreach($files as $file){ + // 移动到框架应用根目录/uploads/ 目录下 + $info = $file->validate(['size'=>$size * 1024 * 1024, 'ext'=>$ext])->move($upload_dir); + if($info){ + //原文件名 + $source_file_name = $info->getInfo('name'); + + //文件类型 + $file_type = $info->getInfo('type'); + + // 输出扩展名 jpg + $extension = $info->getExtension(); + + // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg + $save_name = $info->getSaveName(); + + // 输出 42a79759f284b767dfcb2a0197904287.jpg + $new_filename = $info->getFilename(); + + $relative_url = $outer_req_url.'/'.str_replace('\\', '/', $save_name); + $result[] = [ + 'prefix'=>request()->domain().$outer_req_url,//访问前缀 + 'source_file_name'=>$source_file_name, + 'file_type'=>$file_type, + 'extension'=>$extension, + 'save_name'=>str_replace('\\', '/', $save_name), + 'new_filename'=>$new_filename, + 'real_path'=>$this->dealPath($root_path.'public'.$relative_url),//物理路径 + 'outer_req_url'=>request()->domain().$relative_url, + 'outer_req_relative_url'=>$relative_url, + 'size'=>$info->getSize(), + ]; + }else{ + //忽略错误 + // 上传失败获取错误信息 + $error[] = $file->getError(); + } + } + + $msg = '上传成功'; + $code = 0; + if(count($error) > 0){ + $msg = '上传失败;提示:'.implode(',', $error);//顺带返回错误信息 + $code = 1; + } + return Tools::set_res($code, $msg, $result); + } + + + /** + * desc:单文件 + * + * 【!!!必须确认php.ini中upload_max_filesize的配置足够大,否则上传失败但不会报错!!!】 + * + * author:wh + * @param string $file_upload_name 表单文件元素name值 + * @param int $size 大小,默认10M + * @param string $ext 允许的扩展 + * @return array + */ + function file($file_upload_name = 'file_upload', $size=10, $ext=''){ + if(!$this->uploadMaxFilesizeCheck($size)){ + return Tools::set_res(1, '上传文件受限'); + } + // 获取表单上传文件 例如上传了001.jpg + $file = request()->file($file_upload_name); + if(empty($file)){ + return Tools::set_fail('请上传文件'); + } + // 移动到框架应用根目录/uploads/ 目录下 + $outer_req_url = $this->file_dir.'/file'; + $physics_path = 'public'.$outer_req_url; + + $root_path = explode('vendor',__DIR__)[0]; + + $upload_dir = $root_path.$physics_path; + if(!is_dir($upload_dir)){ + mkdir($upload_dir, 0777, true); + } + if(empty($file)){ + return Tools::set_res(1, '上传文件不存在'); + } + + if(empty($ext)) $ext = $this->file_ext; + + $info = $file->validate(['size'=>$size * 1024 * 1024, 'ext'=>$ext])->move($upload_dir); + if($info){ + //原文件名 + $source_file_name = $info->getInfo('name'); + + //文件类型 + $file_type = $info->getInfo('type'); + + // 输出扩展名 jpg + $extension = $info->getExtension(); + + // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg + $save_name = $info->getSaveName(); + + // 输出 42a79759f284b767dfcb2a0197904287.jpg + $new_filename = $info->getFilename(); + + $relative_url = $outer_req_url.'/'.str_replace('\\', '/', $save_name); + $result = [ + 'prefix'=>request()->domain().$outer_req_url,//访问前缀 + 'source_file_name'=>$source_file_name, + 'file_type'=>$file_type, + 'extension'=>$extension, + 'save_name'=>str_replace('\\', '/', $save_name), + 'new_filename'=>$new_filename, + 'real_path'=>$this->dealPath($root_path.'public'.$relative_url),//物理路径 + 'outer_req_url'=>request()->domain().$relative_url, + 'outer_req_relative_url'=>$relative_url, + 'size'=>$info->getSize(), + ]; + return Tools::set_res(0, '上传成功', $result); + }else{ + // 上传失败获取错误信息 + return Tools::set_res(1, $file->getError()); + } + } + + /** + * desc:多文件 + * + * 【!!!必须确认php.ini中upload_max_filesize的配置足够大,否则上传失败但不会报错!!!】 + * + * author:wh + * @param string $file_upload_name 表单文件元素name值 + * @param int $size 单文件大小,默认10M + * @param string $ext 允许的扩展 + * @return array + */ + function files($file_upload_name = 'file_upload', $size=10, $ext=''){ + if(!$this->uploadMaxFilesizeCheck($size)){ + return Tools::set_res(1, '上传文件受限'); + } + + $root_path = explode('vendor',__DIR__)[0]; + // 获取表单上传文件 + $files = request()->file($file_upload_name); + if(empty($files)){ + return Tools::set_fail('请上传文件'); + } + $outer_req_url = $this->file_dir.'/file'; + $physics_path = 'public'.$outer_req_url; + $upload_dir = $root_path.$physics_path; + if(!is_dir($upload_dir)){ + mkdir($upload_dir, 0777, true); + } + + if(empty($ext)) $ext = $this->file_ext; + + $result = []; + $error = []; + foreach($files as $file){ + // 移动到框架应用根目录/uploads/ 目录下 + $info = $file->validate(['size'=>$size * 1024 * 1024, 'ext'=>$ext])->move($upload_dir); + if($info){ + //原文件名 + $source_file_name = $info->getInfo('name'); + + //文件类型 + $file_type = $info->getInfo('type'); + + // 输出扩展名 jpg + $extension = $info->getExtension(); + + // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg + $save_name = $info->getSaveName(); + + // 输出 42a79759f284b767dfcb2a0197904287.jpg + $new_filename = $info->getFilename(); + + $relative_url = $outer_req_url.'/'.str_replace('\\', '/', $save_name); + $result[] = [ + 'prefix'=>request()->domain().$outer_req_url,//访问前缀 + 'source_file_name'=>$source_file_name, + 'file_type'=>$file_type, + 'extension'=>$extension, + 'save_name'=>str_replace('\\', '/', $save_name), + 'new_filename'=>$new_filename, + 'real_path'=>$this->dealPath($root_path.'public'.$relative_url),//物理路径 + 'outer_req_url'=>request()->domain().$relative_url, + 'outer_req_relative_url'=>$relative_url, + 'size'=>$info->getSize(), + ]; + }else{ + //忽略错误 + // 上传失败获取错误信息 + $error[] = $file->getError(); + } + } + $msg = '上传成功'; + $code = 0; + if(count($error) > 0){ + $msg = '上传失败;提示:'.implode(',', $error);//顺带返回错误信息 + $code = 1; + } + return Tools::set_res($code, $msg, $result); + } + + + /** + * desc:单文件或多文件上传至阿里云OSS服务 + * + * author:wh + * @param array $config 配置 + * //阿里云oss配置 + 'aliyun_oss_config' => [ + //项目应用名称 + 'bucket'=>'wanlliuyinli-adm',//每创建一个bucket必须标明前缀,代表这个bucket属于哪个项目 + 'UserPrincipalName'=>'wanghua@1113242774600735.onaliyun.com', + 'Password'=>'0osE4cGo%tllnP1|uOQADPhM}Y?obR4U', + 'AccessKeyId'=>'LTAI5tPqn1n7jugviVoGqFfa', + 'AccessKeySecret'=>'BRoB5TdcUAFEuIR11BbN3R47Cm4Yep', + //https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints?spm=a2c4g.11186623.0.0.41ae2effA6oZar + 'region_id'=>'cn-chengdu',//这里配置不能包含oss-前缀,否则提示:Invalid signing region in Authorization header + //西南1(成都) + //oss-cn-chengdu + //oss-cn-chengdu.aliyuncs.com + //oss-cn-chengdu-internal.aliyuncs.com + 'endpoint'=>'oss-cn-chengdu.aliyuncs.com',//成都节点 + 'sts_endpoint'=>'sts.cn-chengdu.aliyuncs.com',//sts服务节点 + ] + * @param string $unique_id 唯一id,可以是用户id,可以是其它用于区分的标识,默认存放在(项目名称/控制器/方法/(唯一标识,可为空)/年月日/*.jpg) + * @param string $file_upload_name 文件上传控件的name值,必须带[],例如:file_upload[] + * @param string $oss_type oss类型,可选值:ali_cloud 阿里云,hua_wei 华为云(待扩展) + * @param int $size 单文件大小,默认10M + * @param string $ext 允许的文件扩展名 + * @return array + */ + function filesUploadToAliCloudOss($config,$unique_id='',$file_upload_name = 'file_upload',$size=10, $ext=''){ + return Mmodel::catch(function ()use ($config,$unique_id,$file_upload_name,$size,$ext){ + $ini_upload_max_filesize = str_replace('M','',ini_get('upload_max_filesize')); + if(($size > $ini_upload_max_filesize)){ + return Tools::set_res(1, '上传文件size受限,不能超过upload_max_filesize='.ini_get('upload_max_filesize').'M'); + } + // 获取表单上传文件 + $files = request()->file($file_upload_name); + if(empty($files)){ + return Tools::set_fail('请上传文件'); + } + //扩展 + if(empty($ext)) $ext = $this->file_ext; + //初始化阿里云OSS客户端 + $oss_obj= new Objects($config); + //默认存储地址 + $file_save_dir = $this->setFileSaveDir($unique_id); + $urls = []; + foreach($files as $file){ + if(!$file->isValid()){ + return Tools::set_fail('文件不合法'); + } + $check_size = $file->checkSize($size*1024*1024); + if(!$check_size){ + return Tools::set_fail('文件大小超限'); + } + $check_res = $file->checkExt($ext); + if(!$check_res){ + return Tools::set_fail('请上传合法文件'); + } + $extension = explode('.',$file->getInfo('name'))[1]; + $new_filename = 'file_'.Tools::rand_str(18).'.'.explode('.',$file->getInfo('name'))[1]; + //必须加后缀 + $filename = $file_save_dir.$new_filename; + + // 从文件流上传 + $res = $oss_obj->fileUpload($filename, $file->getInfo('tmp_name'));//上传之前的临时文件物理地址 + $urls[] = [ + 'prefix'=>explode('.com',$res['info']['url'])[0].'.com',//访问前缀 + 'source_file_name'=>$file->getInfo('name'),//源文件名 + 'size'=>$file->getInfo('size'),//大小(b) + 'extension'=>$extension,//扩展名 + 'file_type'=>$file->getInfo('type'),//文件后缀 + 'save_name'=>$filename,//保存文件名 + 'new_filename'=>$new_filename,//新文件名 + 'real_path'=>$res['info']['url'],//实际路径 + 'outer_req_url'=>$res['info']['url'],//外部访问地址 + 'outer_req_relative_url'=>$res['info']['url'],//外部访问相对地址 + ]; + } + return Tools::set_ok('ok', $urls); + }); + } + + /** + * desc:单文件上传至阿里云OSS + * + * author:wh + * @param array $config 配置 + * //阿里云oss配置 + 'aliyun_oss_config' => [ + //项目应用名称 + 'bucket'=>'wanlliuyinli-adm',//每创建一个bucket必须标明前缀,代表这个bucket属于哪个项目 + 'UserPrincipalName'=>'wanghua@1113242774600735.onaliyun.com', + 'Password'=>'0osE4cGo%tllnP1|uOQADPhM}Y?obR4U', + 'AccessKeyId'=>'LTAI5tPqn1n7jugviVoGqFfa', + 'AccessKeySecret'=>'BRoB5TdcUAFEuIR11BbN3R47Cm4Yep', + //https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints?spm=a2c4g.11186623.0.0.41ae2effA6oZar + 'region_id'=>'cn-chengdu',//这里配置不能包含oss-前缀,否则提示:Invalid signing region in Authorization header + //西南1(成都) + //oss-cn-chengdu + //oss-cn-chengdu.aliyuncs.com + //oss-cn-chengdu-internal.aliyuncs.com + 'endpoint'=>'oss-cn-chengdu.aliyuncs.com',//成都节点 + 'sts_endpoint'=>'sts.cn-chengdu.aliyuncs.com',//sts服务节点 + ] + * @param string $unique_id 唯一id,可以是用户id,可以是其它用于区分的标识,默认存放在(项目名称/控制器/方法/(唯一标识,可为空)/年月日/*.jpg) + * @param string $file_upload_name 文件上传控件的name值,例如:file_upload + * @param string $oss_type oss类型,可选值:ali_cloud 阿里云,hua_wei 华为云(待扩展) + * @param int $size 单文件大小,默认10M + * @param string $ext 允许的文件扩展名 + * @return array + */ + function fileUploadToAliCloudOss($config,$unique_id='',$file_upload_name = 'file_upload',$size=10, $ext=''){ + return Mmodel::catch(function ()use ($config,$unique_id,$file_upload_name,$size,$ext){ + $ini_upload_max_filesize = str_replace('M','',ini_get('upload_max_filesize')); + if(($size > $ini_upload_max_filesize)){ + return Tools::set_res(1, '上传文件size受限,不能超过upload_max_filesize='.ini_get('upload_max_filesize').'M'); + } + // 获取表单上传文件 + $file = request()->file($file_upload_name); + if(empty($file)){ + return Tools::set_fail('请上传文件'); + } + //扩展 + if(empty($ext)) $ext = $this->file_ext; + //初始化阿里云OSS客户端 + $oss_obj= new Objects($config); + //默认存储地址 + $file_save_dir = $this->setFileSaveDir($unique_id); + $urls = []; + if(!$file->isValid()){ + return Tools::set_fail('文件不合法'); + } + $check_size = $file->checkSize($size*1024*1024); + if(!$check_size){ + return Tools::set_fail('文件大小超限'); + } + $check_res = $file->checkExt($ext); + if(!$check_res){ + return Tools::set_fail('请上传合法文件'); + } + $extension = explode('.',$file->getInfo('name'))[1]; + $new_filename = 'file_'.Tools::rand_str(18).'.'.explode('.',$file->getInfo('name'))[1]; + //必须加后缀 + $filename = $file_save_dir.$new_filename; + + // 从文件流上传 + $res = $oss_obj->fileUpload($filename, $file->getInfo('tmp_name'));//上传之前的临时文件物理地址 + $urls[] = [ + 'prefix'=>explode('.com',$res['info']['url'])[0].'.com',//访问前缀 + 'source_file_name'=>$file->getInfo('name'),//源文件名 + 'size'=>$file->getInfo('size'),//大小(b) + 'extension'=>$extension,//扩展名 + 'file_type'=>$file->getInfo('type'),//文件后缀 + 'save_name'=>$filename,//保存文件名 + 'new_filename'=>$new_filename,//新文件名 + 'real_path'=>$res['info']['url'],//实际路径 + 'outer_req_url'=>$res['info']['url'],//外部访问地址 + 'outer_req_relative_url'=>$res['info']['url'],//外部访问相对地址 + ]; + return Tools::set_ok('ok', $urls); + }); + } + + /** + * desc:设置文件保存目录 + * author:wh + * @param string $unique_id 唯一id,可以是用户id,可以是其它用于区分的标识 + * @return string + */ + function setFileSaveDir($unique_id=''){ + if($unique_id){ + $unique_id = $unique_id.'/'; + } + //项目名称 + $project_name = Tools::get_project_name(); + //控制器方法路径 + $ctl = strtolower(request()->controller().'/'.request()->action()); + return $project_name.'/'.$ctl.'/'.$unique_id.date('Ymd').'/';//日期 + } + /** + * desc:检测size是否在ini配置范围 + * + * author:wh + * @param $size + * @return bool + */ + private function uploadMaxFilesizeCheck($size){ + $ini_upload_max_filesize = str_replace('M','',ini_get('upload_max_filesize')); + return $size<=$ini_upload_max_filesize; + } + + + /** + * desc:上传base64格式图片【文件不用base64传输】 + * author:wh + * @param string $file_upload_name + * @param int $size + * @param array $ext + * @return array + * @throws \Exception + */ + function uploadBase64Img($file_upload_name = 'file_upload', $size=10, $ext=''){ + $source = input($file_upload_name, 'file_upload'); + $file_size = strlen($source); + if($file_size > $size * 1024 * 1024){ + return Tools::set_res(1, '上传失败,大小限制'); + } + if(preg_match('/^(data:\s*image\/(\w+);base64,)/', $source, $result) < 1){ + return Tools::set_res(1, '上传文件不合法'); + } + $type = $result[2]; + + if(empty($ext)) $ext = $this->file_ext; + + if(!in_array($type, explode($ext))){ + return Tools::set_res(1, '上传失败,类型限制'); + } + $result = base64_image_content($source); + if(false === $result){ + return Tools::set_res(1, '上传失败'); + } + return Tools::set_res(0, '上传成功', $result); + } + + /** + * desc:批量上传base64格式图片【文件不用base64传输】 + * author:wh + * @param string $file_upload_name + * @param int $size + * @param array $ext + * @return array + * @throws \Exception + */ + function uploadBase64Imgs($file_upload_name = 'file_upload', $size=10, $ext=''){ + $source_list = input($file_upload_name, 'file_upload'); + if(!is_array($source_list)){ + return Tools::set_res(1, '参数错误'); + } + + if(empty($ext)) $ext = $this->file_ext; + + $result = []; + $error = []; + foreach ($source_list as $source){ + $file_size = strlen($source); + if($file_size > $size * 1024 * 1024){ + $error[] = '上传失败,大小限制'; + continue; + } + if(preg_match('/^(data:\s*image\/(\w+);base64,)/', $source, $temp) < 1){ + $error[] = '上传文件不合法'; + continue; + } + $type = $temp[2]; + if(!in_array($type, explode(',', $ext))){ + $error[] = '类型限制'; + continue; + } + $up_result = base64_image_content($source); + if(false === $up_result){ + $error[] = '上传失败'; + continue; + } + $result[] = $up_result; + } + + $msg = '上传成功'; + $code = 0; + if(count($error) > 0){ + $msg = '上传失败;提示:'.implode(',', $error);//顺带返回错误信息 + $code = 1; + } + return Tools::set_res($code, $msg, $result); + } + + /** + * desc:优化路径格式 + * author:wh + */ + private function dealPath(string $path){ + $str = str_replace('\\','/',$path); + + return str_replace('//','/',$str); + } + + + /** + * desc:curl上传文件,php上传文件到远程服务器地址 + * + * [php curl模拟文件上传] + * + * 依赖库:"guzzlehttp/guzzle": "^7.8", + * + * author:wh + * @param $url + * @param $params + * @param false[] $config + */ + function uploadCurlFiles($url,$params, $config=['verify' => false]){ + if(empty($this->unique_key)){ + throw new \Exception('UNIQUE_KEY 不能为空'); + } + if(empty($this->file_lists_urls)){ + throw new \Exception('文件地址列表不能为空'); + } + // 创建 Guzzle HTTP 客户端实例 + $client = new Client($config); + + // 定义要上传的文件列表 + $files = [ + //[ + // 'name' => 'file1', // 服务器接收的文件字段名 + // 'contents' => Utils::tryFopen('D:\wanghua\projects\big_world_projects\universal_gravitation\public\uploads\20240506\dc1c441d81d48565ac6817b89d0f8bef.mp4', 'r'), // 文件路径 + // 'filename' => 'dc1c441d81d48565ac6817b89d0f8bef.mp4', // 文件名,可自定义 + //], + //[ + // 'name' => 'files', + // 'contents' => Utils::tryFopen('D:\wanghua\projects\big_world_projects\universal_gravitation\public\uploads\20240506\f80179b23b60619fba8033bfd64f8817.mp4', 'r'), + // 'filename' => 'f80179b23b60619fba8033bfd64f8817.mp4', + //], + //['name'=>'prompt','contents'=>$prompt], + //['name'=>'tts_url','contents'=>$tts_url] + // 可以继续添加更多文件... + ]; + //print_r($params); + foreach ($params as $key=>$val){ + $files[] = ['name'=>$key,'contents'=>$val]; + } + $controller = strtolower(request()->controller()); + $action = strtolower(request()->action()); + $save_path = Tools::get_root_path() . "public/uploads/{$controller}/{$action}/".$this->unique_key; + if(!file_exists($save_path)){ + mkdir($save_path,0777,true); + } + + //文件远程可访问地址列表 + foreach ($this->file_lists_urls as $name=>$video_url) { + //处理可用地址(可能存储在本地或oss) + $video_url = $this->get_usable_url($video_url); + $files[] = [ + 'name'=>"files",//服务器接收的文件字段名 + //读取地址文件流(本地地址或远程地址均可,本地真实物理地址也行) + 'contents'=>Utils::tryFopen($video_url, 'r'), + 'filename'=>$name,//可自定义 文件名 + ]; + } + + // 构建多部分表单数据 + $multipartStream = new MultipartStream($files); + $boundary = $multipartStream->getBoundary(); + $headers = [ + 'Content-Type' => "multipart/form-data; boundary={$boundary}", + ]; + + // 准备请求体 + $body = $multipartStream->getContents(); + + // 发起 POST 请求 + try { + $postinfo = [ + 'headers' => $headers, + 'body' => $body, + ]; + //上传 + $response = $client->request('POST', $url, $postinfo); + // 处理响应 + //$responseBody = (string) $response->getBody(); + // 检查状态码 + //if ($response->getStatusCode() !== 200) { + // return false; + //} + return $response;//返回上传结果 + } catch (\GuzzleHttp\Exception\RequestException $e) { + // 错误处理 + //echo "Error: " . $e->getMessage(); + Tools::error_txt_log($e); + return false; + } + } + + /** + * desc:获取视频可用地址(兼容远程地址或本地地址) + * author:wh + * @param $video_url + * @return string|string[] + */ + private function get_usable_url($video_url){ + if(strpos($video_url,'http')!==false){ + return $video_url;//远程地址 + } + return Tools::get_root_path().$video_url;//本地地址 + } + + + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/README.MD b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/README.MD new file mode 100644 index 0000000..df6ecdf --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/file/upload/README.MD @@ -0,0 +1 @@ +## 文件上传类库 \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/BaseController.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/BaseController.php new file mode 100644 index 0000000..849121c --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/BaseController.php @@ -0,0 +1,210 @@ +checkMaintain(); + if ($chm['is_maintain']) { + if ($chm['users_ids']) { + //解析openid + if (!in_array(api_user_info('id'), explode(',', $chm['users_ids']))) { + //白名单之外维护中 + //Tools::log_to_write_txt([ + // '维护测试'=>$chm['users_ids'], + // 'my'=>index_user_openid() + //]); + return $this->error($chm['msg']); + } + } else { + //不存在,直接维护中 + return $this->error($chm['msg'] . '!'); + } + } + //校验系统维护状态 end + } + + /** + * desc:检查路径维护状态 + * + * “===”完全匹配,不能使用like + * + * author:wh + */ + protected function checkMaintain(){ + $configs = Db::table(TabConf::$fa_sys_maintain_config) + ->where('status','1') + ->cache() + ->select(); + + //模块 + $strmodule = request()->module(); + foreach ($configs as $config){ + if($strmodule == $config['url']){ + //模块维护中 + return ['is_maintain'=>true,'msg'=>$config['msg'],'users_ids'=>$config['users_ids']]; + } + } + + //模块/控制器 + $strcontroller = strtolower(request()->module().'/'.request()->controller()); + foreach ($configs as $config){ + if($strcontroller == $config['url']){ + //模块维护中 + return ['is_maintain'=>true,'msg'=>$config['msg'],'users_ids'=>$config['users_ids']]; + } + } + + //模块/控制器/方法 + $straction = strtolower(request()->module().'/'.request()->controller().'/'.request()->action()); + foreach ($configs as $config){ + if($straction == $config['url']){ + //模块维护中 + return ['is_maintain'=>true,'msg'=>$config['msg'],'users_ids'=>$config['users_ids']]; + } + } + + //未维护 + return ['is_maintain'=>false,'msg'=>'服务运行中']; + } + /** + * desc:清空系统缓存 + * + /index/Test/clearCache + * + * author:wh + */ + function clearCache(){ + + Cache::clear(); + } + /** + * eg:/index/test/buildTablesConf + * + * desc:构建统一的表名配置 + * + * author:wh + */ + function buildTablesConf(){ + + (new MySqlTools())->buildTablesConf(); + + } + + /** + * desc:创建&更新接口文档 + * + * 默认存放在/public/api_docs/api_list.md + * + * author:wh + */ + function buildApiDoc() + { + $obj = new ApiDocument(); + //根据自己的实际情况设置直接继承类(仅供参考) + $obj->extends_base_class = 'app\\api\\controller\\BaseHttpApi,wanghua\\general_utility_tools_php\\framework\\base\\BaseWechatAuthController'; + //设置过滤的类(仅供参考) + $obj->setFilterClass([ + 'BaseCommonController', + 'BaseHttpApi', + 'BaseWssApi', + 'Wsspush', + 'BaseController', + 'BaseAuthController', + //'BaseWechatAuthController', + 'BasePublicController' + ]); + $obj->setFilterFunction([ + 'buildApiDoc', + 'buildTablesConf', + 'checkfailed', + 'clearCache', + 'defaultAuth', + 'operateLog', + 'checkMaintain' + ]); + //构建接口文档 + $obj->buildDoc(); + //生成html + $html = $obj->buildApiDocHtml(); + $path = Tools::get_root_path().'/public/api_docs/'; + if(!file_exists($path)){ + mkdir($path,0777,true); + } + file_put_contents($path.'api_list.html',$html); + echo "api_list.html"; + + } + + /** + * desc:用户操作日志 + * author:wh + */ + protected function operateLog($msg,$users_id=0,$username='',$name=''){ + $tbname = 'fa_users_operate_log'; + $sql = " + CREATE TABLE `{$tbname}` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', + `users_id` int(10) unsigned DEFAULT '0' COMMENT '用户ID', + `username` varchar(15) DEFAULT '' COMMENT '用户名', + `name` varchar(20) DEFAULT '' COMMENT '名称', + `url` varchar(60) DEFAULT '' COMMENT 'URL', + `msg` varchar(90) DEFAULT '' COMMENT '做了什么', + `ip` varchar(30) DEFAULT '' COMMENT '登录ip', + `input` text COMMENT '提交参数', + `create_time` timestamp NULL DEFAULT NULL COMMENT '登陆时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='用户操作日志';"; + + if(cache('cache_db_tables_now_project')){ + $table_arr = cache('cache_db_tables_now_project'); + }else{ + $table_arr = Tools::get_tables(); + } + //表是否存在 + if(!in_array($tbname,$table_arr)){ + cache('cache_db_tables_now_project',$table_arr); + Db::execute($sql); + } + + $data = [ + 'users_id'=>$users_id, + 'username'=>$username, + 'name'=>$name, + 'url'=>request()->url(), + 'msg'=>$msg, + 'ip'=>request()->ip(), + 'input'=>json_encode(input(),JSON_UNESCAPED_UNICODE), + ]; + Db::table($tbname)->data($data)->insert(); + + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/README.MD b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/README.MD new file mode 100644 index 0000000..789b3a0 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/README.MD @@ -0,0 +1 @@ +### this classes only to thinkphp5+ \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BaseAuthController.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BaseAuthController.php new file mode 100644 index 0000000..a73e32d --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BaseAuthController.php @@ -0,0 +1,80 @@ +auth_err_redirect_url = $err_redirect_url; + } + + } + + /** + * desc:默认鉴权 + * author:wh + * @return bool + */ + function defaultAuth(){ + $params = input(); + if(empty($params['nonce'])){ + Tools::log_to_write_txt(['服务被拒绝,鉴权参数缺失:nonce。params'=>input()]); + //跳转至错误中转控制器 + return $this->response($this->auth_err_redirect_url,['title'=>'服务被拒绝. permission denied']); + } + if(empty($params['timestamp'])){ + Tools::log_to_write_txt(['服务被拒绝,鉴权参数缺失:timestamp。params'=>input()]); + //跳转至错误中转控制器 + return $this->response($this->auth_err_redirect_url,['title'=>'服务被拒绝. permission denied.']); + } + if(empty($params['sign'])){ + Tools::log_to_write_txt(['服务被拒绝,鉴权参数缺失:sign。params'=>input()]); + //跳转至错误中转控制器 + return $this->response($this->auth_err_redirect_url,['title'=>'服务被拒绝. permission denied。']); + } + $sign = $params['sign']; + unset($params['sign']); + if(Tools::signature($params) != $sign){ + + Tools::log_to_write_txt(['签名失败,服务被拒绝.'=>input()]); + + //跳转至错误中转控制器 + return $this->response($this->auth_err_redirect_url,['title'=>'服务被拒绝. permission denied!']); + } + return true; + } + protected function response($url,$params){ + + if(Request::instance()->isAjax() || Request::instance()->isPost()){ + return json(Tools::set_res(500,$params['title'],['url'=>$url])); + } + //跳转至错误中转控制器 + return $this->redirect(url($url,$params)); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BasePublicController.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BasePublicController.php new file mode 100644 index 0000000..e2f9fa6 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/framework/base/BasePublicController.php @@ -0,0 +1,29 @@ +assign('index_msg', cache('index_msg_alert_cache_time')); + + //线上环境加载微信授权 + if (config('sys_env') == 'PROD') { + $wx_user_info = session('wx_user_info'); + if (empty($wx_user_info['openid'])) { + //重定向之前,保存当前url, 在获取授权信息之后,回跳到授权之前的网页地址 + session('redirect_before_url_session', request()->url(true)); + $ver = Tools::get_thinkphp_version(); + if($ver == '5.0'){ + $url = url('index/Wexinauth/usrAuth','',false,true); + }else{ + $url = request()->domain().url('index/Wexinauth/usrAuth'); + } + //没有则重定向去授权 + return $this->redirect($url); + } + + $this->saveWechatUser($wx_user_info); + } + + + + + } + + + /** + * desc:周期更新当前用户信息 + * author:wh + * @param $wx_user_info + */ + private function saveWechatUser($wx_user_info) + { + try { + $wechat_user = $this->getWxUserByOpenid($wx_user_info['openid']); + if (empty($wechat_user)) { + return $this->insertInfo($wx_user_info); + } + //扩展,按周期更新,而不是不更新 + if (empty($wechat_user['update_time']) || time() - strtotime($wechat_user['update_time']) > 5 * 3600) { + + return $this->updateUser($wx_user_info); + } + + + } catch (\Exception $e) { + Tools::log_to_write_txt([ + 'error' => '存储异常.' . $e->getMessage(), + 'wx_user_info' => $wx_user_info, + 'error_info' => $e->getTraceAsString() + ]); + } + } + + /** + * desc:新增微信用户信息 + * author:wh + * @param $wx_user_info \app\index\model\微信用户 + * + * { + * "openid":"or9D2vs863Ky5Py2ovkAiu9XFLO4", + * "nickname":"起源果蔬副食大华", + * "sex":0, + * "language":"", + * "city":"", + * "province":"", + * "country":"", + * "headimgurl":"https://thirdwx.qlogo.cn/mmopen/vi_32/joiaA475nx3fJiaqx0ibdnWo4A7Q3uCgu2hsribI0ATLItORjuUgCSP8mCaBkqL61ibGojib4pQYX1djUhZpF5zoqpSg/132", + * "privilege":[] + * } + */ + private function insertInfo(array $wx_user_info) + { + + if (isset($wx_user_info['privilege'])) { + $wx_user_info['privilege'] = json_encode($wx_user_info['privilege']); + } + $data = [ + 'nickname' => $wx_user_info['nickname'], + 'country' => $wx_user_info['country'], + 'province' => $wx_user_info['province'], + 'city' => $wx_user_info['city'], + 'headimage' => $wx_user_info['headimgurl'], + 'language' => $wx_user_info['language'], + 'openid' => $wx_user_info['openid'], + 'unionid' => isset($wx_user_info['unionid']) ? $wx_user_info['unionid'] : '', + 'privilege' => $wx_user_info['privilege'], + 'sex' => $wx_user_info['sex'], + 'arm_group' => '', + 'score' => 0,//积分 + 'group_buy_earnings' => 0,//拼团收益 + 'water_drop_balance' => 0,//水滴 + ]; + Db::table($this->wechat_user_table_name) + ->data($data) + ->insert(); + } + + /** + * desc:更新当前用户信息 + * + * author:wh + */ + private function updateUser($wx_user_info) + { + $data = [ + 'nickname' => $wx_user_info['nickname'], + 'headimage' => $wx_user_info['headimgurl'], + 'unionid' => isset($wx_user_info['unionid']) ? $wx_user_info['unionid'] : '', + ]; + Db::table($this->wechat_user_table_name) + ->data($data) + ->where('openid', index_user_openid()) + ->update(); + } + + /** + * desc:根据unionid获取用户信息 + * author:wh + * @param string $unionid + */ + private function getWxUserByUnionid(string $unionid) + { + return Db::table($this->wechat_user_table_name) + ->field('id') + ->where('unionid', $unionid) + ->find(); + } + + /** + * desc:获取微信用户信息 + * author:wh + * @param string $openid + */ + private function getWxUserByOpenid(string $openid) + { + return Db::table($this->wechat_user_table_name) + //->field('id') + ->where('openid', $openid) + ->find(); + } + + /** + * desc:根据openid获取昵称 + * author:wh + * @param string $openid + */ + private function getNicknameByOpenid(string $openid) + { + return Db::table($this->wechat_user_table_name) + ->where('openid', $openid) + ->value('nickname'); + } + + + + +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/Ftp.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/Ftp.php new file mode 100644 index 0000000..e8c8806 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/Ftp.php @@ -0,0 +1,213 @@ +conn_id = ftp_connect($host, $port); + if(!$this->conn_id) throw new \Exception("FTP服务器连接失败"); + $login_res = ftp_login($this->conn_id, $user, $password); + if(!$login_res) throw new \Exception("FTP服务器登陆失败"); + ftp_pasv($this->conn_id, false); // true打开被动模拟,默认关闭,如果总是失败,可试试true + } + + /** + * desc:打开被动模拟,登录后使用 + * author:wh + */ + function set_ftp_pasv(){ + ftp_pasv($this->conn_id, true); // true打开被动模拟 + } + + /** + * 上传文件 + * param $path 本地文件路径[包含文件名] + * param $newPath 目标目录[包含文件名][默认存放在ftp用户被授权的根路径] + * param bool $type 若目标目录不存在则新建 + */ + function up_file($path, $newPath, $type = true) + { + if ($type) $this->dir_mkdirs($newPath); + $this->off = ftp_put($this->conn_id, $newPath, $path, FTP_BINARY); + if (!$this->off) + return ['code'=>500, 'msg'=>'文件上传失败,请检查权限及路径是否正确!']; + return ['code'=>200, 'msg'=>'文件移动成功']; + } + + /** + * 移动文件 + * 特别注意: + * $path 如果是当前目录,则必须以 “/”开始 + * 正确:/test2.zip + * 错误:test2.zip + * param $path 原路径(含文件名) + * param $newPath 新路径(含文件名) + * param bool $type 若目标目录不存在则新建 + */ + function move_file($path, $newPath, $ftpbasedir, $type = true) + { + if ($type) $this->ftp_mksubdirs($ftpbasedir,$newPath); + $this->off = ftp_rename($this->conn_id, $path, $newPath); + if (!$this->off) + return ['code'=>500, 'msg'=>'文件移动失败,请检查权限及原路径是否正确!']; + return ['code'=>200, 'msg'=>'文件移动成功']; + } + + /** + * 文件改名 + * param $path 原路径 + * param $newPath 新路径 + */ + function rename_file($path, $newPath) + { + $this->off = ftp_rename($this->conn_id, $path, $newPath); + if (!$this->off) + return ['code'=>500, 'msg'=>'文件改名失败,请检查权限及原路径是否正确!']; + return ['code'=>200, 'msg'=>'文件改名成功']; + } + + /** + * 复制文件 + * 说明:由于FTP无复制命令,本方法变通操作为:下载后再上传到新的路径 + * param $path 原路径 + * param $newPath 新路径 + * param bool $type 若目标目录不存在则新建 + */ + function copy_file($path, $newPath, $type = true) + { + $downPath = "c:/tmp.dat"; + $this->off = ftp_get($this->conn_id, $downPath, $path, FTP_BINARY);// 下载 + if (!$this->off) + return ['code'=>500, 'msg'=>'文件复制失败,请检查权限及原路径是否正确!']; + + $this->up_file($downPath, $newPath, $type); + return ['code'=>200, 'msg'=>'文件复制成功']; + } + + /** + * 删除文件 + * param $path 路径 + */ + function del_file($path) + { + $this->off = ftp_delete($this->conn_id, $path); + if (!$this->off) + return ['code'=>500, 'msg'=>'文件删除失败,请检查权限及路径是否正确!']; + + return ['code'=>200, 'msg'=>'文件删除成功']; + } + + /** + * desc:删除给定目录 + * 注: + * 删除多个目录需重复调用 + * author:wh + * param $dir + * return bool + */ + function del_dir($dir){ + + + $children = ftp_nlist ($this->conn_id, $dir); + if(!$children) { + ftp_rmdir($this->conn_id, $dir); + + return true; + } + + throw new \Exception('请确保目录中无内容'); + + } + + + /** + * desc:生成目录 + * author:wh + * param $ftpcon + * param $ftpbasedir + * param $ftpath + */ + function ftp_mksubdirs($ftpbasedir,$ftpath){ + ftp_chdir($this->conn_id, $ftpbasedir); // /var/www/uploads + $parts = explode('/',$ftpath); // 2013/06/11/username + + if(strpos($parts[count($parts)-1], '.')){ + unset($parts[count($parts)-1]); + } + + foreach($parts as $part){ + if(!ftp_chdir($this->conn_id, $part)){ + ftp_mkdir($this->conn_id, $part); + ftp_chdir($this->conn_id, $part); + //ftp_chmod($this->conn_id, 0777, $part); + } + } + } + + /** + * desc:使用ftp连接方式下载文件 + * author:wh + * param string $local_file 文件本地的路径(如果文件已经存在,则会被覆盖)。 + * param string $remote_file 文件的远程路径。[默认查找ftp用户被授权的根路径] + * return array + */ + function download(string $local_file, string $remote_file){ + // 进行ftp下载[默认保存在本地根目录] + if (!ftp_get($this->conn_id, $local_file, $remote_file, FTP_BINARY)) { + return ['code'=>500, 'msg'=>'ftp download fail']; + } + return ['code'=>200, 'msg'=>'ftp download success']; + } + + /** + * desc:判断ftp文件大小, 如果>-1, 说明文件存在;否则不存在. + * author:wh + * param $remote_file + * return int + */ + function ftp_size($remote_file){ + return ftp_size($this->conn_id, $remote_file); + } + + /** + * desc:返回当前目录 + * author:wh + * return false|string + */ + function ftp_pwd(){ + return ftp_pwd($this->conn_id); + } + /** + * 关闭FTP连接 + */ + function close() + { + ftp_close($this->conn_id); + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/README.md b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/README.md new file mode 100644 index 0000000..29b9a72 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/ftp/README.md @@ -0,0 +1,21 @@ +# PHP ftp类库 +#### 实现用ftp方式上传、复制、移动、重命名、删除、下载文件 + +##### 案例代码: +``` + $ftp = new Ftp();//初始化 + //$ftp->up_file('D:\whua\test.zip','test.zip'); // 上传文件 + //$ftp->rename_file('test.zip','test-rename.zip'); // 移动文件 + //$ftp->move_file('/test2.zip','/testdir2/test2.zip', '/www/wwwroot/testftp/'); // 移动文件2 + //$ftp->copy_file('test.zip','test-copy.zip'); // 复制文件 + //$ftp->del_file('/www/aaa.txt'); // 删除具体文件 + $ftp->del_dir('/www'); // 删除目录(错误示范),必须精确到具体文件夹删除 + $ftp->del_dir('/ftp/test/copy-test/a-dir'); // 删除目录(正确示范),必须精确到具体文件夹删除,批量删除请多次调用 + + //下载文件 + //$ftp->download('D:\whua\projects\zc_game_admin3.0\data\local.zip', 'test.zip'); + //$ftp->close(); // 关闭FTP连接 + + //dump($ftp->ftp_pwd());die; + //dump($ftp->ftp_size('test2.zip'));die; +``` \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/BaseChat.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/BaseChat.php new file mode 100644 index 0000000..718f8aa --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/BaseChat.php @@ -0,0 +1,35 @@ +messages[] = $item; } } } function sB3250714FE96BE2F5E2D7798123A1B94($describe = []) { if ($describe) { foreach ($describe as $item) { $this->messages[] = $item; } } } function s326723D163240094B8C736D3A1A5CAD3($describe = []) { if ($describe) { foreach ($describe as $item) { $this->messages[] = $item; } } } private function c2111E682402A3955B616FA5795DEDE4F() { if (empty($this->url) || empty($this->apiKey) || empty($this->model)) { throw new Exception('PARAMS ERROR'); } } function cE0323A9039ADD2978BF5B49550572C7C($question = '', $config = [], &$answer_json_arr) { $answer = ''; $this->c8ECA4C82960B4611B076D51EF8ADF979($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) { $answer_json_arr[] = $data; $answer .= $data; echo $data; ob_flush(); flush(); return strlen($data); }); return $answer; } function crtque($question = '', $config = [], &$answer_json_arr) { $answer = ''; $this->c8ECA4C82960B4611B076D51EF8ADF979($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) { $answer_json_arr[] = $data; $answer .= $data; return strlen($data); }); return $answer; } private function c8ECA4C82960B4611B076D51EF8ADF979($question = '', $config = [], $callback) { $url = $this->url; $apiKey = $this->apiKey; $model = $this->model; $headers = ["Authorization: Bearer $apiKey", 'Accept: application/json', 'Content-Type: application/json',]; $post_msg_body = ["model" => $model, 'stream' => true,]; if ($config) { foreach ($config as $key => $val) { $post_msg_body[$key] = $val; } } if ($question) { $this->messages[] = ["role" => "user", "content" => $question]; } $post_msg_body['messages'] = $this->messages; $postData = json_encode($post_msg_body); $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback); curl_exec($ch); } function getchatgptresponse($question = '', $config = []) { $url = $this->url; $apiKey = $this->apiKey; $model = $this->model; $headers = ["Authorization: Bearer $apiKey", "Content-Type: application/json"]; $post_msg_body = ["model" => $model, 'stream' => false]; if ($config) { foreach ($config as $key => $val) { $post_msg_body[$key] = $val; } } if ($question) { $this->messages[] = ["role" => "user", "content" => $question]; } $post_msg_body['messages'] = $this->messages; $post_msg_body = json_encode($post_msg_body); $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_msg_body); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); if (curl_error($ch)) { return ['code' => curl_errno($ch), 'msg' => curl_error($ch)]; } else { curl_close($ch); return ['code' => 200, 'msg' => 'cURL ok', 'data' => $response]; } } private function pCD736318A127E12426EED8700FF2BF28($data) { if (@json_decode($data)->choices[0]->message->content) { return json_decode($data)->choices[0]->message->content; } $data = str_replace('data: {', '{', $data); $data = rtrim($data, "\n\n"); if (strpos($data, 'data: [DONE]') !== false) { return 'data: [DONE]'; } else { if (false !== strpos($data, "\n\n")) { $exp_arr = explode("\n\n", $data); $str = ''; try { for ($i = 0; $i < count($exp_arr) - 1; $i++) { $jsondecode_arr = json_decode($exp_arr[$i], true); $str .= $jsondecode_arr['choices'][0]['delta']['content']; } return $str; } catch (\Exception $e) { return $str; } } $data = @json_decode($data, true); if (!is_array($data)) { return ''; } if ($data['choices'][0]['finish_reason'] == 'stop') { return 'data: [DONE]'; } elseif ($data['choices'][0]['finish_reason'] == 'length') { return 'data: [CONTINUE]'; } return $data['choices'][0]['delta']['content'] ?? ''; } } } \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/ChatGPT.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/ChatGPT.php new file mode 100644 index 0000000..87e048a --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/ChatGPT.php @@ -0,0 +1,175 @@ +messages[] = $item; + } + } + } + + function setBefore($describe = []) + { + if ($describe) { + foreach ($describe as $item) { + $this->messages[] = $item; + } + } + } + + function setAfter($describe = []) + { + if ($describe) { + foreach ($describe as $item) { + $this->messages[] = $item; + } + } + } + + private function check() + { + if (empty($this->url) || empty($this->apiKey) || empty($this->model)) { + throw new Exception('PARAMS ERROR'); + } + } + + function chat($question = '', $config = [], &$answer_json_arr) + { + $answer = ''; + $this->curlPostChat($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) { + $answer_json_arr[] = $data; + $answer .= $data; + echo $data; + ob_flush(); + flush(); + return strlen($data); + }); + return $answer; + } + + function returnAnswer($question = '', $config = [], &$answer_json_arr) + { + $answer = ''; + $this->curlPostChat($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) { + $answer_json_arr[] = $data; + $answer .= $data; + return strlen($data); + }); + return $answer; + } + + private function curlPostChat($question = '', $config = [], $callback) + { + $url = $this->url; + $apiKey = $this->apiKey; + $model = $this->model; + $headers = ["Authorization: Bearer $apiKey", 'Accept: application/json', 'Content-Type: application/json',]; + $post_msg_body = ["model" => $model, 'stream' => true,]; + if ($config) { + foreach ($config as $key => $val) { + $post_msg_body[$key] = $val; + } + } + if ($question) { + $this->messages[] = ["role" => "user", "content" => $question]; + } + $post_msg_body['messages'] = $this->messages; + $postData = json_encode($post_msg_body); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); + curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback); + curl_exec($ch); + } + + function getchatgptresponse($question = '', $config = []) + { + $url = $this->url; + $apiKey = $this->apiKey; + $model = $this->model; + $headers = ["Authorization: Bearer $apiKey", "Content-Type: application/json"]; + $post_msg_body = ["model" => $model, 'stream' => false]; + if ($config) { + foreach ($config as $key => $val) { + $post_msg_body[$key] = $val; + } + } + if ($question) { + $this->messages[] = ["role" => "user", "content" => $question]; + } + $post_msg_body['messages'] = $this->messages; + $post_msg_body = json_encode($post_msg_body); + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_msg_body); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + if (curl_error($ch)) { + return ['code' => curl_errno($ch), 'msg' => curl_error($ch)]; + } else { + curl_close($ch); + return ['code' => 200, 'msg' => 'cURL ok', 'data' => $response]; + } + } + + private function parseData($data) + { + if (@json_decode($data)->choices[0]->message->content) { + return json_decode($data)->choices[0]->message->content; + } + $data = str_replace('data: {', '{', $data); + $data = rtrim($data, "\n\n"); + if (strpos($data, 'data: [DONE]') !== false) { + return 'data: [DONE]'; + } else { + if (false !== strpos($data, "\n\n")) { + $exp_arr = explode("\n\n", $data); + $str = ''; + try { + for ($i = 0; $i < count($exp_arr) - 1; $i++) { + $jsondecode_arr = json_decode($exp_arr[$i], true); + $str .= $jsondecode_arr['choices'][0]['delta']['content']; + } + return $str; + } catch (\Exception $e) { + return $str; + } + } + $data = @json_decode($data, true); + if (!is_array($data)) { + return ''; + } + if ($data['choices'][0]['finish_reason'] == 'stop') { + return 'data: [DONE]'; + } elseif ($data['choices'][0]['finish_reason'] == 'length') { + return 'data: [CONTINUE]'; + } + return $data['choices'][0]['delta']['content'] ?? ''; + } + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/F37A49CDED4199801B05D5FFFAF78E010.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/F37A49CDED4199801B05D5FFFAF78E010.php new file mode 100644 index 0000000..e373715 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/F37A49CDED4199801B05D5FFFAF78E010.php @@ -0,0 +1,141 @@ +messages[] = $item; + } + } + } + + function s3ASCD163240094B8C736D3A1A5CSD($describe = []) + { + if ($describe) { + foreach ($describe as $item) { + $this->messages[] = $item; + } + } + } + + function s326723D163240094B8C736D3A1A5CAD3($describe = []) + { + if ($describe) { + foreach ($describe as $item) { + $this->messages[] = $item; + } + } + } + + private function c2111E682402A3955B616FA5795DEDE4F() + { + if (empty($this->url) || empty($this->apiKey)) { + throw new Exception('PARAMS ERROR'); + } + } + + function cAA8AF3EBE14831A7CD1B6D1383A03755($question = '', $config = [], &$answer_json_arr) + { + $answer = ''; + $this->c8ECA4C82960B4611B076D51EF8ADF979($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) { + $answer_json_arr[] = $data; + echo $data; + ob_flush(); + flush(); + return strlen($data); + }); + } + + private function c8ECA4C82960B4611B076D51EF8ADF979($question = '', $config = [], $callback) + { + $this->c2111E682402A3955B616FA5795DEDE4F(); + $url = $this->url;; + $apiKey = $this->apiKey; + $model = $this->model; + $chatId = $this->chatId; + $detail = $this->detail; + $headers = ["Authorization: Bearer $apiKey", 'Accept: application/json', 'Content-Type: application/json',]; + $post_msg_body = ['detail' => $detail, 'stream' => true,]; + if ($detail) { + $post_msg_body['detail'] = $detail; + } + if ($chatId) { + $post_msg_body['chatId'] = $chatId; + } + if ($model) { + $post_msg_body['model'] = $model; + } + if ($config) { + foreach ($config as $key => $val) { + $post_msg_body[$key] = $val; + } + } + if ($question) { + $this->messages[] = ["role" => "user", "content" => $question]; + } + $post_msg_body['messages'] = $this->messages; + $postData = json_encode($post_msg_body); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); + curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback); + curl_exec($ch); + } + + private function pCD736318A127E12426EED8700FF2BF28($data) + { + if (@json_decode($data)->choices[0]->message->content) { + return json_decode($data)->choices[0]->message->content; + } + $data = str_replace('data: {', '{', $data); + $data = rtrim($data, "\n\n"); + if (strpos($data, 'data: [DONE]') !== false) { + return 'data: [DONE]'; + } else { + if (false !== strpos($data, "\n\n")) { + $exp_arr = explode("\n\n", $data); + $str = ''; + try { + for ($i = 0; $i < count($exp_arr) - 1; $i++) { + $jsondecode_arr = json_decode($exp_arr[$i], true); + $str .= $jsondecode_arr['choices'][0]['delta']['content']; + } + return $str; + } catch (\Exception $e) { + return $str; + } + } + $data = @json_decode($data, true); + if (!is_array($data)) { + return ''; + } + if ($data['choices'][0]['finish_reason'] == 'stop') { + return 'data: [DONE]'; + } elseif ($data['choices'][0]['finish_reason'] == 'length') { + return 'data: [CONTINUE]'; + } + return $data['choices'][0]['delta']['content'] ?? ''; + } + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/FastGPT.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/FastGPT.php new file mode 100644 index 0000000..85c947e --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/gpt/chat/FastGPT.php @@ -0,0 +1,146 @@ +messages[] = $item; + } + } + } + + function setBefore($describe = []) + { + if ($describe) { + foreach ($describe as $item) { + $this->messages[] = $item; + } + } + } + + function setAfter($describe = []) + { + if ($describe) { + foreach ($describe as $item) { + $this->messages[] = $item; + } + } + } + + private function check() + { + if (empty($this->url) || empty($this->apiKey)) { + throw new Exception('PARAMS ERROR'); + } + } + + function chat($question = '', $config = [], &$answer_json_arr) + { + $answer = ''; + $this->curlPostChat($question, $config, function ($ch, $data) use ($question, &$answer, &$answer_json_arr) { + $answer_json_arr[] = $data; + echo $data; + ob_flush(); + flush(); + return strlen($data); + }); + } + + private function curlPostChat($question = '', $config = [], $callback) + { + $this->check(); + $url = $this->url;; + $apiKey = $this->apiKey; + $model = $this->model; + $chatId = $this->chatId; + $detail = $this->detail; + $headers = ["Authorization: Bearer $apiKey", 'Accept: application/json', 'Content-Type: application/json',]; + $post_msg_body = ['detail' => $detail, 'stream' => true,]; + if ($detail) { + $post_msg_body['detail'] = $detail; + } + if ($chatId) { + $post_msg_body['chatId'] = $chatId; + } + if ($model) { + $post_msg_body['model'] = $model; + } + if ($config) { + foreach ($config as $key => $val) { + $post_msg_body[$key] = $val; + } + } + if ($question) { + $this->messages[] = ["role" => "user", "content" => $question]; + } + $post_msg_body['messages'] = $this->messages; + $postData = json_encode($post_msg_body); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); + curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback); + curl_exec($ch); + } + + private function parseData($data) + { + if (@json_decode($data)->choices[0]->message->content) { + return json_decode($data)->choices[0]->message->content; + } + $data = str_replace('data: {', '{', $data); + $data = rtrim($data, "\n\n"); + if (strpos($data, 'data: [DONE]') !== false) { + return 'data: [DONE]'; + } else { + if (false !== strpos($data, "\n\n")) { + $exp_arr = explode("\n\n", $data); + $str = ''; + try { + for ($i = 0; $i < count($exp_arr) - 1; $i++) { + $jsondecode_arr = json_decode($exp_arr[$i], true); + $str .= $jsondecode_arr['choices'][0]['delta']['content']; + } + return $str; + } catch (\Exception $e) { + return $str; + } + } + $data = @json_decode($data, true); + if (!is_array($data)) { + return ''; + } + if ($data['choices'][0]['finish_reason'] == 'stop') { + return 'data: [DONE]'; + } elseif ($data['choices'][0]['finish_reason'] == 'length') { + return 'data: [CONTINUE]'; + } + return $data['choices'][0]['delta']['content'] ?? ''; + } + } +} \ No newline at end of file diff --git a/digital_doctor/vendor/wanghua/general-utility-tools-php/src/html/Html.php b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/html/Html.php new file mode 100644 index 0000000..d0ccce0 --- /dev/null +++ b/digital_doctor/vendor/wanghua/general-utility-tools-php/src/html/Html.php @@ -0,0 +1,224 @@ +.*?<\/a>/"; + preg_match_all($reg,$html,$a_array); + return $a_array; + } + + /** + * desc:提取div标签 + * author:wh + * @param string $html + * @return null + */ + function getDiv(string $html){ + $a_array = null; + $reg="/
.*?<\/div>/"; + preg_match_all($reg,$html,$a_array); + return $a_array; + } + /** + * desc:提取img标签 + * author:wh + * @param string $html + * @return null + */ + function getImg(string $html){ + $a_array = null; + $reg="/.*?<\/img>/"; + preg_match_all($reg,$html,$a_array); + return $a_array; + } + /** + * desc:提取span标签 + * author:wh + * @param string $html + * @return null + */ + function getSpan(string $html){ + $a_array = null; + $reg="/.*?<\/span>/"; + preg_match_all($reg,$html,$a_array); + return $a_array; + } + /** + * desc:提取ul标签 + * author:wh + * @param string $html + * @return null + */ + function getUl(string $html){ + $a_array = null; + $reg="/