ci: 更换Git仓库

main
sankeyangshu 2024-11-18 11:00:55 +08:00
commit 654e3bde2f
81 changed files with 8466 additions and 0 deletions

16
.editorconfig 100644
View File

@ -0,0 +1,16 @@
# Editor configuration, see http://editorconfig.org
# 表示是最顶层的 EditorConfig 配置文件
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格tab | space
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false

14
.eslintignore 100644
View File

@ -0,0 +1,14 @@
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.local
/bin
Dockerfile

70
.eslintrc.js 100644
View File

@ -0,0 +1,70 @@
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
},
// 指定如何解析语法
parser: 'vue-eslint-parser',
// 优先级低于 parse 的语法解析配置
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 'latest',
sourceType: 'module',
},
// 继承某些已有的规则
extends: [
'plugin:vue/vue3-essential',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended', // 添加 prettier 插件
],
plugins: ['vue', '@typescript-eslint', 'import', 'prettier', 'simple-import-sort'],
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
},
],
rules: {
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/promise-function-async': 'off',
'vue/multi-word-component-names': 'off',
'simple-import-sort/imports': [
'error',
{
groups: [
[
// 以字母(或数字或下划线)或“@”后面跟着字母开头的东西,通常为内置模块引入
'^@?\\w',
// 内部导入 "@/"
'^@(/.*|$)',
`^@/assets$`,
`^@/components$`,
`^@/config$`,
`^@/hooks$`,
`^@/plugins$`,
`^@/router$`,
`^@/store$`,
`^@/styles$`,
`^@/utils$`,
// 父级导入. 把 `..` 放在最后.
'^\\.\\.(?!/?$)',
'^\\.\\./?$',
// 同级导入. 把同一个文件夹.放在最后
'^\\./(?=.*/)(?!/?$)',
'^\\.(?!/?$)',
'^\\./?$',
// 样式导入.
'^.+\\.?(css|less|scss)$',
// 带有副作用导入比如import 'a.css'这种.
'^\\u0000',
],
],
},
],
'simple-import-sort/exports': 'error', // 导出
'import/order': 'off',
},
};

24
.gitignore vendored 100644
View File

@ -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?

View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install commitlint --edit $1

View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged

9
.prettierrc 100644
View File

@ -0,0 +1,9 @@
{
"useTabs": false,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"semi": true
}

3
.stylelintignore 100644
View File

@ -0,0 +1,3 @@
/dist/*
/public/*
public/*

41
.stylelintrc.js 100644
View File

@ -0,0 +1,41 @@
// @see: https://stylelint.io
module.exports = {
root: true,
// 继承某些已有的规则
extends: [
'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
'stylelint-config-standard-scss', // 配置 stylelint scss 插件
'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
'stylelint-config-recess-order', // 配置 stylelint css 属性书写顺序插件,
],
overrides: [
// 扫描 .vue/html 文件中的 <style> 标签内的样式
{
files: ['**/*.{vue,html}'],
customSyntax: 'postcss-html',
},
],
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml'],
rules: {
'keyframes-name-pattern': null,
'function-url-quotes': 'always', // URL 的引号 "always(必须加上引号)"|"never(没有引号)"
'color-hex-length': 'short', // 指定 16 进制颜色的简写或扩写 "short(16进制简写)"|"long(16进制扩写)"
'rule-empty-line-before': 'never', // 要求或禁止在规则之前的空行 "always(规则之前必须始终有一个空行)"|"never(规则前绝不能有空行)"|"always-multi-line(多行规则之前必须始终有一个空行)"|"never-multi-line(多行规则之前绝不能有空行)"
'font-family-no-missing-generic-family-keyword': null, // 禁止在字体族名称列表中缺少通用字体族关键字
'scss/at-import-partial-extension': null, // 解决不能使用 @import 引入 scss 文件
'property-no-unknown': null, // 禁止未知的属性
'no-empty-source': null, // 禁止空源码
'selector-class-pattern': null, // 强制选择器类名的格式
'value-no-vendor-prefix': null, // 关闭 vendor-prefix (为了解决多行省略 -webkit-box)
'no-descending-specificity': null, // 不允许较低特异性的选择器出现在覆盖较高特异性的选择器
'value-keyword-case': null, // 解决在 scss 中使用 v-bind 大写单词报错
'no-duplicate-selectors': null,
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global', 'export', 'v-deep', 'deep'],
},
],
},
};

8
.vscode/extensions.json vendored 100644
View File

@ -0,0 +1,8 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"stylelint.vscode-stylelint",
"vue.volar"
]
}

21
LICENSE 100644
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 三棵杨树
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

3
README.md 100644
View File

@ -0,0 +1,3 @@
# BoatPlatform
船货信息智慧共享服务平台

View File

@ -0,0 +1,15 @@
/**
*
* feat:
* fix: bug
* docs:
* style:
* refactor: bug
* perf:
* test:
* build: npm webpack
* ci: CI
* chore:
* revert: commit
*/
module.exports = { extends: ['@commitlint/config-conventional'] };

13
index.html 100644
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<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>

91
package.json 100644
View File

@ -0,0 +1,91 @@
{
"name": "vue-template-base",
"private": true,
"version": "0.0.0",
"description": "使用 Vue3 + TS 构建的项目基础模版",
"author": "sankeyangshu",
"license": "MIT",
"keywords": [
"vue",
"typescript"
],
"scripts": {
"dev": "vite",
"build": "vite build",
"type-check": "vue-tsc --noEmit --skipLibCheck",
"preview": "vite preview",
"lint:lint-staged": "lint-staged",
"lint:eslint": "eslint \"src/**/*.{vue,ts,tsx}\" --fix",
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
"lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
"prepare": "husky install"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
"prettier --write--parser json"
],
"package.json": [
"prettier --write"
],
"*.vue": [
"eslint --fix",
"prettier --write",
"stylelint --fix"
],
"*.{scss,less,styl}": [
"stylelint --fix",
"prettier --write"
],
"*.md": [
"prettier --write"
]
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"echarts": "^5.5.1",
"element-plus": "^2.8.5",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"pinia": "^2.1.7",
"vue": "^3.4.27",
"vue-echarts": "^7.0.3",
"vue-router": "^4.3.3"
},
"devDependencies": {
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@types/node": "^20.14.2",
"@types/nprogress": "^0.2.3",
"@types/path-browserify": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^7.13.0",
"@typescript-eslint/parser": "^7.13.0",
"@vitejs/plugin-vue": "^5.0.5",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-simple-import-sort": "^12.1.0",
"eslint-plugin-vue": "^9.26.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.7",
"postcss": "^8.4.38",
"postcss-html": "^1.7.0",
"prettier": "^3.3.2",
"sass": "^1.77.5",
"stylelint": "^16.6.1",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recess-order": "^5.0.1",
"stylelint-config-recommended-scss": "^14.0.0",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard-scss": "^13.1.0",
"typescript": "^5.4.5",
"vite": "^5.2.13",
"vite-plugin-svg-icons": "^2.0.1",
"vue-tsc": "^2.0.21"
}
}

6277
pnpm-lock.yaml 100644

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
module.exports = {
plugins: {
autoprefixer: {},
},
};

1
public/vite.svg 100644
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

5
src/App.vue 100644
View File

