新增前端vue

This commit is contained in:
2025-11-26 13:55:01 +08:00
parent ae391f1b94
commit ffd5a6ad66
781 changed files with 83348 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
export default {
host: 'localhost',
port: 3300,
};

View File

@@ -0,0 +1,15 @@
import FileService from '../service/FileService';
import { router } from '../router';
const service: FileService = new FileService();
router.post('/menuRoute', async (ctx) => {
const files: any = ctx.request.files.file;
console.log(files);
if (files.length === undefined) {
service.upload(ctx, files, false);
} else {
service.upload(ctx, files, true);
}
});

View File

@@ -0,0 +1,8 @@
import MenuService from '../service/MenuService';
import { router } from '../router';
const service: MenuService = new MenuService();
router.get('/menuRoute', async (ctx) => {
ctx.body = await service.menuRoute(ctx);
});

View File

@@ -0,0 +1,12 @@
import UserService from '../service/UserService';
import { router } from '../router';
const service: UserService = new UserService();
router.get('/login', async (ctx) => {
ctx.body = await service.login(ctx);
});
router.get('/index', async (ctx) => {
ctx.body = await service.index(ctx);
});

View File

@@ -0,0 +1,20 @@
import path from 'path';
import Koa from 'koa';
import koaStatic from 'koa-static';
import koaWebsocket from 'koa-websocket';
import websocket from './ws';
import config from './config';
import router from './router';
import './router/routes';
const app = koaWebsocket(new Koa());
websocket(app);
router(app);
app.use(koaStatic(path.join(__dirname, '../')));
app.listen(config.port, () => {
console.log(`Application started successfully: http://${config.host}:${config.port}`);
});

View File

@@ -0,0 +1,29 @@
import Router from 'koa-router';
// import routes from './routes';
import cors from 'koa2-cors';
import body from 'koa-body';
const router = new Router();
function initRouter(app: any): Router<any, any> {
// routes.forEach((route) => router[route.method](route.path, route.action));
app.use(cors());
app.use(
body({
encoding: 'gzip',
multipart: true,
formidable: {
// uploadDir: path.join(__dirname, '../../static/upload/'), // 设置文件上传目录
keepExtensions: true,
maxFieldsSize: 20 * 1024 * 1024,
},
}),
);
app.use(router.routes());
app.use(router.allowedMethods());
return router;
}
export { router };
export default initRouter;

View File

@@ -0,0 +1,3 @@
import '../controller/UserController';
import '../controller/MenuController';
import '../controller/FileController';

View File

@@ -0,0 +1,56 @@
import path from 'path';
import fs from 'fs-extra';
import config from '../config';
const uploadUrl = `http://${config.host}:${config.port}/static/upload`;
const filePath = path.join(__dirname, '../../static/upload/');
fs.ensureDir(filePath);
export default class UserService {
async upload(ctx, files, isMultiple) {
let fileReader, fileResource, writeStream;
const fileFunc = function (file) {
fileReader = fs.createReadStream(file.path);
fileResource = filePath + `/${file.name}`;
console.log(fileResource);
writeStream = fs.createWriteStream(fileResource);
fileReader.pipe(writeStream);
};
const returnFunc = function (flag) {
if (flag) {
let url = '';
for (let i = 0; i < files.length; i++) {
url += uploadUrl + `/${files[i].name},`;
}
url = url.replace(/,$/gi, '');
ctx.body = {
url: url,
code: 0,
message: 'upload Success!',
};
} else {
ctx.body = {
url: uploadUrl + `/${files.name}`,
code: 0,
message: 'upload Success!',
};
}
};
console.log(isMultiple, files.length);
if (isMultiple) {
for (let i = 0; i < files.length; i++) {
const f1 = files[i];
fileFunc(f1);
}
} else {
fileFunc(files);
}
fs.ensureDir(filePath);
returnFunc(isMultiple);
}
}

View File

