feat: first commit
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@@ -0,0 +1,16 @@
|
||||
# Vue 3 + TypeScript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
||||
|
||||
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
||||
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
// Generated by 'unplugin-auto-import'
|
||||
// We suggest you to commit this file into source control
|
||||
declare global {
|
||||
|
||||
}
|
||||
export {}
|
||||
Vendored
+39
@@ -0,0 +1,39 @@
|
||||
// generated by unplugin-vue-components
|
||||
// We suggest you to commit this file into source control
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
import '@vue/runtime-core'
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
Angle: typeof import('./src/components/Angle.vue')['default']
|
||||
Autoresponsive: typeof import('./src/components/autoresponsive.vue')['default']
|
||||
CalcRectDock: typeof import('./src/components/CalcRectDock.vue')['default']
|
||||
CodeMirror: typeof import('./src/components/CodeMirror.vue')['default']
|
||||
CountDownMessage: typeof import('./src/components/CountDownMessage.vue')['default']
|
||||
DynamicTags: typeof import('./src/components/DynamicTags.vue')['default']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElLink: typeof import('element-plus/es')['ElLink']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ImgPreview: typeof import('./src/components/ImgPreview.vue')['default']
|
||||
Layout: typeof import('./src/components/Layout.vue')['default']
|
||||
ObjectRect: typeof import('./src/components/ObjectRect.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SingleUpload: typeof import('./src/components/SingleUpload.vue')['default']
|
||||
SystemLayout: typeof import('./src/components/SystemLayout.vue')['default']
|
||||
SystemMenu: typeof import('./src/components/SystemMenu.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>‎</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Generated
+3459
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "funjia-admin",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "vite --port=4444",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port=4444"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-javascript": "^6.1.7",
|
||||
"@kousum/vue3-window": "^0.0.3",
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/js-cookie": "^3.0.1",
|
||||
"autoresponsive-vue3": "^2.0.4",
|
||||
"axios": "^0.26.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"dayjs": "^1.10.7",
|
||||
"element-plus": "2.1.10",
|
||||
"funjialib": "git+http://git.funjia.top/funjia/FunJiaLib_Package.git",
|
||||
"funjiaui": "git+http://git.funjia.top/funjia/FunjiaUI_Vue.git#v1.1.2",
|
||||
"funjia-axios": "git+http://git.funjia.top/funjia/funjia-axios.git",
|
||||
"html-print-element": "^0.0.5",
|
||||
"html2pdf.js": "^0.10.2",
|
||||
"js-cookie": "^3.0.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"md5": "^2.3.0",
|
||||
"pinia": "2.0.13",
|
||||
"printd": "^1.6.0",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"vue": "3.2.33",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
"vue-cropperjs": "^5.0.0",
|
||||
"vue-router": "^4.0.14",
|
||||
"vue3-dnd": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash-es": "^4.17.6",
|
||||
"@types/node": "^17.0.25",
|
||||
"@vitejs/plugin-vue": "^2.3.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"sass": "^1.50.1",
|
||||
"typescript": "^4.5.4",
|
||||
"unplugin-auto-import": "^0.7.1",
|
||||
"unplugin-element-plus": "^0.4.0",
|
||||
"unplugin-vue-components": "^0.19.3",
|
||||
"vite": "^2.9.5",
|
||||
"vue-tsc": "^0.34.7"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 21</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
|
||||
<g id="Group-21" transform="translate(77.000000, 73.000000)">
|
||||
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
|
||||
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
|
||||
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
|
||||
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
|
||||
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
|
||||
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
|
||||
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
|
||||
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
|
||||
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
|
||||
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
|
||||
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
|
||||
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
|
||||
</g>
|
||||
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
|
||||
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
|
||||
</g>
|
||||
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
|
||||
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
|
||||
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
|
||||
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
|
||||
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
|
||||
</g>
|
||||
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
|
||||
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
|
||||
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
</g>
|
||||
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
|
||||
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
|
||||
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
|
||||
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
|
||||
</g>
|
||||
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
|
||||
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
|
||||
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
|
||||
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
|
||||
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
|
||||
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
|
||||
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
@@ -0,0 +1,2 @@
|
||||
static/*
|
||||
config.yml
|
||||
@@ -0,0 +1,22 @@
|
||||
db: # 数据库配置
|
||||
db: &db E:\sourceCode\2025\funjia-admin-template-vue\server\db\db.json
|
||||
resourceDB: &resourceDB E:\sourceCode\2025\funjia-admin-template-vue\server\db\resourceDB.json
|
||||
backupDB: &backupDB E:\sourceCode\2025\funjia-admin-template-vue\server\db\backupDB.json
|
||||
logDB: &logDB E:\sourceCode\2025\funjia-admin-template-vue\server\db\logDB.json
|
||||
dbBak: # 数据库备份配置
|
||||
- #
|
||||
original: *db
|
||||
dest: F:/sourceCode/2022/compute-cms/bak/db
|
||||
category: db
|
||||
- #
|
||||
original: *resourceDB
|
||||
dest: F:/sourceCode/2022/compute-cms/bak/resourceDB
|
||||
category: resourceDB
|
||||
- #
|
||||
original: *backupDB
|
||||
dest: F:/sourceCode/2022/compute-cms/bak/backupDB
|
||||
category: backupDB
|
||||
- #
|
||||
original: *logDB
|
||||
dest: F:/sourceCode/2022/compute-cms/bak/logDB
|
||||
category: logDB
|
||||
@@ -0,0 +1,346 @@
|
||||
{
|
||||
"backupHistory": [
|
||||
{
|
||||
"name": "db20220701112510.json",
|
||||
"category": "db",
|
||||
"id": "cl51w799y00003cny7rm01lx4",
|
||||
"createTime": "2022-07-01T03:25:10.198Z",
|
||||
"status": "1,2"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112510.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w79f900033cnyd44c044t",
|
||||
"createTime": "2022-07-01T03:25:10.389Z",
|
||||
"status": "1,2"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112510.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w79ia00063cny0hty82gs",
|
||||
"createTime": "2022-07-01T03:25:10.499Z",
|
||||
"status": "1,2"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112510.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w79lc00093cny9oiz4tlh",
|
||||
"createTime": "2022-07-01T03:25:10.608Z",
|
||||
"status": "1,2"
|
||||
},
|
||||
{
|
||||
"name": "db20220701112520.json",
|
||||
"category": "db",
|
||||
"id": "cl51w7h1n000c3cnyhpfjbrpj",
|
||||
"createTime": "2022-07-01T03:25:20.267Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112520.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w7h4o000f3cnybldh5115",
|
||||
"createTime": "2022-07-01T03:25:20.376Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112520.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w7h7w000i3cnyafqk3p1o",
|
||||
"createTime": "2022-07-01T03:25:20.492Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112520.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w7haw000l3cny4nv48t44",
|
||||
"createTime": "2022-07-01T03:25:20.600Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220701112530.json",
|
||||
"category": "db",
|
||||
"id": "cl51w7oty000o3cny5v281zy3",
|
||||
"createTime": "2022-07-01T03:25:30.358Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112530.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w7owz000r3cnybuil0qm8",
|
||||
"createTime": "2022-07-01T03:25:30.467Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112530.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w7p0e000u3cnyg8r9by1q",
|
||||
"createTime": "2022-07-01T03:25:30.590Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112530.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w7p37000x3cny9be2eh4h",
|
||||
"createTime": "2022-07-01T03:25:30.691Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220701112540.json",
|
||||
"category": "db",
|
||||
"id": "cl51w7wlu00103cny65nw72bm",
|
||||
"createTime": "2022-07-01T03:25:40.434Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112540.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w7wom00133cnyg0nqc9w3",
|
||||
"createTime": "2022-07-01T03:25:40.534Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112540.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w7wrd00163cnydmnjcgw7",
|
||||
"createTime": "2022-07-01T03:25:40.633Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112540.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w7wuk00193cny8hwlcc89",
|
||||
"createTime": "2022-07-01T03:25:40.748Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220701112550.json",
|
||||
"category": "db",
|
||||
"id": "cl51w84dz001c3cnygo6oeal7",
|
||||
"createTime": "2022-07-01T03:25:50.519Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112550.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w84h0001f3cnyfahs5q4c",
|
||||
"createTime": "2022-07-01T03:25:50.628Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112550.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w84jm001i3cny2tpqcjjp",
|
||||
"createTime": "2022-07-01T03:25:50.722Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112550.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w84ml001l3cnygzl3hjod",
|
||||
"createTime": "2022-07-01T03:25:50.829Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220701112600.json",
|
||||
"category": "db",
|
||||
"id": "cl51w8c63001o3cnyfevk3kyp",
|
||||
"createTime": "2022-07-01T03:26:00.603Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112600.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w8c8m001r3cny9zryh2pe",
|
||||
"createTime": "2022-07-01T03:26:00.694Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112600.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w8cbo001u3cnya2bw2bsi",
|
||||
"createTime": "2022-07-01T03:26:00.804Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112600.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w8ce8001x3cny1cltcbdh",
|
||||
"createTime": "2022-07-01T03:26:00.896Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220701112610.json",
|
||||
"category": "db",
|
||||
"id": "cl51w8jxq00203cny392bhx57",
|
||||
"createTime": "2022-07-01T03:26:10.670Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112610.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w8k0n00233cny37f0cx5j",
|
||||
"createTime": "2022-07-01T03:26:10.775Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112610.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w8k3h00263cnydfiu8inf",
|
||||
"createTime": "2022-07-01T03:26:10.877Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112610.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w8k6n00293cny0j395r0p",
|
||||
"createTime": "2022-07-01T03:26:10.991Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220701112620.json",
|
||||
"category": "db",
|
||||
"id": "cl51w8rq0002c3cny2tih0ehp",
|
||||
"createTime": "2022-07-01T03:26:20.760Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220701112620.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl51w8rv2002f3cnyddcya1y9",
|
||||
"createTime": "2022-07-01T03:26:20.942Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220701112621.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl51w8rz2002i3cnyhsiihd6x",
|
||||
"createTime": "2022-07-01T03:26:21.086Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220701112621.json",
|
||||
"category": "logDB",
|
||||
"id": "cl51w8s5u002l3cny2o7m161c",
|
||||
"createTime": "2022-07-01T03:26:21.330Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "F:\\sourceCode\\2022\\compute-cms\\db20220703182610.json",
|
||||
"category": "db",
|
||||
"id": "cl5564dxd0000sonyakfraso1",
|
||||
"createTime": "2022-07-03T10:26:10.945Z"
|
||||
},
|
||||
{
|
||||
"name": "db20220703182700.json",
|
||||
"category": "db",
|
||||
"id": "cl5565fxt0000s0ny94tvajvl",
|
||||
"createTime": "2022-07-03T10:27:00.209Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220703182700.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl5565g3o0003s0nyhl4m51nu",
|
||||
"createTime": "2022-07-03T10:27:00.420Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220703182700.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl5565g7t0006s0ny2juo1ve3",
|
||||
"createTime": "2022-07-03T10:27:00.570Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220703182700.json",
|
||||
"category": "logDB",
|
||||
"id": "cl5565gas0009s0nyfyi71i0a",
|
||||
"createTime": "2022-07-03T10:27:00.676Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220703182710.json",
|
||||
"category": "db",
|
||||
"id": "cl5565npe000cs0ny4jmk13uj",
|
||||
"createTime": "2022-07-03T10:27:10.274Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220703182710.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl5565num000fs0nyfuynhsvn",
|
||||
"createTime": "2022-07-03T10:27:10.462Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220703182710.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl5565nxt000is0nyfaw54i99",
|
||||
"createTime": "2022-07-03T10:27:10.578Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220703182710.json",
|
||||
"category": "logDB",
|
||||
"id": "cl5565o0q000ls0ny49na7htm",
|
||||
"createTime": "2022-07-03T10:27:10.682Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220703182720.json",
|
||||
"category": "db",
|
||||
"id": "cl5565vh5000os0ny8q5l2dhe",
|
||||
"createTime": "2022-07-03T10:27:20.346Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220703182720.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl5565vlh000rs0ny6nvm1t28",
|
||||
"createTime": "2022-07-03T10:27:20.501Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220703182720.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl5565vpg000us0nyhchjafdx",
|
||||
"createTime": "2022-07-03T10:27:20.644Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220703182720.json",
|
||||
"category": "logDB",
|
||||
"id": "cl5565vs9000xs0nybt568rnh",
|
||||
"createTime": "2022-07-03T10:27:20.745Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "db20220703182730.json",
|
||||
"category": "db",
|
||||
"id": "cl556638l0010s0ny42h7beca",
|
||||
"createTime": "2022-07-03T10:27:30.405Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "resourceDB20220703182730.json",
|
||||
"category": "resourceDB",
|
||||
"id": "cl55663c00013s0nyefkb8ozn",
|
||||
"createTime": "2022-07-03T10:27:30.528Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "backupDB20220703182730.json",
|
||||
"category": "backupDB",
|
||||
"id": "cl55663f50016s0nyhmal0v7o",
|
||||
"createTime": "2022-07-03T10:27:30.641Z",
|
||||
"status": "1"
|
||||
},
|
||||
{
|
||||
"name": "logDB20220703182730.json",
|
||||
"category": "logDB",
|
||||
"id": "cl55663i50019s0nydmqjhwqr",
|
||||
"createTime": "2022-07-03T10:27:30.749Z",
|
||||
"status": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
+21146
File diff suppressed because one or more lines are too long
+72195
File diff suppressed because one or more lines are too long
@@ -0,0 +1,190 @@
|
||||
{
|
||||
"img": [
|
||||
{
|
||||
"id": "cl4u5pghi0001wgny53o32aq4",
|
||||
"filename": "cl4u5pgh40000wgnya0lp59uc.jpg",
|
||||
"path": "static\\cl4u5pgh40000wgnya0lp59uc.jpg",
|
||||
"createTime": "2022-06-25T17:29:06.486Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4u68rlb0001qcnygmv39izm",
|
||||
"filename": "cl4u68rl60000qcny6npk19d3.jpg",
|
||||
"path": "static\\cl4u68rl60000qcny6npk19d3.jpg",
|
||||
"createTime": "2022-06-25T17:44:07.343Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4u692vx0003qcnyaiip9dnn",
|
||||
"filename": "cl4u692vq0002qcny9bmj3q30.jpg",
|
||||
"path": "static\\cl4u692vq0002qcny9bmj3q30.jpg",
|
||||
"createTime": "2022-06-25T17:44:21.981Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4u6agif0005qcny0kd1659n",
|
||||
"filename": "cl4u6agib0004qcnyexnb9xzz.jpg",
|
||||
"path": "static\\cl4u6agib0004qcnyexnb9xzz.jpg",
|
||||
"createTime": "2022-06-25T17:45:26.295Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4u6ls550001ucnyhy6ghpwy",
|
||||
"filename": "cl4u6ls4r0000ucny86k414pr.jpg",
|
||||
"path": "static\\cl4u6ls4r0000ucny86k414pr.jpg",
|
||||
"createTime": "2022-06-25T17:54:14.585Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4u6mmog0003ucnyato6b8qd",
|
||||
"filename": "cl4u6mmoc0002ucny0eaa8t7f.jpg",
|
||||
"path": "static\\cl4u6mmoc0002ucny0eaa8t7f.jpg",
|
||||
"createTime": "2022-06-25T17:54:54.160Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4u7huus0001x4nyalm386vp",
|
||||
"filename": "cl4u7huui0000x4ny1rd095z4.jpg",
|
||||
"path": "static\\cl4u7huui0000x4ny1rd095z4.jpg",
|
||||
"createTime": "2022-06-25T18:19:11.092Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4u7jyqy0003x4nyaa2mhk1a",
|
||||
"filename": "cl4u7jyqv0002x4ny27cb0zyt.jpg",
|
||||
"path": "static\\cl4u7jyqv0002x4ny27cb0zyt.jpg",
|
||||
"createTime": "2022-06-25T18:20:49.450Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4uycgv80005x4nycnn4ahui",
|
||||
"filename": "cl4uycgv30004x4ny4k9a0987.jpg",
|
||||
"path": "static\\cl4uycgv30004x4ny4k9a0987.jpg",
|
||||
"createTime": "2022-06-26T06:50:49.316Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0kl5h000rx4nydmi0gnhl",
|
||||
"filename": "cl4v0kl59000qx4ny0xsx9j2n.jpg",
|
||||
"path": "static\\cl4v0kl59000qx4ny0xsx9j2n.jpg",
|
||||
"createTime": "2022-06-26T07:53:07.349Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0lgm3000tx4ny7i4xdeq4",
|
||||
"filename": "cl4v0lglz000sx4ny17in7q6a.jpg",
|
||||
"path": "static\\cl4v0lglz000sx4ny17in7q6a.jpg",
|
||||
"createTime": "2022-06-26T07:53:48.123Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0m2wm000vx4nye3kl2794",
|
||||
"filename": "cl4v0m2wi000ux4nyhb7xaykl.jpg",
|
||||
"path": "static\\cl4v0m2wi000ux4nyhb7xaykl.jpg",
|
||||
"createTime": "2022-06-26T07:54:17.014Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0mdjv000xx4nycqqngyjr",
|
||||
"filename": "cl4v0mdjl000wx4ny6d4acii7.jpg",
|
||||
"path": "static\\cl4v0mdjl000wx4ny6d4acii7.jpg",
|
||||
"createTime": "2022-06-26T07:54:30.811Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0mzlq000zx4ny37649xm3",
|
||||
"filename": "cl4v0mzlm000yx4nyhjcwdmwb.jpg",
|
||||
"path": "static\\cl4v0mzlm000yx4nyhjcwdmwb.jpg",
|
||||
"createTime": "2022-06-26T07:54:59.390Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0nf8t0011x4ny3vgb0njg",
|
||||
"filename": "cl4v0nf8p0010x4ny1q8o96bb.jpg",
|
||||
"path": "static\\cl4v0nf8p0010x4ny1q8o96bb.jpg",
|
||||
"createTime": "2022-06-26T07:55:19.661Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0q7mv0013x4nybkoy3z9b",
|
||||
"filename": "cl4v0q7ms0012x4ny29i1hy0d.jpg",
|
||||
"path": "static\\cl4v0q7ms0012x4ny29i1hy0d.jpg",
|
||||
"createTime": "2022-06-26T07:57:29.767Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0qaxk0015x4nyc61xhnsk",
|
||||
"filename": "cl4v0qaxi0014x4nyd02n1y0s.jpg",
|
||||
"path": "static\\cl4v0qaxi0014x4nyd02n1y0s.jpg",
|
||||
"createTime": "2022-06-26T07:57:34.040Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0qrtf0017x4ny1y0t0wam",
|
||||
"filename": "cl4v0qrtc0016x4ny1bxh12e8.jpg",
|
||||
"path": "static\\cl4v0qrtc0016x4ny1bxh12e8.jpg",
|
||||
"createTime": "2022-06-26T07:57:55.923Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0s7m10019x4ny5zta50b4",
|
||||
"filename": "cl4v0s7lv0018x4nybu4u9qrp.jpg",
|
||||
"path": "static\\cl4v0s7lv0018x4nybu4u9qrp.jpg",
|
||||
"createTime": "2022-06-26T07:59:03.049Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v0uvxk001bx4ny2qe0c22r",
|
||||
"filename": "cl4v0uvxi001ax4ny0itgd8j9.jpg",
|
||||
"path": "static\\cl4v0uvxi001ax4ny0itgd8j9.jpg",
|
||||
"createTime": "2022-06-26T08:01:07.880Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v18kp9001dx4nya6yhb8yy",
|
||||
"filename": "cl4v18kp6001cx4nyg3xoh7kn.jpg",
|
||||
"path": "static\\cl4v18kp6001cx4nyg3xoh7kn.jpg",
|
||||
"createTime": "2022-06-26T08:11:46.509Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v18mxi001fx4nyc6h2fozb",
|
||||
"filename": "cl4v18mxe001ex4ny8147ehkt.jpg",
|
||||
"path": "static\\cl4v18mxe001ex4ny8147ehkt.jpg",
|
||||
"createTime": "2022-06-26T08:11:49.398Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4v18pi9001hx4ny7idea4m5",
|
||||
"filename": "cl4v18pi3001gx4nyazt40dus.jpg",
|
||||
"path": "static\\cl4v18pi3001gx4nyazt40dus.jpg",
|
||||
"createTime": "2022-06-26T08:11:52.737Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4wq1ywm0001a0ny38cmcwa2",
|
||||
"filename": "cl4wq1ywc0000a0ny2y25e0fa.jpg",
|
||||
"path": "static\\cl4wq1ywc0000a0ny2y25e0fa.jpg",
|
||||
"createTime": "2022-06-27T12:34:14.902Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4wq21w30003a0ny9xpd62rv",
|
||||
"filename": "cl4wq21vu0002a0ny07359nx6.jpg",
|
||||
"path": "static\\cl4wq21vu0002a0ny07359nx6.jpg",
|
||||
"createTime": "2022-06-27T12:34:18.771Z"
|
||||
},
|
||||
{
|
||||
"id": "cl4wq28rv0005a0nycf7k2a34",
|
||||
"filename": "cl4wq28rt0004a0ny5nj4gbe2.jpg",
|
||||
"path": "static\\cl4wq28rt0004a0ny5nj4gbe2.jpg",
|
||||
"createTime": "2022-06-27T12:34:27.691Z"
|
||||
},
|
||||
{
|
||||
"id": "cl550ghgz0009lsnycaace5r1",
|
||||
"filename": "cl550ghgt0008lsnyc7jl7rhw.jpg",
|
||||
"path": "static\\cl550ghgt0008lsnyc7jl7rhw.jpg",
|
||||
"createTime": "2022-07-03T07:47:37.715Z"
|
||||
},
|
||||
{
|
||||
"id": "cl550gk3n000blsnybbxz3rru",
|
||||
"filename": "cl550gk3e000alsnyafhcc8b2.jpg",
|
||||
"path": "static\\cl550gk3e000alsnyafhcc8b2.jpg",
|
||||
"createTime": "2022-07-03T07:47:41.123Z"
|
||||
},
|
||||
{
|
||||
"id": "cl550gmhr000dlsny9oxxex2y",
|
||||
"filename": "cl550gmhf000clsny2c4h5a33.jpg",
|
||||
"path": "static\\cl550gmhf000clsny2c4h5a33.jpg",
|
||||
"createTime": "2022-07-03T07:47:44.223Z"
|
||||
},
|
||||
{
|
||||
"id": "clzwtwwmp00029grb63lr3hcq",
|
||||
"filename": "clzwtwwml00019grbfbsf6r72.viminfo",
|
||||
"path": "static\\clzwtwwml00019grbfbsf6r72.viminfo",
|
||||
"createTime": "2024-08-16T14:53:09.553Z"
|
||||
},
|
||||
{
|
||||
"id": "clzwuyxln00049grb4ng91xik",
|
||||
"filename": "clzwuyxlf00039grb80upct14.yarnrc",
|
||||
"path": "static\\clzwuyxlf00039grb80upct14.yarnrc",
|
||||
"createTime": "2024-08-16T15:22:43.739Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import { CreateServer } from "funjia-server";
|
||||
const app = await CreateServer(4873);
|
||||
@@ -0,0 +1,230 @@
|
||||
// const.ts
|
||||
var accessTokenInfo = {
|
||||
"expires_in": 31536e3,
|
||||
"access_token": "24.e7f0cd92f73198efe99b8ccb4466f045.2592000.1744250279.282335-23610200",
|
||||
"session_secret": "",
|
||||
"session_key": "",
|
||||
"scope": "basic netdisk"
|
||||
};
|
||||
var getUrlParams = (params) => {
|
||||
const body = new URLSearchParams();
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
body.append(key, value);
|
||||
}
|
||||
return body;
|
||||
};
|
||||
var const_default = accessTokenInfo;
|
||||
|
||||
// cookieUtil.ts
|
||||
var CookieUtil = class _CookieUtil {
|
||||
// 静态属性,用于存储单例实例
|
||||
static instance = null;
|
||||
accessTokenInfo = {
|
||||
"expires_in": 31536e3,
|
||||
"access_token": "24.e7f0cd92f73198efe99b8ccb4466f045.2592000.1744250279.282335-23610200",
|
||||
"session_secret": "",
|
||||
"session_key": "",
|
||||
"scope": "basic netdisk",
|
||||
app_id: "250528",
|
||||
cookie: `BIDUPSID=B6F89C8A6AD149BCDC6FF40289C98EEA; PSTM=1719579347; PANWEB=1; Hm_lvt_7a3960b6f067eb0085b7f96ff5e660b0=1719583693,1719754941; BAIDUID=10DC30A9D8497854D8275A9855AA40A6:SL=0:NR=10:FG=1; H_WISE_SIDS_BFESS=60447_60575_60600; csrfToken=UG2bfMChS2_3SL_SPVH_hKvy; Hm_lvt_fa0277816200010a74ab7d2895df481b=1741096444; Hm_lpvt_fa0277816200010a74ab7d2895df481b=1741096444; HMACCOUNT=EDFC1163C2009122; H_PS_PSSID=61027_62277_62325_62336_62347_62372_62243_62390_62420_62423_62474_62484_62499_62493_62522_62457_62455_62453_62451_62568_62610; BDSFRCVID=EB-OJexroGWT0gjJdKLdMO_dgSNbUdrTDYrEjGc3VtzSGYLVd4SGEG0Pts1-dEub6j30ogKKLmOTHpKF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tRAOoC_-tDvDqTrP-trf5DCShUFsXTblB2Q-XPoO3M3xSlv4y4b8j4-kyhOk2M5f5mkf3fbgy4op8P3y0bb2DUA1y4vp-Jo7bmTxoUJ2-KDVeh5Gqq-KXU4ebPRiWPr9Qgbj_43Jtq4KO4bGQq5lDIuTXqO30ptJ06nhVn0MBCK0hD89DjKKD6PVKgTa54cbb4o2WbCQQnC28pcN2b5oQp-734RHBtJqBC74aPbwahQbeq06-lOUWJDkXpJvQnJjt2JxaqRCbtj1fq5jDh3MKToDb-oteltHB2Oy0hvcBn6cShnxjJJjDx7XylOt0ljPt-jr24bS3U8MEtbIe-t2XjQhDNL8q6_qJbCsQnj8HJoHjJbGq4bohjPkLmc9BtQO-DOx-M-M5bckehvsbMccBP0s0PTaL43HQgnkQq5_3b85S4bu0UJZXhKOjbbx0x-jLTneo66e345DMRFRD-nJyUPThtnnBnOi3H8HL4nv2JcJbM5m3x6qLTKkQN3T-PKO5bRu_CcJ-J8XMK8mjTjP; newlogin=1; Hm_lvt_182d6d59474cf78db37e0b2248640ea5=1742211139; H_WISE_SIDS=61027_62277_62325_62336_62347_62372_62243_62390_62420_62423_62474_62484_62499_62493_62522_62457_62455_62453_62451_62568_62610; BDUSS=HB1TDFqeGVLTWZhcURSM015WmJrVi1XaWdqbkdSUWVmaH5mc2daSzJIeG5aUUJvSVFBQUFBJCQAAAAAAAAAAAEAAAAmJicXaG5qaWFuYW4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGfY2Gdn2NhnZ; BDUSS_BFESS=HB1TDFqeGVLTWZhcURSM015WmJrVi1XaWdqbkdSUWVmaH5mc2daSzJIeG5aUUJvSVFBQUFBJCQAAAAAAAAAAAEAAAAmJicXaG5qaWFuYW4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGfY2Gdn2NhnZ; STOKEN=4b412d30af62a38ce1b769718dbf216cbd0ed032e38e2ab282aea36707e93a20; Hm_lvt_bc5920843408306f8b6fc088319384ce=1742264429; Hm_lpvt_bc5920843408306f8b6fc088319384ce=1742264434; BAIDUID_BFESS=10DC30A9D8497854D8275A9855AA40A6:SL=0:NR=10:FG=1; BDSFRCVID_BFESS=EB-OJexroGWT0gjJdKLdMO_dgSNbUdrTDYrEjGc3VtzSGYLVd4SGEG0Pts1-dEub6j30ogKKLmOTHpKF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF_BFESS=tRAOoC_-tDvDqTrP-trf5DCShUFsXTblB2Q-XPoO3M3xSlv4y4b8j4-kyhOk2M5f5mkf3fbgy4op8P3y0bb2DUA1y4vp-Jo7bmTxoUJ2-KDVeh5Gqq-KXU4ebPRiWPr9Qgbj_43Jtq4KO4bGQq5lDIuTXqO30ptJ06nhVn0MBCK0hD89DjKKD6PVKgTa54cbb4o2WbCQQnC28pcN2b5oQp-734RHBtJqBC74aPbwahQbeq06-lOUWJDkXpJvQnJjt2JxaqRCbtj1fq5jDh3MKToDb-oteltHB2Oy0hvcBn6cShnxjJJjDx7XylOt0ljPt-jr24bS3U8MEtbIe-t2XjQhDNL8q6_qJbCsQnj8HJoHjJbGq4bohjPkLmc9BtQO-DOx-M-M5bckehvsbMccBP0s0PTaL43HQgnkQq5_3b85S4bu0UJZXhKOjbbx0x-jLTneo66e345DMRFRD-nJyUPThtnnBnOi3H8HL4nv2JcJbM5m3x6qLTKkQN3T-PKO5bRu_CcJ-J8XMK8mjTjP; ndut_fmt=4AED84C3D5C763CC7467C0BD21B7059718FB121D7685531B0B05A7947CD6E542; ab_sr=1.0.1_MWQ5NTY4MTE4YTU1OTJiNmI0YmUxMDAzNWY1NTkyZjkzZGNkYzBjNDg2NWYxODdhNTM0Zjk4NDNlNzIwNmJhNWFjNTVmYzlhMjllZDQ1YzBhODZkMjFkZjNmODk1YWRkYjU4ZWI4OGQ5ZTY5Yzg1YjU0YTEyNzE4ZTZmZGYyOWYzZTYzZWYwYmFiODVhOWIwMWZjMjUyMDg1ZjExYWE0Y2QzNDU0MWY3MGRiOGQ0NDk2MjZlYWY3NDM2YmI4NmNlNzUxMmEzYjEyOWY5MDI5NDNkMmY4YWUxZDJkNDUwNGI=; PANPSC=12091468029218708382%3AAuI6D6iGxsvfqD2oGDJz%2FlcS2d9ns3O52KR9sgxqNvJDnBUTmlU39wjHRUw%2FZR6kz81ttRoL0tCAzpMjKfHvSrz7Cgwm46ULLjHyseP5LOc2jyb7JodIivKBB5%2BWSCTpbaC532AuNi3w0iRW66wpcaOpfVD7rGCOIND%2Ba86tsPJVcd75GMrlL3ggdH3Ht58%2BGZF3KerqQjL6l%2B17QGFqtw%3D%3D; Hm_lpvt_182d6d59474cf78db37e0b2248640ea5=1742385365`
|
||||
};
|
||||
constructor() {
|
||||
if (_CookieUtil.instance) {
|
||||
return _CookieUtil.instance;
|
||||
}
|
||||
_CookieUtil.instance = this;
|
||||
}
|
||||
// 静态方法,用于获取单例实例
|
||||
static getInstance() {
|
||||
if (!_CookieUtil.instance) {
|
||||
_CookieUtil.instance = new _CookieUtil();
|
||||
}
|
||||
return _CookieUtil.instance;
|
||||
}
|
||||
getHeaders = () => {
|
||||
return {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Host: "pan.baidu.com",
|
||||
Origin: "https://pan.baidu.com",
|
||||
Referer: "https://pan.baidu.com/disk/main",
|
||||
"User-Agent": " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-origin",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"sec-ch-ua": `"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"`,
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": "Windows",
|
||||
"Cookie": this.accessTokenInfo.cookie
|
||||
};
|
||||
};
|
||||
setCookie = ({ cookie: cookie2, accessToken }) => {
|
||||
this.accessTokenInfo.access_token = accessToken;
|
||||
this.accessTokenInfo.cookie = cookie2;
|
||||
};
|
||||
};
|
||||
|
||||
// getBdstoken.ts
|
||||
var url = `http://pan.baidu.com/api/gettemplatevariable?clienttype=0&app_id=250528&web=1&fields=[%22bdstoken%22]`;
|
||||
async function getInfo() {
|
||||
const cookieUtilInstance = CookieUtil.getInstance();
|
||||
const headers = cookieUtilInstance.getHeaders();
|
||||
const res = await fetch(url, { headers });
|
||||
const data = await res.json();
|
||||
return data?.result?.bdstoken;
|
||||
}
|
||||
|
||||
// getDpLogId.ts
|
||||
var DpLogIdUtil = class _DpLogIdUtil {
|
||||
// 静态属性,用于存储单例实例
|
||||
static instance = null;
|
||||
// 实例属性
|
||||
sessionId = 0;
|
||||
// 会话ID,用于标识当前会话
|
||||
userId = "";
|
||||
// 用户ID,用于标识用户
|
||||
_countId = 0;
|
||||
// 计数器ID,用于生成唯一的日志ID
|
||||
client = "";
|
||||
// 客户端标识
|
||||
// 私有化构造函数,防止外部直接实例化
|
||||
constructor() {
|
||||
if (_DpLogIdUtil.instance) {
|
||||
return _DpLogIdUtil.instance;
|
||||
}
|
||||
this.sessionId = this.getRandomInt(6);
|
||||
this.userId = "00" + this.getRandomInt(8);
|
||||
this._countId = 0;
|
||||
this.client = "";
|
||||
_DpLogIdUtil.instance = this;
|
||||
}
|
||||
// 静态方法,用于获取单例实例
|
||||
static getInstance() {
|
||||
if (!_DpLogIdUtil.instance) {
|
||||
_DpLogIdUtil.instance = new _DpLogIdUtil();
|
||||
}
|
||||
return _DpLogIdUtil.instance;
|
||||
}
|
||||
// 生成指定位数的随机整数
|
||||
getRandomInt = function(t) {
|
||||
return Math.floor((9 * Math.random() + 1) * Math.pow(10, t - 1));
|
||||
};
|
||||
// 将数字补足指定位数,不足部分用0填充
|
||||
prefixInteger = function(t, e) {
|
||||
t += "";
|
||||
for (var n = new Array(e - t.length), i = n.length, r = 0; r < i; r++)
|
||||
n[r] = "0";
|
||||
return n.join("") + t;
|
||||
};
|
||||
// 获取并递增计数器ID,确保ID在0到9999之间循环
|
||||
getCountId = function() {
|
||||
return this._countId < 9999 ? this._countId += 1 : this._countId = 0, this.prefixInteger(this._countId, 4);
|
||||
};
|
||||
// 验证用户ID是否为10位
|
||||
validateUk = function(t) {
|
||||
return 10 === (t + "").length;
|
||||
};
|
||||
// 生成完整的日志ID
|
||||
getDpLogId = function() {
|
||||
var e = this.userId;
|
||||
return "" + this.client + this.sessionId + e + this.getCountId();
|
||||
};
|
||||
// 从URL中提取日志ID,如果不存在则生成一个新的日志ID
|
||||
getDpLogIdByUrl = function(t) {
|
||||
var e = t.match(/dp-logid=(\d+)/);
|
||||
return e && e[1] ? e[1] : this.getDpLogId();
|
||||
};
|
||||
// 向URL中添加日志ID参数
|
||||
addDpLogId = function(t, e, n) {
|
||||
if (/dp-logid=\d+/.test(t))
|
||||
return t;
|
||||
var i = n || this.getDpLogId(e);
|
||||
return t += /\?/.test(t) ? "&" : "?", t + "dp-logid=" + i;
|
||||
};
|
||||
};
|
||||
|
||||
// queryMagnetinfo.ts
|
||||
var { access_token } = const_default;
|
||||
async function getMagnetInfo(link, savePath) {
|
||||
let bdstoken2 = await getInfo();
|
||||
let dpLogId2 = DpLogIdUtil.getInstance().getDpLogId();
|
||||
const url2 = `https://pan.baidu.com/rest/2.0/services/cloud_dl?clienttype=0&app_id=250528&web=1&dp-logid=${dpLogId2}&bdstoken=${bdstoken2}`;
|
||||
const cookieUtilInstance = CookieUtil.getInstance();
|
||||
const headers = cookieUtilInstance.getHeaders();
|
||||
const params = {
|
||||
method: "query_magnetinfo",
|
||||
app_id: 250528,
|
||||
save_path: savePath,
|
||||
type: 4,
|
||||
source_url: link
|
||||
};
|
||||
const res = await fetch(url2, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: getUrlParams(params)
|
||||
});
|
||||
const data = await res.json();
|
||||
return data?.total || 0;
|
||||
}
|
||||
|
||||
// offDown.ts
|
||||
var bdstoken = "";
|
||||
var dpLogId = "";
|
||||
var dpLogIdUtil = DpLogIdUtil.getInstance();
|
||||
function generateSelectedIdx(total) {
|
||||
return [...Array(total).keys()].map((i) => i + 1);
|
||||
}
|
||||
function getRandomNumberBetween(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
function randomDelay(min = 2e3, max = 4e3) {
|
||||
const delay = getRandomNumberBetween(min, max);
|
||||
console.log(`\u7B49\u5F85 ${delay} \u6BEB\u79D2...`);
|
||||
return sleep(delay);
|
||||
}
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
async function down(link, savePath = "/movie/2025") {
|
||||
const cookieUtilInstance = CookieUtil.getInstance();
|
||||
bdstoken = await getInfo();
|
||||
dpLogId = dpLogIdUtil?.getDpLogId();
|
||||
const url2 = `https://pan.baidu.com/rest/2.0/services/cloud_dl?clienttype=0&app_id=250528&web=1&dp-logid=${dpLogId}&bdstoken=${bdstoken}`;
|
||||
const headers = cookieUtilInstance.getHeaders();
|
||||
const fileTotal = await getMagnetInfo(link, savePath);
|
||||
randomDelay(2e3, 4e3);
|
||||
const params = {
|
||||
method: "add_task",
|
||||
app_id: 250528,
|
||||
save_path: savePath,
|
||||
selected_idx: generateSelectedIdx(fileTotal).join(","),
|
||||
task_from: 0,
|
||||
t: (/* @__PURE__ */ new Date()).getTime(),
|
||||
type: 4,
|
||||
source_url: link
|
||||
};
|
||||
console.log(params);
|
||||
try {
|
||||
const res = await fetch(url2, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: getUrlParams(params)
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
const data = await res.json();
|
||||
console.log(data);
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error("Fetch error:", error);
|
||||
}
|
||||
}
|
||||
var offDown_default = {
|
||||
down,
|
||||
CookieUtil,
|
||||
randomDelay
|
||||
};
|
||||
export {
|
||||
offDown_default as default
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "server",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@koa/multer": "^3.0.0",
|
||||
"@types/yaml": "^1.9.7",
|
||||
"cuid": "^2.1.8",
|
||||
"dayjs": "^1.11.3",
|
||||
"koa": "^2.13.4",
|
||||
"koa-body": "^4.2.0",
|
||||
"koa-mount": "^4.0.0",
|
||||
"koa-router": "^10.1.1",
|
||||
"koa-static": "^5.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lowdb": "^3.0.0",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"node-cron": "^3.0.1",
|
||||
"uuid": "^8.3.2",
|
||||
"yaml": "^2.1.1",
|
||||
"funjia-server":"git+http://git.funjia.top/funjia/funjia-server.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^6.0.7"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// import RouterFactor from "../RouterFactory.mjs";
|
||||
// import DBHelper from "../DBHelper.mjs";
|
||||
import {RouterFactor,DBHelper} from "funjia-server/lib/funjia-server.mjs";
|
||||
|
||||
const getDataLog = (router) => {
|
||||
const rF = new RouterFactor({
|
||||
router,
|
||||
db: DBHelper.logDB,
|
||||
name: "dataLog"
|
||||
});
|
||||
|
||||
rF.creaetBaseRouter();
|
||||
}
|
||||
|
||||
export default getDataLog;
|
||||
@@ -0,0 +1,173 @@
|
||||
import cuid from "cuid";
|
||||
// import getDb from "../dbServer.mjs";
|
||||
import _ from "lodash";
|
||||
|
||||
import { getDb } from "funjia-server/lib/funjia-server.mjs";
|
||||
const getEmployee = (router) => {
|
||||
|
||||
router.post('/api/employee/list', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const body = ctx.request.body;
|
||||
const data = db.data?.employee?.filter((item) => {
|
||||
let isMatch = true;
|
||||
for (let field in body) {
|
||||
if (["page", "pageSize"].includes(field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof (item[field]) == "string") {
|
||||
isMatch = item[field]?.indexOf?.(body[field]) > -1;
|
||||
} else if (typeof (item[field]) == "number") {
|
||||
isMatch = item[field] == body[field];
|
||||
}
|
||||
if (!isMatch)
|
||||
break;
|
||||
}
|
||||
return isMatch;
|
||||
});
|
||||
|
||||
const {
|
||||
page,
|
||||
pageSize
|
||||
} = body;
|
||||
let batchData = data;
|
||||
if (page && pageSize) {
|
||||
batchData = data.slice((page - 1) * pageSize, page * pageSize);
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: batchData || [],
|
||||
total: data.length
|
||||
};
|
||||
});
|
||||
|
||||
router.get('/api/employee', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const data = db.data.employee;
|
||||
const query = ctx.request.query;
|
||||
console.log("参数:", query, ctx.request.body, ctx.query);
|
||||
let detail = {};
|
||||
if (query.id && data) {
|
||||
detail = data.find((item) => {
|
||||
return item.id == query.id;
|
||||
});
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: detail || {}
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/employee/add', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data?.employee)
|
||||
db.data.employee = [];
|
||||
const {
|
||||
employee
|
||||
} = db.data;
|
||||
const data = ctx.request.body;
|
||||
console.log("add:", data);
|
||||
data.id = cuid();
|
||||
data.createTime = new Date();
|
||||
employee.push(data)
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/employee/upd', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data?.employee)
|
||||
db.data = {
|
||||
employee: []
|
||||
}
|
||||
const {
|
||||
employee
|
||||
} = db.data;
|
||||
const data = ctx.request.body;
|
||||
const id = data.id;
|
||||
console.log("数据Id:", id);
|
||||
if (id && employee) {
|
||||
const currentDetail = employee.find(item => item.id == id);
|
||||
if (currentDetail) {
|
||||
_.merge(currentDetail, data);
|
||||
}
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/employee/delete', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data?.employee)
|
||||
db.data = {
|
||||
employee: []
|
||||
}
|
||||
let {
|
||||
employee
|
||||
} = db.data;
|
||||
const data = ctx.request.body;
|
||||
const ids = data.ids;
|
||||
if (ids?.length > 0 && employee) {
|
||||
let id = null;
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
id = ids[i];
|
||||
const idx = employee.findIndex(item => item.id == id);
|
||||
if (idx != -1) {
|
||||
employee.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/employee/login', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const data = db.data.employee;
|
||||
const params = ctx.request.body;
|
||||
let detail = {};
|
||||
if (data) {
|
||||
detail = data.find((item) => {
|
||||
return item.userName == params.userName && item.pwd == params.pwd;
|
||||
});
|
||||
}
|
||||
|
||||
const code = detail ? 0 : 1;
|
||||
|
||||
ctx.body = {
|
||||
code,
|
||||
data: detail || {}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default getEmployee;
|
||||
@@ -0,0 +1,154 @@
|
||||
import cuid from "cuid";
|
||||
// import getDb from "../dbServer.mjs";
|
||||
import {getDb} from "funjia-server/lib/funjia-server.mjs";
|
||||
import _ from "lodash";
|
||||
|
||||
const getNotice = (router) => {
|
||||
|
||||
router.post('/api/Notice/list', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const body = ctx.request.body;
|
||||
const data = db.data?.Notice?.filter((item) => {
|
||||
let isMatch = true;
|
||||
for (let field in body) {
|
||||
if (["page", "pageSize"].includes(field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof (item[field]) == "string") {
|
||||
isMatch = item[field]?.indexOf?.(body[field]) > -1;
|
||||
} else if (typeof (item[field]) == "number") {
|
||||
isMatch = item[field] == body[field];
|
||||
}
|
||||
if (!isMatch)
|
||||
break;
|
||||
}
|
||||
return isMatch;
|
||||
});
|
||||
|
||||
const {
|
||||
page,
|
||||
pageSize
|
||||
} = body;
|
||||
let batchData = data;
|
||||
if (page && pageSize) {
|
||||
batchData = data.slice((page - 1) * pageSize, page * pageSize);
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: batchData.sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
}) || [],
|
||||
total: data.length
|
||||
};
|
||||
});
|
||||
|
||||
router.get('/api/Notice', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const data = db.data.Notice;
|
||||
const query = ctx.request.query;
|
||||
console.log("参数:", query, ctx.request.body, ctx.query);
|
||||
let detail = {};
|
||||
if (query.id && data) {
|
||||
detail = data.find((item) => {
|
||||
return item.id == query.id;
|
||||
});
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: detail || {}
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/Notice/add', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data?.Notice)
|
||||
db.data.Notice = [];
|
||||
const {
|
||||
Notice
|
||||
} = db.data;
|
||||
const data = ctx.request.body;
|
||||
console.log("add:", data);
|
||||
data.id = cuid();
|
||||
data.createTime = new Date();
|
||||
Notice.push(data)
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/Notice/upd', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data?.Notice)
|
||||
db.data = {
|
||||
Notice: []
|
||||
}
|
||||
const {
|
||||
Notice
|
||||
} = db.data;
|
||||
const data = ctx.request.body;
|
||||
const id = data.id;
|
||||
console.log("数据Id:", id);
|
||||
if (id && Notice) {
|
||||
const currentDetail = Notice.find(item => item.id == id);
|
||||
if (currentDetail) {
|
||||
_.merge(currentDetail, data);
|
||||
}
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/Notice/delete', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data?.Notice)
|
||||
db.data = {
|
||||
Notice: []
|
||||
}
|
||||
let {
|
||||
Notice
|
||||
} = db.data;
|
||||
const data = ctx.request.body;
|
||||
const ids = data.ids;
|
||||
if (ids?.length > 0 && Notice) {
|
||||
let id = null;
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
id = ids[i];
|
||||
const idx = Notice.findIndex(item => item.id == id);
|
||||
if (idx != -1) {
|
||||
Notice.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default getNotice;
|
||||
@@ -0,0 +1,16 @@
|
||||
// import RouterFactor from "../RouterFactory.mjs";
|
||||
// import DBHelper from "../DBHelper.mjs";
|
||||
import {RouterFactor,DBHelper} from "funjia-server/lib/funjia-server.mjs";
|
||||
|
||||
|
||||
const getQA = (router) => {
|
||||
const rF = new RouterFactor({
|
||||
router,
|
||||
db: DBHelper.baseDB,
|
||||
name: "qa"
|
||||
});
|
||||
|
||||
rF.creaetBaseRouter();
|
||||
}
|
||||
|
||||
export default getQA;
|
||||
@@ -0,0 +1,108 @@
|
||||
import _ from "lodash";
|
||||
// import RouterFactor from "../RouterFactory.mjs";
|
||||
// import DBHelper from "../DBHelper.mjs";
|
||||
import {RouterFactor,DBHelper} from "funjia-server/lib/funjia-server.mjs";
|
||||
|
||||
const getBackupHistory = (router) => {
|
||||
const rF = new RouterFactor({
|
||||
router,
|
||||
db: DBHelper.backupDB,
|
||||
name: "backupHistory"
|
||||
});
|
||||
|
||||
rF.createGetList();
|
||||
|
||||
rF.createGetDetail();
|
||||
|
||||
rF.createAdd();
|
||||
|
||||
rF.createUpdate();
|
||||
|
||||
rF.createDelete();
|
||||
|
||||
// router.post('/api/backupHistory/add', async (ctx) => {
|
||||
// ctx.type = 'application/json';
|
||||
// const db = await getBackupDb();
|
||||
|
||||
// // You can also use this syntax if you prefer
|
||||
// if (!db.data.backupHistory)
|
||||
// db.data.backupHistory = [];
|
||||
// const {
|
||||
// backupHistory
|
||||
// } = db.data;
|
||||
// const data = ctx.request.body;
|
||||
// console.log("add:", data);
|
||||
// data.id = cuid();
|
||||
// data.createTime = new Date();
|
||||
// backupHistory.push(data)
|
||||
// // Write db.data content to db.json
|
||||
// await db.write()
|
||||
|
||||
// ctx.body = {
|
||||
// code: 0,
|
||||
// };
|
||||
// });
|
||||
|
||||
// router.post('/api/backupHistory/upd', async (ctx) => {
|
||||
// ctx.type = 'application/json';
|
||||
// const db = await getBackupDb();
|
||||
|
||||
// // You can also use this syntax if you prefer
|
||||
// if (!db.data.backupHistory)
|
||||
// db.data = {
|
||||
// backupHistory: []
|
||||
// }
|
||||
// const {
|
||||
// backupHistory
|
||||
// } = db.data;
|
||||
// const data = ctx.request.body;
|
||||
// const id = data.id;
|
||||
// console.log("数据Id:", id);
|
||||
// if (id && backupHistory) {
|
||||
// const currentDetail = backupHistory.find(item => item.id == id);
|
||||
// if (currentDetail) {
|
||||
// _.merge(currentDetail, data);
|
||||
// }
|
||||
// // Write db.data content to db.json
|
||||
// await db.write()
|
||||
// }
|
||||
|
||||
// ctx.body = {
|
||||
// code: 0,
|
||||
// };
|
||||
// });
|
||||
|
||||
// router.post('/api/backupHistory/delete', async (ctx) => {
|
||||
// ctx.type = 'application/json';
|
||||
// const db = await getBackupDb();
|
||||
|
||||
// // You can also use this syntax if you prefer
|
||||
// if (!db.data.backupHistory)
|
||||
// db.data = {
|
||||
// backupHistory: []
|
||||
// }
|
||||
// let {
|
||||
// backupHistory
|
||||
// } = db.data;
|
||||
// const data = ctx.request.body;
|
||||
// const ids = data.ids;
|
||||
// if (ids.length > 0 && backupHistory) {
|
||||
// let id = null;
|
||||
// for (let i = 0; i < ids.length; i++) {
|
||||
// id = ids[i];
|
||||
// const idx = backupHistory.findIndex(item => item.id == id);
|
||||
// if (idx != -1) {
|
||||
// backupHistory.splice(idx, 1);
|
||||
// }
|
||||
// }
|
||||
// // Write db.data content to db.json
|
||||
// await db.write()
|
||||
// }
|
||||
|
||||
// ctx.body = {
|
||||
// code: 0,
|
||||
// };
|
||||
// });
|
||||
}
|
||||
|
||||
export default getBackupHistory;
|
||||
@@ -0,0 +1,22 @@
|
||||
import cuid from "cuid";
|
||||
// import getDb from "../dbServer.mjs";
|
||||
import { getDb } from "funjia-server/lib/funjia-server.mjs";
|
||||
import _ from "lodash";
|
||||
import offDown from "../offDown.bundle.mjs";
|
||||
|
||||
const baiduCloudPan = async (router) => {
|
||||
router.post('/api/baiduCloudPan/offDown', async (ctx) => {
|
||||
const body = ctx.request.body;
|
||||
// console.log(body);
|
||||
// 延迟发送请求,避免频繁对百度云盘离线下载
|
||||
// await offDown.randomDelay(20000, 40000);
|
||||
const data = await offDown.down(body?.magnet, body?.savePath);
|
||||
console.log("云盘返回参数:", data);
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default baiduCloudPan;
|
||||
@@ -0,0 +1,157 @@
|
||||
import cuid from "cuid";
|
||||
// import getDb from "../dbServer.mjs";
|
||||
import {getDb} from "funjia-server/lib/funjia-server.mjs";
|
||||
import _ from "lodash";
|
||||
|
||||
const getDynamic = (router) => {
|
||||
|
||||
router.post('/api/dynamic/list/:tableName', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const body = ctx.request.body;
|
||||
const data = db.data[ctx.params.tableName]?.filter((item) => {
|
||||
let isMatch = true;
|
||||
for (let field in body) {
|
||||
if (["page", "pageSize"].includes(field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof (item[field]) == "string") {
|
||||
isMatch = item[field]?.indexOf?.(body[field]) > -1;
|
||||
} else if (typeof (item[field]) == "number") {
|
||||
isMatch = item[field] == body[field];
|
||||
}
|
||||
if (!isMatch)
|
||||
break;
|
||||
}
|
||||
return isMatch;
|
||||
});
|
||||
|
||||
const {
|
||||
page,
|
||||
pageSize
|
||||
} = body;
|
||||
let batchData = data;
|
||||
if (page && pageSize) {
|
||||
batchData = data.slice((page - 1) * pageSize, page * pageSize);
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: batchData || [],
|
||||
total: data.length
|
||||
};
|
||||
});
|
||||
|
||||
router.get('/api/dynamic/:tableName', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const data = db.data[ctx.params.tableName];
|
||||
const query = ctx.request.query;
|
||||
console.log("参数:", query, ctx.request.body, ctx.query);
|
||||
let detail = {};
|
||||
if (query.id && data) {
|
||||
detail = data.find((item) => {
|
||||
return item.id == query.id;
|
||||
});
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: detail || {}
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/dynamic/add/:tableName', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const tableName=ctx.params.tableName;
|
||||
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data[tableName])
|
||||
db.data[tableName] = [];
|
||||
|
||||
const dynamic = db.data[tableName];
|
||||
const data = ctx.request.body;
|
||||
console.log("add:", data);
|
||||
data.id = cuid();
|
||||
data.createTime = new Date();
|
||||
dynamic.push(data)
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/dynamic/upd/:tableName', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const tableName=ctx.params.tableName;
|
||||
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data[tableName])
|
||||
db.data = {
|
||||
dynamic: []
|
||||
}
|
||||
|
||||
const dynamic = db.data[tableName];
|
||||
|
||||
const data = ctx.request.body;
|
||||
const id = data.id;
|
||||
console.log("数据Id:", id);
|
||||
if (id && dynamic) {
|
||||
const currentDetail = dynamic.find(item => item.id == id);
|
||||
if (currentDetail) {
|
||||
_.merge(currentDetail, data);
|
||||
}
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
|
||||
router.post('/api/dynamic/delete/:tableName', async (ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const tableName=ctx.params.tableName;
|
||||
|
||||
const db = await getDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data[tableName])
|
||||
db.data = {
|
||||
[tableName]: []
|
||||
}
|
||||
|
||||
const dynamic = db.data[tableName];
|
||||
|
||||
const data = ctx.request.body;
|
||||
const ids = data.ids;
|
||||
if (ids?.length > 0 && dynamic) {
|
||||
let id = null;
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
id = ids[i];
|
||||
const idx = dynamic.findIndex(item => item.id == id);
|
||||
if (idx != -1) {
|
||||
dynamic.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default getDynamic;
|
||||
@@ -0,0 +1,167 @@
|
||||
import cuid from "cuid";
|
||||
// import getDb, {
|
||||
// getResourceDb
|
||||
// } from "../dbServer.mjs";
|
||||
import {getDb,getResourceDb} from "funjia-server/lib/funjia-server.mjs";
|
||||
import _ from "lodash";
|
||||
import multer from '@koa/multer';
|
||||
|
||||
//配置
|
||||
var storage = multer.diskStorage({
|
||||
//文件保存路径
|
||||
destination: function (req, file, cb) {
|
||||
cb(null, 'static') //注意路径必须存最后面在不用加斜杠
|
||||
},
|
||||
//修改文件名称
|
||||
filename: function (req, file, cb) {
|
||||
var fileFormat = (file.originalname).split(".");
|
||||
const filename = cuid() + "." + fileFormat[fileFormat.length - 1];
|
||||
req.filename = filename;
|
||||
cb(null, filename);
|
||||
}
|
||||
})
|
||||
|
||||
//加载配置
|
||||
var upload = multer({
|
||||
storage: storage
|
||||
})
|
||||
|
||||
// const upload = multer({ dest: 'static/' })
|
||||
|
||||
const getUpload = (router) => {
|
||||
router.post('/api/leaseRecords/list', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const body = ctx.request.body;
|
||||
const data = db.data.leaseRecords.filter((item) => {
|
||||
let isMatch = true;
|
||||
for (let field in body) {
|
||||
if (["page", "pageSize"].includes(field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof (item[field]) == "string") {
|
||||
isMatch = item[field].indexOf(body[field]) > -1;
|
||||
} else if (typeof (item[field]) == "number") {
|
||||
isMatch = item[field] == body[field];
|
||||
}
|
||||
if (!isMatch)
|
||||
break;
|
||||
}
|
||||
return isMatch;
|
||||
});
|
||||
|
||||
const {
|
||||
page,
|
||||
pageSize
|
||||
} = body;
|
||||
let batchData = data;
|
||||
if (page && pageSize) {
|
||||
batchData = data.slice((page - 1) * pageSize, page * pageSize);
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: batchData.sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
}) || [],
|
||||
total: data.length
|
||||
};
|
||||
});
|
||||
|
||||
router.get('/api/img', async (ctx) => {
|
||||
// 设置头类型, 如果不设置,会直接下载该页面
|
||||
ctx.type = 'application/json';
|
||||
const db = await getDb();
|
||||
const data = db.data.leaseRecords;
|
||||
const query = ctx.request.query;
|
||||
console.log("参数:", query, ctx.request.body, ctx.query);
|
||||
let detail = {};
|
||||
if (query.id && data) {
|
||||
detail = data.find((item) => {
|
||||
return item.id == query.id;
|
||||
});
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: detail || {}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 添加图片记录
|
||||
* @param {*} path
|
||||
*/
|
||||
const addImg = async (filename, path) => {
|
||||
const data = {};
|
||||
try {
|
||||
const db = await getResourceDb();
|
||||
|
||||
// You can also use this syntax if you prefer
|
||||
if (!db.data.img)
|
||||
db.data.img = [];
|
||||
|
||||
const {
|
||||
img
|
||||
} = db.data;
|
||||
|
||||
data.id = cuid();
|
||||
data.filename = filename;
|
||||
data.path = path;
|
||||
data.createTime = new Date();
|
||||
img.push(data)
|
||||
// Write db.data content to db.json
|
||||
await db.write()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return null;
|
||||
}
|
||||
return data.id;
|
||||
|
||||
}
|
||||
|
||||
// 添加单个文件上传的路由
|
||||
router.post(
|
||||
'/api/upload/img',
|
||||
upload.single('file'),
|
||||
async (ctx) => {
|
||||
const {
|
||||
filename,
|
||||
path
|
||||
} = ctx.file;
|
||||
const res = await addImg(filename, path);
|
||||
|
||||
ctx.body = {
|
||||
code: res ? 0 : 1,
|
||||
data: {
|
||||
id: res,
|
||||
url: path
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 添加单个文件上传的路由
|
||||
router.post(
|
||||
'/api/upload/file',
|
||||
upload.single('file'),
|
||||
async (ctx) => {
|
||||
const {
|
||||
filename,
|
||||
path
|
||||
} = ctx.file;
|
||||
// const res = await addImg(filename, path);
|
||||
|
||||
ctx.body = {
|
||||
code: 0,
|
||||
data: {
|
||||
url: "/resource/static/"+filename
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default getUpload;
|
||||
@@ -0,0 +1,3 @@
|
||||
import offDown from "./offDown.bundle.mjs";
|
||||
|
||||
offDown('xxx');
|
||||
@@ -0,0 +1,16 @@
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
lib: {
|
||||
entry: './src/main.mjs', // 你的库的入口文件,这里假设是 src/main.mjs
|
||||
name: 'YourLibraryName', // 库的全局名称,将在浏览器环境中使用
|
||||
formats: ['es', 'umd'], // 输出的模块格式,这里包含 ES 模块和 UMD 模块
|
||||
fileName: (format) => `your-library-name.${format}.js` // 输出的文件名,根据不同的格式生成不同的文件名
|
||||
},
|
||||
rollupOptions: {
|
||||
// 确保外部化处理那些你不想打包进库中的依赖
|
||||
external: [],
|
||||
}
|
||||
}
|
||||
});
|
||||
+1596
File diff suppressed because it is too large
Load Diff
+53
@@ -0,0 +1,53 @@
|
||||
<script setup lang="ts">
|
||||
// This starter template is using Vue 3 <script setup> SFCs
|
||||
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
|
||||
import SystemMenu from './components/SystemMenu.vue';
|
||||
import SystemLayout from './components/SystemLayout.vue';
|
||||
import "element-plus/dist/index.css";
|
||||
import "funjiaui/dist/style.css";
|
||||
import * as funjiaui from "funjiaui";
|
||||
import axios from "funjia-axios";
|
||||
import * as vue from "vue";
|
||||
import lodashEs from "lodash-es";
|
||||
import * as elementPlus from "element-plus";
|
||||
|
||||
window.vue = vue;
|
||||
window.lodashEs = lodashEs;
|
||||
window.funjiaui = funjiaui;
|
||||
window.axios = axios;
|
||||
window.elementPlus = elementPlus;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* 滚动条 */
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
/* 滚动槽 */
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 滚动条滑块 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 4px;
|
||||
background: #999;
|
||||
-webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,135 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 3015159 */
|
||||
src: url('iconfont.woff2?t=1646121864615') format('woff2'),
|
||||
url('iconfont.woff?t=1646121864615') format('woff'),
|
||||
url('iconfont.ttf?t=1646121864615') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-a-bianzu171:before {
|
||||
content: "\e66b";
|
||||
}
|
||||
|
||||
.icon-duobianxing:before {
|
||||
content: "\e697";
|
||||
}
|
||||
|
||||
.icon-radio-on:before {
|
||||
content: "\ea6a";
|
||||
}
|
||||
|
||||
.icon-zhibo-qingping:before {
|
||||
content: "\e63a";
|
||||
}
|
||||
|
||||
.icon-gouxuan11:before {
|
||||
content: "\e628";
|
||||
}
|
||||
|
||||
.icon-weigouxuan:before {
|
||||
content: "\e623";
|
||||
}
|
||||
|
||||
.icon-bianji1:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.icon-shanchu:before {
|
||||
content: "\e625";
|
||||
}
|
||||
|
||||
.icon-guanbi:before {
|
||||
content: "\e611";
|
||||
}
|
||||
|
||||
.icon-danxuan_weixuanzhong:before {
|
||||
content: "\e653";
|
||||
}
|
||||
|
||||
.icon-danxuan_xuanzhong:before {
|
||||
content: "\e655";
|
||||
}
|
||||
|
||||
.icon-Shape:before {
|
||||
content: "\e665";
|
||||
}
|
||||
|
||||
.icon-jiahaozhankaibeifen:before {
|
||||
content: "\e664";
|
||||
}
|
||||
|
||||
.icon-jiahaozhankai:before {
|
||||
content: "\e663";
|
||||
}
|
||||
|
||||
.icon-shangchuan:before {
|
||||
content: "\e662";
|
||||
}
|
||||
|
||||
.icon-a-gonganjubeifen5:before {
|
||||
content: "\e65e";
|
||||
}
|
||||
|
||||
.icon-gonganju:before {
|
||||
content: "\e65d";
|
||||
}
|
||||
|
||||
.icon-duoxuan-xuanzhong:before {
|
||||
content: "\e65c";
|
||||
}
|
||||
|
||||
.icon-duoxuan-weixuan:before {
|
||||
content: "\e659";
|
||||
}
|
||||
|
||||
.icon-xiala:before {
|
||||
content: "\e6b9";
|
||||
}
|
||||
|
||||
.icon-dingweixiao:before {
|
||||
content: "\e654";
|
||||
}
|
||||
|
||||
.icon-shanchu-:before {
|
||||
content: "\e652";
|
||||
}
|
||||
|
||||
.icon-daoru:before {
|
||||
content: "\e651";
|
||||
}
|
||||
|
||||
.icon-daochu:before {
|
||||
content: "\e650";
|
||||
}
|
||||
|
||||
.icon-xiazai:before {
|
||||
content: "\e64f";
|
||||
}
|
||||
|
||||
.icon-tianjia:before {
|
||||
content: "\e64e";
|
||||
}
|
||||
|
||||
.icon-rili_calendar:before {
|
||||
content: "\e64d";
|
||||
}
|
||||
|
||||
.icon-bianji:before {
|
||||
content: "\e648";
|
||||
}
|
||||
|
||||
.icon-mimabeifen:before {
|
||||
content: "\e638";
|
||||
}
|
||||
|
||||
.icon-qietu:before {
|
||||
content: "\e637";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
{
|
||||
"id": "3015159",
|
||||
"name": "仲恺综合治理平台",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "27921080",
|
||||
"name": "派出所下的二级图标",
|
||||
"font_class": "a-bianzu171",
|
||||
"unicode": "e66b",
|
||||
"unicode_decimal": 58987
|
||||
},
|
||||
{
|
||||
"icon_id": "9706996",
|
||||
"name": "多边形",
|
||||
"font_class": "duobianxing",
|
||||
"unicode": "e697",
|
||||
"unicode_decimal": 59031
|
||||
},
|
||||
{
|
||||
"icon_id": "18175740",
|
||||
"name": "圆形",
|
||||
"font_class": "radio-on",
|
||||
"unicode": "ea6a",
|
||||
"unicode_decimal": 60010
|
||||
},
|
||||
{
|
||||
"icon_id": "26849757",
|
||||
"name": "zhibo-qingping",
|
||||
"font_class": "zhibo-qingping",
|
||||
"unicode": "e63a",
|
||||
"unicode_decimal": 58938
|
||||
},
|
||||
{
|
||||
"icon_id": "16368199",
|
||||
"name": "勾选1",
|
||||
"font_class": "gouxuan11",
|
||||
"unicode": "e628",
|
||||
"unicode_decimal": 58920
|
||||
},
|
||||
{
|
||||
"icon_id": "351775",
|
||||
"name": "未勾选",
|
||||
"font_class": "weigouxuan",
|
||||
"unicode": "e623",
|
||||
"unicode_decimal": 58915
|
||||
},
|
||||
{
|
||||
"icon_id": "4880425",
|
||||
"name": "编辑",
|
||||
"font_class": "bianji1",
|
||||
"unicode": "e607",
|
||||
"unicode_decimal": 58887
|
||||
},
|
||||
{
|
||||
"icon_id": "26535246",
|
||||
"name": "删除",
|
||||
"font_class": "shanchu",
|
||||
"unicode": "e625",
|
||||
"unicode_decimal": 58917
|
||||
},
|
||||
{
|
||||
"icon_id": "4942640",
|
||||
"name": "关闭",
|
||||
"font_class": "guanbi",
|
||||
"unicode": "e611",
|
||||
"unicode_decimal": 58897
|
||||
},
|
||||
{
|
||||
"icon_id": "6548521",
|
||||
"name": "单选_未选中",
|
||||
"font_class": "danxuan_weixuanzhong",
|
||||
"unicode": "e653",
|
||||
"unicode_decimal": 58963
|
||||
},
|
||||
{
|
||||
"icon_id": "6548524",
|
||||
"name": "单选_选中",
|
||||
"font_class": "danxuan_xuanzhong",
|
||||
"unicode": "e655",
|
||||
"unicode_decimal": 58965
|
||||
},
|
||||
{
|
||||
"icon_id": "26507365",
|
||||
"name": "搜索",
|
||||
"font_class": "Shape",
|
||||
"unicode": "e665",
|
||||
"unicode_decimal": 58981
|
||||
},
|
||||
{
|
||||
"icon_id": "26507356",
|
||||
"name": "jiahaozhankai备份",
|
||||
"font_class": "jiahaozhankaibeifen",
|
||||
"unicode": "e664",
|
||||
"unicode_decimal": 58980
|
||||
},
|
||||
{
|
||||
"icon_id": "26507350",
|
||||
"name": "jiahaozhankai",
|
||||
"font_class": "jiahaozhankai",
|
||||
"unicode": "e663",
|
||||
"unicode_decimal": 58979
|
||||
},
|
||||
{
|
||||
"icon_id": "26507342",
|
||||
"name": "上传照片",
|
||||
"font_class": "shangchuan",
|
||||
"unicode": "e662",
|
||||
"unicode_decimal": 58978
|
||||
},
|
||||
{
|
||||
"icon_id": "26507072",
|
||||
"name": "街道,区域",
|
||||
"font_class": "a-gonganjubeifen5",
|
||||
"unicode": "e65e",
|
||||
"unicode_decimal": 58974
|
||||
},
|
||||
{
|
||||
"icon_id": "26507064",
|
||||
"name": "派出所",
|
||||
"font_class": "gonganju",
|
||||
"unicode": "e65d",
|
||||
"unicode_decimal": 58973
|
||||
},
|
||||
{
|
||||
"icon_id": "26507030",
|
||||
"name": "复选框-选中",
|
||||
"font_class": "duoxuan-xuanzhong",
|
||||
"unicode": "e65c",
|
||||
"unicode_decimal": 58972
|
||||
},
|
||||
{
|
||||
"icon_id": "26506763",
|
||||
"name": "复选框-未选中",
|
||||
"font_class": "duoxuan-weixuan",
|
||||
"unicode": "e659",
|
||||
"unicode_decimal": 58969
|
||||
},
|
||||
{
|
||||
"icon_id": "672036",
|
||||
"name": "下拉",
|
||||
"font_class": "xiala",
|
||||
"unicode": "e6b9",
|
||||
"unicode_decimal": 59065
|
||||
},
|
||||
{
|
||||
"icon_id": "26506542",
|
||||
"name": "定位",
|
||||
"font_class": "dingweixiao",
|
||||
"unicode": "e654",
|
||||
"unicode_decimal": 58964
|
||||
},
|
||||
{
|
||||
"icon_id": "26506492",
|
||||
"name": "删除",
|
||||
"font_class": "shanchu-",
|
||||
"unicode": "e652",
|
||||
"unicode_decimal": 58962
|
||||
},
|
||||
{
|
||||
"icon_id": "26506468",
|
||||
"name": "导入",
|
||||
"font_class": "daoru",
|
||||
"unicode": "e651",
|
||||
"unicode_decimal": 58961
|
||||
},
|
||||
{
|
||||
"icon_id": "26506447",
|
||||
"name": "导出",
|
||||
"font_class": "daochu",
|
||||
"unicode": "e650",
|
||||
"unicode_decimal": 58960
|
||||
},
|
||||
{
|
||||
"icon_id": "26506428",
|
||||
"name": "下载",
|
||||
"font_class": "xiazai",
|
||||
"unicode": "e64f",
|
||||
"unicode_decimal": 58959
|
||||
},
|
||||
{
|
||||
"icon_id": "26506404",
|
||||
"name": "添加",
|
||||
"font_class": "tianjia",
|
||||
"unicode": "e64e",
|
||||
"unicode_decimal": 58958
|
||||
},
|
||||
{
|
||||
"icon_id": "26506240",
|
||||
"name": "日期",
|
||||
"font_class": "rili_calendar",
|
||||
"unicode": "e64d",
|
||||
"unicode_decimal": 58957
|
||||
},
|
||||
{
|
||||
"icon_id": "26505995",
|
||||
"name": "编辑",
|
||||
"font_class": "bianji",
|
||||
"unicode": "e648",
|
||||
"unicode_decimal": 58952
|
||||
},
|
||||
{
|
||||
"icon_id": "26462764",
|
||||
"name": "密码",
|
||||
"font_class": "mimabeifen",
|
||||
"unicode": "e638",
|
||||
"unicode_decimal": 58936
|
||||
},
|
||||
{
|
||||
"icon_id": "26462757",
|
||||
"name": "用户",
|
||||
"font_class": "qietu",
|
||||
"unicode": "e637",
|
||||
"unicode_decimal": 58935
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,278 @@
|
||||
import axios from "funjia-axios";
|
||||
// import imgList from "../../../public/data/image_cache.json";
|
||||
// import serviceInfo from "../../../public/data/get_service_info.json";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
export const login = (params: any): Promise<any> => {
|
||||
return axios.post("/api/login", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
export const udpdatePwd = (params: any): Promise<any> => {
|
||||
return axios.post("/api/user/password/update", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取系统信息
|
||||
*/
|
||||
export const getSytemInfo = (): Promise<any> => {
|
||||
return axios.get("/api/get/system");
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据ipcId获取抓拍图片列表
|
||||
*/
|
||||
export const getCaputreImgListByIpcId = (params: any): Promise<any> => {
|
||||
return axios.post("/api/query/device/obejct/image/cache", params);
|
||||
// return imgList;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取日志级别列表
|
||||
*/
|
||||
export const getLevelList = (): Promise<any> => {
|
||||
return axios.post("/api/get/log/level");
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取日志列表
|
||||
*/
|
||||
export const getLogList = (params: any): Promise<any> => {
|
||||
return axios.post("/api/get/log/last", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置日志级别
|
||||
*/
|
||||
export const setLogLevel = (params: any): Promise<any> => {
|
||||
return axios.post(`/set/log/level/${params.level}`, params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 重启系统
|
||||
*/
|
||||
export const restartSystem = (): Promise<any> => {
|
||||
return axios.get('/api/system/reboot');
|
||||
};
|
||||
|
||||
/**
|
||||
* 重启程序
|
||||
*/
|
||||
export const restartApp = (): Promise<any> => {
|
||||
return axios.get('/api/system/restart');
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取服务状态
|
||||
*/
|
||||
export const getServiceStatus = (): Promise<any> => {
|
||||
return axios.get('/get/service/info');
|
||||
// return serviceInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置服务
|
||||
*/
|
||||
export const setService = (params: any): Promise<any> => {
|
||||
return axios.post('/api/set/service/manager', params);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取TravelInformation列表
|
||||
*/
|
||||
export const getTravelInformationList = (params: any): Promise<any> => {
|
||||
return axios.post("/api/TravelInformation/list", params);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取TravelInformation详情
|
||||
*/
|
||||
export const getTravelInformation = (params: any): Promise<any> => {
|
||||
return axios.get("/api/travelInformation", { params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加TravelInformation
|
||||
*/
|
||||
export const addTravelInformation = (params: any): Promise<any> => {
|
||||
return axios.post("/api/TravelInformation/add", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改TravelInformation
|
||||
*/
|
||||
export const updateTravelInformation = (params: any): Promise<any> => {
|
||||
return axios.post("/api/TravelInformation/upd", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除TravelInformation
|
||||
*/
|
||||
export const deleteTravelInformation = (params: any): Promise<any> => {
|
||||
return axios.post("/api/TravelInformation/delete", params);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取Employee列表
|
||||
*/
|
||||
export const getEmployeeList = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Employee/list", params);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取Employee详情
|
||||
*/
|
||||
export const getEmployee = (params: any): Promise<any> => {
|
||||
return axios.get("/api/Employee", { params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加Employee
|
||||
*/
|
||||
export const addEmployee = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Employee/add", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改Employee
|
||||
*/
|
||||
export const updateEmployee = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Employee/upd", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除Employee
|
||||
*/
|
||||
export const deleteEmployee = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Employee/delete", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* Employee登录
|
||||
*/
|
||||
export const employeeLogin = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Employee/login", params);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取Notice列表
|
||||
*/
|
||||
export const getNoticeList = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Notice/list", params);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取Notice详情
|
||||
*/
|
||||
export const getNotice = (params: any): Promise<any> => {
|
||||
return axios.get("/api/Notice", { params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加Notice
|
||||
*/
|
||||
export const addNotice = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Notice/add", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改Notice
|
||||
*/
|
||||
export const updateNotice = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Notice/upd", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除Notice
|
||||
*/
|
||||
export const deleteNotice = (params: any): Promise<any> => {
|
||||
return axios.post("/api/Notice/delete", params);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取QA列表
|
||||
*/
|
||||
export const getQAList = (params: any): Promise<any> => {
|
||||
return axios.post("/api/QA/list", params);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取QA详情
|
||||
*/
|
||||
export const getQA = (params: any): Promise<any> => {
|
||||
return axios.get("/api/QA", { params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加QA
|
||||
*/
|
||||
export const addQA = (params: any): Promise<any> => {
|
||||
return axios.post("/api/QA/add", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改QA
|
||||
*/
|
||||
export const updateQA = (params: any): Promise<any> => {
|
||||
return axios.post("/api/QA/upd", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除QA
|
||||
*/
|
||||
export const deleteQA = (params: any): Promise<any> => {
|
||||
return axios.post("/api/QA/delete", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取Dynamic列表
|
||||
*/
|
||||
export const getDynamicList = (params: any, tableName: string): Promise<any> => {
|
||||
return axios.post("/api/dynamic/list/" + tableName, params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取Dynamic详情
|
||||
*/
|
||||
export const getDynamic = (params: any, tableName: string): Promise<any> => {
|
||||
return axios.get("/api/dynamic/" + tableName, { params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加Dynamic
|
||||
*/
|
||||
export const addDynamic = (params: any, tableName: string): Promise<any> => {
|
||||
return axios.post("/api/dynamic/add/" + tableName, params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改Dynamic
|
||||
*/
|
||||
export const updateDynamic = (params: any, tableName: string): Promise<any> => {
|
||||
return axios.post("/api/dynamic/upd/" + tableName, params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除Dynamic
|
||||
*/
|
||||
export const deleteDynamic = (params: any, tableName: string): Promise<any> => {
|
||||
return axios.post("/api/dynamic/delete/" + tableName, params);
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
import 'element-plus/es/components/message/style/css'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
// axios.defaults.baseURL = ""; // 请求后台地址
|
||||
axios.defaults.headers.post["Content-Type"] = "application/json;charset=utf-8";
|
||||
|
||||
interface LogOutCodesProps {
|
||||
status: number;
|
||||
code: number;
|
||||
msg?: string;
|
||||
}
|
||||
|
||||
axios.interceptors.request.use(
|
||||
(config: AxiosRequestConfig) => {
|
||||
// token授权
|
||||
const jwtToken: string = Cookies.get("Authorization") ?? "";
|
||||
config.headers = config.headers || {};
|
||||
config.headers.Authorization = `${jwtToken}`;
|
||||
// 缓存问题
|
||||
config.headers["Cache-Control"] = "no-cache";
|
||||
return config;
|
||||
},
|
||||
(err) => {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
|
||||
axios.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
const xhr: any = response.data ?? {};
|
||||
const { code, msg: resultMsg } = xhr;
|
||||
// 需要退出重登的code和msg
|
||||
let msg: string = "";
|
||||
switch (code) {
|
||||
case 9:
|
||||
msg = "请重新登录";
|
||||
break;
|
||||
case 18:
|
||||
msg = "授权过期,请重新登录";
|
||||
break;
|
||||
case 27:
|
||||
msg = "未安装License或License已过期";
|
||||
break;
|
||||
case 28:
|
||||
msg = "License权限不足";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (code) {
|
||||
ElMessage.error(msg || resultMsg || "系统异常");
|
||||
}
|
||||
return xhr;
|
||||
},
|
||||
(error) => {
|
||||
const response: any = error.response ?? {};
|
||||
const { data, status } = response;
|
||||
const { code, reason } = data;
|
||||
let msg: string = "";
|
||||
// 获取错误提示
|
||||
switch (status) {
|
||||
case 400:
|
||||
msg =
|
||||
code === 17
|
||||
? `异地登录,登录IP为${data.data},请重新登录`
|
||||
: "请求错误";
|
||||
break;
|
||||
case 401:
|
||||
msg = reason || "鉴权失败";
|
||||
break;
|
||||
case 403:
|
||||
msg = "拒绝访问";
|
||||
break;
|
||||
case 404:
|
||||
msg = "请求错误,未找到该资源";
|
||||
break;
|
||||
case 405:
|
||||
msg = "请求方法未允许";
|
||||
break;
|
||||
case 408:
|
||||
msg = "请求超时";
|
||||
break;
|
||||
case 413:
|
||||
msg = "请求数据过多";
|
||||
break;
|
||||
case 500:
|
||||
msg = "服务器端出错";
|
||||
break;
|
||||
case 501:
|
||||
msg = "网络未实现";
|
||||
break;
|
||||
case 503:
|
||||
msg = "服务不可用";
|
||||
break;
|
||||
case 504:
|
||||
msg = "网络超时";
|
||||
break;
|
||||
case 505:
|
||||
msg = "http版本不支持该请求";
|
||||
break;
|
||||
case 502:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ElMessage.error(msg);
|
||||
return Promise.reject(error).catch(() => {
|
||||
if (401 == status) {
|
||||
window.location.href = "/";
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
export default axios;
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* 获取目标类型的名称 0:人脸, 1:自行车, 2:巴士, 3:小汽车, 4:电动车|摩托车, 5:人体, 6:三轮车,7货车、8车牌、9推车,10鸟、11猫,12 狗,13老鼠
|
||||
* @param objectType
|
||||
* @returns
|
||||
*/
|
||||
export const getObjectTypeName = (objectType: TObjectType) => {
|
||||
switch (objectType) {
|
||||
case 0:
|
||||
return "人脸";
|
||||
case 1:
|
||||
return "自行车";
|
||||
case 2:
|
||||
return "巴士";
|
||||
case 3:
|
||||
return "小汽车";
|
||||
case 4:
|
||||
return "电动车|摩托车";
|
||||
case 5:
|
||||
return "人体";
|
||||
case 6:
|
||||
return "三轮车";
|
||||
case 7:
|
||||
return "货车";
|
||||
case 8:
|
||||
return "车牌";
|
||||
case 9:
|
||||
return "推车";
|
||||
case 10:
|
||||
return "鸟";
|
||||
case 11:
|
||||
return "猫";
|
||||
case 12:
|
||||
return "狗";
|
||||
case 13:
|
||||
return "老鼠";
|
||||
default:
|
||||
return "--";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 解决加减乘除中浮点数精度问题
|
||||
|
||||
/**
|
||||
* arg1 第一位数字
|
||||
* arg2 第二位数字
|
||||
* type 运算符类型 加add, 减reduce,乘ride,除except
|
||||
*/
|
||||
export const FloatPoint = (arg1: number, arg2: number, type: 'add' | 'reduce' | 'ride' | 'except') => {
|
||||
let r1: number = 0;
|
||||
let r2: number = 0;
|
||||
try {
|
||||
r1 = arg1.toString().split(".")[1].length;
|
||||
} catch (e) {
|
||||
r1 = 0;
|
||||
}
|
||||
try {
|
||||
r2 = arg2.toString().split(".")[1].length;
|
||||
} catch (e) {
|
||||
r2 = 0;
|
||||
}
|
||||
const c: number = Math.abs(r1 - r2); // 位数差的绝对值
|
||||
const m: number = Math.pow(10, Math.max(r1, r2)); // 较大数的幂
|
||||
if (c > 0) {
|
||||
// 位数相差
|
||||
const cm: number = Math.pow(10, c);
|
||||
if (r1 > r2) {
|
||||
arg1 = Number(arg1.toString().replace(".", "")); // 转化成数字
|
||||
arg2 = Number(arg2.toString().replace(".", "")) * cm;
|
||||
} else {
|
||||
arg1 = Number(arg1.toString().replace(".", "")) * cm;
|
||||
arg2 = Number(arg2.toString().replace(".", ""));
|
||||
}
|
||||
} else { // 位数相等
|
||||
arg1 = Number(arg1.toString().replace(".", ""));
|
||||
arg2 = Number(arg2.toString().replace(".", ""));
|
||||
}
|
||||
let res: any = null;
|
||||
if (type === 'add') {
|
||||
res = (arg1 + arg2) / m;
|
||||
} else if (type === 'reduce') {
|
||||
res = (arg1 - arg2) / m;
|
||||
} else if (type === 'ride') {
|
||||
res = (arg1 * arg2) / m / m;
|
||||
} else if (type === 'except') {
|
||||
res = (arg1 / arg2);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 对字符串保留小数
|
||||
* @param value 原始值,有可能大于1
|
||||
* @param num 位数
|
||||
*/
|
||||
export const toFixed = (str: any, num: number = 2) => {
|
||||
try {
|
||||
if (typeof (str) === "string") {
|
||||
str = parseFloat(str);
|
||||
} else if (typeof (str) === "number") {
|
||||
str = str;
|
||||
} else {
|
||||
str = parseFloat(str);
|
||||
}
|
||||
str = FloatPoint(str, 100, 'ride');
|
||||
str = str.toString(); // 字符串值
|
||||
const pointIdx = str.indexOf("."); // 字符串中小数点的位置
|
||||
if (pointIdx !== -1) {
|
||||
if (num > 0) {
|
||||
// 存在小数点的情况下
|
||||
// 最多保留num位小数
|
||||
str = str.substring(0, pointIdx + (num + 1));
|
||||
// 小数位小于num位的情况下,在末尾补零
|
||||
const decimalStr = str.substring(pointIdx + 1); // 小数位字符串
|
||||
if (decimalStr.length < num) {
|
||||
for (let i = 0; i < num - decimalStr.length; i++) {
|
||||
str += "0";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
str = str.substring(0, pointIdx);
|
||||
return parseFloat(str);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
return 0;
|
||||
}
|
||||
return parseFloat(str);
|
||||
}
|
||||
|
||||
export function encode(str) {
|
||||
// 对字符串进行编码
|
||||
const encode = encodeURI(str);
|
||||
// 对编码的字符串转化base64
|
||||
const base64 = btoa(encode);
|
||||
return base64;
|
||||
}
|
||||
|
||||
export function decode(base64) {
|
||||
// 对base64转编码
|
||||
const decode = atob(base64);
|
||||
// 编码转字符串
|
||||
const str = decodeURI(decode);
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div :class="'angle ' + identity + ' ' + direction">
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// 箭头方向
|
||||
export enum EDirection {
|
||||
LeftTop = "left-top",
|
||||
LeftBottom = "left-bottom",
|
||||
RightTop = "right-top",
|
||||
RightBottom = "right-bottom"
|
||||
}
|
||||
|
||||
// 身份类型
|
||||
export enum EIdentity {
|
||||
// 重点人员
|
||||
Suspect = "suspect",
|
||||
// 陌生人
|
||||
Stranger = "stranger",
|
||||
// 居民
|
||||
Resident = "resident",
|
||||
// 未归档
|
||||
Unknow = "unknow",
|
||||
// 其它
|
||||
Other = "other"
|
||||
}
|
||||
</script>
|
||||
<script setup lang="ts">
|
||||
withDefaults(defineProps<{ identity: EIdentity, direction: EDirection }>(), {
|
||||
identity: EIdentity.Stranger,
|
||||
direction: EDirection.LeftTop
|
||||
});
|
||||
</script>
|
||||
<style lang="scss">
|
||||
$suspect-color:#ff5757;
|
||||
$stranger-color:#f9db12;
|
||||
$residents-color:#12DB68;
|
||||
$unknow-color:#989898;
|
||||
$primary1_color:#00C9DE;
|
||||
|
||||
|
||||
@mixin borderStyle($color) {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
border-top: 3px solid $color;
|
||||
border-left: 3px solid $color;
|
||||
}
|
||||
|
||||
@mixin angle-block($color) {
|
||||
&.left-top {
|
||||
@include borderStyle($color);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&.left-bottom {
|
||||
@include borderStyle($color);
|
||||
transform: rotate(270deg);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&.right-top {
|
||||
@include borderStyle($color);
|
||||
transform: rotate(90deg);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&.right-bottom {
|
||||
@include borderStyle($color);
|
||||
transform: rotate(180deg);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.angle {
|
||||
|
||||
// 重点人员
|
||||
&.suspect {
|
||||
@include angle-block($suspect-color);
|
||||
}
|
||||
|
||||
// 陌生人
|
||||
&.stranger {
|
||||
@include angle-block($stranger-color);
|
||||
}
|
||||
|
||||
// 居民
|
||||
&.resident {
|
||||
@include angle-block($residents-color);
|
||||
}
|
||||
|
||||
// 未归档
|
||||
&.unknow {
|
||||
@include angle-block($unknow-color);
|
||||
}
|
||||
|
||||
// 其它
|
||||
&.other {
|
||||
@include angle-block($primary1_color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<object-rect :top="top" :left="left" :width="-(left - right)" :height="-(top - bottom)"></object-rect>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// import { EIdentity } from './Angle.vue';
|
||||
import { computed } from 'vue';
|
||||
const props = defineProps<{
|
||||
top: number,
|
||||
right: number,
|
||||
bottom: number,
|
||||
left: number
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<codemirror v-model="value" placeholder="Code goes here..." :style="{ height: '400px' }" :autofocus="true"
|
||||
:indent-with-tab="true" :tab-size="2" :extensions="extensions" @ready="handleReady" @change="log('change', $event)"
|
||||
@focus="log('focus', $event)" @blur="log('blur', $event)" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { Codemirror } from 'vue-codemirror'
|
||||
import { javascript } from '@codemirror/lang-javascript'
|
||||
// import { oneDark } from '@codemirror/theme-one-dark'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Codemirror
|
||||
},
|
||||
setup() {
|
||||
const code = ref(`console.log('Hello, world!')`)
|
||||
const extensions = [javascript()]
|
||||
|
||||
// Codemirror EditorView instance ref
|
||||
const view = shallowRef()
|
||||
const handleReady = (payload) => {
|
||||
view.value = payload.view
|
||||
}
|
||||
|
||||
// Status is available at all times via Codemirror EditorView
|
||||
const getCodemirrorStates = () => {
|
||||
const state = view.value.state
|
||||
const ranges = state.selection.ranges
|
||||
const selected = ranges.reduce((r, range) => r + range.to - range.from, 0)
|
||||
const cursor = ranges[0].anchor
|
||||
const length = state.doc.length
|
||||
const lines = state.doc.lines
|
||||
// more state info ...
|
||||
// return ...
|
||||
}
|
||||
|
||||
return {
|
||||
value,
|
||||
extensions,
|
||||
handleReady,
|
||||
log: console.log
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<p class="el-message__content">{{ getMsgTempalte ? getMsgTempalte(countDownTime) : countDownTime }}</p>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onBeforeMount, ref, onBeforeUnmount } from "vue";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
timespan?: number,
|
||||
getMsgTempalte: (value: number) => string
|
||||
}>(), {
|
||||
timespan: 3
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(n: 'next'): void
|
||||
}>()
|
||||
|
||||
const countDownTime = ref(props.timespan);
|
||||
const timeout = ref();
|
||||
|
||||
onBeforeMount(() => {
|
||||
timeout.value = setInterval(() => {
|
||||
if (countDownTime.value >= 1) {
|
||||
countDownTime.value -= 1;
|
||||
}
|
||||
else {
|
||||
clearInterval(timeout.value);
|
||||
emit('next');
|
||||
}
|
||||
}, 1000);
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(timeout.value);
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<el-tag v-for="tag in dynamicTags" :key="tag" class="mx-1" closable :disable-transitions="false"
|
||||
@close="handleClose(tag)">
|
||||
{{ tag }}
|
||||
</el-tag>
|
||||
<el-input v-if="inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20" size="small"
|
||||
@keyup.enter="handleInputConfirm" @blur="handleInputConfirm" />
|
||||
<el-button v-else class="button-new-tag ml-1" size="small" @click="showInput">
|
||||
+ New Tag
|
||||
</el-button>
|
||||
</template>
|
||||
<style scoped>
|
||||
.mx-1 {
|
||||
margin-left: 0.25rem;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, ref } from 'vue'
|
||||
import { ElInput } from 'element-plus'
|
||||
|
||||
const props = defineProps<{ modelValue: [] }>();
|
||||
const emits = defineEmits<{
|
||||
(
|
||||
e: "update:modelValue",
|
||||
val: string | number | (string | number)[] | undefined
|
||||
): void;
|
||||
}>();
|
||||
|
||||
const inputValue = ref('')
|
||||
const dynamicTags = ref(props.modelValue)
|
||||
const inputVisible = ref(false)
|
||||
const InputRef = ref<InstanceType<typeof ElInput>>()
|
||||
|
||||
const handleClose = (tag: string) => {
|
||||
dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1)
|
||||
emits('update:modelValue', dynamicTags.value)
|
||||
}
|
||||
|
||||
const showInput = () => {
|
||||
inputVisible.value = true
|
||||
nextTick(() => {
|
||||
InputRef.value!.input!.focus()
|
||||
})
|
||||
}
|
||||
|
||||
const handleInputConfirm = () => {
|
||||
if (inputValue.value) {
|
||||
dynamicTags.value.push(inputValue.value)
|
||||
emits('update:modelValue', dynamicTags.value)
|
||||
}
|
||||
inputVisible.value = false
|
||||
inputValue.value = ''
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<div :class="$style['img-preview']">
|
||||
<vue-cropper :key="id" ref="cropper" :src="imgUrl" alt="" :autoCrop="false" dragMode="move" :background="false"
|
||||
:viewMode="2" :toggleDragModeOnDblclick="false" @ready="onReady" @crop="onCrop" @zoom="onZoom" />
|
||||
<div :class="$style['mask']">
|
||||
<calc-rect-dock :top="rectPosition.top" :right="rectPosition.right" :bottom="rectPosition.bottom"
|
||||
:left="rectPosition.left"></calc-rect-dock>
|
||||
</div>
|
||||
<div :class="$style['prev']" @click="$emit('imgIdxChange', -1)">
|
||||
<el-icon>
|
||||
<d-arrow-left />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div :class="$style['next']" @click="$emit('imgIdxChange', 1)">
|
||||
<el-icon>
|
||||
<d-arrow-right />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import VueCropper from 'vue-cropperjs';
|
||||
import 'cropperjs/dist/cropper.css';
|
||||
import { reactive, ref, onBeforeMount, watch } from "vue";
|
||||
import { computed } from '@vue/reactivity';
|
||||
import { merge, cloneDeep } from "lodash-es";
|
||||
import {
|
||||
DArrowLeft,
|
||||
DArrowRight,
|
||||
} from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps<{
|
||||
id: "",
|
||||
imgUrl: "",
|
||||
position: "",
|
||||
}>();
|
||||
|
||||
defineEmits<{
|
||||
(n: 'imgIdxChange', value: TImgPreviewIdx): void
|
||||
}>();
|
||||
|
||||
const cropper = ref();
|
||||
const cropOption = reactive({
|
||||
ratio: 1,
|
||||
delta: { deltaX: 0, deltaY: 0 }
|
||||
});
|
||||
const rectPosition = reactive({
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0
|
||||
});
|
||||
const defRatio = ref(0);
|
||||
|
||||
onBeforeMount(() => {
|
||||
initRectPosition();
|
||||
})
|
||||
|
||||
watch([cropOption, () => props.id], () => {
|
||||
initRectPosition();
|
||||
})
|
||||
|
||||
const initRectPosition = () => {
|
||||
const rectOption: any = formatRectPosition(cloneDeep(props.position)) || {};
|
||||
merge(rectPosition, getStyle(rectOption));
|
||||
}
|
||||
|
||||
const initCropOption = (e) => {
|
||||
const canvasData: any = e.target?.cropper?.canvasData;
|
||||
if (canvasData) {
|
||||
if (e?.detail?.ratio && e.detail.ratio >= defRatio.value) {
|
||||
merge(cropOption, {
|
||||
ratio: e.detail.ratio,
|
||||
delta: {
|
||||
deltaX: canvasData.left,
|
||||
deltaY: canvasData.top
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
merge(cropOption, {
|
||||
delta: {
|
||||
deltaX: canvasData.left,
|
||||
deltaY: canvasData.top
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片渲染完成事件
|
||||
* @param e
|
||||
*/
|
||||
const onReady = (e: any) => {
|
||||
const canvasData: any = e.target?.cropper?.canvasData;
|
||||
if (canvasData) {
|
||||
defRatio.value = canvasData.width / e.target.width;
|
||||
merge(cropOption, {
|
||||
ratio: defRatio.value,
|
||||
delta: { deltaX: 0, deltaY: 0 }
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
const onCrop = (e) => {
|
||||
initCropOption(e);
|
||||
}
|
||||
|
||||
const onZoom = (e) => {
|
||||
initCropOption(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化矩形框位置信息
|
||||
* @param position json字符串
|
||||
*/
|
||||
const formatRectPosition = (position: any) => {
|
||||
const fpm: any = {};
|
||||
let rectInfo: any = {};
|
||||
if (typeof (position) === "string") {
|
||||
try {
|
||||
rectInfo = JSON.parse(position);
|
||||
const { face_rect, object_rect } = rectInfo;
|
||||
if (face_rect) {
|
||||
fpm.top = face_rect.top;
|
||||
fpm.right = face_rect.right;
|
||||
fpm.bottom = face_rect.bottom;
|
||||
fpm.left = face_rect.left;
|
||||
}
|
||||
else if (object_rect) {
|
||||
fpm.top = object_rect.top;
|
||||
fpm.right = object_rect.right;
|
||||
fpm.bottom = object_rect.bottom;
|
||||
fpm.left = object_rect.left;
|
||||
fpm.type = 2;//ERectType.Body;
|
||||
}
|
||||
return fpm;
|
||||
} catch (error) {
|
||||
console.warn("小图位置信息有误", position);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (position.face_rect) {
|
||||
return position.face_rect;
|
||||
}
|
||||
else if (position.object_rect) {
|
||||
return position.object_rect;
|
||||
}
|
||||
}
|
||||
console.warn("小图位置信息有误", position);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位矩形框
|
||||
*/
|
||||
const getStyle = (position: any) => {
|
||||
const faceRect = position;
|
||||
const { ratio, delta } = cropOption;
|
||||
if (ratio != -1) {
|
||||
for (const item in faceRect) {
|
||||
if (["top", "right", "bottom", "left"].includes(item))
|
||||
faceRect[item] = parseFloat(faceRect[item]) * ratio
|
||||
}
|
||||
}
|
||||
return {
|
||||
top: faceRect.top + delta.deltaY,
|
||||
left: faceRect.left + delta.deltaX,
|
||||
bottom: faceRect.bottom + delta.deltaY,
|
||||
right: faceRect.right + delta.deltaX,
|
||||
};
|
||||
}
|
||||
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.img-preview) {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:local(.mask) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
:local(.prev),
|
||||
:local(.next) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
:local(.prev),
|
||||
:local(.next) {
|
||||
position: absolute;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
background-color: rgb(10 10 10 / 20%);
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
pointer-events: painted;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
:local(.prev) {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
:local(.next) {
|
||||
right: 0;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<system-layout>
|
||||
<template #sidebar>
|
||||
<system-menu menuIdx="1-1" :parentIdxList="[1]" />
|
||||
</template>
|
||||
<template #content>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
</system-layout>
|
||||
</template>
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div :class="['face-identity-rect', getRootClassName(), identity].join(' ')"
|
||||
:style="{ width: width + 'px', height: height + 'px' }">
|
||||
<angle :identity="identity" :direction="EDirection.LeftTop"></angle>
|
||||
<angle :identity="identity" :direction="EDirection.LeftBottom"></angle>
|
||||
<angle :identity="identity" :direction="EDirection.RightTop"></angle>
|
||||
<angle :identity="identity" :direction="EDirection.RightBottom"></angle>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { EDirection, EIdentity } from "./Angle.vue";
|
||||
import { computed } from "vue";
|
||||
|
||||
const props: any = withDefaults(defineProps<{
|
||||
identity: EIdentity, type: number,
|
||||
width: number, height: number,
|
||||
top: number,
|
||||
left: number
|
||||
}>(), {
|
||||
identity: EIdentity.Resident,
|
||||
type: 1
|
||||
})
|
||||
|
||||
const topVar = computed(() => props.top + 'px')
|
||||
const leftVar = computed(() => props.left + 'px')
|
||||
|
||||
|
||||
const getRootClassName = () => {
|
||||
// if (props.type == 1)
|
||||
// return "face-rect";
|
||||
// else
|
||||
return "body-rect";
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.face-identity-rect {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: v-bind(topVar);
|
||||
left: v-bind(leftVar);
|
||||
|
||||
&.body-rect {
|
||||
//.face-rect {
|
||||
// background-color: rgba(255, 140, 0, .19);
|
||||
border: solid 2px #ff8c00;
|
||||
// }
|
||||
|
||||
.angle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div :class="$style['upload']" @change="onFileChange">
|
||||
<input ref="fileRef" :accept="accept" v-show="false" type="file" />
|
||||
<el-input :model-value="fileName" :disabled="true" :style="{ width: '200px' }" />
|
||||
<el-button :class="$style['scan']" @click="onPreUpload">浏览</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
withDefaults(defineProps<{
|
||||
accept?: any
|
||||
}>(), {
|
||||
accept: '*'
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(n: "fileChange", file: File): void
|
||||
}>();
|
||||
|
||||
const fileRef = ref();
|
||||
const fileName = ref();
|
||||
|
||||
const onFileChange = (e: any) => {
|
||||
const files = e.target.files;
|
||||
fileName.value = files?.[0]?.name;
|
||||
emit('fileChange', files?.[0]);
|
||||
}
|
||||
|
||||
const onPreUpload = () => {
|
||||
fileRef.value.value = "";
|
||||
fileRef.value?.click();
|
||||
}
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.upload) {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
:local(.scan) {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<slot name="header" :style="{ height: '80px' }">
|
||||
<home-header></home-header>
|
||||
</slot>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :style="{
|
||||
height: 'calc(100% - 80px)'
|
||||
}">
|
||||
<el-col :span="3">
|
||||
<slot name="sidebar"></slot>
|
||||
</el-col>
|
||||
<el-col :span="21" :style="{
|
||||
background: '#f0f2f5', padding: '20px', overflow: 'auto',
|
||||
height: 'calc(100vh - 80px)'
|
||||
}">
|
||||
<slot name="content"></slot>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import HomeHeader from "@/containers/HomeHeader.vue"
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
/* .el-menu-vertical-demo:not(.el-menu--collapse) {
|
||||
width: 200px;
|
||||
min-height: 400px;
|
||||
} */
|
||||
|
||||
:global {
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:local(.layout) {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<!-- <el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
|
||||
<el-radio-button :label="false">expand</el-radio-button>
|
||||
<el-radio-button :label="true">collapse</el-radio-button>
|
||||
</el-radio-group> -->
|
||||
<div :class="$style['system-menu']">
|
||||
<el-menu :default-active="activeIndex" :default-openeds="openeds" :router="true" class="el-menu-vertical-demo"
|
||||
:collapse="isCollapse" active-text-color="#409eff" background-color="#001529" text-color="#fff"
|
||||
:style="{ border: 0 }" @open="handleOpen" @close="handleClose">
|
||||
<template v-if="menuJson.length == 0">
|
||||
<el-menu-item index="/app/Employee">
|
||||
用戶列表
|
||||
</el-menu-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-menu-item v-for="(item, index) in menuJson" :key="item.name" :index="item.route">
|
||||
{{ item.name }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onBeforeMount } from 'vue'
|
||||
import {
|
||||
Menu as IconMenu,
|
||||
Setting,
|
||||
} from '@element-plus/icons-vue'
|
||||
import { useRoute } from "vue-router";
|
||||
import * as api from "@/common/api";
|
||||
import { MENU_JSON } from "@/consts/dataDict";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
menuIdx: string,
|
||||
parentIdxList: string[]
|
||||
}>(), {
|
||||
menuIdx: "/app/system/info",
|
||||
parentIdxList: () => ['system']
|
||||
})
|
||||
|
||||
const activeIndex = ref();
|
||||
const openeds = ref<string[]>([]);
|
||||
const router = useRoute();
|
||||
const menuJson = ref<any>([]);
|
||||
|
||||
onBeforeMount(() => {
|
||||
activeIndex.value = router.path;
|
||||
switch (true) {
|
||||
case router.path.includes('/app/device'):
|
||||
openeds.value = ['/app/device']
|
||||
break;
|
||||
case router.path.includes('/app/system'):
|
||||
default:
|
||||
openeds.value = ['/app/system/info'];
|
||||
break;
|
||||
}
|
||||
getMenuJson();
|
||||
})
|
||||
|
||||
const isCollapse = ref(false)
|
||||
const handleOpen = (key: string, keyPath: string[]) => {
|
||||
}
|
||||
const handleClose = (key: string, keyPath: string[]) => {
|
||||
}
|
||||
|
||||
const goTo = (url) => {
|
||||
document.location.href = url;
|
||||
}
|
||||
|
||||
const getMenuJson = async () => {
|
||||
const { data: dataDict } = await api.getDynamic({ id: MENU_JSON }, "dataDict");
|
||||
|
||||
if (dataDict?.value) {
|
||||
try {
|
||||
menuJson.value = JSON.parse(dataDict.value);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style module lang="scss">
|
||||
/* .el-menu-vertical-demo:not(.el-menu--collapse) {
|
||||
width: 200px;
|
||||
min-height: 400px;
|
||||
} */
|
||||
|
||||
:global {
|
||||
:local(.system-menu) {
|
||||
height: 100%;
|
||||
|
||||
.el-menu-vertical-demo {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
import ExecutionEnvironment from 'exenv';
|
||||
|
||||
function transitionEnd() {
|
||||
const transitionEndEventNames = {
|
||||
WebkitTransition: 'webkitTransitionEnd',
|
||||
MozTransition: 'transitionend',
|
||||
OTransition: 'oTransitionEnd otransitionend',
|
||||
transition: 'transitionend'
|
||||
};
|
||||
if (!ExecutionEnvironment.canUseDOM) {
|
||||
return transitionEndEventNames;
|
||||
}
|
||||
const el = document.createElement('pin');
|
||||
|
||||
for (const name in transitionEndEventNames) {
|
||||
if (el.style[name] !== undefined) {
|
||||
return transitionEndEventNames[name];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const ifHasTransitionEnd = transitionEnd();
|
||||
|
||||
const prefixes = ['Webkit', 'Moz', 'ms', 'O', ''];
|
||||
|
||||
class AnimationManager {
|
||||
constructor() {
|
||||
this.animationHandle = `css${ifHasTransitionEnd ? 3 : 2}Animation`;
|
||||
}
|
||||
|
||||
generate(options) {
|
||||
Object.assign(this, options);
|
||||
return this[this.animationHandle]();
|
||||
}
|
||||
|
||||
css2Animation() {
|
||||
const style = {};
|
||||
style[this.horizontalDirection] = `${this.position[0]}px`;
|
||||
style[this.verticalDirection] = `${this.position[1]}px`;
|
||||
|
||||
this.mixAnimation(style);
|
||||
return style;
|
||||
}
|
||||
|
||||
css3Animation() {
|
||||
const style = {};
|
||||
|
||||
prefixes.map(prefix => {
|
||||
let x, y;
|
||||
|
||||
if (this.horizontalDirection === 'right') {
|
||||
x = this.containerWidth - this.size.width - this.position[0];
|
||||
} else {
|
||||
x = this.position[0];
|
||||
}
|
||||
|
||||
if (this.verticalDirection === 'bottom') {
|
||||
y = this.containerHeight - this.size.height - this.position[1];
|
||||
} else {
|
||||
y = this.position[1];
|
||||
}
|
||||
|
||||
style[`${prefix}Transform`] = `translate3d(${x}px, ${y}px, 0)`;
|
||||
});
|
||||
|
||||
this.mixAnimation(style);
|
||||
return style;
|
||||
}
|
||||
|
||||
mixAnimation(style) {
|
||||
if (!this.closeAnimation) {
|
||||
prefixes.map(prefix => {
|
||||
style[`${prefix}TransitionDuration`] = `${this.transitionDuration}s`;
|
||||
style[`${prefix}TransitionTimingFunction`] = this.transitionTimingFunction;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default AnimationManager;
|
||||
@@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<div ref="container" :class="`${prefixClassName}-container`" :style="containerStyle">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
GridSort
|
||||
} from 'autoresponsive-core3';
|
||||
import pkg from '../../package';
|
||||
import AnimationManager from './animation';
|
||||
import {onBeforeMount, onMounted, onUpdated, ref} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
containerWidth: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
containerHeight: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
gridWidth: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
prefixClassName: {
|
||||
type: String,
|
||||
default: pkg.name
|
||||
},
|
||||
itemClassName: {
|
||||
type: String,
|
||||
default: 'item'
|
||||
},
|
||||
itemMargin: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
horizontalDirection: {
|
||||
type: String,
|
||||
default: 'left'
|
||||
},
|
||||
transitionDuration: {
|
||||
type: [String, Number],
|
||||
default: 1
|
||||
},
|
||||
transitionTimingFunction: {
|
||||
type: String,
|
||||
default: 'linear'
|
||||
},
|
||||
verticalDirection: {
|
||||
type: String,
|
||||
default: 'top'
|
||||
},
|
||||
closeAnimation: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
onItemDidLayout: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
},
|
||||
onContainerDidLayout: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
}
|
||||
});
|
||||
|
||||
const containerStyle = {
|
||||
position: 'relative'
|
||||
};
|
||||
|
||||
let animationManager, fixedContainerHeight;
|
||||
onBeforeMount(() => {
|
||||
animationManager = new AnimationManager();
|
||||
fixedContainerHeight = typeof props.containerHeight === 'number';
|
||||
})
|
||||
|
||||
const mixItemInlineStyle = (s) => {
|
||||
const itemMargin = props.itemMargin;
|
||||
let style = {
|
||||
display: 'block',
|
||||
float: 'left',
|
||||
margin: `0 ${itemMargin}px ${itemMargin}px 0`
|
||||
};
|
||||
|
||||
if (props.containerWidth) {
|
||||
style = {
|
||||
position: 'absolute'
|
||||
};
|
||||
}
|
||||
Object.assign(s, style);
|
||||
}
|
||||
|
||||
const container = ref(null);
|
||||
|
||||
const updateChildren = () => {
|
||||
const sortManager = new GridSort({
|
||||
containerWidth: props.containerWidth,
|
||||
gridWidth: props.gridWidth
|
||||
});
|
||||
sortManager.init();
|
||||
|
||||
let containerHeight = props.verticalDirection === 'bottom' || fixedContainerHeight ? props.containerHeight : 0;
|
||||
|
||||
const children = container.value.children;
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const node = children[i];
|
||||
const canvas = node.__vnode.el;
|
||||
|
||||
let style = {};
|
||||
switch (canvas.style.constructor.name) {
|
||||
case 'CSS2Properties':
|
||||
Object.values(canvas.style).forEach((prop) => {
|
||||
style[prop] = canvas.style[prop];
|
||||
});
|
||||
break;
|
||||
case 'CSSStyleDeclaration':
|
||||
style = canvas.style;
|
||||
break;
|
||||
}
|
||||
|
||||
if (node.className &&
|
||||
props.itemClassName &&
|
||||
!~node.className.indexOf(props.itemClassName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const childWidth = parseInt(style.width, 10) + props.itemMargin;
|
||||
const childHeight = parseInt(style.height, 10) + props.itemMargin;
|
||||
const calculatedPosition = sortManager.getPosition(childWidth, childHeight);
|
||||
|
||||
if (fixedContainerHeight) {
|
||||
container.value.style.height = `${containerHeight}px`;
|
||||
} else {
|
||||
if (calculatedPosition[1] + childHeight > containerHeight) {
|
||||
containerHeight = calculatedPosition[1] + childHeight;
|
||||
container.value.style.height = `${containerHeight}px`;
|
||||
}
|
||||
}
|
||||
|
||||
const options = Object.assign({}, props, {
|
||||
position: calculatedPosition,
|
||||
size: {
|
||||
width: childWidth,
|
||||
height: childHeight
|
||||
},
|
||||
containerHeight: containerHeight
|
||||
});
|
||||
|
||||
const calculatedStyle = animationManager.generate(options);
|
||||
|
||||
mixItemInlineStyle(calculatedStyle);
|
||||
|
||||
Object.assign(node.style, calculatedStyle);
|
||||
|
||||
props.onItemDidLayout(node);
|
||||
|
||||
if (i + 1 === children.length) {
|
||||
props.onContainerDidLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateChildren();
|
||||
})
|
||||
|
||||
onUpdated(() => {
|
||||
updateChildren();
|
||||
})
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
// 接口地址
|
||||
export const RECORD_URL = "clyx9ba3a0000qwrb2mjd25sd"
|
||||
// 菜单项
|
||||
export const MENU_JSON = "clyzxul91000mqorb1w503q2o"
|
||||
// 系统名称
|
||||
export const SYSTEM_TITLE = "cm64rpfik0000egrb3x33hbhj"
|
||||
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<div :class="$style['header']">
|
||||
<!-- <img src="/logo.png" height="80"> -->
|
||||
<el-row :style="{ width: '100%' }">
|
||||
<el-col :span="3">
|
||||
<div class="system-name">
|
||||
{{systemTitle||'...'}}
|
||||
<!-- <img src="/logo.png" height="60"> -->
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="21">
|
||||
<div :class="$style['header-content']">
|
||||
<el-dropdown trigger="click" :class="$style['user-panel']">
|
||||
<div ref="userPopup" class="header-user">
|
||||
<span class="name" :style="{ cursor: 'pointer' }">
|
||||
<el-link>
|
||||
{{ appStore.userInfo?.userName }}
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="openPwdDialog">更改密码</el-dropdown-item>
|
||||
<el-dropdown-item @click="onLogout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<pwd-dialog ref="pwdRef" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Cookies from "js-cookie";
|
||||
import { useAppStore } from "@/store/app";
|
||||
import PwdDialog from "@/containers/PwdDialog/index.vue";
|
||||
import { ref, onBeforeMount } from "vue";
|
||||
import {
|
||||
ArrowDown
|
||||
} from "@element-plus/icons-vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { SYSTEM_TITLE } from "@/consts/dataDict";
|
||||
import * as api from "@/common/api";
|
||||
|
||||
const appStore = useAppStore();
|
||||
const pwdRef = ref<any>();
|
||||
const router=useRouter();
|
||||
const systemTitle = ref();
|
||||
|
||||
(async () => {
|
||||
const { data: dataDict } = await api.getDynamic({ id: SYSTEM_TITLE }, "dataDict");
|
||||
systemTitle.value = dataDict?.value;
|
||||
}
|
||||
)();
|
||||
|
||||
onBeforeMount(() => {
|
||||
const userInfo = Cookies.get("UserInfo");
|
||||
try {
|
||||
const uI = JSON.parse(userInfo);
|
||||
if (!uI?.id) {
|
||||
router.push("/login");
|
||||
return;
|
||||
}
|
||||
appStore.saveUserInfo(uI);
|
||||
} catch (error) {
|
||||
router.push("/login");
|
||||
}
|
||||
})
|
||||
|
||||
const onLogout = () => {
|
||||
Cookies.remove("Authorization")
|
||||
window.location.href = '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
const openPwdDialog = () => {
|
||||
pwdRef.value?.show();
|
||||
};
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.header) {
|
||||
height: 80px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
.system-name {
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
line-height: 80px;
|
||||
background: #002140;
|
||||
// display: inline-block;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
width: 100%;
|
||||
line-height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
:local(.header-content) {
|
||||
box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
|
||||
height: 80px; // calc(100% - 4px);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
:local(.user-panel) {
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div :style="style" :class="$style['image-cell']" @click="$emit('show', id)">
|
||||
<div :class="$style['img-container']">
|
||||
<div class="img-box">
|
||||
<img :src="src">
|
||||
<div class="footer">
|
||||
<div>
|
||||
<div>时间:{{ fDT(info?.time) }}</div>
|
||||
<div>置信度:{{ toFixed((info?.confidence || 0) / 100) }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>类型:{{ getObjectTypeName(info?.objectType) }}</div>
|
||||
<div>地点:{{ info?.deviceName || '--' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { toFixed, getObjectTypeName } from "@/common/tool"
|
||||
import { fDT } from "funjialib";
|
||||
|
||||
const props = defineProps<{
|
||||
id: any,
|
||||
src: string,
|
||||
confidence: any,
|
||||
info: any,
|
||||
style: any
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(n: 'show', id: any): void
|
||||
}>();
|
||||
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.image-cell) {
|
||||
:local(.img-container) {
|
||||
padding: 0 10px 10px 10px;
|
||||
width: calc(100% - 20px);
|
||||
height: calc(100% - 40px);
|
||||
|
||||
.img-box {
|
||||
background-color: #d3d3d3;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
img {
|
||||
object-fit: contain;
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100px;
|
||||
// border: 2px solid #989898;
|
||||
color: #000;
|
||||
border: 0;
|
||||
// border-left-width: 6px;
|
||||
height: 50px;
|
||||
width: 100%; //calc(100% - 8px);
|
||||
// line-height: 36px;
|
||||
padding-left: 4px;
|
||||
font-size: 14px;
|
||||
background-color: #FFF;
|
||||
|
||||
&>div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 4px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div :class="$style['image-list']">
|
||||
<fixed-size-grid :key="gridKey" :columnCount="columnCount" :columnWidth="304" :height="containerHeight || 600"
|
||||
:rowCount="rowCount" :rowHeight="240" :width="1560">
|
||||
<template v-slot:default="slotProps">
|
||||
<image-cell v-if="isShowColumn(slotProps)" :key="getData(slotProps)?.id || slotProps.key"
|
||||
:style="slotProps.style" :id="getData(slotProps)?.id" :src="getData(slotProps)?.objectUrl"
|
||||
:confidence="getData(slotProps)?.confidence" :info="{ ...getData(slotProps) }"
|
||||
@show="(id) => $emit('show', id)">
|
||||
</image-cell>
|
||||
</template>
|
||||
</fixed-size-grid>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { FixedSizeGrid } from '@kousum/vue3-window';
|
||||
import ImageCell from "./ImageCell.vue";
|
||||
import { watch, ref, computed } from "vue";
|
||||
|
||||
const props = withDefaults(defineProps<{ data: any[], containerHeight: number }>(), {
|
||||
containerHeight: 600
|
||||
});
|
||||
const emit = defineEmits<{
|
||||
(n: 'show', id: any): void
|
||||
}>();
|
||||
|
||||
|
||||
const gridKey = ref(-1);
|
||||
const columnCount = ref(5);
|
||||
|
||||
watch(() => props.data, (v) => {
|
||||
gridKey.value = new Date().getTime();
|
||||
})
|
||||
|
||||
const rowCount = computed(() => {
|
||||
const len = props.data?.length || 0;
|
||||
let _rowCount = len / columnCount.value;
|
||||
if (len % columnCount.value) {
|
||||
_rowCount += 1;
|
||||
}
|
||||
return _rowCount;
|
||||
})
|
||||
|
||||
const getData = (prop) => {
|
||||
return props.data?.[prop.rowIndex * columnCount.value + prop.columnIndex];
|
||||
}
|
||||
|
||||
const isShowColumn = (prop) => {
|
||||
return (props.data?.length || 0) > prop.rowIndex * columnCount.value + prop.columnIndex;
|
||||
}
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.image-list) {
|
||||
width: 1400px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<el-form ref="formRef" label-width="80px" :model="formModel" :rules="rules">
|
||||
<el-form-item label="用户名">
|
||||
<span>{{ appStore.userinfo.userName }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="原密码" prop="oldPassword">
|
||||
<el-input placeholder="请输入" show-password v-model="formModel.oldPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input placeholder="6-18个字母,区分大小写" show-password v-model="formModel.newPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="newPassword2">
|
||||
<el-input placeholder="请再次输入密码" show-password v-model="formModel.newPassword2" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export interface PwdFormRefProps {
|
||||
submit: () => void;
|
||||
}
|
||||
|
||||
interface FormDataProps {
|
||||
oldPassword: string;
|
||||
newPassword: string;
|
||||
newPassword2: string;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from "vue";
|
||||
import type { FormItemRule } from "element-plus";
|
||||
import { useAppStore } from "@/store";
|
||||
|
||||
/**
|
||||
* emit
|
||||
*/
|
||||
const emit = defineEmits<{
|
||||
(e: "onLoading", v: boolean): void;
|
||||
(e: "onSuccess"): void;
|
||||
}>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const formRef = ref();
|
||||
const formModel = reactive<FormDataProps>({
|
||||
oldPassword: "",
|
||||
newPassword: "",
|
||||
newPassword2: "",
|
||||
});
|
||||
const rules = ref<Record<string, FormItemRule | FormItemRule[]>>({
|
||||
oldPassword: {
|
||||
required: true,
|
||||
message: "请输入原密码",
|
||||
},
|
||||
newPassword: {
|
||||
required: true,
|
||||
message: "请输入新密码",
|
||||
},
|
||||
newPassword2: {
|
||||
required: true,
|
||||
message: "请确认新密码",
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
const onUpdate = () => {
|
||||
setTimeout(() => {
|
||||
emit("onLoading", false);
|
||||
emit("onSuccess");
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
/**
|
||||
* 提交表单
|
||||
*/
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
emit("onLoading", true);
|
||||
onUpdate();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 暴露给父组件
|
||||
*/
|
||||
defineExpose({
|
||||
submit: onSubmit,
|
||||
} as PwdFormRefProps);
|
||||
</script>
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<um-dialog v-model="visible" title="修改密码" width="328px" :footer="false">
|
||||
<um-table-form :target="UpdatePassword" :data="formData" @ok="onResetSubmit" @cancel="onResetCancel">
|
||||
</um-table-form>
|
||||
</um-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export interface PwdDialogRefProps {
|
||||
/**
|
||||
* 打开弹窗
|
||||
*/
|
||||
show: () => void;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import PwdForm, { PwdFormRefProps } from "./PwdForm.vue";
|
||||
import { UmTableForm,UmDialog } from "funjiaui";
|
||||
import { UpdatePassword } from "@/containers/viewModel/UpdatePassword";
|
||||
import { useAppStore } from "@/store/app";
|
||||
import * as api from "@/common/api";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useRouter } from "vue-router";
|
||||
import md5 from "md5";
|
||||
import { encode } from "@/common/tool"
|
||||
|
||||
/**
|
||||
* emit
|
||||
*/
|
||||
const emit = defineEmits<{
|
||||
(e: "onSuccess"): void;
|
||||
}>();
|
||||
|
||||
const router = useRouter();
|
||||
const visible = ref<boolean>(false);
|
||||
const formRef = ref<PwdFormRefProps>();
|
||||
const loading = ref<boolean>(false);
|
||||
const app = useAppStore();
|
||||
const formData = ref<any>({
|
||||
userName: app.userInfo?.userName,
|
||||
});
|
||||
|
||||
/**
|
||||
* 修改loading状态
|
||||
*/
|
||||
const onLoading = (v: boolean) => {
|
||||
loading.value = v;
|
||||
};
|
||||
|
||||
/**
|
||||
* 表单操作成功
|
||||
*/
|
||||
const onSuccess = () => {
|
||||
visible.value = false;
|
||||
loading.value = false;
|
||||
emit("onSuccess");
|
||||
};
|
||||
|
||||
/**
|
||||
* 提交表单
|
||||
*/
|
||||
const onOk = () => {
|
||||
formRef.value?.submit();
|
||||
};
|
||||
|
||||
const onResetSubmit = async (formData: any) => {
|
||||
const params = {
|
||||
old_password: md5(formData.oldPassword),
|
||||
new_password: encode(formData.password),
|
||||
};
|
||||
|
||||
const { status, reason } = await api.udpdatePwd(params);
|
||||
if (status != "200") {
|
||||
ElMessage.error(reason || "修改失败");
|
||||
} else {
|
||||
ElMessage.success("修改密码成功,3秒内将退出登录");
|
||||
setTimeout(() => {
|
||||
router.push("/login");
|
||||
}, 3000);
|
||||
}
|
||||
};
|
||||
|
||||
const onResetCancel = (value: boolean) => {
|
||||
visible.value = value;
|
||||
};
|
||||
|
||||
/**
|
||||
* 暴露给父组件
|
||||
*/
|
||||
defineExpose({
|
||||
show: () => {
|
||||
visible.value = true;
|
||||
},
|
||||
} as PwdDialogRefProps);
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,149 @@
|
||||
|
||||
import 'reflect-metadata';
|
||||
import { UmTableForm,
|
||||
TableColumnPropertyDecorator as tcpd,
|
||||
TableFormColumnPropertyDecorator as tfcpd,
|
||||
TableColumnMethodDecorator as tcmd,
|
||||
TableSearchFormPropertyDecorator as tsfpd
|
||||
} from "funjiaui";
|
||||
import * as api from "@/common/api"
|
||||
// 数据字典
|
||||
const tableName = "dataDict";
|
||||
|
||||
const isShow = (rowData: any) => {
|
||||
if (rowData?.source_add_type == "1") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 数据字典
|
||||
export default class DataDict {
|
||||
// 侵入性事件注入
|
||||
static singleListen: any = null
|
||||
|
||||
static isEdit = false;
|
||||
|
||||
// 操作列宽度
|
||||
static operateWidth = "140px";
|
||||
|
||||
@tcpd({ "lang": "", "def": "数据", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "id", fieldType: "primaryKey" })
|
||||
id: number = 0;
|
||||
|
||||
@tcpd({ "lang": "", "def": "唯一标识", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "唯一标识", fieldType: "string", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
unionKey: string = ""
|
||||
|
||||
@tcpd({ "lang": "", "def": "数据", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "数据", fieldType: "string", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
value: string = ""
|
||||
|
||||
@tcpd({ "lang": "", "def": "描述", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "描述", fieldType: "string", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
desc: string = ""
|
||||
|
||||
@tcmd({ "key": "table:searchFormMethod", "value": { "type": "getList", "es": "onAfter" } })
|
||||
getList = async (params: any) => {
|
||||
return await api.getDynamicList(params, tableName);
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"key": "table:toolbar", "value": {
|
||||
"type": "添加", "priority": 1, "es": "onAfter", "dialogContent": UmTableForm, "dialogTitle": "增加", "dialogWidth": 650
|
||||
}
|
||||
})
|
||||
onAdd = async (data: any) => {
|
||||
const { code, msg } = await api.addDynamic({ ...data, unionKey: data.unionKey.toUpperCase() }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情数据
|
||||
*/
|
||||
@tcmd({ "value": { "type": "edit", "es": "onBefore", "dialogContent": UmTableForm, "dialogTitle": "编辑" } })
|
||||
getDetail = async (rowId: number, r, meta) => {
|
||||
const { data } = await api.getDynamic({ id: rowId }, tableName);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "edit", "es": "onAfter",
|
||||
sort: 2,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
onEdit = async (params: any) => {
|
||||
const { code, msg } = await api.updateDynamic({ ...params, unionKey: params.unionKey.toUpperCase() }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "del", "es": "onAfter", "dialogContent": "确定要删除该条数据吗?",
|
||||
sort: 3,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
delByIds = async (rowId: number) => {
|
||||
const { code, msg } = await api.deleteDynamic({ ids: [rowId] }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@tcmd({ "key": "table:toolbar", "value": { "type": "批量删除", "priority": 5, "es": "onAfter", "dialogContent": "确定要删除选择的数据吗?" } })
|
||||
onMutilDel = async (ids: any[]) => {
|
||||
const { code, msg } = await api.deleteDynamic({ ids }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
exportText(filename, text) {
|
||||
var element = document.createElement('a');
|
||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
||||
element.setAttribute('download', filename);
|
||||
|
||||
element.style.display = 'none';
|
||||
document.body.appendChild(element);
|
||||
|
||||
element.click();
|
||||
|
||||
document.body.removeChild(element);
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"key": "table:toolbar", "value": {
|
||||
"type": "自定义", id: "anki", "priority": 1, "es": "onAfter", title: "导出字典常量表"
|
||||
}
|
||||
})
|
||||
onExport = async (params: any) => {
|
||||
const { data } = await api.getDynamicList({ ...params, page: 1, pageSize: 10000 }, tableName);
|
||||
|
||||
const content = data.map(item => {
|
||||
return `export const ${item.unionKey} = "${item.id}"`;
|
||||
}).join("\n")
|
||||
|
||||
this.exportText("dataDict.ts", content);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import 'reflect-metadata';
|
||||
import {
|
||||
TableColumnPropertyDecorator as tcpd,
|
||||
TableFormColumnPropertyDecorator as tfcpd,
|
||||
TableColumnMethodDecorator as tcmd, TOperateType,
|
||||
TableSearchFormPropertyDecorator as tsfpd,
|
||||
UmTableForm
|
||||
} from "funjiaui";
|
||||
import * as api from "@/common/api"
|
||||
|
||||
|
||||
export default class Employee {
|
||||
@tfcpd({ "lang": "", "def": "id", fieldType: "primaryKey" })
|
||||
id: number = 0;
|
||||
|
||||
@tcpd({ "lang": "", "def": "姓名", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "姓名", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
name: string = "";
|
||||
|
||||
@tcpd({ "lang": "", "def": "用戶名", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "用戶名", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
userName: string = "";
|
||||
|
||||
@tfcpd({ "lang": "", "def": "密码", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
pwd: string = "";
|
||||
|
||||
@tcpd({ "lang": "", "def": "手机号", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "手机号", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
phone: string = "";
|
||||
|
||||
@tcpd({ "lang": "", "def": "车牌号码", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "车牌号码", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
vehiclePlateNumber: string = "";
|
||||
|
||||
@tcpd({ "lang": "", "def": "用户信息图片地址", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "用户信息图片地址", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
userInfoPic: string = "";
|
||||
|
||||
@tcpd({ "lang": "", "def": "通知总数", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "通知总数", fieldType: "number", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
noticeTotal: number = 0;
|
||||
|
||||
@tcpd({ "lang": "", "def": "备注", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "备注" })
|
||||
remark: string = "";
|
||||
|
||||
@tcmd({ "key": "table:searchFormMethod", "value": { "type": "getList", "es": "onAfter" } })
|
||||
getList = async (params: any) => {
|
||||
return await api.getEmployeeList(params);
|
||||
}
|
||||
|
||||
// @tcmd({
|
||||
// "key": "table:toolbar", "value": {
|
||||
// "type": "添加", "priority": 1, "es": "onAfter", "dialogContent": UmTableForm, "dialogTitle": "增加", "dialogWidth": 650
|
||||
// }
|
||||
// })
|
||||
// onAdd = async (data: any) => {
|
||||
// const { code, msg } = await api.addEmployee(data);
|
||||
// if (code != 0) {
|
||||
// return { code: 1, message: msg };
|
||||
// }
|
||||
// else {
|
||||
// return { code: 0 };
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取详情数据
|
||||
*/
|
||||
@tcmd({ "value": { "type": "edit", "es": "onBefore", "dialogContent": UmTableForm, "dialogTitle": "编辑" } })
|
||||
getDetail = async (rowId: number, r, meta) => {
|
||||
const { data } = await api.getEmployee({ id: rowId });
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "edit", "es": "onAfter",
|
||||
sort: 2,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
onEdit = async (params: any) => {
|
||||
params.source_type = "IPC";
|
||||
params.forever = true;
|
||||
|
||||
const { code, msg } = await api.updateEmployee(params);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// @tcmd({
|
||||
// "value": {
|
||||
// "type": "del", "es": "onAfter", "dialogContent": "确定要删除该条数据吗?",
|
||||
// sort: 3,
|
||||
// // isShow
|
||||
// }
|
||||
// })
|
||||
// delByIds = async (rowId: number) => {
|
||||
// const { code, msg } = await api.deleteEmployee({ ids: [rowId] });
|
||||
// if (code != 0) {
|
||||
// return { code: 1, message: msg };
|
||||
// }
|
||||
// else {
|
||||
// return { code: 0 };
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
|
||||
import 'reflect-metadata';
|
||||
import {
|
||||
TableColumnPropertyDecorator as tcpd,
|
||||
TableFormColumnPropertyDecorator as tfcpd,
|
||||
TableColumnMethodDecorator as tcmd, TOperateType,
|
||||
TableSearchFormPropertyDecorator as tsfpd,
|
||||
UmTableForm
|
||||
} from "funjiaui";
|
||||
import * as api from "@/common/api"
|
||||
// import { ElMessage } from 'element-plus'
|
||||
import { h } from 'vue';
|
||||
|
||||
const isShow = (rowData: any) => {
|
||||
if (rowData?.source_add_type == "1") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default class Notice {
|
||||
// 侵入性事件注入
|
||||
static singleListen: any = null
|
||||
|
||||
static isEdit = false;
|
||||
|
||||
// 操作列宽度
|
||||
static operateWidth = "140px";
|
||||
|
||||
@tfcpd({ "lang": "", "def": "id", fieldType: "primaryKey" })
|
||||
id: number = 0;
|
||||
|
||||
@tcpd({ "lang": "", "def": "消息", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "消息", fieldType: "string", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
message: string = ""
|
||||
|
||||
@tcpd({ "lang": "", "def": "排序", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "排序", fieldType: "number", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
sort: number = 1;
|
||||
|
||||
static userId: any;
|
||||
|
||||
@tcmd({ "key": "table:searchFormMethod", "value": { "type": "getList", "es": "onAfter" } })
|
||||
getList = async (params: any) => {
|
||||
return await api.getNoticeList(params);
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"key": "table:toolbar", "value": {
|
||||
"type": "添加", "priority": 1, "es": "onAfter", "dialogContent": UmTableForm, "dialogTitle": "增加", "dialogWidth": 650
|
||||
}
|
||||
})
|
||||
onAdd = async (data: any) => {
|
||||
const { code, msg } = await api.addNotice({ ...data, userId: Notice.userId });
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情数据
|
||||
*/
|
||||
@tcmd({ "value": { "type": "edit", "es": "onBefore", "dialogContent": UmTableForm, "dialogTitle": "编辑" } })
|
||||
getDetail = async (rowId: number, r, meta) => {
|
||||
const { data } = await api.getNotice({ id: rowId });
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "edit", "es": "onAfter",
|
||||
sort: 2,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
onEdit = async (params: any) => {
|
||||
const { code, msg } = await api.updateNotice({ ...params, userId: Notice.userId });
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "del", "es": "onAfter", "dialogContent": "确定要删除该条数据吗?",
|
||||
sort: 3,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
delByIds = async (rowId: number) => {
|
||||
const { code, msg } = await api.deleteNotice({ ids: [rowId] });
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// @tcmd({
|
||||
// "value": {
|
||||
// "id": 1, "type": "customOperateEvent", "title": "详情",
|
||||
// sort: 1,
|
||||
// isShow: (rowData) => {
|
||||
// if (rowData?.snaper_image > 0) {
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// jumpEmployee = (rowId: number) => {
|
||||
// return rowId;
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
|
||||
import 'reflect-metadata';
|
||||
import {
|
||||
TableColumnPropertyDecorator as tcpd,
|
||||
TableFormColumnPropertyDecorator as tfcpd,
|
||||
TableColumnMethodDecorator as tcmd,
|
||||
TableSearchFormPropertyDecorator as tsfpd,
|
||||
UmTableForm
|
||||
} from "funjiaui";
|
||||
import * as api from "@/common/api"
|
||||
import { h, ref } from 'vue';
|
||||
import SingleUpload from '@/components/SingleUpload.vue';
|
||||
import axios from 'axios';
|
||||
|
||||
// 插件模块
|
||||
const tableName = "plugin";
|
||||
|
||||
const isShow = (rowData: any) => {
|
||||
if (rowData?.source_add_type == "1") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default class Plugin2 {
|
||||
// 侵入性事件注入
|
||||
static singleListen: any = null
|
||||
|
||||
static isEdit = false;
|
||||
|
||||
// 操作列宽度
|
||||
static operateWidth = "140px";
|
||||
|
||||
@tfcpd({ "lang": "", "def": "id", fieldType: "primaryKey" })
|
||||
id: number = 0;
|
||||
|
||||
questionId: string = ""
|
||||
|
||||
@tcpd({ "lang": "", "def": "名称", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "名称", fieldType: "string", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
name: string = ""
|
||||
|
||||
@tcpd({ "lang": "", "def": "描述", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "描述", fieldType: "string", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
desc: string = ""
|
||||
|
||||
@tcpd({ "lang": "", "def": "插件脚本绝对地址", minWidth: 120 })
|
||||
@tfcpd({
|
||||
"lang": "", "def": "插件脚本绝对地址", component: function (props) {
|
||||
const value = ref<any>();
|
||||
const that = this;
|
||||
return h(SingleUpload, {
|
||||
modelValue: value,
|
||||
"onFileChange": async (data) => {
|
||||
const fdata = new FormData();
|
||||
fdata.append("file", data);
|
||||
const res = await axios.post('/api/upload/file', fdata);
|
||||
value.value = res.data?.url
|
||||
// this.$emit("");
|
||||
// debugger;
|
||||
// console.log(res.data?.url,props);
|
||||
props['onUpdate:modelValue']?.(res.data?.url);
|
||||
}
|
||||
})
|
||||
},
|
||||
rule: [{ "type": "require", message: "不能为空" }]
|
||||
})
|
||||
pluginUrl: string = ""
|
||||
|
||||
@tcmd({ "key": "table:searchFormMethod", "value": { "type": "getList", "es": "onAfter" } })
|
||||
getList = async (params: any) => {
|
||||
return await api.getDynamicList(params, tableName);
|
||||
// return [];
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"key": "table:toolbar", "value": {
|
||||
"type": "添加", "priority": 1, "es": "onAfter", "dialogContent": UmTableForm, "dialogTitle": "增加", "dialogWidth": 650
|
||||
}
|
||||
})
|
||||
onAdd = async (data: any) => {
|
||||
const { code, msg } = await api.addDynamic({ ...data }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情数据
|
||||
*/
|
||||
@tcmd({ "value": { "type": "edit", "es": "onBefore", "dialogContent": UmTableForm, "dialogTitle": "编辑" } })
|
||||
getDetail = async (rowId: number, r, meta) => {
|
||||
const { data } = await api.getDynamic({ id: rowId }, tableName);
|
||||
return data;
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "edit", "es": "onAfter",
|
||||
sort: 2,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
onEdit = async (params: any) => {
|
||||
const { code, msg } = await api.updateDynamic({ ...params }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "del", "es": "onAfter", "dialogContent": "确定要删除该条数据吗?",
|
||||
sort: 3,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
delByIds = async (rowId: number) => {
|
||||
const { code, msg } = await api.deleteDynamic({ ids: [rowId] }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@tcmd({ "key": "table:toolbar", "value": { "type": "批量删除", "priority": 5, "es": "onAfter", "dialogContent": "确定要删除选择的数据吗?" } })
|
||||
onMutilDel = async (ids: any[]) => {
|
||||
const { code, msg } = await api.deleteDynamic({ ids }, tableName);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
import 'reflect-metadata';
|
||||
// import {
|
||||
// TableColumnPropertyDecorator as tcpd,
|
||||
// TableFormColumnPropertyDecorator as tfcpd,
|
||||
// TableColumnMethodDecorator as tcmd, TOperateType,
|
||||
// TableSearchFormPropertyDecorator as tsfpd
|
||||
// } from "@/components/UmTable";
|
||||
import * as api from "@/common/api"
|
||||
// import UmTableForm from '@/components/UmTable/UmTableForm.vue';
|
||||
|
||||
import { UmTableForm,
|
||||
TableColumnPropertyDecorator as tcpd,
|
||||
TableFormColumnPropertyDecorator as tfcpd,
|
||||
TableColumnMethodDecorator as tcmd, TOperateType,
|
||||
TableSearchFormPropertyDecorator as tsfpd
|
||||
} from "funjiaui";
|
||||
// import {
|
||||
// TableColumnPropertyDecorator as tcpd,
|
||||
// TableFormColumnPropertyDecorator as tfcpd,
|
||||
// TableColumnMethodDecorator as tcmd, TOperateType,
|
||||
// TableSearchFormPropertyDecorator as tsfpd
|
||||
// } from "funjiaui/UmTable";
|
||||
|
||||
|
||||
import DynamicTags from '@/components/DynamicTags.vue';
|
||||
// import { ElButton, ElInput, ElTag,ElDialog } from 'element-plus';
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
|
||||
|
||||
export default class QA {
|
||||
@tcpd({ "lang": "", "def": "id", width: 240 })
|
||||
@tfcpd({ "lang": "", "def": "id", fieldType: "primaryKey" })
|
||||
id: number = 0;
|
||||
|
||||
@tsfpd({ lang: "", "def": "题目" })
|
||||
@tcpd({ "lang": "", "def": "题目", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "题目", rule: [{ "type": "require", message: "不能为空" }], component: Codemirror })
|
||||
question: string = "";
|
||||
|
||||
// @tcpd({ "lang": "", "def": "答案", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "答案", component: Codemirror, width: 300 })
|
||||
answer: string = "";
|
||||
|
||||
@tcpd({ "lang": "", "def": "标签", minWidth: 120 })
|
||||
@tfcpd({ "lang": "", "def": "标签", component: DynamicTags, width: 300 })
|
||||
@tsfpd({
|
||||
lang: "", "def": "标签", fieldType: "select", async getData() {
|
||||
return {
|
||||
data: [{
|
||||
label: "vue3",
|
||||
value: "vue3"
|
||||
}, {
|
||||
label: "react",
|
||||
value: "react"
|
||||
}, {
|
||||
label: "js",
|
||||
value: "js"
|
||||
}, {
|
||||
label: "html",
|
||||
value: "html"
|
||||
}, {
|
||||
label: "css",
|
||||
value: "css"
|
||||
}, {
|
||||
label: "webpack",
|
||||
value: "webpack"
|
||||
}, {
|
||||
label: "微信小程序",
|
||||
value: "微信小程序"
|
||||
}, {
|
||||
label: "typescript",
|
||||
value: "typescript"
|
||||
}, {
|
||||
label: "boss_vue",
|
||||
value: "boss_vue"
|
||||
}, {
|
||||
label: "高频_css",
|
||||
value: "高频_css"
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
tag: string[] = [];
|
||||
|
||||
@tcmd({ "key": "table:searchFormMethod", "value": { "type": "getList", "es": "onAfter" } })
|
||||
getList = async (params: any) => {
|
||||
return await api.getQAList(params);
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"key": "table:toolbar", "value": {
|
||||
"type": "添加", "priority": 1, "es": "onAfter", "dialogContent": UmTableForm, "dialogTitle": "增加", "dialogWidth": 1200
|
||||
}
|
||||
})
|
||||
onAdd = async (data: any) => {
|
||||
const { code, msg } = await api.addQA({ ...data });
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
exportText(filename, text) {
|
||||
var element = document.createElement('a');
|
||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
||||
element.setAttribute('download', filename);
|
||||
|
||||
element.style.display = 'none';
|
||||
document.body.appendChild(element);
|
||||
|
||||
element.click();
|
||||
|
||||
document.body.removeChild(element);
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"key": "table:toolbar", "value": {
|
||||
"type": "自定义", "priority": 1, "es": "onAfter", title: "导出anki脚本"
|
||||
}
|
||||
})
|
||||
onExport = async (params: any) => {
|
||||
const { data } = await api.getQAList({ ...params, page: 1, pageSize: 10000 });
|
||||
const head = `#separator:tab
|
||||
#html:true
|
||||
#tags column:3
|
||||
`
|
||||
const style = `<style>iframe{width:100%;height:90vh;}</style>`;
|
||||
|
||||
const content = data.map(item => {
|
||||
return `"${style}<iframe src=""http://192.168.6.130:5176/#/question?id=${item.id}"" frameborder=""0""></iframe><br>" "${style}<iframe src=""http://192.168.6.130:5176/#/answer?id=${item.id}"" frameborder=""0""></iframe><br>"`;
|
||||
}).join("\n")
|
||||
|
||||
this.exportText("anki脚本.txt", head + content);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情数据
|
||||
*/
|
||||
@tcmd({ "value": { "type": "edit", "es": "onBefore", "dialogContent": UmTableForm, "dialogTitle": "编辑", "dialogWidth": 1200 } })
|
||||
getDetail = async (rowId: number, r, meta) => {
|
||||
const { data } = await api.getQA({ id: rowId });
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "edit", "es": "onAfter",
|
||||
sort: 2,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
onEdit = async (params: any) => {
|
||||
const { code, msg } = await api.updateQA({ ...params });
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "del", "es": "onAfter", "dialogContent": "确定要删除该条数据吗?",
|
||||
sort: 3,
|
||||
dialogWidth: 400
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
delByIds = async (rowId: number) => {
|
||||
const { code, msg } = await api.deleteQA({ ids: [rowId] });
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// @tcmd({
|
||||
// "key": "table:toolbar", "value": {
|
||||
// "type": "添加", "priority": 1, "es": "onAfter", "dialogContent": UmTableForm, "dialogTitle": "增加", "dialogWidth": 650
|
||||
// }
|
||||
// })
|
||||
// onAdd = async (data: any) => {
|
||||
// const { code, msg } = await api.addQA(data);
|
||||
// if (code != 0) {
|
||||
// return { code: 1, message: msg };
|
||||
// }
|
||||
// else {
|
||||
// return { code: 0 };
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取详情数据
|
||||
*/
|
||||
@tcmd({ "value": { "type": "edit", "es": "onBefore", "dialogContent": UmTableForm, "dialogTitle": "编辑", dialogWidth: 1200 } })
|
||||
getDetail = async (rowId: number, r, meta) => {
|
||||
const { data } = await api.getQA({ id: rowId });
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@tcmd({
|
||||
"value": {
|
||||
"type": "edit", "es": "onAfter",
|
||||
sort: 2,
|
||||
// isShow
|
||||
}
|
||||
})
|
||||
onEdit = async (params: any) => {
|
||||
const { code, msg } = await api.updateQA(params);
|
||||
if (code != 0) {
|
||||
return { code: 1, message: msg };
|
||||
}
|
||||
else {
|
||||
return { code: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// @tcmd({
|
||||
// "value": {
|
||||
// "type": "del", "es": "onAfter", "dialogContent": "确定要删除该条数据吗?",
|
||||
// sort: 3,
|
||||
// // isShow
|
||||
// }
|
||||
// })
|
||||
// delByIds = async (rowId: number) => {
|
||||
// const { code, msg } = await api.deleteQA({ ids: [rowId] });
|
||||
// if (code != 0) {
|
||||
// return { code: 1, message: msg };
|
||||
// }
|
||||
// else {
|
||||
// return { code: 0 };
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
import 'reflect-metadata';
|
||||
import {
|
||||
TableColumnPropertyDecorator as tcpd,
|
||||
TableFormColumnPropertyDecorator as tfcpd,
|
||||
TableColumnMethodDecorator as tcmd, TOperateType,
|
||||
TableSearchFormPropertyDecorator as tsfpd,
|
||||
UmTableForm
|
||||
} from "funjiaui";
|
||||
import * as api from "@/common/api"
|
||||
// import UmTableForm from '@/components/UmTable/UmTableForm.vue';
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
export class UpdatePassword {
|
||||
@tfcpd({ "lang": "", "def": "编号", "fieldType": "primaryKey" })
|
||||
id: number | string = 0;
|
||||
|
||||
// @tcpd({ lang: "name", def: "账号名称" })
|
||||
// @tfcpd({
|
||||
// "lang": "", "def": "账号名称", "fieldType": "default", rule: [{ "type": "require", message: "不能为空" }],
|
||||
// disabled: true
|
||||
// })
|
||||
// userName: string = "";
|
||||
|
||||
@tfcpd({ "lang": "", "def": "原密码", "fieldType": "password", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
oldPassword: string = "";
|
||||
|
||||
@tfcpd({ "lang": "", "def": "新密码", "fieldType": "password", rule: [{ "type": "require", message: "不能为空" }] })
|
||||
password: string = "";
|
||||
|
||||
@tfcpd({
|
||||
"lang": "", "def": "确认密码", "fieldType": "password", rule: [{
|
||||
"type": "require", message: "不能为空",
|
||||
}, {
|
||||
"type": "validator",
|
||||
validator: function (rule: any, value: any, callback: any) {
|
||||
const that: any = this;
|
||||
if (value != that.formData["password"]) {
|
||||
return new Error("两次输入的密码不对");
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
passwordConfirm: string = "";
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
|
||||
declare module 'vue-cropperjs';
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from "@/router";
|
||||
import { createPinia } from "pinia";
|
||||
import "./assets/icon/iconfont.css";
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.use(createPinia());
|
||||
app.mount('#app')
|
||||
@@ -0,0 +1,69 @@
|
||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
|
||||
import Employee from "@/views/Employee.vue";
|
||||
import Notice from "@/views/Notice.vue";
|
||||
import QA from "@/views/QA.vue";
|
||||
import DataDict from "@/views/DataDict.vue";
|
||||
import DynamicTable from "@/views/DynamicTable.vue";
|
||||
import Plugin from "@/views/Plugin.vue";
|
||||
|
||||
const routes: Array<RouteRecordRaw | any> = [
|
||||
{
|
||||
path: "/",
|
||||
component: () => import("@/views/Login.vue"),
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
component: () => import("@/views/Login.vue"),
|
||||
},
|
||||
{
|
||||
path: "/app",
|
||||
component: () => import("@/components/Layout.vue"),
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: Employee,
|
||||
},
|
||||
{
|
||||
path: "/app/Employee",
|
||||
component: Employee,
|
||||
},
|
||||
{
|
||||
path: "/app/Notice",
|
||||
component: Notice,
|
||||
},
|
||||
{
|
||||
path: "/app/QA",
|
||||
component: QA,
|
||||
},
|
||||
// {
|
||||
// path: "/app/tag",
|
||||
// component: Tag,
|
||||
// },
|
||||
{
|
||||
path: "/app/dynamicTable/:name/:path/:title?",
|
||||
// component: Record,
|
||||
component: DynamicTable,
|
||||
// 动态表格
|
||||
},
|
||||
{
|
||||
path: "/app/dataDict",
|
||||
component: DataDict,
|
||||
},
|
||||
{
|
||||
path: "/app/plugin",
|
||||
component: Plugin,
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// path: "/:pathMatch(.*)*",
|
||||
// component: () => import("@/views/NotFound/index.vue"),
|
||||
// },
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,24 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
interface AppType {
|
||||
userInfo: any;
|
||||
isMiniMenu: boolean;
|
||||
}
|
||||
|
||||
export const useAppStore = defineStore("app", {
|
||||
state: (): AppType => ({
|
||||
userInfo: {},
|
||||
isMiniMenu: false
|
||||
}),
|
||||
actions: {
|
||||
/**
|
||||
* 保存登录者信息
|
||||
*/
|
||||
saveUserInfo(payload: any) {
|
||||
this.userInfo = payload;
|
||||
},
|
||||
removeUserInfo() {
|
||||
this.userInfo = null;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
/** 图片预览图片索引切换类型值 */
|
||||
declare type TImgPreviewIdx = -1 | 1;
|
||||
|
||||
/**
|
||||
* 图片类型
|
||||
* 图片类型, 0:人脸, 1:自行车, 2:巴士, 3:小汽车, 4:电动车|摩托车, 5:人体, 6:三轮车,7货车、8车牌、9推车,10鸟、11猫,12 狗,13老鼠
|
||||
* "0 face","1 bicycle","2 bus","3 car","4 motorbike","5 person","6 tricycle","7 truck","8 carplate","9 pram","10 bird","11 cat", "12 dog", "13 mouse"
|
||||
*/
|
||||
declare type TObjectType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
|
||||
|
||||
/**
|
||||
* 订单状态
|
||||
* 0:待完成 1:已完成 2:已取消
|
||||
*/
|
||||
declare type TStatus = 0 | 1 | 2;
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div :class="$style['device-list']">
|
||||
<h2>数据字典列表</h2>
|
||||
<um-table-class-enhance class="role-right" :target="Record" :data="[]"
|
||||
:other-params="{ userId: appStore.userInfo?.id }" @data-change="onDataChange"
|
||||
@fire="onFire">
|
||||
</um-table-class-enhance>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// import UmTableClassEnhance from "@/components/UmTable/UmByClassEnhance.vue";
|
||||
import { UmByClassEnhance as UmTableClassEnhance } from "funjiaui";
|
||||
import Record from "@/containers/viewModel/DataDict";
|
||||
import ImgPreview from "@/components/ImgPreview.vue";
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { useAppStore } from "@/store/app";
|
||||
|
||||
const visible = ref(false);
|
||||
const imgIndex = ref(0);
|
||||
const ipcImgList = ref([]);
|
||||
const imgPreviewInfo = reactive({
|
||||
id: "",
|
||||
imgUrl: "",
|
||||
position: "",
|
||||
time: "",
|
||||
deviceName: ""
|
||||
});
|
||||
const currentDeviceId = ref(null);
|
||||
const appStore = useAppStore();
|
||||
// const formData = reactive<Notice>(traveInfomation)
|
||||
|
||||
|
||||
const onDataChange = (data) => {
|
||||
// ipcImgList.value = data || [];
|
||||
}
|
||||
|
||||
const onFire = async (key: string, value, data: any) => {
|
||||
// imgIndex.value = 0;
|
||||
// const resData = await api.getCaputreImgListByIpcId({ id: data })
|
||||
// ipcImgList.value = resData.data?.objectList || [];
|
||||
// initImgPreviewInfo(ipcImgList.value?.[0]);
|
||||
}
|
||||
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.device-list) {
|
||||
padding: 20px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
:local(.img-preview-dialog) {
|
||||
:local(.footer) {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
>div {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div :class="$style['device-list']">
|
||||
<h2>{{ router.params?.title || router.params?.name }}</h2>
|
||||
<um-table-class-enhance v-if="obj" class="role-right" :target="obj" :data="[]"
|
||||
:other-params="{ userId: appStore.userInfo?.id }" @data-change="onDataChange" @fire="onFire">
|
||||
</um-table-class-enhance>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// import UmTableClassEnhance from "@/components/UmTable/UmByClassEnhance.vue";
|
||||
import { UmByClassEnhance as UmTableClassEnhance } from "funjiaui";
|
||||
// import UmDialog from "@/components/UmDialog/index.vue";
|
||||
// import RecordUser from "@/containers/viewModel/RecordUser";
|
||||
// import ImgPreview from "@/components/ImgPreview.vue";
|
||||
import { ref, reactive, watch, onMounted } from "vue";
|
||||
import { useAppStore } from "@/store/app";
|
||||
// import ThirdPartyLoader from "@/common/ThirdPartyLoader"
|
||||
import { useRoute, onBeforeRouteUpdate } from "vue-router";
|
||||
|
||||
// async function loadModuleFromUrl(url) {
|
||||
// const response = await fetch(url);
|
||||
// const moduleCode = await response.text();
|
||||
|
||||
// // 创建一个新的模块
|
||||
// const module = new Function('module', 'exports', moduleCode);
|
||||
|
||||
// // 执行模块
|
||||
// const exports = {};
|
||||
// module({ exports });
|
||||
|
||||
// return exports;
|
||||
// }
|
||||
|
||||
class ThirdPartyLoader {
|
||||
loadedModules: any = {};
|
||||
constructor() {
|
||||
this.loadedModules = {};
|
||||
}
|
||||
|
||||
loadModule(moduleName, url) {
|
||||
if (!this.loadedModules[moduleName]) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
script.src = url;
|
||||
script.onload = () => {
|
||||
this.loadedModules[moduleName] = true;
|
||||
resolve();
|
||||
};
|
||||
script.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const visible = ref(false);
|
||||
const imgIndex = ref(0);
|
||||
const ipcImgList = ref([]);
|
||||
const imgPreviewInfo = reactive({
|
||||
id: "",
|
||||
imgUrl: "",
|
||||
position: "",
|
||||
time: "",
|
||||
deviceName: ""
|
||||
});
|
||||
const currentDeviceId = ref(null);
|
||||
const appStore = useAppStore();
|
||||
const obj = ref(null);
|
||||
const router = useRoute();
|
||||
|
||||
// const formData = reactive<Notice>(traveInfomation)
|
||||
|
||||
function capitalizeFirstLetter(str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
const { name, path } = router.params;
|
||||
await new ThirdPartyLoader().loadModule(name, "/static/" + path + ".js")
|
||||
// console.log(window[capitalizeFirstLetter(name)]);
|
||||
obj.value = window[capitalizeFirstLetter(name)];
|
||||
// 使用示例
|
||||
// loadModuleFromUrl('/box-admin.iife.js').then(module => {
|
||||
// // 在这里使用导入的模块
|
||||
// // const t=new module;
|
||||
// console.log(module);
|
||||
// });
|
||||
|
||||
})
|
||||
|
||||
watch(() => router.params.name, async () => {
|
||||
const { name, path } = router.params;
|
||||
await new ThirdPartyLoader().loadModule(name, "/static/" + path + ".js")
|
||||
// console.log(window[capitalizeFirstLetter(name)]);
|
||||
obj.value = window[capitalizeFirstLetter(name)];
|
||||
})
|
||||
|
||||
|
||||
onBeforeRouteUpdate((to, from) => {
|
||||
// 在此处执行刷新相关的操作
|
||||
// debugger;
|
||||
});
|
||||
|
||||
const onDataChange = (data) => {
|
||||
// ipcImgList.value = data || [];
|
||||
}
|
||||
|
||||
const onFire = async (key: string, value, data: any) => {
|
||||
// imgIndex.value = 0;
|
||||
// const resData = await api.getCaputreImgListByIpcId({ id: data })
|
||||
// ipcImgList.value = resData.data?.objectList || [];
|
||||
// initImgPreviewInfo(ipcImgList.value?.[0]);
|
||||
}
|
||||
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.device-list) {
|
||||
padding: 20px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
:local(.img-preview-dialog) {
|
||||
:local(.footer) {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
>div {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div :class="$style['device-list']">
|
||||
<h2>用戶列表</h2>
|
||||
<um-table-class-enhance class="role-right" :target="Employee" :data="[]" @data-change="onDataChange" @fire="onFire">
|
||||
</um-table-class-enhance>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { UmByClassEnhance as UmTableClassEnhance,UmDialog } from "funjiaui";
|
||||
import Employee from "@/containers/viewModel/Employee";
|
||||
import { ref, reactive, watch } from "vue";
|
||||
|
||||
const visible = ref(false);
|
||||
|
||||
const onDataChange = (data) => {
|
||||
// ipcImgList.value = data || [];
|
||||
}
|
||||
|
||||
const onFire = async (key: string, value, data: any) => {
|
||||
}
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.device-list) {
|
||||
padding: 20px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<div :class="$style['login']">
|
||||
<div class="login-form">
|
||||
<!-- <img src="/logo.png" :style="{ marginLeft: '45px', marginBottom: '20px' }"> -->
|
||||
<h1>{{systemTitle||'...'}}</h1>
|
||||
<el-form ref="formRef" :model="form" :rules="rules">
|
||||
<el-form-item prop="user">
|
||||
<el-input placeholder="请输入用户名" :prefix-icon="User" size="large" v-model.trim="form.user" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input placeholder="请输入密码" :prefix-icon="Lock" show-password size="large"
|
||||
v-model.trim="form.password" @keyup.enter="onSubmit" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="login-btn" :loading="loading" round size="large" type="primary" @click="onSubmit">
|
||||
登 录
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onBeforeMount, onBeforeUnmount, computed } from "vue";
|
||||
import { ElMessage, FormItemRule } from "element-plus";
|
||||
import * as api from "@/common/api";
|
||||
import Cookies from "js-cookie";
|
||||
import { User, Lock } from "@element-plus/icons-vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useAppStore } from "@/store/app";
|
||||
import { SYSTEM_TITLE } from "@/consts/dataDict";
|
||||
|
||||
const router = useRouter();
|
||||
const formRef = ref();
|
||||
const form = reactive({
|
||||
user: "",
|
||||
password: ""
|
||||
});
|
||||
const appStore = useAppStore();
|
||||
const systemTitle = ref();
|
||||
|
||||
(async () => {
|
||||
const { data: dataDict } = await api.getDynamic({ id: SYSTEM_TITLE }, "dataDict");
|
||||
systemTitle.value = dataDict?.value;
|
||||
}
|
||||
)();
|
||||
|
||||
const rules = ref<Record<string, FormItemRule | FormItemRule[]>>({
|
||||
user: {
|
||||
required: true,
|
||||
message: "请输入用户名",
|
||||
},
|
||||
password: {
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = async () => {
|
||||
formRef.value?.validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { code, data } = await api.employeeLogin({
|
||||
userName: form.user,
|
||||
pwd: form.password
|
||||
});
|
||||
|
||||
if (code == 0 && data) {
|
||||
// 保存登录token信息并设置cookie 过期时间为3天
|
||||
// Cookies.set("Authorization", token, { expires: 3 });
|
||||
Cookies.set("UserInfo", JSON.stringify(data), { expires: 3 });
|
||||
|
||||
appStore.saveUserInfo(data);
|
||||
router.push("/app");
|
||||
// router.push("/app/system/info");
|
||||
}
|
||||
else {
|
||||
ElMessage.error("登录失败");
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:local(.login) {
|
||||
background-image: url(/login_bg.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
|
||||
.login-form {
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
// padding: 120px 160px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
bottom: 1px;
|
||||
left: 1px;
|
||||
margin: auto;
|
||||
|
||||
.el-input__wrapper {
|
||||
background-color: transparent;
|
||||
height: 40px;
|
||||
border-radius: 50px;
|
||||
}
|
||||
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #FFFF;
|
||||
font-size: 40px;
|
||||
font-weight: 400;
|
||||
margin-top: 0;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 234px;
|
||||
margin: 0px auto 30px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
font-size: 16px;
|
||||
|
||||
.el-input__inner {
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-input__inner) {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
height: 50px;
|
||||
font-size: 30px;
|
||||
background: linear-gradient(180deg, #039ad0 0%, #0250bc 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div :class="$style['device-list']">
|
||||
<h2>通知列表</h2>
|
||||
<um-table-class-enhance class="role-right" :target="Notice" :data="[]"
|
||||
:other-params="{ userId: appStore.userInfo?.id }" @data-change="onDataChange"
|
||||
@fire="onFire">
|
||||
</um-table-class-enhance>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// import UmTableClassEnhance from "@/components/UmTable/UmByClassEnhance.vue";
|
||||
import { UmByClassEnhance as UmTableClassEnhance } from "funjiaui";
|
||||
// import UmDialog from "@/components/UmDialog/index.vue";
|
||||
import Notice from "@/containers/viewModel/Notice";
|
||||
import ImgPreview from "@/components/ImgPreview.vue";
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import * as api from "@/common/api";
|
||||
// import { fDT } from "marsLib/date";
|
||||
import { useAppStore } from "@/store/app";
|
||||
|
||||
const visible = ref(false);
|
||||
const imgIndex = ref(0);
|
||||
const ipcImgList = ref([]);
|
||||
const imgPreviewInfo = reactive({
|
||||
id: "",
|
||||
imgUrl: "",
|
||||
position: "",
|
||||
time: "",
|
||||
deviceName: ""
|
||||
});
|
||||
const currentDeviceId = ref(null);
|
||||
const appStore = useAppStore();
|
||||
const traveInfomation = new Notice();
|
||||
const formData = reactive<Notice>(traveInfomation)
|
||||
// debugger;
|
||||
Notice.userId = appStore.userInfo?.id;
|
||||
|
||||
watch(() => appStore.userInfo, (uI) => {
|
||||
// Notice.userId
|
||||
Notice.userId = uI?.id;
|
||||
})
|
||||
|
||||
// Ipc.singleListen = (rowData) => {
|
||||
// initImgPreviewInfo(rowData);
|
||||
// imgIndex.value = (ipcImgList.value || []).findIndex(item => rowData.id == item.id) || 0;
|
||||
// visible.value = true;
|
||||
// }
|
||||
|
||||
const initImgPreviewInfo = (data) => {
|
||||
imgPreviewInfo.id = data?.["id"];
|
||||
imgPreviewInfo.imgUrl = data?.["imgUrl"];
|
||||
imgPreviewInfo.position = data?.["position"];
|
||||
imgPreviewInfo.time = data?.["time"];
|
||||
imgPreviewInfo.deviceName = data?.["deviceName"];
|
||||
}
|
||||
|
||||
watch(imgIndex, (i) => {
|
||||
initImgPreviewInfo(ipcImgList.value?.[i]);
|
||||
})
|
||||
|
||||
watch(visible, () => {
|
||||
if (!visible) {
|
||||
imgIndex.value = 0;
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const onDataChange = (data) => {
|
||||
// ipcImgList.value = data || [];
|
||||
}
|
||||
|
||||
const onImgIdxChange = (idx: TImgPreviewIdx) => {
|
||||
let tempIdx = imgIndex.value;
|
||||
tempIdx += idx;
|
||||
|
||||
if (tempIdx >= 0 && tempIdx < ipcImgList.value?.length) {
|
||||
imgIndex.value = tempIdx;
|
||||
}
|
||||
}
|
||||
|
||||
const onFire = async (key: string, value, data: any) => {
|
||||
// imgIndex.value = 0;
|
||||
// const resData = await api.getCaputreImgListByIpcId({ id: data })
|
||||
// ipcImgList.value = resData.data?.objectList || [];
|
||||
// initImgPreviewInfo(ipcImgList.value?.[0]);
|
||||
currentDeviceId.value = value;
|
||||
visible.value = true;
|
||||
}
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.device-list) {
|
||||
padding: 20px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
:local(.img-preview-dialog) {
|
||||
:local(.footer) {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
>div {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div :class="$style['device-list']">
|
||||
<h2>插件列表</h2>
|
||||
<um-table-class-enhance class="role-right" :target="Plugin2" :data="[]"
|
||||
:other-params="{ userId: appStore?.userInfo?.id }">
|
||||
</um-table-class-enhance>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { UmByClassEnhance as UmTableClassEnhance } from "funjiaui";
|
||||
import Plugin2 from "@/containers/viewModel/Plugin";
|
||||
import { useAppStore } from "@/store/app";
|
||||
|
||||
const appStore = useAppStore();
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.device-list) {
|
||||
padding: 20px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
:local(.img-preview-dialog) {
|
||||
:local(.footer) {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
>div {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div :class="$style['device-list']">
|
||||
<h2>问答列表</h2>
|
||||
<um-table-class-enhance class="role-right" :target="QA" :data="[]" @data-change="onDataChange" @fire="onFire">
|
||||
</um-table-class-enhance>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// import UmTableClassEnhance from "@/components/UmTable/UmByClassEnhance.vue";
|
||||
// import { UmByClassEnhance as UmTableClassEnhance } from "../../lib/funjiaui.es.js";
|
||||
import { UmByClassEnhance as UmTableClassEnhance } from "funjiaui";
|
||||
// import UmDialog from "@/components/UmDialog/index.vue";
|
||||
import QA from "@/containers/viewModel/QA";
|
||||
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import * as api from "@/common/api";
|
||||
// import { fDT } from "marsLib/date";
|
||||
// import CaptureList from "@/containers/CaptureList.vue";
|
||||
// import "funjiaui/style.css";
|
||||
|
||||
const visible = ref(false);
|
||||
const imgIndex = ref(0);
|
||||
const ipcImgList = ref([]);
|
||||
const imgPreviewInfo = reactive({
|
||||
id: "",
|
||||
imgUrl: "",
|
||||
position: "",
|
||||
time: "",
|
||||
deviceName: ""
|
||||
});
|
||||
const currentDeviceId = ref(null);
|
||||
|
||||
// Ipc.singleListen = (rowData) => {
|
||||
// initImgPreviewInfo(rowData);
|
||||
// imgIndex.value = (ipcImgList.value || []).findIndex(item => rowData.id == item.id) || 0;
|
||||
// visible.value = true;
|
||||
// }
|
||||
|
||||
const initImgPreviewInfo = (data) => {
|
||||
imgPreviewInfo.id = data?.["id"];
|
||||
imgPreviewInfo.imgUrl = data?.["imgUrl"];
|
||||
imgPreviewInfo.position = data?.["position"];
|
||||
imgPreviewInfo.time = data?.["time"];
|
||||
imgPreviewInfo.deviceName = data?.["deviceName"];
|
||||
}
|
||||
|
||||
watch(imgIndex, (i) => {
|
||||
initImgPreviewInfo(ipcImgList.value?.[i]);
|
||||
})
|
||||
|
||||
watch(visible, () => {
|
||||
if (!visible) {
|
||||
imgIndex.value = 0;
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const onDataChange = (data) => {
|
||||
// ipcImgList.value = data || [];
|
||||
}
|
||||
|
||||
const onImgIdxChange = (idx: TImgPreviewIdx) => {
|
||||
let tempIdx = imgIndex.value;
|
||||
tempIdx += idx;
|
||||
|
||||
if (tempIdx >= 0 && tempIdx < ipcImgList.value?.length) {
|
||||
imgIndex.value = tempIdx;
|
||||
}
|
||||
}
|
||||
|
||||
const onFire = async (key: string, value, data: any) => {
|
||||
// imgIndex.value = 0;
|
||||
// const resData = await api.getCaputreImgListByIpcId({ id: data })
|
||||
// ipcImgList.value = resData.data?.objectList || [];
|
||||
// initImgPreviewInfo(ipcImgList.value?.[0]);
|
||||
currentDeviceId.value = value;
|
||||
visible.value = true;
|
||||
}
|
||||
</script>
|
||||
<style module lang="scss">
|
||||
:global {
|
||||
:local(.device-list) {
|
||||
padding: 20px;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
:local(.img-preview-dialog) {
|
||||
:local(.footer) {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
>div {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"name": "用户列表",
|
||||
"route": "/app/Employee",
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "问答列表",
|
||||
"route": "/app/QA",
|
||||
"sort": 2
|
||||
},
|
||||
{
|
||||
"name": "通知",
|
||||
"route": "/app/dynamicTable/notice/cm6qnfb9v000a8orbdkv134xe/通知",
|
||||
"sort": 5
|
||||
},
|
||||
{
|
||||
"name": "标签",
|
||||
"route": "/app/dynamicTable/tag/cm7hdjg14000360rb4aetca3p/标签",
|
||||
"sort": 5
|
||||
},
|
||||
{
|
||||
"name": "磁力管理",
|
||||
"route": "/app/dynamicTable/magnet/cm8op0i100002dbmh2ar12374/磁力管理",
|
||||
"sort": 5
|
||||
},
|
||||
{
|
||||
"name": "数据字典",
|
||||
"route": "/app/DataDict",
|
||||
"sort": 6
|
||||
},
|
||||
{
|
||||
"name": "插件列表",
|
||||
"route": "/app/Plugin",
|
||||
"sort": 7
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"target": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
"element-plus/global"
|
||||
],
|
||||
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
import ElementPlus from 'unplugin-element-plus/vite'
|
||||
import { resolve } from "path";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue(),
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
ElementPlus({
|
||||
// options
|
||||
})
|
||||
],
|
||||
server: {
|
||||
host: "0.0.0.0",
|
||||
proxy: {
|
||||
"^/api": {
|
||||
target: "http://localhost:4873/",
|
||||
changeOrigin: true,
|
||||
},
|
||||
"^/static": {
|
||||
target: "http://localhost:4873/resource/",
|
||||
changeOrigin: true,
|
||||
},
|
||||
"^/set/log/level": {
|
||||
target: "http://192.168.1.89:4873/",
|
||||
changeOrigin: true,
|
||||
},
|
||||
"^/cache/image/": {
|
||||
target: "http://192.168.1.102:1221/",
|
||||
changeOrigin: true,
|
||||
},
|
||||
"^/get/service/": {
|
||||
target: "http://192.168.1.102:1221/",
|
||||
changeOrigin: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": resolve(__dirname, "src"),
|
||||
},
|
||||
},
|
||||
build: {
|
||||
cssCodeSplit: true, // 如果设置为false,整个项目中的所有 CSS 将被提取到一个 CSS 文件中
|
||||
sourcemap: false, // 构建后是否生成 source map 文件。如果为 true,将会创建一个独立的 source map 文件
|
||||
target: 'modules', // 设置最终构建的浏览器兼容目标。默认值是一个 Vite 特有的值——'modules' 还可设置为 'es2015' 'es2016'等
|
||||
chunkSizeWarningLimit: 550, // 单位kb 打包后文件大小警告的限制 (文件大于此此值会出现警告)
|
||||
assetsInlineLimit: 4096, // 单位字节(1024等于1kb) 小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项。
|
||||
minify: 'terser', // 'terser' 相对较慢,但大多数情况下构建后的文件体积更小。'esbuild' 最小化混淆更快但构建后的文件相对更大。
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: true, // 生产环境去除console
|
||||
drop_debugger: true // 生产环境去除debugger
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user