feat:init

This commit is contained in:
fanxb 2021-06-21 16:32:10 +08:00
parent 24e05d1596
commit 8e518a614d
50 changed files with 1546 additions and 126 deletions

View File

@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@ -1,26 +0,0 @@
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

View File

@ -1,58 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@ -1,4 +0,0 @@
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')

15
openRenamerBackend/.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
.DS_Store
/.vscode/
.vscode
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
yarn.lock
log
sqls/history.json
static/*
!static/.gitkeep

View File

@ -0,0 +1,18 @@
import { Context } from "koa";
import FileService from "../service/FileService";
const router = {};
router["GET /file/query"] = async function (ctx: Context) {
ctx.body = FileService.readPath(ctx.query.path as string);
};
router["PUT /plan"] = async function (ctx: Context) {
ctx.body = "asdfasdf";
};
router["DELETE /plan/:planId"] = async function (ctx: Context) {
ctx.body = "";
}
export default router;

View File

@ -0,0 +1,17 @@
import { Context } from "koa";
const router = {};
router["GET /plan"] = async function (ctx: Context) {
ctx.body = "asdfasd";
};
router["PUT /plan"] = async function (ctx: Context) {
ctx.body = "asdfasdf";
};
router["DELETE /plan/:planId"] = async function (ctx: Context) {
ctx.body = "";
}
export default router;

View File

@ -0,0 +1,13 @@
{ "name": "nas_backup", "script": "./dist/index.js",
"cwd": "./",
"env": {
"PORT": 8082,
"MYSQL_HOST":"localhost",
"MYSQL_PORT":3306,
"MYSQL_USER":"root",
"MYSQL_PASS":"123456"
},
"log_file": "./log/combined.log",
"out_file": "./log/out.log",
"error_file": "./error.log"
}

View File

@ -0,0 +1,35 @@
import * as path from 'path';
//后台所在绝对路径
const rootPath = path.resolve(__dirname, '..');
let config = {
rootPath,
port: process.env.PORT ? parseInt(process.env.PORT) : 8089,
urlPrefix: '/backup/api',
//是否为windows平台
isWindows: process.platform.toLocaleLowerCase().includes("win"),
//需要监控的磁盘列表
disKCheckList: ["/dev/nvme0n1", "/dev/nvme1n1"],
mysqlConfig: {
host: process.env.MYSQL_HOST || "localhost",
database: "nas_backup",
port: process.env.MYSQL_PORT ? parseInt(process.env.MYSQL_PORT) : 3306,
user: process.env.MYSQL_USER || "root",
password: process.env.MYSQL_PASS || "123456",
supportBigNumbers: true,
multipleStatements: false
},
bodyLimit: {
formLimit: '2mb',
urlencoded: true,
multipart: true,
formidable: {
uploadDir: path.join(rootPath, 'files', 'temp', 'uploads'),
keepExtenstions: true,
maxFieldsSize: 1024 * 1024
}
}
};
export default config;

View File

@ -0,0 +1,32 @@
import { MysqlUtil } from '../util/MysqlHelper';
import History from '../entity/History';
import { OkPacket } from 'mysql2';
import Plan from 'entity/Plan';
export default class HistoryDao {
/**
*
* @param history history
*/
static async addOne(history: History): Promise<number> {
let sql = `insert into history(createdDate,updatedDate,planId,fileNum,fileSize,speed,startTime,endTime,comment) values(?,?,?,?,?,?,?,?,?)`;
let res = await MysqlUtil.pool.execute(sql, [Date.now(), Date.now(), history.planId, history.fileNum, history.fileSize, history.speed, history.startTime, history.endTime, history.comment]);
return (res[0] as unknown as OkPacket).insertId;
}
/**
* plan下所有的历史记录
* @param planId planId
*/
static async deleteByPlanId(planId: number) {
await MysqlUtil.pool.execute("delete from history where planId=?", [planId]);
}
/**
*
* @param planId planId
*/
static async getByPlanId(planId: number): Promise<Array<Plan>> {
return (await MysqlUtil.pool.query("select * from history where planId=?", planId))[0] as unknown as Array<Plan>;
}
}

View File

@ -0,0 +1,40 @@
import { MysqlUtil } from '../util/MysqlHelper';
import Plan from '../entity/Plan';
import { OkPacket } from 'mysql2';
export default class PlanDao {
/**
*
* @param plan plan
*/
static async addOne(plan: Plan): Promise<number> {
let res = await MysqlUtil.pool.execute("insert into plan(createdDate,updatedDate,planName,description,sourcePath,targetPath,nextLaunchTime,launchInterval,latestHistoryId,ignoreList,holdHistory) values(?,?,?,?,?,?,?,?,?,?,?)"
, [Date.now(), Date.now(), plan.planName, plan.description, plan.sourcePath, plan.targetPath, plan.nextLaunchTime, plan.lanuchInterval, plan.latestHistoryId, JSON.stringify(plan.ignoreList), plan.holdHistory]);
return (res[0] as unknown as OkPacket).insertId;
}
/**
* plan
*/
static async getNeedActionPlan(): Promise<Array<Plan>> {
let sql = `select * from plan where nextLaunchTime < ${Date.now()} order by nextLaunchTime`;
return (await MysqlUtil.pool.query(sql))[0] as unknown as Array<Plan>;
}
/**
*
* @param id planId
*/
static async updateNextlaunchTimeAndLatestHistoryId(planId: number, historyId: number) {
await MysqlUtil.pool.execute(`update plan set nextLaunchTime = nextLaunchTime+launchInterval,latestHistoryId=? where planId=?`
, [historyId, planId]);
}
static async deleteByPlanId(planId: number) {
await MysqlUtil.pool.execute(`delete from plan where planid=?`, [planId]);
}
static async getAll(): Promise<Array<Plan>> {
return (await MysqlUtil.pool.query("select * from plan"))[0] as unknown as Array<Plan>;
}
}

