From 1a191f2350634c964331a80f2bb3f133f71f3a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=B1=E6=98=AF=E9=82=A3=E4=B8=AA=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=8B=97?= <1051690893@qq.com> Date: Mon, 13 Dec 2021 07:58:42 +0000 Subject: [PATCH 01/25] =?UTF-8?q?update=20view/php/index.php.=20=E5=9C=A8?= =?UTF-8?q?=E2=80=9C/captcha/check=E2=80=9D=E5=88=A4=E6=96=AD=E5=86=85?= =?UTF-8?q?=EF=BC=8C=E7=94=B1AjCaptcharHelper::ostRequest=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E4=B8=BAAjCaptcharHelper::postRequest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- view/php/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/php/index.php b/view/php/index.php index 8b87517..db85035 100644 --- a/view/php/index.php +++ b/view/php/index.php @@ -11,7 +11,7 @@ if($requestUri == '/captcha/get'){ $payload = file_get_contents('php://input'); header('Content-Type: application/json;charset=UTF-8'); header('Transfer-Encoding: chunked'); - echo AjCaptcharHelper::ostRequest('https://captcha.anji-plus.com/captcha-api/captcha/check', $payload); + echo AjCaptcharHelper::postRequest('https://captcha.anji-plus.com/captcha-api/captcha/check', $payload); }elseif($requestUri == '/captcha/verify'){ $payload = file_get_contents('php://input'); header('Content-Type: application/json;charset=UTF-8'); -- Gitee From 862800436f86ec9e2f22c5f1b05e4700e63ebdaf Mon Sep 17 00:00:00 2001 From: seepine Date: Tue, 28 Dec 2021 02:41:07 +0000 Subject: [PATCH 02/25] fix(verify-slide): fix can drag out verifyArea --- .../vue3/src/components/verifition/Verify/VerifySlide.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/view/vue3/src/components/verifition/Verify/VerifySlide.vue b/view/vue3/src/components/verifition/Verify/VerifySlide.vue index fcd18a5..73c8a9a 100644 --- a/view/vue3/src/components/verifition/Verify/VerifySlide.vue +++ b/view/vue3/src/components/verifition/Verify/VerifySlide.vue @@ -33,7 +33,7 @@ 'top':'-' + (parseInt(setSize.imgHeight) + vSpace) + 'px', 'background-size': setSize.imgWidth + ' ' + setSize.imgHeight, }"> - + @@ -223,11 +223,11 @@ } var bar_area_left = barArea.value.getBoundingClientRect().left; var move_block_left = x - bar_area_left //小方块相对于父元素的left值 - if (move_block_left >= barArea.value.offsetWidth - parseInt(parseInt(blockSize.width) / 2) - 2) { - move_block_left = barArea.value.offsetWidth - parseInt(parseInt(blockSize.width) / 2) - 2; + if (move_block_left >= barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2) { + move_block_left = barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2; } if (move_block_left <= 0) { - move_block_left = parseInt(parseInt(blockSize.width) / 2); + move_block_left = parseInt(parseInt(blockSize.value.width) / 2); } //拖动后小方块的left值 moveBlockLeft.value = (move_block_left - startLeft.value) + "px" -- Gitee From a4b91eb119804bf3daed150bc00ae3edafe6894b Mon Sep 17 00:00:00 2001 From: uctoo Date: Fri, 28 Jan 2022 16:00:13 +0800 Subject: [PATCH 03/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0thinkphp=E6=A1=86?= =?UTF-8?q?=E6=9E=B6route.php=E8=B7=AF=E7=94=B1=E5=AE=9A=E4=B9=89=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E5=BF=AB=E9=80=9F=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E7=A4=BA=E4=BE=8B=E9=A1=B9=E7=9B=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/php/readme.md | 6 +++ .../test/thinkphp/app/controller/Index.php | 19 ++++++++ service/php/test/thinkphp/config/route.php | 45 +++++++++++++++++++ service/php/test/thinkphp/route/app.php | 18 ++++++++ 4 files changed, 88 insertions(+) create mode 100644 service/php/test/thinkphp/config/route.php create mode 100644 service/php/test/thinkphp/route/app.php diff --git a/service/php/readme.md b/service/php/readme.md index fc048b7..1d73d70 100644 --- a/service/php/readme.md +++ b/service/php/readme.md @@ -25,6 +25,12 @@ test 目录下示例了三种使用方式,phper可以参考使用。[查看dem 2. 基于框架使用的场景,输入安装命令`composer require fastknife/ajcaptcha`(稳定版) 或者`composer require fastknife/ajcaptcha dev-master`(最新版) ,建议使用composer阿里源(`https://mirrors.aliyun.com/composer`) * 支持各种前沿框架(ThinkPHP, YII, Laravel, Hyperf,IMI,Swoft,EasySwoole) * 本软件包内,未使用单例、注册树(容器)模式,不含任何全局变量,基于swoole开发的同学不用担心内存泄露。 + +3. 以thinkphp框架后端和vue框架前端为例,在本地开发环境运行起示例项目说明: +3.1 开启命令行窗口,进入 captcha\service\php\test\thinkphp 目录,执行 `composer install` 命令安装依赖,执行 `php think run` 命令启动接口服务。 +3.2 修改 captcha\view\vue\config\dev.env.js 中 BASE_API: '"http://localhost:8000"' ,取值与 3.1中启动的接口服务地址一致。 +3.3 开启命令行窗口,进入 captcha\view\vue 目录,执行 `npm install` 命令安装依赖,执行 `npm run dev` 命令启动前端项目。 + #### 项目结构 > 本软件包基于整洁架构理念,设计了下文的目录结构。Domain(领域层)作为内层同心圆承担所有业务逻辑功能,Service(服务层)并向最外层Controller(需自行实现)提供粗颗粒度服务。 diff --git a/service/php/test/thinkphp/app/controller/Index.php b/service/php/test/thinkphp/app/controller/Index.php index a773762..0494b63 100644 --- a/service/php/test/thinkphp/app/controller/Index.php +++ b/service/php/test/thinkphp/app/controller/Index.php @@ -21,6 +21,16 @@ class Index } catch (\Exception $e) { $this->error($e->getMessage()); } + /* 如果开发框架开启了debug、trace,导致前端项目无法正确获取到后台接口的返回数据,可以修改为本注释内的接口返回方式 + $response = [ + 'error' => false, + 'repCode' => '0000', + 'repData' => $data, + 'repMsg' => null, + 'success' => true, + ]; + return json($response);*/ + $this->success($data); } @@ -34,6 +44,15 @@ class Index } catch (\Exception $e) { $this->error($e->getMessage()); } + /* 如果开发框架开启了debug、trace,导致前端项目无法正确获取到后台接口的返回数据,可以修改为本注释内的接口返回方式 + $response = [ + 'error' => false, + 'repCode' => '0000', + 'repData' => [], + 'repMsg' => null, + 'success' => true, + ]; + return json($response);*/ $this->success([]); } diff --git a/service/php/test/thinkphp/config/route.php b/service/php/test/thinkphp/config/route.php new file mode 100644 index 0000000..955eeec --- /dev/null +++ b/service/php/test/thinkphp/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/service/php/test/thinkphp/route/app.php b/service/php/test/thinkphp/route/app.php new file mode 100644 index 0000000..e82de91 --- /dev/null +++ b/service/php/test/thinkphp/route/app.php @@ -0,0 +1,18 @@ + +// +---------------------------------------------------------------------- +use think\facade\Route; + +Route::get('think', function () { + return 'hello,ThinkPHP6!'; +}); + +Route::post('/captcha/get', 'Index/index')->allowCrossDomain(); +Route::post('/captcha/check', 'Index/check')->allowCrossDomain(); \ No newline at end of file -- Gitee From 8e13c7abba04b85827db02f8faee9c5a93b76fcf Mon Sep 17 00:00:00 2001 From: Raod <1130305001@qq.com> Date: Fri, 18 Feb 2022 06:45:00 +0000 Subject: [PATCH 04/25] update README_CN.md. --- README_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index 5f01315..f38e1c5 100644 --- a/README_CN.md +++ b/README_CN.md @@ -76,7 +76,7 @@ I Your application is running here: http://localhost:8081 # 6 技术支持,如有问题,请提交Issue -微信一二群已满,现开放三群。微信群码会不定期更新。 +加微信前请备注AJ-Captcha。
微信群地址:https://captcha.anji-plus.com/static/weixin.png | 微信 | qq | -- Gitee From 188a1e18df23ea8c2acff7b29bbee83ccbc69d2e Mon Sep 17 00:00:00 2001 From: Foming Date: Fri, 25 Feb 2022 03:04:22 +0000 Subject: [PATCH 05/25] update README_CN.md. --- README_CN.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README_CN.md b/README_CN.md index f38e1c5..a5e7923 100644 --- a/README_CN.md +++ b/README_CN.md @@ -6,6 +6,8 @@     AJ-Captcha行为验证码,包含滑动拼图、文字点选两种方式,UI支持弹出和嵌入两种方式。后端提供Java实现,前端提供了php、angular、html、vue、uni-app、flutter、android、ios等代码示例。 # 1 在线体验 +**在线体验暂时下线** + ####   1.1 电脑在线体验:[https://captcha.anji-plus.com/](https://captcha.anji-plus.com/ "链接") ####   1.2 在线文档:[https://captcha.anji-plus.com/#/doc](https://captcha.anji-plus.com/#/doc "doc")
####   1.3 微信小程序和H5在线体验(基于uni-app实现) -- Gitee From 39a6e56c5c42e9352155b3f760abc47337647f30 Mon Sep 17 00:00:00 2001 From: Foming Date: Fri, 25 Feb 2022 04:32:59 +0000 Subject: [PATCH 06/25] update README_CN.md. --- README_CN.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/README_CN.md b/README_CN.md index a5e7923..70b2784 100644 --- a/README_CN.md +++ b/README_CN.md @@ -8,23 +8,11 @@ # 1 在线体验 **在线体验暂时下线** -####   1.1 电脑在线体验:[https://captcha.anji-plus.com/](https://captcha.anji-plus.com/ "链接") -####   1.2 在线文档:[https://captcha.anji-plus.com/#/doc](https://captcha.anji-plus.com/#/doc "doc")
-####   1.3 微信小程序和H5在线体验(基于uni-app实现) -    如果图片未能正常展示,可查看码云,和github同步 [码云]( https://gitee.com/anji-plus/captcha "码云")
- ![微信小程序](https://captcha.anji-plus.com/static/8cm.jpg "微信小程序")  ![h5](https://images.gitee.com/uploads/images/2020/0429/174246_c33e3fa3_1728982.png "h5.png")
-     微信小程序Demo            uni-app H5 demo - # 2 功能概述 ####   2.1 组件介绍    行为验证码采用嵌入式集成方式,接入方便,安全,高效。抛弃了传统字符型验证码展示-填写字符-比对答案的流程,采用验证码展示-采集用户行为-分析用户行为流程,用户只需要产生指定的行为轨迹,不需要键盘手动输入,极大优化了传统验证码用户体验不佳的问题;同时,快速、准确的返回人机判定结果。目前对外提供两种类型的验证码,其中包含滑动拼图、文字点选。如图1-1、1-2所示。若希望不影响原UI布局,可采用弹出式交互。
   后端基于Java实现,提供纯Java.jar和SpringBoot Starter。前端提供了Android、iOS、Futter、Uni-App、ReactNative、Vue、Angular、Html、Php等多端示例。
-| 滑动拼图 | 文字点选 | -| --- | --- | -|![滑动拼图](https://captcha.anji-plus.com/static/blockPuzzle.png "滑动拼图") |![点选文字](https://captcha.anji-plus.com/static/clickWord.png "点选文字")| -| 图1-1 | 图1-2 | -
####   2.2 概念术语描述 | 术语 | 描述 | @@ -39,7 +27,6 @@ ③ 用户提交表单,前端将第二步的输出一同提交到后台
④ 验证数据随表单提交到后台后,后台需要调用captchaService.verification做二次校验。
⑤ 第4步返回校验通过/失败到产品应用后端,再返回到前端。如下图所示。 -![时序图](https://captcha.anji-plus.com/static/shixu.png "时序图") # 4 目录结构 ├─core
@@ -79,7 +66,7 @@ I Your application is running here: http://localhost:8081 # 6 技术支持,如有问题,请提交Issue 加微信前请备注AJ-Captcha。 -
微信群地址:https://captcha.anji-plus.com/static/weixin.png +
微信群地址 | 微信 | qq | | --- | --- | -- Gitee From 2df4be1033649eacc23d61b2e4a65aa8fb7360cf Mon Sep 17 00:00:00 2001 From: Foming Date: Wed, 2 Mar 2022 08:13:07 +0000 Subject: [PATCH 07/25] update README_CN.md. --- README_CN.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README_CN.md b/README_CN.md index 70b2784..7406159 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,3 +1,5 @@ +# **在线体验暂时下线** + [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)[![Total Lines](https://tokei.rs/b1/github/anji-plus/captcha?category=lines)](https://github.com/anji-plus/captcha) [![EN doc](https://img.shields.io/badge/document-English-blue.svg)](README.md)[![CN doc](https://img.shields.io/badge/文档-中文版-blue.svg)](README_CN.md) -- Gitee From 8608fd6c8a5d0f76e22ce4596677d3fda405c4c4 Mon Sep 17 00:00:00 2001 From: Foming Date: Wed, 2 Mar 2022 08:13:36 +0000 Subject: [PATCH 08/25] update README_CN.md. --- README_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index 7406159..d3fddfe 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,4 +1,4 @@ -# **在线体验暂时下线** +# **在线体验暂时下线 !!!** [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)[![Total Lines](https://tokei.rs/b1/github/anji-plus/captcha?category=lines)](https://github.com/anji-plus/captcha) -- Gitee From b97fac81ce9096d1c65828d21e10fbb51e21eac4 Mon Sep 17 00:00:00 2001 From: Raod <1130305001@qq.com> Date: Thu, 23 Jun 2022 16:28:56 +0800 Subject: [PATCH 09/25] logo-touchstone --- ...221\345\212\250\346\213\274\345\233\276.gif" | Bin 0 -> 73909 bytes ...271\351\200\211\346\226\207\345\255\227.gif" | Bin 0 -> 44076 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 "images/\346\273\221\345\212\250\346\213\274\345\233\276.gif" create mode 100644 "images/\347\202\271\351\200\211\346\226\207\345\255\227.gif" diff --git "a/images/\346\273\221\345\212\250\346\213\274\345\233\276.gif" "b/images/\346\273\221\345\212\250\346\213\274\345\233\276.gif" new file mode 100644 index 0000000000000000000000000000000000000000..0f170423bc1aa339e1d79e50aaf508b02db339a0 GIT binary patch literal 73909 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 Kdz;s@=>8{(@pPjA literal 0 HcmV?d00001 diff --git "a/images/\347\202\271\351\200\211\346\226\207\345\255\227.gif" "b/images/\347\202\271\351\200\211\346\226\207\345\255\227.gif" new file mode 100644 index 0000000000000000000000000000000000000000..0910b153794ce25e5a1638fe2d1b9c5a4774222f GIT binary patch literal 44076 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 Date: Thu, 23 Jun 2022 08:33:34 +0000 Subject: [PATCH 10/25] update README_CN.md. --- README_CN.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README_CN.md b/README_CN.md index d3fddfe..5829e80 100644 --- a/README_CN.md +++ b/README_CN.md @@ -14,6 +14,13 @@ ####   2.1 组件介绍    行为验证码采用嵌入式集成方式,接入方便,安全,高效。抛弃了传统字符型验证码展示-填写字符-比对答案的流程,采用验证码展示-采集用户行为-分析用户行为流程,用户只需要产生指定的行为轨迹,不需要键盘手动输入,极大优化了传统验证码用户体验不佳的问题;同时,快速、准确的返回人机判定结果。目前对外提供两种类型的验证码,其中包含滑动拼图、文字点选。如图1-1、1-2所示。若希望不影响原UI布局,可采用弹出式交互。
   后端基于Java实现,提供纯Java.jar和SpringBoot Starter。前端提供了Android、iOS、Futter、Uni-App、ReactNative、Vue、Angular、Html、Php等多端示例。
+ + +| 滑动拼图 | 文字点选 | +| --- | --- | +|![滑动拼图](images/%E6%BB%91%E5%8A%A8%E6%8B%BC%E5%9B%BE.gif "滑动拼图") |![点选文字](images/%E7%82%B9%E9%80%89%E6%96%87%E5%AD%97.gif "点选文字")| +| 图1-1 | 图1-2 | +
####   2.2 概念术语描述 -- Gitee From baac31277ab971fa26cf3bbe3ca14b88522c4cbb Mon Sep 17 00:00:00 2001 From: Raod <1130305001@qq.com> Date: Thu, 23 Jun 2022 09:16:39 +0000 Subject: [PATCH 11/25] update README_CN.md. --- README_CN.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README_CN.md b/README_CN.md index 5829e80..afa5aa7 100644 --- a/README_CN.md +++ b/README_CN.md @@ -36,6 +36,7 @@ ③ 用户提交表单,前端将第二步的输出一同提交到后台
④ 验证数据随表单提交到后台后,后台需要调用captchaService.verification做二次校验。
⑤ 第4步返回校验通过/失败到产品应用后端,再返回到前端。如下图所示。 +![时序图](view/vue/static/shixu.png "时序图") # 4 目录结构 ├─core
@@ -84,12 +85,10 @@ I Your application is running here: http://localhost:8081 #### 开源不易,劳烦各位star ☺ #### 感谢JetBrains 的支持 - ##### JetBrains:[https://www.jetbrains.com/?from=AJ-Captcha](https://www.jetbrains.com/?from=AJ-Captcha "链接")
# Stargazers over time -[![Stargazers over time](https://whnb.wang/img/anji-plus/captcha?e=604800)](https://whnb.wang/anji-plus/captcha?e=604800) [![Stargazers over time](https://starchart.cc/anji-plus/captcha.svg)](https://starchart.cc/anji-plus/captcha) -- Gitee From c4c2bfc474ef164f7d452db8e252cb126f511e3a Mon Sep 17 00:00:00 2001 From: Raod <1130305001@qq.com> Date: Fri, 8 Jul 2022 10:35:32 +0800 Subject: [PATCH 12/25] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E9=87=8D=E6=96=B0=E4=B8=8A=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README_CN.md | 1 + view/doc/docs/README.md | 22 +--------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/README_CN.md b/README_CN.md index afa5aa7..fafa87f 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,4 +1,5 @@ # **在线体验暂时下线 !!!** +####   在线文档:[https://ajcaptcha.beliefteam.cn/captcha-doc/](https://ajcaptcha.beliefteam.cn/captcha-doc/ "doc")
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)[![Total Lines](https://tokei.rs/b1/github/anji-plus/captcha?category=lines)](https://github.com/anji-plus/captcha) diff --git a/view/doc/docs/README.md b/view/doc/docs/README.md index 60f5bd7..b2c3e4a 100644 --- a/view/doc/docs/README.md +++ b/view/doc/docs/README.md @@ -1,21 +1,9 @@ -# 在线体验 -####   1.1 电脑在线体验:[https://captcha.anji-plus.com/](https://captcha.anji-plus.com/ "链接") -####   1.2 在线文档:[https://captcha.anji-plus.com/#/doc](https://captcha.anji-plus.com/#/doc "doc")
-####   1.3 微信小程序和H5在线体验(基于uni-app实现) -   如果图片未能正常展示,可查看码云,和github同步 [码云]( https://gitee.com/anji-plus/captcha "码云")
-![微信小程序](https://captcha.anji-plus.com/static/8cm.jpg "微信小程序")  
-    微信小程序Demo             # 功能概述 ####   2.1 组件介绍    行为验证码采用嵌入式集成方式,接入方便,安全,高效。抛弃了传统字符型验证码展示-填写字符-比对答案的流程,采用验证码展示-采集用户行为-分析用户行为流程,用户只需要产生指定的行为轨迹,不需要键盘手动输入,极大优化了传统验证码用户体验不佳的问题;同时,快速、准确的返回人机判定结果。目前对外提供两种类型的验证码,其中包含滑动拼图、文字点选。如图1-1、1-2所示。若希望不影响原UI布局,可采用弹出式交互。
   后端基于Java实现,提供纯Java.jar和SpringBoot Starter。前端提供了Android、iOS、Futter、Uni-App、ReactNative、Vue、Angular、Html、Php等多端示例。
-| 滑动拼图 | 文字点选 | -| --- | --- | -|![滑动拼图](https://captcha.anji-plus.com/static/blockPuzzle.png "滑动拼图") |![点选文字](https://captcha.anji-plus.com/static/clickWord.png "点选文字")| -| 图1-1 | 图1-2 | -
####   2.2 概念术语描述 | 术语 | 描述 | @@ -30,7 +18,7 @@ ③ 用户提交表单,前端将第二步的输出一同提交到后台
④ 验证数据随表单提交到后台后,后台需要调用captchaService.verification做二次校验。
⑤ 第4步返回校验通过/失败到产品应用后端,再返回到前端。如下图所示。 -![时序图](https://captcha.anji-plus.com/static/shixu.png "时序图") + # 目录结构 ├─core
@@ -66,14 +54,6 @@ I Your application is running here: http://localhost:8081  详细的前后端接入文档,后端示例代码service目录下,前端示例代码view目录下。 -# 近期计划 -####   6.1 增加weex示例 -####   6.2 增加ReactNative示例(已添加) - -# 技术支持微信群 -微信一群已满,现开放二群。github可能有缓存,不会自动更新。 -
微信群地址:https://captcha.anji-plus.com/static/weixin.png - #### 开源不易,劳烦各位star ☺ -- Gitee From 9bbb7c1f53d6d70bd11c1039bb6706df8829dac3 Mon Sep 17 00:00:00 2001 From: Foming Date: Thu, 22 Sep 2022 07:18:07 +0000 Subject: [PATCH 13/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README_CN.md b/README_CN.md index 848897f..4b23a21 100644 --- a/README_CN.md +++ b/README_CN.md @@ -76,13 +76,10 @@ I Your application is running here: http://localhost:8081  详细的前后端接入文档,后端示例代码service目录下,前端示例代码view目录下。 -# 6 技术支持,如有问题,请提交Issue -加微信前请备注AJ-Captcha。 -
微信群地址 - -| 微信 | qq | -| --- | --- | -||| +# 6 技术支持,如有问题,请提交[Issue](https://gitee.com/anji-plus/captcha/issues) +个人企业微信:加微信进群备注 **AJ-Captcha** 或者 **Captcha**
+如果不是为了进群,请直接说明来意,每天加群的都很多,企微也是我们自己的工作企微,会有很多消息会被刷下去,如果半天没有回复你,请发送多次。如果加了之后一言不发,不好意思,我直接忽略,我也不知道你要干嘛。
+ #### 开源不易,劳烦各位star ☺ -- Gitee From 69f8d62dd9c8a410eb22393129344208d4b821a1 Mon Sep 17 00:00:00 2001 From: Foming Date: Fri, 23 Sep 2022 00:43:44 +0000 Subject: [PATCH 14/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index 4b23a21..a3d4c7b 100644 --- a/README_CN.md +++ b/README_CN.md @@ -89,5 +89,8 @@ I Your application is running here: http://localhost:8081
-# Stargazers over time + + +## Stargazers over time + [![Stargazers over time](https://starchart.cc/anji-plus/captcha.svg)](https://starchart.cc/anji-plus/captcha) -- Gitee From 91f14db4185f5059605d40bc6ab867cf0136e397 Mon Sep 17 00:00:00 2001 From: Foming Date: Mon, 5 Dec 2022 08:10:02 +0000 Subject: [PATCH 15/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_CN.md b/README_CN.md index a3d4c7b..c01e556 100644 --- a/README_CN.md +++ b/README_CN.md @@ -77,8 +77,8 @@ I Your application is running here: http://localhost:8081 # 6 技术支持,如有问题,请提交[Issue](https://gitee.com/anji-plus/captcha/issues) -个人企业微信:加微信进群备注 **AJ-Captcha** 或者 **Captcha**
-如果不是为了进群,请直接说明来意,每天加群的都很多,企微也是我们自己的工作企微,会有很多消息会被刷下去,如果半天没有回复你,请发送多次。如果加了之后一言不发,不好意思,我直接忽略,我也不知道你要干嘛。
+个人企业微信:加微信进群备注 **AJ-Captcha** 或者 **Captcha**,**一定要加备注!!!**
+如果不是为了进群,请直接说明来意,每天加群的都很多,企微也是我们自己的工作企微,会有很多消息会被刷下去,如果半天没有回复你,请过段时间再发送。
#### 开源不易,劳烦各位star ☺ -- Gitee From 9144091ed7c99dc85a173a6a33d54c207f10c7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A5=81=E5=BF=97=E8=BF=9C?= Date: Tue, 7 Feb 2023 17:00:47 +0800 Subject: [PATCH 16/25] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20flutter=20nu?= =?UTF-8?q?ll=5Fsafety=20demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../demo/ios/Flutter/AppFrameworkInfo.plist | 2 +- .../demo/ios/Runner.xcodeproj/project.pbxproj | 13 +- .../contents.xcworkspacedata | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- view/flutter/demo/ios/Runner/Info.plist | 2 + .../flutter/demo/lib/request/HttpManager.dart | 4 +- view/flutter/demo/pubspec.lock | 135 +++-- view/flutter/demo_null_safety/.gitignore | 4 + view/flutter/demo_null_safety/README.md | 16 + .../demo_null_safety/android/.gitignore | 7 + .../demo_null_safety/android/app/build.gradle | 75 +++ .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 37 ++ .../com/anjiplus/captcha/MainActivity.kt | 12 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values/styles.xml | 8 + .../app/src/profile/AndroidManifest.xml | 7 + .../demo_null_safety/android/build.gradle | 31 + .../android/gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 6 + .../demo_null_safety/android/settings.gradle | 15 + view/flutter/demo_null_safety/ios/.gitignore | 32 + .../ios/Flutter/AppFrameworkInfo.plist | 26 + .../ios/Flutter/Debug.xcconfig | 1 + .../ios/Flutter/Release.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 503 ++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Runner.xcscheme | 91 +++ .../contents.xcworkspacedata | 7 + .../ios/Runner/AppDelegate.swift | 13 + .../AppIcon.appiconset/Contents.json | 122 ++++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 10932 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 ++ .../ios/Runner/Base.lproj/Main.storyboard | 26 + .../demo_null_safety/ios/Runner/Info.plist | 47 ++ .../ios/Runner/Runner-Bridging-Header.h | 1 + .../lib/captcha/block_puzzle_captcha.dart | 545 ++++++++++++++++++ .../lib/captcha/click_word_captcha.dart | 367 ++++++++++++ view/flutter/demo_null_safety/lib/demo.dart | 23 + view/flutter/demo_null_safety/lib/login.dart | 122 ++++ view/flutter/demo_null_safety/lib/main.dart | 27 + .../lib/request/HttpManager.dart | 90 +++ .../lib/request/SignConfig.dart | 46 ++ .../lib/request/encrypt_util.dart | 30 + .../lib/tools/object_utils.dart | 27 + .../lib/tools/widget_util.dart | 133 +++++ view/flutter/demo_null_safety/pubspec.lock | 230 ++++++++ view/flutter/demo_null_safety/pubspec.yaml | 75 +++ .../demo_null_safety/test/widget_test.dart | 30 + 73 files changed, 3011 insertions(+), 77 deletions(-) create mode 100644 view/flutter/demo_null_safety/.gitignore create mode 100644 view/flutter/demo_null_safety/README.md create mode 100644 view/flutter/demo_null_safety/android/.gitignore create mode 100644 view/flutter/demo_null_safety/android/app/build.gradle create mode 100644 view/flutter/demo_null_safety/android/app/src/debug/AndroidManifest.xml create mode 100644 view/flutter/demo_null_safety/android/app/src/main/AndroidManifest.xml create mode 100644 view/flutter/demo_null_safety/android/app/src/main/kotlin/com/anjiplus/captcha/MainActivity.kt create mode 100644 view/flutter/demo_null_safety/android/app/src/main/res/drawable/launch_background.xml create mode 100644 view/flutter/demo_null_safety/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 view/flutter/demo_null_safety/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 view/flutter/demo_null_safety/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 view/flutter/demo_null_safety/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 view/flutter/demo_null_safety/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 view/flutter/demo_null_safety/android/app/src/main/res/values/styles.xml create mode 100644 view/flutter/demo_null_safety/android/app/src/profile/AndroidManifest.xml create mode 100644 view/flutter/demo_null_safety/android/build.gradle create mode 100644 view/flutter/demo_null_safety/android/gradle.properties create mode 100644 view/flutter/demo_null_safety/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 view/flutter/demo_null_safety/android/settings.gradle create mode 100644 view/flutter/demo_null_safety/ios/.gitignore create mode 100644 view/flutter/demo_null_safety/ios/Flutter/AppFrameworkInfo.plist create mode 100644 view/flutter/demo_null_safety/ios/Flutter/Debug.xcconfig create mode 100644 view/flutter/demo_null_safety/ios/Flutter/Release.xcconfig create mode 100644 view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.pbxproj create mode 100644 view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 view/flutter/demo_null_safety/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 view/flutter/demo_null_safety/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 view/flutter/demo_null_safety/ios/Runner/AppDelegate.swift create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 view/flutter/demo_null_safety/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 view/flutter/demo_null_safety/ios/Runner/Base.lproj/Main.storyboard create mode 100644 view/flutter/demo_null_safety/ios/Runner/Info.plist create mode 100644 view/flutter/demo_null_safety/ios/Runner/Runner-Bridging-Header.h create mode 100644 view/flutter/demo_null_safety/lib/captcha/block_puzzle_captcha.dart create mode 100644 view/flutter/demo_null_safety/lib/captcha/click_word_captcha.dart create mode 100644 view/flutter/demo_null_safety/lib/demo.dart create mode 100644 view/flutter/demo_null_safety/lib/login.dart create mode 100644 view/flutter/demo_null_safety/lib/main.dart create mode 100644 view/flutter/demo_null_safety/lib/request/HttpManager.dart create mode 100644 view/flutter/demo_null_safety/lib/request/SignConfig.dart create mode 100644 view/flutter/demo_null_safety/lib/request/encrypt_util.dart create mode 100644 view/flutter/demo_null_safety/lib/tools/object_utils.dart create mode 100644 view/flutter/demo_null_safety/lib/tools/widget_util.dart create mode 100644 view/flutter/demo_null_safety/pubspec.lock create mode 100644 view/flutter/demo_null_safety/pubspec.yaml create mode 100644 view/flutter/demo_null_safety/test/widget_test.dart diff --git a/view/flutter/demo/ios/Flutter/AppFrameworkInfo.plist b/view/flutter/demo/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f7..f2872cf 100644 --- a/view/flutter/demo/ios/Flutter/AppFrameworkInfo.plist +++ b/view/flutter/demo/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 9.0 diff --git a/view/flutter/demo/ios/Runner.xcodeproj/project.pbxproj b/view/flutter/demo/ios/Runner.xcodeproj/project.pbxproj index 3705cca..d63af51 100644 --- a/view/flutter/demo/ios/Runner.xcodeproj/project.pbxproj +++ b/view/flutter/demo/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ @@ -135,7 +135,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -241,7 +241,6 @@ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -281,7 +280,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -318,7 +317,6 @@ }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -364,7 +362,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -374,7 +372,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -414,7 +411,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/view/flutter/demo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/view/flutter/demo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/view/flutter/demo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/view/flutter/demo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/view/flutter/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/view/flutter/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140c..3db53b6 100644 --- a/view/flutter/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/view/flutter/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone + diff --git a/view/flutter/demo/lib/request/HttpManager.dart b/view/flutter/demo/lib/request/HttpManager.dart index 711b9c6..80bc840 100644 --- a/view/flutter/demo/lib/request/HttpManager.dart +++ b/view/flutter/demo/lib/request/HttpManager.dart @@ -14,8 +14,8 @@ class HttpManager { "content-Type": CONTENT_TYPE_JSON }; //请求base url -// static String baseUrl = "http://10.108.11.46:8080/api"; - static String baseUrl = "https://captcha.anji-plus.com/captcha-api"; + static String baseUrl = "http://127.0.0.1:8080"; +// static String baseUrl = "https://captcha.anji-plus.com/captcha-api"; ///发起网络请求 ///[ url] 请求url diff --git a/view/flutter/demo/pubspec.lock b/view/flutter/demo/pubspec.lock index c25ade4..08ee1ce 100644 --- a/view/flutter/demo/pubspec.lock +++ b/view/flutter/demo/pubspec.lock @@ -5,86 +5,100 @@ packages: dependency: transitive description: name: args - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.5.2" + version: "1.6.0" asn1lib: dependency: transitive description: name: asn1lib - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "0.5.15" + version: "0.6.5" async: dependency: transitive description: name: async - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.3.0" + version: "2.8.2" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.3.1" clock: dependency: transitive description: name: clock - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0" collection: dependency: transitive description: name: collection - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.16.0" convert: dependency: transitive description: name: convert - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.1" crypto: dependency: transitive description: name: crypto - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.5" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.1.3" dio: dependency: "direct main" description: name: dio - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "3.0.9" + version: "3.0.10" encrypt: dependency: "direct main" description: name: encrypt - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.0.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" flutter: dependency: "direct main" description: flutter @@ -99,51 +113,44 @@ packages: dependency: transitive description: name: http_parser - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "3.1.3" + version: "3.1.4" matcher: dependency: transitive description: name: matcher - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" source: hosted - version: "0.12.5" + version: "0.1.4" meta: dependency: transitive description: name: meta - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.1.7" + version: "1.7.0" path: dependency: transitive description: name: path - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.8.0+1" + version: "1.8.1" pointycastle: dependency: transitive description: name: pointycastle - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.0.2" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.0.5" sky_engine: dependency: transitive description: flutter @@ -153,64 +160,64 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.8.2" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" steel_crypt: dependency: "direct main" description: name: steel_crypt - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.5.4" + version: "1.7.1+1" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "0.2.5" + version: "0.4.9" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.1" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.2" sdks: - dart: ">2.4.0 <3.0.0" + dart: ">=2.17.0-0 <3.0.0" diff --git a/view/flutter/demo_null_safety/.gitignore b/view/flutter/demo_null_safety/.gitignore new file mode 100644 index 0000000..8786b94 --- /dev/null +++ b/view/flutter/demo_null_safety/.gitignore @@ -0,0 +1,4 @@ +/.dart_tool/ +/.idea/ +/build/ +.packages \ No newline at end of file diff --git a/view/flutter/demo_null_safety/README.md b/view/flutter/demo_null_safety/README.md new file mode 100644 index 0000000..4090572 --- /dev/null +++ b/view/flutter/demo_null_safety/README.md @@ -0,0 +1,16 @@ +# captcha + +A new Flutter application. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/view/flutter/demo_null_safety/android/.gitignore b/view/flutter/demo_null_safety/android/.gitignore new file mode 100644 index 0000000..bc2100d --- /dev/null +++ b/view/flutter/demo_null_safety/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/view/flutter/demo_null_safety/android/app/build.gradle b/view/flutter/demo_null_safety/android/app/build.gradle new file mode 100644 index 0000000..acf469b --- /dev/null +++ b/view/flutter/demo_null_safety/android/app/build.gradle @@ -0,0 +1,75 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.anjiplus.captcha" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + ndk { + abiFilters 'armeabi-v7a','x86' + } + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + + ndk { + abiFilters 'armeabi-v7a' + } + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/view/flutter/demo_null_safety/android/app/src/debug/AndroidManifest.xml b/view/flutter/demo_null_safety/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..ba4ee87 --- /dev/null +++ b/view/flutter/demo_null_safety/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/view/flutter/demo_null_safety/android/app/src/main/AndroidManifest.xml b/view/flutter/demo_null_safety/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..40685f6 --- /dev/null +++ b/view/flutter/demo_null_safety/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/view/flutter/demo_null_safety/android/app/src/main/kotlin/com/anjiplus/captcha/MainActivity.kt b/view/flutter/demo_null_safety/android/app/src/main/kotlin/com/anjiplus/captcha/MainActivity.kt new file mode 100644 index 0000000..ae94e23 --- /dev/null +++ b/view/flutter/demo_null_safety/android/app/src/main/kotlin/com/anjiplus/captcha/MainActivity.kt @@ -0,0 +1,12 @@ +package com.anjiplus.captcha + +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugins.GeneratedPluginRegistrant + +class MainActivity: FlutterActivity() { + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} diff --git a/view/flutter/demo_null_safety/android/app/src/main/res/drawable/launch_background.xml b/view/flutter/demo_null_safety/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/view/flutter/demo_null_safety/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/view/flutter/demo_null_safety/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/android/app/src/main/res/values/styles.xml b/view/flutter/demo_null_safety/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..00fa441 --- /dev/null +++ b/view/flutter/demo_null_safety/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/view/flutter/demo_null_safety/android/app/src/profile/AndroidManifest.xml b/view/flutter/demo_null_safety/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..ba4ee87 --- /dev/null +++ b/view/flutter/demo_null_safety/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/view/flutter/demo_null_safety/android/build.gradle b/view/flutter/demo_null_safety/android/build.gradle new file mode 100644 index 0000000..3100ad2 --- /dev/null +++ b/view/flutter/demo_null_safety/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/view/flutter/demo_null_safety/android/gradle.properties b/view/flutter/demo_null_safety/android/gradle.properties new file mode 100644 index 0000000..38c8d45 --- /dev/null +++ b/view/flutter/demo_null_safety/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/view/flutter/demo_null_safety/android/gradle/wrapper/gradle-wrapper.properties b/view/flutter/demo_null_safety/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..296b146 --- /dev/null +++ b/view/flutter/demo_null_safety/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/view/flutter/demo_null_safety/android/settings.gradle b/view/flutter/demo_null_safety/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/view/flutter/demo_null_safety/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/view/flutter/demo_null_safety/ios/.gitignore b/view/flutter/demo_null_safety/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /dev/null +++ b/view/flutter/demo_null_safety/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/view/flutter/demo_null_safety/ios/Flutter/AppFrameworkInfo.plist b/view/flutter/demo_null_safety/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..f2872cf --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 9.0 + + diff --git a/view/flutter/demo_null_safety/ios/Flutter/Debug.xcconfig b/view/flutter/demo_null_safety/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/view/flutter/demo_null_safety/ios/Flutter/Release.xcconfig b/view/flutter/demo_null_safety/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.pbxproj b/view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d63af51 --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,503 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.anjiplus.captcha; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.anjiplus.captcha; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.anjiplus.captcha; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/view/flutter/demo_null_safety/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/view/flutter/demo_null_safety/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..3db53b6 --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/view/flutter/demo_null_safety/ios/Runner.xcworkspace/contents.xcworkspacedata b/view/flutter/demo_null_safety/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/view/flutter/demo_null_safety/ios/Runner/AppDelegate.swift b/view/flutter/demo_null_safety/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9ada4725e9b0ddb1deab583e5b5102493aa332 GIT binary patch literal 10932 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 literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 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 literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 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 literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/view/flutter/demo_null_safety/ios/Runner/Base.lproj/LaunchScreen.storyboard b/view/flutter/demo_null_safety/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/view/flutter/demo_null_safety/ios/Runner/Base.lproj/Main.storyboard b/view/flutter/demo_null_safety/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/view/flutter/demo_null_safety/ios/Runner/Info.plist b/view/flutter/demo_null_safety/ios/Runner/Info.plist new file mode 100644 index 0000000..88f1f9f --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + captcha + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + + diff --git a/view/flutter/demo_null_safety/ios/Runner/Runner-Bridging-Header.h b/view/flutter/demo_null_safety/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..7335fdf --- /dev/null +++ b/view/flutter/demo_null_safety/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/view/flutter/demo_null_safety/lib/captcha/block_puzzle_captcha.dart b/view/flutter/demo_null_safety/lib/captcha/block_puzzle_captcha.dart new file mode 100644 index 0000000..1aececc --- /dev/null +++ b/view/flutter/demo_null_safety/lib/captcha/block_puzzle_captcha.dart @@ -0,0 +1,545 @@ +import 'dart:convert'; +import 'dart:math'; + +import 'package:captcha/request/HttpManager.dart'; +import 'package:captcha/request/encrypt_util.dart'; +import 'package:captcha/tools/object_utils.dart'; +import 'package:captcha/tools/widget_util.dart'; +import 'package:flutter/material.dart'; +import 'package:steel_crypt/steel_crypt.dart'; +typedef VoidSuccessCallback = dynamic Function(String v); +class BlockPuzzleCaptchaPage extends StatefulWidget { + final VoidSuccessCallback? onSuccess; //拖放完成后验证成功回调 + final VoidCallback? onFail; //拖放完成后验证失败回调 + + BlockPuzzleCaptchaPage({this.onSuccess, this.onFail}); + + @override + _BlockPuzzleCaptchaPageState createState() => _BlockPuzzleCaptchaPageState(); +} + +class _BlockPuzzleCaptchaPageState extends State + with TickerProviderStateMixin { +// String baseImageBase64 = +// "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"; + String baseImageBase64 = ""; + String slideImageBase64 = ""; + String captchaToken = ""; + String secretKey = "";//加密key + + Size baseSize = Size.zero; //底部基类图片 + Size slideSize = Size.zero; //滑块图片 + + + var sliderColor = Colors.white; //滑块的背景色 + var sliderIcon = Icons.arrow_forward; //滑块的图标 + var movedXBorderColor = Colors.white; //滑块拖动时,左边已滑的区域边框颜色 + double sliderStartX = 0; //滑块未拖前的X坐标 + double sliderXMoved = 0; + bool sliderMoveFinish = false; //滑块拖动结束 + bool checkResultAfterDrag = false; //拖动后的校验结果 + + //-------------动画------------ + int _checkMilliseconds = 0; //滑动时间 + bool _showTimeLine = false; //是否显示动画部件 + bool _checkSuccess = false; //校验是否成功 + late AnimationController controller; + + //高度动画 + late Animation offsetAnimation; + + //底部部件key + GlobalKey _containerKey = new GlobalKey(); + //背景图key + GlobalKey _baseImageKey = new GlobalKey(); + //滑块 + GlobalKey _slideImageKey = new GlobalKey(); + double _bottomSliderSize = 60; + + + //------------动画------------ + + //校验通过 + void checkSuccess(String content) { + setState(() { + checkResultAfterDrag = true; + _checkSuccess = true; + _showTimeLine = true; + }); + _forwardAnimation(); + updateSliderColorIcon(); + + //刷新验证码 + Future.delayed(Duration(milliseconds: 1000)).then((v) { + _reverseAnimation().then((v) { + setState(() { + _showTimeLine = false; + }); + //回调 + if (widget.onSuccess != null) { + widget.onSuccess!(content); + } + //关闭验证码 + print(content); + Navigator.pop(context); + }); + }); + } + + //校验失败 + void checkFail() { + setState(() { + _showTimeLine = true; + _checkSuccess = false; + checkResultAfterDrag = false; + }); + _forwardAnimation(); + updateSliderColorIcon(); + + //刷新验证码 + Future.delayed(Duration(milliseconds: 1000)).then((v) { + _reverseAnimation().then((v) { + setState(() { + _showTimeLine = false; + }); + loadCaptcha(); + //回调 + if (widget.onFail != null) { + widget.onFail!(); + } + }); + }); + } + + //重设滑动颜色与图标 + void updateSliderColorIcon() { + var _sliderColor; //滑块的背景色 + var _sliderIcon; //滑块的图标 + var _movedXBorderColor; //滑块拖动时,左边已滑的区域边框颜色 + + //滑块的背景色 + if (sliderMoveFinish) { + //拖动结束 + _sliderColor = checkResultAfterDrag ? Colors.green : Colors.red; + _sliderIcon = checkResultAfterDrag ? Icons.check : Icons.close; + _movedXBorderColor = checkResultAfterDrag ? Colors.green : Colors.red; + } else { + //拖动未开始或正在拖动中 + _sliderColor = sliderXMoved > 0 ? Color(0xff447ab2) : Colors.white; + _sliderIcon = Icons.arrow_forward; + _movedXBorderColor = Color(0xff447ab2); + } + + sliderColor = _sliderColor; + sliderIcon = _sliderIcon; + movedXBorderColor = _movedXBorderColor; + setState(() {}); + } + + //加载验证码 + void loadCaptcha() { + setState(() { + _showTimeLine = false; + sliderMoveFinish = false; + checkResultAfterDrag = false; + sliderColor = Colors.white; //滑块的背景色 + sliderIcon = Icons.arrow_forward; //滑块的图标 + movedXBorderColor = Colors.white; //滑块拖动时,左边已滑的区域边框颜色 + }); + HttpManager.requestData( + '/captcha/get', {"captchaType": "blockPuzzle"}, {}) + .then((res) async { + if (res['repCode'] != '0000' || res['repData'] == null) { + setState(() { + secretKey = ""; + }); + return; + } + + Map repData = res['repData']; + sliderXMoved = 0; + sliderStartX = 0; + captchaToken = ''; + checkResultAfterDrag = false; + + baseImageBase64 = repData["originalImageBase64"]; + baseImageBase64 = repData["originalImageBase64"]; + secretKey = repData["secretKey"] ?? ""; + baseImageBase64 = baseImageBase64.replaceAll('\n', ''); + slideImageBase64 = repData["jigsawImageBase64"]; + slideImageBase64 = slideImageBase64.replaceAll('\n', ''); + captchaToken = repData["token"]; + + var baseR = await WidgetUtil.getImageWH( + image: Image.memory(Base64Decoder().convert(baseImageBase64))); + baseSize = baseR.size; + + var silderR = await WidgetUtil.getImageWH( + image: Image.memory(Base64Decoder().convert(slideImageBase64))); + slideSize = silderR.size; + + setState(() {}); + }).catchError((error) { + print(error); + }); + } + + //校验验证码 + void checkCaptcha(sliderXMoved, captchaToken, {BuildContext? myContext}) { + setState(() { + sliderMoveFinish = true; + }); + //滑动结束,改变滑块的图标及颜色 +// updateSliderColorIcon(); + + //pointJson参数需要aes加密 + +// MediaQueryData mediaQuery = MediaQuery.of(myContext); + var pointMap = {"x": sliderXMoved, "y": 5}; + var pointStr = json.encode(pointMap); + var cryptedStr = pointStr; + + // secretKey 不为空 进行as加密 + if(!ObjectUtils.isEmpty(secretKey)){ + cryptedStr = EncryptUtil.aesEncode(key: secretKey, content: pointStr); + var dcrypt = EncryptUtil.aesDecode(key: secretKey, content: cryptedStr); + json.decode(dcrypt); + + } + + + HttpManager.requestData('/captcha/check', { + "pointJson": cryptedStr, + "captchaType": "blockPuzzle", + "token": captchaToken + }, {}).then((res) { + if (res['repCode'] != '0000' || res['repData'] == null) { + checkFail(); + return; + } + + Map repData = res['repData']; + if (repData["result"] != null && repData["result"] == true) { + //如果不加密 将 token 和 坐标序列化 通过 --- 链接成字符串 + var captchaVerification = "$captchaToken---$pointStr"; + if(!ObjectUtils.isEmpty(secretKey)){ + //如果加密 将 token 和 坐标序列化 通过 --- 链接成字符串 进行加密 加密密钥为 _clickWordCaptchaModel.secretKey + captchaVerification = EncryptUtil.aesEncode(key: secretKey, content: captchaVerification); + } + checkSuccess(captchaVerification); + } else { + checkFail(); + } + }).catchError((error) { + loadCaptcha(); + print(error); + }); + } + + @override + void initState() { + super.initState(); + initAnimation(); + loadCaptcha(); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + // 初始化动画 + void initAnimation() { + controller = + AnimationController(duration: Duration(milliseconds: 500), vsync: this); + + offsetAnimation = Tween(begin: 0.5, end: 0) + .animate(CurvedAnimation(parent: controller, curve: Curves.ease)) + ..addListener(() { + this.setState(() {}); + }); + } + + // 反向执行动画 + _reverseAnimation() async { + await controller.reverse(); + } + + // 正向执行动画 + _forwardAnimation() async { + await controller.forward(); + } + + @override + void didUpdateWidget(BlockPuzzleCaptchaPage oldWidget) { + // TODO: implement didUpdateWidget + super.didUpdateWidget(oldWidget); + } + + @override + Widget build(BuildContext context) { + return MaxScaleTextWidget( + child: buildContent(context), + ); + } + + Widget buildContent(BuildContext context) { + var mediaQuery = MediaQuery.of(context); + var dialogWidth = 0.9 * mediaQuery.size.width; + if (dialogWidth < 330) { + dialogWidth = mediaQuery.size.width; + } + + return Scaffold( + backgroundColor: Colors.transparent, + body: Center( + child: Container( + key: _containerKey, + width: dialogWidth, + height: 340, + color: Colors.white, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + _topContainer(), + _middleContainer(), + _bottomContainer(), + ], + ), + ), + ), + ); + } + + ///顶部,提示+关闭 + _topContainer() { + return Container( + height: 50, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + decoration: BoxDecoration( + border: Border(bottom: BorderSide(width: 1, color: Color(0xffe5e5e5))), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '请完成安全验证', + style: TextStyle(fontSize: 18), + ), + IconButton( + icon: Icon(Icons.highlight_off), + iconSize: 30, + color: Colors.black38, + onPressed: () { + //退出 + Navigator.pop(context); + }), + ], + ), + ); + } + + _middleContainer() { + ////显示验证码 + return Container( + margin: EdgeInsets.symmetric(vertical: 10), + child: Stack( + children: [ + ///底图 310*155 + baseImageBase64.length > 0 + ? Image.memory( + Base64Decoder().convert(baseImageBase64), + fit: BoxFit.fitWidth, + key: _baseImageKey, + gaplessPlayback: true, + ) + : Container( + width: 310, + height: 155, + alignment: Alignment.center, + child: CircularProgressIndicator(), + ), + + ///滑块图 + slideImageBase64.length > 0 + ? Container( + margin: EdgeInsets.fromLTRB(sliderXMoved, 0, 0, 0), + child: Image.memory( + Base64Decoder().convert(slideImageBase64), + fit: BoxFit.fitHeight, + key: _slideImageKey, + gaplessPlayback: true, + ), + ) + : Container(), + + //刷新按钮 + Positioned( + top: 0, + right: 0, + child: IconButton( + icon: Icon(Icons.refresh), + iconSize: 30, + color: Colors.black54, + onPressed: () { + //刷新 + loadCaptcha(); + }), + ), + Positioned( + bottom: 0, + left: -10, + right: -10, + child: Offstage( + offstage: !_showTimeLine, + child: FractionalTranslation( + translation: Offset(0, offsetAnimation.value), + child: Container( + margin: EdgeInsets.only(left: 10, right: 10), + height: 40, + color: _checkSuccess + ? Color(0x7F66BB6A) + : Color.fromRGBO(200, 100, 100, 0.4), + alignment: Alignment.centerLeft, + child: Text( + _checkSuccess + ? "${(_checkMilliseconds / (60.0 * 12)).toStringAsFixed(2)}s验证成功" + : "验证失败", + style: TextStyle(color: Colors.white), + ), + ), + ), + )), + Positioned( + bottom: -20, + left: 0, + right: 0, + child: Offstage( + offstage: !_showTimeLine, + child: Container( + margin: EdgeInsets.only(left: 10, right: 10), + height: 20, + color: Colors.white, + ), + )) + ], + ), + ); + } + ///底部,滑动区域 + _bottomContainer() { + return baseSize.width >0 + ? Container( + height: 70, + width: baseSize.width, +// color: Colors.cyanAccent, + child: Stack( + alignment: AlignmentDirectional.centerStart, + children: [ + Container( + height: _bottomSliderSize, + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: Color(0xffe5e5e5), + ), + color: Color(0xfff8f9fb), + ), + ), + Container( + alignment: Alignment.center, + child: Text( + '向右拖动滑块填充拼图', + style: TextStyle(fontSize: 16), + ), + ), + Container( + width: sliderXMoved, + height: _bottomSliderSize-2, + decoration: BoxDecoration( + border: Border.all( + width: sliderXMoved > 0 ? 1 : 0, + color: movedXBorderColor, + ), + color: Color(0xfff3fef1), + ), + ), + GestureDetector( + onPanStart: (startDetails) {///开始 + _checkMilliseconds = new DateTime.now().millisecondsSinceEpoch; + print(startDetails.localPosition); + sliderStartX = startDetails.localPosition.dx; + }, + onPanUpdate: (updateDetails) { ///更新 + print(updateDetails.localPosition); + double _w1 = _baseImageKey.currentContext!.size!.width - _slideImageKey.currentContext!.size!.width; + double offset = updateDetails.localPosition.dx - sliderStartX; + if(offset < 0){ + offset = 0; + } + if(offset > _w1){ + offset = _w1; + } + print("offset ------ $offset"); + setState(() { + sliderXMoved = offset; + }); + //滑动过程,改变滑块左边框颜色 + updateSliderColorIcon(); + }, + onPanEnd: (endDetails) { //结束 + print("endDetails"); + checkCaptcha(sliderXMoved, captchaToken); + int _nowTime = new DateTime.now().millisecondsSinceEpoch; + _checkMilliseconds = _nowTime - _checkMilliseconds; + }, + child: Container( + width: _bottomSliderSize, + height: _bottomSliderSize, + margin: EdgeInsets.only(left: sliderXMoved > 0 ? sliderXMoved : 1), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + width: 1, + color: Color(0xffe5e5e5), + ), + right: BorderSide( + width: 1, + color: Color(0xffe5e5e5), + ), + bottom: BorderSide( + width: 1, + color: Color(0xffe5e5e5), + ), + ), + color: sliderColor, + ), + child: IconButton( + icon: Icon(sliderIcon), + iconSize: 30, + color: Colors.black54, onPressed: () { }, + ), + ), + ) + ], + )) + : Container(); + } +} + + +class MaxScaleTextWidget extends StatelessWidget { + final double max; + final Widget child; + + MaxScaleTextWidget({Key? key, this.max = 1.0, required this.child}) : super(key: key); + + @override + Widget build(BuildContext context) { + var data = MediaQuery.of(context); + var textScaleFactor = min(max, data.textScaleFactor); + return MediaQuery(data: data.copyWith(textScaleFactor: textScaleFactor), child: child); + } +} diff --git a/view/flutter/demo_null_safety/lib/captcha/click_word_captcha.dart b/view/flutter/demo_null_safety/lib/captcha/click_word_captcha.dart new file mode 100644 index 0000000..56e1f2e --- /dev/null +++ b/view/flutter/demo_null_safety/lib/captcha/click_word_captcha.dart @@ -0,0 +1,367 @@ +import 'dart:convert'; + +import 'package:captcha/request/HttpManager.dart'; +import 'package:captcha/request/encrypt_util.dart'; +import 'package:captcha/tools/object_utils.dart'; +import 'package:captcha/tools/widget_util.dart'; +import 'package:flutter/material.dart'; +import 'package:steel_crypt/steel_crypt.dart'; + +typedef VoidSuccessCallback = dynamic Function(String v); + +class ClickWordCaptcha extends StatefulWidget { + final VoidSuccessCallback? onSuccess; //文字点击后验证成功回调 + final VoidCallback? onFail; //文字点击完成后验证失败回调 + + const ClickWordCaptcha({Key? key, this.onSuccess, this.onFail}) + : super(key: key); + + @override + _ClickWordCaptchaState createState() => _ClickWordCaptchaState(); +} + +class _ClickWordCaptchaState extends State { + ClickWordCaptchaState _clickWordCaptchaState = ClickWordCaptchaState.none; + List _tapOffsetList = []; + ClickWordCaptchaModel _clickWordCaptchaModel = ClickWordCaptchaModel(); + + Color titleColor = Colors.black; + Color borderColor = Color(0xffdddddd); + String bottomTitle = ""; + Size baseSize = Size(310.0, 155.0); + + //改变底部样式及字段 + _changeResultState() { + switch (_clickWordCaptchaState) { + case ClickWordCaptchaState.normal: + titleColor = Colors.black; + borderColor = Color(0xffdddddd); + break; + case ClickWordCaptchaState.success: + _tapOffsetList = []; + titleColor = Colors.green; + borderColor = Colors.green; + bottomTitle = "验证成功"; + break; + case ClickWordCaptchaState.fail: + _tapOffsetList = []; + titleColor = Colors.red; + borderColor = Colors.red; + bottomTitle = "验证失败"; + break; + default: + titleColor = Colors.black; + borderColor = Color(0xffdddddd); + bottomTitle = "数据加载中……"; + break; + } + setState(() {}); + } + + @override + void initState() { + super.initState(); + _loadCaptcha(); + } + + //加载验证码 + _loadCaptcha() async { + _tapOffsetList = []; + _clickWordCaptchaState = ClickWordCaptchaState.none; + _changeResultState(); + var res = await HttpManager.requestData( + '/captcha/get', {"captchaType": "clickWord"}, {}); + if (res['repCode'] != '0000' || res['repData'] == null) { + _clickWordCaptchaModel.secretKey = ""; + bottomTitle = "加载失败,请刷新"; + _clickWordCaptchaState = ClickWordCaptchaState.normal; + _changeResultState(); + return; + } else { + Map repData = res['repData']; + _clickWordCaptchaModel = ClickWordCaptchaModel.fromMap(repData); + + var baseR = await WidgetUtil.getImageWH( + image: Image.memory( + Base64Decoder().convert(_clickWordCaptchaModel.imgStr))); + baseSize = baseR.size; + + bottomTitle = "请依次点击【${_clickWordCaptchaModel.wordStr}】"; + } + + _clickWordCaptchaState = ClickWordCaptchaState.normal; + _changeResultState(); + } + + //校验验证码 + _checkCaptcha() async { + List> mousePos = []; + _tapOffsetList.map((size) { + mousePos + .add({"x": size.dx.roundToDouble(), "y": size.dy.roundToDouble()}); + }).toList(); + var pointStr = json.encode(mousePos); + + var cryptedStr = pointStr; + + // secretKey 不为空 进行as加密 + if (!ObjectUtils.isEmpty(_clickWordCaptchaModel.secretKey)) { + cryptedStr = EncryptUtil.aesEncode( + key: _clickWordCaptchaModel.secretKey, content: pointStr); + var dcrypt = EncryptUtil.aesDecode( + key: _clickWordCaptchaModel.secretKey, content: cryptedStr); + } + +// Map _map = json.decode(dcrypt); + var res = await HttpManager.requestData('/captcha/check', { + "pointJson": cryptedStr, + "captchaType": "clickWord", + "token": _clickWordCaptchaModel.token + }, {}); + if (res['repCode'] != '0000' || res['repData'] == null) { + _checkFail(); + return; + } + Map repData = res['repData']; + if (repData["result"] != null && repData["result"] == true) { + //如果不加密 将 token 和 坐标序列化 通过 --- 链接成字符串 + var captchaVerification = "${_clickWordCaptchaModel.token}---$pointStr"; + if (!ObjectUtils.isEmpty(_clickWordCaptchaModel.secretKey)) { + //如果加密 将 token 和 坐标序列化 通过 --- 链接成字符串 进行加密 加密密钥为 _clickWordCaptchaModel.secretKey + captchaVerification = EncryptUtil.aesEncode( + key: _clickWordCaptchaModel.secretKey, + content: captchaVerification); + } + _checkSuccess(captchaVerification); + } else { + _checkFail(); + } + } + + //校验失败 + _checkFail() async { + _clickWordCaptchaState = ClickWordCaptchaState.fail; + _changeResultState(); + + await Future.delayed(Duration(milliseconds: 1000)); + _loadCaptcha(); + //回调 + if (widget.onFail != null) { + widget.onFail!(); + } + } + + //校验成功 + _checkSuccess(String pointJson) async { + _clickWordCaptchaState = ClickWordCaptchaState.success; + _changeResultState(); + + await Future.delayed(Duration(milliseconds: 1000)); + + var cryptedStr = EncryptUtil.aesEncode(key: 'BGxdEUOZkXka4HSj', content: pointJson); + + print(cryptedStr); + //回调 pointJson 是经过es加密之后的信息 + if (widget.onSuccess != null) { + widget.onSuccess!(cryptedStr); + } + //关闭 + Navigator.pop(context); + } + + @override + Widget build(BuildContext context) { + var data = MediaQuery.of(context); + var dialogWidth = 0.9 * data.size.width; + var isRatioCross = false; + if (dialogWidth < 320.0) { + dialogWidth = data.size.width; + isRatioCross = true; + } + return Scaffold( + backgroundColor: Colors.transparent, + body: Center( + child: Container( + width: dialogWidth, + height: 320, + color: Colors.white, + child: Column( + children: [ + _topConttainer(), + _captchaContainer(), + _bottomContainer() + ], + ), + ), + ), + ); + } + + //图片验证码 + _captchaContainer() { + List _widgetList = []; + if (!ObjectUtils.isEmpty(_clickWordCaptchaModel.imgStr)) { + _widgetList.add(Image( + width: baseSize.width, + height: baseSize.height, + gaplessPlayback: true, + image: MemoryImage( + Base64Decoder().convert(_clickWordCaptchaModel.imgStr)))); + } + + double _widgetW = 20; + for (int i = 0; i < _tapOffsetList.length; i++) { + Offset offset = _tapOffsetList[i]; + _widgetList.add(Positioned( + left: offset.dx - _widgetW * 0.5, + top: offset.dy - _widgetW * 0.5, + child: Container( + alignment: Alignment.center, + width: _widgetW, + height: _widgetW, + decoration: BoxDecoration( + color: Color(0xCC43A047), + borderRadius: BorderRadius.all(Radius.circular(_widgetW))), + child: Text( + "${i + 1}", + style: TextStyle(color: Colors.white, fontSize: 15), + ), + ))); + } + _widgetList.add(//刷新按钮 + Positioned( + top: 0, + right: 0, + child: IconButton( + icon: Icon(Icons.refresh), + iconSize: 30, + color: Colors.deepOrangeAccent, + onPressed: () { + //刷新 + _loadCaptcha(); + }), + )); + + return GestureDetector( + onTapDown: (TapDownDetails details) { + debugPrint( + "onTapDown globalPosition全局坐标系位置: ${details.globalPosition} localPosition组件坐标系位置: ${details.localPosition} "); + if (!ObjectUtils.isListEmpty(_clickWordCaptchaModel.wordList) && + _tapOffsetList.length < _clickWordCaptchaModel.wordList.length) { + _tapOffsetList.add( + Offset(details.localPosition.dx, details.localPosition.dy)); + } + setState(() {}); + if (!ObjectUtils.isListEmpty(_clickWordCaptchaModel.wordList) && + _tapOffsetList.length == _clickWordCaptchaModel.wordList.length) { + _checkCaptcha(); + } + }, + child: Container( + width: baseSize.width, + height: baseSize.height, + child: Stack( + children: _widgetList, + ), + )); + } + + //底部提示部件 + _bottomContainer() { + return Container( + height: 50, + margin: EdgeInsets.only(top: 10), + alignment: Alignment.center, + width: baseSize.width, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(4)), + border: Border.all(color: borderColor)), + child: + Text(bottomTitle, style: TextStyle(fontSize: 18, color: titleColor)), + ); + } + + //顶部,提示+关闭 + _topConttainer() { + return Container( + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + margin: EdgeInsets.only(bottom: 20, top: 5), + decoration: BoxDecoration( + border: Border(bottom: BorderSide(width: 1, color: Color(0xffe5e5e5))), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '请完成安全验证', + style: TextStyle(fontSize: 18), + ), + IconButton( + icon: Icon(Icons.highlight_off), + iconSize: 35, + color: Colors.black54, + onPressed: () { + //退出 + Navigator.pop(context); + }), + ], + ), + ); + } +} + +//校验状态 +enum ClickWordCaptchaState { + normal, //默认 可自定义描述 + success, //成功 + fail, //失败 + none, //无状态 用于加载使用 +} + +//请求数据模型 +class ClickWordCaptchaModel { + String imgStr; //图表url 目前用base64 data + String token; // 获取的token 用于校验 + List wordList; //显示需要点选的字 + String wordStr; //显示需要点选的字转换为字符串 + String secretKey; //加密key + + ClickWordCaptchaModel( + {this.imgStr = "", + this.token = "", + this.secretKey = "", + this.wordList = const [], + this.wordStr = ""}); + + //解析数据转换模型 + static ClickWordCaptchaModel fromMap(Map map) { + ClickWordCaptchaModel captchaModel = ClickWordCaptchaModel(); + captchaModel.imgStr = map["originalImageBase64"] ?? ""; + captchaModel.token = map["token"] ?? ""; + captchaModel.secretKey = map["secretKey"] ?? ""; + captchaModel.wordList = map["wordList"] ?? []; + + if (!ObjectUtils.isListEmpty(captchaModel.wordList)) { + captchaModel.wordStr = captchaModel.wordList.join(","); + } + + return captchaModel; + } + + //将模型转换 + Map toJson() { + var map = new Map(); + map['imgStr'] = imgStr; + map['token'] = token; + map['secretKey'] = token; + map['wordList'] = wordList; + map['wordStr'] = wordStr; + return map; + } + + @override + String toString() { + // TODO: implement toString + return JsonEncoder.withIndent(' ').convert(toJson()); + } +} diff --git a/view/flutter/demo_null_safety/lib/demo.dart b/view/flutter/demo_null_safety/lib/demo.dart new file mode 100644 index 0000000..dee4c86 --- /dev/null +++ b/view/flutter/demo_null_safety/lib/demo.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +class DemoPage extends StatefulWidget { + + @override + _DemoPageState createState() => _DemoPageState(); +} + +class _DemoPageState extends State { + @override + Widget build(BuildContext context) { + // TODO: implement build + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text('title'), + ), + body: Container(), + ); + } + +} \ No newline at end of file diff --git a/view/flutter/demo_null_safety/lib/login.dart b/view/flutter/demo_null_safety/lib/login.dart new file mode 100644 index 0000000..13b4bc8 --- /dev/null +++ b/view/flutter/demo_null_safety/lib/login.dart @@ -0,0 +1,122 @@ +import 'package:captcha/captcha/click_word_captcha.dart'; +import 'package:flutter/material.dart'; + +import 'package:captcha/captcha/block_puzzle_captcha.dart'; + +class LoginPage extends StatefulWidget { + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + + List getListData(){ + List items= []; + DropdownMenuItem dropdownMenuItem1=new DropdownMenuItem( + child:new Text('滑动拼图'), + value: 1, + ); + items.add(dropdownMenuItem1); + DropdownMenuItem dropdownMenuItem2=new DropdownMenuItem( + child:new Text('文字点选'), + value: 2, + ); + items.add(dropdownMenuItem2); + + return items; + } + + int? value; + + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text('title'), + ), + body: Container( + alignment: Alignment.center, + child: Column( + children: [ + TextField( + decoration: InputDecoration( + icon: Icon(Icons.person), + labelText: "用户名", + labelStyle: TextStyle( + color: Colors.red, + fontSize: 20, + )), + ), + TextField( + decoration: InputDecoration( + icon: Icon(Icons.lock), + labelText: "密码", + labelStyle: TextStyle( + color: Colors.red, + fontSize: 20, + )), + ), + DropdownButton( + items: getListData(), + hint:new Text('登录'),//当没有默认值的时候可以设置的提示 + value: value,//下拉菜单选择完之后显示给用户的值 + onChanged: (v){//下拉菜单item点击之后的回调 + if(v == 1){ + loadingBlockPuzzle(context); + } else { + loadingClickWord(context); + } + }, + elevation: 24,//设置阴影的高度 + style: new TextStyle(//设置文本框里面文字的样式 + color: Colors.red + ), +// isDense: false,//减少按钮的高度。默认情况下,此按钮的高度与其菜单项的高度相同。如果isDense为true,则按钮的高度减少约一半。 这个当按钮嵌入添加的容器中时,非常有用 + iconSize: 50.0,//设置三角标icon的大小 + ) + ], + ), + ), + ); + } + + //点选拼图 + static void loadingClickWord(BuildContext context, {barrierDismissible = true}) { + showDialog( + context: context, + barrierDismissible: barrierDismissible, + builder: (BuildContext context) { + return ClickWordCaptcha( + onSuccess: (v){ + + }, + onFail: (){ + + }, + ); + }, + ); + } + + //滑动拼图 + static void loadingBlockPuzzle(BuildContext context, {barrierDismissible = true}) { + showDialog( + context: context, + barrierDismissible: barrierDismissible, + builder: (BuildContext context) { + return BlockPuzzleCaptchaPage( + onSuccess: (v){ + + }, + onFail: (){ + + }, + ); + }, + ); + } +} diff --git a/view/flutter/demo_null_safety/lib/main.dart b/view/flutter/demo_null_safety/lib/main.dart new file mode 100644 index 0000000..b7695ea --- /dev/null +++ b/view/flutter/demo_null_safety/lib/main.dart @@ -0,0 +1,27 @@ +import 'package:captcha/login.dart'; +import 'package:flutter/material.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + ), + home: LoginPage(), + ); + } +} diff --git a/view/flutter/demo_null_safety/lib/request/HttpManager.dart b/view/flutter/demo_null_safety/lib/request/HttpManager.dart new file mode 100644 index 0000000..3fe85b2 --- /dev/null +++ b/view/flutter/demo_null_safety/lib/request/HttpManager.dart @@ -0,0 +1,90 @@ +import 'dart:io'; + +import 'package:captcha/request/SignConfig.dart'; +import 'package:dio/dio.dart'; +import 'dart:collection'; + + +///http请求 +class HttpManager { + static const CONTENT_TYPE_JSON = "application/json"; + static const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded"; + static Map optionParams = { + "mirrorToken": null, + "content-Type": CONTENT_TYPE_JSON + }; + + //请求base url + //todo 请求host配置 + static String baseUrl = "http://127.0.0.1:8080"; +// static late String baseUrl; + + ///发起网络请求 + ///[ url] 请求url + ///[ param] 请求参数 + ///[ header] 外加头 + ///[ isNeedToken] 是否需要token + ///[ optionMetod] 请求类型 post、get + ///[ noTip] 是否需要返回错误信息 默认不需要 + ///[ needSign] 是否需要Sign校验 默认需要 + ///[ needError] 是否需要错误提示 + static requestData(url, param, Map? header, + {bool isNeedToken = true, + String optionMetod = "post", + noTip = false, + needSign = true, + needError = true}) async { + ///初始化请求类 + Dio dio = Dio(); + + ///头部 + Map headers = HashMap(); + if (header != null) { + headers.addAll(header); + } + + //请求协议 post 、get + Options option = Options(method: optionMetod); + + ///设置头部 + option.headers = headers; + + option.sendTimeout = 15000; + + //获取token + // var mirrorToken = ""; + + var params = param; +// if (needSign) { +// //获取加密的请求参数 +// params = await SignConfig.signData(param, mirrorToken); +// } + + late Response response; + try { + ///开始请求 + response = + await dio.request("$baseUrl$url", data: params, options: option); + } on DioError catch (e) { + if (e.response != null) { + } else { + } + + ///请求失败处理 + if (needError) { + return e; + } + } + + try { + var responseJson = response.data; + if (response.statusCode == 200) { + ///请求链接成功 + return responseJson; + } + } catch (e) { + print(e.toString()); + throw e; + } + } +} diff --git a/view/flutter/demo_null_safety/lib/request/SignConfig.dart b/view/flutter/demo_null_safety/lib/request/SignConfig.dart new file mode 100644 index 0000000..15baa7c --- /dev/null +++ b/view/flutter/demo_null_safety/lib/request/SignConfig.dart @@ -0,0 +1,46 @@ +import 'dart:convert'; +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart'; + +class SignConfig { + + + static String generateMd5(String data){ + var content = new Utf8Encoder().convert(data); + var digest = md5.convert(content); + return hex.encode(digest.bytes); + } + + static signData(Object params, tokenStr) async { + var time = new DateTime.now().millisecondsSinceEpoch; + String token = tokenStr; + Map reqData = new Map(); + Map? paramsObj = new Map(); + paramsObj = params as Map?; + var arr = []; + //将字典转成数组 + paramsObj?.forEach((key, value) => arr.add(key)); + //进行签名校验 + Map cr = new Map(); + cr['token'] = token; + cr['time'] = time.toString(); + cr['reqData'] = json.encode(paramsObj); + var array = []; + cr.forEach((key, value) => array.add(key)); + array.sort(); + var str = ''; + for (var i = 0; i < array.length; i++) { + var key = array[i]; + var value = cr[key]; + str += key + value; + } + + reqData["time"] = time; + reqData["token"] = token; + reqData['reqData'] = params; + reqData['sign'] = generateMd5(str); + + return reqData; + } + +} \ No newline at end of file diff --git a/view/flutter/demo_null_safety/lib/request/encrypt_util.dart b/view/flutter/demo_null_safety/lib/request/encrypt_util.dart new file mode 100644 index 0000000..2b7ff84 --- /dev/null +++ b/view/flutter/demo_null_safety/lib/request/encrypt_util.dart @@ -0,0 +1,30 @@ +import 'dart:convert'; + +import 'package:steel_crypt/steel_crypt.dart'; +//import 'package:encrypt/encrypt.dart'; + +class EncryptUtil { + + ///aes加密 + /// [key]AesCrypt加密key + /// [content] 需要加密的内容字符串 + static String aesEncode({required String key, required String content}) { + var aesCrypt = AesCrypt( + key: base64UrlEncode(key.codeUnits), padding: PaddingAES.pkcs7); + return aesCrypt.ecb.encrypt(inp: content); + } + + ///aes解密 + /// [key]aes解密key + /// [content] 需要加密的内容字符串 + static String aesDecode({required String key, required String content}) { + var aesCrypt = AesCrypt( + key: base64UrlEncode(key.codeUnits), padding: PaddingAES.pkcs7); + return aesCrypt.ecb.decrypt(enc: content); + } + + + + + +} \ No newline at end of file diff --git a/view/flutter/demo_null_safety/lib/tools/object_utils.dart b/view/flutter/demo_null_safety/lib/tools/object_utils.dart new file mode 100644 index 0000000..92208ac --- /dev/null +++ b/view/flutter/demo_null_safety/lib/tools/object_utils.dart @@ -0,0 +1,27 @@ +import 'dart:convert'; + +class ObjectUtils { + /// isEmpty. + static bool isEmpty(Object? value) { + if (value == null) return true; + if (value is String && value.isEmpty) { + return true; + } + return false; + } + + //list length == 0 || list == null + static bool isListEmpty(Object? value) { + if (value == null) return true; + if (value is List && value.length == 0) { + return true; + } + return false; + } + + static String jsonFormat(Map map) { + Map _map = Map.from(map); + JsonEncoder encoder = JsonEncoder.withIndent(' '); + return encoder.convert(_map); + } +} diff --git a/view/flutter/demo_null_safety/lib/tools/widget_util.dart b/view/flutter/demo_null_safety/lib/tools/widget_util.dart new file mode 100644 index 0000000..16e7244 --- /dev/null +++ b/view/flutter/demo_null_safety/lib/tools/widget_util.dart @@ -0,0 +1,133 @@ +import 'dart:async'; + +import 'package:flutter/widgets.dart'; + +import 'object_utils.dart'; +/** + * @Author: thl + * @GitHub: https://github.com/Sky24n + * @Email: 863764940@qq.com + * @Email: sky24no@gmail.com + * @Description: Widget Util. + * @Date: 2018/9/10 + */ + +/// Widget Util. +class WidgetUtil { + bool _hasMeasured = false; + late double _width; + late double _height; + + /// Widget rendering listener. + /// Widget渲染监听. + /// context: Widget context. + /// isOnce: true,Continuous monitoring false,Listen only once. + /// onCallBack: Widget Rect CallBack. + void asyncPrepare( + BuildContext context, bool isOnce, ValueChanged onCallBack) { + if (_hasMeasured) return; + WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) { + RenderObject? box = context.findRenderObject(); + if (box != null) { + if (isOnce) _hasMeasured = true; + double width = box.semanticBounds.width; + double height = box.semanticBounds.height; + if (_width != width || _height != height) { + _width = width; + _height = height; + if (onCallBack != null) onCallBack(box.semanticBounds); + } + } + }); + } + + /// Widget渲染监听. + void asyncPrepares(bool isOnce, ValueChanged? onCallBack) { + if (_hasMeasured) return; + WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) { + if (isOnce) _hasMeasured = true; + if (onCallBack != null) onCallBack(null); + }); + } + + ///get Widget Bounds (width, height, left, top, right, bottom and so on).Widgets must be rendered completely. + ///获取widget Rect + static Rect getWidgetBounds(BuildContext context) { + RenderObject? box = context.findRenderObject(); + return (box != null) ? box.semanticBounds : Rect.zero; + } + + ///Get the coordinates of the widget on the screen.Widgets must be rendered completely. + ///获取widget在屏幕上的坐标,widget必须渲染完成 + static Offset getWidgetLocalToGlobal(BuildContext context) { + RenderBox? box = context.findRenderObject() as RenderBox?; + return box == null ? Offset.zero : box.localToGlobal(Offset.zero); + } + + /// get image width height,load error return Rect.zero.(unit px) + /// 获取图片宽高,加载错误情况返回 Rect.zero.(单位 px) + /// image + /// url network + /// local url , package + static Future getImageWH( + {Image? image, String? url, String? localUrl, String? package}) { + if (ObjectUtils.isEmpty(image) && + ObjectUtils.isEmpty(url) && + ObjectUtils.isEmpty(localUrl)) { + return Future.value(Rect.zero); + } + Completer completer = Completer(); + Image img = image ?? ((url != null && url.isNotEmpty) + ? Image.network(url) + : Image.asset(localUrl!, package: package)); + img.image + .resolve(const ImageConfiguration()) + .addListener(ImageStreamListener( + (ImageInfo info, bool _) { + completer.complete(Rect.fromLTWH(0, 0, info.image.width.toDouble(), + info.image.height.toDouble())); + }, + onError: (Object exception, StackTrace? stackTrace) { + completer.completeError(exception, stackTrace); + }, + )); + return completer.future; + } + + /// get image width height, load error throw exception.(unit px) + /// 获取图片宽高,加载错误会抛出异常.(单位 px) + /// image + /// url network + /// local url (full path/全路径,example:"assets/images/ali_connors.png",""assets/images/3.0x/ali_connors.png"" ); + /// package + static Future getImageWHE( + {Image? image, + required String url, + required String localUrl, + required String package}) { + if (ObjectUtils.isEmpty(image) && + ObjectUtils.isEmpty(url) && + ObjectUtils.isEmpty(localUrl)) { + return Future.error("image is null."); + } + Completer completer = Completer(); + Image img = image != null + ? image + : ((url != null && url.isNotEmpty) + ? Image.network(url) + : Image.asset(localUrl, package: package)); + img.image + .resolve(const ImageConfiguration()) + .addListener(ImageStreamListener( + (ImageInfo info, bool _) { + completer.complete(Rect.fromLTWH(0, 0, info.image.width.toDouble(), + info.image.height.toDouble())); + }, + onError: (Object exception, StackTrace? stackTrace) { + completer.completeError(exception, stackTrace); + }, + )); + + return completer.future; + } +} diff --git a/view/flutter/demo_null_safety/pubspec.lock b/view/flutter/demo_null_safety/pubspec.lock new file mode 100644 index 0000000..38a40a7 --- /dev/null +++ b/view/flutter/demo_null_safety/pubspec.lock @@ -0,0 +1,230 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + asn1lib: + dependency: transitive + description: + name: asn1lib + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.2" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + dio: + dependency: "direct main" + description: + name: dio + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.6" + encrypt: + dependency: "direct main" + description: + name: encrypt + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.1" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.2" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.5" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + pointycastle: + dependency: transitive + description: + name: pointycastle + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + steel_crypt: + dependency: "direct main" + description: + name: steel_crypt + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0+1" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.9" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" +sdks: + dart: ">=2.17.0-0 <3.0.0" diff --git a/view/flutter/demo_null_safety/pubspec.yaml b/view/flutter/demo_null_safety/pubspec.yaml new file mode 100644 index 0000000..361a843 --- /dev/null +++ b/view/flutter/demo_null_safety/pubspec.yaml @@ -0,0 +1,75 @@ +name: captcha +description: A new Flutter application. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 2.0.0+1 + +environment: + sdk: ">=2.12.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.5 + + dio: ^4.0.6 + steel_crypt: ^3.0.0+1 + encrypt: ^5.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + #assets: + # - assets/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/view/flutter/demo_null_safety/test/widget_test.dart b/view/flutter/demo_null_safety/test/widget_test.dart new file mode 100644 index 0000000..ed8f894 --- /dev/null +++ b/view/flutter/demo_null_safety/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:captcha/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} -- Gitee From ecd80b2db76e3749b750be4207a1ccd271f3d640 Mon Sep 17 00:00:00 2001 From: Foming Date: Tue, 14 Nov 2023 07:24:09 +0000 Subject: [PATCH 17/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index c01e556..d255b1f 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,4 +1,7 @@ -# **在线体验暂时下线 !!!** +# 企微可添加人数已满上限,目前正在申请扩充,现有问题可直接提Issue + +# **在线体验暂时下线** + ####   在线文档:[https://ajcaptcha.beliefteam.cn/captcha-doc/](https://ajcaptcha.beliefteam.cn/captcha-doc/ "doc")
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)[![Total Lines](https://tokei.rs/b1/github/anji-plus/captcha?category=lines)](https://github.com/anji-plus/captcha) -- Gitee From 4358b4200d84e2cf14c03249c3994fa767e617d6 Mon Sep 17 00:00:00 2001 From: Foming Date: Mon, 4 Dec 2023 02:33:25 +0000 Subject: [PATCH 18/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README_CN.md b/README_CN.md index d255b1f..6761b04 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,4 +1,3 @@ -# 企微可添加人数已满上限,目前正在申请扩充,现有问题可直接提Issue # **在线体验暂时下线** @@ -80,9 +79,14 @@ I Your application is running here: http://localhost:8081 # 6 技术支持,如有问题,请提交[Issue](https://gitee.com/anji-plus/captcha/issues) -个人企业微信:加微信进群备注 **AJ-Captcha** 或者 **Captcha**,**一定要加备注!!!**
-如果不是为了进群,请直接说明来意,每天加群的都很多,企微也是我们自己的工作企微,会有很多消息会被刷下去,如果半天没有回复你,请过段时间再发送。
- + +AJ-Captcha技术支持三群
+
+ + +个人微信:个人微信,不闲聊,加群/咨询请备注 **AJ-Captcha**、**Captcha**、*验证码*,**一定要加备注 !!!没有备注一律忽略!!!**
+ + #### 开源不易,劳烦各位star ☺ -- Gitee From ee0cbc9a6db56685d267f26ffebaa4da6301311a Mon Sep 17 00:00:00 2001 From: Foming Date: Mon, 4 Dec 2023 02:36:41 +0000 Subject: [PATCH 19/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index 6761b04..0a6772e 100644 --- a/README_CN.md +++ b/README_CN.md @@ -84,7 +84,7 @@ AJ-Captcha技术支持三群

-个人微信:个人微信,不闲聊,加群/咨询请备注 **AJ-Captcha**、**Captcha**、*验证码*,**一定要加备注 !!!没有备注一律忽略!!!**
+个人微信:个人微信,不闲聊,加群/咨询请备注 **AJ-Captcha**/**Captcha**/**验证码**,**一定要加备注 !!!没有备注一律忽略!!!**
-- Gitee From adf7ce5d7329e2fe15e2922a0e3850bc568547d3 Mon Sep 17 00:00:00 2001 From: Foming Date: Thu, 14 Dec 2023 02:23:22 +0000 Subject: [PATCH 20/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README_CN.md b/README_CN.md index 0a6772e..1cbda86 100644 --- a/README_CN.md +++ b/README_CN.md @@ -80,11 +80,16 @@ I Your application is running here: http://localhost:8081 # 6 技术支持,如有问题,请提交[Issue](https://gitee.com/anji-plus/captcha/issues) -AJ-Captcha技术支持三群
+AJ-Captcha技术支持三群,有问题都可以在群里问
+如果不能直接加进去或者群二维码过期了,请添加下面个人微信

-个人微信:个人微信,不闲聊,加群/咨询请备注 **AJ-Captcha**/**Captcha**/**验证码**,**一定要加备注 !!!没有备注一律忽略!!!**
+个人微信:个人微信,不闲聊,加群、咨询请备注,备注格式不限但最好是:“项目名 问题”, 项目名可以是**AJ-Captcha**、**Captcha**、**验证码**,只要能一眼分辨就行
+例1:验证码 加群 +例2:captche 有个问题xxxx
+有问题,不管是技术问题还是使用问题,都尽量在群里问,没啥特殊问题尽量别加个人微信。加个人微信记得**一定要加备注 !!!**
+ -- Gitee From 5680c84de5362ba9a7c153cd4a999ed11e09ecae Mon Sep 17 00:00:00 2001 From: Foming Date: Thu, 14 Dec 2023 02:24:00 +0000 Subject: [PATCH 21/25] update README_CN.md. Signed-off-by: Foming --- README_CN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_CN.md b/README_CN.md index 1cbda86..c56c10a 100644 --- a/README_CN.md +++ b/README_CN.md @@ -85,8 +85,8 @@ AJ-Captcha技术支持三群,有问题都可以在群里问

-个人微信:个人微信,不闲聊,加群、咨询请备注,备注格式不限但最好是:“项目名 问题”, 项目名可以是**AJ-Captcha**、**Captcha**、**验证码**,只要能一眼分辨就行
-例1:验证码 加群 +个人微信:个人微信,不闲聊,加群、咨询请备注,备注格式不限但最好是:“项目名 + 问题”, 项目名可以是**AJ-Captcha**、**Captcha**、**验证码**,只要能一眼分辨就行
+例1:验证码 加群
例2:captche 有个问题xxxx
有问题,不管是技术问题还是使用问题,都尽量在群里问,没啥特殊问题尽量别加个人微信。加个人微信记得**一定要加备注 !!!**
-- Gitee From 1b2509840b62e96b2866bef9a82fa8bf3ca8244a Mon Sep 17 00:00:00 2001 From: baoge Date: Mon, 15 Apr 2024 09:00:03 +0800 Subject: [PATCH 22/25] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0SpringBoot3.0.?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README_CN.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README_CN.md b/README_CN.md index c56c10a..4985356 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,3 +1,4 @@ +2024-04-11 升级到SpringBoot3.0.2 # **在线体验暂时下线** -- Gitee From 6c828a18b05320b5a65e2092abf92ba15dd40d41 Mon Sep 17 00:00:00 2001 From: baoge Date: Mon, 15 Apr 2024 09:20:22 +0800 Subject: [PATCH 23/25] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0SpringBoot3.0.?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/META-INF/spring.factories | 1 - 1 file changed, 1 deletion(-) delete mode 100644 core/captcha-spring-boot-starter/src/main/resources/META-INF/spring.factories diff --git a/core/captcha-spring-boot-starter/src/main/resources/META-INF/spring.factories b/core/captcha-spring-boot-starter/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 218ca00..0000000 --- a/core/captcha-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.anji.captcha.config.AjCaptchaAutoConfiguration \ No newline at end of file -- Gitee From 4047ef2720fc953518d95613f13a9276f42327b3 Mon Sep 17 00:00:00 2001 From: baoge Date: Mon, 15 Apr 2024 09:20:31 +0800 Subject: [PATCH 24/25] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0SpringBoot3.0.?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ....springframework.boot.autoconfigure.AutoConfiguration.imports | 1 + 1 file changed, 1 insertion(+) create mode 100644 core/captcha-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/core/captcha-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/core/captcha-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..4a295be --- /dev/null +++ b/core/captcha-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.anji.captcha.config.AjCaptchaAutoConfiguration -- Gitee From d1ab6e5cac9d6bc864c3957ed87c043534ec3e5e Mon Sep 17 00:00:00 2001 From: baoge Date: Mon, 15 Apr 2024 09:20:44 +0800 Subject: [PATCH 25/25] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0SpringBoot3.0.?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/captcha-spring-boot-starter/pom.xml | 10 ++++----- .../captcha/controller/CaptchaController.java | 2 +- core/captcha/pom.xml | 9 ++++---- pom.xml | 18 +++++++++++++--- service/springboot/pom.xml | 21 ++++++++++++++++--- .../anji/captcha/demo/filter/CorsFilter.java | 8 +++---- service/springmvc/pom.xml | 16 +++++++------- 7 files changed, 55 insertions(+), 29 deletions(-) diff --git a/core/captcha-spring-boot-starter/pom.xml b/core/captcha-spring-boot-starter/pom.xml index f0c4178..95b65d9 100644 --- a/core/captcha-spring-boot-starter/pom.xml +++ b/core/captcha-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.5.RELEASE + 3.0.2 com.anji-plus @@ -20,8 +20,8 @@ jar - 1.8 - 2.3.5.RELEASE + 17 + 3.0.2 @@ -85,8 +85,8 @@ maven-compiler-plugin 3.3 - 1.8 - 1.8 + 17 + 17 UTF-8 diff --git a/core/captcha-spring-boot-starter/src/main/java/com/anji/captcha/controller/CaptchaController.java b/core/captcha-spring-boot-starter/src/main/java/com/anji/captcha/controller/CaptchaController.java index 468833e..8156e0f 100644 --- a/core/captcha-spring-boot-starter/src/main/java/com/anji/captcha/controller/CaptchaController.java +++ b/core/captcha-spring-boot-starter/src/main/java/com/anji/captcha/controller/CaptchaController.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @RestController diff --git a/core/captcha/pom.xml b/core/captcha/pom.xml index c9585dc..8394cd5 100644 --- a/core/captcha/pom.xml +++ b/core/captcha/pom.xml @@ -16,7 +16,7 @@ UTF-8 UTF-8 - 1.8 + 17 @@ -24,7 +24,7 @@ org.slf4j slf4j-api - 1.7.25 + 2.0.2 provided @@ -51,7 +51,6 @@ https://github.com/anji-plus - snapshots @@ -65,8 +64,8 @@ maven-compiler-plugin 3.3 - 1.8 - 1.8 + 17 + 17 UTF-8 diff --git a/pom.xml b/pom.xml index ac76340..97c7f58 100644 --- a/pom.xml +++ b/pom.xml @@ -10,10 +10,10 @@ pom - 2.0.4.RELEASE + 3.0.2 1.2.0 - 1.8 - 1.8 + 17 + 17 UTF-8 @@ -43,6 +43,18 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + core/captcha core/captcha-spring-boot-starter diff --git a/service/springboot/pom.xml b/service/springboot/pom.xml index 54bd33a..7e83a1c 100644 --- a/service/springboot/pom.xml +++ b/service/springboot/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.5.RELEASE + 3.0.2 com.anji.captcha @@ -20,8 +20,8 @@ jar - 1.8 - 2.3.5.RELEASE + 17 + 3.0.2 true @@ -61,6 +61,13 @@ + + + junit + junit + 4.11 + test + @@ -70,6 +77,14 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + diff --git a/service/springboot/src/main/java/com/anji/captcha/demo/filter/CorsFilter.java b/service/springboot/src/main/java/com/anji/captcha/demo/filter/CorsFilter.java index f684079..ff36e7c 100644 --- a/service/springboot/src/main/java/com/anji/captcha/demo/filter/CorsFilter.java +++ b/service/springboot/src/main/java/com/anji/captcha/demo/filter/CorsFilter.java @@ -12,10 +12,10 @@ package com.anji.captcha.demo.filter; */ import org.springframework.context.annotation.Configuration; -import javax.servlet.*; -import javax.servlet.annotation.WebFilter; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.*; +import jakarta.servlet.annotation.WebFilter; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(filterName = "CorsFilter ") diff --git a/service/springmvc/pom.xml b/service/springmvc/pom.xml index 351af8c..1963c80 100644 --- a/service/springmvc/pom.xml +++ b/service/springmvc/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.anjiplus.demo @@ -14,12 +14,12 @@ UTF-8 - 1.7 - 1.7 + 17 + 17 1.8 1.6.6 1.2.12 - 5.0.16.RELEASE + 6.0.4 @@ -33,7 +33,7 @@ com.anji-plus captcha - 1.2.9 + 1.3.1 com.alibaba @@ -96,13 +96,13 @@ org.slf4j slf4j-api - 1.7.25 + 2.0.2 org.slf4j slf4j-log4j12 - 1.7.25 + 2.0.2 @@ -114,7 +114,7 @@ org.springframework.data spring-data-redis - 1.8.1.RELEASE + 3.0.1 -- Gitee