初始化项目

This commit is contained in:
wcq 2023-12-12 17:14:30 +08:00
parent b255ec0152
commit 511ea4f8ee
30 changed files with 3921 additions and 0 deletions

29
.gitignore vendored Normal file
View File

@ -0,0 +1,29 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
/frcb/

9
auto-imports.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
}

23
components.d.ts vendored Normal file
View File

@ -0,0 +1,23 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {}
declare module 'vue' {
export interface GlobalComponents {
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElInput: typeof import('element-plus/es')['ElInput']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElText: typeof import('element-plus/es')['ElText']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

1
env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

8
global.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
import Vue from 'vue';
declare global {
interface Window {
Vue: typeof Vue;
ElementPlus: any; // 如果 Element Plus 没有提供类型声明文件,可以使用 any
}
}

17
index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/logo.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件收集</title>
</head>
<body>
<link rel="stylesheet" type="text/css" href='https://unpkg.com/element-plus@2.4.2/dist/index.css'>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

37
package.json Normal file
View File

@ -0,0 +1,37 @@
{
"name": "kanban",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
},
"dependencies": {
"axios": "^1.6.2",
"element-plus": "^2.4.2",
"pinia": "^2.1.7",
"vue": "^3.3.4",
"vue-grid-layout": "3.0.0-beta1",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.18.5",
"@vitejs/plugin-vue": "^4.4.0",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"@vue/tsconfig": "^0.4.0",
"autoprefixer": "^10.4.16",
"npm-run-all2": "^6.1.1",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"typescript": "~5.2.0",
"unplugin-auto-import": "^0.16.7",
"unplugin-vue-components": "^0.25.2",
"vite": "^4.4.11",
"vite-plugin-cdn-import": "^0.3.5",
"vue-tsc": "^1.8.19"
}
}

3231
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

BIN
public/logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

11
src/App.vue Normal file
View File

@ -0,0 +1,11 @@
<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
</script>
<template>
<div style="height: 100vh;width: 100vw;">
<RouterView />
</div>
</template>
<style scoped></style>

1
src/assets/404.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

1
src/assets/4041.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.5 KiB

1
src/assets/4042.svg Normal file
View File

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" data-imageid="404-page-not-found-two-color-d285f" imageName="404 Page Not Found" class="illustrations_image" style="width: 163px;"><path d="M95.85,121.73c-27.66,4.91-47.21,29-44,55.43,1.71,14,8.64,26.43,26.47,30,47.3,9.51,225.85,45.31,260.93-16.72,27.35-48.34,11.05-81.81-14.35-102.76s-78-16.6-121.53-2.26C171,96.11,146.93,112.65,95.85,121.73Z" fill="#e6e6e6" opacity="0.3"/><ellipse cx="205.6" cy="245.02" rx="161.02" ry="11.9" fill="#e6e6e6" opacity="0.45"/><circle cx="115.32" cy="60.66" r="19.14" fill="#ffd200"/><circle cx="115.32" cy="60.66" r="36.49" fill="#ffd200" opacity="0.15"/><circle cx="195.69" cy="193.3" r="51.17" fill="#24285b"/><circle cx="195.69" cy="193.3" r="32.21" fill="#fff"/><path d="M133.91,205.51c3.39,0,4.61,1.22,4.61,4.6v5.83c0,3.39-1,4.61-4.61,4.61h-9.35V238.3c0,3.38-1.22,4.6-4.61,4.6h-6.64c-3.38,0-4.6-1.22-4.6-4.6V220.55H64c-3.38,0-4.6-1.22-4.6-4.61v-4.88A9,9,0,0,1,61,205.51l45-55.83a8.07,8.07,0,0,1,6.5-3.25H120c3.39,0,4.61.95,4.61,4.61v54.47Zm-25.2-36.32L79.3,205.51h29.41Z" fill="#68e1fd" class="target-color"/><path d="M327.42,205.51c3.39,0,4.61,1.22,4.61,4.6v5.83c0,3.39-.95,4.61-4.61,4.61h-9.35V238.3c0,3.38-1.22,4.6-4.61,4.6h-6.64c-3.38,0-4.6-1.22-4.6-4.6V220.55H257.5c-3.38,0-4.6-1.22-4.6-4.61v-4.88a9,9,0,0,1,1.62-5.55l45-55.83a8.07,8.07,0,0,1,6.5-3.25h7.45c3.39,0,4.61.95,4.61,4.61v54.47Zm-25.2-36.32-29.41,36.32h29.41Z" fill="#68e1fd" class="target-color"/><path d="M307.35,135.53s-8.51-2.32-10.36-10.25c0,0,13.19-2.66,13.57,10.95Z" fill="#68e1fd" opacity="0.58" class="target-color"/><path d="M308.4,134.69s-5.95-9.41-.72-18.2c0,0,10,6.37,5.58,18.22Z" fill="#68e1fd" opacity="0.73" class="target-color"/><path d="M309.93,134.7s3.14-9.94,12.65-11.82c0,0,1.78,6.45-6.16,11.84Z" fill="#68e1fd" class="target-color"/><polygon points="303.76 134.47 305.48 146.28 316.35 146.33 317.95 134.53 303.76 134.47" fill="#24285b"/><path d="M201.88,126.11s1.4,6.75.79,11.43a3.46,3.46,0,0,1-3.91,3c-2.35-.34-5.43-1.48-6.62-5l-2.76-5.75a6.21,6.21,0,0,1,1.93-6.9C194.85,119.63,201.23,122,201.88,126.11Z" fill="#f4a28c"/><polygon points="189.88 130.8 188.98 153.41 201.47 153.01 197.11 136.72 189.88 130.8" fill="#f4a28c"/><path d="M200.21,126.59a27.36,27.36,0,0,1-6.37.27,5.76,5.76,0,0,1,.74,6.27,4.68,4.68,0,0,1-5.4,2.52l-.93-8.82a7,7,0,0,1,2.8-6.64,24.34,24.34,0,0,1,2.77-1.79c2.41-1.32,6.32-.07,8.39-2.05a1.67,1.67,0,0,1,2.75.78c.72,2.63.74,6.9-2.71,8.79A6.36,6.36,0,0,1,200.21,126.59Z" fill="#24285b"/><path d="M195.29,132.84s-.36-2.64-2.32-2.2-1.46,4.25,1.28,4.28Z" fill="#f4a28c"/><path d="M202.54,130.41l2.23,2.41a1.11,1.11,0,0,1-.49,1.81l-2.56.8Z" fill="#f4a28c"/><path d="M198.22,140.25a8.24,8.24,0,0,1-4.3-1.92s.66,4.09,5.66,7.61Z" fill="#ce8172" opacity="0.31"/><path d="M189,153.41l12.49-.4s19.62-3.33,26.43,12.67S226,204.29,226,204.29,218.9,228.16,189,225.52c0,0-24.87-1.44-27.68-35.53a33.25,33.25,0,0,0-.68-4.42C159.5,180.24,158.84,164.07,189,153.41Z" fill="#68e1fd" class="target-color"/><path d="M172.27,174.65s6.66.73,15.91,16.22,27.41,9.81,37.65-1.65l-19,25.14-21.28-1.71-11.57-30.8Z" opacity="0.08"/><rect x="242.24" y="139" width="3.69" height="10.74" transform="translate(-16.97 33.59) rotate(-7.61)" fill="#ffd200"/><rect x="242.24" y="139" width="3.69" height="10.74" transform="translate(-16.97 33.59) rotate(-7.61)" opacity="0.08"/><rect x="242.52" y="146.67" width="5.67" height="13.79" transform="translate(-18.17 33.84) rotate(-7.61)" fill="#24285b"/><path d="M240,116.77a12.1,12.1,0,1,0,13.6,10.39A12.1,12.1,0,0,0,240,116.77Zm2.74,20.46a8.55,8.55,0,1,1,7.33-9.6A8.56,8.56,0,0,1,242.78,137.23Z" fill="#ffd200"/><circle cx="241.67" cy="128.8" r="8.59" fill="#fff"/><path d="M161,176.33a6.18,6.18,0,0,1,11.25-1.68,141.62,141.62,0,0,1,12,24.39c7.15,19.06,42.21,6.49,55.15-37.95l7.38,4.59s-10.18,57.72-51.16,59.84c0,0-25.58,5.18-33.35-26.21,0,0-2-5.91-2.12-9.25l-.54-3.76a31.69,31.69,0,0,1,1.32-9.87Z" fill="#68e1fd" class="target-color"/><path d="M161,176.33a6.18,6.18,0,0,1,11.25-1.68,141.62,141.62,0,0,1,12,24.39c7.15,19.06,42.21,6.49,55.15-37.95l7.38,4.59s-10.18,57.72-51.16,59.84c0,0-25.58,5.18-33.35-26.21,0,0-2-5.91-2.12-9.25l-.54-3.76a31.69,31.69,0,0,1,1.32-9.87Z" fill="#fff" opacity="0.39"/><path d="M241.27,162.21s.75-9.51,4.67-9.49,13.13,7.06-1.09,11.71Z" fill="#f4a28c"/><path d="M343.49,89.6a6.76,6.76,0,0,0-6.76-6.76,6.59,6.59,0,0,0-1.09.09,9.1,9.1,0,0,0-8-4.8l-.33,0a10.82,10.82,0,1,0-21,0l-.33,0a9.12,9.12,0,1,0,0,18.23h31.63V96.3A6.77,6.77,0,0,0,343.49,89.6Z" fill="#e6e6e6"/><path d="M80.7,156.51a5.8,5.8,0,0,0-5.8-5.8,7,7,0,0,0-.93.08,7.81,7.81,0,0,0-6.89-4.11H66.8a9.28,9.28,0,1,0-18,0h-.28a7.82,7.82,0,1,0,0,15.63H75.65v-.05A5.81,5.81,0,0,0,80.7,156.51Z" fill="#e6e6e6"/></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

1
src/assets/4044.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.9 KiB

9
src/assets/logo2.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 112 KiB

3
src/assets/main.css Normal file
View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

27
src/assets/thelogo.svg Normal file
View File

@ -0,0 +1,27 @@
<svg data-v-0dd9719b="" version="1.0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="109" height="99.71706716519995" viewBox="0 0 200.000000 200.000000" preserveAspectRatio="xMidYMid meet"
color-interpolation-filters="sRGB" style="margin: auto;">
<g fill="#333" class="icon-text-wrapper icon-svg-group iconsvg"
transform="translate(91.58499908447266,66.81999778747559)">
<g class="iconsvg-imagesvg" transform="translate(0,0.8214645385742188)">
<g>
<rect fill="#333" fill-opacity="0" stroke-width="2" x="0" y="0" width="109" height="99.71706716519995"
class="image-rect"></rect>
<svg x="-45" y="-20" width="109" height="99.71706716519995"
class="image-svg-svg primary" style="overflow: visible;">
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0.007376670837402344 0.017479896545410156 109.63544464111328 99.98246765136719">
<g fill-rule="evenodd">
<path d="M46.12 21.84c-2.94-8.25-7.27-15.43-1.06-17.59C53.49 1.3 60.41-3 62.64 3.15c3 8.39 7.23 15.37 1.06 17.6L52.39 24.8c-10.91 3.9-8.55 23-5.62 31.19C54.16 76.67 23 87.73 15.59 67.14A16.58 16.58 0 0 1 25.61 46c3.09 0 23.98-14.41 20.51-24.16z"
fill="#104e70"></path>
<path d="M83.51 43C82 51 84.92 71.28 93.82 73c8.39 1.62 17 1.62 15.69 8-1.83 9.17-1.67 16.89-8 15.7-8.37-1.59-16.91-1.65-15.69-8l2.28-11.82c2.18-11.39-15.46-19.05-24-20.7A16.53 16.53 0 0 1 51 36.77C55.1 15.24 87.68 21.51 83.51 43z"
fill="#2491eb"></path>
<path d="M25.67 89.11c-6.16 7.08-10 13.8-14.81 9.58-7-6.13-13.74-9.91-9.57-14.79 4.8-5.62 9.76-14 14.8-9.58l9.08 7.9c8.74 7.57 24.23-3.87 29.9-10.44a16.58 16.58 0 0 1 23.38-1.65c16.57 14.44-5.21 39.37-21.72 25 2.5.04-23.48-14.74-31.06-6.02z"
fill="#85c4f5"></path>
</g>
</svg>
</svg> <!---->
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

25
src/common/api.ts Normal file
View File

@ -0,0 +1,25 @@
import axios from "axios";
import {ElMessage} from "element-plus";
export const api = axios.create({
// 公共配置
baseURL: "",
timeout: 15000
});
api.interceptors.request.use(
// 在发送请求之前做什么
config => {
return config;
}
);
function errorHandle(status: number) {
switch (status) {
case 401:
break;
default:
break;
}
}

26
src/main.ts Normal file
View File

@ -0,0 +1,26 @@
import './assets/main.css'
// TailwindCSS 引入位置一定要在引入 App.vue 前面
// 不然会导致 TailwindCSS 样式覆盖 ElementPlus 按钮的样式
import { createPinia } from 'pinia'
//@ts-ignore
import ElementPlus from "element-plus"
import App from './App.vue'
import router from './router'
import { createApp } from 'vue'
//@ts-ignore
import VueGridLayout from 'vue-grid-layout'
let app = createApp(App)
if (import.meta.env.DEV) {
//动态组件需要使用vue.esm-bundler编译器但cdn的vue是包含了编译器所以不需要
//@ts-ignore
const { createApp } = await import('vue/dist/vue.esm-bundler.js')
app = createApp(App)
}
app.use(createPinia())
app.use(ElementPlus)
app.use(router)
app.use(VueGridLayout)
app.mount('#app')
export { app }

23
src/router/index.ts Normal file
View File

@ -0,0 +1,23 @@
import { createRouter, createWebHistory,createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
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('../views/AboutView.vue')
}
]
})
export default router