View File

View File

@ -0,0 +1,14 @@
export default class DiskInfo{
/**
*
*/
name:string;
/**
*
*/
isOk:boolean;
/**
*
*/
detail:string;
}

View File

@ -0,0 +1,10 @@
export default class History {
historyId: number = 0;
planId: number = 0;
fileNum: number = 0;
fileSize: number = 0;
speed: number = 0;
startTime: number = 0;
endTime: number = 0;
comment: string = "";
}

View File

@ -0,0 +1,22 @@
export default class Plan {
/**
*/
createdDate: number;
/**
*/
updateDate: number;
planId: number = 0;
planName: string = "";
description: string = "";
//保留的历史份数,最小1
holdHistory: number = 1;
sourcePath: string = "";
targetPath: string = "";
nextLaunchTime: number = 0;
lanuchInterval: number = 0;
latestHistoryId: number = 0;
ignoreList: Array<String> = [];
latestHistoryDetail: Object | null = null;
}

View File

@ -0,0 +1,36 @@
import koa from "koa";
import Router from "koa-router";
import koaBody from "koa-body";
import * as path from "path";
import RouterMW from "./middleware/controllerEngine";
import config from "./config";
import handleError from "./middleware/handleError";
import init from "./middleware/init";
import SqliteUtil from './util/SqliteHelper';
import log from './util/LogUtil';
console.log(config);
const app = new koa();
let router = new Router({
prefix: config.urlPrefix
});
app.use(require('koa-static')(path.join(config.rootPath, 'static')));
//表单解析
app.use(koaBody(config.bodyLimit));
//请求预处理
app.use(init);
//错误处理
app.use(handleError);
app.use(RouterMW(router, path.join(config.rootPath, "dist/api")));
(async () => {
await SqliteUtil.createPool(config.mysqlConfig);
app.listen(config.port);
log.info(`server listened `, config.port);
})();

View File

@ -0,0 +1,50 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import log from '../util/LogUtil';
async function addMapping(router, filePath: string) {
let mapping = require(filePath).default;
for (let url in mapping) {
if (url.startsWith('GET ')) {
let temp = url.substring(4);
router.get(temp, mapping[url]);
log.info(`----GET${temp}`);
} else if (url.startsWith('POST ')) {
let temp = url.substring(5);
router.post(temp, mapping[url]);
log.info(`----POST${temp}`);
} else if (url.startsWith('PUT ')) {
let temp = url.substring(4);
router.put(temp, mapping[url]);
log.info(`----PUT${temp}`);
} else if (url.startsWith('DELETE ')) {
let temp = url.substring(7);
router.delete(temp, mapping[url]);
log.info(`----DELETE: ${temp}`);
} else {
log.info(`xxxxx无效路径${url}`);
}
}
}
function addControllers(router, filePath) {
let files = fs.readdirSync(filePath).filter(item => item.endsWith('.js'));
for (let index in files) {
let element = files[index];
let temp = path.join(filePath, element);
let state = fs.statSync(temp);
if (state.isDirectory()) {
addControllers(router, temp);
} else {
if (!temp.endsWith('Helper.js')) {
log.info('\n--开始处理: ' + element + '路由');
addMapping(router, temp);
}
}
}
}
export default function engine(router, folder) {
addControllers(router, folder);
return router.routes();
}

View File

@ -0,0 +1,15 @@
let f = async (ctx, next) => {
try {
await next();
} catch (error) {
if (error.status != undefined) {
ctx.status = error.status;
} else {
ctx.status = 500;
}
ctx.body = error.message;
console.error(error);
}
}
export default f;

View File