@ -0,0 +1,5 @@
<template>
<router-view />
</template>
<style lang="scss"></style>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="29px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -84 -186 )">
<path d="M 31.8064516129032 16.1945266272189 C 32.1290322580645 15.7655325443787 31.9139784946237 15.0147928994083 31.2688172043011 14.6930473372781 L 26.9677419354839 12.8698224852071 L 26.9677419354839 7.40014792899408 C 26.9677419354839 6.86390532544379 26.6451612903226 6.43491124260355 26.2150537634409 6.22041420118343 L 18.4731182795699 3.21745562130178 L 18.4731182795699 2.46671597633136 C 18.4731182795699 1.07248520710059 17.3978494623656 0 16 0 C 14.6021505376344 0 13.5268817204301 1.07248520710059 13.5268817204301 2.46671597633136 L 13.5268817204301 3.21745562130178 L 5.67741935483871 6.32766272189349 C 5.13978494623656 6.54215976331361 4.9247311827957 6.97115384615385 4.9247311827957 7.40014792899408 L 4.9247311827957 12.8698224852071 L 0.731182795698925 14.6930473372781 C 0.0860215053763442 15.0147928994083 -0.129032258064516 15.7655325443787 0.301075268817205 16.301775147929 L 6.75268817204301 26.5976331360947 C 6.86021505376344 26.8121301775148 7.0752688172043 26.9193786982249 7.29032258064516 27.0266272189349 C 8.47311827956989 27.241124260355 9.44086021505376 27.7773668639053 10.3010752688172 28.6353550295858 L 10.4086021505376 28.7426035502959 C 10.7311827956989 29.064349112426 11.3763440860215 29.064349112426 11.6989247311828 28.7426035502959 L 11.8064516129032 28.6353550295858 C 12.8817204301075 27.5628698224852 14.3870967741935 26.9193786982248 16 26.9193786982248 C 17.6129032258065 26.9193786982248 19.1182795698925 27.5628698224852 20.1935483870968 28.6353550295858 C 20.5161290322581 28.957100591716 21.1612903225806 28.957100591716 21.4838709677419 28.6353550295858 C 22.3440860215054 27.7773668639053 23.5268817204301 27.133875739645 24.7096774193548 26.9193786982248 C 24.9247311827957 26.9193786982248 25.1397849462366 26.7048816568047 25.3548387096774 26.4903846153846 L 31.8064516129032 16.1945266272189 Z M 24.494623655914 11.7973372781065 L 16.8602150537634 8.47263313609468 C 16.3225806451613 8.25813609467456 15.6774193548387 8.25813609467456 15.1397849462366 8.47263313609468 L 7.29032258064516 11.7973372781065 L 7.29032258064516 8.25813609467456 L 16 4.93343195266272 L 24.494623655914 8.25813609467456 L 24.494623655914 11.7973372781065 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 186 )" />
</g>
</svg>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="10px" height="16px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -1407 -27 )">
<path d="M 5.36290322580645 0.117647058823529 C 6.7741935483871 0.117647058823529 7.98387096774194 0.509803921568627 8.79032258064516 1.29411764705882 C 9.59677419354839 2.07843137254902 10 3.05882352941177 10 4.43137254901961 C 10 5.41176470588235 9.79838709677419 6.3921568627451 9.19354838709677 6.98039215686275 C 9.19354838709677 7.17647058823529 8.58870967741935 7.76470588235294 7.37903225806452 8.74509803921568 C 6.9758064516129 9.13725490196078 6.7741935483871 9.33333333333333 6.57258064516129 9.72549019607843 C 6.37096774193548 10.1176470588235 6.16935483870968 10.7058823529412 6.16935483870968 11.2941176470588 L 6.16935483870968 11.6862745098039 L 3.75 11.6862745098039 L 3.75 11.2941176470588 C 3.75 10.5098039215686 3.95161290322581 9.72549019607843 4.15322580645161 9.33333333333333 C 4.55645161290323 8.74509803921568 5.36290322580645 7.76470588235294 6.7741935483871 6.58823529411765 L 7.17741935483871 6 C 7.58064516129032 5.41176470588235 7.78225806451613 5.01960784313725 7.78225806451613 4.43137254901961 C 7.78225806451613 3.64705882352941 7.58064516129032 3.05882352941176 7.17741935483871 2.66666666666667 C 6.7741935483871 2.27450980392157 5.96774193548387 2.07843137254902 5.16129032258065 2.07843137254902 C 4.35483870967742 2.07843137254902 3.54838709677419 2.47058823529412 3.14516129032258 3.05882352941176 C 2.74193548387097 3.45098039215686 2.54032258064516 4.23529411764706 2.54032258064516 5.2156862745098 L 0.120967741935484 5.2156862745098 C 0.120967741935484 3.64705882352941 0.524193548387097 2.47058823529412 1.53225806451613 1.49019607843137 C 2.54032258064516 0.509803921568627 3.75 0.117647058823529 5.36290322580645 0.117647058823529 Z M 4.95967741935484 12.8627450980392 C 5.56451612903226 12.6666666666667 5.96774193548387 12.8627450980392 6.16935483870968 13.2549019607843 C 6.57258064516129 13.4509803921569 6.57258064516129 13.843137254902 6.57258064516129 14.4313725490196 C 6.57258064516129 14.8235294117647 6.37096774193548 15.2156862745098 6.16935483870968 15.6078431372549 C 5.76612903225807 15.8039215686275 5.36290322580645 16 4.95967741935484 16 C 4.55645161290323 16 4.15322580645161 15.8039215686275 3.75 15.6078431372549 C 3.34677419354839 15.2156862745098 3.34677419354839 15.0196078431373 3.34677419354839 14.4313725490196 C 3.34677419354839 14.0392156862745 3.54838709677419 13.6470588235294 3.75 13.2549019607843 C 3.95161290322581 13.0588235294118 4.35483870967742 12.8627450980392 4.95967741935484 12.8627450980392 Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 1407 27 )" />
</g>
</svg>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="32px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -84 -593 )">
<path d="M 32 21.3333333333333 C 32 27.2 27.7333333333333 32 22.4 32 C 17.0666666666667 32 12.8 27.2 12.8 21.3333333333333 C 12.8 15.4666666666667 17.0666666666667 10.6666666666667 22.4 10.6666666666667 C 27.7333333333333 10.6666666666667 32 15.4666666666667 32 21.3333333333333 Z M 27.2 19.5555555555556 L 24 19.5555555555556 L 24 16 C 24 15.1111111111111 23.2888888888889 14.2222222222222 22.4 14.2222222222222 C 21.5111111111111 14.2222222222222 20.8 14.9333333333333 20.8 16 L 20.8 21.3333333333333 C 20.8 22.2222222222222 21.5111111111111 23.1111111111111 22.4 23.1111111111111 L 27.2 23.1111111111111 C 28.0888888888889 23.1111111111111 28.8 22.4 28.8 21.3333333333333 C 28.8 20.2666666666667 28.0888888888889 19.5555555555556 27.2 19.5555555555556 Z M 0 2.66666666666667 C 0 1.24444444444444 1.06666666666667 0 2.31111111111111 0 L 29.5111111111111 0 C 30.9333333333333 0 32 1.24444444444444 32 2.66666666666667 C 32 4.08888888888889 30.9333333333333 5.33333333333333 29.6888888888889 5.33333333333333 L 2.31111111111111 5.33333333333333 C 1.06666666666667 5.33333333333333 0 4.08888888888889 0 2.66666666666667 Z M 0 11.5555555555556 C 0 10.1333333333333 1.06666666666667 8.88888888888889 2.31111111111111 8.88888888888889 L 10.3111111111111 8.88888888888889 C 11.7333333333333 8.88888888888889 12.6222222222222 10.1333333333333 12.6222222222222 11.5555555555556 C 12.6222222222222 12.9777777777778 11.7333333333333 14.2222222222222 10.4888888888889 14.2222222222222 L 2.31111111111111 14.2222222222222 C 1.06666666666667 14.2222222222222 0 12.9777777777778 0 11.5555555555556 Z M 0 20.4444444444444 C 0 19.0222222222222 1.06666666666667 17.7777777777778 2.31111111111111 17.7777777777778 L 7.11111111111111 17.7777777777778 C 8.53333333333333 17.7777777777778 9.42222222222222 19.0222222222222 9.42222222222222 20.4444444444444 C 9.6 21.8666666666667 8.53333333333333 23.1111111111111 7.11111111111111 23.1111111111111 L 2.31111111111111 23.1111111111111 C 1.06666666666667 23.1111111111111 0 21.8666666666667 0 20.4444444444444 Z M 0 29.3333333333333 C 0 27.9111111111111 1.06666666666667 26.6666666666667 2.31111111111111 26.6666666666667 L 3.91111111111111 26.6666666666667 C 5.33333333333333 26.6666666666667 6.22222222222222 27.9111111111111 6.22222222222222 29.3333333333333 C 6.22222222222222 30.7555555555555 5.33333333333333 32 4.08888888888889 32 L 2.31111111111111 32 C 1.06666666666667 32 0 30.7555555555555 0 29.3333333333333 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 593 )" />
</g>
</svg>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="30px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -788 -20 )">
<path d="M 27.578375 28.520625 C 26.7179375 29.31625 25.627875 29.4065 25.17796875 29.40653125 C 25.116625 29.40653125 25.0673125 29.40484375 25.03196875 29 L 6.352125 29 C 5.1008125 29.4030625 4.38053125 28.87603125 3.99665625 28.43390625 C 3.1554375 27.4650625 3.223 26.1515 3.2609375 25.78703125 L 3.2609375 14.55171875 L 5.2609375 14.55171875 L 5.2609375 25.924 L 5.2515 25.98284375 C 5.22771875 26.182875 5.22546875 26.804 5.51053125 27.126875 C 5.57084375 27.1951875 5.754375 27.4030625 6.35215625 27 L 25.11178125 27 L 25.13521875 27.405625 C 25.2025 27.408 25.8325625 27.4191875 26.22884375 27.04446875 C 26.49303125 26.79465625 26.62696875 26.38159375 26 25.81671875 L 26 14.54309375 L 28 14.54309375 L 28 25.81671875 C 28.62696875 27.2501875 28.05675 28.0783125 27.578375 28.520625 Z M 5.26090625 14.49025 C 5.26090625 15.04253125 4.8131875 15.49025 4.26090625 15.49025 L 1.1875 15.49025 C 0.77215625 15.49025 0.40009375 15.2335625 0.252625 14.84528125 C 0.1051875 14.457 0.2130625 14.01803125 0.5236875 13.74234375 L 15.28053125 0.645781250000001 C 15.65615625 0.312406250000001 16.22075 0.309343750000001 16.6 0.638687500000001 L 31.56190625 13.63215625 C 31.873 13.90234375 31.98653125 14.3356875 31.847875 14.7236875 C 31.70921875 15.1116875 31.34678125 15.3749375 30.934875 15.38678125 L 27.6555625 15.48090625 C 27.64578125 15.48121875 27.6360625 15.48134375 27.6263125 15.48134375 C 27.08734375 15.48134375 26.64284375 15.0523125 26.62725 14.51003125 C 26.61140625 13.95796875 27.04609375 13.49759375 27.59815625 13.48175 L 28.31475 13.4611875 L 15.9515 2.72434375 L 3.8208125 13.49025 L 4.26090625 13.49025 C 4.8131875 13.49025 5.26090625 13.93796875 5.26090625 14.49025 Z M 13.43746875 27.56878125 C 13.4375 28.03478125 13.05975 28.41253125 12.59375 28.41253125 C 12.12775 28.41253125 11.75 28.03478125 11.75 27.56878125 L 11.75 20.51109375 C 11.7500625 20.35903125 11.7885625 19.73296875 12.37565625 19.13625 C 13.08815625 18.41209375 14.29621875 18.04490625 15.9663125 18.04490625 C 17.61125 18.04490625 18.8061875 18.417125 19.5179375 19.15125 C 20.11871875 19.770875 20.1574375 20.4233125 20.15625 20.596375 L 20.15625 27.5416875 C 20.15625 28.0076875 19.7785 28.3854375 19.3125 28.3854375 C 18.8465 28.3854375 18.46875 28.0076875 18.46875 27.5416875 L 18.46875 20.6063125 C 18.46315625 20.56984375 18.427875 20.4155625 18.21821875 20.24565625 C 17.9816875 20.05396875 17.3745625 19.73240625 15.96628125 19.73240625 C 14.33278125 19.73240625 13.75228125 20.1431875 13.57853125 20.31975 C 13.49321875 20.40646875 13.45740625 20.48025 13.442375 20.52684375 C 13.44009375 20.533875 13.43853125 20.5396875 13.43746875 20.544 L 13.43746875 27.56878125 Z M 13.09375 19.71875 L 12.8125 21.6875 L 12.53125 28.125 L 5.09375 27.71875 L 4.5625 19.78125 L 4.71875 14.59375 L 2.5 13.875 L 15.90625 1.71875 L 29.125 13.25 L 27.78125 14.53125 L 27.21875 26.09375 L 26.6875 27.875 L 19.6875 28.125 L 19.5625 23.46875 L 19.125 20.34375 L 18.25 19.625 L 16.53125 19.34375 L 14.40625 19.53125 L 13.09375 19.71875 Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 788 20 )" />
</g>
</svg>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="30px" height="32px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -1548 -19 )">
<path d="M 23.5222843905362 4.66289516129032 C 24.520607532848 5.37817795698925 25.4068816472834 6.18891428091398 26.1812429643111 7.09421018145161 C 26.9574780495384 8.00046885080645 27.6217322221236 8.97886787634409 28.1759133078835 10.0293384408602 C 28.7301284512607 11.0808061827957 29.1510703457919 12.1926888776882 29.4387729825107 13.3669121303763 C 29.7264756192294 14.5411353830645 29.8712978959517 15.7310038978495 29.8712978959517 16.9393717069892 C 29.8712978959517 19.0189252016129 29.4773717817827 20.9698089717742 28.6914614701705 22.792091733871 C 27.9036433327415 24.6143744959677 26.8415793124112 26.2027685483871 25.4995801225142 27.5553482526882 C 24.1594886918501 28.9079279905914 22.5876680353338 29.9808177755376 20.7803365922408 30.7750491599462 C 18.9768207341974 31.5692461693548 17.0420075350675 31.9658461021505 14.9816544633345 31.9658461021505 C 12.944467496005 31.9658461021505 11.0231792325107 31.5692461693548 9.21577964089134 30.7750491599462 C 7.41226378284801 29.9808177419355 5.83274380770597 28.9079279569892 4.4810693248402 27.5553482526882 C 3.12939484197443 26.2018057459677 2.06736491255327 24.6143744959677 1.291129827326 22.792091733871 C 0.514860684481536 20.9698089717742 0.128667979847303 19.0189252016129 0.128667979847303 16.9393717069892 C 0.128667979847303 15.7543858870968 0.265756847034803 14.5908564852151 0.54191052246094 13.4507434475806 C 0.819971990411934 12.3105960349462 1.21389810458097 11.2260152553763 1.72365474076705 10.1969323252688 C 2.23341141024503 9.16888094758064 2.86291642622514 8.20705564516129 3.6159853737571 7.31248797043011 C 4.36905435458097 6.41788592069892 5.21097216796875 5.61299506048387 6.14170475630327 4.8977122983871 C 6.63023717151989 4.54007090053763 7.15736841930043 4.40559005376344 7.72122476473722 4.49523249327957 C 8.28504705255682 4.5848749327957 8.74462180397728 4.86360208333333 9.0999150279652 5.33330514112903 C 9.45520821866122 5.80297379032258 9.58653965065696 6.3282434811828 9.49963266823509 6.91000816532258 C 9.41081789328835 7.49177288306452 9.1346982754794 7.96147590725807 8.66739011452415 8.31908293010753 C 7.27323306551847 9.3471686827957 6.20346975985441 10.61106875 5.46198383123225 12.1088575604839 C 4.72049793590199 13.6076091397849 4.34783013361151 15.2174252352151 4.34783013361151 16.9393373319892 C 4.34783013361151 18.414706922043 4.62394975142045 19.8072079637097 5.18007268732244 21.1149836693548 C 5.73231188964844 22.4237221438172 6.49120645419034 23.5638695564516 7.45474638227983 24.5363886760753 C 8.42022816051137 25.5089077956989 9.54790676047585 26.2807199932796 10.845515625 26.8507937163979 C 12.1411826060902 27.420867405914 13.5199069269354 27.7054056787634 14.9816544966264 27.7054056787634 C 16.4453098588423 27.7054056787634 17.8240341796875 27.420867405914 19.1197011607777 26.8507937163979 C 20.4153681418679 26.2807200268817 21.5449886252663 25.5089422043011 22.5104704034979 24.5363886760753 C 23.4740102982955 23.5638695564516 24.2367545387962 22.4237221438172 24.8025186767578 21.1149836693548 C 25.3682828147195 19.8072423723118 25.6501939586293 18.4147413306452 25.6501939586293 16.9393373319892 C 25.6501939586293 15.1950060147849 25.2505104092685 13.5461970094086 24.4529829545455 11.9919132056452 C 23.6555236483487 10.4375949932796 22.5374521262429 9.15715561155914 21.0969628684304 8.15148904569893 C 20.6103723366477 7.81626686827957 20.3168781405362 7.35729203629033 20.2164462224787 6.77652449596774 C 20.1160483953303 6.19475977822581 20.2338208007813 5.65779912634409 20.5659478870739 5.16567688172043 C 20.8980749733665 4.69600823252688 21.351858231978 4.41143558467742 21.9272976296165 4.31106491935484 C 22.504678877397 4.2097314516129 23.0356938587536 4.32767298387097 23.5222843905362 4.66289516129032 Z M 14.9816544966264 17.0397423723118 C 14.4062150989879 17.0397423723118 13.9137989501953 16.8331555443548 13.5025323486328 16.4189847446237 C 13.0931394486861 16.0058111223118 12.8884941184304 15.5078433467742 13 14.9260786626344 L 13 2.18086186155914 C 12.8884940851385 1.5990971438172 13.0931735063033 1.09628108198925 13.5025323153409 0.671416465053763 C 13.9137989169034 0.246586223118279 14.406215065696 0.0341195228494623 14.9816544633345 0.0341195228494623 C 15.5802259077592 0.0341195228494623 16.0842251087536 0.246586223118279 16.4935839177912 0.671416465053764 C 16.9048846102628 1.09628108198925 17.1095639981357 1.59909717741935 17 2.18086186155914 L 17 14.9260786626344 C 17.1095639981357 15.5078433803763 16.9048845769709 16.0058111223118 16.4935839177912 16.4189847446237 C 16.0842251087536 16.8331899193548 15.5802259410511 17.0397423723118 14.9816544966264 17.0397423723118 Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 1548 19 )" />
</g>
</svg>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3Z"/></svg>