12
src/stores/counter.ts Normal file
View File

@ -0,0 +1,12 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})

15
src/views/AboutView.vue Normal file
View File

@ -0,0 +1,15 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
display: flex;
align-items: center;
}
}
</style>

267
src/views/HomeView.vue Normal file
View File

@ -0,0 +1,267 @@
<template>
<div class="h-full">
<div v-if="checked && inited" class="h-full">
<div class="px-6 pt-0 pb-4 h-full">
<div class="relative h-full">
<el-tabs v-model="activePane" class="h-full flex flex-col">
<el-tab-pane label="文件接收" name="receive" class="h-full">
<div class="flex justify-center h-full">
<div class="card-form">
<h2 style="font-size: 1.2rem;font-weight: bold;color: #484848;" class="w-full text-center mt-4 mb-12">
{{ data.subject?.name+'文件收集' }}
</h2>
<div>
<span>接收主题</span>
<span>{{ data.subject?.name }}</span>
</div>
<div>
<span>公司名称</span>
<span>{{ data.sender_company }}</span>
</div>
<div>
<span>接收状态</span>
<span>
<el-text :type="{receiving:'primary',examining:'primary',finish:'success'}[data.subject?.state]">
{{ {receiving: '接收中', examining: '审核中', finish: '完成'}[data.subject?.state] }}
</el-text>
</span>
</div>
<div>
<span>上传进度</span>
<span>{{ progressInfo }}</span>
</div>
<el-divider style="margin-top:2rem;margin-bottom: 2rem "></el-divider>
<div class="flex">
<span class="h-fit">上传文件</span>
<div class="flex-1">
<div class="flex w-full max-h-[14rem]">
<div class="flex-1">
<el-table :data="data.files" border style="--el-table-header-bg-color: #f5f5f5;height: 100%;">
<el-table-column label="ID" prop="id" align="center"></el-table-column>
<el-table-column label="需求文件" align="center"
prop="receive_subject_file.name"></el-table-column>
<el-table-column label="状态" align="center">
<template #default="{row}">
{{ row.file_path ? '已上传' : '未上传' }}
</template>
</el-table-column>
<el-table-column label="上传文件" prop="name" align="center"></el-table-column>
<el-table-column label="上传时间" align="center" prop="upload_time">
<template #default="{row}">
{{ datetimeFormat(row.upload_time) }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template #default="{row}">
<div class="flex justify-center items-center">
<el-button size="small" type="success"
@click="()=>downFile(row.file_path,row.name)">上传
</el-button>
<el-button size="small" type="primary" :disabled="!row.file_path"
@click="()=>downFile(row.file_path,row.name)">下载
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="联系" name="concat">
联系
</el-tab-pane>
</el-tabs>
<div class="ml-auto flex gap-6 absolute top-3 right-0"
style="font-size: 0.8rem;opacity: 0.7;margin-right: 2rem">
<div>
<span class="font-bold mx-2">编号:</span><span>{{ data['id'] }}</span>
</div>
<div>
<span class="font-bold mx-2">创建时间:</span><span>{{ datetimeFormat(data['create_time']) }}</span>
</div>
</div>
</div>
</div>
</div>
<div v-else-if="authCode.urlCode && inited" class="flex justify-center items-center h-full">
<div class="flex flex-col justify-center items-center">
<div style="font-size: 1.75rem;font-weight: bold">
文件收集系统
</div>
<el-card class="code-card m-[6rem]">
<div style="padding-left:1rem ">
<div class="font-bold" style="margin-bottom: 3rem;margin-top: 1rem">请输入密码</div>
<el-input v-model="codeTemp" style="width: 8rem;margin-right: 2rem;"></el-input>
<el-button type="primary" @click="setCode">确定</el-button>
</div>
</el-card>
</div>
<div style="border: 1px solid #dadada;width: 1px;height: 100%" class="my-10"></div>
<div class="mx-4 flex-1 items-center">
<img class="m-auto" :src="codeCardBg">
</div>
</div>
<div v-else-if="inited" class="flex justify-center items-center h-full">
<div class="flex flex-col justify-center items-center">
<div style="font-size: 1.75rem;font-weight: bold" class="mx-16">
文件收集系统
</div>
<div class=" m-[6rem]" style=" color: #ff0000;
font-size: 1rem;">
错误的链接地址
</div>
</div>
<div style="border: 1px solid #dadada;width: 1px;height: 100%" class="my-10"></div>
<div class="mx-4 flex-1 items-center">
<img class="m-auto" :src="bg404">
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {useRoute, useRouter} from "vue-router";
import {computed, onBeforeMount, onMounted, ref, watch} from "vue";
import {api} from "@/common/api";
import {dayjs, ElMessage} from "element-plus";
import codeCardBg from "@/assets/code-card-bg.svg"
import bg404 from "@/assets/4041.svg"
const route = useRoute()
const router = useRouter()
const data = ref({subject: {}, files: []})
const codeTemp = ref('')
const inited = ref(false)
const activePane = ref<'receive' | 'concat'>('receive')
const checked = ref(false)
const authCode = ref({urlCode: '', code: ''})
watch(() => route.fullPath, () => {
window.location.reload()
})
onBeforeMount(() => {
const query = route.query
if (query && query.u) {
authCode.value.urlCode = query.u as string
const code = localStorage.getItem(query.u as string)
if (code) {
authCode.value.code = code
checkCode()
} else {
inited.value = true
}
} else {
inited.value = true
}
})
const header = computed<any>(() => {
return {
urlcode: authCode.value.urlCode,
code: authCode.value.code
}
})
function setCode() {
authCode.value.code = codeTemp.value
checkCode()
}
function checkCode() {
return new Promise((resolve, reject) => {
api.post('/file-receive/receive_client/check', {}, {
headers: header.value
}).then(res => {
localStorage.setItem(authCode.value.urlCode, authCode.value.code)
checked.value = true
getData()
resolve({state: true, msg: ''})
}).catch(e => {
checked.value = false
authCode.value.code = ''
ElMessage.warning('错误的链接或密码')
localStorage.removeItem(authCode.value.urlCode)
resolve({state: false, msg: '错误的链接或密码'})
})
})
}
const progressInfo = computed(() => {
const count = data.value?.files?.length
const finished = data.value?.files?.filter(item => item.file_path).length
return `${finished}/${count}`
})
function getData() {
api.post('/file-receive/receive_client/receive_order/get', {}, {
headers: header.value
}).then(res => {
data.value = res.data
inited.value = true
}).catch(e => {
if (e.response.status == 403) {
ElMessage.warning('访问错误,请输入正确的链接或密码')
checked.value = false
authCode.value.code = ''
localStorage.removeItem(authCode.value.urlCode)
}
inited.value = true
})
}
function datetimeFormat(datetime) {
return datetime ? dayjs(datetime).format("YYYY/MM/DD HH:mm") : datetime
}
</script>
<style>
.code-card {
width: 18rem !important;
height: 12rem !important;
border-radius: 1rem !important;
background: #ffffff !important;
border: 1px solid #b5b5ff !important;
box-shadow: 2px 2px 5px 2px #9b9b9b57 !important;
}
.card-form {
border: 1px solid rgba(144, 168, 255, 0.53);
box-shadow: 4px 3px 7px 0px #bebebe61;
padding: 1rem 3rem;
margin: 0.5rem;
border-radius: 0.5rem;
color: #4d4d4d;
min-width: 50rem;
font-size: 0.9rem;
background: white;
}
.card-form > div {
margin: 1rem 0;
font-size: 0.8rem;
}
.card-form > div > :first-child {
display: inline-block;
background: #7986d5;
border-radius: 0.15rem;
color: aliceblue;
padding: 0.2rem 0.5rem;
margin-right: 1rem;
}
.card-form > div > span:nth-child(2) {
font-weight: bold;
color: #535456;
}
.el-tabs__content {
flex: 1;
}
</style>

11
tailwind.config.js Normal file
View File

@ -0,0 +1,11 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}