@@ -0,0 +1,261 @@
import { Result } from '../utils';
import { fakeUserList } from './UserService';
// single
const dashboardRoute = {
path: '/dashboard',
name: 'Dashboard',
component: 'LAYOUT',
redirect: '/dashboard/analysis',
meta: {
title: 'routes.dashboard.dashboard',
hideChildrenInMenu: true,
icon: 'i-bx:bx-home',
},
children: [
{
path: 'analysis',
name: 'Analysis',
component: '/dashboard/analysis/index',
meta: {
hideMenu: true,
hideBreadcrumb: true,
title: 'routes.dashboard.analysis',
currentActiveMenu: '/dashboard',
icon: 'i-bx:bx-home',
},
},
{
path: 'workbench',
name: 'Workbench',
component: '/dashboard/workbench/index',
meta: {
hideMenu: true,
hideBreadcrumb: true,
title: 'routes.dashboard.workbench',
currentActiveMenu: '/dashboard',
icon: 'i-bx:bx-home',
},
},
],
};
const backRoute = {
path: 'back',
name: 'PermissionBackDemo',
meta: {
title: 'routes.demo.permission.back',
},
children: [
{
path: 'page',
name: 'BackAuthPage',
component: '/demo/permission/back/index',
meta: {
title: 'routes.demo.permission.backPage',
},
},
{
path: 'btn',
name: 'BackAuthBtn',
component: '/demo/permission/back/Btn',
meta: {
title: 'routes.demo.permission.backBtn',
},
},
],
};
const authRoute = {
path: '/permission',
name: 'Permission',
component: 'LAYOUT',
redirect: '/permission/front/page',
meta: {
icon: 'i-carbon:user-role',
title: 'routes.demo.permission.permission',
},
children: [backRoute],
};
const levelRoute = {
path: '/level',
name: 'Level',
component: 'LAYOUT',
redirect: '/level/menu1/menu1-1',
meta: {
icon: 'i-carbon:user-role',
title: 'routes.demo.level.level',
},
children: [
{
path: 'menu1',
name: 'Menu1Demo',
meta: {
title: 'Menu1',
},
children: [
{
path: 'menu1-1',
name: 'Menu11Demo',
meta: {
title: 'Menu1-1',
},
children: [
{
path: 'menu1-1-1',
name: 'Menu111Demo',
component: '/demo/level/Menu111',
meta: {
title: 'Menu111',
},
},
],
},
{
path: 'menu1-2',
name: 'Menu12Demo',
component: '/demo/level/Menu12',
meta: {
title: 'Menu1-2',
},
},
],
},
{
path: 'menu2',
name: 'Menu2Demo',
component: '/demo/level/Menu2',
meta: {
title: 'Menu2',
},
},
],
};
const sysRoute = {
path: '/system',
name: 'System',
component: 'LAYOUT',
redirect: '/system/account',
meta: {
icon: 'i-ion:settings-outline',
title: 'routes.demo.system.moduleName',
},
children: [
{
path: 'account',
name: 'AccountManagement',
meta: {
title: 'routes.demo.system.account',
ignoreKeepAlive: true,
},
component: '/demo/system/account/index',
},
{
path: 'account_detail/:id',
name: 'AccountDetail',
meta: {
hideMenu: true,
title: 'routes.demo.system.account_detail',
ignoreKeepAlive: true,
showMenu: false,
currentActiveMenu: '/system/account',
},
component: '/demo/system/account/AccountDetail',
},
{
path: 'role',
name: 'RoleManagement',
meta: {
title: 'routes.demo.system.role',
ignoreKeepAlive: true,
},
component: '/demo/system/role/index',
},
{
path: 'menu',
name: 'MenuManagement',
meta: {
title: 'routes.demo.system.menu',
ignoreKeepAlive: true,
},
component: '/demo/system/menu/index',
},
{
path: 'dept',
name: 'DeptManagement',
meta: {
title: 'routes.demo.system.dept',
ignoreKeepAlive: true,
},
component: '/demo/system/dept/index',
},
{
path: 'changePassword',
name: 'ChangePassword',
meta: {
title: 'routes.demo.system.password',
ignoreKeepAlive: true,
},
component: '/demo/system/password/index',
},
],
};
const linkRoute = {
path: '/link',
name: 'Link',
component: 'LAYOUT',
meta: {
icon: 'i-ion:tv-outline',
title: 'routes.demo.iframe.frame',
},
children: [
{
path: 'doc',
name: 'Doc',
meta: {
title: 'routes.demo.iframe.doc',
frameSrc: 'https://vvbin.cn/doc-next/',
},
},
{
path: 'https://vvbin.cn/doc-next/',
name: 'DocExternal',
component: 'LAYOUT',
meta: {
title: 'routes.demo.iframe.docExternal',
},
},
],
};
export default class MenuService {
async menuRoute(ctx) {
const { token } = ctx.request.query;
if (!token) return Result.error('Invalid token');
const checkUser = fakeUserList.find((item) => item.token === token);
if (!checkUser) {
return Result.error('Invalid user token!');
}
const id = checkUser.userCode;
let menu: object[];
switch (id) {
case '1':
dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[0].path;
menu = [dashboardRoute, authRoute, levelRoute, sysRoute, linkRoute];
break;
case '2':
dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[1].path;
menu = [dashboardRoute, authRoute, levelRoute, linkRoute];
break;
default:
menu = [];
}
return Result.success(menu);
}
}