@ -0,0 +1,51 @@
import config from '../config';
import ObjectHelper from '../util/ObjectOperate';
let doSuccess = (ctx, body) => {
switch (ctx.method) {
case 'GET':
ctx.status = body !== null ? 200 : 204;
ctx.body = body;
break;
case 'POST':
ctx.status = body !== null ? 201 : 204;
ctx.body = body;
break;
case 'PUT':
ctx.status = body !== null ? 200 : 204;
ctx.body = body;
break;
case 'DELETE':
ctx.status = body !== null ? 200 : 204;
ctx.body = body;
break;
}
Object.assign(ctx.allParams, ctx.params);
}
export default async (ctx, next) => {
//跨域
ctx.set("Access-Control-Allow-Origin", "*");
ctx.set("Access-Control-Allow-Headers", "X-Requested-With");
ctx.set("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
ctx.set("X-Powered-By", ' 3.2.1');
ctx.set("Content-Type", "application/json;charset=utf-8");
//合并请求参数到allParams
let objs = new Array();
if (ctx.method == "POST" || ctx.method == "PUT") {
if (ctx.request.body) {
if (ctx.request.body.fields != undefined && ctx.request.body.files != undefined) {
objs.push(ctx.request.body.fields, ctx.request.body.files);
} else {
objs.push(ctx.request.body);
}
}
}
objs.push(ctx.query);
ctx.allParams = ObjectHelper.combineObject(objs);
ctx.onSuccess = function (body = null) {
doSuccess(ctx, body);
};
await next();
}

View File

@ -0,0 +1,29 @@
{
"name": "nas_backup",
"version": "1.0.0",
"description": "文件备份用",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxb",
"license": "ISC",
"dependencies": {
"@types/fs-extra": "^5.0.4",
"@types/koa": "^2.0.47",
"@types/node": "^11.13.4",
"axios": "^0.21.1",
"fs-extra": "^7.0.0",
"koa": "^2.5.3",
"koa-body": "^4.0.4",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"koa2-cors": "^2.0.6",
"log4js": "^6.3.0",
"moment": "^2.22.2",
"mysql2": "^2.2.5",
"sqlite": "^4.0.23",
"uuid": "^3.3.2",
"winston": "^3.1.0"
}
}

View File

@ -0,0 +1,45 @@
import config from '../config';
import * as path from 'path';
import * as fs from 'fs-extra';
import ProcessHelper from '../util/ProcesHelper';
import FileObj from '../vo/FileObj';
class FileService {
static async readPath(pathStr: string): Promise<Array<FileObj>> {
let fileList = new Array();
if (pathStr.trim().length == 0) {
//获取根目录路径
if (config.isWindows) {
//windows下
let std: string = (await ProcessHelper.exec("wmic logicaldisk get caption") as Object)['stdout'].replace("Caption", "");
fileList = std.split("\r\n").filter(item => item.trim().length > 0).map(item => item.trim());
} else {
//linux下
pathStr = "/";
fileList = await fs.readdir(pathStr);
}
} else {
fileList = await fs.readdir(pathStr);
}
let resList = new Array();
for (let index in fileList) {
try {
let stat = await fs.stat(path.join(pathStr, fileList[index]));
resList.push(new FileObj(fileList[index], stat.isDirectory(), stat.birthtime.getTime(), stat.mtime.getTime()));
} catch (e) {
console.error(e);
}
}
return resList;
}
static async createPath(pathStr: string) {
await fs.ensureDir(pathStr);
}
}
export default FileService;

View File

View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ES2017",
"noImplicitAny": false,
"module": "commonjs",
"sourceMap": true,
"outDir": "./dist",
"baseUrl":".",
"rootDir": "./",
"watch": false,
"strict": true,
"strictNullChecks": false,
"esModuleInterop": true
}
}

View File

@ -0,0 +1,29 @@
class ErrorHelper {
/**
*
* @param {String} message
* @param {Number} status
*/
static newError(message, status) {
return getError(message, status);
}
static Error403(message){
return getError(message,403);
}
static Error406(message){
return getError(message,406);
}
static Error400(message){
return getError(message,400);
}
}
let getError = (message, status) => {
let error = new Error(message);
error['status'] = status;
return error;
}
export default ErrorHelper;

View File

@ -0,0 +1,9 @@
import { getLogger, configure } from "log4js";
configure({
appenders: { cheese: { type: "console" } },
categories: { default: { appenders: ["cheese"], level: "info" } }
});
const logger = getLogger();
logger.level = "debug";
export default logger;

View File

@ -0,0 +1,108 @@
import mysql from "mysql2/promise";
import config from '../config';
import * as fs from "fs-extra";
import * as path from 'path';
import log from '../util/LogUtil';
const HISTORY_NAME = "history.json";
interface Res {
rows: any;
fields: mysql.FieldPacket;
}
class MysqlUtil {
public static pool: mysql.Pool = null;
static async createPool(mysqlConfig: any) {
MysqlUtil.pool = await mysql.createPool(mysqlConfig);
let basePath = path.join(config.rootPath, "sqls");
let hisPath = path.join(basePath, HISTORY_NAME);
let history: Array<string>;
if (fs.existsSync(hisPath)) {
history = JSON.parse(await fs.readFile(hisPath, "utf-8"));
} else {
history = new Array();
}
//执行数据库
let files = (await fs.readdir(basePath)).sort((a, b) => a.localeCompare(b)).filter(item => !(item === HISTORY_NAME));
let error = null;
for (let i = 0; i < files.length; i++) {
if (history.indexOf(files[i]) > -1) {
log.info("sql无需重复执行:", files[i]);
continue;
}
let sqlLines = (await fs.readFile(path.join(basePath, files[i]), 'utf-8')).split(/[\r\n]/g);
try {
let sql = "";
for (let j = 0; j < sqlLines.length; j++) {
sql = sql + sqlLines[j];
if (sqlLines[j].endsWith(";")) {
await MysqlUtil.pool.execute(sql);
sql = "";
}
}
log.info("sql执行成功:", files[i]);
history.push(files[i]);
} catch (err) {
error = err;
break;
}
}
await fs.writeFile(hisPath, JSON.stringify(history));
if (error != null) {
throw error;
}
}
static async getRows(sql: string, params: Array<any>, connection: mysql.PoolConnection = null): Promise<Array<any>> {
return (await MysqlUtil.execute(sql, params, connection)).rows;
}
static async getRow(sql: string, params: Array<any>, connection: mysql.PoolConnection = null): Promise<any> {
let rows = (await MysqlUtil.execute(sql, params, connection)).rows;
return rows.length > 0 ? rows[0] : null;
}
static async getSingle(sql: string, params: Array<any>, connection: mysql.PoolConnection = null): Promise<any> {
let rows = (await MysqlUtil.execute(sql, params, connection)).rows;
if (rows.length == 0) {
return null;
}
let row = rows[0];
return row[Object.keys(row)[0]];
}
static async execute(sql: string, params: Array<any>, connection: mysql.PoolConnection = null): Promise<Res> {
let res: any = {};
if (connection == null) {
let [rows, fields] = await MysqlUtil.pool.query(sql, params);
res['rows'] = fields === undefined ? null : rows;
res['fields'] = fields === undefined ? rows : fields;
} else {
let [rows, fields] = await connection.query(sql, params);
res['rows'] = rows;
res['fields'] = fields;
}
return res;
}
static async test() {
let connection = await MysqlUtil.pool.getConnection();
connection.beginTransaction();
connection.query(`insert into url value(6,"GET","asd","public")`);
connection.query(`insert into url value(7,"GET","asd","public")`);
await connection.commit();
connection.release();
}
}
export {
MysqlUtil,
Res,
mysql
}