12
tsconfig.app.json Normal file
View File

@ -0,0 +1,12 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}

16
tsconfig.json Normal file
View File

@ -0,0 +1,16 @@
{
"files": [],
"compilerOptions": {
"types": [
"element-plus/global"
]
},
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}

16
tsconfig.node.json Normal file
View File

@ -0,0 +1,16 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*"
],
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}

82
vite.config.ts Normal file
View File

@ -0,0 +1,82 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { autoComplete, Plugin as importToCDN } from "vite-plugin-cdn-import";
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
importToCDN({
// prodUrl: 'https://cdn.jsdelivr.net/npm/{name}@{version}/{path}',
modules: [
{
name: 'vue',
var: 'Vue',
path: `https://unpkg.com/vue@3.3.4/dist/vue.global.prod.js`,
},
{
name: 'vue-demi',
var: 'VueDemi',
path: `https://unpkg.com/vue-demi@0.14.6`,
},
{
name: 'vue-router',
var: 'VueRouter',
path: `https://unpkg.com/vue-router@4.2.5/dist/vue-router.global.prod.js`,
},
{
name: 'element-plus',
var: 'ElementPlus',
path: 'https://unpkg.com/element-plus@2.4.2/dist/index.full.min.js',
// css: 'https://unpkg.com/element-plus@2.4.2/dist/index.css'
},
// {
// name: 'echarts',
// var: 'Echarts',
// path: 'https://unpkg.com/echarts@5.4.3/dist/echarts.min.js',
// },
// {
// name: 'vue-grid-layout',
// var: 'VueGridLayout',
// path: 'https://unpkg.com/vue-grid-layout@3.0.0-beta1/dist/vue-grid-layout.umd.min.js',
// },
],
}),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
build:{
outDir:"frcb"
},
base:"/frcb/",
server: {
// 是否开启 https
https: false,
// 端口号
host: "0.0.0.0",
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {
"/file-receive/": {
target: "http://127.0.0.1:8041",
// target: "http://122.9.155.209",
changeOrigin: true
}
}
},
})