更新结构
This commit is contained in:
parent
8444433e5b
commit
9a51adf2e8
1
.example.env
Normal file
1
.example.env
Normal file
@ -0,0 +1 @@
|
|||||||
|
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = test
USERNAME = username
PASSWORD = password
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true
[LANG]
default_lang = zh-cn
|
||||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
/vendor
|
||||||
|
*.log
|
||||||
|
.env
|
||||||
42
.travis.yml
Normal file
42
.travis.yml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
sudo: false
|
||||||
|
|
||||||
|
language: php
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- stable
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.composer/cache
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- composer self-update
|
||||||
|
|
||||||
|
install:
|
||||||
|
- composer install --no-dev --no-interaction --ignore-platform-reqs
|
||||||
|
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
|
||||||
|
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
|
||||||
|
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
|
||||||
|
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
|
||||||
|
|
||||||
|
script:
|
||||||
|
- php think unit
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
api_key:
|
||||||
|
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
|
||||||
|
file:
|
||||||
|
- ThinkPHP_Core.zip
|
||||||
|
- ThinkPHP_Full.zip
|
||||||
|
skip_cleanup: true
|
||||||
|
on:
|
||||||
|
tags: true
|
||||||
32
LICENSE.txt
Normal file
32
LICENSE.txt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
|
||||||
|
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
|
||||||
|
All rights reserved。
|
||||||
|
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
|
||||||
|
|
||||||
|
Apache Licence是著名的非盈利开源组织Apache采用的协议。
|
||||||
|
该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
|
||||||
|
允许代码修改,再作为开源或商业软件发布。需要满足
|
||||||
|
的条件:
|
||||||
|
1. 需要给代码的用户一份Apache Licence ;
|
||||||
|
2. 如果你修改了代码,需要在被修改的文件中说明;
|
||||||
|
3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
|
||||||
|
带有原来代码中的协议,商标,专利声明和其他原来作者规
|
||||||
|
定需要包含的说明;
|
||||||
|
4. 如果再发布的产品中包含一个Notice文件,则在Notice文
|
||||||
|
件中需要带有本协议内容。你可以在Notice中增加自己的
|
||||||
|
许可,但不可以表现为对Apache Licence构成更改。
|
||||||
|
具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
126
README.md
Normal file
126
README.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
目录结构
|
||||||
|
=========================
|
||||||
|
www WEB部署目录(或者子目录)
|
||||||
|
├─app 应用目录
|
||||||
|
│ ├─controller 控制器目录
|
||||||
|
│ ├─model 模型目录
|
||||||
|
│ ├─ ... 更多类库目录
|
||||||
|
│ │
|
||||||
|
│ ├─common.php 公共函数文件
|
||||||
|
│ └─event.php 事件定义文件
|
||||||
|
│
|
||||||
|
├─config 配置目录
|
||||||
|
│ ├─app.php 应用配置
|
||||||
|
│ ├─cache.php 缓存配置
|
||||||
|
│ ├─console.php 控制台配置
|
||||||
|
│ ├─cookie.php Cookie配置
|
||||||
|
│ ├─database.php 数据库配置
|
||||||
|
│ ├─filesystem.php 文件磁盘配置
|
||||||
|
│ ├─lang.php 多语言配置
|
||||||
|
│ ├─log.php 日志配置
|
||||||
|
│ ├─middleware.php 中间件配置
|
||||||
|
│ ├─route.php URL和路由配置
|
||||||
|
│ ├─session.php Session配置
|
||||||
|
│ ├─trace.php Trace配置
|
||||||
|
│ └─view.php 视图配置
|
||||||
|
│
|
||||||
|
├─view 视图目录
|
||||||
|
├─route 路由定义目录
|
||||||
|
│ ├─route.php 路由定义文件
|
||||||
|
│ └─ ...
|
||||||
|
│
|
||||||
|
├─public WEB目录(对外访问目录)
|
||||||
|
│ ├─index.php 入口文件
|
||||||
|
│ ├─router.php 快速测试文件
|
||||||
|
│ └─.htaccess 用于apache的重写
|
||||||
|
│
|
||||||
|
├─extend 扩展类库目录
|
||||||
|
├─runtime 应用的运行时目录(可写,可定制)
|
||||||
|
├─vendor Composer类库目录
|
||||||
|
├─.example.env 环境变量示例文件
|
||||||
|
├─composer.json composer 定义文件
|
||||||
|
├─LICENSE.txt 授权说明文件
|
||||||
|
├─README.md README 文件
|
||||||
|
├─think 命令行入口文件
|
||||||
|
|
||||||
|
|
||||||
|
默认应用文件
|
||||||
|
=========================
|
||||||
|
默认安装后,app目录下会包含下面的文件。
|
||||||
|
├─app 应用目录
|
||||||
|
│ │
|
||||||
|
│ ├─BaseController.php 默认基础控制器类
|
||||||
|
│ ├─ExceptionHandle.php 应用异常定义文件
|
||||||
|
│ ├─common.php 全局公共函数文件
|
||||||
|
│ ├─middleware.php 全局中间件定义文件
|
||||||
|
│ ├─provider.php 服务提供定义文件
|
||||||
|
│ ├─Request.php 应用请求对象
|
||||||
|
│ └─event.php 全局事件定义文件
|
||||||
|
|
||||||
|
配置目录
|
||||||
|
=========================
|
||||||
|
├─config(配置目录)
|
||||||
|
│ ├─app.php 应用配置
|
||||||
|
│ ├─cache.php 缓存配置
|
||||||
|
│ ├─console.php 控制台配置
|
||||||
|
│ ├─cookie.php Cookie配置
|
||||||
|
│ ├─database.php 数据库配置
|
||||||
|
│ ├─filesystem.php 文件磁盘配置
|
||||||
|
│ ├─lang.php 多语言配置
|
||||||
|
│ ├─log.php 日志配置
|
||||||
|
│ ├─middleware.php 中间件配置
|
||||||
|
│ ├─route.php URL和路由配置
|
||||||
|
│ ├─session.php Session配置
|
||||||
|
│ ├─trace.php Trace配置
|
||||||
|
│ ├─view.php 视图配置
|
||||||
|
│ └─ ... 更多配置文件
|
||||||
|
│
|
||||||
|
|
||||||
|
|
||||||
|
ThinkPHP 6.0
|
||||||
|
===============
|
||||||
|
|
||||||
|
> 运行环境要求PHP7.2+,兼容PHP8.1
|
||||||
|
|
||||||
|
[官方应用服务市场](https://market.topthink.com) | [`ThinkAPI`——官方统一API服务](https://docs.topthink.com/think-api)
|
||||||
|
|
||||||
|
ThinkPHPV6.0版本由[亿速云](https://www.yisu.com/)独家赞助发布。
|
||||||
|
|
||||||
|
## 主要新特性
|
||||||
|
|
||||||
|
* 采用`PHP7`强类型(严格模式)
|
||||||
|
* 支持更多的`PSR`规范
|
||||||
|
* 原生多应用支持
|
||||||
|
* 更强大和易用的查询
|
||||||
|
* 全新的事件系统
|
||||||
|
* 模型事件和数据库事件统一纳入事件系统
|
||||||
|
* 模板引擎分离出核心
|
||||||
|
* 内部功能中间件化
|
||||||
|
* SESSION/Cookie机制改进
|
||||||
|
* 对Swoole以及协程支持改进
|
||||||
|
* 对IDE更加友好
|
||||||
|
* 统一和精简大量用法
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
|
||||||
|
|
||||||
|
## 参与开发
|
||||||
|
|
||||||
|
请参阅 [ThinkPHP 核心框架包](https://github.com/top-think/framework)。
|
||||||
|
|
||||||
|
## 版权信息
|
||||||
|
|
||||||
|
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
|
||||||
|
|
||||||
|
本项目包含的第三方源码和二进制文件之版权信息另行标注。
|
||||||
|
|
||||||
|
版权所有Copyright © 2006-2021 by ThinkPHP (http://thinkphp.cn)
|
||||||
|
|
||||||
|
All rights reserved。
|
||||||
|
|
||||||
|
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
|
||||||
|
|
||||||
|
更多细节参阅 [LICENSE.txt](LICENSE.txt)
|
||||||
1
app/.htaccess
Normal file
1
app/.htaccess
Normal file
@ -0,0 +1 @@
|
|||||||
|
deny from all
|
||||||
22
app/AppService.php
Normal file
22
app/AppService.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
declare (strict_types = 1);
|
||||||
|
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use think\Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用服务类
|
||||||
|
*/
|
||||||
|
class AppService extends Service
|
||||||
|
{
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
// 服务注册
|
||||||
|
}
|
||||||
|
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
// 服务启动
|
||||||
|
}
|
||||||
|
}
|
||||||
94
app/BaseController.php
Normal file
94
app/BaseController.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
declare (strict_types = 1);
|
||||||
|
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use think\App;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器基础类
|
||||||
|
*/
|
||||||
|
abstract class BaseController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Request实例
|
||||||
|
* @var \think\Request
|
||||||
|
*/
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用实例
|
||||||
|
* @var \think\App
|
||||||
|
*/
|
||||||
|
protected $app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否批量验证
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $batchValidate = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器中间件
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $middleware = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造方法
|
||||||
|
* @access public
|
||||||
|
* @param App $app 应用对象
|
||||||
|
*/
|
||||||
|
public function __construct(App $app)
|
||||||
|
{
|
||||||
|
$this->app = $app;
|
||||||
|
$this->request = $this->app->request;
|
||||||
|
|
||||||
|
// 控制器初始化
|
||||||
|
$this->initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
protected function initialize()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证数据
|
||||||
|
* @access protected
|
||||||
|
* @param array $data 数据
|
||||||
|
* @param string|array $validate 验证器名或者验证规则数组
|
||||||
|
* @param array $message 提示信息
|
||||||
|
* @param bool $batch 是否批量验证
|
||||||
|
* @return array|string|true
|
||||||
|
* @throws ValidateException
|
||||||
|
*/
|
||||||
|
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
|
||||||
|
{
|
||||||
|
if (is_array($validate)) {
|
||||||
|
$v = new Validate();
|
||||||
|
$v->rule($validate);
|
||||||
|
} else {
|
||||||
|
if (strpos($validate, '.')) {
|
||||||
|
// 支持场景
|
||||||
|
[$validate, $scene] = explode('.', $validate);
|
||||||
|
}
|
||||||
|
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
|
||||||
|
$v = new $class();
|
||||||
|
if (!empty($scene)) {
|
||||||
|
$v->scene($scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v->message($message);
|
||||||
|
|
||||||
|
// 是否批量验证
|
||||||
|
if ($batch || $this->batchValidate) {
|
||||||
|
$v->batch(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $v->failException(true)->check($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
58
app/ExceptionHandle.php
Normal file
58
app/ExceptionHandle.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\exception\Handle;
|
||||||
|
use think\exception\HttpException;
|
||||||
|
use think\exception\HttpResponseException;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\Response;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用异常处理类
|
||||||
|
*/
|
||||||
|
class ExceptionHandle extends Handle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 不需要记录信息(日志)的异常类列表
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $ignoreReport = [
|
||||||
|
HttpException::class,
|
||||||
|
HttpResponseException::class,
|
||||||
|
ModelNotFoundException::class,
|
||||||
|
DataNotFoundException::class,
|
||||||
|
ValidateException::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录异常信息(包括日志或者其它方式记录)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param Throwable $exception
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function report(Throwable $exception): void
|
||||||
|
{
|
||||||
|
// 使用内置的方式记录异常日志
|
||||||
|
parent::report($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render an exception into an HTTP response.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param \think\Request $request
|
||||||
|
* @param Throwable $e
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function render($request, Throwable $e): Response
|
||||||
|
{
|
||||||
|
// 添加自定义异常处理机制
|
||||||
|
|
||||||
|
// 其他错误交给系统处理
|
||||||
|
return parent::render($request, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
app/Request.php
Normal file
8
app/Request.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
// 应用请求对象类
|
||||||
|
class Request extends \think\Request
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
17
app/admin/controller/Index.php
Normal file
17
app/admin/controller/Index.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\admin\controller;
|
||||||
|
|
||||||
|
use app\BaseController;
|
||||||
|
|
||||||
|
class Index extends BaseController
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V' . \think\facade\App::version() . '<br/><span style="font-size:30px;">16载初心不改 - 你值得信赖的PHP框架 Admin模块</span></p><span style="font-size:25px;">[ V6.0 版本由 <a href="https://www.yisu.com/" target="yisu">亿速云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ee9b1aa918103c4fc"></think>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hello($name = 'ThinkPHP6')
|
||||||
|
{
|
||||||
|
return 'hello,' . $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
app/common.php
Normal file
2
app/common.php
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?php
|
||||||
|
// 应用公共文件
|
||||||
17
app/event.php
Normal file
17
app/event.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
// 事件定义文件
|
||||||
|
return [
|
||||||
|
'bind' => [
|
||||||
|
],
|
||||||
|
|
||||||
|
'listen' => [
|
||||||
|
'AppInit' => [],
|
||||||
|
'HttpRun' => [],
|
||||||
|
'HttpEnd' => [],
|
||||||
|
'LogLevel' => [],
|
||||||
|
'LogWrite' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'subscribe' => [
|
||||||
|
],
|
||||||
|
];
|
||||||
10
app/middleware.php
Normal file
10
app/middleware.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
// 全局中间件定义文件
|
||||||
|
return [
|
||||||
|
// 全局请求缓存
|
||||||
|
// \think\middleware\CheckRequestCache::class,
|
||||||
|
// 多语言加载
|
||||||
|
// \think\middleware\LoadLangPack::class,
|
||||||
|
// Session初始化
|
||||||
|
// \think\middleware\SessionInit::class
|
||||||
|
];
|
||||||
9
app/provider.php
Normal file
9
app/provider.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
use app\ExceptionHandle;
|
||||||
|
use app\Request;
|
||||||
|
|
||||||
|
// 容器Provider定义文件
|
||||||
|
return [
|
||||||
|
'think\Request' => Request::class,
|
||||||
|
'think\exception\Handle' => ExceptionHandle::class,
|
||||||
|
];
|
||||||
9
app/service.php
Normal file
9
app/service.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use app\AppService;
|
||||||
|
|
||||||
|
// 系统服务定义文件
|
||||||
|
// 服务在完成全局初始化之后执行
|
||||||
|
return [
|
||||||
|
AppService::class,
|
||||||
|
];
|
||||||
49
composer.json
Normal file
49
composer.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "topthink/think",
|
||||||
|
"description": "the new thinkphp framework",
|
||||||
|
"type": "project",
|
||||||
|
"keywords": [
|
||||||
|
"framework",
|
||||||
|
"thinkphp",
|
||||||
|
"ORM"
|
||||||
|
],
|
||||||
|
"homepage": "https://www.thinkphp.cn/",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "liu21st",
|
||||||
|
"email": "liu21st@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yunwuxin",
|
||||||
|
"email": "448901948@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"topthink/framework": "^6.1.0",
|
||||||
|
"topthink/think-orm": "^2.0",
|
||||||
|
"topthink/think-filesystem": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/var-dumper": "^4.2",
|
||||||
|
"topthink/think-trace": "^1.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"app\\": "app"
|
||||||
|
},
|
||||||
|
"psr-0": {
|
||||||
|
"": "extend/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"preferred-install": "dist"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"post-autoload-dump": [
|
||||||
|
"@php think service:discover",
|
||||||
|
"@php think vendor:publish"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
1155
composer.lock
generated
Normal file
1155
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
39
config/app.php
Normal file
39
config/app.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 应用设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 应用地址
|
||||||
|
'app_host' => env('app.host', ''),
|
||||||
|
// 应用的命名空间
|
||||||
|
'app_namespace' => '',
|
||||||
|
// 是否启用路由
|
||||||
|
'with_route' => true,
|
||||||
|
// 是否启用事件
|
||||||
|
'with_event' => true,
|
||||||
|
// 自动多应用模式
|
||||||
|
'auto_multi_app' => true,
|
||||||
|
// 默认应用
|
||||||
|
'default_app' => 'index',
|
||||||
|
// 默认时区
|
||||||
|
'default_timezone' => 'Asia/Shanghai',
|
||||||
|
|
||||||
|
// 应用映射(自动多应用模式有效)
|
||||||
|
'app_map' => [
|
||||||
|
'admin' => 'admin',
|
||||||
|
'pc' => 'pc'
|
||||||
|
],
|
||||||
|
// 域名绑定(自动多应用模式有效)
|
||||||
|
'domain_bind' => [],
|
||||||
|
// 禁止URL访问的应用列表(自动多应用模式有效)
|
||||||
|
'deny_app_list' => [],
|
||||||
|
|
||||||
|
// 异常页面的模板文件
|
||||||
|
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
|
||||||
|
|
||||||
|
// 错误显示信息,非调试模式有效
|
||||||
|
'error_message' => '页面错误!请稍后再试~',
|
||||||
|
// 显示错误信息
|
||||||
|
'show_error_msg' => true,
|
||||||
|
];
|
||||||
29
config/cache.php
Normal file
29
config/cache.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 缓存设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认缓存驱动
|
||||||
|
'default' => env('cache.driver', 'file'),
|
||||||
|
|
||||||
|
// 缓存连接方式配置
|
||||||
|
'stores' => [
|
||||||
|
'file' => [
|
||||||
|
// 驱动方式
|
||||||
|
'type' => 'File',
|
||||||
|
// 缓存保存目录
|
||||||
|
'path' => '',
|
||||||
|
// 缓存前缀
|
||||||
|
'prefix' => '',
|
||||||
|
// 缓存有效期 0表示永久缓存
|
||||||
|
'expire' => 0,
|
||||||
|
// 缓存标签前缀
|
||||||
|
'tag_prefix' => 'tag:',
|
||||||
|
// 序列化机制 例如 ['serialize', 'unserialize']
|
||||||
|
'serialize' => [],
|
||||||
|
],
|
||||||
|
// 更多的缓存连接
|
||||||
|
],
|
||||||
|
];
|
||||||
9
config/console.php
Normal file
9
config/console.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 控制台配置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// 指令定义
|
||||||
|
'commands' => [
|
||||||
|
],
|
||||||
|
];
|
||||||
20
config/cookie.php
Normal file
20
config/cookie.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Cookie设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// cookie 保存时间
|
||||||
|
'expire' => 0,
|
||||||
|
// cookie 保存路径
|
||||||
|
'path' => '/',
|
||||||
|
// cookie 有效域名
|
||||||
|
'domain' => '',
|
||||||
|
// cookie 启用安全传输
|
||||||
|
'secure' => false,
|
||||||
|
// httponly设置
|
||||||
|
'httponly' => false,
|
||||||
|
// 是否使用 setcookie
|
||||||
|
'setcookie' => true,
|
||||||
|
// samesite 设置,支持 'strict' 'lax'
|
||||||
|
'samesite' => '',
|
||||||
|
];
|
||||||
63
config/database.php
Normal file
63
config/database.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认使用的数据库连接配置
|
||||||
|
'default' => env('database.driver', 'mysql'),
|
||||||
|
|
||||||
|
// 自定义时间查询规则
|
||||||
|
'time_query_rule' => [],
|
||||||
|
|
||||||
|
// 自动写入时间戳字段
|
||||||
|
// true为自动识别类型 false关闭
|
||||||
|
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date
|
||||||
|
'auto_timestamp' => true,
|
||||||
|
|
||||||
|
// 时间字段取出后的默认时间格式
|
||||||
|
'datetime_format' => 'Y-m-d H:i:s',
|
||||||
|
|
||||||
|
// 时间字段配置 配置格式:create_time,update_time
|
||||||
|
'datetime_field' => '',
|
||||||
|
|
||||||
|
// 数据库连接配置信息
|
||||||
|
'connections' => [
|
||||||
|
'mysql' => [
|
||||||
|
// 数据库类型
|
||||||
|
'type' => env('database.type', 'mysql'),
|
||||||
|
// 服务器地址
|
||||||
|
'hostname' => env('database.hostname', '127.0.0.1'),
|
||||||
|
// 数据库名
|
||||||
|
'database' => env('database.database', ''),
|
||||||
|
// 用户名
|
||||||
|
'username' => env('database.username', 'root'),
|
||||||
|
// 密码
|
||||||
|
'password' => env('database.password', ''),
|
||||||
|
// 端口
|
||||||
|
'hostport' => env('database.hostport', '3306'),
|
||||||
|
// 数据库连接参数
|
||||||
|
'params' => [],
|
||||||
|
// 数据库编码默认采用utf8
|
||||||
|
'charset' => env('database.charset', 'utf8'),
|
||||||
|
// 数据库表前缀
|
||||||
|
'prefix' => env('database.prefix', ''),
|
||||||
|
|
||||||
|
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||||
|
'deploy' => 0,
|
||||||
|
// 数据库读写是否分离 主从式有效
|
||||||
|
'rw_separate' => false,
|
||||||
|
// 读写分离后 主服务器数量
|
||||||
|
'master_num' => 1,
|
||||||
|
// 指定从服务器序号
|
||||||
|
'slave_no' => '',
|
||||||
|
// 是否严格检查字段是否存在
|
||||||
|
'fields_strict' => true,
|
||||||
|
// 是否需要断线重连
|
||||||
|
'break_reconnect' => false,
|
||||||
|
// 监听SQL
|
||||||
|
'trigger_sql' => env('app_debug', true),
|
||||||
|
// 开启字段缓存
|
||||||
|
'fields_cache' => false,
|
||||||
|
],
|
||||||
|
|
||||||
|
// 更多的数据库配置信息
|
||||||
|
],
|
||||||
|
];
|
||||||
24
config/filesystem.php
Normal file
24
config/filesystem.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认磁盘
|
||||||
|
'default' => env('filesystem.driver', 'local'),
|
||||||
|
// 磁盘列表
|
||||||
|
'disks' => [
|
||||||
|
'local' => [
|
||||||
|
'type' => 'local',
|
||||||
|
'root' => app()->getRuntimePath() . 'storage',
|
||||||
|
],
|
||||||
|
'public' => [
|
||||||
|
// 磁盘类型
|
||||||
|
'type' => 'local',
|
||||||
|
// 磁盘路径
|
||||||
|
'root' => app()->getRootPath() . 'public/storage',
|
||||||
|
// 磁盘路径对应的外部URL路径
|
||||||
|
'url' => '/storage',
|
||||||
|
// 可见性
|
||||||
|
'visibility' => 'public',
|
||||||
|
],
|
||||||
|
// 更多的磁盘配置信息
|
||||||
|
],
|
||||||
|
];
|
||||||
27
config/lang.php
Normal file
27
config/lang.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 多语言设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认语言
|
||||||
|
'default_lang' => env('lang.default_lang', 'zh-cn'),
|
||||||
|
// 允许的语言列表
|
||||||
|
'allow_lang_list' => [],
|
||||||
|
// 多语言自动侦测变量名
|
||||||
|
'detect_var' => 'lang',
|
||||||
|
// 是否使用Cookie记录
|
||||||
|
'use_cookie' => true,
|
||||||
|
// 多语言cookie变量
|
||||||
|
'cookie_var' => 'think_lang',
|
||||||
|
// 多语言header变量
|
||||||
|
'header_var' => 'think-lang',
|
||||||
|
// 扩展语言包
|
||||||
|
'extend_list' => [],
|
||||||
|
// Accept-Language转义为对应语言包名称
|
||||||
|
'accept_language' => [
|
||||||
|
'zh-hans-cn' => 'zh-cn',
|
||||||
|
],
|
||||||
|
// 是否支持语言分组
|
||||||
|
'allow_group' => false,
|
||||||
|
];
|
||||||
45
config/log.php
Normal file
45
config/log.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 日志设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// 默认日志记录通道
|
||||||
|
'default' => env('log.channel', 'file'),
|
||||||
|
// 日志记录级别
|
||||||
|
'level' => [],
|
||||||
|
// 日志类型记录的通道 ['error'=>'email',...]
|
||||||
|
'type_channel' => [],
|
||||||
|
// 关闭全局日志写入
|
||||||
|
'close' => false,
|
||||||
|
// 全局日志处理 支持闭包
|
||||||
|
'processor' => null,
|
||||||
|
|
||||||
|
// 日志通道列表
|
||||||
|
'channels' => [
|
||||||
|
'file' => [
|
||||||
|
// 日志记录方式
|
||||||
|
'type' => 'File',
|
||||||
|
// 日志保存目录
|
||||||
|
'path' => '',
|
||||||
|
// 单文件日志写入
|
||||||
|
'single' => false,
|
||||||
|
// 独立日志级别
|
||||||
|
'apart_level' => [],
|
||||||
|
// 最大日志文件数量
|
||||||
|
'max_files' => 0,
|
||||||
|
// 使用JSON格式记录
|
||||||
|
'json' => false,
|
||||||
|
// 日志处理
|
||||||
|
'processor' => null,
|
||||||
|
// 关闭通道日志写入
|
||||||
|
'close' => false,
|
||||||
|
// 日志输出格式化
|
||||||
|
'format' => '[%s][%s] %s',
|
||||||
|
// 是否实时写入
|
||||||
|
'realtime_write' => false,
|
||||||
|
],
|
||||||
|
// 其它日志通道配置
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
8
config/middleware.php
Normal file
8
config/middleware.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
// 中间件配置
|
||||||
|
return [
|
||||||
|
// 别名或分组
|
||||||
|
'alias' => [],
|
||||||
|
// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
|
||||||
|
'priority' => [],
|
||||||
|
];
|
||||||
45
config/route.php
Normal file
45
config/route.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 路由设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// pathinfo分隔符
|
||||||
|
'pathinfo_depr' => '/',
|
||||||
|
// 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_key' => 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',
|
||||||
|
];
|
||||||
19
config/session.php
Normal file
19
config/session.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 会话设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// session name
|
||||||
|
'name' => 'PHPSESSID',
|
||||||
|
// SESSION_ID的提交变量,解决flash上传跨域
|
||||||
|
'var_session_id' => '',
|
||||||
|
// 驱动方式 支持file cache
|
||||||
|
'type' => 'file',
|
||||||
|
// 存储连接标识 当type使用cache的时候有效
|
||||||
|
'store' => null,
|
||||||
|
// 过期时间
|
||||||
|
'expire' => 1440,
|
||||||
|
// 前缀
|
||||||
|
'prefix' => '',
|
||||||
|
];
|
||||||
10
config/trace.php
Normal file
10
config/trace.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Trace设置 开启调试模式后有效
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// 内置Html和Console两种方式 支持扩展
|
||||||
|
'type' => 'Html',
|
||||||
|
// 读取的日志通道名
|
||||||
|
'channel' => '',
|
||||||
|
];
|
||||||
25
config/view.php
Normal file
25
config/view.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 模板设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 模板引擎类型使用Think
|
||||||
|
'type' => 'Think',
|
||||||
|
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
|
||||||
|
'auto_rule' => 1,
|
||||||
|
// 模板目录名
|
||||||
|
'view_dir_name' => 'view',
|
||||||
|
// 模板后缀
|
||||||
|
'view_suffix' => 'html',
|
||||||
|
// 模板文件名分隔符
|
||||||
|
'view_depr' => DIRECTORY_SEPARATOR,
|
||||||
|
// 模板引擎普通标签开始标记
|
||||||
|
'tpl_begin' => '{',
|
||||||
|
// 模板引擎普通标签结束标记
|
||||||
|
'tpl_end' => '}',
|
||||||
|
// 标签库标签开始标记
|
||||||
|
'taglib_begin' => '{',
|
||||||
|
// 标签库标签结束标记
|
||||||
|
'taglib_end' => '}',
|
||||||
|
];
|
||||||
2
extend/.gitignore
vendored
Normal file
2
extend/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
8
nginx.htaccess
Normal file
8
nginx.htaccess
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
location ~* (runtime|application)/{
|
||||||
|
return 403;
|
||||||
|
}
|
||||||
|
location / {
|
||||||
|
if (!-e $request_filename){
|
||||||
|
rewrite ^(.*)$ /index.php?s=$1 last; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +0,0 @@
|
|||||||
[*.{js,jsx,ts,tsx,vue}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
end_of_line = crlf
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
max_line_length = 120
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
# 本地运行端口号
|
|
||||||
VITE_PORT = 8686
|
|
||||||
|
|
||||||
# API接口域名配置
|
|
||||||
API_BASE_URL = https://api.example.com/
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# 本地环境
|
|
||||||
VITE_USER_NODE_ENV = development
|
|
||||||
|
|
||||||
# 公共基础路径
|
|
||||||
VITE_PUBLIC_PATH = /
|
|
||||||
|
|
||||||
# proxy
|
|
||||||
VITE_PROXY = [["/api","http://localhost:8080"]]
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
# 线上环境
|
|
||||||
VITE_USER_NODE_ENV = production
|
|
||||||
|
|
||||||
# 公共基础路径
|
|
||||||
VITE_PUBLIC_PATH = /
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
node_modules
|
|
||||||
dist
|
|
||||||
public
|
|
||||||
*.md
|
|
||||||
*.txt
|
|
||||||
.vscode
|
|
||||||
index.html
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
es2021: true,
|
|
||||||
node: true
|
|
||||||
},
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:vue/vue3-essential',
|
|
||||||
'plugin:prettier/recommended' // 后续兼容prettier
|
|
||||||
],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
env: {
|
|
||||||
node: true
|
|
||||||
},
|
|
||||||
files: ['.eslintrc.{js,cjs}'],
|
|
||||||
parserOptions: {
|
|
||||||
sourceType: 'script'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 'latest',
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
sourceType: 'module'
|
|
||||||
},
|
|
||||||
plugins: ['@typescript-eslint', 'vue'],
|
|
||||||
rules: {
|
|
||||||
// Switch语句 https://zh-hans.eslint.org/docs/latest/rules/indent#switchcase
|
|
||||||
indent: ['error', 2, { SwitchCase: 1 }],
|
|
||||||
'linebreak-style': ['error', 'windows'],
|
|
||||||
quotes: ['error', 'single'],
|
|
||||||
semi: ['error', 'never']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
pc-b/.gitignore
vendored
24
pc-b/.gitignore
vendored
@ -1,24 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
node_modules
|
|
||||||
dist
|
|
||||||
public
|
|
||||||
*.md
|
|
||||||
*.txt
|
|
||||||
.vscode
|
|
||||||
index.html
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"useTabs": false,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"printWidth": 120,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "none",
|
|
||||||
"bracketSpacing": true,
|
|
||||||
"semi": false,
|
|
||||||
"endOfLine": "crlf"
|
|
||||||
}
|
|
||||||
3
pc-b/.vscode/extensions.json
vendored
3
pc-b/.vscode/extensions.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": ["Vue.volar"]
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
PATH=D:\Software\Python36\Scripts\;D:\Software\Python36;D:\Software\VMware\VMware Workstation\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Windows;C:\Windows\System32\OpenSSH\;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\system32;D:\Cache\Android\android-sdk\platform-tools;D:\Software\Git\cmd;D:\Software\JetBrains\IntelliJ IDEA 2023.3.5\bin;D:\Software\JetBrains\PhpStorm 2023.3.2\bin;D:\Software\JetBrains\PyCharm 2023.3.4\bin;c:\Users\Administrator\AppData\Local\Programs\cursor\resources\app\bin;C:\ProgramData\ComposerSetup\bin;D:\Software\Tencent\΢ÐÅweb¿ª·¢Õß¹¤¾ß\dll;C:\Program Files\python;C:\Program Files\python\Scripts;D:\BtSoft\panel\script;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\Software\TortoiseGit\bin;D:\Software\nvm;D:\Software\nvm4w\nodejs;D:\Software\phpstudy_pro\Extensions\php\php7.4.3nts;C:\Program Files\PuTTY\;d:\Software\Trae CN\bin;D:\Software\Python36\;D:\Software\Python39\Scripts\;D:\Software\Python39\;D:\Software\Python310\Scripts\;D:\Software\Python310\;C:\Users\Administrator\AppData\Local\JetBrains\Toolbox\scripts;D:\phpEnv\php\php-8.0;D:\phpEnv\server\mysql\mysql-5.7\bin;D:\phpEnv\tools\Composer;C:\Users\Administrator\AppData\Roaming\Composer\vendor\bin;D:\Software\Microsoft VS Code\bin;C:\Users\Administrator\AppData\Local\Programs\Ollama
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
# Vue 3 + TypeScript + Vite
|
|
||||||
|
|
||||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
|
||||||
|
|
||||||
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
|
|
||||||
|
|
||||||
# 目录结构
|
|
||||||
```
|
|
||||||
| .env
|
|
||||||
| .env.development
|
|
||||||
| .env.production
|
|
||||||
| .gitignore
|
|
||||||
| index.html
|
|
||||||
| package-lock.json
|
|
||||||
| package.json
|
|
||||||
| README.md
|
|
||||||
| tree.txt
|
|
||||||
| tsconfig.json
|
|
||||||
| tsconfig.node.json
|
|
||||||
| vite.config.ts
|
|
||||||
|
|
|
||||||
+---.vscode
|
|
||||||
| extensions.json
|
|
||||||
|
|
|
||||||
+---build
|
|
||||||
| index.ts
|
|
||||||
|
|
|
||||||
+---node_modules
|
|
||||||
+---public
|
|
||||||
| vite.svg
|
|
||||||
|
|
|
||||||
+---src
|
|
||||||
| | App.vue
|
|
||||||
| | main.ts
|
|
||||||
| | style.css
|
|
||||||
| | vite-env.d.ts
|
|
||||||
| |
|
|
||||||
| +---assets
|
|
||||||
| | vue.svg
|
|
||||||
| |
|
|
||||||
| \---components
|
|
||||||
| HelloWorld.vue
|
|
||||||
|
|
|
||||||
\---types
|
|
||||||
index.d.ts
|
|
||||||
```
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
// 环境变量处理方法
|
|
||||||
export function wrapperEnv(envConf: Recordable): ViteEnv {
|
|
||||||
const ret: Record<string, string | number | boolean> = {};
|
|
||||||
|
|
||||||
for (const envName of Object.keys(envConf)) {
|
|
||||||
let realName = envConf[envName].replace(/\\n/g, "\n");
|
|
||||||
realName = realName === "true" ? true : realName === "false" ? false : realName;
|
|
||||||
if (envName === "VITE_PORT") realName = Number(realName);
|
|
||||||
ret[envName] = realName;
|
|
||||||
if (typeof realName === "string") {
|
|
||||||
process.env[envName] = realName;
|
|
||||||
} else if (typeof realName === "object") {
|
|
||||||
process.env[envName] = JSON.stringify(realName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import vue from '@vitejs/plugin-vue'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* * 扩展setup插件,支持在script标签中使用name属性
|
|
||||||
* usage: <script setup name="MyComp"></script>
|
|
||||||
*/
|
|
||||||
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
|
|
||||||
|
|
||||||
export function createVitePlugins(viteEnv: Record<string, string>, isBuild: boolean): any[] {
|
|
||||||
const plugins = [
|
|
||||||
vue(),
|
|
||||||
VueSetupExtend(),
|
|
||||||
]
|
|
||||||
|
|
||||||
return plugins
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import js from "@eslint/js";
|
|
||||||
import globals from "globals";
|
|
||||||
import tseslint from "typescript-eslint";
|
|
||||||
import pluginVue from "eslint-plugin-vue";
|
|
||||||
import { defineConfig } from "eslint/config";
|
|
||||||
|
|
||||||
|
|
||||||
export default defineConfig([
|
|
||||||
{ files: ["**/*.{js,mjs,cjs,ts,vue}"], plugins: { js }, extends: ["js/recommended"] },
|
|
||||||
{ files: ["**/*.{js,mjs,cjs,ts,vue}"], languageOptions: { globals: {...globals.browser, ...globals.node} } },
|
|
||||||
tseslint.configs.recommended,
|
|
||||||
pluginVue.configs["flat/essential"],
|
|
||||||
{ files: ["**/*.vue"], languageOptions: { parserOptions: { parser: tseslint.parser } } },
|
|
||||||
]);
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Vite + Vue + TS</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
5996
pc-b/package-lock.json
generated
5996
pc-b/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,50 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "vue3project",
|
|
||||||
"private": true,
|
|
||||||
"version": "0.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "vue-tsc -b && vite build",
|
|
||||||
"type-check": "vue-tsc --noEmit",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"lint": "eslint --fix --ext .ts,.tsx,.vue,.js,.jsx --max-warnings 0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@types/js-cookie": "^3.0.6",
|
|
||||||
"@vueuse/core": "^13.1.0",
|
|
||||||
"axios": "^1.8.4",
|
|
||||||
"echarts": "^5.6.0",
|
|
||||||
"element-plus": "^2.9.8",
|
|
||||||
"js-cookie": "^3.0.5",
|
|
||||||
"pinia": "^3.0.2",
|
|
||||||
"pinia-plugin-persistedstate": "^4.2.0",
|
|
||||||
"vue": "^3.5.13",
|
|
||||||
"vue-i18n": "^11.1.3",
|
|
||||||
"vue-router": "^4.5.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@eslint/js": "^9.25.1",
|
|
||||||
"@types/node": "^22.14.1",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^8.31.0",
|
|
||||||
"@typescript-eslint/parser": "^8.31.0",
|
|
||||||
"@vitejs/plugin-vue": "^5.2.2",
|
|
||||||
"@vue/tsconfig": "^0.7.0",
|
|
||||||
"eslint": "^9.25.1",
|
|
||||||
"eslint-config-prettier": "^10.1.2",
|
|
||||||
"eslint-plugin-prettier": "^5.2.6",
|
|
||||||
"eslint-plugin-vue": "^10.0.0",
|
|
||||||
"globals": "^16.0.0",
|
|
||||||
"naive-ui": "^2.41.0",
|
|
||||||
"prettier": "^3.5.3",
|
|
||||||
"sass": "^1.87.0",
|
|
||||||
"sass-embedded": "^1.87.0",
|
|
||||||
"typescript": "~5.7.2",
|
|
||||||
"typescript-eslint": "^8.31.0",
|
|
||||||
"unplugin-vue-components": "^28.5.0",
|
|
||||||
"unplugin-vue-router": "^0.12.0",
|
|
||||||
"vite": "^6.3.1",
|
|
||||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
|
||||||
"vue-tsc": "^2.2.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,4 +0,0 @@
|
|||||||
root: pc
|
|
||||||
path: C:\Program Files\nodejs
|
|
||||||
arch: 64
|
|
||||||
proxy: none
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { onMounted, ref ,provide} from 'vue'
|
|
||||||
import * as echarts from "echarts";
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
|
|
||||||
//通过provide提供echarts
|
|
||||||
provide("echarts", echarts);
|
|
||||||
|
|
||||||
const I18n = useI18n()
|
|
||||||
const { locale } = useI18n()
|
|
||||||
// 切换语言更改locale.value的值即可但要跟你index.js中message设置的值一致!
|
|
||||||
|
|
||||||
const translate = (lang) => {
|
|
||||||
locale.value = lang
|
|
||||||
localStorage.setItem('lang', lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
const type = ref('light')
|
|
||||||
const onChange = (e) => {
|
|
||||||
document.documentElement.setAttribute('theme-mode', type.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<p>{{ $t('welcome') }}</p>
|
|
||||||
</div>
|
|
||||||
<button @click="translate('zh-cn')">切换为中文</button>
|
|
||||||
<button @click="translate('en-us')">切换为英文</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-select style="width: 80px;margin: 10px;" v-model="type" @change="onChange">
|
|
||||||
<el-option label="light" value="light" />
|
|
||||||
<el-option label="dark" value="dark" />
|
|
||||||
<el-option label="red" value="red" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
<router-link to="/"> 去首页 </router-link> 丨 <router-link to="/login"> 去登录 </router-link> 丨 <router-link to="/demo"> 查看demo </router-link>
|
|
||||||
<router-view />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
#app {
|
|
||||||
background-color: $primaryColor;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { defRequest } from '../utils/request'
|
|
||||||
|
|
||||||
export const loginApi = (params: Record<string, unknown>) => {
|
|
||||||
// 设置 showLoading,timeout 会覆盖index.ts里的默认值
|
|
||||||
return defRequest.post<Record<string, unknown>>('/login', params, { showLoading: false, timeout: 1000 })
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
:root[theme-mode='light'] {
|
|
||||||
--bg-color: #fff;
|
|
||||||
--text-color: #000
|
|
||||||
}
|
|
||||||
|
|
||||||
:root[theme-mode='dark'] {
|
|
||||||
--bg-color: #2c2c2c;
|
|
||||||
--text-color: #fff
|
|
||||||
}
|
|
||||||
|
|
||||||
:root[theme-mode='red'] {
|
|
||||||
--bg-color: rgb(0, 128, 255);
|
|
||||||
--text-color: red;
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
:root {
|
|
||||||
color: var(--text-color);
|
|
||||||
background-color: var(--bg-color);
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
$primaryColor: #316c72;
|
|
||||||
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 496 B |
@ -1,41 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
defineProps<{ msg: string }>()
|
|
||||||
|
|
||||||
const count = ref(0)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<button type="button" @click="count++">count is {{ count }}</button>
|
|
||||||
<p>
|
|
||||||
Edit
|
|
||||||
<code>components/HelloWorld.vue</code> to test HMR
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Check out
|
|
||||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
|
||||||
>create-vue</a
|
|
||||||
>, the official Vue + Vite starter
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Learn more about IDE Support for Vue in the
|
|
||||||
<a
|
|
||||||
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
|
|
||||||
target="_blank"
|
|
||||||
>Vue Docs Scaling up Guide</a
|
|
||||||
>.
|
|
||||||
</p>
|
|
||||||
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.read-the-docs {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
export default {
|
|
||||||
welcome: 'Welcome',
|
|
||||||
login: 'Login',
|
|
||||||
register: 'Register',
|
|
||||||
// 可以根据实际需求添加更多翻译项
|
|
||||||
};
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
import {createI18n} from 'vue-i18n'
|
|
||||||
// 从语言包文件中导入语言包对象
|
|
||||||
import zh from '@language/zh-CN'
|
|
||||||
import en from '@language/en-US'
|
|
||||||
|
|
||||||
const messages = {
|
|
||||||
'zh-cn': zh,
|
|
||||||
'en-us': en
|
|
||||||
}
|
|
||||||
|
|
||||||
const language = (navigator.language || 'en').toLocaleLowerCase() // 这是获取浏览器的语言
|
|
||||||
// 获取浏览器当前使用的语言,并进行处理
|
|
||||||
const i18n = createI18n({
|
|
||||||
legacy: false,
|
|
||||||
locale: localStorage.getItem('lang') || language.split('-')[0] || 'en', // 首先从缓存里拿,没有的话就用浏览器语言,
|
|
||||||
fallbackLocale: 'zh-cn', // 设置备用语言
|
|
||||||
messages,
|
|
||||||
})
|
|
||||||
|
|
||||||
export default i18n
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
export default {
|
|
||||||
welcome: '欢迎',
|
|
||||||
login: '登录',
|
|
||||||
register: '注册',
|
|
||||||
// 可以根据实际需求添加更多翻译项
|
|
||||||
};
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import { createApp } from 'vue'
|
|
||||||
import pinia from '@/store'
|
|
||||||
import './style.css'
|
|
||||||
import '@css/index.scss'
|
|
||||||
import App from './App.vue'
|
|
||||||
import * as echarts from 'echarts'
|
|
||||||
import router from '@/router/index'
|
|
||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
|
||||||
import i18n from './language'
|
|
||||||
import ElementPlus from 'element-plus'
|
|
||||||
import 'element-plus/dist/index.css'
|
|
||||||
|
|
||||||
// 初始化pinia插件
|
|
||||||
pinia.use(piniaPluginPersistedstate)
|
|
||||||
|
|
||||||
// 创建并配置Vue应用
|
|
||||||
const app = createApp(App)
|
|
||||||
.use(router)
|
|
||||||
.use(pinia)
|
|
||||||
.use(i18n)
|
|
||||||
.use(ElementPlus)
|
|
||||||
|
|
||||||
// 全局挂载echarts
|
|
||||||
app.config.globalProperties.$echarts = echarts
|
|
||||||
|
|
||||||
// 挂载应用
|
|
||||||
app.mount('#app')
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
import { Router, createRouter, createWebHistory } from 'vue-router'
|
|
||||||
|
|
||||||
/** 自动导入 src/router/modules 下的静态路由
|
|
||||||
* import.meta.glob使用说明:https://cn.vitejs.dev/guide/features#glob-import
|
|
||||||
*/
|
|
||||||
const modules: Record<string, unknown> = import.meta.glob(['./modules/**/*.ts'], {
|
|
||||||
eager: true
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 初始路由 **/
|
|
||||||
const routes: unknown[] = []
|
|
||||||
|
|
||||||
Object.keys(modules).forEach((key) => {
|
|
||||||
const module = (modules[key] as { default: unknown }).default;
|
|
||||||
if (Array.isArray(module)) {
|
|
||||||
for (const item of module) {
|
|
||||||
routes.push(item)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
routes.push(module)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建路由实例
|
|
||||||
* createRouter选项有:https://router.vuejs.org/zh/api/interfaces/RouterOptions.html
|
|
||||||
* hash模式使用createWebHashHistory(): https://router.vuejs.org/zh/api/#Functions-createWebHashHistory
|
|
||||||
*/
|
|
||||||
export const router: Router = createRouter({
|
|
||||||
history: createWebHistory(),
|
|
||||||
routes,
|
|
||||||
strict: true,
|
|
||||||
scrollBehavior(_to, from, savedPosition) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
if (savedPosition) {
|
|
||||||
return savedPosition
|
|
||||||
} else {
|
|
||||||
if (from.meta.saveSrollTop) {
|
|
||||||
const top: number = document.documentElement.scrollTop || document.body.scrollTop
|
|
||||||
resolve({ left: 0, top })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 路由守卫
|
|
||||||
* https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
|
|
||||||
*/
|
|
||||||
router.beforeEach((to, _from, next) => {
|
|
||||||
// isAuthenticated 代表你的鉴权
|
|
||||||
const isAuthenticated = true
|
|
||||||
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
|
|
||||||
else next()
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
const routes = [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
component: () => import('@/views/default/home.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
component: () => import('@/views/default/login.vue') //路由懒加载
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
export default routes
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { createPinia } from 'pinia'
|
|
||||||
import persist from 'pinia-plugin-persistedstate';
|
|
||||||
|
|
||||||
const pinia = createPinia();
|
|
||||||
pinia.use(persist);
|
|
||||||
|
|
||||||
export default pinia
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
import { defineStore } from 'pinia'
|
|
||||||
import { UserState } from 'types/store'
|
|
||||||
import { getToken, setToken } from '@/utils/auth'
|
|
||||||
|
|
||||||
// 第一个参数是id,唯一
|
|
||||||
export const useUserStore = defineStore('user', {
|
|
||||||
state: () => {
|
|
||||||
return {
|
|
||||||
token: getToken() || 'YUNZER68205747',
|
|
||||||
userInfo: { name: 'yunzer', phone: '19895983967' }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getters: {
|
|
||||||
namePic: (state) => state.userInfo.name.substring(0, 1)
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
setToken(token: string) {
|
|
||||||
this.token = token
|
|
||||||
},
|
|
||||||
setUserInfo(userInfo: UserState['userInfo']) {
|
|
||||||
this.userInfo = { ...this.userInfo, ...userInfo }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setToken(token: string) {
|
|
||||||
this.token = token
|
|
||||||
setToken({
|
|
||||||
token,
|
|
||||||
expires: 30
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
import {defineStore} from 'pinia'
|
|
||||||
import {getToken,setToken} from "@/utils/storage.ts";
|
|
||||||
export const useSettingsStore = defineStore('settings', {
|
|
||||||
id: 'settings', // id必填,且需要唯一
|
|
||||||
state: () => {
|
|
||||||
return {
|
|
||||||
menuCollapse: false,//// 是否水平折叠收起菜单
|
|
||||||
// 布局方式 Classic 经典布局 Streamline 单行布局
|
|
||||||
layoutMode: getToken('layoutMode')?getToken('layoutMode'):'Classic'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
changeSetting({ key, value }) {
|
|
||||||
//改变全局变量的方法
|
|
||||||
this[key] = value
|
|
||||||
setToken(key, value)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
import { defineStore } from 'pinia';
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import type { User } from '@/types/user';
|
|
||||||
|
|
||||||
export const usersStore = defineStore('users', () => {
|
|
||||||
const userInfo = ref<User>({
|
|
||||||
name:'abc',
|
|
||||||
avatar: '123', // 头像
|
|
||||||
mobile: '13221091091', // 手机号
|
|
||||||
account: 'lita', // 用户名
|
|
||||||
id: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
const setUserInfo = (u:User) =>{
|
|
||||||
userInfo.value = u;
|
|
||||||
}
|
|
||||||
|
|
||||||
const clearUserInfo = () =>{
|
|
||||||
// void 是用来创建 undefined,不管它后面跟个啥,得到的都是 undefined;
|
|
||||||
userInfo.value = void 0;
|
|
||||||
// 上面的代码代表 userinfo.value = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { userInfo ,setUserInfo, clearUserInfo }
|
|
||||||
},{persist: true})
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
:root {
|
|
||||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
||||||
line-height: 1.5;
|
|
||||||
font-weight: 400;
|
|
||||||
|
|
||||||
color-scheme: light dark;
|
|
||||||
color: rgba(255, 255, 255, 0.87);
|
|
||||||
background-color: #242424;
|
|
||||||
|
|
||||||
font-synthesis: none;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: 500;
|
|
||||||
color: #646cff;
|
|
||||||
text-decoration: inherit;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color: #535bf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
place-items: center;
|
|
||||||
min-width: 320px;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 3.2em;
|
|
||||||
line-height: 1.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
padding: 0.6em 1.2em;
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: 500;
|
|
||||||
font-family: inherit;
|
|
||||||
background-color: #1a1a1a;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: border-color 0.25s;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
border-color: #646cff;
|
|
||||||
}
|
|
||||||
button:focus,
|
|
||||||
button:focus-visible {
|
|
||||||
outline: 4px auto -webkit-focus-ring-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
|
||||||
max-width: 1280px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
|
||||||
:root {
|
|
||||||
color: #213547;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color: #747bff;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import Cookies from 'js-cookie'
|
|
||||||
|
|
||||||
export const TokenKey = 'yunzer-token'
|
|
||||||
|
|
||||||
type ExpiresData = Date | number
|
|
||||||
export interface TokenInfo {
|
|
||||||
token: string
|
|
||||||
expires: ExpiresData
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getToken() {
|
|
||||||
return Cookies.get(TokenKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setToken(data: TokenInfo) {
|
|
||||||
const { token, expires } = data
|
|
||||||
return expires ? Cookies.set(TokenKey, token, { expires: expires }) : Cookies.set(TokenKey, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeToken() {
|
|
||||||
return Cookies.remove(TokenKey)
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* 创建实例,可以多个,当你需要请求多个不同域名的接口时
|
|
||||||
*/
|
|
||||||
import Request from './request'
|
|
||||||
import { getToken } from '@/utils/auth'
|
|
||||||
|
|
||||||
const defRequest = new Request({
|
|
||||||
// 这里用 Easy Mock 模拟了真实接口
|
|
||||||
baseURL: import.meta.env.VITE_API_BASE_URL,
|
|
||||||
timeout: 5000,
|
|
||||||
showLoading: true,
|
|
||||||
interceptorHooks: {
|
|
||||||
requestInterceptor: (config) => {
|
|
||||||
const token = getToken()
|
|
||||||
if (token) {
|
|
||||||
config.headers.Authorization = token
|
|
||||||
}
|
|
||||||
return config
|
|
||||||
},
|
|
||||||
requestInterceptorCatch: (err) => {
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
responseInterceptor: (res) => {
|
|
||||||
return res.data
|
|
||||||
},
|
|
||||||
responseInterceptorCatch: (err) => {
|
|
||||||
return Promise.reject(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 创建其他示例,然后导出
|
|
||||||
// const otherRequest = new Request({...})
|
|
||||||
|
|
||||||
export { defRequest }
|
|
||||||
@ -1,123 +0,0 @@
|
|||||||
/**
|
|
||||||
* 封装axios
|
|
||||||
* axios 实例的类型为 AxiosInstance,请求需要传入的参数类型为 AxiosRequestConfig,响应的数据类型为 AxiosResponse,InternalAxiosRequestConfig 继承于 AxiosRequestConfig
|
|
||||||
*/
|
|
||||||
import axios, { AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig, AxiosResponse } from 'axios'
|
|
||||||
import { ErrMessage } from './status'
|
|
||||||
|
|
||||||
// 自定义请求返回数据的类型
|
|
||||||
interface Data<T> {
|
|
||||||
data: T
|
|
||||||
code: string
|
|
||||||
success: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
// 扩展 InternalAxiosRequestConfig,让每个请求都可以控制是否要loading
|
|
||||||
interface RequestInternalAxiosRequestConfig extends InternalAxiosRequestConfig {
|
|
||||||
showLoading?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拦截器
|
|
||||||
interface InterceptorHooks {
|
|
||||||
requestInterceptor?: (config: RequestInternalAxiosRequestConfig) => RequestInternalAxiosRequestConfig
|
|
||||||
requestInterceptorCatch?: (error: unknown) => unknown
|
|
||||||
responseInterceptor?: (response: AxiosResponse) => AxiosResponse
|
|
||||||
responseInterceptorCatch?: (error: unknown) => unknown
|
|
||||||
}
|
|
||||||
// 扩展 AxiosRequestConfig,showLoading 给实例默认增加loading,interceptorHooks 拦截
|
|
||||||
interface RequestConfig extends AxiosRequestConfig {
|
|
||||||
showLoading?: boolean
|
|
||||||
interceptorHooks?: InterceptorHooks
|
|
||||||
}
|
|
||||||
|
|
||||||
class Request {
|
|
||||||
config: RequestConfig
|
|
||||||
instance: AxiosInstance
|
|
||||||
loading?: boolean // 用loading指代加载动画状态
|
|
||||||
|
|
||||||
constructor(options: RequestConfig) {
|
|
||||||
this.config = options
|
|
||||||
this.instance = axios.create(options)
|
|
||||||
this.setupInterceptor()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 类型参数的作用,T决定AxiosResponse实例中data的类型
|
|
||||||
request<T>(config: RequestConfig): Promise<T> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.instance
|
|
||||||
.request<Data<T>, Data<T>>(config)
|
|
||||||
.then((res) => {
|
|
||||||
resolve(res.data)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 封装常用方法
|
|
||||||
// 移除了默认的 any 类型,要求调用者显式指定类型
|
|
||||||
get<T>(url: string, params?: object, _object = {}): Promise<T> {
|
|
||||||
return this.request({ url, params, ..._object, method: 'GET' })
|
|
||||||
}
|
|
||||||
|
|
||||||
post<T>(url: string, params?: object, _object = {}): Promise<T> {
|
|
||||||
return this.request({ url, params, ..._object, method: 'POST' })
|
|
||||||
}
|
|
||||||
|
|
||||||
delete<T>(url: string, params?: object, _object = {}): Promise<T> {
|
|
||||||
return this.request({ url, params, ..._object, method: 'DELETE' })
|
|
||||||
}
|
|
||||||
|
|
||||||
patch<T>(url: string, params?: object, _object = {}): Promise<T> {
|
|
||||||
return this.request({ url, params, ..._object, method: 'PATCH' })
|
|
||||||
}
|
|
||||||
|
|
||||||
put<T>(url: string, params?: object, _object = {}): Promise<T> {
|
|
||||||
return this.request({ url, params, ..._object, method: 'PUT' })
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自定义拦截器 https://axios-http.com/zh/docs/interceptors
|
|
||||||
setupInterceptor(): void {
|
|
||||||
/**
|
|
||||||
* 通用拦截
|
|
||||||
*/
|
|
||||||
this.instance.interceptors.request.use((config: RequestInternalAxiosRequestConfig) => {
|
|
||||||
if (config.showLoading) {
|
|
||||||
// 加载loading动画
|
|
||||||
this.loading = true
|
|
||||||
}
|
|
||||||
return config
|
|
||||||
})
|
|
||||||
// 响应后关闭loading
|
|
||||||
this.instance.interceptors.response.use(
|
|
||||||
(res) => {
|
|
||||||
if (this.loading) this.loading = false
|
|
||||||
return res
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
const { response, message } = err
|
|
||||||
if (this.loading) this.loading = false
|
|
||||||
// 根据不同状态码,返回不同信息
|
|
||||||
const messageStr = response ? ErrMessage(response.status) : message || '请求失败,请重试'
|
|
||||||
window.alert(messageStr)
|
|
||||||
return Promise.reject(err)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
/**
|
|
||||||
* 使用通用实例里的拦截,两个拦截都会生效,返回值以后一个执行的为准
|
|
||||||
*/
|
|
||||||
// 请求拦截
|
|
||||||
this.instance.interceptors.request.use(
|
|
||||||
this.config?.interceptorHooks?.requestInterceptor,
|
|
||||||
this.config?.interceptorHooks?.requestInterceptorCatch
|
|
||||||
)
|
|
||||||
// 响应拦截
|
|
||||||
this.instance.interceptors.response.use(
|
|
||||||
this.config?.interceptorHooks?.responseInterceptor,
|
|
||||||
this.config?.interceptorHooks?.responseInterceptorCatch
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Request
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
export const ErrMessage = (status: number | string): string => {
|
|
||||||
let message: string = ''
|
|
||||||
switch (status) {
|
|
||||||
case 400:
|
|
||||||
message = '请求错误!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 401:
|
|
||||||
message = '未授权!请您重新登录'
|
|
||||||
break
|
|
||||||
case 403:
|
|
||||||
message = '当前账号无访问权限!'
|
|
||||||
break
|
|
||||||
case 404:
|
|
||||||
message = '访问的资源不存在!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 405:
|
|
||||||
message = '请求方式错误!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 408:
|
|
||||||
message = '请求超时!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 500:
|
|
||||||
message = '服务异常!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 501:
|
|
||||||
message = '不支持此请求!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 502:
|
|
||||||
message = '网关错误!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 503:
|
|
||||||
message = '服务不可用!请您稍后重试'
|
|
||||||
break
|
|
||||||
case 504:
|
|
||||||
message = '网关超时!请您稍后重试'
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
message = '请求失败!请您稍后重试'
|
|
||||||
}
|
|
||||||
return message
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { onMounted, ref ,provide} from 'vue'
|
|
||||||
import * as echarts from "echarts";
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
|
|
||||||
//通过provide提供echarts
|
|
||||||
provide("echarts", echarts);
|
|
||||||
|
|
||||||
const I18n = useI18n()
|
|
||||||
const { locale } = useI18n()
|
|
||||||
// 切换语言更改locale.value的值即可但要跟你index.js中message设置的值一致!
|
|
||||||
|
|
||||||
const translate = (lang) => {
|
|
||||||
locale.value = lang
|
|
||||||
localStorage.setItem('lang', lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<p>{{ $t('welcome') }}</p>
|
|
||||||
</div>
|
|
||||||
<button @click="translate('zh-cn')">切换为中文</button>
|
|
||||||
<button @click="translate('en-us')">切换为英文</button>
|
|
||||||
</div>
|
|
||||||
<router-link to="/"> 去首页 </router-link> 丨 <router-link to="/login"> 去登录 </router-link> 丨 <router-link to="/demo"> 查看demo </router-link>
|
|
||||||
<router-view />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="right-content">
|
|
||||||
<div ref="Chart" style="width: 800px; height: 500px"></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { onMounted, getCurrentInstance, ref } from 'vue'
|
|
||||||
let internalInstance = getCurrentInstance(); //获取当前实例
|
|
||||||
let echarts = internalInstance.appContext.config.globalProperties.$echarts; //获取echarts实例
|
|
||||||
|
|
||||||
|
|
||||||
//通过ref获取html元素
|
|
||||||
const Chart = ref();
|
|
||||||
|
|
||||||
const init = () => {
|
|
||||||
// 渲染echarts的父元素
|
|
||||||
var infoEl = Chart.value;
|
|
||||||
|
|
||||||
// light dark
|
|
||||||
var myChart = echarts.init(infoEl, "light"); //初始化echarts实例
|
|
||||||
|
|
||||||
// 指定图表的配置项和数据 树图
|
|
||||||
var option = {
|
|
||||||
title: {
|
|
||||||
text: 'ECharts 入门示例'
|
|
||||||
},
|
|
||||||
tooltip: {},
|
|
||||||
xAxis: {
|
|
||||||
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
|
|
||||||
},
|
|
||||||
yAxis: {},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '销量',
|
|
||||||
type: 'bar',
|
|
||||||
data: [5, 20, 36, 10, 10, 20]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用刚指定的配置项和数据显示图表。
|
|
||||||
myChart.setOption(option);
|
|
||||||
window.onresize = function () {
|
|
||||||
myChart.resize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
init()
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scope lang="scss"></style>
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed } from 'vue'
|
|
||||||
import { storeToRefs } from 'pinia'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
|
|
||||||
defineOptions({
|
|
||||||
name: 'V-home'
|
|
||||||
})
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
// 获取state使用computed或者使用storeToRefs,直接使用不具备响应式(拿到的永远是初次的值)
|
|
||||||
const username = computed(() => userStore.userInfo.name)
|
|
||||||
// 获取getter使用storeToRefs,或者直接使用,在模板里 userStore.namePic
|
|
||||||
const { token } = storeToRefs(userStore)
|
|
||||||
const namePic = computed(() => userStore.userInfo.name + '的头像') // 根据store结构,使用userInfo.name生成头像信息
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>Hello: {{ namePic }}, your name is {{ username }}, your token is {{ token }}</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { storeToRefs } from 'pinia'
|
|
||||||
import { useUserStore } from '@store/modules/user'
|
|
||||||
import { loginApi } from '@/api/login'
|
|
||||||
|
|
||||||
defineOptions({
|
|
||||||
name: 'V-login'
|
|
||||||
})
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const { userInfo, token } = storeToRefs(userStore)
|
|
||||||
let userName = ref(userInfo.value.name)
|
|
||||||
let userToken = ref(token)
|
|
||||||
|
|
||||||
const updateUserName = () => {
|
|
||||||
userStore.setUserInfo({
|
|
||||||
name: userName.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const updateUserToken = () => {
|
|
||||||
userStore.setToken(userToken.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const login = () => {
|
|
||||||
loginApi({
|
|
||||||
name: userName.value
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
userName.value = res.name
|
|
||||||
userToken.value = res.token
|
|
||||||
updateUserToken()
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>login page</div>
|
|
||||||
name:
|
|
||||||
<input type="text" v-model="userName" @input="updateUserName" />
|
|
||||||
<br />
|
|
||||||
token:
|
|
||||||
<input type="text" v-model="userToken" />
|
|
||||||
<hr />
|
|
||||||
<button @click="login">login</button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
1
pc-b/src/vite-env.d.ts
vendored
1
pc-b/src/vite-env.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
||||||
|
|
||||||
/* Linting */
|
|
||||||
"strict": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"noUncheckedSideEffectImports": true
|
|
||||||
},
|
|
||||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ESNext", // 将代码编译为最新版本的 JS
|
|
||||||
"useDefineForClassFields": true,
|
|
||||||
"module": "ESNext", // 使用 ES Module 格式打包编译后的文件
|
|
||||||
"lib": ["ESNext", "DOM", "DOM.Iterable"], // 引入 ES 最新特性和 DOM 接口的类型定义
|
|
||||||
"skipLibCheck": true, // 跳过对 .d.ts 文件的类型检查
|
|
||||||
"esModuleInterop": true, // 允许使用 import 引入使用 export = 导出的内容
|
|
||||||
"sourceMap": true, // 用来指定编译时是否生成.map文件
|
|
||||||
"allowJs": false, // 是否允许使用js
|
|
||||||
"baseUrl": ".", // 查询的基础路径
|
|
||||||
"paths": {
|
|
||||||
// 路径映射,配合别名使用
|
|
||||||
"@": ["src"],
|
|
||||||
"@/*": ["src/*"],
|
|
||||||
"@build/*": ["build/*"],
|
|
||||||
"@language/*": ["src/language/*"],
|
|
||||||
"@store/*": ["src/store/modules/*"],
|
|
||||||
"#/*": ["types/*"]
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Bundler mode */
|
|
||||||
"moduleResolution": "node", // 使用 Node/bundler 的模块解析策略
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"resolveJsonModule": true, // 允许引入 JSON 文件
|
|
||||||
"isolatedModules": true, // 要求所有文件都是 ES Module 模块。
|
|
||||||
"noEmit": true, // 不输出文件,即编译后不会生成任何js文件
|
|
||||||
"jsx": "preserve", // 保留原始的 JSX 代码,不进行编译
|
|
||||||
|
|
||||||
/* Linting */
|
|
||||||
"strict": true, // 开启所有严格的类型检查
|
|
||||||
"noUnusedLocals": true, // 报告未使用的局部变量的错误
|
|
||||||
"noUnusedParameters": true, // 报告函数中未使用参数的错误
|
|
||||||
"noFallthroughCasesInSwitch": true // 确保switch语句中的任何非空情况都包含
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
// 需要检测的文件
|
|
||||||
"src/**/*.ts",
|
|
||||||
"build/*.ts",
|
|
||||||
"src/**/*.d.ts",
|
|
||||||
"src/**/*.tsx",
|
|
||||||
"src/**/*.vue",
|
|
||||||
"mock/*.ts",
|
|
||||||
"types/*.d.ts",
|
|
||||||
"vite.config.ts"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
// 不需要检测的文件
|
|
||||||
"dist",
|
|
||||||
"**/*.js",
|
|
||||||
"node_modules"
|
|
||||||
],
|
|
||||||
"references": [{ "path": "./tsconfig.node.json" }] // 为文件进行不同配置
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": true, // 对于引用项目必须设置该属性
|
|
||||||
"skipLibCheck": true, // 跳过对 .d.ts 文件的类型检查
|
|
||||||
"module": "ESNext", // 使用 ES Module 格式打包编译后的文件
|
|
||||||
"moduleResolution": "Node", // 使用 Node/bundler 的模块解析策略
|
|
||||||
"allowSyntheticDefaultImports": true // 允许使用 import 导入使用 export = 导出的默认内容
|
|
||||||
},
|
|
||||||
"include": ["build/*.ts", "types/*.d.ts", "vite.config.ts"]
|
|
||||||
}
|
|
||||||
26
pc-b/typed-router.d.ts
vendored
26
pc-b/typed-router.d.ts
vendored
@ -1,26 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
/* prettier-ignore */
|
|
||||||
// @ts-nocheck
|
|
||||||
// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
|
|
||||||
// It's recommended to commit this file.
|
|
||||||
// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
|
|
||||||
|
|
||||||
declare module 'vue-router/auto-routes' {
|
|
||||||
import type {
|
|
||||||
RouteRecordInfo,
|
|
||||||
ParamValue,
|
|
||||||
ParamValueOneOrMore,
|
|
||||||
ParamValueZeroOrMore,
|
|
||||||
ParamValueZeroOrOne,
|
|
||||||
} from 'vue-router'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Route name map generated by unplugin-vue-router
|
|
||||||
*/
|
|
||||||
export interface RouteNamedMap {
|
|
||||||
'/default/demo': RouteRecordInfo<'/default/demo', '/default/demo', Record<never, never>, Record<never, never>>,
|
|
||||||
'/default/demo-i18n': RouteRecordInfo<'/default/demo-i18n', '/default/demo-i18n', Record<never, never>, Record<never, never>>,
|
|
||||||
'/default/home': RouteRecordInfo<'/default/home', '/default/home', Record<never, never>, Record<never, never>>,
|
|
||||||
'/default/login': RouteRecordInfo<'/default/login', '/default/login', Record<never, never>, Record<never, never>>,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
22
pc-b/types/index.d.ts
vendored
22
pc-b/types/index.d.ts
vendored
@ -1,22 +0,0 @@
|
|||||||
type TargetContext = "_self" | "_blank";
|
|
||||||
type EmitType = (event: string, ...args: any[]) => void;
|
|
||||||
type AnyFunction<T> = (...args: any[]) => T;
|
|
||||||
type PropType<T> = VuePropType<T>;
|
|
||||||
type Writable<T> = {
|
|
||||||
-readonly [P in keyof T]: T[P];
|
|
||||||
};
|
|
||||||
type Nullable<T> = T | null;
|
|
||||||
type NonNullable<T> = T extends null | undefined ? never : T;
|
|
||||||
type Recordable<T = any> = Record<string, T>;
|
|
||||||
|
|
||||||
interface Fn<T = any, R = T> {
|
|
||||||
(...arg: T[]): R;
|
|
||||||
}
|
|
||||||
interface PromiseFn<T = any, R = T> {
|
|
||||||
(...arg: T[]): Promise<R>;
|
|
||||||
}
|
|
||||||
interface ViteEnv {
|
|
||||||
VITE_USER_NODE_ENV: "development" | "production";
|
|
||||||
VITE_PUBLIC_PATH: string;
|
|
||||||
VITE_PORT: number;
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
export interface UserState {
|
|
||||||
token: string
|
|
||||||
userInfo: { name?: string; phone?: string }
|
|
||||||
}
|
|
||||||
7
pc-b/types/user.d.ts
vendored
7
pc-b/types/user.d.ts
vendored
@ -1,7 +0,0 @@
|
|||||||
interface User {
|
|
||||||
token: string;
|
|
||||||
avatar: string; // 头像
|
|
||||||
mobile:string; // 手机号
|
|
||||||
account:string; // 用户名
|
|
||||||
id:number; // 用户id
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
import { defineConfig, loadEnv, ConfigEnv, UserConfig } from "vite";
|
|
||||||
import vue from "@vitejs/plugin-vue";
|
|
||||||
import { resolve } from "path";
|
|
||||||
import { wrapperEnv } from "./build";
|
|
||||||
import VueRouter from 'unplugin-vue-router/vite';
|
|
||||||
|
|
||||||
// 路径查找
|
|
||||||
const pathResolve = (dir: string): string => {
|
|
||||||
return resolve(__dirname, ".", dir);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置别名,还可以添加其他路径
|
|
||||||
const alias: Record<string, string> = {
|
|
||||||
"@": pathResolve("src"),
|
|
||||||
"@views": pathResolve("src/views"),
|
|
||||||
"@store": pathResolve("src/store"),
|
|
||||||
"@language": pathResolve("src/language"),
|
|
||||||
"@css": pathResolve("src/assets/css"),
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
|
||||||
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
|
||||||
const root = process.cwd();
|
|
||||||
const env = loadEnv(mode, root);
|
|
||||||
const viteEnv = wrapperEnv(env);
|
|
||||||
|
|
||||||
return {
|
|
||||||
base: viteEnv.VITE_PUBLIC_PATH,
|
|
||||||
plugins: [
|
|
||||||
VueRouter({
|
|
||||||
routesFolder: 'src/views', // 指定路由文件所在的目录
|
|
||||||
exclude: ['**/components/*.vue'],
|
|
||||||
extensions: ['.vue'], // 指定路由文件的后缀名
|
|
||||||
}),
|
|
||||||
vue(),
|
|
||||||
],
|
|
||||||
resolve: {
|
|
||||||
alias, // 设置别名
|
|
||||||
},
|
|
||||||
css: {
|
|
||||||
preprocessorOptions: {
|
|
||||||
scss: {
|
|
||||||
additionalData: `@import "@css/variables.scss";`, // 引入全局变量
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
server: {
|
|
||||||
host: "0.0.0.0", // 设置服务器主机名
|
|
||||||
port: viteEnv.VITE_PORT, // 设置服务启动端口号
|
|
||||||
https: undefined, // 是否开启 https
|
|
||||||
open: true, // 是否自动打开浏览器
|
|
||||||
cors: true, // 允许跨域
|
|
||||||
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
|
|
||||||
proxy: {
|
|
||||||
"^/api": {
|
|
||||||
target: "http://127.0.0.1:8686", // 代理的目标地址
|
|
||||||
changeOrigin: true, // 开发模式,默认的 origin 是真实的 origin:localhost:3000
|
|
||||||
rewrite: (path) => path.replace(/^\/api/, ""), // 把 /api 替换成 target 中的地址
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
5
pc/.env
5
pc/.env
@ -1,5 +0,0 @@
|
|||||||
# 本地运行端口号
|
|
||||||
VITE_PORT = 8686
|
|
||||||
|
|
||||||
# API接口域名配置
|
|
||||||
VITE_BASE_URL = http://localhost/
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# 开发环境
|
|
||||||
NODE_ENV = development
|
|
||||||
# 后台请求前缀,这是mock地址
|
|
||||||
VITE_BASE_URL = '/apis'
|
|
||||||
|
|
||||||
VITE_PERMISSION_MODE = 'CONSTANT'
|
|
||||||
# VITE_PERMISSION_MODE = 'FRONT'
|
|
||||||
# VITE_PERMISSION_MODE = 'BACK'
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# 生产环境
|
|
||||||
NODE_ENV = prod
|
|
||||||
# 后台请求前缀,这是mock地址
|
|
||||||
VITE_BASE_URL = 'https://mock.apifox.cn/m1/3365861-0-default'
|
|
||||||
|
|
||||||
VITE_PERMISSION_MODE = 'CONSTANT'
|
|
||||||
# VITE_PERMISSION_MODE = 'FRONT'
|
|
||||||
# VITE_PERMISSION_MODE = 'BACK'
|
|
||||||
25
pc/.gitignore
vendored
25
pc/.gitignore
vendored
@ -1,25 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
src/views/test
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
127
pc/LICENSE
127
pc/LICENSE
@ -1,127 +0,0 @@
|
|||||||
木兰宽松许可证, 第2版
|
|
||||||
|
|
||||||
木兰宽松许可证, 第2版
|
|
||||||
2020年1月 http://license.coscl.org.cn/MulanPSL2
|
|
||||||
|
|
||||||
|
|
||||||
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
|
|
||||||
|
|
||||||
0. 定义
|
|
||||||
|
|
||||||
“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
|
|
||||||
|
|
||||||
“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
|
|
||||||
|
|
||||||
“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
|
|
||||||
|
|
||||||
“法人实体”是指提交贡献的机构及其“关联实体”。
|
|
||||||
|
|
||||||
“关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
|
|
||||||
|
|
||||||
1. 授予版权许可
|
|
||||||
|
|
||||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
|
|
||||||
|
|
||||||
2. 授予专利许可
|
|
||||||
|
|
||||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
|
|
||||||
|
|
||||||
3. 无商标许可
|
|
||||||
|
|
||||||
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
|
|
||||||
|
|
||||||
4. 分发限制
|
|
||||||
|
|
||||||
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
|
|
||||||
|
|
||||||
5. 免责声明与责任限制
|
|
||||||
|
|
||||||
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
|
|
||||||
|
|
||||||
6. 语言
|
|
||||||
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
|
|
||||||
|
|
||||||
条款结束
|
|
||||||
|
|
||||||
如何将木兰宽松许可证,第2版,应用到您的软件
|
|
||||||
|
|
||||||
如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
|
|
||||||
|
|
||||||
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
|
|
||||||
|
|
||||||
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
|
|
||||||
|
|
||||||
3, 请将如下声明文本放入每个源文件的头部注释中。
|
|
||||||
|
|
||||||
Copyright (c) [Year] [name of copyright holder]
|
|
||||||
[Software Name] is licensed under Mulan PSL v2.
|
|
||||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
http://license.coscl.org.cn/MulanPSL2
|
|
||||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
See the Mulan PSL v2 for more details.
|
|
||||||
|
|
||||||
|
|
||||||
Mulan Permissive Software License,Version 2
|
|
||||||
|
|
||||||
Mulan Permissive Software License,Version 2 (Mulan PSL v2)
|
|
||||||
January 2020 http://license.coscl.org.cn/MulanPSL2
|
|
||||||
|
|
||||||
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
|
|
||||||
|
|
||||||
0. Definition
|
|
||||||
|
|
||||||
Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
|
|
||||||
|
|
||||||
Contribution means the copyrightable work licensed by a particular Contributor under this License.
|
|
||||||
|
|
||||||
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
|
|
||||||
|
|
||||||
Legal Entity means the entity making a Contribution and all its Affiliates.
|
|
||||||
|
|
||||||
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
|
|
||||||
|
|
||||||
1. Grant of Copyright License
|
|
||||||
|
|
||||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
|
|
||||||
|
|
||||||
2. Grant of Patent License
|
|
||||||
|
|
||||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
|
|
||||||
|
|
||||||
3. No Trademark License
|
|
||||||
|
|
||||||
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4.
|
|
||||||
|
|
||||||
4. Distribution Restriction
|
|
||||||
|
|
||||||
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
|
|
||||||
|
|
||||||
5. Disclaimer of Warranty and Limitation of Liability
|
|
||||||
|
|
||||||
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
6. Language
|
|
||||||
|
|
||||||
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
|
|
||||||
|
|
||||||
END OF THE TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software
|
|
||||||
|
|
||||||
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
|
|
||||||
|
|
||||||
i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
|
|
||||||
|
|
||||||
ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
|
|
||||||
|
|
||||||
iii Attach the statement to the appropriate annotated syntax at the beginning of each source file.
|
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) [Year] [name of copyright holder]
|
|
||||||
[Software Name] is licensed under Mulan PSL v2.
|
|
||||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
http://license.coscl.org.cn/MulanPSL2
|
|
||||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
See the Mulan PSL v2 for more details.
|
|
||||||
53
pc/README.md
53
pc/README.md
@ -1,53 +0,0 @@
|
|||||||
### 介绍
|
|
||||||
|
|
||||||
**Yunzer-Admin** 基于 Vue3.3、TypeScript、Vite3、Pinia、Element-Plus 专注于表格,表单的企业级后台管理框架,取名 **Yunzer**源于NBA球队圣安东尼奥马刺队(San Antonio Yunzer),作为一支专业篮球队,马刺的卓越不止在于技术水平和战术运筹的精妙,更在于他们小石匠精神一直激励着大家。
|
|
||||||
马刺队更衣室里的一句话:
|
|
||||||
|
|
||||||
“当一切看起来无可挽回之时,我跑去看石匠重复捶击他面前的岩石一百次,而那块石头连
|
|
||||||
一个裂缝都没有露出来。接下来的第一百零一次捶击之时,此石一分为二。不是因为这
|
|
||||||
一次捶击,而是因为你的始终如一。”
|
|
||||||
|
|
||||||
共勉......
|
|
||||||
|
|
||||||
[代码gitee地址](https://gitee.com/3439/Yunzer-Admin)
|
|
||||||
|
|
||||||
[在线预览](http://jdvip.suipin.net)
|
|
||||||
|
|
||||||
### 技术栈+版本
|
|
||||||
|
|
||||||
本项目技术栈基于`npm^6.14.7+node^14.8.1+Vue3.3.4 + TypeScript + Vite4.4.5 + vue-router4.2.4 + pinia + axios`
|
|
||||||
|
|
||||||
### 运行
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
克隆项目
|
|
||||||
git clone https://gitee.com/3439/Yunzer-Admin.git
|
|
||||||
|
|
||||||
进入项目目录
|
|
||||||
cd Yunzer-Admin
|
|
||||||
|
|
||||||
安装依赖
|
|
||||||
npm install
|
|
||||||
|
|
||||||
本地开发 启动项目
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 系列文章
|
|
||||||
|
|
||||||
[从零开始vue3+vite+ts+pinia+router4后台管理(1)](https://juejin.cn/post/7286112965609357347)
|
|
||||||
|
|
||||||
[从零开始vue3+vite+ts+pinia+router4后台管理(2)-页面布局](https://juejin.cn/post/7286508785104322594)
|
|
||||||
|
|
||||||
[从零开始vue3+vite+ts+pinia+router4后台管理(3)-动态路由](https://juejin.cn/post/7286679458131312674)
|
|
||||||
|
|
||||||
[从零开始vue3+vite+ts+pinia+router4后台管理(4)-导航标签栏和keep-alive缓存](https://juejin.cn/post/7287053284787028003)
|
|
||||||
|
|
||||||
[从零开始vue3+vite+ts+pinia+router4后台管理(5)-二次封装表格1.0](https://juejin.cn/post/7288963909581635618)
|
|
||||||
|
|
||||||
[从零开始vue3+vite+ts+pinia+router4后台管理(6)-全局自定义指令实现节流与防抖](https://juejin.cn/post/7290470513116856320)
|
|
||||||
|
|
||||||
[什么才是完美的表格二次封装elementPlus表格?-从零开始vue3+vite+ts+pinia+router4后台管理(7)](https://juejin.cn/post/7301903019222155264)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
6
pc/env.d.ts
vendored
6
pc/env.d.ts
vendored
@ -1,6 +0,0 @@
|
|||||||
//解决import vue文件红色波浪线问题
|
|
||||||
declare module '*.vue' {
|
|
||||||
import { DefineComponent } from 'vue';
|
|
||||||
const component: DefineComponent<{}, {}, any>;
|
|
||||||
export default component;
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="shortcut icon" href="./src/assets/favicon.ico" type="image/x-icon">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Yunzer-Admin</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
2391
pc/package-lock.json
generated
2391
pc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Yunzer-Admin",
|
|
||||||
"private": true,
|
|
||||||
"version": "0.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "vue-tsc && vite build",
|
|
||||||
"preview": "vite preview"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@element-plus/icons-vue": "^2.1.0",
|
|
||||||
"@imengyu/vue3-context-menu": "^1.3.3",
|
|
||||||
"axios": "^1.5.0",
|
|
||||||
"element-plus": "^2.4.2",
|
|
||||||
"element-plus-table-dragable": "^1.0.0",
|
|
||||||
"js-cookie": "^3.0.5",
|
|
||||||
"nprogress": "^0.2.0",
|
|
||||||
"pinia": "^2.1.7",
|
|
||||||
"vue": "^3.3.4",
|
|
||||||
"vue-router": "^4.2.4"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^20.9.0",
|
|
||||||
"@types/nprogress": "^0.2.3",
|
|
||||||
"@vitejs/plugin-vue": "^4.2.3",
|
|
||||||
"@vitejs/plugin-vue-jsx": "^3.0.2",
|
|
||||||
"sass": "^1.69.5",
|
|
||||||
"typescript": "^5.0.2",
|
|
||||||
"vite": "^4.4.5",
|
|
||||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
|
||||||
"vue-tsc": "^1.8.5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user