View File

@ -0,0 +1,8 @@
class NumberUtil {
static getRandom(min: number, max: number): number {
return Math.floor((Math.random() * (max - min + 1) + min));
}
}
export default NumberUtil;

View File

@ -0,0 +1,18 @@
/*
node对象
*/
class ObjectOperation {
static combineObject(...objs) {
if (objs.length == 1 && objs[0] instanceof Array) {
objs = objs[0];
}
let sum = {};
let length = objs.length;
for (let i = 0; i < length; i++) {
sum = Object.assign(sum,objs[i]);
}
return sum;
}
}
export default ObjectOperation

View File

@ -0,0 +1,24 @@
import * as childPrecess from 'child_process';
class ProcessHelper {
static exec(cmd): Promise<string> {
return new Promise((resolve, reject) => {
childPrecess.exec(cmd, (error, stdout, stderr) => {
if (error) {
reject(error);
} if (stderr) {
reject(stderr);
} else {
resolve(stdout)
}
})
})
}
}
// (async()=>{
// let res= await ProcessHelper.exec('cd /d e://workspace&&dir');
// console.log(res);
// })()
export default ProcessHelper

View File

@ -0,0 +1,59 @@
import sqlite3 from 'sqlite3';
import { open, Database } from 'sqlite';
import config from '../config';
import * as fs from "fs-extra";
import * as path from 'path';
import log from './LogUtil';
const HISTORY_NAME = "history.json";
class MysqlUtil {
public static pool: Database = null;
static async createPool(mysqlConfig: any) {
MysqlUtil.pool = await open({
filename: path.join(config.rootPath, "database.db"),
driver: sqlite3.Database
});
let basePath = path.join(config.rootPath, "sqls");
let hisPath = path.join(basePath, HISTORY_NAME);
let history: Array<string>;
if (fs.existsSync(hisPath)) {
history = JSON.parse(await fs.readFile(hisPath, "utf-8"));
} else {
history = new Array();
}
//执行数据库
let files = (await fs.readdir(basePath)).sort((a, b) => a.localeCompare(b)).filter(item => !(item === HISTORY_NAME));
let error = null;
for (let i = 0; i < files.length; i++) {
if (history.indexOf(files[i]) > -1) {
log.info("sql无需重复执行:", files[i]);
continue;
}
let sqlLines = (await fs.readFile(path.join(basePath, files[i]), 'utf-8')).split(/[\r\n]/g);
try {
let sql = "";
for (let j = 0; j < sqlLines.length; j++) {
sql = sql + sqlLines[j];
if (sqlLines[j].endsWith(";")) {
await MysqlUtil.pool.exec(sql);
sql = "";
}
}
log.info("sql执行成功:", files[i]);
history.push(files[i]);
} catch (err) {
error = err;
break;
}
}
await fs.writeFile(hisPath, JSON.stringify(history));
if (error != null) {
throw error;
}
}
}
export default MysqlUtil;

View File

@ -0,0 +1,22 @@
import moment from 'moment';
class TimeUtil {
/**
*
*/
static getZeroTime(): Date {
return moment()
.millisecond(0)
.second(0)
.minute(0)
.hour(0)
.toDate();
}
static async sleep(duration: number): Promise<void> {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), duration);
});
}
}
export default TimeUtil;

View File

@ -0,0 +1,14 @@
import path, { dirname } from 'path'
class pathUtil {
static getPath(pathStr) {
return path.resolve(pathUtil.getRootPath(), pathStr);
}
static getRootPath() {
return path.resolve(__dirname, '..');
}
}
export default pathUtil

View File

@ -0,0 +1,26 @@
export default class FileObj {
/**
*
*/
name: string;
/**
*
*/
isFolder: boolean;
/**
* ms
*/
createdTime: number;
/**
*
*/
updatedTime: number;
constructor(name, isFolder, createdTime, updatedTime) {
this.name = name;
this.isFolder = isFolder;
this.createdTime = createdTime;
this.updatedTime = updatedTime;
}
}

View File

@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

View File

@ -0,0 +1,14 @@
module.exports = {
root: true,
env: {
node: true,
},
extends: ["plugin:vue/vue3-essential", "eslint:recommended", "@vue/prettier"],
parserOptions: {
parser: "babel-eslint",
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
},
};

View File

@ -0,0 +1,3 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
};

View File