After

Width:  |  Height:  |  Size: 459 B

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="29px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -84 -394 )">
<path d="M 31.8318401748088 4.05227163775821 C 32.0982363040425 2.9064139719341 31.8318401748088 1.82791880937854 31.0327142188232 1.0190632354223 L 30.899547370064 0.884275037043493 C 30.0338067738411 0.142813562276649 28.8351178398627 -0.126794430401814 27.769626970501 0.277633356576309 L 1.66483533635087 10.5231162294082 C 0.732542531606056 10.8601499171969 0.133198064616825 11.7363995903425 0.0665834243795847 12.7474690577878 C 0 13.7585385252332 0.466146402372405 14.7022138934891 1.33188699859529 15.1740357796566 L 6.85915405025753 18.4768837705918 C 7.19213360387077 18.6790976640809 7.59169658186359 18.5442778697812 7.79147807086 18.2072441819925 C 7.99125955985641 17.8702420901246 7.85806149523958 17.4658143031465 7.525113157484 17.2636004096575 L 1.9978148899641 14.0281781138325 C 1.59825191197128 13.7585385252332 1.33188699859529 13.354110738255 1.39847042297487 12.8822888520875 C 1.46505384735446 12.41046696592 1.73144997658811 12.0060391789419 2.19759637896051 11.8038252854528 L 28.3023880131107 1.55831081670008 C 28.7019509911035 1.42349102240042 29.1015139690963 1.42349102240042 29.4344623068519 1.55831081670008 L 10.1888559388169 18.5442778697812 C 9.5229280474481 19.1509195502484 9.12336506945528 20.0271692233941 9.12336506945528 20.97084459165 L 9.12336506945528 28.1831506580668 C 9.12336506945528 28.5875784450449 9.38972998283128 28.8571864377234 9.7892929608241 28.8571864377234 C 10.1888559388169 28.8571864377234 10.4552208521929 28.5875784450449 10.4552208521929 28.1831506580668 L 10.4552208521929 20.97084459165 C 10.4552208521929 20.4315970103722 10.6550023411893 19.8923810250153 11.1211799594194 19.5553473372265 L 30.4333697518339 2.43456048984573 C 30.6331512408303 2.83898827682385 30.6331512408303 3.24341606380197 30.5665678164508 3.64784385078009 L 25.7052286561573 22.4537359452628 C 25.4388325269237 23.3974113135187 24.7729046355549 24.2062668874749 23.9071952551896 24.5433005752637 C 23.0414858748244 24.8803342630524 21.9759637896051 24.8803026671315 21.1102544092399 24.3410866817746 L 14.6506321211175 20.6338109038612 C 14.3176837833619 20.4315970103722 13.9181208053691 20.5664168046718 13.7183393163727 20.9034504924606 C 13.5185578273763 21.2404525843284 13.6517246761355 21.6448803713065 13.9847042297487 21.8470942647956 L 20.4442953020134 25.6217641418984 C 21.1102544092399 26.0261919288765 21.9093803652255 26.2284058223656 22.6418916809739 26.2284058223656 C 23.2412361479632 26.2284058223656 23.7739971905728 26.0935860280659 24.373341657562 25.8913721345768 C 25.6386140159201 25.3521561492199 26.6375214609021 24.2736609866643 26.9705010145154 22.8581637322409 L 31.8318401748088 4.05227163775821 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 394 )" />
</g>
</svg>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="36px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -84 -488 )">
<path d="M 18.6666666545139 13.4556212879068 L 23.999999984375 13.4556212879068 L 23.999999984375 8.13017750092455 C 23.999999984375 7.63998393215635 24.3979690984866 7.24260352949335 24.8888888796296 7.24260352949335 C 25.3798086607727 7.24260352949335 25.7777777748843 7.63998393215635 25.7777777748843 8.13017750092455 L 25.7777777748843 13.4556212879068 L 31.1111111047454 13.4556212879068 C 31.6020308858885 13.4556212879068 32 13.8530016905698 32 14.343195259338 C 32 14.8333888281062 31.6020308858885 15.2307692307692 31.1111111047454 15.2307692307692 L 25.7777777748843 15.2307692307692 L 25.7777777748843 20.5562130177515 C 25.7777777748843 21.0464065865197 25.3798086607727 21.4437869891827 24.8888888796296 21.4437869891827 C 24.3979690984866 21.4437869891827 23.999999984375 21.0464065865197 23.999999984375 20.5562130177515 L 23.999999984375 15.2307692307692 L 18.6666666545139 15.2307692307692 C 18.1757468733708 15.2307692307692 17.7777777592593 14.8333888281062 17.7777777592593 14.343195259338 C 17.7777777592593 13.8530016905698 18.1757468733708 13.4556212879068 18.6666666545139 13.4556212879068 Z M 30 20.6840236686391 L 30.2222221886574 20.6831361085429 C 30.2222221886574 20.1929425397747 30.620191302769 19.7955621371117 31.1111110839121 19.7955621371117 C 31.6020308650551 19.7955621371117 31.9999999791667 20.1929425397747 31.9999999791667 20.6831361085429 L 32 33.2662721754808 C 31.9995564818193 34.7365396105881 30.8057791101131 35.928192063087 29.3333334351962 35.928192063087 C 28.8188541791035 35.928192063087 28.3153585793775 35.779587327387 27.8835555235133 35.5002958441198 L 16.5048888642546 28.1378698086169 C 16.2109336845382 27.9478214882398 15.8326218362668 27.9478214882398 15.5386666565504 28.1378698086169 L 4.11377778898842 35.5082840098003 C 3.68254972175569 35.7864761256624 3.1800650159474 35.9344576611834 2.66666655930324 35.9344576611834 C 1.19420033215083 35.9344576611834 0.000414442319860577 34.7427731863621 0 33.2724852209689 L 0 6.35502959966716 C 0 2.92367461115139 2.78578377079869 0.142011820451183 6.22222220428241 0.142011820451183 L 25.7777777748843 0.142011820451183 C 29.214216208368 0.142011820451183 31.9999999791667 2.92367461115139 31.9999999791667 6.35502955806213 L 31.9999999791667 8.18343193879438 C 31.9999999791667 8.67362550756258 31.6020308650551 9.07100591022559 31.1111110839121 9.07100591022559 C 30.620191302769 9.07100591022559 30.2222221886574 8.67362550756259 30.2222221886574 8.18343193879438 L 30.2222221886574 6.35502959966716 C 30.2222221886574 3.90406178356279 28.2323766528219 1.91715978629143 25.7777777748843 2 L 6.22222220428241 2 C 3.76762332634482 1.91715978629143 1.77777779050926 3.90406178356279 2 6.35502959966716 L 2 33.2724852209689 C 1.77777776933179 33.2725643174599 1.77777775874305 33.2726434139586 1.77777775874305 33.2727225104524 C 1.77777775874305 33.7629160677317 2.17574686352721 34.1602964610811 2.66666663316435 34.1602964610811 C 2.83791950301204 34.1602964610811 3.00552670215961 34.1109001074683 3.14933333128299 34.0180473511464 L 14.5742221988449 26.6467455482618 C 15.4564039377868 26.0777934671316 16.5908684453466 26.0788359085129 17.471999988625 26.6494082701553 L 28.8497777728843 34.0118343056583 C 28.9937759684371 34.1050539462454 29.1617203167725 34.1546583128729 29.3333336863881 34.1546583128729 C 29.8242534560252 34.1546583128729 30.2222225608094 33.7572779195235 30.2222225608094 33.2670843622442 C 30.2222225608094 33.2668136332811 30.2222224367587 33.2665429043305 30 33.2662721754808 L 30 20.6840236686391 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 488 )" />
</g>
</svg>

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="currentColor" d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6ZM5.394 6.813L6.81 5.399l3.505 3.506L8.9 10.319zM2 15.005h5v2H2zm3.394 10.193L8.9 21.692l1.414 1.414l-3.505 3.506zM15 25.005h2v5h-2zm6.687-1.9l1.414-1.414l3.506 3.506l-1.414 1.414zm3.313-8.1h5v2h-5zm-3.313-6.101l3.506-3.506l1.414 1.414l-3.506 3.506zM15 2.005h2v5h-2z"/></svg>

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@ -0,0 +1,34 @@
<template>
<!-- 分页组件 开始 -->
<el-pagination
:background="true"
:current-page="pageAble.page"
:page-size="pageAble.rows"
:page-sizes="[10, 25, 50, 100]"
:total="pageAble.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
<!-- 分页组件 结束 -->
</template>
<script lang="ts" setup>
//
interface pageAbleType {
page: number;
rows: number;
total: number;
}
//
interface PaginationProps {
pageAble: pageAbleType;
handleSizeChange: (size: number) => void;
handleCurrentChange: (currentPage: number) => void;
}
defineProps<PaginationProps>();
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,49 @@
<template>
<!-- svg图标组件 开始 -->
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
<!-- svg图标组件 结束 -->
</template>
<script lang="ts" setup>
import { computed } from 'vue';
//
const props = defineProps({
// icon
icon: {
type: String,
required: true,
},
//
className: {
type: String,
default: '',
},
});
/**
* svg图标类名
*/
const svgClass = computed(() => {
return props.className ? 'svg-icon ' + props.className : 'svg-icon';
});
/**
* 项目内图标
*/
const iconName = computed(() => {
return props.icon ? `#icon-${props.icon}` : '#icon';
});
</script>
<style lang="scss" scoped>
.svg-icon {
width: 1em;
height: 1em;
overflow: hidden;
vertical-align: -0.15em;
fill: currentColor;
}
</style>