View File

@@ -0,0 +1,68 @@
import { Result } from '../utils';
export const fakeUserList: any = [
{
userCode: '1',
username: 'c3lzdGVt',
password: 'YWRtaW4=',
userName: 'ThinkGem',
avatarUrl: 'https://q1.qlogo.cn/g?b=qq&nk=190848757&s=640',
remarks: 'manager',
token: 'fakeToken1',
roleList: [
{
roleName: 'Super Admin',
roleCode: 'super',
},
],
},
{
userCode: '2',
username: 'test',
password: '123456',
userName: 'TestUser',
avatarUrl: 'https://q1.qlogo.cn/g?b=qq&nk=339449197&s=640',
remarks: 'tester',
token: 'fakeToken2',
roleList: [
{
roleName: 'Tester',
roleCode: 'test',
},
],
},
];
export const fakeCodeList: any = {
'1': ['1000', '3000', '5000'],
'2': ['2000', '4000', '6000'],
};
export default class UserService {
async login(ctx) {
const { username, password } = ctx.request.query;
const checkUser = fakeUserList.find((item) => item.username === username && password === item.password);
if (!checkUser) {
return Result.error('Incorrect account or password');
}
const { userCode, username: _username, token, realName, desc, roles } = checkUser;
return Result.success({
roles,
userCode,
username: _username,
token,
realName,
desc,
});
}
async index(ctx) {
const { token } = ctx.request.query;
if (!token) return Result.error('Invalid token');
const checkUser = fakeUserList.find((item) => item.token === token);
if (!checkUser) {
return Result.error('The corresponding user information was not obtained!');
}
return Result.success(fakeUserList);
}
}

View File

@@ -0,0 +1,16 @@
export class Result {
static success(data: any) {
return {
code: 0,
success: true,
result: data,
};
}
static error(data: any) {
return {
code: 0,
success: false,
result: data,
};
}
}

View File

@@ -0,0 +1,28 @@
import route from 'koa-route';
function initWebsocket(app: any) {
app.ws.use(function (ctx, next) {
ctx.websocket.send('connection succeeded!');
return next(ctx);
});
app.ws.use(
route.all('/test', function (ctx) {
// ctx.websocket.send('Hello World');
ctx.websocket.on('message', function (message) {
// do something with the message from client
if (message !== 'ping') {
const data = JSON.stringify({
id: Math.ceil(Math.random() * 1000),
time: new Date().getTime(),
res: `${message}`,
});
ctx.websocket.send(data);
}
console.log(message);
});
}),
);
}
export default initWebsocket;