From dd98a98b57154df97042e01f68182162a0bbb570 Mon Sep 17 00:00:00 2001 From: zhaocheng <578322713@qq.com> Date: Mon, 22 Feb 2021 20:46:11 +0800 Subject: [PATCH] first commit --- .gitignore | 8 + .travis.yml | 42 + CHANGELOG.md | 927 ++++++++++ LICENSE.txt | 32 + README.md | 52 +- app/.htaccess | 1 + app/AppService.php | 22 + app/BaseController.php | 182 ++ app/ExceptionHandle.php | 58 + app/Request.php | 8 + app/common.php | 11 + app/controller/Crontab.php | 86 + app/controller/Index.php | 498 ++++++ app/controller/Index.php.bak | 498 ++++++ app/controller/Task.php | 615 +++++++ app/controller/Task.php.bak | 605 +++++++ app/event.php | 17 + app/jobs/DelayQueue.php | 41 + app/middleware.php | 10 + app/model/CarInfoT.php | 17 + app/model/CrontabT.php | 24 + app/model/ExportLogT.php | 12 + app/model/ExportLogT.php.bak | 0 app/model/JobsT.php | 10 + app/model/PeerPhoneT.php | 14 + app/model/RepeatFrameT.php | 14 + app/provider.php | 9 + app/service.php | 9 + app/view/index/edit.html | 170 ++ app/view/index/edit.html.bak | 170 ++ app/view/index/index.html | 384 ++++ app/view/index/index.html.bak | 365 ++++ app/view/public/base.html | 10 + app/view/public/header.html | 12 + app/view/public/header.html.bak | 12 + app/view/public/layout.html | 38 + app/view/public/script.html | 4 + app/view/task/index.html | 449 +++++ app/view/task/index.html.bak | 444 +++++ build.php | 26 + composer.json | 54 + composer.lock | 1557 +++++++++++++++++ config/app.php | 34 + config/cache.php | 29 + config/console.php | 11 + config/cookie.php | 18 + config/database.php | 62 + config/filesystem.php | 24 + config/lang.php | 25 + config/log.php | 45 + config/middleware.php | 8 + config/queue.php | 21 + config/route.php | 45 + config/session.php | 19 + config/template.php | 35 + config/trace.php | 10 + config/view.php | 25 + extend/.gitignore | 2 + public/.htaccess | 8 + public/favicon.ico | Bin 0 -> 1150 bytes public/index.php | 24 + public/robots.txt | 2 + public/router.php | 19 + public/static/.gitignore | 2 + route/app.php | 17 + route/route.php | 21 + .../sess_f0c35153899e626149d7aa338fcf92c5 | 1 + .../temp/2c7bddf2602390fe3491ea487d866ef2.php | 433 +++++ .../temp/4a1403173de2fcfc7cfff92a06a360dc.php | 499 ++++++ .../temp/dc3e3ddb370b0b9564cb52310d05c516.php | 185 ++ think | 10 + view/README.md | 1 + 更新.bat | 1 + 73 files changed, 9152 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 LICENSE.txt create mode 100644 app/.htaccess create mode 100644 app/AppService.php create mode 100644 app/BaseController.php create mode 100644 app/ExceptionHandle.php create mode 100644 app/Request.php create mode 100644 app/common.php create mode 100644 app/controller/Crontab.php create mode 100644 app/controller/Index.php create mode 100644 app/controller/Index.php.bak create mode 100644 app/controller/Task.php create mode 100644 app/controller/Task.php.bak create mode 100644 app/event.php create mode 100644 app/jobs/DelayQueue.php create mode 100644 app/middleware.php create mode 100644 app/model/CarInfoT.php create mode 100644 app/model/CrontabT.php create mode 100644 app/model/ExportLogT.php create mode 100644 app/model/ExportLogT.php.bak create mode 100644 app/model/JobsT.php create mode 100644 app/model/PeerPhoneT.php create mode 100644 app/model/RepeatFrameT.php create mode 100644 app/provider.php create mode 100644 app/service.php create mode 100644 app/view/index/edit.html create mode 100644 app/view/index/edit.html.bak create mode 100644 app/view/index/index.html create mode 100644 app/view/index/index.html.bak create mode 100644 app/view/public/base.html create mode 100644 app/view/public/header.html create mode 100644 app/view/public/header.html.bak create mode 100644 app/view/public/layout.html create mode 100644 app/view/public/script.html create mode 100644 app/view/task/index.html create mode 100644 app/view/task/index.html.bak create mode 100644 build.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/app.php create mode 100644 config/cache.php create mode 100644 config/console.php create mode 100644 config/cookie.php create mode 100644 config/database.php create mode 100644 config/filesystem.php create mode 100644 config/lang.php create mode 100644 config/log.php create mode 100644 config/middleware.php create mode 100644 config/queue.php create mode 100644 config/route.php create mode 100644 config/session.php create mode 100644 config/template.php create mode 100644 config/trace.php create mode 100644 config/view.php create mode 100644 extend/.gitignore create mode 100644 public/.htaccess create mode 100644 public/favicon.ico create mode 100644 public/index.php create mode 100644 public/robots.txt create mode 100644 public/router.php create mode 100644 public/static/.gitignore create mode 100644 route/app.php create mode 100644 route/route.php create mode 100644 runtime/session/sess_f0c35153899e626149d7aa338fcf92c5 create mode 100644 runtime/temp/2c7bddf2602390fe3491ea487d866ef2.php create mode 100644 runtime/temp/4a1403173de2fcfc7cfff92a06a360dc.php create mode 100644 runtime/temp/dc3e3ddb370b0b9564cb52310d05c516.php create mode 100644 think create mode 100644 view/README.md create mode 100644 更新.bat diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ede57e --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/.idea +/.vscode +/vendor +/public/export +/public/storage +/public/uploads +*.log +.env \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..36f7b6f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,42 @@ +sudo: false + +language: php + +branches: + only: + - stable + +cache: + directories: + - $HOME/.composer/cache + +before_install: + - composer self-update + +install: + - composer install --no-dev --no-interaction --ignore-platform-reqs + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . + - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" + - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . + +script: + - php think unit + +deploy: + provider: releases + api_key: + secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= + file: + - ThinkPHP_Core.zip + - ThinkPHP_Full.zip + skip_cleanup: true + on: + tags: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e320da4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,927 @@ +## V5.1.39 LTS(2019-11-18) + +本次更新为常规更新,主要包括: + +* 修正`memcached`驱动 +* 改进`HasManyThrough`关联查询 +* 改进`Request`类`isJson`方法 +* 改进关联查询 +* 改进`redis`驱动 +* 增加 Model类`getWhere`方法对复合主键的支持 +* 改进`newQuery`方法 +* 改进闭包查询的参数绑定 +* 修正`Validate` +* 修复某些情况下URL会多一个冒号 +* 调整composer.json +* 修复使用`Cache::clear()`时,报错缓存文件不存在问题 +* 使用File类的unlink方法进行文件删除 +* 改进`paraseData`方法 +* 修正image验证方法 +* 改进Url生成 +* 改进空操作对数字的支持 +* 改进一处PHP7.4兼容性问题 + +## V5.1.38 LTS(2019-8-8) + +本次更新为常规更新,主要包括: + +* `Request`类增加`isJson`方法 +* 改进浮点型查询 +* 修正关联查询关联外键为空的查询错误 +* 远程一对多支持关联统计和预载入查询 +* 远程一对多关联支持`has`/`hasWhere`查询 +* 优化`parseIn`解析 +* 改进`parseLike`查询 +* 改进Url生成 +* 改进模型的`toArray`方法 +* 修正`notIn`查询 +* 改进`JSON`字段查询 +* 改进Controller类`display`/`fetch`方法返回`ViewResponse`对象 +* 改进`param`方法 +* 改进`mysql`驱动`getExplain`方法 +* 改进时间查询 +* 改进模型关联的`has`/`hasWhere`方法对软删除的支持 +* 修正社区反馈的BUG + +## V5.1.37 LTS(2019-5-26) + +本次更新为常规更新,主要更新如下: + +* 改进关联数据更新 +* 修正关联动态获取器 +* 改进`redis`驱动 +* 修复验证规则里面出现二维数组时的错误 +* 改进跨域请求支持 +* 完善模型`hidden`方法对关联属性的支持 +* 改进`where`查询方法传入`Query`对象的支持`bind`数据 +* 改进数据集对象的`load`方法 +* 修正缓存类`clear`方法对`tag`的支持 + +## V5.1.36 LTS(2019-4-28) + +本次更新为常规更新,主要更新如下: + +* 修正`chunk`方法一处异常抛出的错误 +* 修正模型输出的`visible` +* 改进环境变量加载 +* 改进命令行日志的`level`配置支持 +* 修复设置有缓存前缀时,无法清空缓存标签的问题 +* HasMony对象`saveAll`方法兼容`Collection`格式参数格式 +* 修正`whereOr`查询使用字符串的问题 +* 改进`dateFormat`设置对写入数据的影响 +* 修正查询缓存 +* 记住指定的跳转地址 +* 改进软删除 +* 改进聚合查询SQL去除limit 1 +* 改进缓存驱动 + +## V5.1.35 LTS(2019-3-2) + +本次主要为常规更新,修正了一些反馈的问题。 + +* 修正验证类自定义验证方法执行两次的问题 +* 模型增加`isEmpty`方法用于判断是否空模型 +* 改进获取器对`append`的支持 +* 修正一对多关联的`withCount`自关联问题 +* facade类注释调整 +* 改进关联属性的`visible`和`hidden`判断 +* 修正路由分组的`MISS`路由 +* 改进pgsql.sql + +## V5.1.34 LTS(2019-1-30) + +本次更新为常规更新,修正了一些反馈的问题。 + +* 改进Request类的`has`方法,支持`patch` +* 改进`unique`验证的多条件支持 +* 修复自定义上传验证,检测文件大小 +* 改进`in`查询支持表达式 +* 改进路由的`getBind`方法 +* 改进验证类的错误信息获取 +* 改进`response`助手函数默认值 +* 修正mysql的`regexp`查询 +* 改进模型类型强制转换写入对`Expression`对象的支持 + +## V5.1.33 LTS(2019-1-16) + +* 修复路由中存在多个相同替换的正则BUG +* 修正whereLike查询 +* join方法支持参数绑定 +* 改进union方法 +* 修正多对多关联的attach方法 +* 改进验证类的正则规则自定义 +* 改进Request类method方法 +* 改进File日志类型的CLI日志写入 +* 改进文件日志time_format配置对JSON格式的支持 + +## V5.1.32 LTS(2018-12-24) + +本次主要为常规更新,修正了一些反馈的问题。 + + +* 改进多对多关联的`attach`方法 +* 改进聚合查询的`field`处理 +* 改进关联的`save`方法 +* 修正模型`exists`方法返回值 +* 改进时间字段写入和输出 +* 改进控制器中间件的调用 +* 改进路由变量替换的性能 +* 改进缓存标签的处理机制 + +## V5.1.31 LTS (2018-12-9) + +本次版本包含一个安全更新,建议升级。 + +* 改进`field`方法 +* 改进`count`方法返回类型 +* `download`函数增加在浏览器中显示文件功能 +* 修正多对多模型的中间表数据写入 +* 改进`sqlsrv`驱动支持多个Schemas模式查询 +* 统一助手函数与\think\response\Download函数文件过期时间 +* 完善关联模型的`save`方法 增加`make`方法仅创建对象不保存 +* 修改条件表达式对静态变量的支持 +* 修正控制器名获取 +* 改进view方法的`field`解析 + +## V5.1.30 LTS(2018-11-30) + +该版本为常规更新,修正了一些社区反馈的问题。 + +主要更新如下: + +* 改进查询类的`execute`方法 +* 判断路由规则定义添加对请求类型的判断 +* 修复`orderRaw`异常 +* 修正 `optimize:autoload`指令 +* 改进软删除的`destroy`方法造成重复执行事件的问题 +* 改进验证类对扩展验证规则 始终验证 不管是否`require` +* 修复自定义验证`remove`所有规则的异常 +* 改进时间字段的自动写入支持微秒数据 +* 改进`Connection`类的`getrealsql`方法 +* 修正`https`地址的URL生成 +* 修复 `array_walk_recursive` 在低于PHP7.1消耗内部指针问题 +* 改进手动参数绑定使用 +* 改进聚合查询方法的`field`参数支持`Expression` + +## V5.1.29 LTS(2018-11-11) + +该版本主要改进了参数绑定的解析问题和提升性能,并修正了一些反馈的问题。 + +* 改进手动参数绑定 +* 修正MISS路由的分组参数无效问题 +* 行为支持对象的方法 +* 修正全局查询范围 +* 改进`belongsto`关联的`has`方法 +* 改进`hasMany`关联 +* 改进模型观察者多次注册的问题 +* 改进`query`类的默认查询参数处理 +* 修正`parseBetween`解析方法 +* 改进路由地址生成的本地域名支持 +* 改进参数绑定的实际URL解析性能 +* 改进`Env`类的`getEnv`和`get`方法 +* 改进模板缓存的生成优化 +* 修复验证类的多语言支持 +* 修复自定义场景验证`remove`规则异常 +* File类添加是否自动补全扩展名的选项 +* 改进`strpos`对子串是否存在的判断 +* 修复`choice`无法用值选择第一个选项问题 +* 验证器支持多维数组取值验证 +* 改进解析`extend`和`block`标签的正则 + +## V5.1.28 LTS(2018-10-29) + +该版本主要修正了上一个版本存在的一些问题,并改进了关联查询 + +* 改进聚合查询方法的字段支持DISTINCT +* 改进定义路由后url函数的端口生成 +* 改进控制器中间件对`swoole`等的支持 +* 改进Log类`save`方法 +* 改进验证类的闭包验证参数 +* 多对多关联支持指定中间表数据的名称 +* 关联聚合查询支持闭包方式指定聚合字段 +* 改进Lang类`get`方法 +* 多对多关联增加判断关联数据是否存在的方法 +* 改进关联查询使用`fetchsql`的情况 +* 改进修改器的是否已经执行判断 +* 增加`afterWith`和`beforeWith`验证规则 用于比较日期字段 + +## V5.1.27 LTS(2018-10-22) + +该版本主要修正了路由绑定的参数,改进了修改器的执行多次问题,并正式宣布为LTS版本! + + +* 修正路由绑定的参数丢失问题 +* 修正路由别名的参数获取 +* 改进修改器会执行多次的问题 + +## V5.1.26(2018-10-12) + +该版本主要修正了上一个版本的一些问题,并改进了全局查询范围的支持,同时包含了一个安全更新。 + + +* 修正单一模块下注解路由无效的问题 +* 改进数据库的聚合查询的字段处理 +* 模型类增加`globalScope`属性定义 用于指定全局的查询范围 +* 模型的`useGlobalScope`方法支持传入数组 用于指定当前查询需要使用的全局查询范围 +* 改进数据集的`order`方法对数字类型的支持 +* 修正上一个版本`order`方法解析的一处BUG +* 排序字段不合法或者错误的时候抛出异常 +* 改进`Request`类的`file`方法对上传文件的错误判断 + +## V5.1.25(2018-9-21) + +该版本主要改进了查询参数绑定的性能和对浮点型的支持,以及一些细节的完善。 + +* 修正一处命令行问题 +* 改进`Socketlog`日志驱动,支持自定义默认展开日志类别 +* 修正`MorphMany`一处bug +* 跳转到上次记住的url,并支持默认值 +* 改进模型的异常提示 +* 改进参数绑定对浮点型的支持 +* 改进`order`方法解析 +* 改进`json`字段数据的自动编码 +* 改进日志`log_write`可能造成的日志写入死循环 +* Log类增加`log_level`行为标签位置,用于对某个类型的日志进行处理 +* Route类增加`clear`方法清空路由规则 +* 分布式数据库配置支持使用数组 +* 单日志文件也支持`max_files`参数 +* 改进查询参数绑定的性能 +* 改进别名路由的URL后缀参数检测 +* 控制器前置方法和控制器中间件的`only`和`except`定义不区分大小写 + +## V5.1.24(2018-9-5) + +该版本主要增加了命令行的表格输出功能,并增加了查看路由定义的指令,以及修正了社区的一些反馈问题。 + +* 修正`Request`类的`file`方法 +* 修正路由的`cache`方法 +* 修正路由缓存的一处问题 +* 改进上传文件获取的异常处理 +* 改进`fetchCollection`方法支持传入数据集类名 +* 修正多级控制器的注解路由生成 +* 改进`Middleware`类`clear`方法 +* 增加`route:list`指令用于[查看定义的路由](752690) 并支持排序 +* 命令行增加`Table`输出类 +* `Command`类增加`table`方法用于输出表格 +* 改进搜索器查询方法支持别名定义 +* 命令行配置增加`auto_path`参数用于定义自动载入的命令类路径 +* 增加`make:command`指令用于[快速生成指令](354146) +* 改进`make:controller`指令对操作方法后缀的支持 +* 改进命令行的定义文件支持索引数组 用于指令对象的惰性加载 +* 改进`value`和`column`方法对后续查询结果的影响 +* 改进`RuleName`类的`setRule`方法 + +## V5.1.23(2018-8-23) + +该版本主要改进了数据集对象的处理,增加了`findOrEmpty`方法,并且修正了一些社区反馈的BUG。 + +* 数据集类增加`diff`/`intersect`方法用于获取差集和交集(默认根据主键值比较) +* 数据集类增加`order`方法支持指定字段排序 +* 数据集类增加`map`方法使用回调函数处理数据并返回新的数据集对象 +* Db增加`allowEmpty`方法允许`find`方法在没有数据的时候返回空数组或者空模型对象而不是null +* Db增加`findOrEmpty`方法 +* Db增加`fetchCollection`方法用于指定查询返回数据集对象 +* 改进`order`方法的数组方式解析,增强安全性 +* 改进`withSearch`方法,支持第三个参数传入字段前缀标识,用于多表查询字段搜索 +* 修正`optimize:route`指令开启类库后缀后的注解路由生成 +* 修正redis缓存及session驱动 +* 支持指定`Yaconf`的独立配置文件 +* 增加`yaconf`助手函数用于配置文件 + + +## V5.1.22(2018-8-9) + +该版本主要增加了模型搜索器和`withJoin`方法,完善了模型输出和对`Yaconf`的支持,修正了一些社区反馈的BUG。 + +* 改进一对一关联的`table`识别问题 +* 改进内置`Facade`类 +* 增加`withJoin`方法支持`join`方式的[一对一关联](一对一关联.md)查询 +* 改进`join`预载入查询的空数据问题 +* 改进`Config`类的`load`方法支持快速加载配置文件 +* 改进`execute`方法和事务的断线重连 +* 改进`memcache`驱动的`has`方法 +* 模型类支持定义[搜索器](搜索器.md)方法 +* 完善`Config`类对`Yaconf`的支持 +* 改进模型的`hidden/visible/append/withAttr`方法,支持在[查询前后调用](数组访问.md),以及支持数据集对象 +* 数据集对象增加`where`方法根据字段或者关联数据[过滤数据](模型数据集.md) +* 改进AJAX请求的`204`判断 + + +## V5.1.21(2018-8-2) + +该版本主要增加了下载响应对象和数组查询对象的支持,并修正了一些社区反馈的问题。 + +* 改进核心对象的无用信息调试输出 +* 改进模型的`isRelationAttr`方法判断 +* 模型类的`get`和`all`方法并入Db类 +* 增加[下载响应对象](文件下载.md)和`download`助手函数 +* 修正别名路由配置定义读取 +* 改进`resultToModel`方法 +* 修正开启类库后缀后的注解路由生成 +* `Response`类增加`noCache`快捷方法 +* 改进路由对象在`Swoole`/`Workerman`下面参数多次合并问题 +* 修正路由`ajax`/`pjax`参数后路由变量无法正确获取的问题 +* 增加清除中间件的方法 +* 改进依赖注入的参数规范自动识别(便于对接前端小写+下划线规范) +* 改进`hasWhere`的数组条件的字段判断 +* 增加[数组查询对象](高级查询.md)`Where`支持(喜欢数组查询的福音) +* 改进多对多关联的闭包支持 + +## V5.1.20(2018-7-25) + +该版本主要增加了Db和模型的动态获取器的支持,并修正了一些已知问题。 + +* Db类添加[获取器支持](703981) +* 支持模型及关联模型字段[动态定义获取器](354046) +* 动态获取器支持`JSON`字段 +* 改进路由的`before`行为执行(匹配后执行) +* `Config`类支持`Yaconf` +* 改进Url生成的端口问题 +* Request类增加`setUrl`和`setBaseUrl`方法 +* 改进页面trace的信息显示 +* 修正`MorphOne`关联 +* 命令行添加[查看版本指令](703994) + +## V5.1.19 (2018-7-13) + +该版本是一个小幅改进版本,针对`Swoole`和`Workerman`的`Cookie`支持做了一些改进,并修正了一些已知的问题。 + + +* 改进query类`delete`方法对软删除条件判断 +* 修正分表查询的软删除问题 +* 模型查询的时候同时传入`table`和`name`属性 +* 容器类增加`IteratorAggregate`和`Countable`接口支持 +* 路由分组支持对下面的资源路由统一设置`only/except/vars`参数 +* 改进Cookie类更好支持扩展 +* 改进Request类`post`方法 +* 改进模型自关联的自动识别 +* 改进Request类对`php://input`数据的处理 + + +## V5.1.18 (2018-6-30) + +该版本主要完善了对`Swoole`和`Workerman`的`HttpServer`运行支持,改进`Request`类,并修正了一些已知的问题。 + +* 改进关联`append`方法的处理 +* 路由初始化和检测方法分离 +* 修正`destroy`方法强制删除 +* `app_init`钩子位置移入`run`方法 +* `think-swoole`扩展更新到2.0版本 +* `think-worker`扩展更新到2.0版本 +* 改进Url生成的域名自动识别 +* `Request`类增加`setPathinfo`方法和`setHost`方法 +* `Request`类增加`withGet`/`withPost`/`withHeader`/`withServer`/`withCookie`/`withEnv`方法进行赋值操作 +* Route类改进`host`属性的获取 +* 解决注解路由配置不生效的问题 +* 取消Test日志驱动,改为使用`close`设置关闭全局日志写入 +* 修正路由的`response`参数 +* 修正204响应输出的判断 + +## V5.1.17 (2018-6-18) + +该版本主要增加了控制器中间件的支持,改进了路由功能,并且修正了社区反馈的一些问题。 + +* 修正软删除的`delete`方法 +* 修正Query类`Count`方法 +* 改进多对多`detach`方法 +* 改进Request类`Session`方法 +* 增加控制器中间件支持 +* 模型类增加`jsonAssoc`属性用于定义json数据是否返回数组 +* 修正Request类`method`方法的请求伪装 +* 改进静态路由的匹配 +* 分组首页路由自动完整匹配 +* 改进sqlsrv的`column`方法 +* 日志类的`apart_level`配置支持true自动生成对应类型的日志文件 +* 改进`204`输出判断 +* 修正cli下页面输出的BUG +* 验证类使用更高效的`ctype`验证机制 +* 改进Request类`cookie`方法 +* 修正软删除的`withTrashed`方法 +* 改进多态一对多的预载入查询 +* 改进Query类`column`方法的缓存读取 +* Query类增加`whereBetweenTimeField`方法 +* 改进分组下多个相同路由规则的合并匹配问题 +* 路由类增加`getRule`/`getRuleList`方法获取定义的路由 + +## V5.1.16 (2018-6-7) + +该版本主要修正了社区反馈的一些问题,并对Request类做了进一步规范和优化。 + +* 改进Session类的`boot`方法 +* App类的初始化方法可以单独执行 +* 改进Request类的`param`方法 +* 改进资源路由的变量替换 +* Request类增加`__isset`方法 +* 改进`useGlobalScope`方法对软删除的影响 +* 修正命令行调用 +* 改进Cookie类`init`方法 +* 改进多对多关联删除的返回值 +* 一对多关联写入支持`replace` +* 路由增加`filter`检测方法,用于通过请求参数检测路由是否匹配 +* 取消Request类`session/env/server`方法的`filter`参数 +* 改进关联的指定属性输出 +* 模型删除操作删除后不清空对象数据仅作标记 +* 调整模型的`save`方法返回值为布尔值 +* 修正Request类`isAjax`方法 +* 修正中间件的模块配置读取 +* 取消Request类的请求变量的设置功能 +* 取消请求变量获取的默认修饰符 +* Request类增加`setAction/setModule/setController`方法 +* 关联模型的`delete`方法调用Query类 +* 改进URL生成的域名识别 +* 改进URL检测对已定义路由的域名判断 +* 模型类增加`isExists`和`isForce`方法 +* 软删除的`destroy`和`restore`方法返回值调整为布尔值 + +## V5.1.15 (2018-6-1) + +该版本主要改进了路由缓存的性能和缓存方式设置,增加了JSON格式文件日志的支持,并修正了社区反馈的一些问题。 + +* 容器类增加`exists`方法 仅判断是否存在对象实例 +* 取消配置类的`autoload`方法 +* 改进路由缓存大小提高性能 +* 改进Dispatch类`init`方法 +* 增加`make:validate`指令生成验证器类 +* Config类`get`方法支持默认值参数 +* 修正字段缓存指令 +* 改进App类对`null`数据的返回 +* 改进模型类的`__isset`方法判断 +* 修正`Query`类的`withAggregate`方法 +* 改进`RuleItem`类的`setRuleName`方法 +* 修正依赖注入和参数的冲突问题 +* 修正Db类对第三方驱动的支持 +* 修正模型类查询对象问题 +* 修正File缓存驱动的`has`方法 +* 修正资源路由嵌套 +* 改进Request类对`$_SERVER`变量的读取 +* 改进请求缓存处理 +* 路由缓存支持指定单独的缓存方式和参数 +* 修正资源路由的中间件多次执行问题 +* 修正`optimize:config`指令 +* 文件日志支持`JSON`格式日志保存 +* 修正Db类`connect`方法 +* 改进Log类`write`方法不会自动写入之前日志 +* 模型的关联操作默认启用事务 +* 改进软删除的事件响应 + +## V5.1.14 (2018-5-18) + +该版本主要对底层容器进行了一些优化改进,并增加了路由缓存功能,可以进一步提升路由性能。 + +* 依赖注入的对象参数传入改进 +* 改进核心类的容器实例化 +* 改进日期字段的读取 +* 改进验证类的`getScene`方法 +* 模型的`create`方法和`save`方法支持`replace`操作 +* 改进`Db`类的调用机制 +* App类调整为容器类 +* 改进容器默认绑定 +* `Loader`类增加工厂类的实例化方法 +* 增加路由变量默认规则配置参数 +* 增加路由缓存设计 +* 错误处理机制改进 +* 增加清空路由缓存指令 + + +## V5.1.13 (2018-5-11) + +该版本主要增加了MySQL的XA事务支持,模型事件支持观察者,以及对Facade类的改进。 + +* 改进自动缓存 +* 改进Url生成 +* 修正数据缓存 +* 修正`value`方法的缓存 +* `join`方法和`view`方法的条件支持使用`Expression`对象 +* 改进驱动的`parseKey`方法 +* 改进Request类`host`方法和`domain`方法对端口的处理 +* 模型增加`withEvent`方法用于控制当前操作是否需要执行模型事件 +* 模型`setInc/setDec`方法支持更新事件 +* 模型添加`before_restore/after_restore`事件 +* 增加模型事件观察者 +* 路由增加`mobile`方法设置是否允许手机访问 +* 数据库XA事务支持 +* 改进索引数组查询对`IN`查询的支持 +* 修正`invokeMethod`方法 +* 修正空数据写入返回值的BUG +* redis驱动支持`predis` +* 改进`parseData`方法 +* 改进模块加载 +* App类初始化方法调整 +* 改进数组查询对表达式`Expression`对象支持 +* 改进闭包的依赖注入调用 +* 改进多对多关联的中间表模型更新 +* 增加容器中对象的自定义实例化 + +## V5.1.12 (2018-4-25) + +该版本主要改进了主从查询的及时性,并支持动态设置请求数据。 + +* 支持动态设置请求数据 +* 改进`comment`方法解析 +* 修正App类`__unset`方法 +* 改进url生成的域名绑定 +* 改进主从查询的及时性 +* 修正`value`的数据缓存功能 +* 改进分页类的集合对象方法调用 +* 改进Db类的代码提示 +* SQL日志增加主从标记 + +## V5.1.11 (2018-4-19) + +该版本为安全和修正版本,改进了JSON查询的参数绑定问题和容器类对象实例获取,并包含一处可能的安全隐患,建议更新。 + +* 支持指定JSON数据查询的字段类型 +* 修正`selectInsert`方法 +* `whereColumn`方法支持数组方式 +* 改进容器类`make`方法 +* 容器类`delete`方法支持数组 +* 改进`composer`自动加载 +* 改进模板引擎 +* 修正`like`查询的一处安全隐患 + +## V5.1.10 (2018-4-16) + +该版本为修正版本,修正上一个版本的一些BUG,并增强了`think clear`指令。 + +* 改进`orderField`方法 +* 改进`exists`查询 +* 修改cli模式入口文件位置计算 +* 修正`null`查询 +* 改进`parseTime`方法 +* 修正关联预载入查询 +* 改进`mysql`驱动 +* 改进`think clear`指令 支持 `-c -l -r `选项 +* 改进路由规则对`/`结尾的支持 + +## V5.1.9 (2018-4-12) + +该版本主要是一些改进和修正,并包含一个安全更新,是一个推荐更新版本。 + +* 默认模板渲染规则支持配置保持操作方法名 +* 改进`Request`类的`ip`方法 +* 支持模型软删除字段的默认值定义 +* 改进路由变量规则对中文的支持 +* 使用闭包查询的时候使用`cache(true)` 抛出异常提示 +* 改进`Loader`类`loadComposerAutoloadFiles`方法 +* 改进查询方法安全性 +* 修正路由地址中控制器名驼峰问题 +* 调整上一个版本的`module_init`和`app_begin`的钩子顺序问题 +* 改进CLI命令行执行的问题 +* 修正社区反馈的其它问题 + +## V5.1.8 (2018-4-5) + +该版本主要改进了中间件的域名和模块支持,并同时修正了几个已知问题。 + +* 增加`template.auto_rule` 参数设置默认模板渲染的操作名自动转换规则 +* 默认模板渲染规则改由视图驱动实现 +* 修正路由标识定义 +* 修正控制器路由方法 +* 改进Request类`ip`方法支持自定义代理IP参数 +* 路由注册中间件支持数组方式别名 +* 改进命令行执行下的`composer`自动加载 +* 添加域名中间件注册支持 +* 全局中间件支持模块定义文件 +* Log日志配置支持`close`参数可以全局关闭日志写入 +* 中间件方法中捕获`HttpResponseException`异常 +* 改进中间件的闭包参数传入 +* 改进分组路由的延迟解析 +* 改进URL生成对域名绑定的支持 +* 改进文件缓存和文件日志驱动的并发支持 + +## V5.1.7 (2018-3-28) + +该版本主要修正了路由的一些问题,并改进了查询的安全性。 + +* 支持`middleware`配置文件预先定义中间件别名方便路由调用 +* 修正资源路由 +* 改进`field`方法 自动识别`fieldRaw` +* 增加`Expression`类 +* Query类增加`raw`方法 +* Query类的`field`/ `order` 和` where`方法都支持使用`raw`表达式查询 +* 改进`inc/dec`查询 支持批量更新 +* 改进路由分组 +* 改进Response类`create`方法 +* 改进composer自动加载 +* 修正域名路由的`append`方法 +* 修正操作方法的初始化方法获取不到问题 + +## V5.1.6 (2018-3-26) + +该版本主要改进了路由规则的匹配算法,大幅提升了路由性能。并正式引入了中间件的支持,可以在路由中定义或者全局定义。另外包含了一个安全更新,是一个建议更新版本。 + +* 改进URL生成对路由`ext`方法的支持 +* 改进查询缓存对不同数据库相同表名的支持 +* 改进composer自动加载的性能 +* 改进空路由变量对默认参数的影响 +* mysql的`json`字段查询支持多级 +* Query类增加`option`方法 +* 优化路由匹配 +* 修复验证规则数字键名丢失问题 +* 改进路由Url生成 +* 改进一对一关联预载入查询 +* Request类增加`rootDomain`方法 +* 支持API资源控制器生成 `make:controller --api` +* 优化Template类的标签解析 +* 容器类增加删除和清除对象实例的方法 +* 修正MorphMany关联的`eagerlyMorphToMany`方法一处错误 +* Container类的异常捕获改进 +* Domain对象支持`bind`方法 +* 修正分页参数 +* 默认模板的输出规则不受URL影响 +* 注解路由支持多级控制器 +* Query类增加`getNumRows`方法获取前次操作影响的记录数 +* 改进查询条件的性能 +* 改进模型类`readTransform`方法对序列化类型的处理 +* Log类增加`close`方法可以临时关闭当前请求的日志写入 +* 文件日志方式增加自动清理功能(设置`max_files`参数) +* 修正Query类的`getPk`方法 +* 修正模板缓存的布局开关问题 +* 修正Query类`select`方法的缓存 +* 改进input助手函数 +* 改进断线重连的信息判断 +* 改进正则验证方法 +* 调整语言包的加载顺序 放到`app_init`之前 +* controller类`fetch`方法改为`final` +* 路由地址中的变量支持使用``方式 +* 改进XMLResponse 支持传入编码过的xml内容 +* 修正Query类`view`方法的数组表名支持 +* 改进路由的模型闭包绑定 +* 改进分组变量规则的继承 +* 改进`cli-server`模式下的`composer`自动加载 +* 路由变量规则异常捕获 +* 引入中间件支持 +* 路由定义增加`middleware`方法 +* 增加生成中间件指令`make:middleware` +* 增加全局中间件定义支持 +* 改进`optimize:config`指令对全局中间件的支持 +* 改进config类`has`方法 +* 改进时间查询的参数绑定 +* 改进`inc/dec/exp`查询的安全性 + + +## V5.1.5 (2018-1-31) + +该版本主要增强了数据库的JSON查询,并支持JSON字段的聚合查询,改进了一些性能问题,修正了路由的一些BUG,主要更新如下: + +* 改进数据集查询对`JSON`数据的支持 +* 改进聚合查询对`JSON`字段的支持 +* 模型类增加`getOrFail`方法 +* 改进数据库驱动的`parseKey`方法 +* 改进Query类`join`方法的自关联查询 +* 改进数据查询不存在不生成查询缓存 +* 增加`run`命令行指令启动内置服务器 +* `Request`类`pathinfo`方法改进对`cli-server`支持 +* `Session`类增加`use_lock`配置参数设置是否启用锁机制 +* 优化`File`缓存自动生成空目录的问题 +* 域名及分组路由支持`append`方法传递隐式参数 +* 改进日志的并发写入问题 +* 改进`Query`类的`where`方法支持传入`Query`对象 +* 支持设置单个日志文件的文件名 +* 修正路由规则的域名条件约束 +* `Request`类增加`subDomain`方法用于获取当前子域名 +* `Response`类增加`allowCache`方法控制是否允许请求缓存 +* `Request`类增加`sendData`方法便于扩展 +* 改进`Env`类不依赖`putenv`方法 +* 改进控制台`trace`显示错误 +* 改进`MorphTo`关联 +* 改进完整路由匹配后带斜线访问出错的情况 +* 改进路由的多级分组问题 +* 路由url地址生成支持多级分组 +* 改进路由Url生成的`url_convert`参数的影响 +* 改进`miss`和`auto`路由内部解析 +* 取消预载入关联查询缓存功能 + +## V5.1.4 (2018-1-19) + +该版本主要增强了数据库和模型操作,主要更新如下: + +* 支持设置 `deleteTime`属性为`false` 关闭软删除 +* 模型增加`getError`方法 +* 改进Query类的`getTableFields`/`getFieldsType`方法 支持表名自动获取 +* 模型类`toCollection`方法增加参数指定数据集类 +* 改进`union`查询 +* 关联预载入`with`方法增加缓存参数 +* 改进模型类的`get`和`all`方法的缓存 支持关联缓存 +* 支持`order by field`操作 +* 改进`insertAll`分批写入 +* 改进`json`字段数据支持 +* 增加JSON数据的模型对象化操作 +* 改进路由`ext`参数检测 +* 修正`rule`方法的`method`参数使用 `get|post` 方式注册路由的问题 + +## V5.1.3 (2018-1-12) + +该版本主要改进了路由及调整函数加载顺序,主要更新如下: + +* 增加`env`助手函数; +* 增加`route`助手函数; +* 增加视图路由方法; +* 增加路由重定向方法; +* 路由默认区分最后的目录斜杆(支持设置不区分); +* 调整公共文件和配置文件的加载顺序(可以在配置文件中直接使用助手函数); +* 视图类增加`filter`方法设置输出过滤; +* `view`助手函数增加`filter`参数; +* 改进缓存生成指令; +* Session类的`get`方法支持获取多级; +* Request类`only`方法支持指定默认值; +* 改进路由分组; +* 修正使用闭包查询的时候自动数据缓存出错的情况; +* 废除`view_filter`钩子位置; +* 修正分组下面的资源路由; +* 改进session驱动; + +## V5.1.2 (2018-1-8) + +该版本改进了配置类及数据库类,主要更新如下: + +* 修正嵌套路由分组; +* 修正自定义模板标签界定符后表达式语法出错的情况; +* 修正自关联的多次调用问题; +* 修正数组查询的`null`条件查询; +* 修正Query类的`order`及`field`的一处可能的BUG; +* 配置参数设置支持三级; +* 配置对象支持`ArrayAccess`; +* App类增加`path`方法用于设置应用目录; +* 关联定义增加`selfRelation`方法用于设置是否为自关联; + +## V5.1.1 (2018-1-3) + +修正一些反馈的BUG,包括: + +* 修正Cookie类存取数组的问题 +* 修正Controller的`fetch`方法 +* 改进跨域请求 +* 修正`insertAll`方法 +* 修正`chunk`方法 + +## V5.1.0 (2018-1-1) + +主要更新如下: + +* 增加注解路由支持 +* 路由支持跨域请求设置 +* 增加`app_dispatch`钩子位置 +* 修正多对多关联的`detach`方法 +* 修正软删除的`destroy`方法 +* Cookie类`httponly`参数默认为false +* 日志File驱动增加`single`参数配置记录同一个文件(不按日期生成) +* 路由的`ext`和`denyExt`方法支持不传任何参数 +* 改进模型的`save`方法对`oracle`的支持 +* Query类的`insertall`方法支持配合`data`和`limit`方法 +* 增加`whereOr`动态查询支持 +* 日志的ip地址记录改进 +* 模型`saveAll`方法支持`isUpdate`方法 +* 改进`Pivot`模型的实例化操作 +* 改进Model类的`data`方法 +* 改进多对多中间表模型类 +* 模型增加`force`方法强制更新所有数据 +* Hook类支持设置入口方法名称 +* 改进验证类 +* 改进`hasWhere`查询的数据重复问题 +* 模型的`saveall`方法返回数据集对象 +* 改进File缓存的`clear`方法 +* 缓存添加统一的序列化机制 +* 改进泛三级域名的绑定 +* 改进泛域名的传值和取值 +* Request类增加`panDomain`方法 +* 改进废弃字段判断 +* App类增加`create`方法用于实例化应用类库 +* 容器类增加`has`方法 +* 改进多数据库切换连接 +* 改进断线重连的异常捕获 +* 改进模型类`buildQuery`方法 +* Query类增加`unionAll`方法 +* 关联统计功能增强(支持Sum/Max/Min/Avg) +* 修正延迟写入 +* chunk方法支持复合主键 +* 改进JSON类型的写入 +* 改进Mysql的insertAll方法 +* Model类`save`方法改进复合主键包含自增的情况 +* 改进Query类`inc`和`dec`方法的关键字处理 +* File缓存inc和dec方法保持原来的有效期 +* 改进redis缓存的有效期判断 +* 增加checkRule方法用于单独数据的多个验证规则 +* 修正setDec方法的延迟写入 +* max和min方法增加force参数 +* 二级配置参数区分大小写 +* 改进join方法自关联的问题 +* 修正关联模型自定义表名的情况 +* Query类增加getFieldsType和getTableFields方法 +* 取消视图替换功能及view_replace_str配置参数 +* 改进域名绑定模块后的额外路由规则问题 +* 改进mysql的insertAll方法 +* 改进insertAll方法写入json字段数据的支持 +* 改进redis长连接多编号库的情况 + +## RC3版本(2017-11-6) + +主要更新如下: + +* 改进redis驱动的`get`方法 +* 修正Query类的`alias`方法 +* `File`类错误信息支持多语言 +* 修正路由的额外参数解析 +* 改进`whereTime`方法 +* 改进Model类`getAttr`方法 +* 改进App类的`controller`和`validate`方法支持多层 +* 改进`HasManyThrough`类 +* 修正软删除的`restore`方法 +* 改进`MorpthTo`关联 +* 改进数据库驱动类的`parseKey`方法 +* 增加`whereField`动态查询方法 +* 模型增加废弃字段功能 +* 改进路由的`after`行为检查和`before`行为机制 +* 改进路由分组的检查 +* 修正mysql的`json`字段查询 +* 取消Connection类的`quote`方法 +* 改进命令行的支持 +* 验证信息支持多语言 +* 修正路由模型绑定 +* 改进参数绑定类型对枚举类型的支持 +* 修正模板的`{$Think.version} `输出 +* 改进模板`date`函数解析 +* 改进`insertAll`方法支持分批执行 +* Request类`host`方法支持反向代理 +* 改进`JumpResponse`支持区分成功和错误模板 +* 改进开启类库后缀后的关联外键自动识别问题 +* 修正一对一关联的JOIN方式预载入查询问题 +* Query类增加`hidden`方法 + +## RC2版本(2017-10-17) + +主要更新如下: + +* 修正视图查询 +* 修正资源路由 +* 修正`HasMany`关联 修正`where`方法的闭包查询 +* 一对一关联绑定属性到父模型后 关联属性不再保留 +* 修正应用的命令行配置文件读取 +* 改进`Connection`类的`getCacheKey`方法 +* 改进文件上传的非法图像异常 +* 改进验证类的`unique`规则 +* Config类`get`方法支持获取一级配置 +* 修正count方法对`fetchSql`的支持 +* 修正mysql驱动对`socket`支持 +* 改进Connection类的`getRealSql`方法 +* 修正`view`助手函数 +* Query类增加`leftJoin` `rightJoin` 和 `fullJoin`方法 +* 改进app_namespace的获取 +* 改进`append`方法对一对一`bind`属性的支持 +* 改进关联的`saveall`方法的返回值 +* 路由标识设置异常修复 +* 改进Route类`rule`方法 +* 改进模型的`table`属性设置 +* 改进composer autofile的加载顺序 +* 改进`exception_handle`配置对闭包的支持 +* 改进app助手函数增加参数 +* 改进composer的加载路径判断 +* 修正路由组合变量的URL生成 +* 修正路由URL生成 +* 改进`whereTime`查询并支持扩展规则 +* File类的`move`方法第二个参数支持`false` +* 改进Config类 +* 改进缓存类`remember`方法 +* 惯例配置文件调整 Url类当普通模式参数的时候不做`urlencode`处理 +* 取消`ROOT_PATH`和`APP_PATH`常量定义 如需更改应用目录 自己重新定义入口文件 +* 增加`app_debug`的`Env`获取 +* 修正泛域名绑定 +* 改进查询表达式的解析机制 +* mysql增加`regexp`查询表达式 支持正则查询 +* 改进查询表达式的异常判断 +* 改进model类的`destroy`方法 +* 改进Builder类 取消`parseValue`方法 +* 修正like查询的参数绑定问题 +* console和start文件移出核心纳入应用库 +* 改进Db类主键删除方法 +* 改进泛域名绑定模块 +* 取消`BIND_MODULE`常量 改为在入口文件使用`bind`方法设置 +* 改进数组查询 +* 改进模板渲染的异常处理 +* 改进控制器基类的架构方法参数 +* 改进Controller类的`success`和`error`方法 +* 改进对浏览器`JSON-Handle`插件的支持 +* 优化跳转模板的移动端显示 +* 修正模型查询的`chunk`方法对时间字段的支持 +* 改进trace驱动 +* Collection类增加`push`方法 +* 改进Redis Session驱动 +* 增加JumpResponse驱动 + + +## RC1(2017-9-8) + +主要新特性为: + +* 引入容器和Facade支持 +* 依赖注入完善和支持更多场景 +* 重构的(对象化)路由 +* 配置和路由目录独立 +* 取消系统常量 +* 助手函数增强 +* 类库别名机制 +* 模型和数据库增强 +* 验证类增强 +* 模板引擎改进 +* 支持PSR-3日志规范 +* RC1版本取消了5.0多个字段批量数组查询的方式 \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..574a39c --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,32 @@ + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 +版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) +All rights reserved。 +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +Apache Licence是著名的非盈利开源组织Apache采用的协议。 +该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, +允许代码修改,再作为开源或商业软件发布。需要满足 +的条件: +1. 需要给代码的用户一份Apache Licence ; +2. 如果你修改了代码,需要在被修改的文件中说明; +3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 +带有原来代码中的协议,商标,专利声明和其他原来作者规 +定需要包含的说明; +4. 如果再发布的产品中包含一个Notice文件,则在Notice文 +件中需要带有本协议内容。你可以在Notice中增加自己的 +许可,但不可以表现为对Apache Licence构成更改。 +具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index db6113b..7661c30 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,52 @@ -# excel_handle +ThinkPHP 6.0 +=============== +> 运行环境要求PHP7.1+。 + +## 主要新特性 + +* 采用`PHP7`强类型(严格模式) +* 支持更多的`PSR`规范 +* 原生多应用支持 +* 更强大和易用的查询 +* 全新的事件系统 +* 模型事件和数据库事件统一纳入事件系统 +* 模板引擎分离出核心 +* 内部功能中间件化 +* SESSION/Cookie机制改进 +* 对Swoole以及协程支持改进 +* 对IDE更加友好 +* 统一和精简大量用法 + +## 安装 + +~~~ +composer create-project topthink/think tp 6.0.* +~~~ + +如果需要更新框架使用 +~~~ +composer update topthink/framework +~~~ + +## 文档 + +[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content) + +## 参与开发 + +请参阅 [ThinkPHP 核心框架包](https://github.com/top-think/framework)。 + +## 版权信息 + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 + +本项目包含的第三方源码和二进制文件之版权信息另行标注。 + +版权所有Copyright © 2006-2020 by ThinkPHP (http://thinkphp.cn) + +All rights reserved。 + +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +更多细节参阅 [LICENSE.txt](LICENSE.txt) diff --git a/app/.htaccess b/app/.htaccess new file mode 100644 index 0000000..3418e55 --- /dev/null +++ b/app/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/app/AppService.php b/app/AppService.php new file mode 100644 index 0000000..96556e8 --- /dev/null +++ b/app/AppService.php @@ -0,0 +1,22 @@ +app = $app; + $this->request = $this->app->request; + $this->view = $this->app->view; + + // 控制器初始化 + $this->initialize(); + } + + // 初始化 + protected function initialize() + { + if($this->request->isAjax() && $this->request->action() != 'login'){ + $lastAction = session('last_action'); + if (session('login_time') === null || time() - $lastAction > 600) { + session('login_time', null); + $this->json_data['code'] = '-1'; + $this->json_data['msg'] = '登录超时'; + throw new HttpResponseException(json($this->json_data)); + }else if($this->request->action() != 'process'){ + session('last_action', time()); + } + } + + $this->layui_data = [ + 'code' => 0, + 'msg' => '请求成功', + 'count' => 0, + 'data' => [], + ]; + $this->json_data = ['code' => 1, 'msg' => '操作成功']; + } + + /** + * 验证数据 + * @access protected + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @return array|string|true + * @throws ValidateException + */ + protected function validate(array $data, $validate, array $message = [], bool $batch = false) + { + if (is_array($validate)) { + $v = new Validate(); + $v->rule($validate); + } else { + if (strpos($validate, '.')) { + // 支持场景 + [$validate, $scene] = explode('.', $validate); + } + $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); + $v = new $class(); + if (!empty($scene)) { + $v->scene($scene); + } + } + + $v->message($message); + + // 是否批量验证 + if ($batch || $this->batchValidate) { + $v->batch(true); + } + + return $v->failException(true)->check($data); + } + + /** + * 加载模板输出 + * @access protected + * @param string $template 模板文件名 + * @param array $vars 模板输出变量 + * @return string + * @throws Exception + */ + protected function fetch($template = '', $vars = []) + { + return $this->view->fetch($template, $vars); + } + + /** + * 渲染内容输出 + * @access protected + * @param string $content 模板内容 + * @param array $vars 模板输出变量 + * @return mixed + */ + protected function display($content = '', $vars = []) + { + return $this->view->display($content, $vars); + } + + /** + * 模板变量赋值 + * @access protected + * @param mixed $name 要显示的模板变量 + * @param mixed $value 变量的值 + * @return $this + */ + protected function assign($name, $value = '') + { + $this->view->assign($name, $value); + + return $this; + } + + /** + * 初始化模板引擎 + * @access protected + * @param array|string $engine 引擎参数 + * @return $this + */ + protected function engine($engine) + { + $this->view->engine($engine); + + return $this; + } + +} diff --git a/app/ExceptionHandle.php b/app/ExceptionHandle.php new file mode 100644 index 0000000..453d126 --- /dev/null +++ b/app/ExceptionHandle.php @@ -0,0 +1,58 @@ +model = new CarInfoT; + } + + /** + * 显示资源列表 + * + * @return string + * @throws \Exception + */ + public function index() + { + $peer_phone_count = PeerPhoneT::count(); + $repeat_frame_count = RepeatFrameT::count(); + $this->assign('peer_phone_count', $peer_phone_count); + $this->assign('repeat_frame_count', $repeat_frame_count); + return $this->fetch(); + } + + /** + * @return Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function carInfo(){ + $params = $this->request->param(); + $page = $this->request->param('page', 1); + $limit = $this->request->param('limit', 20); + if ($page <= 1) { + $page = 1; + } + $offset = ($page - 1) * $limit; + $map = $this->getQueryCondition($params); + $jobs_name = ['0' => '']; + if (isset($params['is_check_peer_phone']) && $params['is_check_peer_phone'] > 0) { + $params['data_check'] = 'car_phone_check'; + } + if ((isset($params['is_check_repeat_frame']) && $params['is_check_repeat_frame'] > 0) || + isset($params['is_delete_frame']) && $params['is_delete_frame'] > 0) { + $params['data_check'] = 'car_frame_check'; + } + if(isset($params['data_check']) && $params['data_check'] == 'car_frame_check'){ + $query = $this->model->rightJoin('repeat_frame_t','repeat_frame_t.car_frame_no = car_info_t.car_frame_no')->field('car_info_t.*')->where($map)->order('repeat_frame_t.car_frame_no desc'); + if (isset($params['is_check_repeat_frame']) && $params['is_check_repeat_frame'] > 0) { + $jobs_info = JobsT::find($params['is_check_repeat_frame']); + $job_info_payload = json_decode($jobs_info->payload,true)['data']['params']; + if(isset($job_info_payload['export_date1']) && $job_info_payload['export_date1'] != ''){ + $query = $query->where('car_info_t.register_date', '>=', $job_info_payload['export_date1']); + } + if(isset($job_info_payload['export_date2']) && $job_info_payload['export_date2'] != ''){ + $query = $query->where('car_info_t.register_date', '<=', $job_info_payload['export_date2']); + } + $query = $query->where([ + ['repeat_frame_t.source', '=', $params['is_check_repeat_frame']]]); + } else if (isset($params['is_delete_frame']) && $params['is_delete_frame'] > 0) { + $query = $query->where('repeat_frame_t.is_delete', '=', $params['is_delete_frame']); + } + }else if(isset($params['data_check']) && $params['data_check'] == 'car_phone_check'){ + $query = $this->model->rightJoin('peer_phone_t','peer_phone_t.phone = car_info_t.car_phone')->field('car_info_t.*')->where($map)->order('peer_phone_t.phone desc'); + if (isset($params['is_check_peer_phone']) && $params['is_check_peer_phone'] > 0) { + $jobs_info = JobsT::find($params['is_check_peer_phone']); + $job_info_payload = json_decode($jobs_info->payload, true)['data']['params']; + if (isset($job_info_payload['export_date1']) && $job_info_payload['export_date1'] != '') { + $query = $query->where('car_info_t.register_date', '>=', $job_info_payload['export_date1']); + } + if (isset($job_info_payload['export_date2']) && $job_info_payload['export_date2'] != '') { + $query = $query->where('car_info_t.register_date', '<=', $job_info_payload['export_date2']); + } + $query = $query->where('peer_phone_t.source', '=', $params['is_check_peer_phone'])->where('car_info_t.car_number', 'REGEXP', '^[1-9][[:digit:]]{7}((0[[:digit:]])|(1[0-2]))(([0|1|2][[:digit:]])|3[0-1])[[:digit:]]{3}$|^[1-9][[:digit:]]{5}[1-9][[:digit:]]{3}((0[[:digit:]])|(1[0-2]))(([0|1|2][[:digit:]])|3[0-1])[[:digit:]]{3}([0-9]|X)$'); + } + } else if (isset($params['export_name']) && $params['export_name'] != '') { + $export_name = JobsT::where('queue', 'like', '%' . $params['export_name'] . '%')->column('queue,download_times', 'id'); + $ids = array_keys($export_name); + $query = $this->model->where($map)->where(function ($query) use ($ids) { + $query->whereOr(['car_info_t.is_export_bhx' => $ids, 'car_info_t.is_export_bmc' => $ids]); + })->field('*')->order('is_export_bhx desc,is_export_bmc desc'); + } else { + $query = $this->model->where($map)->order('id desc'); + } + $map_or1 = []; + $map_or2 = []; + $insurer_month1 = $params['insurer_month1']??''; + $insurer_day1 = $params['insurer_day1']??''; + $insurer_month2 = $params['insurer_month2']??''; + $insurer_day2 = $params['insurer_day2']??''; + if($insurer_month1 != '' && $insurer_day1 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '>=', $insurer_month1]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '>=', $insurer_month1]; + } else if ($insurer_month1 == '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '>=', $insurer_day1]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '>=', $insurer_day1]; + } else if ($insurer_month1 != '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + } + if($insurer_month2 != '' && $insurer_day2 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '<=', $insurer_month2]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '<=', $insurer_month2]; + } else if ($insurer_month2 == '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '<=', $insurer_day2]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '<=', $insurer_day2]; + } else if ($insurer_month2 != '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + } + if(count($map_or1) > 0){ + $map_or1 = array_merge([['car_info_t.insurer1_date', '<>', '']],$map_or1); + } + if(count($map_or2) > 0){ + $map_or2 = array_merge([['car_info_t.insurer1_date', '=', ''],['car_info_t.insurer2_date', '<>', '']],$map_or2); + } + if (count($map_or1) > 0 && count($map_or2) > 0) { + $query = $query->where(function ($query) use ($map_or1, $map_or2) { + if (count($map_or1) > 0 && count($map_or2) > 0) { + $query->whereOr([$map_or1, $map_or2]); + } + }); + } + if (isset($params['data_filter']) && !empty($params['data_filter'])) { + $map = $this->getAddStatusQuery(array_flip($params['data_filter'])); + if(count($map) > 1 ){ + $query = $query->where(function ($query) use ($map) { + if (count($map) > 0){ + $query->whereOr($map); + } + }); + }else { + $query = $query->where($map); + } + } + $count = $query->count(); + $list = $query->limit($offset, $limit)->select()->toArray(); + if(isset($export_name) && count($export_name) > 0 ){ + $jobs_name = $jobs_name + $export_name; + } + foreach ($list as &$item) { + $item['export_bhx_name'] = $jobs_name[$item['is_export_bhx']]['queue'] ?? ''; + $item['export_bmc_name'] = $jobs_name[$item['is_export_bmc']]['queue'] ?? ''; + $item['bhx_download_times'] = $jobs_name[$item['is_export_bhx']]['download_times'] ?? 0; + $item['bmc_download_times'] = $jobs_name[$item['is_export_bmc']]['download_times'] ?? 0; + } + $this->layui_data['data'] = $list; + $this->layui_data['count'] = $count; + return json($this->layui_data); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return string + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function edit($id) + { + $car_info = $this->model->find($id); + if($this->request->isGet()){ + $this->assign('info', $car_info); + return $this->fetch(); + }else if($this->request->isPost()){ + $data = $this->request->param(); + $car_info->car_no = $data['car_no'] ?? $car_info->car_no; + $car_info->car_frame_no = $data['car_frame_no'] ?? $car_info->car_frame_no; + $car_info->engine_no = $data['engine_no'] ?? $car_info->engine_no; + $car_info->factory_model = $data['factory_model'] ?? $car_info->factory_model; + $car_info->register_date = $data['register_date'] ?? $car_info->register_date; + $car_info->purchase_price = $data['purchase_price'] ?? $car_info->purchase_price; + $car_info->company = $data['company'] ?? $car_info->company; + $car_info->insurer1_date = $data['insurer1_date'] ?? $car_info->insurer1_date; + $car_info->insurer2_date = $data['insurer2_date'] ?? $car_info->insurer2_date; + $car_info->car_man = $data['car_man'] ?? $car_info->car_man; + $car_info->car_number = $data['car_number'] ?? $car_info->car_number; + $car_info->car_phone = $data['car_phone'] ?? $car_info->car_phone; + $car_info->id_man = $data['id_man'] ?? $car_info->id_man; + $car_info->id_number = $data['id_number'] ?? $car_info->id_number; + $car_info->update_timestamp = date('Y-m-d H:i:s'); + if($car_info->save()){ + return json($this->json_data); + }else { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '保存失败'; + return json($this->layui_data); + } + } + + } + + /** + * 删除指定资源 + * @param $id + * @return Json + */ + public function delete($id) + { + // + $this->json_data['code'] = intval($this->model->destroy($id)); + $this->json_data['msg'] = $this->json_data['code'] ? '删除成功' : '删除失败'; + return json($this->json_data); + } + + /** + * 批量删除 + * @return Json + * @throws \Exception + */ + public function deletes() + { + // + $params = $this->request->param(); + $map = $this->getQueryCondition($params); + if($this->model->where($map)->delete()){ + $this->json_data['msg'] = '删除成功'; + }else { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '删除失败'; + } + return json($this->json_data); + } + + /** + * 清除数据 + * @return Json + */ + public function truncate(){ + $ret = Db::execute("truncate table car_info_t"); + if($ret === false){ + $this->json_data['code'] = 0; + $this->json_data['msg'] = '删除失败'; + }else { + $this->json_data['msg'] = '删除成功'; + } + return json($this->json_data); + } + + /** + * @param $id + * @return Json + */ + public function clearPhone($id){ + $this->json_data['code'] = $this->model->where('id', $id)->update(['car_phone' => '']); + $this->json_data['msg'] = $this->json_data['code'] ? '操作成功' : '操作失败'; + return json($this->json_data); + } + + /** + * 保存更新的资源 + * + * @param int $id + * @param $field + * @param $value + * @return \think\Response + */ + public function update($id, $field, $value) + { + $this->json_data['code'] = $this->model->where('id', $id)->update([$field => $value]); + $this->json_data['msg'] = $this->json_data['code'] ? '更新成功' : '更新失败'; + return json($this->json_data); + } + + public function login(){ + $password = $this->request->param('password',''); + if ($password === 'wuwei088277') { + session('login_time', time()); + session('last_action', time()); + }else { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '密码错误'; + } + return json($this->json_data); + } + + /** + * @param $params + * @return array + */ + private function getQueryCondition($params) + { + $map = []; + if (isset($params['car_man']) && $params['car_man'] != '') { + $car_man = explode(',', str_replace(',', '', $params['car_man'])); + array_walk($car_man, function (&$value) { + $value = '%' . $value . '%'; + }); + $map[] = ['car_info_t.car_man', 'like', $car_man]; + } + if (isset($params['factory_model']) && $params['factory_model'] != '') { + $factory_model = explode(',', str_replace(',', '', $params['factory_model'])); + array_walk($factory_model, function (&$value) { + $value = '%' . $value . '%'; + }); + $map[] = ['car_info_t.factory_model', 'like', $factory_model]; + } + if (isset($params['car_frame_no']) && $params['car_frame_no'] != '') { + $map[] = ['car_info_t.car_frame_no', '=', $params['car_frame_no']]; + } + if (isset($params['car_no']) && $params['car_no'] != '') { + $map[] = ['car_info_t.car_no', '=', $params['car_no']]; + } + if (isset($params['car_number']) && $params['car_number'] != '') { + $map[] = ['car_info_t.car_number', '=', $params['car_number']]; + } + if (isset($params['car_phone']) && $params['car_phone'] != '') { + $map[] = ['car_info_t.car_phone', '=', $params['car_phone']]; + } + if (isset($params['register_date']) && $params['register_date'] != '') { + $map[] = ['car_info_t.register_date', '=', $params['register_date']]; + } + if (isset($params['car_phone_empty']) && $params['car_phone_empty'] == 'yes') { + $map[] = ['car_info_t.car_phone', '<>', '']; + } + if (isset($params['car_phone_empty']) && $params['car_phone_empty'] == 'no') { + $map[] = ['car_info_t.car_phone', '=', '']; + } + if (isset($params['car_phone_repeat']) && $params['car_phone_repeat'] == 'yes') { + $map[] = ['car_info_t.id', '=', 'peer_phone_t.id']; + } + if (isset($params['is_update_bhx']) && $params['is_update_bhx'] > 0 ) { + $map[] = ['car_info_t.is_update_bhx', '=', $params['is_update_bhx']]; + } + if (isset($params['is_export_bhx']) && $params['is_export_bhx'] > 0 ) { + $map[] = ['car_info_t.is_export_bhx', '=', $params['is_export_bhx']]; + } + if (isset($params['is_export_bmc']) && $params['is_export_bmc'] > 0 ) { + $map[] = ['car_info_t.is_export_bmc', '=', $params['is_export_bmc']]; + } + if (isset($params['is_export_failed']) && $params['is_export_failed'] > 0 ) { + $map[] = ['car_info_t.is_export_failed', '=', $params['is_export_failed']]; + } + if (isset($params['is_export_failed_bmc']) && $params['is_export_failed_bmc'] > 0 ) { + $map[] = ['car_info_t.is_export_failed_bmc', '=', $params['is_export_failed_bmc']]; + } + if (isset($params['is_export_none_bmc']) && $params['is_export_none_bmc'] > 0 ) { + $map[] = ['car_info_t.is_export_none_bmc', '=', $params['is_export_none_bmc']]; + } + + if (isset($params['source']) && $params['source'] > 0 ) { + $map[] = ['car_info_t.source', '=', $params['source']]; + } + if(isset($params['register_date1']) && $params['register_date1'] != ''){ + $map[] = ['car_info_t.register_date', '>=', $params['register_date1']]; + } + if(isset($params['register_date2']) && $params['register_date2'] != ''){ + $map[] = ['car_info_t.register_date', '<=', $params['register_date2']]; + } + if (isset($params['price1']) && $params['price1'] != '') { + $map[] = ['car_info_t.purchase_price', '>=', $params['price1'] * 10000]; + } + if (isset($params['price2']) && $params['price2'] != '') { + $map[] = ['car_info_t.purchase_price', '<=', $params['price2'] * 10000]; + } + return $map; + } + + /** + * 添加状态筛选 + * @param $data_filter + * @return array + */ + private function getAddStatusQuery($data_filter) + { + $tree = new Tree(); + $tree->setNode(1, isset($data_filter['bhx']) ? [['car_info_t.is_export_bhx', '>', 0]] : []); + $tree->setNode(2, isset($data_filter['none']) ? [['car_info_t.is_export_bhx', '=', 0]] : []); + if(isset($data_filter['bhx_success'])){ + $tree->setNode(3, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '>', 0], + ]],1); + $tree->setNode(1, [], 0); + }else { + $tree->setNode(3, [],1); + } + if(isset($data_filter['bhx_failed'])){ + $tree->setNode(4, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '<', 0], + ]],1); + $tree->setNode(1, [], 0); + }else { + $tree->setNode(4, [],1); + } + if(isset($data_filter['bhx_none'])){ + $tree->setNode(5, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '=', 0], + ]],1); + $tree->setNode(1, [], 0); + }else { + $tree->setNode(5, [],1); + } + if(isset($data_filter['none_bmc'])){ + $tree->setNode(6, [[ + ['car_info_t.is_export_bhx', '=', 0], + ['car_info_t.is_export_none_bmc', '>', 0], + ]],2); + $tree->setNode(2, [], 0); + }else { + $tree->setNode(6, [],2); + } + if(isset($data_filter['none_none'])){ + $tree->setNode(7, [[ + ['car_info_t.is_export_bhx', '=', 0], + ['car_info_t.is_export_none_bmc', '=', 0], + ]],2); + $tree->setNode(2, [], 0); + }else { + $tree->setNode(7, [],2); + } + if(isset($data_filter['bhx_success_bmc'])){ + $tree->setNode(8, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '>', 0], + ['car_info_t.is_export_bmc', '>', 0], + ]],3); + $tree->setNode(3, [], 0); + }else { + $tree->setNode(8, [],3); + } + if(isset($data_filter['bhx_success_none'])){ + $tree->setNode(9, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '>', 0], + ['car_info_t.is_export_bmc', '=', 0], + ]],3); + $tree->setNode(3, [], 0); + }else { + $tree->setNode(9, [],3); + } + if(isset($data_filter['bhx_failed_bmc'])){ + $tree->setNode(10, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '<', 0], + ['car_info_t.is_export_bmc', '=', 0], + ['car_info_t.is_export_failed', '=', 0], + ['car_info_t.is_export_failed_bmc', '>', 0], + ]],4); + $tree->setNode(4, [], 0); + }else { + $tree->setNode(10, [],4); + } + if(isset($data_filter['bhx_failed_bhx'])){ + $tree->setNode(11, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '<', 0], + ['car_info_t.is_export_bmc', '=', 0], + ['car_info_t.is_export_failed', '>', 0], + ]],4); + $tree->setNode(4, [], 0); + }else { + $tree->setNode(11, [],4); + } + if(isset($data_filter['bhx_failed_none'])){ + $tree->setNode(12, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '<', 0], + ['car_info_t.is_export_bmc', '=', 0], + ['car_info_t.is_export_failed', '=', 0], + ['car_info_t.is_export_failed_bmc', '=', 0], + ]],4); + $tree->setNode(4, [], 0); + }else { + $tree->setNode(12, [],4); + } + + $map = $tree->getAllChildrenNodes(0, function ($value) { + return count($value) > 0; + }, function ($value) { + return $value; + }); + return array_column(array_filter($map), null); + } +} diff --git a/app/controller/Index.php.bak b/app/controller/Index.php.bak new file mode 100644 index 0000000..03d2511 --- /dev/null +++ b/app/controller/Index.php.bak @@ -0,0 +1,498 @@ +model = new CarInfoT; + } + + /** + * 显示资源列表 + * + * @return string + * @throws \Exception + */ + public function index() + { + $peer_phone_count = PeerPhoneT::count(); + $repeat_frame_count = RepeatFrameT::count(); + $this->assign('peer_phone_count', $peer_phone_count); + $this->assign('repeat_frame_count', $repeat_frame_count); + return $this->fetch(); + } + + /** + * @return Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function carInfo(){ + $params = $this->request->param(); + $page = $this->request->param('page', 1); + $limit = $this->request->param('limit', 20); + if ($page <= 1) { + $page = 1; + } + $offset = ($page - 1) * $limit; + $map = $this->getQueryCondition($params); + $jobs_name = ['0' => '']; + if (isset($params['is_check_peer_phone']) && $params['is_check_peer_phone'] > 0) { + $params['data_check'] = 'car_phone_check'; + } + if ((isset($params['is_check_repeat_frame']) && $params['is_check_repeat_frame'] > 0) || + isset($params['is_delete_frame']) && $params['is_delete_frame'] > 0) { + $params['data_check'] = 'car_frame_check'; + } + if(isset($params['data_check']) && $params['data_check'] == 'car_frame_check'){ + $query = $this->model->rightJoin('repeat_frame_t','repeat_frame_t.car_frame_no = car_info_t.car_frame_no')->field('car_info_t.*')->where($map)->order('repeat_frame_t.car_frame_no desc'); + if (isset($params['is_check_repeat_frame']) && $params['is_check_repeat_frame'] > 0) { + $jobs_info = JobsT::find($params['is_check_repeat_frame']); + $job_info_payload = json_decode($jobs_info->payload,true)['data']['params']; + if(isset($job_info_payload['export_date1']) && $job_info_payload['export_date1'] != ''){ + $query = $query->where('car_info_t.register_date', '>=', $job_info_payload['export_date1']); + } + if(isset($job_info_payload['export_date2']) && $job_info_payload['export_date2'] != ''){ + $query = $query->where('car_info_t.register_date', '<=', $job_info_payload['export_date2']); + } + $query = $query->where([ + ['repeat_frame_t.source', '=', $params['is_check_repeat_frame']]]); + } else if (isset($params['is_delete_frame']) && $params['is_delete_frame'] > 0) { + $query = $query->where('repeat_frame_t.is_delete', '=', $params['is_delete_frame']); + } + }else if(isset($params['data_check']) && $params['data_check'] == 'car_phone_check'){ + $query = $this->model->rightJoin('peer_phone_t','peer_phone_t.phone = car_info_t.car_phone')->field('car_info_t.*')->where($map)->order('peer_phone_t.phone desc'); + if (isset($params['is_check_peer_phone']) && $params['is_check_peer_phone'] > 0) { + $jobs_info = JobsT::find($params['is_check_peer_phone']); + $job_info_payload = json_decode($jobs_info->payload, true)['data']['params']; + if (isset($job_info_payload['export_date1']) && $job_info_payload['export_date1'] != '') { + $query = $query->where('car_info_t.register_date', '>=', $job_info_payload['export_date1']); + } + if (isset($job_info_payload['export_date2']) && $job_info_payload['export_date2'] != '') { + $query = $query->where('car_info_t.register_date', '<=', $job_info_payload['export_date2']); + } + $query = $query->where('peer_phone_t.source', '=', $params['is_check_peer_phone'])->where('car_info_t.car_number', 'REGEXP', '^[1-9][[:digit:]]{7}((0[[:digit:]])|(1[0-2]))(([0|1|2][[:digit:]])|3[0-1])[[:digit:]]{3}$|^[1-9][[:digit:]]{5}[1-9][[:digit:]]{3}((0[[:digit:]])|(1[0-2]))(([0|1|2][[:digit:]])|3[0-1])[[:digit:]]{3}([0-9]|X)$'); + } + } else if (isset($params['export_name']) && $params['export_name'] != '') { + $export_name = JobsT::where('queue', 'like', '%' . $params['export_name'] . '%')->column('queue,download_times', 'id'); + $ids = array_keys($export_name); + $query = $this->model->where($map)->where(function ($query) use ($ids) { + $query->whereOr(['car_info_t.is_export_bhx' => $ids, 'car_info_t.is_export_bmc' => $ids]); + })->field('*')->order('is_export_bhx desc,is_export_bmc desc'); + } else { + $query = $this->model->where($map)->order('id desc'); + } + $map_or1 = []; + $map_or2 = []; + $insurer_month1 = $params['insurer_month1']??''; + $insurer_day1 = $params['insurer_day1']??''; + $insurer_month2 = $params['insurer_month2']??''; + $insurer_day2 = $params['insurer_day2']??''; + if($insurer_month1 != '' && $insurer_day1 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '>=', $insurer_month1]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '>=', $insurer_month1]; + } else if ($insurer_month1 == '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '>=', $insurer_day1]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '>=', $insurer_day1]; + } else if ($insurer_month1 != '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + } + if($insurer_month2 != '' && $insurer_day2 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '<=', $insurer_month2]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '<=', $insurer_month2]; + } else if ($insurer_month2 == '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '<=', $insurer_day2]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '<=', $insurer_day2]; + } else if ($insurer_month2 != '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + } + if(count($map_or1) > 0){ + $map_or1 = array_merge([['car_info_t.insurer1_date', '<>', '']],$map_or1); + } + if(count($map_or2) > 0){ + $map_or2 = array_merge([['car_info_t.insurer1_date', '=', ''],['car_info_t.insurer2_date', '<>', '']],$map_or2); + } + if (count($map_or1) > 0 && count($map_or2) > 0) { + $query = $query->where(function ($query) use ($map_or1, $map_or2) { + if (count($map_or1) > 0 && count($map_or2) > 0) { + $query->whereOr([$map_or1, $map_or2]); + } + }); + } + if (isset($params['data_filter']) && !empty($params['data_filter'])) { + $map = $this->getAddStatusQuery(array_flip($params['data_filter'])); + if(count($map) > 1 ){ + $query = $query->where(function ($query) use ($map) { + if (count($map) > 0){ + $query->whereOr($map); + } + }); + }else { + $query = $query->where($map); + } + } + $count = $query->count(); + $list = $query->limit($offset, $limit)->select()->toArray(); + if(isset($export_name) && count($export_name) > 0 ){ + $jobs_name = $jobs_name + $export_name; + } + foreach ($list as &$item) { + $item['export_bhx_name'] = $jobs_name[$item['is_export_bhx']]['queue'] ?? ''; + $item['export_bmc_name'] = $jobs_name[$item['is_export_bmc']]['queue'] ?? ''; + $item['bhx_download_times'] = $jobs_name[$item['is_export_bhx']]['download_times'] ?? 0; + $item['bmc_download_times'] = $jobs_name[$item['is_export_bmc']]['download_times'] ?? 0; + } + $this->layui_data['data'] = $list; + $this->layui_data['count'] = $count; + return json($this->layui_data); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return string + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function edit($id) + { + $car_info = $this->model->find($id); + if($this->request->isGet()){ + $this->assign('info', $car_info); + return $this->fetch(); + }else if($this->request->isPost()){ + $data = $this->request->param(); + $car_info->car_no = $data['car_no'] ?? $car_info->car_no; + $car_info->car_frame_no = $data['car_frame_no'] ?? $car_info->car_frame_no; + $car_info->engine_no = $data['engine_no'] ?? $car_info->engine_no; + $car_info->factory_model = $data['factory_model'] ?? $car_info->factory_model; + $car_info->register_date = $data['register_date'] ?? $car_info->register_date; + $car_info->purchase_price = $data['purchase_price'] ?? $car_info->purchase_price; + $car_info->company = $data['company'] ?? $car_info->company; + $car_info->insurer1_date = $data['insurer1_date'] ?? $car_info->insurer1_date; + $car_info->insurer2_date = $data['insurer2_date'] ?? $car_info->insurer2_date; + $car_info->car_man = $data['car_man'] ?? $car_info->car_man; + $car_info->car_number = $data['car_number'] ?? $car_info->car_number; + $car_info->car_phone = $data['car_phone'] ?? $car_info->car_phone; + $car_info->id_man = $data['id_man'] ?? $car_info->id_man; + $car_info->id_number = $data['id_number'] ?? $car_info->id_number; + $car_info->update_timestamp = date('Y-m-d H:i:s'); + if($car_info->save()){ + return json($this->json_data); + }else { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '保存失败'; + return json($this->layui_data); + } + } + + } + + /** + * 删除指定资源 + * @param $id + * @return Json + */ + public function delete($id) + { + // + $this->json_data['code'] = intval($this->model->destroy($id)); + $this->json_data['msg'] = $this->json_data['code'] ? '删除成功' : '删除失败'; + return json($this->json_data); + } + + /** + * 批量删除 + * @return Json + * @throws \Exception + */ + public function deletes() + { + // + $params = $this->request->param(); + $map = $this->getQueryCondition($params); + if($this->model->where($map)->delete()){ + $this->json_data['msg'] = '删除成功'; + }else { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '删除失败'; + } + return json($this->json_data); + } + + /** + * 清除数据 + * @return Json + */ + public function truncate(){ + $ret = Db::execute("truncate table car_info_t"); + if($ret === false){ + $this->json_data['code'] = 0; + $this->json_data['msg'] = '删除失败'; + }else { + $this->json_data['msg'] = '删除成功'; + } + return json($this->json_data); + } + + /** + * @param $id + * @return Json + */ + public function clearPhone($id){ + $this->json_data['code'] = $this->model->where('id', $id)->update(['car_phone' => '']); + $this->json_data['msg'] = $this->json_data['code'] ? '操作成功' : '操作失败'; + return json($this->json_data); + } + + /** + * 保存更新的资源 + * + * @param int $id + * @param $field + * @param $value + * @return \think\Response + */ + public function update($id, $field, $value) + { + $this->json_data['code'] = $this->model->where('id', $id)->update([$field => $value]); + $this->json_data['msg'] = $this->json_data['code'] ? '更新成功' : '更新失败'; + return json($this->json_data); + } + + public function login(){ + $password = $this->request->param('password',''); + if ($password === 'wuwei088277') { + session('login_time', time()); + session('last_action', time()); + }else { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '密码错误'; + } + return json($this->json_data); + } + + /** + * @param $params + * @return array + */ + private function getQueryCondition($params) + { + $map = []; + if (isset($params['car_man']) && $params['car_man'] != '') { + $car_man = explode(',', str_replace(',', '', $params['car_man'])); + array_walk($car_man, function (&$value) { + $value = '%' . $value . '%'; + }); + $map[] = ['car_info_t.car_man', 'like', $car_man]; + } + if (isset($params['factory_model']) && $params['factory_model'] != '') { + $factory_model = explode(',', str_replace(',', '', $params['factory_model'])); + array_walk($factory_model, function (&$value) { + $value = '%' . $value . '%'; + }); + $map[] = ['car_info_t.factory_model', 'like', $factory_model]; + } + if (isset($params['car_frame_no']) && $params['car_frame_no'] != '') { + $map[] = ['car_info_t.car_frame_no', '=', $params['car_frame_no']]; + } + if (isset($params['car_no']) && $params['car_no'] != '') { + $map[] = ['car_info_t.car_no', '=', $params['car_no']]; + } + if (isset($params['car_number']) && $params['car_number'] != '') { + $map[] = ['car_info_t.car_number', '=', $params['car_number']]; + } + if (isset($params['car_phone']) && $params['car_phone'] != '') { + $map[] = ['car_info_t.car_phone', '=', $params['car_phone']]; + } + if (isset($params['register_date']) && $params['register_date'] != '') { + $map[] = ['car_info_t.register_date', '=', $params['register_date']]; + } + if (isset($params['car_phone_empty']) && $params['car_phone_empty'] == 'yes') { + $map[] = ['car_info_t.car_phone', '<>', '']; + } + if (isset($params['car_phone_empty']) && $params['car_phone_empty'] == 'no') { + $map[] = ['car_info_t.car_phone', '=', '']; + } + if (isset($params['car_phone_repeat']) && $params['car_phone_repeat'] == 'yes') { + $map[] = ['car_info_t.id', '=', 'peer_phone_t.id']; + } + if (isset($params['is_update_bhx']) && $params['is_update_bhx'] > 0 ) { + $map[] = ['car_info_t.is_update_bhx', '=', $params['is_update_bhx']]; + } + if (isset($params['is_export_bhx']) && $params['is_export_bhx'] > 0 ) { + $map[] = ['car_info_t.is_export_bhx', '=', $params['is_export_bhx']]; + } + if (isset($params['is_export_bmc']) && $params['is_export_bmc'] > 0 ) { + $map[] = ['car_info_t.is_export_bmc', '=', $params['is_export_bmc']]; + } + if (isset($params['is_export_failed']) && $params['is_export_failed'] > 0 ) { + $map[] = ['car_info_t.is_export_failed', '=', $params['is_export_failed']]; + } + if (isset($params['is_export_failed_bmc']) && $params['is_export_failed_bmc'] > 0 ) { + $map[] = ['car_info_t.is_export_failed_bmc', '=', $params['is_export_failed_bmc']]; + } + if (isset($params['is_export_none_bmc']) && $params['is_export_none_bmc'] > 0 ) { + $map[] = ['car_info_t.is_export_none_bmc', '=', $params['is_export_none_bmc']]; + } + + if (isset($params['source']) && $params['source'] > 0 ) { + $map[] = ['car_info_t.source', '=', $params['source']]; + } + if(isset($params['register_date1']) && $params['register_date1'] != ''){ + $map[] = ['car_info_t.register_date', '>=', $params['register_date1']]; + } + if(isset($params['register_date2']) && $params['register_date2'] != ''){ + $map[] = ['car_info_t.register_date', '<=', $params['register_date2']]; + } + if (isset($params['price1']) && $params['price1'] != '') { + $map[] = ['car_info_t.purchase_price', '>=', $params['price1'] * 10000]; + } + if (isset($params['price2']) && $params['price2'] != '') { + $map[] = ['car_info_t.purchase_price', '<=', $params['price2'] * 10000]; + } + return $map; + } + + /** + * 添加状态筛选 + * @param $data_filter + * @return array + */ + private function getAddStatusQuery($data_filter) + { + $tree = new Tree(); + $tree->setNode(1, isset($data_filter['bhx']) ? [['car_info_t.is_export_bhx', '>', 0]] : []); + $tree->setNode(2, isset($data_filter['none']) ? [['car_info_t.is_export_bhx', '=', 0]] : []); + if(isset($data_filter['bhx_success'])){ + $tree->setNode(3, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '>', 0], + ]],1); + $tree->setNode(1, [], 0); + }else { + $tree->setNode(3, [],1); + } + if(isset($data_filter['bhx_failed'])){ + $tree->setNode(4, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '<', 0], + ]],1); + $tree->setNode(1, [], 0); + }else { + $tree->setNode(4, [],1); + } + if(isset($data_filter['bhx_none'])){ + $tree->setNode(5, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '=', 0], + ]],1); + $tree->setNode(1, [], 0); + }else { + $tree->setNode(5, [],1); + } + if(isset($data_filter['none_bmc'])){ + $tree->setNode(6, [[ + ['car_info_t.is_export_bhx', '=', 0], + ['car_info_t.is_export_none_bmc', '>', 0], + ]],2); + $tree->setNode(2, [], 0); + }else { + $tree->setNode(6, [],2); + } + if(isset($data_filter['none_none'])){ + $tree->setNode(7, [[ + ['car_info_t.is_export_bhx', '=', 0], + ['car_info_t.is_export_none_bmc', '=', 0], + ]],2); + $tree->setNode(2, [], 0); + }else { + $tree->setNode(7, [],2); + } + if(isset($data_filter['bhx_success_bmc'])){ + $tree->setNode(8, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '>', 0], + ['car_info_t.is_export_bmc', '>', 0], + ]],3); + $tree->setNode(3, [], 0); + }else { + $tree->setNode(8, [],3); + } + if(isset($data_filter['bhx_success_none'])){ + $tree->setNode(9, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '>', 0], + ['car_info_t.is_export_bmc', '=', 0], + ]],3); + $tree->setNode(3, [], 0); + }else { + $tree->setNode(9, [],3); + } + if(isset($data_filter['bhx_failed_bmc'])){ + $tree->setNode(10, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '=', -1], + ['car_info_t.is_export_bmc', '=', 0], + ['car_info_t.is_export_failed', '=', 0], + ['car_info_t.is_export_failed_bmc', '>', 0], + ]],4); + $tree->setNode(4, [], 0); + }else { + $tree->setNode(10, [],4); + } + if(isset($data_filter['bhx_failed_bhx'])){ + $tree->setNode(11, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '=', -1], + ['car_info_t.is_export_bmc', '=', 0], + ['car_info_t.is_export_failed', '>', 0], + ]],4); + $tree->setNode(4, [], 0); + }else { + $tree->setNode(11, [],4); + } + if(isset($data_filter['bhx_failed_none'])){ + $tree->setNode(12, [[ + ['car_info_t.is_export_bhx', '>', 0], + ['car_info_t.is_update_bhx', '=', -1], + ['car_info_t.is_export_bmc', '=', 0], + ['car_info_t.is_export_failed', '=', 0], + ['car_info_t.is_export_failed_bmc', '=', 0], + ]],4); + $tree->setNode(4, [], 0); + }else { + $tree->setNode(12, [],4); + } + + $map = $tree->getAllChildrenNodes(0, function ($value) { + return count($value) > 0; + }, function ($value) { + return $value; + }); + return array_column(array_filter($map), null); + } +} diff --git a/app/controller/Task.php b/app/controller/Task.php new file mode 100644 index 0000000..8326513 --- /dev/null +++ b/app/controller/Task.php @@ -0,0 +1,615 @@ +model = new JobsT; + } + + public function test(){ + return Db::table('jobs_t')->where('id',8917)->update(['payload' => '{"job":"app\\jobs\\DelayQueue","maxTries":null,"timeout":null,"data":{"params":{"task_type":"5","original_filename":"\u5bfc\u51fa\u6e05\u6d17\u5931\u8d252019-02-01\u20142019-02-28\u7b2c3\u62791472\u6761(\u6267\u884c\u7ed3\u679c)","filename":"uploads\/20201122\\88559f1802f684d14c2e9aa1def8353e.xlsx"},"controller":"service\\CarInfoHandle","action":"carInfoUpdate"}}']); + } + + /** + * 显示资源列表 + * + * @return string + * @throws \Exception + */ + public function index() + { + return $this->fetch(); + } + + /** + * @return \think\response\Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function taskInfo(){ + $page = $this->request->param('page', 1); + $limit = $this->request->param('limit', 20); + $queue = $this->request->param('queue', ''); + if ($page <= 1) { + $page = 1; + } + $offset = ($page - 1) * $limit; + $query = $this->model->field(['id','payload','remark', 'type', 'queue', 'download_times', + "(case `status` when 2 then '100' else '0' end)" => 'process', + 'date_format(from_unixtime(create_time),"%Y-%m-%d %H:%i:%s") as create_timestamp', + "(case `type` when 1 then '导入' when 2 then '导出' when 3 then '同行电话' when 4 then '重复车架号' when 5 then '更新车辆信息' when 6 then '清除重复电话' when 7 then '删除重复数据' else '' end)" => 'type_txt', + "(case `status` when 0 then '排队中' when 1 then '处理中' when 2 then '已完成' when 3 then '失败' else '' end)" => 'status', 'create_time']); + if($queue != ''){ + $query = $query->where('queue','like','%'. $queue .'%')->whereOr('payload','like','%'. str_replace(['\\','"'],['_',''],json_encode($queue)) .'%'); + } + $count = $query->count(); + $list = $query->limit($offset, (int)$limit)->order('id desc')->select()->toArray(); + foreach ($list as &$item){ + if($item['type'] == 1 || $item['type'] == 5){ + $item['type_txt'] = json_decode($item['payload'],true)['data']['params']['original_filename'] ?? ''; + } + if ($item['type'] == 2) { + $item['type_txt'] = $item['queue'] != 'default' ? $item['queue']: $item['type_txt']; + } + if($item['type'] == 3){ + $item['info_num'] = PeerPhoneT::where(['source' => $item['id']])->count(); + } + if($item['type'] == 4){ + $item['info_num'] = RepeatFrameT::where(['source' => $item['id'], 'is_delete' => 0])->count(); + } + } + $this->layui_data['data'] = $list; + $this->layui_data['count'] = $count; + return json($this->layui_data); + } + + /** + * 显示创建资源表单页. + * + */ + public function create() + { + + } + + /** + * 保存新建的资源 + * + * @return \think\Response + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function save() + { + $params = $this->request->param(); + $type = $this->request->param('task_type', '0'); + $original_filename = $this->request->param('original_filename'); + $filename = $this->request->param('filename'); + $peer_phone_number = $this->request->param('peer_phone_number'); + $queue = $this->request->param('queue', ''); + if(isset($params['source_id']) && $params['source_id'] > 0) { + $job_info = JobsT::find($params['source_id']); + $job_info_payload = json_decode($job_info->payload,true)['data']['params']; + $params = []; + $params['export_type'] = 'repeat'; + $params['export_limit'] = 0; + $params['export_table'] = $job_info->type == 3? 'peer_phone_t': ($job_info->type == 4?'repeat_frame_t':''); + $params['source_id'] = $job_info->id; + $params['export_date1'] = $job_info_payload['export_date1']; + $params['export_date2'] = $job_info_payload['export_date2']; + } + if (($type == 1 || $type == 5) && ( $filename == '' || ($filename != '' && !file_exists(public_path('public/storage') . $filename)))) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '导入文件不存在'; + return json($this->json_data); + } else if ($type == 1 || $type == 5) { + $original_filename = basename($original_filename); + $original_filename = str_replace(strrchr($original_filename, '.'), '', $original_filename); + $params['original_filename'] = $original_filename; + } + if ($type == 2 && (!isset($params['source_id']) || $params['source_id'] <= 0) && $params['export_date1'] == '' && $params['export_date2'] == '') { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '请先填写注册日期'; + return json($this->json_data); + } else if ($type == 2 && isset($params['export_type']) && $params['export_type'] != '' && !in_array($params['export_type'], ['bhx', 'bmc', 'failed', 'repeat', 'failed_bmc', 'none_bmc'])) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '导出类型错误,请选择正确的导出类型'; + return json($this->json_data); + } else if ($type == 2) { + if(trim($params['export_limit']) === ''){ + $this->json_data['code'] = 0; + $this->json_data['msg'] = '导出数量必填'; + return json($this->json_data); + } + $where = []; + $map_or1 = []; + $map_or2 = []; + if(isset($params['export_date1']) && $params['export_date1'] != ''){ + $where[] = ['car_info_t.register_date', '>=', $params['export_date1']]; + } + if(isset($params['export_date2']) && $params['export_date2'] != ''){ + $where[] = ['car_info_t.register_date', '<=', $params['export_date2']]; + } + if (isset($params['price1']) && $params['price1'] != '') { + $where[] = ['car_info_t.purchase_price', '>=', $params['price1'] * 10000]; + } + if (isset($params['price2']) && $params['price2'] != '') { + $where[] = ['car_info_t.purchase_price', '<=', $params['price2'] * 10000]; + } + if(isset($params['empty_phone_check']) && $params['empty_phone_check'] == 'yes'){ + $where[] = ['car_phone', '<>', '']; + } + if(isset($params['export_field'])){ + foreach ($params['export_field'] as $item){ + $where[] = [$item, '<>', '']; + } + } + if(isset($params['export_type']) && $params['export_type'] != '' && $params['export_limit'] != 0){ + if($params['export_type'] == 'bhx'){ + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if($params['export_type'] == 'bmc'){ + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '>', 0]; + $where[] = ['is_export_bmc', '=', 0]; + } + if ($params['export_type'] == 'failed') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + } + if ($params['export_type'] == 'failed_bmc') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if ($params['export_type'] == 'none_bmc') { + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + $where[] = ['is_export_none_bmc', '=', 0]; + } + } + $insurer_month1 = $params['insurer_month1']??''; + $insurer_day1 = $params['insurer_day1']??''; + $insurer_month2 = $params['insurer_month2']??''; + $insurer_day2 = $params['insurer_day2']??''; + if($insurer_month1 != '' && $insurer_day1 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '>=', $insurer_month1]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '>=', $insurer_month1]; + } else if ($insurer_month1 == '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '>=', $insurer_day1]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '>=', $insurer_day1]; + } else if ($insurer_month1 != '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + } + if($insurer_month2 != '' && $insurer_day2 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '<=', $insurer_month2]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '<=', $insurer_month2]; + } else if ($insurer_month2 == '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '<=', $insurer_day2]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '<=', $insurer_day2]; + } else if ($insurer_month2 != '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + } + if(count($map_or1) > 0){ + $map_or1 = array_merge([['car_info_t.insurer1_date', '<>', '']],$map_or1); + } + if(count($map_or2) > 0){ + $map_or2 = array_merge([['car_info_t.insurer1_date', '=', ''],['car_info_t.insurer2_date', '<>', '']],$map_or2); + } + $query = CarInfoT::where($where)->where(function ($query) use ($map_or1, $map_or2) { + if (count($map_or1) > 0 && count($map_or2) > 0){ + $query->whereOr([$map_or1, $map_or2]); + } + }); + $count = $query->count(); + if ($count < $params['export_limit']) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '当前导出数量为' . $count . ', 不足' . $params['export_limit'] . ',请检查条件'; + return json($this->json_data); + } + } + if ($type == 3 && $peer_phone_number <= 0) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '请填写正确的个人电话重复数'; + return json($this->json_data); + } + if ($type == 3 || $type == 4) { + $where = []; + if($params['export_date1'] != ''){ + $where[] = ['car_info_t.register_date', '>=', $params['export_date1']]; + } + if($params['export_date2'] != ''){ + $where[] = ['car_info_t.register_date', '<=', $params['export_date2']]; + } + $count = CarInfoT::where($where)->count(); + if ($count <= 0) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '当前待处理数据为空,请检查条件'; + return json($this->json_data); + } + } + $action = [ + '1'=>'import', + '2'=>'export', + '3'=>'peerPhones', + '4'=>'carFrameNo', + '5'=>'carInfoUpdate', + '6'=>'deletePeerPhones', + '7'=>'deleteCarFrameNo', + ]; + $id = Queue::push( + 'app\jobs\DelayQueue', + ['params' => $params, 'controller' => 'service\\CarInfoHandle', 'action' => $action[$type]], + $queue, $type); + if (!$id) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '任务创建失败'; + } + return json($this->json_data); + } + + /** + * 显示指定的资源 + * + * @param int $id + * @return \think\Response + */ + public function read($id) + { + // + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + // + } + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + // + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + // + } + + /** + * @return Json + */ + public function upload(){ + $file = request()->file('file'); + $savename = Filesystem::disk('public')->putFile('uploads', $file); + $filename = public_path('public\storage') . $savename; + if ($this->checkUploadTpl($filename, $this->request->param('task_type'))) { + $this->json_data['msg'] = '上传成功'; + $this->json_data['original_filename'] = $file->getOriginalName(); + $this->json_data['filename'] = $savename; + } else { + @unlink($filename); + $this->json_data['code'] = 0; + $this->json_data['msg'] = '上传文件[' . $file->getOriginalName() . ']与模板不匹配,请检查文件重新上传'; + } + return json($this->json_data); + } + + public function clearSubTable(){ + Db::startTrans(); + try { + Db::execute("truncate table jobs_t;"); + Db::execute("truncate table peer_phone_t;"); + Db::execute("truncate table repeat_frame_t;"); + $this->json_data['msg'] = '删除成功'; + Db::commit(); + } catch (\Exception $e) { + Db::rollback(); + $this->json_data['code'] = 0; + $this->json_data['msg'] = '删除失败'; + } + return json($this->json_data); + } + + public function download($id) + { + $job_info = JobsT::find($id); + $job_info->download_times = Db::raw('download_times+1'); + $downloadName = $this->downloadName($job_info); + $job_info->save(); + return download(root_path(). 'public' . $job_info->remark, $downloadName); + } + + public function process(){ + $list = JobsT::where('status', '=', 1) + ->whereOr('create_time', '>=', strtotime(date('Y-m-d'))) + ->order('create_time desc') + ->select(); + foreach ($list as $item) { + $process = cache('shell_process_' . $item['id']); + if($item->status == 1 || $process){ + $this->json_data['data'][] = [ + 'id' => $item['id'], + 'process' => $process, + ]; + } + if($process >= 100){ + Cache::delete('shell_process_' . $item['id']); + } + } + return json($this->json_data); + } + + /** + * 导出名称 + * @return \think\response\Json + */ + public function exportName() + { + $export_date1 = $this->request->param('export_date1'); + $export_date2 = $this->request->param('export_date2'); + if ($export_date1 == '' || $export_date2 == '') { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '注册日期范围不能为空'; + return json($this->json_data); + } + $type = $this->request->param('export_type'); + $export_limit = $this->request->param('export_limit'); + $name = ''; + if ($type == 'bhx') { + $name = '导出清洗'; + } else if ($type == 'failed') { + $name = '导出清洗失败'; + } else if ($type == 'bmc') { + $name = '导出清洗成功至上传'; + } else if ($type == 'failed_bmc') { + $name = '导出清洗失败至上传'; + } else if ($type == 'none_bmc') { + $name = '导出未处理至上传'; + } + $count = ExportLogT::where('name','like', $name . $export_date1 . '—' . $export_date2 . '%')->count(); + $name .= $export_date1 . '—' . $export_date2 . '第' . ($count + 1) . '批' . $export_limit . '条'; + $this->json_data['name'] = $name; + return json($this->json_data); + } + + /** + * 任务操作 + * @param $jobId + * @return \think\response\Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function taskBtn($jobId){ + $job_info = JobsT::find($jobId); + if($job_info->type == 2){ + $this->json_data['btns'] = '下载文件'; + }else if($job_info->type == 3 && PeerPhoneT::where(['source' => $job_info->id])->count() > 0){ + $this->json_data['btns'] = ' + + + '; + }else if($job_info->type == 4 && RepeatFrameT::where(['source' => $job_info->id, 'is_delete' => 0])->count() > 0){ + $this->json_data['btns'] = ' + + + '; + } + return json($this->json_data); + } + + public function exportNum(){ + $params = $this->request->param(); + $where = []; + $map_or1 = []; + $map_or2 = []; + if(isset($params['export_date1']) && $params['export_date1'] != ''){ + $where[] = ['car_info_t.register_date', '>=', $params['export_date1']]; + } + if(isset($params['export_date2']) && $params['export_date2'] != ''){ + $where[] = ['car_info_t.register_date', '<=', $params['export_date2']]; + } + if (isset($params['price1']) && $params['price1'] != '') { + $where[] = ['car_info_t.purchase_price', '>=', $params['price1'] * 10000]; + } + if (isset($params['price2']) && $params['price2'] != '') { + $where[] = ['car_info_t.purchase_price', '<=', $params['price2'] * 10000]; + } + if(isset($params['empty_phone_check']) && $params['empty_phone_check'] == 'yes'){ + $where[] = ['car_phone', '<>', '']; + } + if(isset($params['export_field'])){ + foreach ($params['export_field'] as $item){ + $where[] = [$item, '<>', '']; + } + } + if(isset($params['export_type']) && $params['export_type'] != ''){ + if($params['export_type'] == 'bhx'){ + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if($params['export_type'] == 'bmc'){ + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '>', 0]; + $where[] = ['is_export_bmc', '=', 0]; + } + if ($params['export_type'] == 'failed') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + } + if ($params['export_type'] == 'failed_bmc') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if ($params['export_type'] == 'none_bmc') { + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + $where[] = ['is_export_none_bmc', '=', 0]; + } + } + $insurer_month1 = $params['insurer_month1']??''; + $insurer_day1 = $params['insurer_day1']??''; + $insurer_month2 = $params['insurer_month2']??''; + $insurer_day2 = $params['insurer_day2']??''; + if($insurer_month1 != '' && $insurer_day1 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '>=', $insurer_month1]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '>=', $insurer_month1]; + } else if ($insurer_month1 == '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '>=', $insurer_day1]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '>=', $insurer_day1]; + } else if ($insurer_month1 != '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + } + if($insurer_month2 != '' && $insurer_day2 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '<=', $insurer_month2]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '<=', $insurer_month2]; + } else if ($insurer_month2 == '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '<=', $insurer_day2]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '<=', $insurer_day2]; + } else if ($insurer_month2 != '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + } + if(count($map_or1) > 0){ + $map_or1 = array_merge([['car_info_t.insurer1_date', '<>', '']],$map_or1); + } + if(count($map_or2) > 0){ + $map_or2 = array_merge([['car_info_t.insurer1_date', '=', ''],['car_info_t.insurer2_date', '<>', '']],$map_or2); + } + $query = CarInfoT::where($where)->where(function ($query) use ($map_or1, $map_or2) { + if (count($map_or1) > 0 && count($map_or2) > 0){ + $query->whereOr([$map_or1, $map_or2]); + } + }); + $this->json_data['data'] = $query->count(); + $this->json_data['sql'] = CarInfoT::getLastSql(); + return json($this->json_data); + } + + public function checkIsExistName($name,$type){ + if($name == ''){ + $this->json_data['code'] = 0; + $this->json_data['msg'] = '文件名为空,请检查'; + return json($this->json_data); + } + if($type == 'update'){ + $name = basename($name); + $name = str_replace(strrchr($name, '.'), '', $name); + } + $count = $this->model->where('queue', '=', $name) + ->whereOr('payload', 'like', '%' . str_replace(['\\', '"'], ['_', ''], json_encode($name)) . '%') + ->count(); + if ($count > 0) { + $this->json_data['msg'] = $type == 'upload' ? '当前文件已处理,确定继续?' : '当前任务名已存在,是否继续'; + }else { + $this->json_data['code'] = 2; + } + return json($this->json_data); + } + + private function downloadName(JobsT $job_info){ + $job_params = json_decode($job_info->payload,true)['data']['params']; + list(,$ext) = explode('.', $job_info->remark); + $downloadName = $job_params['export_date1'] . '-' . $job_params['export_date2']; + if($job_info->queue != 'default'){ + $downloadName = $job_info->queue; + }else if($job_params['export_type'] == 'repeat' && $job_params['export_table'] == 'repeat_frame_t'){ + $downloadName = '重复车架' . $downloadName; + } else if($job_params['export_type'] == 'repeat' && $job_params['export_table'] == 'peer_phone_t'){ + $downloadName = '重复电话' . $downloadName; + } + $downloadName .= '.' . $ext; + return $downloadName; + } + + private function checkUploadTpl($file, $type) + { + $path_info = pathinfo($file); + if ($type == 1 && $path_info['extension'] == 'csv') { + $title = \file\FileSystem::getFileBlockData($file,0,1); + $tpl_title = ['税号', '初登日期', '车主', '证件号', '电话号码', '车架号', '车牌号', '发动机号', '车型', '新车购置价']; + // $tpl_title = ['区域', '购车日期', '客户姓名', '证件号码', '联系方式', '车架号', '车牌号', '发动机号', '品牌型号', '新车购置价', '保险公司', '商业止保日期', '交强止保日期', '被保险人', '被保险人证件号']; + $title = explode(',', trim($title[0])); + if (count(array_diff($tpl_title, $title)) > 0) { + return false; + } + } else if ($type == 5 && $path_info['extension'] == 'xlsx') { + $spreadsheetReader = Excel::loadFile($file); + $sheet = $spreadsheetReader->getSheet(0); + $highestColumn = $sheet->getHighestColumn(); // e.g 'F' + $title = $sheet->rangeToArray("A1:{$highestColumn}1")[0]; + $tpl_title = ['车牌号','车主','品牌型号','发动机号','车架号','注册日期','上年承保公司','商业险到期日期','交强险到期日期','被保险人姓名','被保险人证件号']; + if (count(array_diff($tpl_title, $title)) > 0) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/app/controller/Task.php.bak b/app/controller/Task.php.bak new file mode 100644 index 0000000..d46e193 --- /dev/null +++ b/app/controller/Task.php.bak @@ -0,0 +1,605 @@ +model = new JobsT; + } + + /** + * 显示资源列表 + * + * @return string + * @throws \Exception + */ + public function index() + { + return $this->fetch(); + } + + /** + * @return \think\response\Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function taskInfo(){ + $page = $this->request->param('page', 1); + $limit = $this->request->param('limit', 20); + $queue = $this->request->param('queue', ''); + if ($page <= 1) { + $page = 1; + } + $offset = ($page - 1) * $limit; + $query = $this->model->field(['id','payload','remark', 'type', 'queue', 'download_times', + "(case `status` when 2 then '100' else '0' end)" => 'process', + 'date_format(from_unixtime(create_time),"%Y-%m-%d %H:%i:%s") as create_timestamp', + "(case `type` when 1 then '导入' when 2 then '导出' when 3 then '同行电话' when 4 then '重复车架号' when 5 then '更新车辆信息' when 6 then '清除重复电话' when 7 then '删除重复数据' else '' end)" => 'type_txt', + "(case `status` when 0 then '排队中' when 1 then '处理中' when 2 then '已完成' when 3 then '失败' else '' end)" => 'status', 'create_time']); + if($queue != ''){ + $query = $query->where('queue','like','%'. $queue .'%')->whereOr('payload','like','%'. str_replace(['\\','"'],['_',''],json_encode($queue)) .'%'); + } + $count = $query->count(); + $list = $query->limit($offset, (int)$limit)->order('id desc')->select()->toArray(); + foreach ($list as &$item){ + if($item['type'] == 1 || $item['type'] == 5){ + $item['type_txt'] = json_decode($item['payload'],true)['data']['params']['original_filename'] ?? ''; + } + if ($item['type'] == 2) { + $item['type_txt'] = $item['queue'] != 'default' ? $item['queue']: $item['type_txt']; + } + if($item['type'] == 3){ + $item['info_num'] = PeerPhoneT::where(['source' => $item['id']])->count(); + } + if($item['type'] == 4){ + $item['info_num'] = RepeatFrameT::where(['source' => $item['id'], 'is_delete' => 0])->count(); + } + } + $this->layui_data['data'] = $list; + $this->layui_data['count'] = $count; + return json($this->layui_data); + } + + /** + * 显示创建资源表单页. + * + */ + public function create() + { + + } + + /** + * 保存新建的资源 + * + * @return \think\Response + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function save() + { + $params = $this->request->param(); + $type = $this->request->param('task_type', '0'); + $original_filename = $this->request->param('original_filename'); + $filename = $this->request->param('filename'); + $peer_phone_number = $this->request->param('peer_phone_number'); + $queue = $this->request->param('queue', ''); + if(isset($params['source_id']) && $params['source_id'] > 0) { + $job_info = JobsT::find($params['source_id']); + $job_info_payload = json_decode($job_info->payload,true)['data']['params']; + $params = []; + $params['export_type'] = 'repeat'; + $params['export_limit'] = 0; + $params['export_table'] = $job_info->type == 3? 'peer_phone_t': ($job_info->type == 4?'repeat_frame_t':''); + $params['source_id'] = $job_info->id; + $params['export_date1'] = $job_info_payload['export_date1']; + $params['export_date2'] = $job_info_payload['export_date2']; + } + if (($type == 1 || $type == 5) && ( $filename == '' || ($filename != '' && !file_exists(public_path('public/storage') . $filename)))) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '导入文件不存在'; + return json($this->json_data); + } else if ($type == 1 || $type == 5) { + $original_filename = basename($original_filename); + $original_filename = str_replace(strrchr($original_filename, '.'), '', $original_filename); + $params['original_filename'] = $original_filename; + } + if ($type == 2 && (!isset($params['source_id']) || $params['source_id'] <= 0) && $params['export_date1'] == '' && $params['export_date2'] == '') { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '请先填写注册日期'; + return json($this->json_data); + } else if ($type == 2 && isset($params['export_type']) && $params['export_type'] != '' && !in_array($params['export_type'], ['bhx', 'bmc', 'failed', 'repeat', 'failed_bmc', 'none_bmc'])) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '导出类型错误,请选择正确的导出类型'; + return json($this->json_data); + } else if ($type == 2) { + $where = []; + $map_or1 = []; + $map_or2 = []; + if(isset($params['export_date1']) && $params['export_date1'] != ''){ + $where[] = ['car_info_t.register_date', '>=', $params['export_date1']]; + } + if(isset($params['export_date2']) && $params['export_date2'] != ''){ + $where[] = ['car_info_t.register_date', '<=', $params['export_date2']]; + } + if (isset($params['price1']) && $params['price1'] != '') { + $where[] = ['car_info_t.purchase_price', '>=', $params['price1'] * 10000]; + } + if (isset($params['price2']) && $params['price2'] != '') { + $where[] = ['car_info_t.purchase_price', '<=', $params['price2'] * 10000]; + } + if(isset($params['empty_phone_check']) && $params['empty_phone_check'] == 'yes'){ + $where[] = ['car_phone', '<>', '']; + } + if(isset($params['export_field'])){ + foreach ($params['export_field'] as $item){ + $where[] = [$item, '<>', '']; + } + } + if(isset($params['export_type']) && $params['export_type'] != '' && $params['export_limit'] != 0){ + if($params['export_type'] == 'bhx'){ + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if($params['export_type'] == 'bmc'){ + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '>', 0]; + $where[] = ['is_export_bmc', '=', 0]; + } + if ($params['export_type'] == 'failed') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + } + if ($params['export_type'] == 'failed_bmc') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if ($params['export_type'] == 'none_bmc') { + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + $where[] = ['is_export_none_bmc', '=', 0]; + } + } + $insurer_month1 = $params['insurer_month1']??''; + $insurer_day1 = $params['insurer_day1']??''; + $insurer_month2 = $params['insurer_month2']??''; + $insurer_day2 = $params['insurer_day2']??''; + if($insurer_month1 != '' && $insurer_day1 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '>=', $insurer_month1]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '>=', $insurer_month1]; + } else if ($insurer_month1 == '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '>=', $insurer_day1]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '>=', $insurer_day1]; + } else if ($insurer_month1 != '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + } + if($insurer_month2 != '' && $insurer_day2 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '<=', $insurer_month2]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '<=', $insurer_month2]; + } else if ($insurer_month2 == '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '<=', $insurer_day2]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '<=', $insurer_day2]; + } else if ($insurer_month2 != '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + } + if(count($map_or1) > 0){ + $map_or1 = array_merge([['car_info_t.insurer1_date', '<>', '']],$map_or1); + } + if(count($map_or2) > 0){ + $map_or2 = array_merge([['car_info_t.insurer1_date', '=', ''],['car_info_t.insurer2_date', '<>', '']],$map_or2); + } + $query = CarInfoT::where($where)->where(function ($query) use ($map_or1, $map_or2) { + if (count($map_or1) > 0 && count($map_or2) > 0){ + $query->whereOr([$map_or1, $map_or2]); + } + }); + $count = $query->count(); + if ($count < $params['export_limit']) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '当前导出数量为' . $count . ', 不足' . $params['export_limit'] . ',请检查条件'; + return json($this->json_data); + } + } + if ($type == 3 && $peer_phone_number <= 0) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '请填写正确的个人电话重复数'; + return json($this->json_data); + } + if ($type == 3 || $type == 4) { + $where = []; + if($params['export_date1'] != ''){ + $where[] = ['car_info_t.register_date', '>=', $params['export_date1']]; + } + if($params['export_date2'] != ''){ + $where[] = ['car_info_t.register_date', '<=', $params['export_date2']]; + } + $count = CarInfoT::where($where)->count(); + if ($count <= 0) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '当前待处理数据为空,请检查条件'; + return json($this->json_data); + } + } + $action = [ + '1'=>'import', + '2'=>'export', + '3'=>'peerPhones', + '4'=>'carFrameNo', + '5'=>'carInfoUpdate', + '6'=>'deletePeerPhones', + '7'=>'deleteCarFrameNo', + ]; + $id = Queue::push( + 'app\jobs\DelayQueue', + ['params' => $params, 'controller' => 'service\\CarInfoHandle', 'action' => $action[$type]], + $queue, $type); + if (!$id) { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '任务创建失败'; + } + return json($this->json_data); + } + + /** + * 显示指定的资源 + * + * @param int $id + * @return \think\Response + */ + public function read($id) + { + // + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + // + } + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + // + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + // + } + + /** + * @return Json + */ + public function upload(){ + $file = request()->file('file'); + $savename = Filesystem::disk('public')->putFile('uploads', $file); + $filename = public_path('public\storage') . $savename; + if ($this->checkUploadTpl($filename, $this->request->param('task_type'))) { + $this->json_data['msg'] = '上传成功'; + $this->json_data['original_filename'] = $file->getOriginalName(); + $this->json_data['filename'] = $savename; + } else { + @unlink($filename); + $this->json_data['code'] = 0; + $this->json_data['msg'] = '上传文件[' . $file->getOriginalName() . ']与模板不匹配,请检查文件重新上传'; + } + return json($this->json_data); + } + + public function clearSubTable(){ + Db::startTrans(); + try { + Db::execute("truncate table jobs_t;"); + Db::execute("truncate table peer_phone_t;"); + Db::execute("truncate table repeat_frame_t;"); + $this->json_data['msg'] = '删除成功'; + Db::commit(); + } catch (\Exception $e) { + Db::rollback(); + $this->json_data['code'] = 0; + $this->json_data['msg'] = '删除失败'; + } + return json($this->json_data); + } + + public function download($id) + { + $job_info = JobsT::find($id); + $job_info->download_times = Db::raw('download_times+1'); + $downloadName = $this->downloadName($job_info); + $job_info->save(); + return download(root_path(). 'public' . $job_info->remark, $downloadName); + } + + public function process(){ + $list = JobsT::where('status', '=', 1) + ->whereOr('create_time', '>=', strtotime(date('Y-m-d'))) + ->order('create_time desc') + ->select(); + foreach ($list as $item) { + $process = cache('shell_process_' . $item['id']); + if($item->status == 1 || $process){ + $this->json_data['data'][] = [ + 'id' => $item['id'], + 'process' => $process, + ]; + } + if($process >= 100){ + Cache::delete('shell_process_' . $item['id']); + } + } + return json($this->json_data); + } + + /** + * 导出名称 + * @return \think\response\Json + */ + public function exportName() + { + $export_date1 = $this->request->param('export_date1'); + $export_date2 = $this->request->param('export_date2'); + if ($export_date1 == '' || $export_date2 == '') { + $this->json_data['code'] = 0; + $this->json_data['msg'] = '注册日期范围不能为空'; + return json($this->json_data); + } + $type = $this->request->param('export_type'); + $export_limit = $this->request->param('export_limit'); + $name = ''; + if ($type == 'bhx') { + $name = '导出清洗'; + } else if ($type == 'failed') { + $name = '导出清洗失败'; + } else if ($type == 'bmc') { + $name = '导出清洗成功至上传'; + } else if ($type == 'failed_bmc') { + $name = '导出清洗失败至上传'; + } else if ($type == 'none_bmc') { + $name = '导出未处理至上传'; + } + $count = ExportLogT::where('name','like', $name . $export_date1 . '—' . $export_date2 . '%')->count(); + $name .= $export_date1 . '—' . $export_date2 . '第' . ($count + 1) . '批' . $export_limit . '条'; + $this->json_data['name'] = $name; + return json($this->json_data); + } + + /** + * 任务操作 + * @param $jobId + * @return \think\response\Json + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function taskBtn($jobId){ + $job_info = JobsT::find($jobId); + if($job_info->type == 2){ + $this->json_data['btns'] = '下载文件'; + }else if($job_info->type == 3 && PeerPhoneT::where(['source' => $job_info->id])->count() > 0){ + $this->json_data['btns'] = ' + + + '; + }else if($job_info->type == 4 && RepeatFrameT::where(['source' => $job_info->id, 'is_delete' => 0])->count() > 0){ + $this->json_data['btns'] = ' + + + '; + } + return json($this->json_data); + } + + public function exportNum(){ + $params = $this->request->param(); + $where = []; + $map_or1 = []; + $map_or2 = []; + if(isset($params['export_date1']) && $params['export_date1'] != ''){ + $where[] = ['car_info_t.register_date', '>=', $params['export_date1']]; + } + if(isset($params['export_date2']) && $params['export_date2'] != ''){ + $where[] = ['car_info_t.register_date', '<=', $params['export_date2']]; + } + if (isset($params['price1']) && $params['price1'] != '') { + $where[] = ['car_info_t.purchase_price', '>=', $params['price1'] * 10000]; + } + if (isset($params['price2']) && $params['price2'] != '') { + $where[] = ['car_info_t.purchase_price', '<=', $params['price2'] * 10000]; + } + if(isset($params['empty_phone_check']) && $params['empty_phone_check'] == 'yes'){ + $where[] = ['car_phone', '<>', '']; + } + if(isset($params['export_field'])){ + foreach ($params['export_field'] as $item){ + $where[] = [$item, '<>', '']; + } + } + if(isset($params['export_type']) && $params['export_type'] != ''){ + if($params['export_type'] == 'bhx'){ + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if($params['export_type'] == 'bmc'){ + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '>', 0]; + $where[] = ['is_export_bmc', '=', 0]; + } + if ($params['export_type'] == 'failed') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + } + if ($params['export_type'] == 'failed_bmc') { + $where[] = ['is_export_bhx', '>', 0]; + $where[] = ['is_update_bhx', '<', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + } + if ($params['export_type'] == 'none_bmc') { + $where[] = ['is_export_bhx', '=', 0]; + $where[] = ['is_update_bhx', '=', 0]; + $where[] = ['is_export_bmc', '=', 0]; + $where[] = ['is_export_failed', '=', 0]; + $where[] = ['is_export_failed_bmc', '=', 0]; + $where[] = ['is_export_none_bmc', '=', 0]; + } + } + $insurer_month1 = $params['insurer_month1']??''; + $insurer_day1 = $params['insurer_day1']??''; + $insurer_month2 = $params['insurer_month2']??''; + $insurer_day2 = $params['insurer_day2']??''; + if($insurer_month1 != '' && $insurer_day1 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '>=', $insurer_month1]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '>=', $insurer_month1]; + } else if ($insurer_month1 == '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '>=', $insurer_day1]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '>=', $insurer_day1]; + } else if ($insurer_month1 != '' && $insurer_day1 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '>=', substr('0' . $insurer_month1, -2) . '-' . substr('0' . $insurer_day1, -2)]; + } + if($insurer_month2 != '' && $insurer_day2 == '') { + $map_or1[] = [Db::raw('month(car_info_t.insurer1_date)'), '<=', $insurer_month2]; + $map_or2[] = [Db::raw('month(car_info_t.insurer2_date)'), '<=', $insurer_month2]; + } else if ($insurer_month2 == '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('day(car_info_t.insurer1_date)'), '<=', $insurer_day2]; + $map_or2[] = [Db::raw('day(car_info_t.insurer2_date)'), '<=', $insurer_day2]; + } else if ($insurer_month2 != '' && $insurer_day2 != '') { + $map_or1[] = [Db::raw('DATE_FORMAT(car_info_t.insurer1_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + $map_or2[] = [Db::raw('DATE_FORMAT(car_info_t.insurer2_date,"%m-%d")'), '<=', substr('0' . $insurer_month2, -2) . '-' . substr('0' . $insurer_day2, -2)]; + } + if(count($map_or1) > 0){ + $map_or1 = array_merge([['car_info_t.insurer1_date', '<>', '']],$map_or1); + } + if(count($map_or2) > 0){ + $map_or2 = array_merge([['car_info_t.insurer1_date', '=', ''],['car_info_t.insurer2_date', '<>', '']],$map_or2); + } + $query = CarInfoT::where($where)->where(function ($query) use ($map_or1, $map_or2) { + if (count($map_or1) > 0 && count($map_or2) > 0){ + $query->whereOr([$map_or1, $map_or2]); + } + }); + $this->json_data['data'] = $query->count(); + return json($this->json_data); + } + + public function checkIsExistName($name,$type){ + if($name == ''){ + $this->json_data['code'] = 0; + $this->json_data['msg'] = '文件名为空,请检查'; + return json($this->json_data); + } + if($type == 'update'){ + $name = basename($name); + $name = str_replace(strrchr($name, '.'), '', $name); + } + $count = $this->model->where('queue', '=', $name) + ->whereOr('payload', 'like', '%' . str_replace(['\\', '"'], ['_', ''], json_encode($name)) . '%') + ->count(); + if ($count > 0) { + $this->json_data['msg'] = $type == 'upload' ? '当前文件已处理,确定继续?' : '当前任务名已存在,是否继续'; + }else { + $this->json_data['code'] = 2; + } + return json($this->json_data); + } + + private function downloadName(JobsT $job_info){ + $job_params = json_decode($job_info->payload,true)['data']['params']; + list(,$ext) = explode('.', $job_info->remark); + $downloadName = $job_params['export_date1'] . '-' . $job_params['export_date2']; + if($job_info->queue != 'default'){ + $downloadName = $job_info->queue; + }else if($job_params['export_type'] == 'repeat' && $job_params['export_table'] == 'repeat_frame_t'){ + $downloadName = '重复车架' . $downloadName; + } else if($job_params['export_type'] == 'repeat' && $job_params['export_table'] == 'peer_phone_t'){ + $downloadName = '重复电话' . $downloadName; + } + $downloadName .= '.' . $ext; + return $downloadName; + } + + private function checkUploadTpl($file, $type) + { + $path_info = pathinfo($file); + if ($type == 1 && $path_info['extension'] == 'csv') { + $title = \file\FileSystem::getFileBlockData($file,0,1); + $tpl_title = ['税号', '初登日期', '车主', '证件号', '电话号码', '车架号', '车牌号', '发动机号', '车型', '新车购置价']; + // $tpl_title = ['区域', '购车日期', '客户姓名', '证件号码', '联系方式', '车架号', '车牌号', '发动机号', '品牌型号', '新车购置价', '保险公司', '商业止保日期', '交强止保日期', '被保险人', '被保险人证件号']; + $title = explode(',', trim($title[0])); + if (count(array_diff($tpl_title, $title)) > 0) { + return false; + } + } else if ($type == 5 && $path_info['extension'] == 'xlsx') { + $spreadsheetReader = Excel::loadFile($file); + $sheet = $spreadsheetReader->getSheet(0); + $highestColumn = $sheet->getHighestColumn(); // e.g 'F' + $title = $sheet->rangeToArray("A1:{$highestColumn}1")[0]; + $tpl_title = ['车牌号','车主','品牌型号','发动机号','车架号','注册日期','上年承保公司','商业险到期日期','交强险到期日期','被保险人姓名','被保险人证件号']; + if (count(array_diff($tpl_title, $title)) > 0) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/app/event.php b/app/event.php new file mode 100644 index 0000000..e9851bb --- /dev/null +++ b/app/event.php @@ -0,0 +1,17 @@ + [ + ], + + 'listen' => [ + 'AppInit' => [], + 'HttpRun' => [], + 'HttpEnd' => [], + 'LogLevel' => [], + 'LogWrite' => [], + ], + + 'subscribe' => [ + ], +]; diff --git a/app/jobs/DelayQueue.php b/app/jobs/DelayQueue.php new file mode 100644 index 0000000..2b5e09a --- /dev/null +++ b/app/jobs/DelayQueue.php @@ -0,0 +1,41 @@ +doJob($job, $data); + if ($result['code'] == 1) { + $job->finish(2, $result['msg']); + } else { + $job->finish(3, $result['msg']); + } + } + + private function doJob(Job $job, $data) + { + ini_set('memory_limit', '2048M'); + $class = $data['controller']; + $method = $data['action']; + $this->instance = app()->make($class); + if ($this->instance) { + return ['code' => 1, 'msg' => $this->instance->{$method}($data['params'], $job->getJobId())]; + } + return ['code' => 0, 'msg' => '处理类不存在']; + } +} diff --git a/app/middleware.php b/app/middleware.php new file mode 100644 index 0000000..c8d321e --- /dev/null +++ b/app/middleware.php @@ -0,0 +1,10 @@ +hasOne('ImportLog','id','batch_id'); + } +} diff --git a/app/model/CrontabT.php b/app/model/CrontabT.php new file mode 100644 index 0000000..dce7669 --- /dev/null +++ b/app/model/CrontabT.php @@ -0,0 +1,24 @@ +crontab_str)) { + return ['code' => 0, 'msg' => "格式错误: {$this->crontab_str}"]; + } + return CronParser::formatToDate($this->crontab_str, 1)[0]; + } +} \ No newline at end of file diff --git a/app/model/ExportLogT.php b/app/model/ExportLogT.php new file mode 100644 index 0000000..97a6fff --- /dev/null +++ b/app/model/ExportLogT.php @@ -0,0 +1,12 @@ + Request::class, + 'think\exception\Handle' => ExceptionHandle::class, +]; diff --git a/app/service.php b/app/service.php new file mode 100644 index 0000000..db1ee6a --- /dev/null +++ b/app/service.php @@ -0,0 +1,9 @@ + + .layui-form-label { + width: 100px; + } + + .layui-badge { + height: 28px; + line-height: 28px; + font-size: 14px; + } + +{/block} +{block name="body"} +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ {if $info.is_export_bhx == 0 && $info.is_update_bhx == 0 && $info.is_export_bmc == 0 && + $info.is_export_failed == 0 && $info.is_export_none_bmc == 0 && $info.is_export_failed_bmc == 0} + 未处理 + {/if} + {if $info.is_export_bhx > 0 /} + 导出至清洗 + {/if} + {if $info.is_export_bhx > 0 && $info.is_update_bhx > 0 /} + 清洗成功 + {/if} + {if $info.is_export_bhx > 0 && $info.is_update_bhx < 0 /} + 清洗失败 + {/if} + {if $info.is_export_bhx > 0 && $info.is_export_failed > 0 /} + 导出清洗失败 + {/if} + {if $info.is_export_bhx > 0 && $info.is_export_failed_bmc > 0 /} + 导出清洗失败至上传 + {/if} + {if $info.is_export_bhx > 0 && $info.is_update_bhx > 0 && $info.is_export_bmc > 0 /} + 导出清洗成功至上传 + {/if} + {if $info.is_export_none_bmc > 0 /} + 导出未处理至上传 + {/if} +
+
+
+ + + +
+
+
+{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/app/view/index/edit.html.bak b/app/view/index/edit.html.bak new file mode 100644 index 0000000..45b9758 --- /dev/null +++ b/app/view/index/edit.html.bak @@ -0,0 +1,170 @@ +{extend name="public/base" /} +{block name="header"} + +{/block} +{block name="body"} +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ {if $info.is_export_bhx == 0 && $info.is_update_bhx == 0 && $info.is_export_bmc == 0 && + $info.is_export_failed == 0 && $info.is_export_none_bmc == 0 && $info.is_export_failed_bmc == 0} + 未处理 + {/if} + {if $info.is_export_bhx > 0 /} + 导出至清洗 + {/if} + {if $info.is_export_bhx > 0 && $info.is_update_bhx > 0 /} + 清洗成功 + {/if} + {if $info.is_export_bhx > 0 && $info.is_update_bhx == -1 /} + 清洗失败 + {/if} + {if $info.is_export_bhx > 0 && $info.is_export_failed > 0 /} + 导出清洗失败 + {/if} + {if $info.is_export_bhx > 0 && $info.is_export_failed_bmc > 0 /} + 导出清洗失败至上传 + {/if} + {if $info.is_export_bhx > 0 && $info.is_update_bhx > 0 && $info.is_export_bmc > 0 /} + 导出清洗成功至上传 + {/if} + {if $info.is_export_none_bmc > 0 /} + 导出未处理至上传 + {/if} +
+
+
+ + + +
+
+
+{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/app/view/index/index.html b/app/view/index/index.html new file mode 100644 index 0000000..00510c1 --- /dev/null +++ b/app/view/index/index.html @@ -0,0 +1,384 @@ +{extend name="public/layout" /} +{block name="header"} + +{/block} +{block name="body"} +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
-
+
+ +
+
+
+ +
+ 月 + 日 +
+
-
+
+ 月 + 日 +
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+
+
+
+ +
+ 万 +
+
-
+
+ 万 +
+
+
+ +
+ + + +
+
+
+ +
+ + {if $repeat_frame_count > 0 } + + {/if} + {if $peer_phone_count > 0 } + + {/if} +
+
+
+ + 重置条件 + + +
+
+
+
+
+
+
+{/block} +{block name="script"} + + + + + +{/block} \ No newline at end of file diff --git a/app/view/index/index.html.bak b/app/view/index/index.html.bak new file mode 100644 index 0000000..b5cd98b --- /dev/null +++ b/app/view/index/index.html.bak @@ -0,0 +1,365 @@ +{extend name="public/layout" /} +{block name="header"} + +{/block} +{block name="body"} +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ 万 +
+
-
+
+ 万 +
+
+
+
+
+ +
+ +
+
-
+
+ +
+
+
+ +
+ 月 + 日 +
+
-
+
+ 月 + 日 +
+
+
+
+
+ +
+ + + + +
+
+
+ +
+ +
+
+
+
+
+ +
+ + + +
+
+
+ +
+ + {if $repeat_frame_count > 0 } + + {/if} + {if $peer_phone_count > 0 } + + {/if} +
+
+
+ + 重置条件 + + +
+
+
+
+
+
+
+{/block} +{block name="script"} + + + + + +{/block} \ No newline at end of file diff --git a/app/view/public/base.html b/app/view/public/base.html new file mode 100644 index 0000000..ffce6b8 --- /dev/null +++ b/app/view/public/base.html @@ -0,0 +1,10 @@ +{include file="public/header" /} + +{block name="header"}{/block} + + +{block name="body"}{/block} +{include file="public/script" /} +{block name="script"}{/block} + + diff --git a/app/view/public/header.html b/app/view/public/header.html new file mode 100644 index 0000000..fce126b --- /dev/null +++ b/app/view/public/header.html @@ -0,0 +1,12 @@ + + + + + + + + + 粮仓 + + + \ No newline at end of file diff --git a/app/view/public/header.html.bak b/app/view/public/header.html.bak new file mode 100644 index 0000000..e28f9a3 --- /dev/null +++ b/app/view/public/header.html.bak @@ -0,0 +1,12 @@ + + + + + + + + + 数据处理 + + + \ No newline at end of file diff --git a/app/view/public/layout.html b/app/view/public/layout.html new file mode 100644 index 0000000..201d427 --- /dev/null +++ b/app/view/public/layout.html @@ -0,0 +1,38 @@ +{include file="public/header" /} + +{block name="header"}{/block} + + +
+
+ + +
+
+ {block name="body"}{/block} +
+ + +
+
+
+
+ +
+ +
+
+ +
+
+
+
+{include file="public/script" /} +{block name="script"}{/block} + + diff --git a/app/view/public/script.html b/app/view/public/script.html new file mode 100644 index 0000000..24e9bb7 --- /dev/null +++ b/app/view/public/script.html @@ -0,0 +1,4 @@ + + + + diff --git a/app/view/task/index.html b/app/view/task/index.html new file mode 100644 index 0000000..507cf60 --- /dev/null +++ b/app/view/task/index.html @@ -0,0 +1,449 @@ +{extend name="public/layout" /} +{block name="header"} +{/block} +{block name="body"} +
+
+
+
+ +
+ + + + + +
+
+
+ +
+ + +
+
+ +
+ [下载车辆信息导入模板] +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+
+{/block} +{block name="script"} + + + + +{/block} \ No newline at end of file diff --git a/app/view/task/index.html.bak b/app/view/task/index.html.bak new file mode 100644 index 0000000..05c2ab8 --- /dev/null +++ b/app/view/task/index.html.bak @@ -0,0 +1,444 @@ +{extend name="public/layout" /} +{block name="header"} +{/block} +{block name="body"} +
+
+
+
+ +
+ + + + + +
+
+
+ +
+ + +
+
+ +
+ [下载车辆信息导入模板] +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+
+{/block} +{block name="script"} + + + + +{/block} \ No newline at end of file diff --git a/build.php b/build.php new file mode 100644 index 0000000..34ba3c8 --- /dev/null +++ b/build.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- + +return [ + // 生成应用公共文件 + '__file__' => ['common.php'], + + // 定义demo模块的自动生成 (按照实际定义的文件名生成) + 'demo' => [ + '__file__' => ['common.php'], + '__dir__' => ['behavior', 'controller', 'model', 'view'], + 'controller' => ['Index', 'Test', 'UserType'], + 'model' => ['User', 'UserType'], + 'view' => ['index/index'], + ], + + // 其他更多的模块定义 +]; diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9195624 --- /dev/null +++ b/composer.json @@ -0,0 +1,54 @@ +{ + "name": "topthink/think", + "description": "the new thinkphp framework", + "type": "project", + "keywords": [ + "framework", + "thinkphp", + "ORM" + ], + "homepage": "http://thinkphp.cn/", + "license": "Apache-2.0", + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "require": { + "php": ">=7.1.0", + "topthink/framework": "^6.0.0", + "topthink/think-orm": "^2.0", + "topthink/think-multi-app": "^1.0", + "topthink/think-template": "^2.0", + "topthink/think-view": "^1.0", + "topthink/think-queue": "^3.0", + "nuovo/spreadsheet-reader": "^0.5.11", + "phpoffice/phpspreadsheet": "^1.10" + }, + "require-dev": { + "symfony/var-dumper": "^4.2", + "topthink/think-trace":"^1.0" + }, + "autoload": { + "psr-4": { + "app\\": "app" + }, + "psr-0": { + "": "extend/" + } + }, + "config": { + "preferred-install": "dist" + }, + "scripts": { + "post-autoload-dump": [ + "@php think service:discover", + "@php think vendor:publish" + ] + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..3be67b9 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1557 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "e4e60ed910b3ff78d1f500f16a66e570", + "packages": [ + { + "name": "league/flysystem", + "version": "1.0.63", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "8132daec326565036bc8e8d1876f77ec183a7bd6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8132daec326565036bc8e8d1876f77ec183a7bd6", + "reference": "8132daec326565036bc8e8d1876f77ec183a7bd6", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": ">=5.5.9" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7.10" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "ext-ftp": "Allows you to use FTP server storage", + "ext-openssl": "Allows you to use FTPS server storage", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", + "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", + "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "time": "2020-01-04T16:30:31+00:00" + }, + { + "name": "league/flysystem-cached-adapter", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-cached-adapter.git", + "reference": "08ef74e9be88100807a3b92cc9048a312bf01d6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/08ef74e9be88100807a3b92cc9048a312bf01d6f", + "reference": "08ef74e9be88100807a3b92cc9048a312bf01d6f", + "shasum": "" + }, + "require": { + "league/flysystem": "~1.0", + "psr/cache": "^1.0.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7", + "predis/predis": "~1.0", + "tedivm/stash": "~0.12" + }, + "suggest": { + "ext-phpredis": "Pure C implemented extension for PHP" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Cached\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "frankdejonge", + "email": "info@frenky.net" + } + ], + "description": "An adapter decorator to enable meta-data caching.", + "time": "2018-07-09T20:51:04+00:00" + }, + { + "name": "markbaker/complex", + "version": "1.4.7", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "shasum": "" + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "phpcompatibility/php-compatibility": "^8.0", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "2.*", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^4.8.35|^5.4.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "^3.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "files": [ + "classes/src/functions/abs.php", + "classes/src/functions/acos.php", + "classes/src/functions/acosh.php", + "classes/src/functions/acot.php", + "classes/src/functions/acoth.php", + "classes/src/functions/acsc.php", + "classes/src/functions/acsch.php", + "classes/src/functions/argument.php", + "classes/src/functions/asec.php", + "classes/src/functions/asech.php", + "classes/src/functions/asin.php", + "classes/src/functions/asinh.php", + "classes/src/functions/atan.php", + "classes/src/functions/atanh.php", + "classes/src/functions/conjugate.php", + "classes/src/functions/cos.php", + "classes/src/functions/cosh.php", + "classes/src/functions/cot.php", + "classes/src/functions/coth.php", + "classes/src/functions/csc.php", + "classes/src/functions/csch.php", + "classes/src/functions/exp.php", + "classes/src/functions/inverse.php", + "classes/src/functions/ln.php", + "classes/src/functions/log2.php", + "classes/src/functions/log10.php", + "classes/src/functions/negative.php", + "classes/src/functions/pow.php", + "classes/src/functions/rho.php", + "classes/src/functions/sec.php", + "classes/src/functions/sech.php", + "classes/src/functions/sin.php", + "classes/src/functions/sinh.php", + "classes/src/functions/sqrt.php", + "classes/src/functions/tan.php", + "classes/src/functions/tanh.php", + "classes/src/functions/theta.php", + "classes/src/operations/add.php", + "classes/src/operations/subtract.php", + "classes/src/operations/multiply.php", + "classes/src/operations/divideby.php", + "classes/src/operations/divideinto.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "time": "2018-10-13T23:28:42+00:00" + }, + { + "name": "markbaker/matrix", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/5348c5a67e3b75cd209d70103f916a93b1f1ed21", + "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21", + "shasum": "" + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "dev-master", + "phploc/phploc": "^4", + "phpmd/phpmd": "dev-master", + "phpunit/phpunit": "^5.7", + "sebastian/phpcpd": "^3.0", + "squizlabs/php_codesniffer": "^3.0@dev" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + }, + "files": [ + "classes/src/functions/adjoint.php", + "classes/src/functions/antidiagonal.php", + "classes/src/functions/cofactors.php", + "classes/src/functions/determinant.php", + "classes/src/functions/diagonal.php", + "classes/src/functions/identity.php", + "classes/src/functions/inverse.php", + "classes/src/functions/minors.php", + "classes/src/functions/trace.php", + "classes/src/functions/transpose.php", + "classes/src/operations/add.php", + "classes/src/operations/directsum.php", + "classes/src/operations/subtract.php", + "classes/src/operations/multiply.php", + "classes/src/operations/divideby.php", + "classes/src/operations/divideinto.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "time": "2019-10-06T11:29:25+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.29.1", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "e509be5bf2d703390e69e14496d9a1168452b0a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e509be5bf2d703390e69e14496d9a1168452b0a2", + "reference": "e509be5bf2d703390e69e14496d9a1168452b0a2", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/translation": "^3.4 || ^4.0 || ^5.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.14 || ^3.0", + "kylekatarnls/multi-tester": "^1.1", + "phpmd/phpmd": "^2.8", + "phpstan/phpstan": "^0.11", + "phpunit/phpunit": "^7.5 || ^8.0", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "http://nesbot.com" + }, + { + "name": "kylekatarnls", + "homepage": "http://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "http://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "time": "2020-01-21T09:36:43+00:00" + }, + { + "name": "nuovo/spreadsheet-reader", + "version": "0.5.11", + "source": { + "type": "git", + "url": "https://github.com/nuovo/spreadsheet-reader.git", + "reference": "f6bd49d101042eaa71b0fbd82e7a57e5a276dc3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nuovo/spreadsheet-reader/zipball/f6bd49d101042eaa71b0fbd82e7a57e5a276dc3d", + "reference": "f6bd49d101042eaa71b0fbd82e7a57e5a276dc3d", + "shasum": "" + }, + "require": { + "ext-zip": "*", + "php": ">= 5.3.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "./" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Martins Pilsetnieks", + "email": "pilsetnieks@gmail.com", + "homepage": "http://www.nuovo.lv/" + } + ], + "description": "Spreadsheet reader library for Excel, OpenOffice and structured text files", + "homepage": "https://github.com/nuovo/spreadsheet-reader", + "keywords": [ + "OpenOffice", + "csv", + "excel", + "ods", + "spreadsheet", + "xls", + "xlsx" + ], + "time": "2015-04-30T00:00:00+00:00" + }, + { + "name": "opis/closure", + "version": "3.5.1", + "source": { + "type": "git", + "url": "https://github.com/opis/closure.git", + "reference": "93ebc5712cdad8d5f489b500c59d122df2e53969" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/closure/zipball/93ebc5712cdad8d5f489b500c59d122df2e53969", + "reference": "93ebc5712cdad8d5f489b500c59d122df2e53969", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0" + }, + "require-dev": { + "jeremeamia/superclosure": "^2.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Closure\\": "src/" + }, + "files": [ + "functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", + "homepage": "https://opis.io/closure", + "keywords": [ + "anonymous functions", + "closure", + "function", + "serializable", + "serialization", + "serialize" + ], + "time": "2019-11-29T22:36:02+00:00" + }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.10.1", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "1648dc9ebef6ebe0c5a172e16cf66732918416e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/1648dc9ebef6ebe0c5a172e16cf66732918416e0", + "reference": "1648dc9ebef6ebe0c5a172e16cf66732918416e0", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "markbaker/complex": "^1.4", + "markbaker/matrix": "^1.2", + "php": "^7.1", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "dompdf/dompdf": "^0.8.3", + "friendsofphp/php-cs-fixer": "^2.16", + "jpgraph/jpgraph": "^4.0", + "mpdf/mpdf": "^8.0", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.5", + "squizlabs/php_codesniffer": "^3.5", + "tecnickcom/tcpdf": "^6.3" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "time": "2019-12-01T23:13:51+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/log", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2019-11-01T11:05:21+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.13.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2019-11-27T14:18:11+00:00" + }, + { + "name": "symfony/process", + "version": "v4.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "f5697ab4cb14a5deed7473819e63141bf5352c36" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/f5697ab4cb14a5deed7473819e63141bf5352c36", + "reference": "f5697ab4cb14a5deed7473819e63141bf5352c36", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2020-01-09T09:50:08+00:00" + }, + { + "name": "symfony/translation", + "version": "v5.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "28e1054f1ea26c63762d9260c37cb1056ea62dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/28e1054f1ea26c63762d9260c37cb1056ea62dbb", + "reference": "28e1054f1ea26c63762d9260c37cb1056ea62dbb", + "shasum": "" + }, + "require": { + "php": "^7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2" + }, + "conflict": { + "symfony/config": "<4.4", + "symfony/dependency-injection": "<5.0", + "symfony/http-kernel": "<5.0", + "symfony/twig-bundle": "<5.0", + "symfony/yaml": "<4.4" + }, + "provide": { + "symfony/translation-implementation": "2.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/http-kernel": "^5.0", + "symfony/intl": "^4.4|^5.0", + "symfony/service-contracts": "^1.1.2|^2", + "symfony/yaml": "^4.4|^5.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "time": "2020-01-21T08:40:24+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/8cc682ac458d75557203b2f2f14b0b92e1c744ed", + "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed", + "shasum": "" + }, + "require": { + "php": "^7.2.5" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2019-11-18T17:27:11+00:00" + }, + { + "name": "topthink/framework", + "version": "v6.0.2", + "source": { + "type": "git", + "url": "https://github.com/top-think/framework.git", + "reference": "1444cce94b40a836958380b160a5fb7bfc165daf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/framework/zipball/1444cce94b40a836958380b160a5fb7bfc165daf", + "reference": "1444cce94b40a836958380b160a5fb7bfc165daf", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "league/flysystem": "^1.0", + "league/flysystem-cached-adapter": "^1.0", + "opis/closure": "^3.1", + "php": ">=7.1.0", + "psr/container": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "topthink/think-helper": "^3.1.1", + "topthink/think-orm": "^2.0" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "files": [], + "psr-4": { + "think\\": "src/think/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP Framework.", + "homepage": "http://thinkphp.cn/", + "keywords": [ + "framework", + "orm", + "thinkphp" + ], + "time": "2020-01-13T05:48:05+00:00" + }, + { + "name": "topthink/think-factory", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-factory.git", + "reference": "b8080a6472aae1cff47ceb8c30feec3c2835364b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-factory/zipball/b8080a6472aae1cff47ceb8c30feec3c2835364b", + "reference": "b8080a6472aae1cff47ceb8c30feec3c2835364b", + "shasum": "" + }, + "require": { + "topthink/framework": "^6.0.0", + "topthink/think-helper": "^3.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "think\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "time": "2019-04-15T06:55:28+00:00" + }, + { + "name": "topthink/think-helper", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-helper.git", + "reference": "4d85dfd3778623bbb1de3648f1dcd0c82f4439f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-helper/zipball/4d85dfd3778623bbb1de3648f1dcd0c82f4439f4", + "reference": "4d85dfd3778623bbb1de3648f1dcd0c82f4439f4", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "think\\": "src" + }, + "files": [ + "src/helper.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP6 Helper Package", + "time": "2019-09-30T02:36:48+00:00" + }, + { + "name": "topthink/think-multi-app", + "version": "v1.0.11", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-multi-app.git", + "reference": "215f4a6bb88e53ad41b448c61957336eb55ce6f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/215f4a6bb88e53ad41b448c61957336eb55ce6f9", + "reference": "215f4a6bb88e53ad41b448c61957336eb55ce6f9", + "shasum": "" + }, + "require": { + "php": ">=7.1.0", + "topthink/framework": "^6.0.0" + }, + "type": "library", + "extra": { + "think": { + "services": [ + "think\\app\\Service" + ] + } + }, + "autoload": { + "psr-4": { + "think\\app\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "thinkphp6 multi app support", + "time": "2019-10-29T06:34:59+00:00" + }, + { + "name": "topthink/think-orm", + "version": "v2.0.31", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-orm.git", + "reference": "d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-orm/zipball/d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4", + "reference": "d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "topthink/think-helper": "^3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "think\\": "src" + }, + "files": [] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "think orm", + "keywords": [ + "database", + "orm" + ], + "time": "2020-01-07T10:05:10+00:00" + }, + { + "name": "topthink/think-queue", + "version": "v3.0.4", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-queue.git", + "reference": "a993295b68a483dc3cb2c0fee05683908fa2572e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-queue/zipball/a993295b68a483dc3cb2c0fee05683908fa2572e", + "reference": "a993295b68a483dc3cb2c0fee05683908fa2572e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "nesbot/carbon": "^2.16", + "symfony/process": "^4.2", + "topthink/framework": "^6.0.0", + "topthink/think-factory": "^1.0.0", + "topthink/think-helper": "^3.0.4" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^6.2", + "topthink/think-migration": "^3.0.0" + }, + "type": "library", + "extra": { + "think": { + "services": [ + "think\\queue\\Service" + ], + "config": { + "queue": "src/config.php" + } + } + }, + "autoload": { + "psr-4": { + "think\\": "src" + }, + "files": [ + "src/common.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP5 Queue Package", + "time": "2019-10-13T03:51:32+00:00" + }, + { + "name": "topthink/think-template", + "version": "v2.0.7", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-template.git", + "reference": "e98bdbb4a4c94b442f17dfceba81e0134d4fbd19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-template/zipball/e98bdbb4a4c94b442f17dfceba81e0134d4fbd19", + "reference": "e98bdbb4a4c94b442f17dfceba81e0134d4fbd19", + "shasum": "" + }, + "require": { + "php": ">=7.1.0", + "psr/simple-cache": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "think\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "the php template engine", + "time": "2019-09-20T15:31:04+00:00" + }, + { + "name": "topthink/think-view", + "version": "v1.0.13", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-view.git", + "reference": "90803b73f781db5d42619082c4597afc58b2d4c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-view/zipball/90803b73f781db5d42619082c4597afc58b2d4c5", + "reference": "90803b73f781db5d42619082c4597afc58b2d4c5", + "shasum": "" + }, + "require": { + "php": ">=7.1.0", + "topthink/think-template": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "think\\view\\driver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "thinkphp template driver", + "time": "2019-10-07T12:23:10+00:00" + } + ], + "packages-dev": [ + { + "name": "symfony/polyfill-php72", + "version": "v1.13.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2019-11-27T13:56:44+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v4.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "7cfa470bc3b1887a7b2a47c0a702a84ad614fa92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7cfa470bc3b1887a7b2a47c0a702a84ad614fa92", + "reference": "7cfa470bc3b1887a7b2a47c0a702a84ad614fa92", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/console": "<3.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "time": "2020-01-04T13:00:46+00:00" + }, + { + "name": "topthink/think-trace", + "version": "v1.2", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-trace.git", + "reference": "4589d06a07945d57478cc2236f4b23d51ff919cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-trace/zipball/4589d06a07945d57478cc2236f4b23d51ff919cc", + "reference": "4589d06a07945d57478cc2236f4b23d51ff919cc", + "shasum": "" + }, + "require": { + "php": ">=7.1.0", + "topthink/framework": "^6.0.0" + }, + "type": "library", + "extra": { + "think": { + "services": [ + "think\\trace\\Service" + ], + "config": { + "trace": "src/config.php" + } + } + }, + "autoload": { + "psr-4": { + "think\\trace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "thinkphp debug trace", + "time": "2019-10-17T02:14:09+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.1.0" + }, + "platform-dev": [] +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..1cfaf5c --- /dev/null +++ b/config/app.php @@ -0,0 +1,34 @@ + env('app.host', ''), + // 应用的命名空间 + 'app_namespace' => '', + // 是否启用路由 + 'with_route' => true, + // 是否启用事件 + 'with_event' => true, + // 默认应用 + 'default_app' => 'index', + // 默认时区 + 'default_timezone' => 'Asia/Shanghai', + + // 应用映射(自动多应用模式有效) + 'app_map' => [], + // 域名绑定(自动多应用模式有效) + 'domain_bind' => [], + // 禁止URL访问的应用列表(自动多应用模式有效) + 'deny_app_list' => [], + + // 异常页面的模板文件 + 'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl', + + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => false, +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..a8d69d2 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,29 @@ + env('cache.driver', 'file'), + + // 缓存连接方式配置 + 'stores' => [ + 'file' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => '', + // 缓存前缀 + 'prefix' => '', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, + // 缓存标签前缀 + 'tag_prefix' => 'tag:', + // 序列化机制 例如 ['serialize', 'unserialize'] + 'serialize' => [], + ], + // 更多的缓存连接 + ], +]; diff --git a/config/console.php b/config/console.php new file mode 100644 index 0000000..d0f6f36 --- /dev/null +++ b/config/console.php @@ -0,0 +1,11 @@ + [ + 'crontab' => 'app\command\Crontab', + 'hello' => 'app\command\Hello', + ], +]; diff --git a/config/cookie.php b/config/cookie.php new file mode 100644 index 0000000..f728024 --- /dev/null +++ b/config/cookie.php @@ -0,0 +1,18 @@ + 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => false, + // 是否使用 setcookie + 'setcookie' => true, +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..7b94ac1 --- /dev/null +++ b/config/database.php @@ -0,0 +1,62 @@ + env('database.driver', 'mysql'), + + // 自定义时间查询规则 + 'time_query_rule' => [], + + // 自动写入时间戳字段 + // true为自动识别类型 false关闭 + // 字符串则明确指定时间字段类型 支持 int timestamp datetime date + 'auto_timestamp' => true, + + // 时间字段取出后的默认时间格式 + 'datetime_format' => 'Y-m-d H:i:s', + + // 数据库连接配置信息 + 'connections' => [ + 'mysql' => [ + // 数据库类型 + 'type' => env('database.type', 'mysql'), + // 服务器地址 + 'hostname' => env('database.hostname', '127.0.0.1'), + // 数据库名 + 'database' => env('database.database', ''), + // 用户名 + 'username' => env('database.username', 'root'), + // 密码 + 'password' => env('database.password', ''), + // 端口 + 'hostport' => env('database.hostport', '3306'), + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => env('database.charset', 'utf8'), + // 数据库表前缀 + 'prefix' => env('database.prefix', ''), + + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 是否严格检查字段是否存在 + 'fields_strict' => true, + // 是否需要断线重连 + 'break_reconnect' => false, + // 监听SQL + 'trigger_sql' => env('app_debug', true), + // 开启字段缓存 + 'fields_cache' => false, + // 字段缓存路径 + 'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR, + ], + + // 更多的数据库配置信息 + ], +]; diff --git a/config/filesystem.php b/config/filesystem.php new file mode 100644 index 0000000..965297e --- /dev/null +++ b/config/filesystem.php @@ -0,0 +1,24 @@ + env('filesystem.driver', 'local'), + // 磁盘列表 + 'disks' => [ + 'local' => [ + 'type' => 'local', + 'root' => app()->getRuntimePath() . 'storage', + ], + 'public' => [ + // 磁盘类型 + 'type' => 'local', + // 磁盘路径 + 'root' => app()->getRootPath() . 'public/storage', + // 磁盘路径对应的外部URL路径 + 'url' => '/storage', + // 可见性 + 'visibility' => 'public', + ], + // 更多的磁盘配置信息 + ], +]; diff --git a/config/lang.php b/config/lang.php new file mode 100644 index 0000000..e3b4986 --- /dev/null +++ b/config/lang.php @@ -0,0 +1,25 @@ + env('lang.default_lang', 'zh-cn'), + // 允许的语言列表 + 'allow_lang_list' => [], + // 多语言自动侦测变量名 + 'detect_var' => 'lang', + // 是否使用Cookie记录 + 'use_cookie' => true, + // 多语言cookie变量 + 'cookie_var' => 'think_lang', + // 扩展语言包 + 'extend_list' => [], + // Accept-Language转义为对应语言包名称 + 'accept_language' => [ + 'zh-hans-cn' => 'zh-cn', + ], + // 是否支持语言分组 + 'allow_group' => false, +]; diff --git a/config/log.php b/config/log.php new file mode 100644 index 0000000..8de6c82 --- /dev/null +++ b/config/log.php @@ -0,0 +1,45 @@ + env('log.channel', 'file'), + // 日志记录级别 + 'level' => [], + // 日志类型记录的通道 ['error'=>'email',...] + 'type_channel' => [], + // 关闭全局日志写入 + 'close' => false, + // 全局日志处理 支持闭包 + 'processor' => null, + + // 日志通道列表 + 'channels' => [ + 'file' => [ + // 日志记录方式 + 'type' => 'File', + // 日志保存目录 + 'path' => '', + // 单文件日志写入 + 'single' => false, + // 独立日志级别 + 'apart_level' => [], + // 最大日志文件数量 + 'max_files' => env('log.max_files', 0), + // 使用JSON格式记录 + 'json' => false, + // 日志处理 + 'processor' => null, + // 关闭通道日志写入 + 'close' => false, + // 日志输出格式化 + 'format' => '[%s][%s] %s', + // 是否实时写入 + 'realtime_write' => false, + ], + // 其它日志通道配置 + ], + +]; diff --git a/config/middleware.php b/config/middleware.php new file mode 100644 index 0000000..7e1972f --- /dev/null +++ b/config/middleware.php @@ -0,0 +1,8 @@ + [], + // 优先级设置,此数组中的中间件会按照数组中的顺序优先执行 + 'priority' => [], +]; diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..423c3a0 --- /dev/null +++ b/config/queue.php @@ -0,0 +1,21 @@ + +// +---------------------------------------------------------------------- + +return [ + 'default' => 'database', + 'connections' => [ + 'database' => [ + 'type' => 'database', + 'queue' => 'default', + 'table' => 'jobs_t', + ], + ], +]; diff --git a/config/route.php b/config/route.php new file mode 100644 index 0000000..955eeec --- /dev/null +++ b/config/route.php @@ -0,0 +1,45 @@ + '/', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // URL普通方式参数 用于自动生成 + 'url_common_param' => true, + // 是否开启路由延迟解析 + 'url_lazy_route' => false, + // 是否强制使用路由 + 'url_route_must' => false, + // 合并路由规则 + 'route_rule_merge' => false, + // 路由是否完全匹配 + 'route_complete_match' => false, + // 访问控制器层名称 + 'controller_layer' => 'controller', + // 空控制器名 + 'empty_controller' => 'Error', + // 是否使用控制器后缀 + 'controller_suffix' => false, + // 默认的路由变量规则 + 'default_route_pattern' => '[\w\.]+', + // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 + 'request_cache' => false, + // 请求缓存有效期 + 'request_cache_expire' => null, + // 全局请求缓存排除规则 + 'request_cache_except' => [], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 操作方法后缀 + 'action_suffix' => '', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..c1ef6e1 --- /dev/null +++ b/config/session.php @@ -0,0 +1,19 @@ + 'PHPSESSID', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // 驱动方式 支持file cache + 'type' => 'file', + // 存储连接标识 当type使用cache的时候有效 + 'store' => null, + // 过期时间 + 'expire' => 1440, + // 前缀 + 'prefix' => '', +]; diff --git a/config/template.php b/config/template.php new file mode 100644 index 0000000..299bd6f --- /dev/null +++ b/config/template.php @@ -0,0 +1,35 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 模板设置 +// +---------------------------------------------------------------------- + +return [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法 + 'auto_rule' => 1, + // 模板路径 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DIRECTORY_SEPARATOR, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', +]; diff --git a/config/trace.php b/config/trace.php new file mode 100644 index 0000000..fad2392 --- /dev/null +++ b/config/trace.php @@ -0,0 +1,10 @@ + 'Html', + // 读取的日志通道名 + 'channel' => '', +]; diff --git a/config/view.php b/config/view.php new file mode 100644 index 0000000..01259a0 --- /dev/null +++ b/config/view.php @@ -0,0 +1,25 @@ + 'Think', + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法 + 'auto_rule' => 1, + // 模板目录名 + 'view_dir_name' => 'view', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DIRECTORY_SEPARATOR, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', +]; diff --git a/extend/.gitignore b/extend/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/extend/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..cbc7868 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,8 @@ + + Options +FollowSymlinks -Multiviews + RewriteEngine On + + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e71815a6618c6ef19c78d27840b8995fb2521499 GIT binary patch literal 1150 zcmbVMSx8i26uv?4_SAEaJq7BFqqJE;Q9TBc5JYcLIgSmPnyr-jk`K{>ZB(>aLWVXo z*9E63a&I$RrZR03EEi&&_1^#9`}O_*AViPd;mm*e&-u>z&UX%1)0XhJY?;RY723X~ znzmfiw3Reo@g{fAL(}N{_i=@Ma0M%r6$X8HFcE zpG~1@_%Y6ow1ksJIN%eE0)m_g-8Gd#K%-r;7XvI$t0gLrlUMS(*o zV$Y+$Ct(SJ+L5c+)7OmI%nVG$!vbteaep>7ij6%r*#F`@;?!a~HIJfDIkr7LrT7TO z8Pus^>>;*w*WwO!6s7@#wJgVkVE+^G7)ra2;Ldm_p8Ob6`0br_NQk8JTkP3k{J^jG z*cCa8vT!3JGaq0ucb3{&JkLiTVfXWMD5q9ZyH%ZD)V;jPIT^6ouVd%VG`X~V*0H+F zhl^v6kP#Mn+6Yg-!rHDH>fs|^>X)1U?nncMSj%CIp#G9el3d=+e!&L43iV_6ITI5d zQv>h>y$V~X^k*JwD7m;pl{iR^$K%uN!-g$vq?qse=KxBm_3+$BoO#pw7gpx+aR#|L z%6Dm{!D`%_jIeKm8ajyn9!EZFoOpW+Tl5oZR|^>D;?7A9ZiV-%JuQ#*owco@x{a zD-|ENtov7tOFzK5r}KRMSHhkEb!7aa$$nhqBKuHtV!cJ5I+?Si!w-Hm{`)ye +// +---------------------------------------------------------------------- + +// [ 应用入口文件 ] +namespace think; + +require __DIR__ . '/../vendor/autoload.php'; + +// 执行HTTP应用并响应 +$http = (new App())->http; + +$response = $http->run(); + +$response->send(); + +$http->end($response); diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..eb05362 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/public/router.php b/public/router.php new file mode 100644 index 0000000..9b39a62 --- /dev/null +++ b/public/router.php @@ -0,0 +1,19 @@ + +// +---------------------------------------------------------------------- +// $Id$ + +if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SCRIPT_NAME"])) { + return false; +} else { + $_SERVER["SCRIPT_FILENAME"] = __DIR__ . '/index.php'; + + require __DIR__ . "/index.php"; +} diff --git a/public/static/.gitignore b/public/static/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/public/static/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/route/app.php b/route/app.php new file mode 100644 index 0000000..d8e09e3 --- /dev/null +++ b/route/app.php @@ -0,0 +1,17 @@ + +// +---------------------------------------------------------------------- +use think\facade\Route; + +Route::get('think', function () { + return 'hello,ThinkPHP6!'; +}); + +Route::get('hello/:name', 'index/hello'); diff --git a/route/route.php b/route/route.php new file mode 100644 index 0000000..2804cfc --- /dev/null +++ b/route/route.php @@ -0,0 +1,21 @@ + +// +---------------------------------------------------------------------- +use think\facade\Route; + +Route::get('think', function () { + return 'hello,ThinkPHP5!'; +}); + +Route::get('hello/:name', 'index/hello'); + +return [ + +]; diff --git a/runtime/session/sess_f0c35153899e626149d7aa338fcf92c5 b/runtime/session/sess_f0c35153899e626149d7aa338fcf92c5 new file mode 100644 index 0000000..21c27e5 --- /dev/null +++ b/runtime/session/sess_f0c35153899e626149d7aa338fcf92c5 @@ -0,0 +1 @@ +a:2:{s:10:"login_time";i:1613982663;s:11:"last_action";i:1613982691;} \ No newline at end of file diff --git a/runtime/temp/2c7bddf2602390fe3491ea487d866ef2.php b/runtime/temp/2c7bddf2602390fe3491ea487d866ef2.php new file mode 100644 index 0000000..dd92aac --- /dev/null +++ b/runtime/temp/2c7bddf2602390fe3491ea487d866ef2.php @@ -0,0 +1,433 @@ + + + + + + + + + + 粮仓 + + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
-
+
+ +
+
+
+ +
+ 月 + 日 +
+
-
+
+ 月 + 日 +
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+
+
+
+ +
+ 万 +
+
-
+
+ 万 +
+
+
+ +
+ + + +
+
+
+ +
+ + 0): ?> + + 0): ?> + + +
+
+
+ + 重置条件 + + +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + diff --git a/runtime/temp/4a1403173de2fcfc7cfff92a06a360dc.php b/runtime/temp/4a1403173de2fcfc7cfff92a06a360dc.php new file mode 100644 index 0000000..b782702 --- /dev/null +++ b/runtime/temp/4a1403173de2fcfc7cfff92a06a360dc.php @@ -0,0 +1,499 @@ + + + + + + + + + + 粮仓 + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ +
+ + + + + +
+
+
+ +
+ + +
+
+ +
+ [下载车辆信息导入模板] +
+ + + +
+
+
+ +
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + diff --git a/runtime/temp/dc3e3ddb370b0b9564cb52310d05c516.php b/runtime/temp/dc3e3ddb370b0b9564cb52310d05c516.php new file mode 100644 index 0000000..6b2e762 --- /dev/null +++ b/runtime/temp/dc3e3ddb370b0b9564cb52310d05c516.php @@ -0,0 +1,185 @@ + + + + + + + + + + 粮仓 + + + + + + + + + + +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ + 未处理 + 0): ?> + 导出至清洗 + 0 && $info['is_update_bhx'] > 0): ?> + 清洗成功 + 0 && $info['is_update_bhx'] < 0): ?> + 清洗失败 + 0 && $info['is_export_failed'] > 0): ?> + 导出清洗失败 + 0 && $info['is_export_failed_bmc'] > 0): ?> + 导出清洗失败至上传 + 0 && $info['is_update_bhx'] > 0 && $info['is_export_bmc'] > 0): ?> + 导出清洗成功至上传 + 0): ?> + 导出未处理至上传 + +
+
+
+ + + +
+
+
+ + + + + + + + + + + diff --git a/think b/think new file mode 100644 index 0000000..2429d22 --- /dev/null +++ b/think @@ -0,0 +1,10 @@ +#!/usr/bin/env php +console->run(); \ No newline at end of file diff --git a/view/README.md b/view/README.md new file mode 100644 index 0000000..360eb24 --- /dev/null +++ b/view/README.md @@ -0,0 +1 @@ +如果不使用模板,可以删除该目录 \ No newline at end of file diff --git a/更新.bat b/更新.bat new file mode 100644 index 0000000..bddc158 --- /dev/null +++ b/更新.bat @@ -0,0 +1 @@ +git pull \ No newline at end of file