View File

@ -0,0 +1,35 @@
<template>
<div class="switch-dark" @click="onClickToggleDark">
<svg-icon v-if="isDark" icon="Moon" className="switch-svg"></svg-icon>
<svg-icon v-else icon="Sunny" className="switch-svg"></svg-icon>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useTheme } from '@/hooks/useTheme';
import { useSettingStore } from '@/store/modules/setting';
//
const settingStore = useSettingStore();
const isDark = computed(() => settingStore.isDark);
// hooks
const { switchDark } = useTheme();
//
const onClickToggleDark = () => {
settingStore.setThemeDark(!isDark.value);
switchDark();
};
</script>
<style lang="scss" scoped>
.switch-dark {
cursor: pointer;
transition: all 0.3s;
.switch-svg {
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,26 @@
import { computed } from 'vue';
import { useSettingStore } from '@/store/modules/setting';
/**
* @description:
*/
export const useTheme = () => {
// 获取全局状态管理仓库中系统设置状态
const settingStore = useSettingStore();
const isDark = computed(() => settingStore.isDark);
// 切换暗黑模式
const switchDark = () => {
const body = document.documentElement;
if (isDark.value) {
body.setAttribute('class', 'dark');
} else {
body.setAttribute('class', '');
}
};
return {
switchDark,
};
};

View File

@ -0,0 +1,7 @@
<template>
<div></div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,81 @@
<template>
<div class="header-left">
<img class="logo" src="@/assets/imgs/logo.png" />
<div class="left-title">
<div class="title">船货信息智慧共享服务平台</div>
<div class="text">Intelligent sharing service platform for ship and cargo information</div>
</div>
</div>
<div class="header-right">
<div class="nav-item">
<svg-icon icon="Home" className="icon"></svg-icon>
<span>首页</span>
</div>
<div class="nav-item">
<svg-icon icon="Notify" className="icon"></svg-icon>
<span>公告</span>
</div>
<div class="nav-item">
<svg-icon icon="API" className="icon"></svg-icon>
<span>API</span>
</div>
<div class="nav-item">
<svg-icon icon="Setting" className="icon"></svg-icon>
<span>设置</span>
</div>
<div class="nav-item">
<svg-icon icon="Help" className="icon"></svg-icon>
<span>帮助</span>
</div>
<div class="nav-item">
<svg-icon icon="Logout" className="icon"></svg-icon>
<span>退出</span>
</div>
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.header-left {
display: flex;
align-items: center;
.logo {
width: 80px;
height: 50px;
margin-right: 16px;
}
.left-title {
display: flex;
flex-direction: column;
color: #fff;
.title {
font-size: 24px;
font-weight: 700;
}
.text {
font-size: 15px;
font-weight: 400;
}
}
}
.header-right {
display: flex;
height: 100%;
.nav-item {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 100%;
font-size: 18px;
color: #fff;
.icon {
margin-right: 6px;
}
}
.nav-item:hover {
background-color: rgb(109 0 14 / 100%);
}
}
</style>

View File

@ -0,0 +1,21 @@
<template>
<div class="app-main">
<router-view v-slot="{ Component, route }">
<transition name="fade-slide" mode="out-in" appear>
<component :is="Component" :key="route.path" />
</transition>
</router-view>
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.app-main {
box-sizing: border-box;
width: 100%;
height: 100%;
overflow: auto;
background-color: var(--el-bg-color-page);
}
</style>

View File

@ -0,0 +1,45 @@
<template>
<template v-for="subItem in menuList" :key="subItem.path">
<el-sub-menu v-if="subItem.children && subItem.children.length > 0" :index="subItem.path">
<template #title>
<el-icon v-if="subItem.meta.native">
<component :is="subItem.meta?.icon"></component>
</el-icon>
<svg-icon :icon="subItem.meta?.icon" className="side-icon" v-else></svg-icon>
<span>{{ subItem.meta?.title }}</span>
</template>
<!-- 有children递归本次组件 -->
<SubMenu :menuList="subItem.children" />
</el-sub-menu>
<el-menu-item v-else :index="subItem.path">
<el-icon v-if="subItem.meta?.native">
<component :is="subItem.meta?.icon"></component>
</el-icon>
<svg-icon :icon="subItem.meta?.icon" className="side-icon" v-else></svg-icon>
<template #title>
<span>{{ subItem.meta?.title }}</span>
</template>
</el-menu-item>
</template>
</template>
<script lang="ts" setup>
import { RouteRecordRaw } from 'vue-router';
//
defineProps({
menuList: {
type: Array<RouteRecordRaw>,
default: () => [],
},
});
</script>
<style lang="scss" scoped>
.side-icon {
margin-right: 10px;
font-size: 18px;
text-align: center;
}
</style>

View File

@ -0,0 +1,54 @@
<template>
<div class="sidebar">
<img class="side-logo" src="@/assets/imgs/logo.png" />
<el-scrollbar>
<el-menu :default-active="activeMenu" background-color="#333" text-color="#fff" router>
<SubMenu :menuList="menuList"></SubMenu>
</el-menu>
</el-scrollbar>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { filterRoutes, generateMenus } from '@/utils/routers';
import SubMenu from './components/SubMenu.vue';
//
const route = useRoute();
//
const activeMenu = computed(() => {
const { path } = route;
return path;
});
//
const router = useRouter();
//
const menuList = computed(() => {
const fRoutes = filterRoutes(router.getRoutes());
return generateMenus(fRoutes);
});
</script>
<style lang="scss" scoped>
.sidebar {
position: fixed;
top: 0;
bottom: 0;
left: 0;
z-index: 999;
width: 200px;
height: 100%;
overflow: hidden;
background: #333;
box-shadow: 2px 0 6px rgb(0 21 41 / 35%);
.side-logo {
width: 100%;
height: 170px;
}
}
</style>

View File

@ -0,0 +1,47 @@
<template>
<el-container class="layout-container">
<el-aside>
<Sidebar />
</el-aside>
<el-container>
<el-header>
<Header />
</el-header>
<el-main>
<Main />
</el-main>
<!-- <el-footer>Footer</el-footer> -->
</el-container>
</el-container>
</template>
<script lang="ts" setup>
import Header from './Header/index.vue';
import Main from './Main/index.vue';
import Sidebar from './Sidebar/index.vue';
</script>
<style lang="scss" scoped>
.layout-container {
width: 100%;
height: 100%;
:deep(.el-aside) {
width: 200px;
background-color: #555c64;
border-right: 1px solid var(--el-aside-border-color);
}
.el-header {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
height: 70px;
padding: 0 20px;
color: #fff;
background-color: #9c000c;
}
}
</style>

29
src/main.ts 100644
View File

@ -0,0 +1,29 @@
import { createApp } from 'vue';
import setupElementPlus from '@/plugins/element'; // 导入element plus
import setupSvgIcons from '@/plugins/icons'; // 导入svg图标组件
import { setupRouter } from '@/router';
import { setupStore } from '@/store';
import App from './App.vue';
import './styles/index.scss'; // 全局css
import 'virtual:svg-icons-register'; // svg-icons注册导入
function bootstrap() {
// 创建实例
const app = createApp(App);
// 配置 store
setupStore(app);
// 配置路由
setupRouter(app);
// 导入svg图标
setupSvgIcons(app);
// 导入element和全局注册element 图标
setupElementPlus(app);
app.mount('#app');
}
bootstrap();

View File

@ -0,0 +1,16 @@
import * as ElementPlusIconsVue from '@element-plus/icons-vue'; // 统一导入el-icon图标
import ElementPlus from 'element-plus';
import { App } from 'vue';
import 'element-plus/dist/index.css';
import 'element-plus/theme-chalk/dark/css-vars.css'; // 暗黑主题
/**
* elementelement
*/
export default (app: App<Element>) => {
app.use(ElementPlus);
// 统一注册el-icon图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component);
}
};

View File

@ -0,0 +1,6 @@
import { App } from 'vue';
import SvgIcon from '@/components/SvgIcon/index.vue'; // svg图标组件
export default (app: App<Element>) => {
app.component('svg-icon', SvgIcon);
};

View File

@ -0,0 +1,53 @@
import { App } from 'vue';
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import Layout from '@/layouts/index.vue';
import boatRoutes from './modules/boat';
import historyRoutes from './modules/history';
import manifestRoutes from './modules/manifest';
import sendRoutes from './modules/send';
import subscribeRoutes from './modules/subscribe';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'layout',
component: Layout,
redirect: '/home',
children: [
{
path: '/home',
name: 'home',
component: () => import('@/views/Home/index.vue'),
meta: { title: 'home', affix: true },
},
{
path: '/notify',
name: 'notify',
component: () => import('@/views/Notify/index.vue'),
meta: { title: 'notify', affix: true },
},
{
path: '/resource',
name: 'resource',
component: () => import('@/views/Resource/index.vue'),
meta: { title: 'resource', affix: true },
},
],
},
...boatRoutes,
...manifestRoutes,
...sendRoutes,
...subscribeRoutes,
...historyRoutes,
];
// 创建一个可以被 Vue 应用程序使用的路由实例
export const router = createRouter({
history: createWebHashHistory(),
routes,
});
// 配置路由器
export function setupRouter(app: App<Element>) {
app.use(router);
}