@ -8,16 +8,23 @@
"version": "0.1.0",
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0"
"vue": "^3.0.0",
"vue-router": "^4.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0"
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.0.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"prettier": "^2.2.1"
}
},
"node_modules/@babel/code-frame": {
@ -2453,6 +2460,19 @@
"yallist": "^2.1.2"
}
},
"node_modules/@vue/component-compiler-utils/node_modules/prettier": {
"version": "1.19.1",
"resolved": "https://registry.nlark.com/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1622888855914&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz",
"integrity": "sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=",
"dev": true,
"optional": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@vue/component-compiler-utils/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
@ -2468,6 +2488,25 @@
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
"dev": true
},
"node_modules/@vue/devtools-api": {
"version": "6.0.0-beta.14",
"resolved": "https://registry.nlark.com/@vue/devtools-api/download/@vue/devtools-api-6.0.0-beta.14.tgz",
"integrity": "sha1-btLW+NZqklbJrQS//wgwm6h7lyM="
},
"node_modules/@vue/eslint-config-prettier": {
"version": "6.0.0",
"resolved": "https://registry.npm.taobao.org/@vue/eslint-config-prettier/download/@vue/eslint-config-prettier-6.0.0.tgz",
"integrity": "sha1-rVkSswj0rkaEWOAqKwXbC50kZwA=",
"dev": true,
"dependencies": {
"eslint-config-prettier": "^6.0.0"
},
"peerDependencies": {
"eslint": ">= 5.0.0",
"eslint-plugin-prettier": "^3.1.0",
"prettier": ">= 1.13.0"
}
},
"node_modules/@vue/preload-webpack-plugin": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.2.tgz",
@ -4471,6 +4510,15 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
"dev": true
},
"node_modules/copy-anything": {
"version": "2.0.3",
"resolved": "https://registry.npm.taobao.org/copy-anything/download/copy-anything-2.0.3.tgz?cache=0&sync_timestamp=1612448016991&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-anything%2Fdownload%2Fcopy-anything-2.0.3.tgz",
"integrity": "sha1-hCQHugJGaw34RIGbvjuuu+XUXYc=",
"dev": true,
"dependencies": {
"is-what": "^3.12.0"
}
},
"node_modules/copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz",
@ -5835,6 +5883,21 @@
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
}
},
"node_modules/eslint-config-prettier": {
"version": "6.15.0",
"resolved": "https://registry.nlark.com/eslint-config-prettier/download/eslint-config-prettier-6.15.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.15.0.tgz",
"integrity": "sha1-f5P2y31FqS8VN6cOzAY2bhrG/tk=",
"dev": true,
"dependencies": {
"get-stdin": "^6.0.0"
},
"bin": {
"eslint-config-prettier-check": "bin/cli.js"
},
"peerDependencies": {
"eslint": ">=3.14.1"
}
},
"node_modules/eslint-loader": {
"version": "2.2.1",
"resolved": "https://registry.nlark.com/eslint-loader/download/eslint-loader-2.2.1.tgz",
@ -5853,6 +5916,22 @@
"webpack": ">=2.0.0 <5.0.0"
}
},
"node_modules/eslint-plugin-prettier": {
"version": "3.4.0",
"resolved": "https://registry.nlark.com/eslint-plugin-prettier/download/eslint-plugin-prettier-3.4.0.tgz",
"integrity": "sha1-zbrTvx29Kxd+mCVzf+Y7R2oI8Mc=",
"dev": true,
"dependencies": {
"prettier-linter-helpers": "^1.0.0"
},
"engines": {
"node": ">=6.0.0"
},
"peerDependencies": {
"eslint": ">=5.0.0",
"prettier": ">=1.13.0"
}
},
"node_modules/eslint-plugin-vue": {
"version": "7.11.1",
"resolved": "https://registry.nlark.com/eslint-plugin-vue/download/eslint-plugin-vue-7.11.1.tgz",
@ -6485,6 +6564,12 @@
"integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=",
"dev": true
},
"node_modules/fast-diff": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/fast-diff/download/fast-diff-1.2.0.tgz",
"integrity": "sha1-c+4RmC2Gyq95WYKNUZz+kn+sXwM=",
"dev": true
},
"node_modules/fast-glob": {
"version": "2.2.7",
"resolved": "https://registry.npm.taobao.org/fast-glob/download/fast-glob-2.2.7.tgz?cache=0&sync_timestamp=1612237392146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-2.2.7.tgz",
@ -6899,6 +6984,15 @@
"has-symbols": "^1.0.1"
}
},
"node_modules/get-stdin": {
"version": "6.0.0",
"resolved": "https://registry.npm.taobao.org/get-stdin/download/get-stdin-6.0.0.tgz",
"integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz",
@ -7561,6 +7655,19 @@
"node": ">= 4"
}
},
"node_modules/image-size": {
"version": "0.5.5",
"resolved": "https://registry.npm.taobao.org/image-size/download/image-size-0.5.5.tgz?cache=0&sync_timestamp=1618422554012&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimage-size%2Fdownload%2Fimage-size-0.5.5.tgz",
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
"dev": true,
"optional": true,
"bin": {
"image-size": "bin/image-size.js"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/import-cwd": {
"version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz",
@ -8269,6 +8376,12 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true
},
"node_modules/is-what": {
"version": "3.14.1",
"resolved": "https://registry.nlark.com/is-what/download/is-what-3.14.1.tgz",
"integrity": "sha1-4SIvRt3ahd6tD9HJ3xMXYOd3VcE=",
"dev": true
},
"node_modules/is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz",
@ -8496,6 +8609,105 @@
"launch-editor": "^2.2.1"
}
},
"node_modules/less": {
"version": "3.13.1",
"resolved": "https://registry.npm.taobao.org/less/download/less-3.13.1.tgz",
"integrity": "sha1-DryR0qDpwMZzW4PUlrCrBYMHeQk=",
"dev": true,
"dependencies": {
"copy-anything": "^2.0.1",
"tslib": "^1.10.0"
},
"bin": {
"lessc": "bin/lessc"
},
"engines": {
"node": ">=6"
},
"optionalDependencies": {
"errno": "^0.1.1",
"graceful-fs": "^4.1.2",
"image-size": "~0.5.0",
"make-dir": "^2.1.0",
"mime": "^1.4.1",
"native-request": "^1.0.5",
"source-map": "~0.6.0"
}
},
"node_modules/less-loader": {
"version": "5.0.0",
"resolved": "https://registry.nlark.com/less-loader/download/less-loader-5.0.0.tgz?cache=0&sync_timestamp=1623935559769&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fless-loader%2Fdownload%2Fless-loader-5.0.0.tgz",
"integrity": "sha1-SY3eOmxsT4h0WO6e0/CGoSrRtGY=",
"dev": true,
"dependencies": {
"clone": "^2.1.1",
"loader-utils": "^1.1.0",
"pify": "^4.0.1"
},
"engines": {
"node": ">= 4.8.0"
},
"peerDependencies": {
"less": "^2.3.1 || ^3.0.0",
"webpack": "^2.0.0 || ^3.0.0 || ^4.0.0"
}
},
"node_modules/less-loader/node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/clone/download/clone-2.1.2.tgz",
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
"dev": true,
"engines": {
"node": ">=0.8"
}
},
"node_modules/less/node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz",
"integrity": "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU=",
"dev": true,
"optional": true,
"dependencies": {
"pify": "^4.0.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/less/node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.nlark.com/mime/download/mime-1.6.0.tgz?cache=0&sync_timestamp=1618846922439&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fmime%2Fdownload%2Fmime-1.6.0.tgz",
"integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=",
"dev": true,
"optional": true,
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/less/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1616464367341&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz",
"integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
"dev": true,
"optional": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/less/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true,
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/levn": {
"version": "0.3.0",
"resolved": "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz",
@ -9147,6 +9359,13 @@
"node": ">=0.10.0"
}
},
"node_modules/native-request": {
"version": "1.0.8",
"resolved": "https://registry.npm.taobao.org/native-request/download/native-request-1.0.8.tgz",
"integrity": "sha1-j2a/YG4PfqJ8DlmV6y9dA+M65vs=",
"dev": true,
"optional": true
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz",
@ -10882,16 +11101,27 @@
}
},
"node_modules/prettier": {
"version": "1.19.1",
"resolved": "https://registry.nlark.com/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1622888855914&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz",
"integrity": "sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=",
"version": "2.3.1",
"resolved": "https://registry.nlark.com/prettier/download/prettier-2.3.1.tgz?cache=0&sync_timestamp=1622888855914&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fprettier%2Fdownload%2Fprettier-2.3.1.tgz",
"integrity": "sha1-dpA8P4xESbyaxZes76JNxa1MvqY=",
"dev": true,
"optional": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=4"
"node": ">=10.13.0"
}
},
"node_modules/prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/prettier-linter-helpers/download/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha1-0j1B/hN1ZG3i0BBNNFSjAIgCz3s=",
"dev": true,
"dependencies": {
"fast-diff": "^1.1.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/pretty-error": {
@ -13821,6 +14051,17 @@
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
"dev": true
},
"node_modules/vue-router": {
"version": "4.0.9",
"resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.9.tgz",
"integrity": "sha1-JISWlBt5xMEBD26/zyNc1CZ9hdo=",
"dependencies": {
"@vue/devtools-api": "^6.0.0-beta.14"
},
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/vue-style-loader": {
"version": "4.1.3",
"resolved": "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.3.tgz",
@ -16834,6 +17075,13 @@
"yallist": "^2.1.2"
}
},
"prettier": {
"version": "1.19.1",
"resolved": "https://registry.nlark.com/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1622888855914&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz",
"integrity": "sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=",
"dev": true,
"optional": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
@ -16848,6 +17096,20 @@
}
}
},
"@vue/devtools-api": {
"version": "6.0.0-beta.14",
"resolved": "https://registry.nlark.com/@vue/devtools-api/download/@vue/devtools-api-6.0.0-beta.14.tgz",
"integrity": "sha1-btLW+NZqklbJrQS//wgwm6h7lyM="
},
"@vue/eslint-config-prettier": {
"version": "6.0.0",
"resolved": "https://registry.npm.taobao.org/@vue/eslint-config-prettier/download/@vue/eslint-config-prettier-6.0.0.tgz",
"integrity": "sha1-rVkSswj0rkaEWOAqKwXbC50kZwA=",
"dev": true,
"requires": {
"eslint-config-prettier": "^6.0.0"
}
},
"@vue/preload-webpack-plugin": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.2.tgz",
@ -18562,6 +18824,15 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
"dev": true
},
"copy-anything": {
"version": "2.0.3",
"resolved": "https://registry.npm.taobao.org/copy-anything/download/copy-anything-2.0.3.tgz?cache=0&sync_timestamp=1612448016991&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-anything%2Fdownload%2Fcopy-anything-2.0.3.tgz",
"integrity": "sha1-hCQHugJGaw34RIGbvjuuu+XUXYc=",
"dev": true,
"requires": {
"is-what": "^3.12.0"
}
},
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz",
@ -19759,6 +20030,15 @@
}
}
},
"eslint-config-prettier": {
"version": "6.15.0",
"resolved": "https://registry.nlark.com/eslint-config-prettier/download/eslint-config-prettier-6.15.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.15.0.tgz",
"integrity": "sha1-f5P2y31FqS8VN6cOzAY2bhrG/tk=",
"dev": true,
"requires": {
"get-stdin": "^6.0.0"
}
},
"eslint-loader": {
"version": "2.2.1",
"resolved": "https://registry.nlark.com/eslint-loader/download/eslint-loader-2.2.1.tgz",
@ -19772,6 +20052,15 @@
"rimraf": "^2.6.1"
}
},
"eslint-plugin-prettier": {
"version": "3.4.0",
"resolved": "https://registry.nlark.com/eslint-plugin-prettier/download/eslint-plugin-prettier-3.4.0.tgz",
"integrity": "sha1-zbrTvx29Kxd+mCVzf+Y7R2oI8Mc=",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0"
}
},
"eslint-plugin-vue": {
"version": "7.11.1",
"resolved": "https://registry.nlark.com/eslint-plugin-vue/download/eslint-plugin-vue-7.11.1.tgz",
@ -20225,6 +20514,12 @@
"integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=",
"dev": true
},
"fast-diff": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/fast-diff/download/fast-diff-1.2.0.tgz",
"integrity": "sha1-c+4RmC2Gyq95WYKNUZz+kn+sXwM=",
"dev": true
},
"fast-glob": {
"version": "2.2.7",
"resolved": "https://registry.npm.taobao.org/fast-glob/download/fast-glob-2.2.7.tgz?cache=0&sync_timestamp=1612237392146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-2.2.7.tgz",
@ -20567,6 +20862,12 @@
"has-symbols": "^1.0.1"
}
},
"get-stdin": {
"version": "6.0.0",
"resolved": "https://registry.npm.taobao.org/get-stdin/download/get-stdin-6.0.0.tgz",
"integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=",
"dev": true
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz",
@ -21115,6 +21416,13 @@
"integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=",
"dev": true
},
"image-size": {
"version": "0.5.5",
"resolved": "https://registry.npm.taobao.org/image-size/download/image-size-0.5.5.tgz?cache=0&sync_timestamp=1618422554012&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimage-size%2Fdownload%2Fimage-size-0.5.5.tgz",
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
"dev": true,
"optional": true
},
"import-cwd": {
"version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz",
@ -21663,6 +21971,12 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true
},
"is-what": {
"version": "3.14.1",
"resolved": "https://registry.nlark.com/is-what/download/is-what-3.14.1.tgz",
"integrity": "sha1-4SIvRt3ahd6tD9HJ3xMXYOd3VcE=",
"dev": true
},
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz",
@ -21854,6 +22168,76 @@
"launch-editor": "^2.2.1"
}
},
"less": {
"version": "3.13.1",
"resolved": "https://registry.npm.taobao.org/less/download/less-3.13.1.tgz",
"integrity": "sha1-DryR0qDpwMZzW4PUlrCrBYMHeQk=",
"dev": true,
"requires": {
"copy-anything": "^2.0.1",
"errno": "^0.1.1",
"graceful-fs": "^4.1.2",
"image-size": "~0.5.0",
"make-dir": "^2.1.0",
"mime": "^1.4.1",
"native-request": "^1.0.5",
"source-map": "~0.6.0",
"tslib": "^1.10.0"
},
"dependencies": {
"make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz",
"integrity": "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU=",
"dev": true,
"optional": true,
"requires": {
"pify": "^4.0.1",
"semver": "^5.6.0"
}
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.nlark.com/mime/download/mime-1.6.0.tgz?cache=0&sync_timestamp=1618846922439&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fmime%2Fdownload%2Fmime-1.6.0.tgz",
"integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=",
"dev": true,
"optional": true
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1616464367341&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz",
"integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
"dev": true,
"optional": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true,
"optional": true
}
}
},
"less-loader": {
"version": "5.0.0",
"resolved": "https://registry.nlark.com/less-loader/download/less-loader-5.0.0.tgz?cache=0&sync_timestamp=1623935559769&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fless-loader%2Fdownload%2Fless-loader-5.0.0.tgz",
"integrity": "sha1-SY3eOmxsT4h0WO6e0/CGoSrRtGY=",
"dev": true,
"requires": {
"clone": "^2.1.1",
"loader-utils": "^1.1.0",
"pify": "^4.0.1"
},
"dependencies": {
"clone": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/clone/download/clone-2.1.2.tgz",
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
"dev": true
}
}
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz",
@ -22406,6 +22790,13 @@
"to-regex": "^3.0.1"
}
},
"native-request": {
"version": "1.0.8",
"resolved": "https://registry.npm.taobao.org/native-request/download/native-request-1.0.8.tgz",
"integrity": "sha1-j2a/YG4PfqJ8DlmV6y9dA+M65vs=",
"dev": true,
"optional": true
},
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz",
@ -23856,11 +24247,19 @@
"dev": true
},
"prettier": {
"version": "1.19.1",
"resolved": "https://registry.nlark.com/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1622888855914&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz",
"integrity": "sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=",
"version": "2.3.1",
"resolved": "https://registry.nlark.com/prettier/download/prettier-2.3.1.tgz?cache=0&sync_timestamp=1622888855914&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fprettier%2Fdownload%2Fprettier-2.3.1.tgz",
"integrity": "sha1-dpA8P4xESbyaxZes76JNxa1MvqY=",
"dev": true
},
"prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/prettier-linter-helpers/download/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha1-0j1B/hN1ZG3i0BBNNFSjAIgCz3s=",
"dev": true,
"optional": true
"requires": {
"fast-diff": "^1.1.2"
}
},
"pretty-error": {
"version": "2.1.2",
@ -26346,6 +26745,14 @@
}
}
},
"vue-router": {
"version": "4.0.9",
"resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.9.tgz",
"integrity": "sha1-JISWlBt5xMEBD26/zyNc1CZ9hdo=",
"requires": {
"@vue/devtools-api": "^6.0.0-beta.14"
}
},
"vue-style-loader": {
"version": "4.1.3",
"resolved": "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.3.tgz",

View File

@ -8,35 +8,24 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
"vue": "^3.0.0"
"vue": "^3.0.0",
"vue-router": "^4.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.0.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"prettier": "^2.2.1"
}
}

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,30 @@
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,126 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br />
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
>vue-cli documentation</a
>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
target="_blank"
rel="noopener"
>babel</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
target="_blank"
rel="noopener"
>router</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
target="_blank"
rel="noopener"
>eslint</a
>
</li>
</ul>
<h3>Essential Links</h3>
<ul>
<li>
<a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
</li>
<li>
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
>Forum</a
>
</li>
<li>
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
>Community Chat</a
>
</li>
<li>
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
>Twitter</a
>
</li>
<li>
<a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
</li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li>
<a href="https://router.vuejs.org" target="_blank" rel="noopener"
>vue-router</a
>
</li>
<li>
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
</li>
<li>
<a
href="https://github.com/vuejs/vue-devtools#vue-devtools"
target="_blank"
rel="noopener"
>vue-devtools</a
>
</li>
<li>
<a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
>vue-loader</a
>
</li>
<li>
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
rel="noopener"
>awesome-vue</a
>
</li>
</ul>
</div>
</template>
<script>
import HttpUtil from "../utils/HttpUtil";
export default {
name: "HelloWorld",
props: {
msg: String,
},
mounted() {
HttpUtil.get("");
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@ -0,0 +1,5 @@
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
createApp(App).use(router).mount("#app");

View File

@ -0,0 +1,26 @@
import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue"),
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;

View File

@ -0,0 +1,113 @@
import * as http from "axios";
import router from "../router/index";
/**
* 请求
* @param {*} url url
* @param {*} method 方法
* @param {*} params url参数
* @param {*} body 请求体
* @param {*} isForm 是否form
* @param {*} redirect 接口返回未认证是否跳转到登陆
* @returns 数据
*/
async function request(url, method, params, body, isForm, redirect) {
let options = {
url,
baseURL: "/bookmark/api",
method,
params,
// headers: {
// "jwt-token": vuex.state.globalConfig.token,
// },
};
if (isForm) {
options.headers["Content-Type"] = "multipart/form-data";
}
if (body) {
options.data = body;
}
let res;
try {
res = await http.default.request(options);
} catch (err) {
window.vueInstance.$message.error("发生了某些异常问题");
console.error(err);
return;
}
const { code, data, message } = res.data;
if (code === 1) {
return data;
} else if (code === -1 && redirect) {
// 跳转到登陆页
window.vueInstance.$message.error("您尚未登陆,请先登陆");
router.replace(
`/public/login?redirect=${encodeURIComponent(
router.currentRoute.fullPath
)}`
);
throw new Error(message);
} else if (code === 0) {
//通用异常,使用
window.vueInstance.$notification.error({
message: "异常",
description: message,
});
throw new Error(message);
} else if (code === -2) {
//表单异常使用message提示
window.vueInstance.$message.error(message);
throw new Error(message);
}
}
/**
* get方法
* @param {*} url url
* @param {*} params url参数
* @param {*} redirect 未登陆是否跳转到登陆页
*/
async function get(url, params = null, redirect = true) {
return request(url, "get", params, null, false, redirect);
}
/**
* post方法
* @param {*} url url
* @param {*} params url参数
* @param {*} body body参数
* @param {*} isForm 是否表单数据
* @param {*} redirect 是否重定向
*/
async function post(url, params, body, isForm = false, redirect = true) {
return request(url, "post", params, body, isForm, redirect);
}
/**
* put方法
* @param {*} url url
* @param {*} params url参数
* @param {*} body body参数
* @param {*} isForm 是否表单数据
* @param {*} redirect 是否重定向
*/
async function put(url, params, body, isForm = false, redirect = true) {
return request(url, "put", params, body, isForm, redirect);
}
/**
* delete方法
* @param {*} url url
* @param {*} params url参数
* @param {*} redirect 是否重定向
*/
async function deletes(url, params = null, redirect = true) {
return request(url, "delete", params, null, redirect);
}
export default {
get,
post,
put,
delete: deletes,
};

View File

@ -0,0 +1,5 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>

View File

@ -0,0 +1,18 @@
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "Home",
components: {
HelloWorld,
},
};
</script>