理顺框架
This commit is contained in:
parent
62a323bdf9
commit
07347cba09
@ -1,3 +1,56 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v5.0.1 | 20191019
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
main, menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, main, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
/* HTML5 hidden-attribute fix for newer browsers */
|
||||
*[hidden] {
|
||||
display: none;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
menu, ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--max-width: 1100px;
|
||||
--border-radius: 12px;
|
||||
@ -73,12 +126,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
max-width: 100vw;
|
||||
|
@ -86,6 +86,9 @@ export const LoginComponent = () => {
|
||||
{/*</div>*/}
|
||||
</Modal>
|
||||
{visible ? 'xxx' : '0000'}
|
||||
<Button type="primary" onClick={() => setVisible(true)}>点击登录</Button>
|
||||
<Button type="primary" onClick={() => {
|
||||
setVisible(true)
|
||||
// Modal.success({ title: 'This is a success message', content: 'bla bla bla...' });
|
||||
}}>点击登录</Button>
|
||||
</div>)
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ export const AppRouter = () => (<WebRouter>
|
||||
<div className="page-body-content">
|
||||
<Routes>
|
||||
<Route path="/" element={<DefaultPage/>}/>
|
||||
|
||||
<Route path="*" element={<NotFound/>}/>
|
||||
</Routes>
|
||||
</div>
|
||||
|
@ -4,6 +4,15 @@
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
.modal{
|
||||
|
||||
.title{
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.loginWrapper {
|
||||
background-color: #fff;
|
||||
padding: 15px 20px;
|
||||
border-radius: 6px;
|
||||
width: 350px;
|
||||
}
|
||||
|
@ -1,10 +1,77 @@
|
||||
import React from "react";
|
||||
import React, {useRef, useState} from "react";
|
||||
import {IconGithubLogo, IconWeibo} from "@douyinfe/semi-icons";
|
||||
import css from './index.module.scss'
|
||||
import {LoginComponent} from "../../components/LoginComponent.tsx";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import {useUserinfoStore} from "../../store/userinfoStore.ts";
|
||||
import {Button, Divider, Form, Modal, Notification, Space} from "@douyinfe/semi-ui";
|
||||
import {cx} from "@emotion/css";
|
||||
|
||||
const DefaultPage: React.FC = () => {
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const {login} = useUserinfoStore()
|
||||
|
||||
const onFinish = async (values: any) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const user = await login(values)
|
||||
setVisible(true);
|
||||
navigate('/dashboard')
|
||||
} catch (err) {
|
||||
// 登录失败
|
||||
console.log(err)
|
||||
// 登录失败
|
||||
Notification.error({
|
||||
content: '登录失败,请检查用户名和密码'
|
||||
})
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
const hideModal = () => setVisible(false)
|
||||
|
||||
return (<div className={css.index}>
|
||||
<LoginComponent/>
|
||||
{/*<LoginComponent/>*/}
|
||||
<div className={css.loginWrapper}>
|
||||
<h2 className={cx('text-center', css.title)}>登录</h2>
|
||||
<Form
|
||||
onSubmit={onFinish}
|
||||
>
|
||||
<Form.Input
|
||||
field="account"
|
||||
placeholder="请输入用户名"
|
||||
noLabel
|
||||
rules={[{required: true, message: '用户名不可空'}]}
|
||||
/>
|
||||
<Form.Input
|
||||
type="password"
|
||||
field="password"
|
||||
placeholder="请输入登录密码"
|
||||
noLabel
|
||||
rules={[{required: true, message: '密码不可空'}]}
|
||||
/>
|
||||
<Form.Checkbox
|
||||
field="remember"
|
||||
value={false}
|
||||
noLabel
|
||||
>下次自动登录</Form.Checkbox>
|
||||
<div className='flex align-center space-between'>
|
||||
<Button block type='primary' theme='solid' loading={loading} htmlType="submit">登录</Button>
|
||||
</div>
|
||||
</Form>
|
||||
<div style={{padding: '30px 0 20px'}}>
|
||||
<Divider>OR</Divider>
|
||||
<div className="text-center" style={{marginTop: 20}}>
|
||||
<Space>
|
||||
<Button icon={<IconWeibo/>}>GOOGLE</Button>
|
||||
<Button theme='solid' type="primary" icon={<IconGithubLogo/>}>GITHUB</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
export default DefaultPage;
|
||||
|
@ -35,7 +35,7 @@ Axios.interceptors.request.use(config => {
|
||||
const token = Storage.get<string>(APP_CONFIG.LOGIN_TOKEN_KEY)
|
||||
// const {token} = useUserinfoStore()
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
config.headers['Authorization'] = `${token}`; // Bearer
|
||||
}
|
||||
if (config.data && config.data instanceof FormData) {
|
||||
config.headers['Content-Type'] = 'multipart/form-data';
|
||||
@ -81,7 +81,7 @@ export function request<T>(url: string, method: RequestMethod, data: any = null,
|
||||
if (code == 403) {
|
||||
const state = useUserinfoStore.getState()
|
||||
// 未登录 显示登录modal
|
||||
state.showLogin(true);
|
||||
// state.showLogin(true);
|
||||
}
|
||||
reject(new BizError(msg, code))
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ import {get, post} from "./request.ts";
|
||||
import {UserModel} from "../../model";
|
||||
|
||||
|
||||
export function login(user: string, password: string) {
|
||||
return post<UserModel>('/api/user/info', {user, password})
|
||||
export function login(username: string, password: string) {
|
||||
return post<UserModel>('/api/user/login', {username, password})
|
||||
}
|
||||
|
||||
export function getInfo() {
|
||||
|
@ -74,8 +74,7 @@ export const useUserinfoStore = create<{
|
||||
},
|
||||
login: (data) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const promise = login(data.account, data.password);
|
||||
promise.then((ret) => {
|
||||
login(data.account, data.password).then((ret) => {
|
||||
const token = ret.token;
|
||||
Storage.put(LOGIN_TOKEN_KEY, token)
|
||||
getInfo().then(userinfo => {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { InitServerOption } from "./types";
|
||||
// import { createServer as createServerOrigin } from "http";
|
||||
import express = require("express");
|
||||
// import express = require("express");
|
||||
import * as express from "express";
|
||||
|
||||
export function createServer(options: Partial<InitServerOption>, callback?: () => void) {
|
||||
// 创建express服务器
|
||||
|
@ -2,7 +2,7 @@ import {Application, Request, Response} from "express";
|
||||
import {RouteHandleFunction, RouteHandleFunctionParam} from "../core/types";
|
||||
import {home} from "./home";
|
||||
import {appList, reportToServer, appEvent, eventData} from "./reportor";
|
||||
import {loginHandler} from "./user.ts";
|
||||
import {getUserInfo, loginHandler} from "./user.ts";
|
||||
|
||||
//
|
||||
function createRoute(handler: RouteHandleFunction) {
|
||||
@ -28,5 +28,6 @@ export function initRoutes(app: Application) {
|
||||
app.all('/api/app/list', createRoute(appList))
|
||||
app.all('/api/app/event', createRoute(appEvent))
|
||||
app.all('/api/app/event-data', createRoute(eventData))
|
||||
app.all('/api/login', createRoute(loginHandler))
|
||||
app.all('/api/user/login', createRoute(loginHandler))
|
||||
app.all('/api/user/info', createRoute(getUserInfo))
|
||||
}
|
||||
|
@ -30,19 +30,23 @@ export async function selectArray<T>(sql: string, params: any = null) {
|
||||
// })
|
||||
// });
|
||||
}
|
||||
|
||||
// 查询单个对象
|
||||
export async function selectOne<T>(sql: string, params: any = null) {
|
||||
// 执行查询sql并返回查询结果
|
||||
const arr = await selectArray<T>(sql, params);
|
||||
if (arr.length != 1) throw new Error("查询结果数量不等于1");
|
||||
return arr[0];
|
||||
// if (arr.length != 1) throw new Error("查询结果数量不等于1");
|
||||
return arr.length > 0 ? arr[0] : null;
|
||||
}
|
||||
|
||||
// 统计数据
|
||||
export async function queryCount(sql: string, params: any = null) {
|
||||
const obj = await selectOne<{ [key: string]: number }>(sql, params);
|
||||
if(!obj) return 0;
|
||||
const keys = Object.keys(obj);
|
||||
return obj[keys[0]];
|
||||
}
|
||||
|
||||
// 根据表名和条件判断数据是否存在
|
||||
export async function isExistByTable(tableName: string, condition: any = {}) {
|
||||
let sql = `select count(*) as count from ${tableName} where 1=1`;
|
||||
@ -54,10 +58,12 @@ export async function isExistByTable(tableName: string, condition: any = {}) {
|
||||
const count = await queryCount(sql, params);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
export async function isExist(sql: string, params: any) {
|
||||
const count = await queryCount(sql, params);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
// 查询多条数据
|
||||
|
||||
function executeSQL<T>(sql: string, params: any) {
|
||||
@ -76,10 +82,12 @@ export async function execute(sql: string, params: any = null) {
|
||||
const ret = await executeSQL<{ affectedRows: number }>(sql, params)
|
||||
return ret.affectedRows
|
||||
}
|
||||
|
||||
export async function insertAndGetInsertId(tableName: string, data: any = null) {
|
||||
const ret = await executeSQL<{ insertId: number }>(`insert into \`${tableName}\` set ?`, data)
|
||||
return ret.insertId
|
||||
}
|
||||
|
||||
export default {
|
||||
selectArray,
|
||||
executeSQL,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { execute, selectArray, pool, queryCount } from './../src/service/mysql'
|
||||
import { execute, selectArray, pool, queryCount } from './../service/service/mysql'
|
||||
|
||||
// 使用execute执行更新数据
|
||||
describe('Database', () => {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {Test} from 'supertest';
|
||||
import { PORT } from './../config'
|
||||
import {PORT} from './../service/config'
|
||||
|
||||
const request = require("supertest");
|
||||
|
||||
// import { createServer } from './../src/core/server'
|
||||
|
@ -1,8 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* ESNext */
|
||||
"target": "ESNext",
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"module": "CommonJS",
|
||||
"module": "commonjs",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
|
@ -12,11 +12,12 @@ export default defineConfig(({mode}) => {
|
||||
'@/': '/front/'
|
||||
}
|
||||
},
|
||||
define: {
|
||||
buildVersion: JSON.stringify((new Date()).toLocaleString()),
|
||||
mode:JSON.stringify(mode),
|
||||
},
|
||||
// define: {
|
||||
// buildVersion: JSON.stringify((new Date()).toLocaleString()),
|
||||
// mode:JSON.stringify(mode),
|
||||
// },
|
||||
build: {
|
||||
outDir:'static',
|
||||
// 小于10kb直接base64
|
||||
assetsInlineLimit: 10240,
|
||||
rollupOptions: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user