View File

@ -0,0 +1,52 @@
import { RouteRecordRaw } from 'vue-router';
import Layout from '@/layouts/index.vue';
/**
*
*/
const boatRoutes: Array<RouteRecordRaw> = [
{
path: '/boat',
component: Layout,
redirect: '/boat/info',
meta: {
title: '船舶信息',
icon: 'BoatInfo',
native: false,
},
children: [
{
path: '/boat/info',
name: 'boatInfo',
component: () => import('@/views/Boat/Info/index.vue'),
meta: {
title: '船期信息',
icon: 'Menu',
native: true,
},
},
{
path: '/boat/query',
name: 'boatQuery',
component: () => import('@/views/Boat/Query/index.vue'),
meta: {
title: '船图查询',
icon: 'Menu',
native: true,
},
},
{
path: '/boat/track',
name: 'boatTrack',
component: () => import('@/views/Boat/Track/index.vue'),
meta: {
title: '船位跟踪',
icon: 'Menu',
native: true,
},
},
],
},
];
export default boatRoutes;

View File

@ -0,0 +1,42 @@
import { RouteRecordRaw } from 'vue-router';
import Layout from '@/layouts/index.vue';
/**
*
*/
const historyRoutes: Array<RouteRecordRaw> = [
{
path: '/history',
component: Layout,
redirect: '/history/mine',
meta: {
title: '历史数据',
icon: 'History',
native: false,
},
children: [
{
path: '/history/mine',
name: 'Mine',
component: () => import('@/views/History/Mine/index.vue'),
meta: {
title: '我发布的',
icon: 'Menu',
native: true,
},
},
{
path: '/history/receive',
name: 'Receive',
component: () => import('@/views/History/Receive/index.vue'),
meta: {
title: '我收到的',
icon: 'Menu',
native: true,
},
},
],
},
];
export default historyRoutes;

