Merge branch 'main' into Mobile
This commit is contained in:
commit
c0b015cbf1
2
auto-imports.d.ts
vendored
2
auto-imports.d.ts
vendored
@ -5,5 +5,7 @@
|
||||
// Generated by unplugin-auto-import
|
||||
export {}
|
||||
declare global {
|
||||
const ElMess: typeof import('element-plus/es')['ElMess']
|
||||
const ElMessaeg: typeof import('element-plus/es')['ElMessaeg']
|
||||
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
||||
}
|
||||
|
4
components.d.ts
vendored
4
components.d.ts
vendored
@ -7,7 +7,6 @@ export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
@ -17,16 +16,15 @@ declare module 'vue' {
|
||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
ElWatermark: typeof import('element-plus/es')['ElWatermark']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
VanButton: typeof import('vant/es')['Button']
|
||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanImage: typeof import('vant/es')['Image']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
|
25
package-lock.json
generated
25
package-lock.json
generated
@ -11,7 +11,8 @@
|
||||
"@types/crypto-js": "^4.2.1",
|
||||
"axios": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"element-plus": "^2.4.2",
|
||||
"echarts": "^5.4.3",
|
||||
"element-plus": "^2.4.3",
|
||||
"vant": "^4.7.3",
|
||||
"vue": "^3.3.4",
|
||||
"vue-router": "^4.2.5"
|
||||
@ -1590,6 +1591,15 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/echarts": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz",
|
||||
"integrity": "sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==",
|
||||
"dependencies": {
|
||||
"tslib": "2.3.0",
|
||||
"zrender": "5.4.4"
|
||||
}
|
||||
},
|
||||
"node_modules/element-plus": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.4.3.tgz",
|
||||
@ -2877,6 +2887,11 @@
|
||||
"typescript": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
|
||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz",
|
||||
@ -3297,6 +3312,14 @@
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/zrender": {
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz",
|
||||
"integrity": "sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==",
|
||||
"dependencies": {
|
||||
"tslib": "2.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,8 @@
|
||||
"@types/crypto-js": "^4.2.1",
|
||||
"axios": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"element-plus": "^2.4.2",
|
||||
"echarts": "^5.4.3",
|
||||
"element-plus": "^2.4.3",
|
||||
"vant": "^4.7.3",
|
||||
"vue": "^3.3.4",
|
||||
"vue-router": "^4.2.5"
|
||||
|
@ -11,7 +11,7 @@ const onInitOrResize = () => {
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
window.onresize = onInitOrResize;
|
||||
window.addEventListener("resize", onInitOrResize);
|
||||
onInitOrResize();
|
||||
})
|
||||
</script>
|
||||
|
@ -5,6 +5,8 @@ import {md5Hex} from "./CryptoUtils";
|
||||
import {User} from "../entities/User";
|
||||
import {Auth} from "../entities/Auth";
|
||||
import {File} from "../entities/File";
|
||||
import {SearchType} from "../entities/SearchType.ts";
|
||||
import {AccessInformation} from "../entities/AccessInformation.ts";
|
||||
|
||||
export const baseUrl = 'http://localhost:8081';
|
||||
|
||||
@ -26,7 +28,7 @@ const instance = axios.create({
|
||||
timeout: 1000,
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
});
|
||||
axios.interceptors.request.use(function (config) {
|
||||
instance.interceptors.request.use(function (config) {
|
||||
config.headers['Authorization'] = window.sessionStorage.getItem("authorization");
|
||||
return config;
|
||||
}, function (error) {
|
||||
@ -35,8 +37,8 @@ axios.interceptors.request.use(function (config) {
|
||||
});
|
||||
|
||||
// 添加响应拦截器
|
||||
axios.interceptors.response.use(function (response) {
|
||||
const authorization = response.headers['Set-Authorization'];
|
||||
instance.interceptors.response.use(function (response) {
|
||||
const authorization = response.headers['set-authorization'];
|
||||
if (authorization) {
|
||||
window.sessionStorage.setItem("authorization", authorization);
|
||||
}
|
||||
@ -44,12 +46,24 @@ axios.interceptors.response.use(function (response) {
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
/**
|
||||
* 登录接口
|
||||
* @param username 用户名
|
||||
* @param password 密码(未加密的)
|
||||
*/
|
||||
export const login = (username: string, password: string) => {
|
||||
return instance.post<Result<User>>("/api/user/login", {
|
||||
name: username,
|
||||
password: md5Hex(password)
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 注册接口
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @param auth 注册的权限(Auth.user或Auth.admin)
|
||||
* @param verifyCode 注册管理员所需的验证码(若注册的权限为Auth.user则无需填写)
|
||||
*/
|
||||
export const register = (username: string, password: string, auth: Auth, verifyCode?: string) => {
|
||||
return instance.post<Result<User>>("/api/user/register", {
|
||||
name: username,
|
||||
@ -58,13 +72,26 @@ export const register = (username: string, password: string, auth: Auth, verifyC
|
||||
verifyCode: verifyCode,
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取验证码(只能以管理员用户运行,后端会验签)
|
||||
*/
|
||||
export const generatorVerifyCode = () => {
|
||||
return instance.get<Result<string>>("/api/user/verifyCode")
|
||||
}
|
||||
|
||||
// 获取文件
|
||||
/**
|
||||
* 获取所有文件
|
||||
* @param page 页数
|
||||
* @param num 一页多少文件
|
||||
*/
|
||||
export const getAllFiles = (page: number, num: number) => {
|
||||
return instance.get<PageResult<File>>("/api/file/getAll", {params: {num, page}});
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
/**
|
||||
* 上传文件接口
|
||||
* @param options 上传选项(会在el-upload的http-request方法调用时传入)
|
||||
* @param controller 取消控制器(自己创建后传入)
|
||||
*/
|
||||
export const upload = (options: UploadRequestOptions, controller: AbortController) => {
|
||||
const param = new FormData();
|
||||
param.append("file", options.file);
|
||||
@ -81,4 +108,62 @@ export const upload = (options: UploadRequestOptions, controller: AbortControlle
|
||||
},
|
||||
signal: controller.signal
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取下载链接
|
||||
* @param id 文件id
|
||||
*/
|
||||
export const getLink = (id: number) => {
|
||||
return instance.get<Result<string>>("/api/file/link", {params: {id}});
|
||||
}
|
||||
/**
|
||||
* 删除文件
|
||||
* @param id 文件id
|
||||
*/
|
||||
export const remove = (id: number) => {
|
||||
return instance.post<Result<boolean>>("/api/file/remove", {id});
|
||||
}
|
||||
const handlerSearchType = (searchType: SearchType): string => {
|
||||
switch (searchType){
|
||||
case SearchType.ID:
|
||||
return "ID"
|
||||
case SearchType.TYPE:
|
||||
return "TYPE"
|
||||
case SearchType.UPLOAD_DAY:
|
||||
return "UPLOAD_DAY"
|
||||
case SearchType.UPLOADER:
|
||||
return "UPLOADER"
|
||||
default:
|
||||
return "FILE_NAME"
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 搜索
|
||||
* @param page 页数
|
||||
* @param num 一页多少文件
|
||||
* @param searchType 搜索类型
|
||||
* @param data 搜索数据
|
||||
*/
|
||||
export const search = (page: number, num: number, searchType: SearchType, data: string) => {
|
||||
return instance.get<PageResult<File>>("/api/file/search", {params: {page, num, type: handlerSearchType(searchType), data}});
|
||||
}
|
||||
/**
|
||||
* 获取访问情况
|
||||
* @param count 获取的天数
|
||||
*/
|
||||
export const getAccessInformation = (count: number) => {
|
||||
return instance.get<AccessInformation[]>("/api/access/get", {params: {count}});
|
||||
}
|
||||
/**
|
||||
* 获取总访问情况
|
||||
*/
|
||||
export const getTotalAccessInformation = () => {
|
||||
return instance.get<AccessInformation>("/api/access/getAll");
|
||||
}
|
||||
/**
|
||||
* 检查是否可以上传
|
||||
* @param filename 文件名
|
||||
*/
|
||||
export const checkUpload = (filename: string) => {
|
||||
return instance.get<Result<boolean>>("/api/file/checkUpload", {params: {filename}});
|
||||
}
|
17
src/entities/AccessInformation.ts
Normal file
17
src/entities/AccessInformation.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 访问情况类
|
||||
*/
|
||||
export interface AccessInformation {
|
||||
/**
|
||||
* 总下载量
|
||||
*/
|
||||
totalDownload: number;
|
||||
/**
|
||||
* 总访问量
|
||||
*/
|
||||
totalAccess: number;
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
date: string;
|
||||
}
|
@ -1,3 +1,13 @@
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
export enum Auth {
|
||||
user, admin
|
||||
/**
|
||||
* 普通用户
|
||||
*/
|
||||
USER,
|
||||
/**
|
||||
* 管理员
|
||||
*/
|
||||
ADMIN,
|
||||
}
|
@ -1,10 +1,37 @@
|
||||
/**
|
||||
* 文件类
|
||||
*/
|
||||
export interface File {
|
||||
/**
|
||||
* 下载数
|
||||
*/
|
||||
downloadCount: number;
|
||||
/**
|
||||
* 文件hash(sha512)
|
||||
*/
|
||||
hash: string;
|
||||
/**
|
||||
* 文件id
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 文件大小(字节为单位)
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* 上传时间
|
||||
*/
|
||||
uploadTime: string;
|
||||
/**
|
||||
* 上传者名称
|
||||
*/
|
||||
uploaderName: string;
|
||||
}
|
25
src/entities/SearchType.ts
Normal file
25
src/entities/SearchType.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 搜索类型
|
||||
*/
|
||||
export enum SearchType {
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
FILE_NAME,
|
||||
/**
|
||||
* 文件ID
|
||||
*/
|
||||
ID,
|
||||
/**
|
||||
* 上传者
|
||||
*/
|
||||
UPLOADER,
|
||||
/**
|
||||
* 上传日期
|
||||
*/
|
||||
UPLOAD_DAY,
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
TYPE
|
||||
}
|
@ -1,7 +1,19 @@
|
||||
import {Auth} from "./Auth";
|
||||
|
||||
/**
|
||||
* 用户类
|
||||
*/
|
||||
export interface User {
|
||||
id: string
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
auth: Auth;
|
||||
}
|
@ -3,6 +3,7 @@ import './style.css'
|
||||
import App from './App.vue'
|
||||
import Mobile from './views/AppMobile.vue'
|
||||
import PC from './views/AppPC.vue'
|
||||
import 'element-plus/dist/index.css';
|
||||
import {createRouter, createWebHashHistory} from "vue-router";
|
||||
|
||||
const router = createRouter({
|
||||
|
@ -120,6 +120,24 @@
|
||||
<h2>emm,咱就是说,这个分享站好像有点bug,这个东西好像展示不出来捏:<</h2>
|
||||
</div>
|
||||
</van-popup>
|
||||
<!-- 文件详情 -->
|
||||
<van-popup v-model:show="showFileInformation" round>
|
||||
<div class="file-information-popover" v-if="nowSelectedFileInformation">
|
||||
<h2>文件名称:<span>{{ nowSelectedFileInformation.name }}</span></h2>
|
||||
<div>
|
||||
<p>文件ID: <span>{{ nowSelectedFileInformation.id }}</span></p>
|
||||
<p>文件类型: <span>{{ nowSelectedFileInformation.type }}</span></p>
|
||||
<p>文件大小: <span>{{ parserByteSize(nowSelectedFileInformation.size) }}</span></p>
|
||||
<p title="点击复制"><a class="file-hash-a" @click="copyFullHash">文件校验值:
|
||||
<span>{{ shortHash(nowSelectedFileInformation.hash) }}</span></a></p>
|
||||
<p>文件上传者: <span>{{ nowSelectedFileInformation.uploaderName }}</span></p>
|
||||
<p>文件上传时间: <span>{{ nowSelectedFileInformation.uploadTime }}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="file-information-popover" v-else>
|
||||
<h2>emm,咱就是说,这个分享站好像有点bug,这个东西好像展示不出来捏:<</h2>
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
<div class="fileLiteBox">
|
||||
<el-table ref="fileListTable" :data="pageFileData" class="files-data-table" border stripe>
|
||||
@ -511,7 +529,6 @@ const handleUpload = (options: UploadRequestOptions): XMLHttpRequest | Promise<u
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
// TODO: 页面主题
|
||||
onBeforeMount(() => {
|
||||
initTheme();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,12 @@
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"auto-imports.d.ts"
|
||||
],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ export default defineConfig({
|
||||
}),
|
||||
Components({
|
||||
resolvers: [
|
||||
ElementPlusResolver(),
|
||||
ElementPlusResolver({
|
||||
importStyle: "css", // 确保样式也被自动导入
|
||||
}),
|
||||
VantResolver(),
|
||||
],
|
||||
}),
|
||||
|
Loading…
x
Reference in New Issue
Block a user