View File

@ -0,0 +1,53 @@
import { RouteRecordRaw } from 'vue-router';
import Layout from '@/layouts/index.vue';
/**
*
*/
const manifestRoutes: Array<RouteRecordRaw> = [
{
path: '/manifest',
component: Layout,
redirect: '/manifest/manage',
meta: {
title: '舱单信息',
icon: 'ManifestInfo',
native: false,
},
children: [
{
path: '/manifest/manage',
name: 'manifestManage',
component: () => import('@/views/Manifest/Manage/index.vue'),
meta: {
title: '舱单信息',
icon: 'Menu',
native: true,
},
},
{
path: '/manifest/detail',
name: 'manifestDetail',
component: () => import('@/views/Manifest/Detail/index.vue'),
meta: {
title: '提单明细',
icon: 'Menu',
native: true,
},
},
{
path: '/manifest/stowage',
name: 'manifestStowage',
component: () => import('@/views/Manifest/Stowage/index.vue'),
meta: {
title: '积载图',
icon: 'Menu',
native: true,
},
},
],
},
];
export default manifestRoutes;

View File

@ -0,0 +1,23 @@
import { RouteRecordRaw } from 'vue-router';
import Layout from '@/layouts/index.vue';
/**
*
*/
const sendRoutes: Array<RouteRecordRaw> = [
{
path: '/send',
component: Layout,
redirect: '/send/index',
children: [
{
path: '/send/index',
name: 'send',
component: () => import('@/views/Send/index.vue'),
meta: { title: '发布信息', icon: 'SendInfo', native: false },
},
],
},
];
export default sendRoutes;

View File

@ -0,0 +1,42 @@
import { RouteRecordRaw } from 'vue-router';
import Layout from '@/layouts/index.vue';
/**
*
*/
const subscribeRoutes: Array<RouteRecordRaw> = [
{
path: '/subscribe',
component: Layout,
redirect: '/subscribe/mine',
meta: {
title: '订阅信息',
icon: 'SubscribeInfo',
native: false,
},
children: [
{
path: '/subscribe/mine',
name: 'Mine',
component: () => import('@/views/Subscribe/Mine/index.vue'),
meta: {
title: '我的订阅',
icon: 'Menu',
native: true,
},
},
{
path: '/subscribe/receive',
name: 'Receive',
component: () => import('@/views/Subscribe/Receive/index.vue'),
meta: {
title: '收到订阅',
icon: 'Menu',
native: true,
},
},
],
},
];
export default subscribeRoutes;

View File

@ -0,0 +1,76 @@
import NProgress from 'nprogress'; // 进度条
import { router } from '@/router';
import 'nprogress/nprogress.css'; // 进度条样式
// 进度条配置
NProgress.configure({ showSpinner: false });
// 白名单-不需要权限验证
const whiteList = ['/login'];
/**
*
* @param to
* @param from
* @param next
*/
router.beforeEach(async (to, from, next) => {
// 进度条开始
NProgress.start();
// 设置标题
if (typeof to.meta.title === 'string') {
document.title = to.meta.title || import.meta.env.VITE_APP_TITLE;
}
// 获取用户信息 store
// const userStore = useUserStore();
// 获取用户是否登录状态确定用户是否已登录过存在Token
// const hasToken = userStore.token;
if (false) {
// 用户登录
if (to.path === '/login') {
// 如果已登录,重定向到主页
next({ path: '/' });
} else {
// 获取用户权限 store
// const permissionStore = usePermissionStore();
// 确定用户是否已通过getInfo获得其权限角色
// const hasRoles = userStore.roles && userStore.roles.length > 0;
try {
// // 路由添加进去了没有及时更新 需要重新进去一次拦截
// if (!permissionStore.routes.length) {
// // 获取权限列表进行接口访问 因为这里页面要切换权限
// const accessRoutes = await permissionStore.generateRoutes(userStore.roles);
// // 动态添加访问路由表
// accessRoutes.forEach((item) => router.addRoute(item));
// // 这里相当于push到一个页面 不在进入路由拦截
// next({ ...to, replace: true });
// } else {
// // 如果不传参数就会重新执行路由拦截,重新进到这里
// next();
// }
next();
} catch (error) {
next(`/login?redirect=${to.path}`);
}
}
} else {
// 用户未登录
if (whiteList.indexOf(to.path) !== -1) {
// 在免登录白名单中,直接进入
next();
} else {
// 没有访问权限的其他页面将重定向到登录页面
next(`/login?redirect=${to.path}`);
}
}
});
router.afterEach(() => {
// 进度条结束
NProgress.done();
});

12
src/store/index.ts 100644
View File

@ -0,0 +1,12 @@
import { createPinia } from 'pinia';
import { App } from 'vue';
// 创建pinia实例
const store = createPinia();
// 配置pinia
export function setupStore(app: App<Element>) {
app.use(store);
}
export { store };

View File

@ -0,0 +1,23 @@
import { defineStore } from 'pinia';
interface settingsStateType {
isDark: boolean;
}
export const useSettingStore = defineStore({
// id: 必须的,在所有 Store 中唯一
id: 'settingState',
// state: 返回对象的函数
state: (): settingsStateType => ({
isDark: false, // 深色模式 切换暗黑模式
}),
// actions: 可以同步 也可以异步
actions: {
// 设置暗黑模式
setThemeDark(value: boolean) {
this.isDark = value;
},
},
});

View File

@ -0,0 +1,32 @@
@import './reset.scss';
@import './transition.scss';
html,
body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei',
Arial, sans-serif;
}
label {
font-weight: 700;
}
html {
box-sizing: border-box;
height: 100%;
}
body {
background: #f0f2f5;
}
#app {
height: 100%;
}
/* 自定义暗黑模式样式 */
html.dark {
body {
color: #fff;
background-color: #222;
}
}

View File

@ -0,0 +1,126 @@
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
padding: 0;
margin: 0;
font: inherit;
font-size: 100%;
vertical-align: baseline;
border: 0;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
padding: 0;
margin: 0;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote::before,
blockquote::after,
q::before,
q::after {
content: '';
content: none;
}
table {
border-spacing: 0;
border-collapse: collapse;
}

View File

@ -0,0 +1,38 @@
// css
// logo
.sidebarLogoFade-enter-active {
transition: opacity 2s;
}
.sidebarLogoFade-enter-from,
.sidebarLogoFade-leave-to {
opacity: 0;
}
//
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all 0.5s;
}
.breadcrumb-enter-from,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(10px) skewX(-10deg);
}
.breadcrumb-leave-active {
position: absolute;
}
//
.fade-slide-leave-active,
.fade-slide-enter-active {
transition: all 0.3s;
}
.fade-slide-enter-from {
opacity: 0;
transform: translateX(-30px);
}
.fade-slide-leave-to {
opacity: 0;
transform: translateX(30px);
}

View File

@ -0,0 +1,86 @@
import path from 'path-browserify';
import { RouteRecordRaw } from 'vue-router';
/**
* @description:
* @param {RouteRecordRaw[]} routes
* @return
*/
const getChildrenRoutes = (routes: RouteRecordRaw[]) => {
const result: RouteRecordRaw[] = [];
routes.forEach((route) => {
if (route.children && route.children.length > 0) {
result.push(...route.children);
}
});
return result;
};
/**
* @description:
* @param {RouteRecordRaw[]} routes
* @return
*/
export const filterRoutes = (routes: RouteRecordRaw[]) => {
const childrenRoutes = getChildrenRoutes(routes);
return routes.filter((route) => {
return !childrenRoutes.find((childrenRoute) => {
return childrenRoute.path === route.path;
});
});
};
/**
* @description:
* @param {any} data
* @return -
*/
const isNull = (data: any) => {
if (!data) return true;
if (JSON.stringify(data) === '{}') return true;
if (JSON.stringify(data) === '[]') return true;
return false;
};
/**
* @description: routesmenu
* @param {RouteRecordRaw[]} routes
* @param {string} basePath
* @return menu
*/
export const generateMenus = (routes: RouteRecordRaw[], basePath = '') => {
const result: RouteRecordRaw[] = [];
// 不满足条件meta && meta.title && meta.icon 的数据不应该存在
routes.forEach((item) => {
// 不存在children && meta ,直接返回
if (isNull(item.children) && isNull(item.meta)) return;
// 存在children不存在meta迭代 generateMenus
if (isNull(item.meta) && !isNull(item.children)) {
result.push(...generateMenus(item.children as RouteRecordRaw[])); // 断言children为Array<RouteRecordRaw>类型
return;
}
// 不存在 children存在meta || 存在children也存在meta
// 因为最终的menu需要进行跳转此时我们需要合并path
const routePath = path.resolve(basePath, item.path);
// 路由分离之后,可能存在同名父路由的情况
let route = result.find((item) => item.path === routePath);
// 当前路由尚未加入到result
if (!route) {
route = {
...item,
path: routePath,
children: [],
};
// 路由icon和title存在
if (route.meta?.icon && route.meta.title) {
result.push(route);
}
}
// 存在children 和 meta
if (!isNull(item.children)) {
route.children?.push(...generateMenus(item.children as RouteRecordRaw[], route.path));
}
});
return result;
};

View File

@ -0,0 +1,117 @@
<template>
<div class="center-table">
<!-- <div class="header">
<!~~ <el-form :inline="true" :model="searchTableForm" ref="searchTableFormRef">
<el-form-item label="助力中心" prop="name">
<el-input v-model="searchTableForm.name" placeholder="请输入助力中心名" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" >查询</el-button>
<el-button icon="Refresh" >重置</el-button>
</el-form-item>
</el-form> ~~>
</div>-->
<div class="footer">
<div class="footer-util">
<el-button type="primary"> 船期导出 </el-button>
</div>
<!-- 表格 -->
<div class="footer-table">
<el-table :data="tableData" border stripe style="width: 100%; height: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
</el-table>
</div>
<!-- 分页 -->
<div class="footer-pagination">
<!-- <Pagination
:pageAble="10"
:handle-size-change="handleSizeChange"
:handle-current-change="handleCurrentChange"
/> -->
</div>
</div>
</div>
</template>
<script lang="ts" setup>
// import Pagination from '@/components/Pagination/index.vue';
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
];
</script>
<style lang="scss" scoped>
.center-table {
position: relative;
display: flex;
flex: 1;
flex-direction: column;
width: 100%;
.header {
display: flex;
padding: 16px 16px 0;
margin-bottom: 16px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
}
.footer {
position: relative;
box-sizing: border-box;
display: flex;
flex: 1;
flex-direction: column;
padding: 16px;
overflow: hidden;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
.footer-util {
display: flex;
flex-shrink: 0;
justify-content: flex-end;
margin-bottom: 15px;
}
.footer-table {
position: relative;
flex: 1;
max-height: calc(100% - 100px);
}
.footer-pagination {
box-sizing: border-box;
display: flex;
flex-shrink: 0;
justify-content: flex-end;
width: 100%;
padding-top: 20px;
}
}
}
</style>

View File

@ -0,0 +1,16 @@
<template>
<div class="boat">
<InfoTable />
</div>
</template>
<script lang="ts" setup>
import InfoTable from './components/InfoTable.vue';
</script>
<style lang="scss" scoped>
.boat {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="query">查询</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.query {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="track">跟踪</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.track {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="mine"></div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.mine {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="receive">收到的订阅</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.receive {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<div class="card">
<div class="card-title">{{ cardData.title }}</div>
<div class="card-text number">{{ cardData.number }}</div>
<div class="card-text">
<div>{{ cardData.totalTitle }}</div>
<div>{{ cardData.totalNumber }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
defineProps<{
cardData: {
title: string;
number: number;
totalTitle: string;
totalNumber: number;
};
}>();
</script>
<style lang="scss" scoped>
.card {
width: 100%;
margin-bottom: 20px;
color: #020817;
background-color: #fff;
border: 1px solid #e4e4e7;
border-radius: 8px;
.card-title {
box-sizing: border-box;
width: 100%;
padding: 10px;
font-size: 18px;
font-weight: 500;
}
.card-text {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 40px;
padding: 0 10px 10px;
}
.number {
font-size: 24px;
font-weight: 700;
}
}
</style>

View File

@ -0,0 +1,30 @@
<template>
<v-chart class="chart" :option="option" />
</template>
<script setup>
import { PieChart } from 'echarts/charts';
import { LegendComponent, TitleComponent, TooltipComponent } from 'echarts/components';
import { use } from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import VChart from 'vue-echarts';
use([CanvasRenderer, PieChart, TitleComponent, TooltipComponent, LegendComponent]);
defineProps({
option: {
type: Object,
default: () => {},
},
});
</script>
<style lang="scss" scoped>
.chart {
width: 100%;
height: 400px;
background-color: #fff;
border: 1px solid #e4e4e7;
border-radius: 8px;
}
</style>

View File

@ -0,0 +1,162 @@
<template>
<div class="home">
<div class="home-search">
<el-form :inline="true" :model="searchTableForm" ref="searchTableFormRef">
<el-form-item label="车架号" prop="name">
<el-input v-model="searchTableForm.name" placeholder="请输入车架号" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search">查询</el-button>
</el-form-item>
</el-form>
</div>
<div class="home-header">
<el-row :gutter="20">
<el-col
:xs="24"
:sm="12"
:md="8"
:lg="6"
:xl="2"
v-for="(item, index) in dataCard"
:key="index"
>
<Card :cardData="item"></Card>
</el-col>
</el-row>
</div>
<div class="home-content">
<el-row :gutter="32">
<el-col
:xs="24"
:sm="24"
:md="8"
:lg="8"
:xl="4"
class="charts"
v-for="item in 3"
:key="item"
>
<HomeChart :option="option" />
</el-col>
</el-row>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import Card from './components/Card.vue';
import HomeChart from './components/HomeChart.vue';
//
const searchTableForm = reactive({
name: '',
});
const dataCard = ref([
{
title: '年度船舶艘次',
number: 500,
totalTitle: '累计船舶艘次',
totalNumber: 4000,
},
{
title: '本港年度艘次',
number: 30,
totalTitle: '本港船舶艘次',
totalNumber: 100,
},
{
title: '年度货物数量',
number: 500,
totalTitle: '累计货物数量',
totalNumber: 2000,
},
{
title: '本港年度货物',
number: 100,
totalTitle: '本港货物累计',
totalNumber: 300,
},
]);
// TEST:
const option = ref({
title: {
text: '测试数据',
left: 'center',
},
legend: {
bottom: '2%',
left: 'center',
},
series: [
{
animationDelay() {
return Math.random() * 100;
},
animationEasing: 'exponentialInOut',
animationType: 'scale',
avoidLabelOverlap: false,
color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
data: [
{ name: '搜索引擎', value: 1048 },
{ name: '直接访问', value: 735 },
{ name: '邮件营销', value: 580 },
{ name: '联盟广告', value: 484 },
],
emphasis: {
label: {
fontSize: '12',
fontWeight: 'bold',
show: true,
},
},
itemStyle: {
// borderColor: '#fff',
borderRadius: 10,
borderWidth: 2,
},
label: {
position: 'center',
show: false,
},
labelLine: {
show: false,
},
name: '访问来源',
radius: ['40%', '65%'],
type: 'pie',
},
],
tooltip: {
trigger: 'item',
},
});
</script>
<style lang="scss" scoped>
.home {
width: 100%;
height: 100%;
.home-search {
display: flex;
padding: 16px 16px 0;
margin-bottom: 16px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
}
.home-header {
width: 100%;
}
.home-content {
width: 100%;
.charts {
width: 100%;
margin-bottom: 20px;
}
}
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="detail"></div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.detail {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="info"></div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.info {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="stowage"></div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.stowage {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,91 @@
<template>
<div class="notify">
<div class="list">
<ul class="list-wrap">
<li v-for="o in 4" :key="o" class="list-item">
<div class="item-title">公告标题</div>
<div class="item-date">2022-01-01</div>
</li>
</ul>
</div>
<div class="content">
<div class="title">平台公告</div>
<el-card class="card">
<template #header>
<div class="card-header">Card name</div>
</template>
<div>Content</div>
</el-card>
</div>
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.notify {
display: flex;
justify-content: space-between;
width: 100%;
height: 100%;
overflow-x: hidden;
.list {
box-sizing: border-box;
width: 40%;
height: 100%;
padding: 20px;
color: #303133;
background-color: #fff;
border: 1px solid #e4ede7;
border-radius: 4px;
.list-wrap {
box-sizing: border-box;
width: 100%;
height: 100%;
overflow-y: auto;
.list-item {
box-sizing: border-box;
display: flex;
align-items: center;
width: 100%;
padding: 10px 0;
overflow: hidden;
border-bottom: 1px dashed #e4e4e7;
.item-title {
flex: 1;
overflow: hidden;
font-size: 16px;
text-overflow: ellipsis;
white-space: nowrap;
}
.item-date {
margin-left: 20px;
font-size: 14px;
}
}
}
}
.content {
width: 60%;
height: 100%;
margin-left: 20px;
.title {
display: flex;
justify-content: center;
padding: 16px;
font-size: 23px;
font-weight: 700;
color: var(--el-text-color-regular);
}
.card {
width: 100%;
height: calc(100% - 70px);
.card-header {
font-size: 16px;
font-weight: 700;
color: var(--el-text-color-regular);
}
}
}
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="resource">resource</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.resource {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="send">发布信息</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.send {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="mine"></div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.mine {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="receive">收到的订阅</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.receive {
width: 100%;
height: 100%;
}
</style>

7
src/vite-env.d.ts vendored 100644
View File

@ -0,0 +1,7 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}

21
tsconfig.json 100644
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

28
vite.config.ts 100644
View File

@ -0,0 +1,28 @@
import vue from '@vitejs/plugin-vue';
import path from 'path';
import { defineConfig } from 'vite';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
function resolve(dir: string) {
return path.join(__dirname, '.', dir);
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
// 使用 svg 图标
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
}),
],
// 配置别名
resolve: {
alias: {
'@': resolve('src'), // 设置 `@` 指向 `src` 目录
},
},
});