commit fc25792e619516843ec11da5d1d67b160820a90f
Author: 榆钱落尽槿花稀 <2675540038@qq.com>
Date: Tue Jul 9 18:07:55 2024 +0800
1
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..4fc13c7
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,14 @@
+root = true
+
+[*]
+indent_style = space
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.{ts,js,vue,css}]
+indent_size = 2
diff --git a/.env b/.env
new file mode 100644
index 0000000..9465e81
--- /dev/null
+++ b/.env
@@ -0,0 +1,2 @@
+# 打包路径 根据项目不同按需配置
+VITE_BASE_URL = ./
diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..c9080bb
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,2 @@
+# 打包路径
+VITE_BASE_URL = ./
diff --git a/.env.site b/.env.site
new file mode 100644
index 0000000..9465e81
--- /dev/null
+++ b/.env.site
@@ -0,0 +1,2 @@
+# 打包路径 根据项目不同按需配置
+VITE_BASE_URL = ./
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..d631784
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,3 @@
+dist
+node_modules
+!.prettierrc.js
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..875ec75
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,76 @@
+{
+ "extends": ["airbnb-base", "prettier", "plugin:@typescript-eslint/recommended", "plugin:vue/essential"],
+ "env": {
+ "browser": true,
+ "node": true,
+ "jest": true,
+ "es6": true
+ },
+ "globals": {
+ "cy": "readonly"
+ },
+ "plugins": ["vue", "@typescript-eslint"],
+ "parserOptions": {
+ "parser": "@typescript-eslint/parser",
+ "sourceType": "module",
+ "allowImportExportEverywhere": true,
+ "ecmaFeatures": {
+ "jsx": true
+ }
+ },
+ "rules": {
+ "@typescript-eslint/ban-ts-ignore": 0,
+ "@typescript-eslint/no-explicit-any": 0,
+ "@typescript-eslint/no-require-imports": 0,
+ "@typescript-eslint/no-var-requires": 0,
+ "@typescript-eslint/prefer-for-of": 0,
+ "@typescript-eslint/explicit-function-return-type": 0,
+ "@typescript-eslint/explicit-module-boundary-types": 0,
+ "import/no-extraneous-dependencies": 0,
+ "import/extensions": 0,
+ "import/no-unresolved": 0,
+ "indent": [2, 2],
+ "camelcase": 0,
+ "class-methods-use-this": 0,
+ "new-cap": 0,
+ "no-new": 1,
+ "no-shadow": 0,
+ "no-console": 0,
+ "no-underscore-dangle": 0,
+ "no-confusing-arrow": 0,
+ "no-plusplus": [
+ "error",
+ {
+ "allowForLoopAfterthoughts": true
+ }
+ ],
+ "no-param-reassign": 0,
+ "func-style": 0,
+ "prefer-default-export": 0,
+ "max-len": 0,
+ "consistent-return": 0
+ },
+ "overrides": [
+ {
+ "files": ["*.vue"],
+ "rules": {
+ "vue/return-in-computed-property": 1,
+ "vue/order-in-components": 2,
+ "vue/component-name-in-template-casing": [2, "kebab-case"],
+ "vue/require-default-prop": 0,
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "import/order": "off"
+ }
+ },
+ {
+ "files": ["src/*", "*.js"],
+ "rules": {
+ "no-var-requires": 0,
+ "no-console": 0,
+ "no-unused-expressions": 0,
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "import/order": "off"
+ }
+ }
+ ]
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2c4cd52
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+*.local
+.vscode
+.history
+README.html
+
+.stylelintcache
+.idea
+yarn.lock
+package-lock.json
\ No newline at end of file
diff --git a/.husky/commit-msg b/.husky/commit-msg
new file mode 100644
index 0000000..ccfec39
--- /dev/null
+++ b/.husky/commit-msg
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx --no-install commitlint -e $GIT_PARAMS
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..c37466e
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx lint-staged
\ No newline at end of file
diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg
new file mode 100644
index 0000000..71fe5b3
--- /dev/null
+++ b/.husky/prepare-commit-msg
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+exec < /dev/tty && npx git-cz --hook || true
\ No newline at end of file
diff --git a/.prettierrc.js b/.prettierrc.js
new file mode 100644
index 0000000..5e92232
--- /dev/null
+++ b/.prettierrc.js
@@ -0,0 +1,39 @@
+module.exports = {
+ // 一行最多 120 字符
+ printWidth: 120,
+ // 使用 2 个空格缩进
+ tabWidth: 2,
+ // 不使用缩进符,而使用空格
+ useTabs: false,
+ // 行尾需要有分号
+ semi: true,
+ // 使用单引号
+ singleQuote: true,
+ // 对象的 key 仅在必要时用引号
+ quoteProps: 'as-needed',
+ // jsx 不使用单引号,而使用双引号
+ jsxSingleQuote: false,
+ // 末尾需要有逗号
+ trailingComma: 'all',
+ // 大括号内的首尾需要空格
+ bracketSpacing: true,
+ // jsx 标签的反尖括号需要换行
+ jsxBracketSameLine: false,
+ // 箭头函数,只有一个参数的时候,也需要括号
+ arrowParens: 'always',
+ // 每个文件格式化的范围是文件的全部内容
+ rangeStart: 0,
+ rangeEnd: Infinity,
+ // 不需要写文件开头的 @prettier
+ requirePragma: false,
+ // 不需要自动在文件开头插入 @prettier
+ insertPragma: false,
+ // 使用默认的折行标准
+ proseWrap: 'preserve',
+ // 根据显示样式决定 html 要不要折行
+ htmlWhitespaceSensitivity: 'css',
+ // vue 文件中的 script 和 style 内不用缩进
+ vueIndentScriptAndStyle: false,
+ // 换行符使用 lf
+ endOfLine: 'lf',
+};
diff --git a/.stylelintignore b/.stylelintignore
new file mode 100644
index 0000000..1b7da3c
--- /dev/null
+++ b/.stylelintignore
@@ -0,0 +1,8 @@
+# .stylelintignore
+# 旧的不需打包的样式库
+*.min.css
+
+# 其他类型文件
+*.js
+*.jpg
+*.woff
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..789cbde
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2021-present TDesign
+
+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.
diff --git a/PROXY.md b/PROXY.md
new file mode 100644
index 0000000..8a56932
--- /dev/null
+++ b/PROXY.md
@@ -0,0 +1,22 @@
+# TDesign starter 本地开发联调
+
+## 工具准备
+
+- 浏览器插件:[SwitchyOmega](https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif?hl=zh-CNhttps://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif?hl=zh-CN)
+- 调试代理工具:[whistle](https://wproxy.org/whistle/)
+
+## 代理配置
+
+`npm run dev`开启本地服务后,可以配置代理将线上域名的非后台 api 路径(如`/api`)的静态文件请求代理到本地,这样就可以进行本地联调和前端代码热更新了。
+
+举例子:
+
+```
+/tdesign.tencent.com(?!\/api)/ 127.0.0.1:3001
+```
+
+其中:
+
+- tdesign.tencent.com:修改你的线上域名
+- /api:修改成后台请求路径
+- 3001:修改成本地服务端口
diff --git a/README-zh_CN.md b/README-zh_CN.md
new file mode 100644
index 0000000..cb90038
--- /dev/null
+++ b/README-zh_CN.md
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+简体中文 | [English](./README.md)
+
+### 项目简介
+
+TDesign Vue Starter 是一个基于 tdesign-vue,使用 `Vue2`、`Vite`开发,可进行个性化主题配置,旨在提供项目开箱即用的、配置式的中后台项目。
+
+
+ 在线预览
+ ·
+ 使用文档
+
+
+
+
+
+### 特性
+
+- 内置多种常用的中后台页面
+- 完善的目录结构
+- 完善的代码规范配置
+- 支持暗黑模式
+- 自定义主题颜色
+- 多种空间布局
+- 内置 Mock 数据方案
+
+### 使用
+
+> 通过 [tdesign-starter-cli](https://www.npmjs.com/package/tdesign-starter-cli) 初始化项目仓库
+
+```bash
+## 1、安装 tdesign-starter-cli
+npm i tdesign-starter-cli@latest -g
+
+## 2、创建项目
+td-starter init
+```
+
+### 开发
+
+```bash
+## 安装依赖
+npm install
+
+## 启动项目
+npm run dev
+```
+
+### 构建
+
+```bash
+## 构建正式环境
+npm run build
+
+## 构建测试环境
+npm run build:test
+```
+
+### 其他
+
+```bash
+## 预览构建产物
+npm run preview
+
+## 代码格式检查
+npm run lint
+
+## 代码格式检查与自动修复
+npm run lint:fix
+
+## style格式检查
+npm run stylelint
+
+## style格式检查与自动修复
+npm run stylelint:fix
+```
+
+### 如何贡献
+
+非常欢迎您的贡献!提交您的 [Issue](https://github.com/tencent/tdesign-vue-starter/issues/new/choose) 或者提交 [Pull Request](https://github.com/Tencent/tdesign-vue-starter/pulls)。
+
+#### 贡献提交规范
+
+- [Angular Convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular)
+- [Vue Style Guide](https://v3.vuejs.org/style-guide/#rule-categories)
+
+### 兼容性
+
+| [ ](http://godban.github.io/browsers-support-badges/) IE / Edge | [ ](http://godban.github.io/browsers-support-badges/)Firefox | [ ](http://godban.github.io/browsers-support-badges/)Chrome | [ ](http://godban.github.io/browsers-support-badges/)Safari |
+| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Edge >=84 | Firefox >=83 | Chrome >=84 | Safari >=14.1 |
+
+### 社区版本
+
+基于 TDesign Vue 的 starter-kit 有多种社区版本,访问 [社区链接](https://tdesign.tencent.com/starter/docs/vue/community-link) 可以访问更多版本。
+如果您也开发了 TDesign Starter 的社区版本,可以提交 Issue 或者直接给我们提Pull Request 😊。
+
+### 开源协议
+
+TDesign 遵循 [MIT 协议](https://github.com/Tencent/tdesign-vue-starter/LICENSE)。
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4ead8fd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+English | [简体中文](./README-zh_CN.md)
+### Introduction
+
+TDesign Vue Starter is a TDesign-based project developed with `Vue2`, `Vite`. It can be customized theme configuration, and aims to provide project out-of-the-box, configuration-style middle and background projects.
+
+
+ Live Preview
+ ·
+ Documentation
+
+
+
+
+### Features
+
+- Various provided pages for develop
+- Complete directory structure for develop
+- Code specification configuration
+- Support dark mode
+- Custom theme colors
+- Various space layouts
+- Mock data scheme
+
+### Usage
+
+> Initialize project with our CLI tool `tdesign-starter-cli`
+
+```bash
+## install tdesign-starter-cli
+npm i tdesign-starter-cli@latest -g
+
+## create project
+td-starter init
+```
+
+### Develop
+
+```bash
+## install dependencies
+npm install
+
+## set up
+npm run dev
+```
+
+### Build
+
+```bash
+## build
+npm run build
+
+## build for test
+npm run build:test
+```
+
+
+### Contributing Guide
+
+We welcome contributions to our project. Create your [Issue](https://github.com/tencent/tdesign-vue-starter/issues/new/choose) or Submit your [Pull Request](https://github.com/Tencent/tdesign-vue-starter/pulls).
+
+#### Commit Specification
+
+- [Angular Convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular)
+- [Vue Style Guide](https://v3.vuejs.org/style-guide/#rule-categories)
+
+### Browser Support
+
+| [ ](http://godban.github.io/browsers-support-badges/) IE / Edge | [ ](http://godban.github.io/browsers-support-badges/)Firefox | [ ](http://godban.github.io/browsers-support-badges/)Chrome | [ ](http://godban.github.io/browsers-support-badges/)Safari |
+| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Edge >=84 | Firefox >=83 | Chrome >=84 | Safari >=14.1 |
+
+### Community Versions
+
+There are kinds of community versions of starter-kit based on TDesign Vue Next, visit [community-link](https://tdesign.tencent.com/starter/docs/vue-next/community-link) for more detail. If you developed a community versions of tdesign starter, please create a issue or submit a pull request to let us know 😊.
+
+### License
+
+The MIT License. Please see [the license file](LICENSE) for more information.
diff --git a/cache.dockerfile b/cache.dockerfile
new file mode 100644
index 0000000..5e0cae1
--- /dev/null
+++ b/cache.dockerfile
@@ -0,0 +1,15 @@
+# 选择一个 Base 镜像
+FROM node:12
+
+# 设置工作目录
+WORKDIR /space
+
+# 将 by 中的文件列表 COPY 过来
+COPY . .
+
+# 根据 COPY 过来的文件进行依赖的安装
+RUN npm i
+
+# 设置好需要的环境变量
+ENV NODE_PATH=/space/node_modules
+
diff --git a/commitlint.config.js b/commitlint.config.js
new file mode 100644
index 0000000..422b194
--- /dev/null
+++ b/commitlint.config.js
@@ -0,0 +1 @@
+module.exports = { extends: ['@commitlint/config-conventional'] };
diff --git a/globals.d.ts b/globals.d.ts
new file mode 100644
index 0000000..09a605d
--- /dev/null
+++ b/globals.d.ts
@@ -0,0 +1,13 @@
+// 通用声明
+declare type ClassName = { [className: string]: any } | ClassName[] | string;
+
+declare interface ImportMeta {
+ env: {
+ MODE: 'mock' | 'development' | 'test' | 'release' | 'site';
+ };
+}
+
+declare module '*.svg' {
+ const content: string;
+ export default content;
+}
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..8a8e00c
--- /dev/null
+++ b/index.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jsx.d.ts b/jsx.d.ts
new file mode 100644
index 0000000..84f32e2
--- /dev/null
+++ b/jsx.d.ts
@@ -0,0 +1,13 @@
+import Vue, { VNode } from 'vue';
+
+
+declare global {
+ namespace JSX {
+ type Element = VNode;
+ type ElementClass = Vue;
+ interface IntrinsicElements {
+ [elem: string]: any;
+ }
+ type IntrinsicAttributes = any;
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..8905c08
--- /dev/null
+++ b/package.json
@@ -0,0 +1,92 @@
+{
+ "name": "yunshangxie",
+ "version": "0.6.2",
+ "scripts": {
+ "dev:mock": "vite --open --mode mock",
+ "dev": "vite --open --mode development",
+ "dev:linux": "vite --mode development",
+ "build:test": "vite build --mode test",
+ "build": "vite build --mode release",
+ "build:site": "vite build --mode site",
+ "site:preview": "npm run build && cp -r dist _site",
+ "preview": "vite preview",
+ "lint": "eslint --ext .vue,.js,.jsx,.ts,.tsx ./ --max-warnings 0",
+ "lint:fix": "eslint --ext .vue,.js,jsx,.ts,.tsx ./ --max-warnings 0 --fix",
+ "stylelint": "stylelint src/**/*.{html,vue,sass,less}",
+ "stylelint:fix": "stylelint --cache --fix src/**/*.{html,vue,vss,sass,less}",
+ "prepare": "node -e \"if(require('fs').existsSync('.git')){process.exit(1)}\" || is-ci || husky install",
+ "test": "echo \"no test specified,work in process\"",
+ "test:coverage": "echo \"no test:coverage specified,work in process\""
+ },
+ "dependencies": {
+ "@wangeditor/editor-for-vue": "^1.0.2",
+ "axios": "^1.1.3",
+ "dayjs": "^1.10.8",
+ "echarts": "5.1.2",
+ "lodash": "^4.17.21",
+ "nprogress": "^0.2.0",
+ "qrcode.vue": "^1.7.0",
+ "tdesign-icons-vue": "^0.1.11",
+ "tdesign-vue": "^1.9.0",
+ "tvision-color": "~1.6.0",
+ "vue": "~2.6.14",
+ "vue-clipboard2": "^0.3.1",
+ "vue-cropper": "^0.6.5",
+ "vue-qr": "^4.0.9",
+ "vue-router": "^3.5.1",
+ "vuex": "^3.6.2",
+ "vuex-router-sync": "^5.0.0"
+ },
+ "devDependencies": {
+ "@commitlint/cli": "^17.0.3",
+ "@commitlint/config-conventional": "^17.1.0",
+ "@types/vue-color": "^2.4.3",
+ "@typescript-eslint/eslint-plugin": "^6.17.0",
+ "@typescript-eslint/parser": "^6.17.0",
+ "commitizen": "^4.2.3",
+ "eslint": "^7.22.0",
+ "eslint-config-airbnb-base": "^14.2.1",
+ "eslint-config-prettier": "^8.5.0",
+ "eslint-import-resolver-alias": "^1.1.2",
+ "eslint-plugin-import": "^2.22.1",
+ "eslint-plugin-vue": "^7.8.0",
+ "husky": "^8.0.1",
+ "less": "^4.1.0",
+ "lint-staged": "^13.0.3",
+ "mockjs": "^1.1.0",
+ "prettier": "^2.6.0",
+ "stylelint": "~13.13.1",
+ "stylelint-config-prettier": "~9.0.3",
+ "stylelint-less": "1.0.5",
+ "stylelint-order": "~4.1.0",
+ "typescript": "^5.4.5",
+ "vite": "^4.1.4",
+ "vite-plugin-mock": "^3.0.0",
+ "vite-plugin-theme": "^0.8.1",
+ "vite-plugin-vue2": "^2.0.1",
+ "vite-plugin-vue2-svg": "~0.4.0",
+ "vue-template-compiler": "~2.6.14"
+ },
+ "config": {
+ "commitizen": {
+ "path": "./node_modules/cz-conventional-changelog"
+ }
+ },
+ "husky": {
+ "hooks": {
+ "pre-commit": "lint-staged",
+ "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true",
+ "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
+ }
+ },
+ "lint-staged": {
+ "*.{js,jsx,vue,ts,tsx}": [
+ "prettier --write",
+ "npm run lint:fix"
+ ],
+ "*.{html,vue,vss,sass,less}": [
+ "npm run stylelint:fix"
+ ]
+ },
+ "description": "云商协"
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..47a62f6
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/shims-vue.d.ts b/shims-vue.d.ts
new file mode 100644
index 0000000..5424484
--- /dev/null
+++ b/shims-vue.d.ts
@@ -0,0 +1,5 @@
+declare module '*.vue' {
+ import Vue from 'vue';
+
+ export default Vue;
+}
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..554771e
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
diff --git a/src/assets/assets-login-bg-black.png b/src/assets/assets-login-bg-black.png
new file mode 100644
index 0000000..b4dde4b
Binary files /dev/null and b/src/assets/assets-login-bg-black.png differ
diff --git a/src/assets/assets-login-bg-white.png b/src/assets/assets-login-bg-white.png
new file mode 100644
index 0000000..0207739
Binary files /dev/null and b/src/assets/assets-login-bg-white.png differ
diff --git a/src/assets/assets-logo-full.svg b/src/assets/assets-logo-full.svg
new file mode 100644
index 0000000..94f0049
--- /dev/null
+++ b/src/assets/assets-logo-full.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/assets-product-1.svg b/src/assets/assets-product-1.svg
new file mode 100644
index 0000000..29e97f0
--- /dev/null
+++ b/src/assets/assets-product-1.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-product-2.svg b/src/assets/assets-product-2.svg
new file mode 100644
index 0000000..827c8bf
--- /dev/null
+++ b/src/assets/assets-product-2.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-product-3.svg b/src/assets/assets-product-3.svg
new file mode 100644
index 0000000..a3d461b
--- /dev/null
+++ b/src/assets/assets-product-3.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-product-4.svg b/src/assets/assets-product-4.svg
new file mode 100644
index 0000000..7ac1abc
--- /dev/null
+++ b/src/assets/assets-product-4.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-result-403.svg b/src/assets/assets-result-403.svg
new file mode 100644
index 0000000..343a25e
--- /dev/null
+++ b/src/assets/assets-result-403.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-result-404.svg b/src/assets/assets-result-404.svg
new file mode 100644
index 0000000..db1cb36
--- /dev/null
+++ b/src/assets/assets-result-404.svg
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-result-500.svg b/src/assets/assets-result-500.svg
new file mode 100644
index 0000000..e820fe2
--- /dev/null
+++ b/src/assets/assets-result-500.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-result-ie.svg b/src/assets/assets-result-ie.svg
new file mode 100644
index 0000000..ebaf5ba
--- /dev/null
+++ b/src/assets/assets-result-ie.svg
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-result-maintenance.svg b/src/assets/assets-result-maintenance.svg
new file mode 100644
index 0000000..f0cc27e
--- /dev/null
+++ b/src/assets/assets-result-maintenance.svg
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/assets-result-wifi.svg b/src/assets/assets-result-wifi.svg
new file mode 100644
index 0000000..eeee8b5
--- /dev/null
+++ b/src/assets/assets-result-wifi.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-setting-auto.svg b/src/assets/assets-setting-auto.svg
new file mode 100644
index 0000000..66f57de
--- /dev/null
+++ b/src/assets/assets-setting-auto.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-setting-dark.svg b/src/assets/assets-setting-dark.svg
new file mode 100644
index 0000000..0f15649
--- /dev/null
+++ b/src/assets/assets-setting-dark.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-setting-light.svg b/src/assets/assets-setting-light.svg
new file mode 100644
index 0000000..ffa8f34
--- /dev/null
+++ b/src/assets/assets-setting-light.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/assets-t-logo.svg b/src/assets/assets-t-logo.svg
new file mode 100644
index 0000000..3f95cba
--- /dev/null
+++ b/src/assets/assets-t-logo.svg
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/color/index.vue b/src/components/color/index.vue
new file mode 100644
index 0000000..cbc41d3
--- /dev/null
+++ b/src/components/color/index.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
diff --git a/src/components/product-card/index.vue b/src/components/product-card/index.vue
new file mode 100644
index 0000000..fb97173
--- /dev/null
+++ b/src/components/product-card/index.vue
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ product.isSetup ? '已启用' : '已停用'
+ }}
+
+
+ {{ product.name }}
+ {{ product.description }}
+
+
+
+ {{ typeMap[product.type - 1] }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/result/index.vue b/src/components/result/index.vue
new file mode 100644
index 0000000..b730233
--- /dev/null
+++ b/src/components/result/index.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
{{ title }}
+
{{ tip }}
+
+
+
+
+
diff --git a/src/components/thumbnail/index.vue b/src/components/thumbnail/index.vue
new file mode 100644
index 0000000..61d8bac
--- /dev/null
+++ b/src/components/thumbnail/index.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
diff --git a/src/components/trend/index.vue b/src/components/trend/index.vue
new file mode 100644
index 0000000..2b2a7ba
--- /dev/null
+++ b/src/components/trend/index.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ describe }}
+
+
+
+
+
diff --git a/src/config/color.ts b/src/config/color.ts
new file mode 100644
index 0000000..300ac1d
--- /dev/null
+++ b/src/config/color.ts
@@ -0,0 +1,30 @@
+export type TColorToken = Record;
+export type TColorSeries = Record;
+
+// TODO: 中性色暂时固定 待tvision-color生成带色彩倾向的中性色
+export const LIGHT_CHART_COLORS = {
+ textColor: 'rgba(0, 0, 0, 0.9)',
+ placeholderColor: 'rgba(0, 0, 0, 0.35)',
+ borderColor: '#dcdcdc',
+ containerColor: '#fff',
+};
+
+export const DARK_CHART_COLORS = {
+ textColor: 'rgba(255, 255, 255, 0.9)',
+ placeholderColor: 'rgba(255, 255, 255, 0.35)',
+ borderColor: '#5e5e5e',
+ containerColor: '#242424',
+};
+
+export type TChartColor = typeof LIGHT_CHART_COLORS;
+
+export const DEFAULT_COLOR_OPTIONS = [
+ '#0052D9',
+ '#0594FA',
+ '#00A870',
+ '#EBB105',
+ '#ED7B2F',
+ '#E34D59',
+ '#ED49B4',
+ '#834EC2',
+];
diff --git a/src/config/global.ts b/src/config/global.ts
new file mode 100644
index 0000000..5ea972f
--- /dev/null
+++ b/src/config/global.ts
@@ -0,0 +1,2 @@
+export const prefix = 'tdesign-starter';
+export const TOKEN_NAME = 'tdesign-starter';
diff --git a/src/config/host.ts b/src/config/host.ts
new file mode 100644
index 0000000..b6145e2
--- /dev/null
+++ b/src/config/host.ts
@@ -0,0 +1,26 @@
+export default {
+ development: {
+ // 开发环境接口请求
+ API: '',
+ // 开发环境 cdn 路径
+ CDN: '',
+ },
+ test: {
+ // 测试环境接口地址
+ API: 'https://service-exndqyuk-1257786608.gz.apigw.tencentcs.com',
+ // 测试环境 cdn 路径
+ CDN: '',
+ },
+ release: {
+ // 正式环境接口地址
+ API: 'https://service-bv448zsw-1257786608.gz.apigw.tencentcs.com',
+ // 正式环境 cdn 路径
+ CDN: '',
+ },
+ site: {
+ // 正式环境接口地址
+ API: 'https://service-bv448zsw-1257786608.gz.apigw.tencentcs.com',
+ // 正式环境 cdn 路径
+ CDN: '',
+ },
+};
diff --git a/src/config/style.ts b/src/config/style.ts
new file mode 100644
index 0000000..b652f5a
--- /dev/null
+++ b/src/config/style.ts
@@ -0,0 +1,14 @@
+export default {
+ showFooter: true,
+ isSidebarCompact: false,
+ showBreadcrumb: false,
+ mode: 'light',
+ layout: 'side',
+ splitMenu: false,
+ isFooterAside: false,
+ isSidebarFixed: true,
+ isHeaderFixed: true,
+ isUseTabsRouter: false,
+ showHeader: true,
+ brandTheme: '#0052D9',
+};
diff --git a/src/constants/index.ts b/src/constants/index.ts
new file mode 100644
index 0000000..06557c7
--- /dev/null
+++ b/src/constants/index.ts
@@ -0,0 +1,46 @@
+interface IOption {
+ value: number | string;
+ label: string;
+}
+// 合同状态枚举
+export const CONTRACT_STATUS = {
+ FAIL: 0,
+ AUDIT_PENDING: 1,
+ EXEC_PENDING: 2,
+ EXECUTING: 3,
+ FINISH: 4,
+};
+
+export const CONTRACT_STATUS_OPTIONS: Array = [
+ { value: CONTRACT_STATUS.FAIL, label: '审核失败' },
+ { value: CONTRACT_STATUS.AUDIT_PENDING, label: '待审核' },
+ { value: CONTRACT_STATUS.EXEC_PENDING, label: '待履行' },
+ { value: CONTRACT_STATUS.EXECUTING, label: '审核成功' },
+ { value: CONTRACT_STATUS.FINISH, label: '已完成' },
+];
+
+// 合同类型枚举
+export const CONTRACT_TYPES = {
+ MAIN: 0,
+ SUB: 1,
+ SUPPLEMENT: 2,
+};
+
+export const CONTRACT_TYPE_OPTIONS: Array = [
+ { value: CONTRACT_TYPES.MAIN, label: '主合同' },
+ { value: CONTRACT_TYPES.SUB, label: '子合同' },
+ { value: CONTRACT_TYPES.SUPPLEMENT, label: '补充合同' },
+];
+
+// 合同收付类型枚举
+export const CONTRACT_PAYMENT_TYPES = {
+ PAYMENT: 0,
+ RECIPT: 1,
+};
+
+// 通知的优先级对应的TAG类型
+export const NOTIFICATION_TYPES = {
+ low: 'primary',
+ middle: 'warning',
+ high: 'danger',
+};
diff --git a/src/interface.ts b/src/interface.ts
new file mode 100644
index 0000000..f82260c
--- /dev/null
+++ b/src/interface.ts
@@ -0,0 +1,39 @@
+import STYLE_CONFIG from '@/config/style';
+
+export interface ResDataType {
+ code: number;
+ data: any;
+}
+
+export interface MenuRoute {
+ path: string;
+ title?: string;
+ icon?:
+ | string
+ | {
+ render: () => void;
+ };
+ redirect?: string;
+ children: MenuRoute[];
+ meta: any;
+}
+
+export type ModeType = 'dark' | 'light';
+
+export type SettingType = typeof STYLE_CONFIG;
+
+export type ClassName = { [className: string]: any } | ClassName[] | string;
+
+export type CommonObjType = {
+ [key: string]: string | number;
+};
+
+export interface NotificationItem {
+ id: string;
+ content: string;
+ type: string;
+ status: boolean;
+ collected: boolean;
+ date: string;
+ quality: 'high' | 'low' | 'middle';
+}
diff --git a/src/layouts/blank.vue b/src/layouts/blank.vue
new file mode 100644
index 0000000..dcdc217
--- /dev/null
+++ b/src/layouts/blank.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/src/layouts/components/Breadcrumb.vue b/src/layouts/components/Breadcrumb.vue
new file mode 100644
index 0000000..24b774d
--- /dev/null
+++ b/src/layouts/components/Breadcrumb.vue
@@ -0,0 +1,39 @@
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
diff --git a/src/layouts/components/Content.vue b/src/layouts/components/Content.vue
new file mode 100644
index 0000000..7c80189
--- /dev/null
+++ b/src/layouts/components/Content.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/components/Footer.vue b/src/layouts/components/Footer.vue
new file mode 100644
index 0000000..aeeea8f
--- /dev/null
+++ b/src/layouts/components/Footer.vue
@@ -0,0 +1,27 @@
+
+ Copyright © 2021-{{ new Date().getFullYear() }} LingRui. All Rights Reserved
+
+
+
+
+
diff --git a/src/layouts/components/Header.vue b/src/layouts/components/Header.vue
new file mode 100644
index 0000000..24afa7f
--- /dev/null
+++ b/src/layouts/components/Header.vue
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 退出登录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/components/LayoutContent.vue b/src/layouts/components/LayoutContent.vue
new file mode 100644
index 0000000..d5c1e5b
--- /dev/null
+++ b/src/layouts/components/LayoutContent.vue
@@ -0,0 +1,168 @@
+
+
+
+ handleRemove(route.path, idx)"
+ >
+
+
+
+ {{ route.title }}
+
+
+
+
+ handleRefresh(route.path, idx)">
+
+ 刷新
+
+ handleCloseAhead(route.path, idx)">
+
+ 关闭左侧
+
+ handleCloseBehind(route.path, idx)"
+ >
+
+ 关闭右侧
+
+ handleCloseOther(route.path, idx)">
+
+ 关闭其它
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/components/LayoutHeader.vue b/src/layouts/components/LayoutHeader.vue
new file mode 100644
index 0000000..cd0c866
--- /dev/null
+++ b/src/layouts/components/LayoutHeader.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
diff --git a/src/layouts/components/LayoutSidebar.vue b/src/layouts/components/LayoutSidebar.vue
new file mode 100644
index 0000000..3e44db6
--- /dev/null
+++ b/src/layouts/components/LayoutSidebar.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
diff --git a/src/layouts/components/MenuContent.vue b/src/layouts/components/MenuContent.vue
new file mode 100644
index 0000000..2ba62e3
--- /dev/null
+++ b/src/layouts/components/MenuContent.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/components/Notice.vue b/src/layouts/components/Notice.vue
new file mode 100644
index 0000000..33f140b
--- /dev/null
+++ b/src/layouts/components/Notice.vue
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/components/Search.vue b/src/layouts/components/Search.vue
new file mode 100644
index 0000000..15f6b43
--- /dev/null
+++ b/src/layouts/components/Search.vue
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+
diff --git a/src/layouts/components/SideNav.vue b/src/layouts/components/SideNav.vue
new file mode 100644
index 0000000..7ec12d5
--- /dev/null
+++ b/src/layouts/components/SideNav.vue
@@ -0,0 +1,157 @@
+
+
+
+
+ handleNav('/dashboard/base')">
+
+
+
+
+
+
+
+ {{association.association_name}}
+
+
+
+
+
+
+
diff --git a/src/layouts/index.vue b/src/layouts/index.vue
new file mode 100644
index 0000000..8b6c643
--- /dev/null
+++ b/src/layouts/index.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/setting.vue b/src/layouts/setting.vue
new file mode 100644
index 0000000..ff71218
--- /dev/null
+++ b/src/layouts/setting.vue
@@ -0,0 +1,404 @@
+
+
+
+
+
+ 主题模式
+
+
+
+ 主题色
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 导航布局
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 元素开关
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
请复制后手动修改配置文件: /src/config/style.ts
+
复制配置项
+
+
+
+
+
+
+
diff --git a/src/main.jsx b/src/main.jsx
new file mode 100644
index 0000000..ce9955e
--- /dev/null
+++ b/src/main.jsx
@@ -0,0 +1,50 @@
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import { sync } from 'vuex-router-sync';
+import TDesign from 'tdesign-vue';
+import VueClipboard from 'vue-clipboard2';
+import axiosInstance from '@/utils/request';
+import App from './App.vue';
+import router from './router';
+import zhConfig from 'tdesign-vue/es/locale/zh_CN';
+// import enConfig from 'tdesign-vue/es/locale/en_US'; // 英文多语言配置
+
+import 'tdesign-vue/es/style/index.css';
+import '@/style/index.less';
+
+import './permission';
+import store from './store';
+Vue.use(VueRouter);
+Vue.use(TDesign);
+Vue.use(VueClipboard);
+
+Vue.component('t-page-header');
+
+Vue.prototype.$request = axiosInstance;
+
+const originPush = VueRouter.prototype.push;
+VueRouter.prototype.push = function push(location) {
+ return originPush.call(this, location).catch((err) => err);
+};
+
+const originReplace = VueRouter.prototype.replace;
+VueRouter.prototype.replace = function replace(location) {
+ return originReplace.call(this, location).catch((err) => err);
+};
+
+Vue.config.productionTip = false;
+sync(store, router);
+new Vue({
+ router,
+ store,
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ render: (h) => (
+
+ {/* 可以通过config-provider提供全局(多语言、全局属性)配置,如
+
*/}
+
+
+
+
+ ),
+}).$mount('#app');
diff --git a/src/pages/activity/activity_index.vue b/src/pages/activity/activity_index.vue
new file mode 100644
index 0000000..9070cf4
--- /dev/null
+++ b/src/pages/activity/activity_index.vue
@@ -0,0 +1,1102 @@
+
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{row.nikename}}
+
+
+ 已签到
+ 未签到
+
+
+
+ 无
+
+
+
+
+ 拒绝
+
+
+ 通过
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 第{{ index + 1 }}题
+ (单选题)
+ (多选题)
+ (问答题)
+
+ {{item.title}}
+ 票数
+ 答题数:{{item.quantity}}
+
+
+
+
+ {{d.name}}
+ {{d.val}}
+ {{d.num}}
+
+
+ -
+ {{d.option}}
+
+
+
+
+
+
+
+
+
+
+
+ {{getType==3?'捐赠人':'付费姓名'}}
+
+ 金额
+ {{getType==3?'捐赠时间':'付费时间'}}
+
+
+
+
+ {{item.nikename}}
+ {{item.money}}元
+ {{item.createtime}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ onCreated(e)"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 单选题
+ 多选题
+ 问答题
+
+
+
+
+
+
+
+
+
+
+ X
+
+
+ 添加一个选项
+
+
+ 删除题目
+
+
+
+
+
+ 添加一个题目
+
+
+
+
+
+
+
+
+
+
+
+ 单选题
+ 多选题
+ 问答题
+
+
+
+
+
+
+
+
+
+
+ X
+
+
+ 添加一个选项
+
+
+
+ 删除题目
+
+
+
+ 保存
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/activity/activity_top.vue b/src/pages/activity/activity_top.vue
new file mode 100644
index 0000000..d38d2f0
--- /dev/null
+++ b/src/pages/activity/activity_top.vue
@@ -0,0 +1,160 @@
+
+
+
+ 新增置顶
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/association/carousel.vue b/src/pages/association/carousel.vue
new file mode 100644
index 0000000..6daa024
--- /dev/null
+++ b/src/pages/association/carousel.vue
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/association/index.vue b/src/pages/association/index.vue
new file mode 100644
index 0000000..7887b03
--- /dev/null
+++ b/src/pages/association/index.vue
@@ -0,0 +1,286 @@
+
+
+
+
+
+
+
+
diff --git a/src/pages/association/opinion.vue b/src/pages/association/opinion.vue
new file mode 100644
index 0000000..618a2c0
--- /dev/null
+++ b/src/pages/association/opinion.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
diff --git a/src/pages/association/person.vue b/src/pages/association/person.vue
new file mode 100644
index 0000000..430a776
--- /dev/null
+++ b/src/pages/association/person.vue
@@ -0,0 +1,209 @@
+
+
+
+ 新增
+
+
+ 超级管理员
+ 办事员
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
diff --git a/src/pages/association/system.vue b/src/pages/association/system.vue
new file mode 100644
index 0000000..6a6eb33
--- /dev/null
+++ b/src/pages/association/system.vue
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+ 空间总量:{{info.totalSpaceInMB}} MB
+ 已使用:{{info.usedSpaceInMB}} MB
+
+
+
+
+
+ 流量总量:{{info.totalSpaceInMB}} MB
+ 已使用:{{info.usedSpaceInMB}} MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/business/business_type.vue b/src/pages/business/business_type.vue
new file mode 100644
index 0000000..394860a
--- /dev/null
+++ b/src/pages/business/business_type.vue
@@ -0,0 +1,136 @@
+
+
+
+ 新增类别
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/business/index.vue b/src/pages/business/index.vue
new file mode 100644
index 0000000..2a79fe3
--- /dev/null
+++ b/src/pages/business/index.vue
@@ -0,0 +1,264 @@
+
+
+
+ 新增商家
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ onCreated(e)"
+ />
+
+
+
+
+
+
+
+ onCreatedHd(e)"
+ />
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/dashboard/base/components/MiddleChart.vue b/src/pages/dashboard/base/components/MiddleChart.vue
new file mode 100644
index 0000000..a3852cc
--- /dev/null
+++ b/src/pages/dashboard/base/components/MiddleChart.vue
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/dashboard/base/components/OutputOverview.vue b/src/pages/dashboard/base/components/OutputOverview.vue
new file mode 100644
index 0000000..05c8990
--- /dev/null
+++ b/src/pages/dashboard/base/components/OutputOverview.vue
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/dashboard/base/components/RankList.vue b/src/pages/dashboard/base/components/RankList.vue
new file mode 100644
index 0000000..d513322
--- /dev/null
+++ b/src/pages/dashboard/base/components/RankList.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ 本周
+ 近三个月
+
+
+
+
+
+ {{ rowIndex + 1 }}
+
+
+
+
+
+
+ 详情
+
+
+
+
+
+
+
+
+ 本周
+ 近三个月
+
+
+
+
+
+ {{ rowIndex + 1 }}
+
+
+
+
+
+
+ 详情
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/dashboard/base/components/TopPanel.vue b/src/pages/dashboard/base/components/TopPanel.vue
new file mode 100644
index 0000000..53482af
--- /dev/null
+++ b/src/pages/dashboard/base/components/TopPanel.vue
@@ -0,0 +1,246 @@
+
+
+
+
+
+ {{ item.number }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/dashboard/base/index.ts b/src/pages/dashboard/base/index.ts
new file mode 100644
index 0000000..c31a8e9
--- /dev/null
+++ b/src/pages/dashboard/base/index.ts
@@ -0,0 +1,703 @@
+import dayjs from 'dayjs';
+import { getChartListColor } from '@/utils/color';
+import { getRandomArray } from '@/utils/charts';
+
+/** 首页 dashboard 折线图 */
+export function constructInitDashboardDataset(type: string) {
+ const dateArray: Array = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
+ const datasetAxis = {
+ xAxis: {
+ type: 'category',
+ show: false,
+ data: dateArray,
+ },
+ yAxis: {
+ show: false,
+ type: 'value',
+ },
+ grid: {
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ },
+ };
+
+ if (type === 'line') {
+ const lineDataset = {
+ ...datasetAxis,
+ color: ['#fff'],
+ series: [
+ {
+ data: [150, 230, 224, 218, 135, 147, 260],
+ type,
+ showSymbol: true,
+ symbol: 'circle',
+ symbolSize: 0,
+ markPoint: {
+ data: [
+ { type: 'max', name: '最大值' },
+ { type: 'min', name: '最小值' },
+ ],
+ },
+ itemStyle: {
+ normal: {
+ lineStyle: {
+ width: 2,
+ },
+ },
+ },
+ },
+ ],
+ };
+ return lineDataset;
+ }
+ if (type === 'bar') {
+ const barDataset = {
+ ...datasetAxis,
+ color: getChartListColor(),
+ series: [
+ {
+ data: [
+ 100,
+ 130,
+ 184,
+ 218,
+ {
+ value: 135,
+ itemStyle: {
+ opacity: 0.2,
+ },
+ },
+ {
+ value: 118,
+ itemStyle: {
+ opacity: 0.2,
+ },
+ },
+ {
+ value: 60,
+ itemStyle: {
+ opacity: 0.2,
+ },
+ },
+ ],
+ type,
+ barWidth: 9,
+ },
+ ],
+ };
+ return barDataset;
+ }
+}
+
+/** 柱状图数据源 */
+export function constructInitDataset({
+ dateTime = [],
+ placeholderColor,
+ borderColor,
+}: { dateTime: Array } & Record) {
+ const divideNum = 10;
+ const timeArray = [];
+ const inArray = [];
+ const outArray = [];
+ for (let i = 0; i < divideNum; i++) {
+ if (dateTime.length > 0) {
+ const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum;
+ const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i;
+ timeArray.push(dayjs(enhandTime).format('MM-DD'));
+ } else {
+ timeArray.push(
+ dayjs()
+ .subtract(divideNum - i, 'day')
+ .format('MM-DD'),
+ );
+ }
+
+ inArray.push(getRandomArray().toString());
+ outArray.push(getRandomArray().toString());
+ }
+ const dataset = {
+ color: getChartListColor(),
+ tooltip: {
+ trigger: 'item',
+ },
+ xAxis: {
+ type: 'category',
+ data: timeArray,
+ axisLabel: {
+ color: placeholderColor,
+ },
+ axisLine: {
+ lineStyle: {
+ color: borderColor,
+ width: 1,
+ },
+ },
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ color: placeholderColor,
+ },
+ splitLine: {
+ lineStyle: {
+ color: borderColor,
+ },
+ },
+ },
+ grid: {
+ top: '5%',
+ left: '25px',
+ right: 0,
+ bottom: '60px',
+ },
+ legend: {
+ icon: 'rect',
+ itemWidth: 12,
+ itemHeight: 4,
+ itemGap: 48,
+ textStyle: {
+ fontSize: 12,
+ color: placeholderColor,
+ },
+ left: 'center',
+ bottom: '0',
+ orient: 'horizontal',
+ data: ['本月', '上月'],
+ },
+ series: [
+ {
+ name: '本月',
+ data: outArray,
+ type: 'bar',
+ },
+ {
+ name: '上月',
+ data: inArray,
+ type: 'bar',
+ },
+ ],
+ };
+
+ return dataset;
+}
+
+export function getLineChartDataSet({
+ dateTime = [],
+ placeholderColor,
+ borderColor,
+}: { dateTime?: Array } & Record) {
+ const divideNum = 10;
+ const timeArray = [];
+ const inArray = [];
+ const outArray = [];
+ for (let i = 0; i < divideNum; i++) {
+ if (dateTime.length > 0) {
+ const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum;
+ const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i;
+ timeArray.push(dayjs(enhandTime).format('MM-DD'));
+ } else {
+ timeArray.push(
+ dayjs()
+ .subtract(divideNum - i, 'day')
+ .format('MM-DD'),
+ );
+ }
+ console.log(timeArray);
+ inArray.push(getRandomArray().toString());
+ outArray.push(getRandomArray().toString());
+
+ }
+
+ const dataSet = {
+ color: getChartListColor(),
+ tooltip: {
+ trigger: 'item',
+ },
+ grid: {
+ left: '0',
+ right: '20px',
+ top: '5px',
+ bottom: '36px',
+ containLabel: true,
+ },
+ legend: {
+ left: 'center',
+ bottom: '0',
+ orient: 'horizontal', // legend 横向布局。
+ data: ['本月', '上月'],
+ textStyle: {
+ fontSize: 12,
+ color: placeholderColor,
+ },
+ },
+ xAxis: {
+ type: 'category',
+ data: timeArray,
+ boundaryGap: false,
+ axisLabel: {
+ color: placeholderColor,
+ },
+ axisLine: {
+ lineStyle: {
+ width: 1,
+ },
+ },
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ color: placeholderColor,
+ },
+ splitLine: {
+ lineStyle: {
+ color: borderColor,
+ },
+ },
+ },
+ series: [
+ {
+ name: '本月',
+ data: outArray,
+ type: 'line',
+ smooth: false,
+ showSymbol: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ itemStyle: {
+ normal: {
+ borderColor,
+ borderWidth: 1,
+ },
+ },
+ areaStyle: {
+ normal: {
+ opacity: 0.1,
+ },
+ },
+ },
+ {
+ name: '上月',
+ data: inArray,
+ type: 'line',
+ smooth: false,
+ showSymbol: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ itemStyle: {
+ normal: {
+ borderColor,
+ borderWidth: 1,
+ },
+ },
+ },
+ ],
+ };
+ return dataSet;
+}
+
+/**
+ * 获取表行数据
+ *
+ * @export
+ * @param {string} productName
+ * @param {number} divideNum
+ */
+export function getSelftItemList(productName: string, divideNum: number): string[] {
+ const productArray: string[] = [productName];
+ for (let i = 0; i < divideNum; i++) {
+ productArray.push(getRandomArray(100 * i).toString());
+ }
+
+ return productArray;
+}
+
+/**
+ * 散点图数据
+ *
+ * @export
+ * @returns {any[]}
+ */
+export function getScatterDataSet({
+ dateTime = [],
+ placeholderColor,
+ borderColor,
+}: { dateTime?: Array } & Record): any {
+ const divideNum = 40;
+ const timeArray = [];
+ const inArray = [];
+ const outArray = [];
+ for (let i = 0; i < divideNum; i++) {
+ // const [timeArray, inArray, outArray] = dataset;
+ if (dateTime.length > 0) {
+ const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum;
+ const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i;
+ timeArray.push(dayjs(enhandTime).format('MM-DD'));
+ } else {
+ timeArray.push(
+ dayjs()
+ .subtract(divideNum - i, 'day')
+ .format('MM-DD'),
+ );
+ }
+
+ inArray.push(getRandomArray().toString());
+ outArray.push(getRandomArray().toString());
+ }
+
+ return {
+ color: getChartListColor(),
+ xAxis: {
+ data: timeArray,
+ axisLabel: {
+ color: placeholderColor,
+ },
+ splitLine: { show: false },
+ axisLine: {
+ lineStyle: {
+ color: borderColor,
+ width: 1,
+ },
+ },
+ },
+ yAxis: {
+ type: 'value',
+ // splitLine: { show: false},
+ axisLabel: {
+ color: placeholderColor,
+ },
+ nameTextStyle: {
+ padding: [0, 0, 0, 60],
+ },
+ axisTick: {
+ show: false,
+ axisLine: {
+ show: false,
+ },
+ },
+ axisLine: {
+ show: false,
+ },
+ splitLine: {
+ lineStyle: {
+ color: borderColor,
+ },
+ },
+ },
+ tooltip: {
+ trigger: 'item',
+ },
+ grid: {
+ top: '5px',
+ left: '25px',
+ right: '5px',
+ bottom: '60px',
+ },
+ legend: {
+ left: 'center',
+ bottom: '0',
+ orient: 'horizontal', // legend 横向布局。
+ data: ['按摩仪', '咖啡机'],
+ itemHeight: 8,
+ itemWidth: 8,
+ textStyle: {
+ fontSize: 12,
+ color: placeholderColor,
+ },
+ },
+ series: [
+ {
+ name: '按摩仪',
+ symbolSize: 10,
+ data: outArray.reverse(),
+ type: 'scatter',
+ },
+ {
+ name: '咖啡机',
+ symbolSize: 10,
+ data: inArray.concat(inArray.reverse()),
+ type: 'scatter',
+ },
+ ],
+ };
+}
+
+/**
+ * 获域图数据结构
+ *
+ * @export
+ * @returns {any[]}
+ */
+export function getAreaChartDataSet(): any {
+ const xAxisData = [];
+ const data1 = [];
+ const data2 = [];
+ for (let i = 0; i < 50; i++) {
+ xAxisData.push(`${i}`);
+ data1.push((getRandomArray() * Math.sin(i / 5) * (i / 5 - 5) + i / 6) * 2);
+ data2.push((getRandomArray() * Math.cos(i / 5) * (i / 5 - 5) + i / 6) * 2);
+ }
+
+ return {
+ color: getChartListColor(),
+ // title: {
+ // text: '柱状图动画延迟',
+ // },
+ legend: {
+ left: 'center',
+ bottom: '5%',
+ orient: 'horizontal',
+ data: ['测试', '上线'],
+ },
+ tooltip: {
+ trigger: 'item',
+ },
+ xAxis: {
+ data: xAxisData,
+ splitLine: {
+ show: false,
+ },
+ },
+ yAxis: {},
+ series: [
+ {
+ name: '测试',
+ type: 'bar',
+ data: data1,
+ emphasis: {
+ focus: 'series',
+ },
+ animationDelay(idx: number) {
+ return idx * 10;
+ },
+ },
+ {
+ name: '上线',
+ type: 'bar',
+ data: data2,
+ emphasis: {
+ focus: 'series',
+ },
+ animationDelay(idx: number) {
+ return idx * 10 + 100;
+ },
+ },
+ ],
+ animationEasing: 'elasticOut',
+ animationDelayUpdate(idx: number) {
+ return idx * 5;
+ },
+ };
+}
+
+/**
+ * 柱状图数据结构
+ *
+ * @export
+ * @param {boolean} [isMonth=false]
+ * @returns {*}
+ */
+export function getColumnChartDataSet(isMonth = false) {
+ if (isMonth) {
+ return {
+ color: getChartListColor(),
+ legend: {
+ left: 'center',
+ top: '10%',
+ orient: 'horizontal', // legend 横向布局。
+ data: ['直接访问'],
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ // 坐标轴指示器,坐标轴触发有效
+ type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
+ },
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ data: ['1', '4', '8', '12', '16', '20', '24'],
+ axisTick: {
+ alignWithLabel: true,
+ },
+ },
+ ],
+ yAxis: [
+ {
+ type: 'value',
+ },
+ ],
+ series: [
+ {
+ name: '直接访问',
+ type: 'bar',
+ barWidth: '60%',
+ data: [
+ getRandomArray(Math.random() * 100),
+ getRandomArray(Math.random() * 200),
+ getRandomArray(Math.random() * 300),
+ getRandomArray(Math.random() * 400),
+ getRandomArray(Math.random() * 500),
+ getRandomArray(Math.random() * 600),
+ getRandomArray(Math.random() * 700),
+ ],
+ },
+ ],
+ };
+ }
+
+ return {
+ color: getChartListColor(),
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ // 坐标轴指示器,坐标轴触发有效
+ type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
+ },
+ },
+ legend: {
+ left: 'center',
+ bottom: '0%',
+ orient: 'horizontal', // legend 横向布局。
+ data: ['直接访问'],
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '13%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
+ axisTick: {
+ alignWithLabel: true,
+ },
+ },
+ ],
+ yAxis: [
+ {
+ type: 'value',
+ },
+ ],
+ series: [
+ {
+ name: '直接访问',
+ type: 'bar',
+ barWidth: '20%',
+ data: [
+ getRandomArray(Math.random() * 100),
+ getRandomArray(Math.random() * 200),
+ getRandomArray(Math.random() * 300),
+ getRandomArray(Math.random() * 400),
+ getRandomArray(Math.random() * 500),
+ getRandomArray(Math.random() * 600),
+ getRandomArray(Math.random() * 700),
+ ],
+ },
+ ],
+ };
+}
+
+export function getPieChartDataSet({
+ radius = 42,
+ textColor,
+ placeholderColor,
+ containerColor,
+}: { radius: number } & Record) {
+ return {
+ color: getChartListColor(),
+ tooltip: {
+ show: false,
+ trigger: 'axis',
+ position: null,
+ },
+ grid: {
+ top: '0',
+ right: '0',
+ },
+ legend: {
+ selectedMode: false,
+ itemWidth: 12,
+ itemHeight: 4,
+ textStyle: {
+ fontSize: 12,
+ color: placeholderColor,
+ },
+ left: 'center',
+ bottom: '0',
+ orient: 'horizontal', // legend 横向布局。
+ },
+ series: [
+ {
+ name: '观看渠道',
+ type: 'pie',
+ radius: ['48%', '60%'],
+ avoidLabelOverlap: true,
+ selectedMode: true,
+ hoverAnimation: true,
+ silent: true,
+ itemStyle: {
+ borderColor: containerColor,
+ borderWidth: 1,
+ },
+ label: {
+ show: true,
+ position: 'center',
+ formatter: ['{value|{d}%}', '{name|{b}渠道占比}'].join('\n'),
+ rich: {
+ value: {
+ color: textColor,
+ fontSize: 28,
+ fontWeight: 'normal',
+ lineHeight: 46,
+ },
+ name: {
+ color: '#909399',
+ fontSize: 12,
+ lineHeight: 14,
+ },
+ },
+ },
+ emphasis: {
+ label: {
+ show: true,
+ formatter: ['{value|{d}%}', '{name|{b}渠道占比}'].join('\n'),
+ rich: {
+ value: {
+ color: textColor,
+ fontSize: 28,
+ fontWeight: 'normal',
+ lineHeight: 46,
+ },
+ name: {
+ color: '#909399',
+ fontSize: 14,
+ lineHeight: 14,
+ },
+ },
+ },
+ },
+ labelLine: {
+ show: false,
+ },
+ data: [
+ {
+ value: 1048,
+ name: '线上',
+ },
+ { value: radius * 7, name: '门店' },
+ ],
+ },
+ ],
+ };
+}
diff --git a/src/pages/dashboard/base/index.vue b/src/pages/dashboard/base/index.vue
new file mode 100644
index 0000000..6c20ef4
--- /dev/null
+++ b/src/pages/dashboard/base/index.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/dashboard/detail/index.ts b/src/pages/dashboard/detail/index.ts
new file mode 100644
index 0000000..c8efbe1
--- /dev/null
+++ b/src/pages/dashboard/detail/index.ts
@@ -0,0 +1,267 @@
+import dayjs from 'dayjs';
+import { getChartListColor } from '@/utils/color';
+import { getDateArray, getRandomArray } from '@/utils/charts';
+
+/**
+ * 散点图数据
+ *
+ * @export
+ * @returns {any[]}
+ */
+export function getScatterDataSet({
+ dateTime = [],
+ placeholderColor,
+ borderColor,
+}: { dateTime?: Array } & Record): any {
+ const divideNum = 40;
+ const timeArray = [];
+ const inArray = [];
+ const outArray = [];
+ for (let i = 0; i < divideNum; i++) {
+ // const [timeArray, inArray, outArray] = dataset;
+ if (dateTime.length > 0) {
+ const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum;
+ const endTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i;
+ timeArray.push(dayjs(endTime).format('MM-DD'));
+ } else {
+ timeArray.push(
+ dayjs()
+ .subtract(divideNum - i, 'day')
+ .format('MM-DD'),
+ );
+ }
+
+ inArray.push(getRandomArray().toString());
+ outArray.push(getRandomArray().toString());
+ }
+
+ return {
+ color: getChartListColor(),
+ xAxis: {
+ data: timeArray,
+ axisLabel: {
+ color: placeholderColor,
+ },
+ splitLine: { show: false },
+ axisLine: {
+ lineStyle: {
+ color: borderColor,
+ width: 1,
+ },
+ },
+ },
+ yAxis: {
+ type: 'value',
+ // splitLine: { show: false},
+ axisLabel: {
+ color: placeholderColor,
+ },
+ nameTextStyle: {
+ padding: [0, 0, 0, 60],
+ },
+ axisTick: {
+ show: false,
+ axisLine: {
+ show: false,
+ },
+ },
+ axisLine: {
+ show: false,
+ },
+ splitLine: {
+ lineStyle: {
+ color: borderColor,
+ },
+ },
+ },
+ tooltip: {
+ trigger: 'item',
+ },
+ grid: {
+ top: '5px',
+ left: '25px',
+ right: '5px',
+ bottom: '60px',
+ },
+ legend: {
+ left: 'center',
+ bottom: '0',
+ orient: 'horizontal', // legend 横向布局。
+ data: ['按摩仪', '咖啡机'],
+ itemHeight: 8,
+ itemWidth: 8,
+ textStyle: {
+ fontSize: 12,
+ color: placeholderColor,
+ },
+ },
+ series: [
+ {
+ name: '按摩仪',
+ symbolSize: 10,
+ data: outArray.reverse(),
+ type: 'scatter',
+ },
+ {
+ name: '咖啡机',
+ symbolSize: 10,
+ data: inArray.concat(inArray.reverse()),
+ type: 'scatter',
+ },
+ ],
+ };
+}
+
+/** 折线图数据 */
+export function getFolderLineDataSet({
+ dateTime = [],
+ placeholderColor,
+ borderColor,
+}: { dateTime?: Array } & Record) {
+ let dateArray: Array = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
+ if (dateTime.length > 0) {
+ const divideNum = 7;
+ dateArray = getDateArray(dateTime, divideNum);
+ }
+ return {
+ color: getChartListColor(),
+ grid: {
+ top: '5%',
+ right: '10px',
+ left: '30px',
+ bottom: '60px',
+ },
+ legend: {
+ left: 'center',
+ bottom: '0',
+ orient: 'horizontal', // legend 横向布局。
+ data: ['杯子', '茶叶', '蜂蜜', '面粉'],
+ textStyle: {
+ fontSize: 12,
+ color: placeholderColor,
+ },
+ },
+ xAxis: {
+ type: 'category',
+ data: dateArray,
+ boundaryGap: false,
+ axisLabel: {
+ color: placeholderColor,
+ },
+ axisLine: {
+ lineStyle: {
+ color: borderColor,
+ width: 1,
+ },
+ },
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ color: placeholderColor,
+ },
+ splitLine: {
+ lineStyle: {
+ color: borderColor,
+ },
+ },
+ },
+ tooltip: {
+ trigger: 'item',
+ },
+ series: [
+ {
+ showSymbol: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ name: '杯子',
+ stack: '总量',
+ data: [
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ ],
+ type: 'line',
+ itemStyle: {
+ normal: {
+ borderColor,
+ borderWidth: 1,
+ },
+ },
+ },
+ {
+ showSymbol: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ name: '茶叶',
+ stack: '总量',
+ data: [
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ ],
+ type: 'line',
+ itemStyle: {
+ normal: {
+ borderColor,
+ borderWidth: 1,
+ },
+ },
+ },
+ {
+ showSymbol: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ name: '蜂蜜',
+ stack: '总量',
+ data: [
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ ],
+ type: 'line',
+ itemStyle: {
+ normal: {
+ borderColor,
+ borderWidth: 1,
+ },
+ },
+ },
+ {
+ showSymbol: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ name: '面粉',
+ stack: '总量',
+ data: [
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ getRandomArray(),
+ ],
+ type: 'line',
+ itemStyle: {
+ normal: {
+ borderColor,
+ borderWidth: 1,
+ },
+ },
+ },
+ ],
+ };
+}
diff --git a/src/pages/dashboard/detail/index.vue b/src/pages/dashboard/detail/index.vue
new file mode 100644
index 0000000..8719a1b
--- /dev/null
+++ b/src/pages/dashboard/detail/index.vue
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+ {{ item.number }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 导出数据
+
+
+
+
+
+
+
diff --git a/src/pages/login/index.less b/src/pages/login/index.less
new file mode 100644
index 0000000..13d38ec
--- /dev/null
+++ b/src/pages/login/index.less
@@ -0,0 +1,202 @@
+@import '@/style/variables.less';
+
+.light {
+ &.login-wrapper {
+ background-color: white;
+ background-image: url('@/assets/assets-login-bg-white.png');
+ }
+}
+
+.dark {
+ &.login-wrapper {
+ background-color: var(--td-bg-color-page);
+ background-image: url('@/assets/assets-login-bg-black.png');
+ }
+}
+
+.login-wrapper {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background-size: cover;
+ background-position: 100%;
+ position: relative;
+}
+
+.login-container {
+ position: absolute;
+ top: 22%;
+ left: 5%;
+ min-height: 500px;
+ line-height: 22px;
+}
+
+.title-container {
+ .title {
+ font-size: 36px;
+ line-height: 44px;
+ color: var(--td-text-color-primary);
+ margin-top: 4px;
+
+ &.margin-no {
+ margin-top: 0;
+ }
+ }
+
+ .sub-title {
+ margin-top: 16px;
+
+ .tip {
+ display: inline-block;
+ margin-right: 8px;
+ font-size: 14px;
+
+ &:first-child {
+ color: var(--td-text-color-secondary);
+ }
+
+ &:last-child {
+ color: var(--td-text-color-primary);
+ cursor: pointer;
+ }
+ }
+ }
+}
+
+.item-container {
+ width: 400px;
+ margin-top: 48px;
+
+ &.login-qrcode {
+ .tip-container {
+ width: 192px;
+ margin-bottom: 16px;
+ font-size: 14px;
+ display: flex;
+ justify-content: space-between;
+
+ .tip {
+ color: var(--td-text-color-primary);
+ }
+
+ .refresh {
+ display: flex;
+ align-items: center;
+ color: var(--td-brand-color);
+
+ .t-icon {
+ font-size: 14px;
+ }
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .bottom-container {
+ margin-top: 32px;
+ }
+ }
+
+ &.login-phone {
+ .bottom-container {
+ margin-top: 66px;
+ }
+ }
+
+ .check-container {
+ display: flex;
+ align-items: center;
+
+ &.remember-pwd {
+ margin-bottom: 16px;
+ justify-content: space-between;
+ }
+
+ .t-checkbox__label {
+ color: var(--td-text-color-secondary);
+ }
+
+ span {
+ color: var(--td-brand-color);
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .verification-code {
+ display: flex;
+ align-items: center;
+
+ .t-form__controls {
+ width: 100%;
+
+ button {
+ flex-shrink: 0;
+ width: 102px;
+ height: 40px;
+ margin-left: 11px;
+ }
+ }
+ }
+
+ .btn-container {
+ margin-top: 48px;
+ }
+}
+
+.switch-container {
+ margin-top: 24px;
+
+ .tip {
+ font-size: 14px;
+ color: var(--td-brand-color);
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ margin-right: 14px;
+
+ &:last-child {
+ &::after {
+ display: none;
+ }
+ }
+
+ &::after {
+ content: '';
+ display: block;
+ width: 1px;
+ height: 12px;
+ background: var(--td-gray-color-3);
+ margin-left: 14px;
+ }
+ }
+}
+
+.check-container {
+ font-size: 14px;
+ color: var(--td-text-color-secondary);
+
+ .tip {
+ float: right;
+ font-size: 14px;
+ color: var(--td-brand-color);
+ }
+}
+
+.copyright {
+ font-size: 14px;
+ position: absolute;
+ left: 5%;
+ bottom: var(--td-comp-size-xxxl);
+ color: var(--td-text-color-secondary);
+}
+
+@media screen and (max-height: 700px) {
+ .copyright {
+ display: none;
+ }
+}
diff --git a/src/pages/login/index.vue b/src/pages/login/index.vue
new file mode 100644
index 0000000..3b174db
--- /dev/null
+++ b/src/pages/login/index.vue
@@ -0,0 +1,186 @@
+
+
+
+
+
登录到
+ 河南省青年企业家协会管理系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
Copyright @ 2021-2022 LingRui. All Rights Reserved
+
+
+
+
diff --git a/src/pages/news/news_index.vue b/src/pages/news/news_index.vue
new file mode 100644
index 0000000..d4bb065
--- /dev/null
+++ b/src/pages/news/news_index.vue
@@ -0,0 +1,393 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ onCreated(e)"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/news/news_type.vue b/src/pages/news/news_type.vue
new file mode 100644
index 0000000..0f0c729
--- /dev/null
+++ b/src/pages/news/news_type.vue
@@ -0,0 +1,136 @@
+
+
+
+ 新增
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/register/index.less b/src/pages/register/index.less
new file mode 100644
index 0000000..13d38ec
--- /dev/null
+++ b/src/pages/register/index.less
@@ -0,0 +1,202 @@
+@import '@/style/variables.less';
+
+.light {
+ &.login-wrapper {
+ background-color: white;
+ background-image: url('@/assets/assets-login-bg-white.png');
+ }
+}
+
+.dark {
+ &.login-wrapper {
+ background-color: var(--td-bg-color-page);
+ background-image: url('@/assets/assets-login-bg-black.png');
+ }
+}
+
+.login-wrapper {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background-size: cover;
+ background-position: 100%;
+ position: relative;
+}
+
+.login-container {
+ position: absolute;
+ top: 22%;
+ left: 5%;
+ min-height: 500px;
+ line-height: 22px;
+}
+
+.title-container {
+ .title {
+ font-size: 36px;
+ line-height: 44px;
+ color: var(--td-text-color-primary);
+ margin-top: 4px;
+
+ &.margin-no {
+ margin-top: 0;
+ }
+ }
+
+ .sub-title {
+ margin-top: 16px;
+
+ .tip {
+ display: inline-block;
+ margin-right: 8px;
+ font-size: 14px;
+
+ &:first-child {
+ color: var(--td-text-color-secondary);
+ }
+
+ &:last-child {
+ color: var(--td-text-color-primary);
+ cursor: pointer;
+ }
+ }
+ }
+}
+
+.item-container {
+ width: 400px;
+ margin-top: 48px;
+
+ &.login-qrcode {
+ .tip-container {
+ width: 192px;
+ margin-bottom: 16px;
+ font-size: 14px;
+ display: flex;
+ justify-content: space-between;
+
+ .tip {
+ color: var(--td-text-color-primary);
+ }
+
+ .refresh {
+ display: flex;
+ align-items: center;
+ color: var(--td-brand-color);
+
+ .t-icon {
+ font-size: 14px;
+ }
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .bottom-container {
+ margin-top: 32px;
+ }
+ }
+
+ &.login-phone {
+ .bottom-container {
+ margin-top: 66px;
+ }
+ }
+
+ .check-container {
+ display: flex;
+ align-items: center;
+
+ &.remember-pwd {
+ margin-bottom: 16px;
+ justify-content: space-between;
+ }
+
+ .t-checkbox__label {
+ color: var(--td-text-color-secondary);
+ }
+
+ span {
+ color: var(--td-brand-color);
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .verification-code {
+ display: flex;
+ align-items: center;
+
+ .t-form__controls {
+ width: 100%;
+
+ button {
+ flex-shrink: 0;
+ width: 102px;
+ height: 40px;
+ margin-left: 11px;
+ }
+ }
+ }
+
+ .btn-container {
+ margin-top: 48px;
+ }
+}
+
+.switch-container {
+ margin-top: 24px;
+
+ .tip {
+ font-size: 14px;
+ color: var(--td-brand-color);
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ margin-right: 14px;
+
+ &:last-child {
+ &::after {
+ display: none;
+ }
+ }
+
+ &::after {
+ content: '';
+ display: block;
+ width: 1px;
+ height: 12px;
+ background: var(--td-gray-color-3);
+ margin-left: 14px;
+ }
+ }
+}
+
+.check-container {
+ font-size: 14px;
+ color: var(--td-text-color-secondary);
+
+ .tip {
+ float: right;
+ font-size: 14px;
+ color: var(--td-brand-color);
+ }
+}
+
+.copyright {
+ font-size: 14px;
+ position: absolute;
+ left: 5%;
+ bottom: var(--td-comp-size-xxxl);
+ color: var(--td-text-color-secondary);
+}
+
+@media screen and (max-height: 700px) {
+ .copyright {
+ display: none;
+ }
+}
diff --git a/src/pages/register/index.vue b/src/pages/register/index.vue
new file mode 100644
index 0000000..8b84ce4
--- /dev/null
+++ b/src/pages/register/index.vue
@@ -0,0 +1,721 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 同意安装协议
+
+
+ 下一步
+
+
+
+
+
+
+
登陆信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 下一步
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 上一步
+ 提交申请
+
+
+
+
+
+
+
+
+
+
申请已提交
+
登陆小程序可查看审核结果
+
+ this.$router.push('/login?id='+id)">返回首页
+
+
+
+
+
+
diff --git a/src/pages/user/user_add.vue b/src/pages/user/user_add.vue
new file mode 100644
index 0000000..2f20b9d
--- /dev/null
+++ b/src/pages/user/user_add.vue
@@ -0,0 +1,755 @@
+
+
+
+
+
登陆信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
人员信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
点击上传图片
+
+
请选择身份证正面照
+
+
+
+
+
+
+
+
+
+
+
+
企业信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_edit.vue b/src/pages/user/user_edit.vue
new file mode 100644
index 0000000..9f63d0a
--- /dev/null
+++ b/src/pages/user/user_edit.vue
@@ -0,0 +1,844 @@
+
+
+
+
+
登陆信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
人员信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
点击上传图片
+
+
请选择身份证正面照
+
+
+
+
+
+
+
+
+
+
+
+
企业信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交修改
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_edit_shen.vue b/src/pages/user/user_edit_shen.vue
new file mode 100644
index 0000000..2b1af59
--- /dev/null
+++ b/src/pages/user/user_edit_shen.vue
@@ -0,0 +1,306 @@
+
+
+
+
+
+
+
+
+ 类别
+
+
+ 原信息
+
+
+
+
+ 新信息
+
+
+
+
+
+ 名片背景图:
+ 形象照:
+ 协会职务:
+ 姓名:
+ 性别:
+ 联系方式:
+ 个人经历:
+ 公司图标:
+ 公司名称:
+ 公司行业:
+ 公司地址:
+ 公司介绍:
+
+
+
+
+
+
+
+ 无
+
+
+
+ {{ updateInfo.member.position_name }}
+ {{ updateInfo.member.nikename }}
+ {{ updateInfo.member.gender_name }}
+ {{ updateInfo.member.phone }}
+ {{ updateInfo.member.introduction }}
+
+
+
+ 无
+
+
+ {{ updateInfo.member.enterprise_name }}
+ {{updateInfo.member.industry_id==-1?'其他行业':updateInfo.member.industry_name }}
+ {{ updateInfo.member.enterprise_location==''?'无':updateInfo.member.enterprise_location }}
+ {{ updateInfo.member.enterprise_Introduction }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ updateInfo.member_log.position_name }}
+ {{ updateInfo.member_log.nikename }}
+ {{ updateInfo.member_log.gender_name }}
+ {{ updateInfo.member_log.phone }}
+ {{ updateInfo.member_log.introduction }}
+
+
+
+ 无
+
+
+ {{ updateInfo.member_log.enterprise_name }}
+ {{updateInfo.member_log.industry_id==-1?'其他行业':updateInfo.member_log.industry_name }}
+ {{ updateInfo.member_log.enterprise_location }}
+ {{ updateInfo.member_log.enterprise_Introduction }}
+
+
+
+
+
+
+ 审核通过
+
+
+
+ 拒绝理由
+
+
+
+
+ 审核拒绝
+
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_index.vue b/src/pages/user/user_index.vue
new file mode 100644
index 0000000..7772991
--- /dev/null
+++ b/src/pages/user/user_index.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_info.vue b/src/pages/user/user_info.vue
new file mode 100644
index 0000000..b56c941
--- /dev/null
+++ b/src/pages/user/user_info.vue
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{info.gender==1?"男":"女"}}
+
+
+
+
+
+
+
+
+
+
+
+ {{info.introduction}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{info.if_list==1?"否":"是"}}
+
+
+
+
+
+
+
+
+
+ {{info.enterprise_Introduction}}
+
+
+
+
+
+
+
+
+ {{info.if_organization==1?"否":"是"}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 拒绝
+
+
+ 通过审核
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_invoice.vue b/src/pages/user/user_invoice.vue
new file mode 100644
index 0000000..206bde7
--- /dev/null
+++ b/src/pages/user/user_invoice.vue
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ info.header.name }}
+ {{ info.header.unit }}
+ {{ info.header.taxpayer_identification_number }}
+
+ {{ info.header.unit_address }}
+ {{ info.header.telephone }}
+ {{ info.header.bank_basic_account_number }}
+ {{ info.header.bank }}
+ {{ info.invoice_type==1?'普票':'专票' }}
+ {{ info.money }} 元
+
+
+
+ 上传发票
+
+
+
+
+
+ 通过
+
+
+
+ 请说明拒绝原因
+
+
+
+
+ 拒绝
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_line.vue b/src/pages/user/user_line.vue
new file mode 100644
index 0000000..eacaf14
--- /dev/null
+++ b/src/pages/user/user_line.vue
@@ -0,0 +1,136 @@
+
+
+
+ 新增
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_plan.vue b/src/pages/user/user_plan.vue
new file mode 100644
index 0000000..ea97eca
--- /dev/null
+++ b/src/pages/user/user_plan.vue
@@ -0,0 +1,156 @@
+
+
+
+ 新增
+
+
+ 理事会
+ 监事会
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/user/user_region.vue b/src/pages/user/user_region.vue
new file mode 100644
index 0000000..bfea732
--- /dev/null
+++ b/src/pages/user/user_region.vue
@@ -0,0 +1,128 @@
+
+
+
+ 新增
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/permission.js b/src/permission.js
new file mode 100644
index 0000000..bbd4c70
--- /dev/null
+++ b/src/permission.js
@@ -0,0 +1,57 @@
+import NProgress from 'nprogress'; // progress bar
+import 'nprogress/nprogress.css'; // progress bar style
+
+import store from '@/store';
+import router from '@/router';
+const whiteListRouters = store.getters['permission/whiteListRouters'];
+NProgress.configure({ showSpinner: false });
+router.beforeEach(async (to, from, next) => {
+ NProgress.start();
+ document.title = '智慧云商协-'+to.meta.title;
+ const token = localStorage.getItem('associationToken');
+if(store.state.user.association!=''){
+ if(typeof (store.state.user.association)=='object'){
+ var association=store.state.user.association;
+ }else{
+ var association=JSON.parse(store.state.user.association);
+ }
+}
+ if (token) {
+ if (to.path === '/login') {
+ next('/dashboard/base');
+ return;
+ }
+ await store.dispatch('user/getUserInfo');
+ await store.dispatch('permission/initRoutes', store.getters['user/roles']);
+ const roles = store.getters['user/roles'];
+ if (roles && roles.length > 0) {
+ if(roles[0]==='ALL_ROUTERS'){
+ next();
+ }else{
+ if (roles.indexOf(to.name) !== -1) {
+ next();
+ } else {
+ next('/dashboard/base');
+ }
+ }
+ } else {
+ try {
+ next({ ...to , replace: true });
+ } catch (error) {
+ await store.commit('user/removeToken');
+ next(`/login`);
+ }
+ }
+ } else {
+ if (whiteListRouters.indexOf(to.path) !== -1) {
+ next();
+ } else {
+ next(`/login`);
+ }
+ NProgress.done();
+ }
+});
+
+router.afterEach(() => {
+ NProgress.done();
+});
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..b52e50d
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,50 @@
+import VueRouter from 'vue-router';
+
+import baseRouters from './modules/base';
+import componentsRouters from './modules/components';
+const env = import.meta.env.MODE || 'development';
+
+// 存放动态路由
+export const asyncRouterList = [...baseRouters, ...componentsRouters];
+
+// 存放固定的路由
+const defaultRouterList = [
+ {
+ path: '/login',
+ name: 'login',
+ meta: {
+ title: '登录',
+ },
+ component: () => import('@/pages/login/index.vue'),
+ },
+ {
+ path: '/register',
+ name: 'register',
+ meta: {title: '会员注册'},
+ component: () => import('@/pages/register/index.vue'),
+ },
+ {
+ path: '*',
+ redirect: '/dashboard/base',
+ },
+ ...asyncRouterList,
+];
+
+const createRouter = () =>
+ new VueRouter({
+ mode: 'hash',
+ base: env === 'site' ? '/starter/vue/' : null,
+ routes: defaultRouterList,
+ scrollBehavior() {
+ return { x: 0, y: 0 };
+ },
+ });
+
+const router = createRouter();
+
+export function resetRouter() {
+ const newRouter = createRouter();
+ router.matcher = newRouter.matcher; // reset router
+}
+
+export default router;
diff --git a/src/router/modules/base.ts b/src/router/modules/base.ts
new file mode 100644
index 0000000..2ea9684
--- /dev/null
+++ b/src/router/modules/base.ts
@@ -0,0 +1,23 @@
+import { DashboardIcon } from 'tdesign-icons-vue';
+import Layout from '@/layouts/index.vue';
+
+export default [
+ {
+ path: '/dashboard',
+ component: Layout,
+ redirect: '/dashboard/base',
+ name: 'dashboard',
+ meta: {
+ title: '首页',
+ icon: DashboardIcon,
+ },
+ children: [
+ {
+ path: 'base',
+ name: 'DashboardBase',
+ component: () => import('@/pages/dashboard/base/index.vue'),
+ meta: { title: '数据大屏' },
+ }
+ ],
+ },
+];
diff --git a/src/router/modules/components.ts b/src/router/modules/components.ts
new file mode 100644
index 0000000..23e1113
--- /dev/null
+++ b/src/router/modules/components.ts
@@ -0,0 +1,150 @@
+import {ViewModuleIcon, UsergroupIcon, ViewListIcon, ChartBubbleIcon, HomeIcon, HelpIcon} from 'tdesign-icons-vue';
+
+import Layout from '@/layouts/index.vue';
+
+export default [
+ {
+ path: '/user',
+ name: 'user',
+ component: Layout,
+ redirect: '/user/user_index',
+ meta: {title: '会员管理', icon: UsergroupIcon},
+ children: [
+ {
+ path: 'user_index',
+ name: 'userIndex',
+ component: () => import('@/pages/user/user_index.vue'),
+ meta: {title: '会员列表'},
+ },
+ {
+ path: 'plan',
+ name: 'userPlan',
+ component: () => import('@/pages/user/user_plan.vue'),
+ meta: {title: '职位管理'},
+ },
+ {
+ path: 'line',
+ name: 'userLine',
+ component: () => import('@/pages/user/user_line.vue'),
+ meta: {title: '行业管理'},
+ },
+ {
+ path: 'region',
+ name: 'userRegion',
+ component: () => import('@/pages/user/user_region.vue'),
+ meta: {title: '区域管理'},
+ },
+ {
+ path: 'user_info',
+ name: 'userInfo',
+ component: () => import('@/pages/user/user_info.vue'),
+ meta: {title: '会员详情', hidden: true},
+ },
+ {
+ path: 'user_edit',
+ name: 'userEdit',
+ component: () => import('@/pages/user/user_edit.vue'),
+ meta: {title: '会员编辑', hidden: true},
+ },
+ {
+ path: 'user_add',
+ name: 'userAdd',
+ component: () => import('@/pages/user/user_add.vue'),
+ meta: {title: '新增会员', hidden: true},
+ },
+ {
+ path: 'user_invoice',
+ name: 'userInvoice',
+ component: () => import('@/pages/user/user_invoice.vue'),
+ meta: {title: '会员发票管理'},
+ },
+ {
+ path: 'user_edit_shen',
+ name: 'userEditShen',
+ component: () => import('@/pages/user/user_edit_shen.vue'),
+ meta: {title: '编辑信息审核'},
+ },
+ ],
+ },
+ {
+ path: '/activity',
+ name: 'activity',
+ component: Layout,
+ redirect: '/activity/index',
+ meta: {title: '活动管理', icon: ChartBubbleIcon},
+ children: [
+ {
+ path: 'activity_index',
+ name: 'activityIndex',
+ component: () => import('@/pages/activity/activity_index.vue'),
+ meta: {title: '活动列表'},
+ },
+ {
+ path: 'activity_top',
+ name: 'activityTop',
+ component: () => import('@/pages/activity/activity_top.vue'),
+ meta: {title: '活动首页置顶'},
+ }
+ ],
+ },
+ {
+ path: '/news',
+ name: 'news',
+ component: Layout,
+ redirect: '/news/news_index',
+ meta: {title: '新闻文章', icon: ViewListIcon},
+ children: [
+ {
+ path: 'news_index',
+ name: 'newsIndex',
+ component: () => import('@/pages/news/news_index.vue'),
+ meta: {title: '新闻内容管理'},
+ },
+ {
+ path: 'news_type',
+ name: 'newsType',
+ component: () => import('@/pages/news/news_type.vue'),
+ meta: {title: '新闻类目管理'},
+ }
+ ],
+ }, {
+ path: '/association',
+ name: 'association',
+ component: Layout,
+ redirect: '/association/index',
+ meta: {title: '协会管理', icon: HomeIcon},
+ children: [
+ {
+ path: 'person ',
+ name: 'associationPerson',
+ component: () => import('@/pages/association/person.vue'),
+ meta: {title: '管理员'},
+ },
+ {
+ path: 'carousel ',
+ name: 'associationCarousel',
+ component: () => import('@/pages/association/carousel.vue'),
+ meta: {title: '轮播图'},
+ },
+ {
+ path: 'opinion',
+ name: 'associationOpinion',
+ component: () => import('@/pages/association/opinion.vue'),
+ meta: {title: '意见反馈'},
+ },
+ {
+ path: 'index',
+ name: 'associationIndex',
+ component: () => import('@/pages/association/index.vue'),
+ meta: {title: '关于我们'},
+ },
+ {
+ path: 'system',
+ name: 'systemIndex',
+ component: () => import('@/pages/association/system.vue'),
+ meta: {title: '系统设置'},
+ }
+ ],
+ }
+
+];
diff --git a/src/service/service-advance.ts b/src/service/service-advance.ts
new file mode 100644
index 0000000..de45eda
--- /dev/null
+++ b/src/service/service-advance.ts
@@ -0,0 +1,233 @@
+type AdvancedColumn = {
+ name: string;
+ value: string;
+ type?: any;
+};
+type TableItem = {
+ width?: string | number;
+ ellipsis?: any;
+ colKey: string;
+ title: string;
+ sorter?: any;
+ align?: string;
+ fixed?: string;
+ className?: string;
+};
+class DetailBase {
+ /**
+ * 下拉框选项数据
+ *
+ * @returns
+ *
+ * @memberOf DetailBase
+ */
+ getBaseInfoData(): Array {
+ return [
+ {
+ name: '合同名称',
+ value: '总部办公用品采购项目',
+ },
+ {
+ name: '合同状态',
+ value: '履行中',
+ type: {
+ key: 'contractStatus',
+ value: 'inProgress',
+ },
+ },
+ {
+ name: '合同编号',
+ value: 'BH00010',
+ },
+ {
+ name: '合同类型',
+ value: '主合同',
+ },
+ {
+ name: '合同收付类型',
+ value: '付款',
+ },
+ {
+ name: '合同金额',
+ value: '5,000,000元',
+ },
+ {
+ name: '甲方',
+ value: '腾讯科技(深圳)有限公司',
+ },
+ {
+ name: '乙方',
+ value: '欧尚',
+ },
+ {
+ name: '合同签订日期',
+ value: '2020-12-20',
+ },
+ {
+ name: '合同生效日期',
+ value: '2021-01-20',
+ },
+ {
+ name: '合同结束日期',
+ value: '2022-12-20',
+ },
+ {
+ name: '合同附件',
+ value: '总部办公用品采购项目合同.pdf',
+ type: {
+ key: 'contractAnnex',
+ value: 'pdf',
+ },
+ },
+ {
+ name: '备注',
+ value: '--',
+ },
+ {
+ name: '创建时间',
+ value: '2020-12-22 10:00:00',
+ },
+ ];
+ }
+
+ /**
+ * 表格定义基础数据
+ *
+ * @returns
+ *
+ * @memberOf DetailBase
+ */
+ getTableColumns(): Array {
+ return [
+ {
+ width: 300,
+ ellipsis: true,
+ colKey: 'index',
+ title: '申请号',
+ sorter: (a, b) => a.index.substr(3) - b.index.substr(3),
+ },
+ {
+ width: 200,
+ ellipsis: true,
+ colKey: 'pdName',
+ title: '产品名称',
+ sorter: (a, b) => a.pdName.length - b.pdName.length,
+ },
+ {
+ width: 200,
+ ellipsis: true,
+ colKey: 'pdNum',
+ title: '产品编号',
+ },
+ {
+ width: 200,
+ ellipsis: true,
+ colKey: 'purchaseNum',
+ title: '采购数量',
+ sorter: (a, b) => a.purchaseNum - b.purchaseNum,
+ },
+ {
+ width: 200,
+ ellipsis: true,
+ colKey: 'adminName',
+ title: '申请部门',
+ },
+ {
+ width: 200,
+ ellipsis: true,
+ colKey: 'updateTime',
+ title: '创建时间',
+ sorter: (a, b) => Date.parse(a.updateTime) - Date.parse(b.updateTime),
+ },
+ {
+ align: 'left',
+ fixed: 'right',
+ width: 200,
+ className: 'test2',
+ colKey: 'op',
+ title: '操作',
+ },
+ ];
+ }
+
+ /**
+ * 获取弹窗配置数据
+ *
+ * @memberOf DetailBase
+ */
+ getPropUpData(): any {
+ const INITIAL_DATA = {
+ name: '',
+ warning: '',
+ success: '',
+ failB: '',
+ warningB: '',
+ loading: '',
+ add: '',
+ help: '',
+ };
+
+ return {
+ formData: { ...INITIAL_DATA },
+ courseOptions: [
+ { label: '语文', value: '1' },
+ { label: '数学', value: '2' },
+ { label: '英语', value: '3' },
+ ],
+ options: [
+ {
+ label: '资源初始化后',
+ value: 'beijing',
+ },
+ {
+ label: '上海',
+ value: 'shanghai',
+ },
+ ],
+ options1: [
+ {
+ label: '资源初始化后',
+ value: 'guangzhou',
+ },
+ {
+ label: '深圳',
+ value: 'shenzhen',
+ },
+ {
+ label: '东莞',
+ value: 'dongguang',
+ },
+ ],
+ options2: [
+ {
+ label: '资源初始化后',
+ value: 'nanjing',
+ },
+ {
+ label: '苏州',
+ value: '苏州',
+ },
+ {
+ label: '无锡',
+ value: 'wuxi',
+ },
+ ],
+ tSelectOptions: [
+ {
+ label: 'Sanzhang',
+ value: '1',
+ },
+ {
+ label: 'ls',
+ value: '2',
+ },
+ {
+ label: 'James',
+ value: '3',
+ },
+ ],
+ };
+ }
+}
+
+export default new DetailBase();
diff --git a/src/service/service-base.ts b/src/service/service-base.ts
new file mode 100644
index 0000000..6392242
--- /dev/null
+++ b/src/service/service-base.ts
@@ -0,0 +1,205 @@
+import { TdBaseTableProps } from 'tdesign-vue';
+
+interface DashboardPanel {
+ title: string;
+ number: string | number;
+ leftType: string;
+ upTrend?: string;
+ downTrend?: string;
+}
+
+interface TendItem {
+ growUp?: number;
+ productName: string;
+ count: number;
+ date: string;
+}
+
+export const PANE_LIST: Array = [
+ {
+ title: '总浏览量',
+ number: '28,425.00',
+ upTrend: '20.5%',
+ leftType: 'echarts-line',
+ },
+ {
+ title: '本周浏览量',
+ number: '768.00',
+ downTrend: '20.5%',
+ leftType: 'echarts-bar',
+ },
+ {
+ title: '活跃用户(个)',
+ number: '1126',
+ downTrend: '20.5%',
+ leftType: 'icon-usergroup',
+ },
+ {
+ title: '上传文章(个)',
+ number: 527,
+ downTrend: '20.5%',
+ leftType: 'icon-file-paste',
+ },
+];
+
+export const SALE_TEND_LIST: Array = [
+ {
+ growUp: 1,
+ productName: '协会新闻',
+ count: 7059,
+ date: '2024-05-12',
+ },
+ {
+ growUp: -1,
+ productName: '商学院',
+ count: 6437,
+ date: '2024-05-10',
+ },
+ {
+ growUp: 4,
+ productName: '协会动态',
+ count: 4221,
+ date: '2024-05-03',
+ },
+ {
+ growUp: 3,
+ productName: '党群工作',
+ count: 3317,
+ date: '2024-04-28',
+ },
+ {
+ growUp: -3,
+ productName: '通知公告',
+ count: 3015,
+ date: '2024-04-23',
+ },
+ {
+ growUp: -3,
+ productName: '联系我们',
+ count: 2015,
+ date: '2024-03-12',
+ },
+];
+
+export const BUY_TEND_LIST: Array = [
+ {
+ growUp: 1,
+ productName: '线下活动',
+ count: 3015,
+ date: '2024-05-12',
+ },
+ {
+ growUp: -1,
+ productName: '调查问卷',
+ count: 2015,
+ date: '2024-05-10',
+ },
+ {
+ growUp: 6,
+ productName: '公益捐赠',
+ count: 1815,
+ date: '2024-05-03',
+ },
+ {
+ growUp: -3,
+ productName: '学习培训',
+ count: 1015,
+ date: '2024-04-28',
+ },
+ {
+ growUp: -4,
+ productName: '协会活动',
+ count: 445,
+ date: '2024-04-23',
+ },
+ {
+ growUp: -3,
+ productName: '其它内容',
+ count: 2015,
+ date: '2023-03-12',
+ },
+];
+
+export const SALE_COLUMNS: TdBaseTableProps['columns'] = [
+ {
+ align: 'center',
+ colKey: 'index',
+ title: '排名',
+ width: 80,
+ fixed: 'left',
+ },
+ {
+ align: 'left',
+ ellipsis: true,
+ colKey: 'productName',
+ title: '类别',
+ minWidth: 200,
+ },
+ {
+ align: 'center',
+ colKey: 'growUp',
+ width: 100,
+ title: '较上周',
+ },
+ {
+ align: 'center',
+ colKey: 'count',
+ title: '阅读量',
+ width: 100,
+ },
+ {
+ align: 'center',
+ colKey: 'date',
+ width: 140,
+ title: '日期',
+ },
+ {
+ align: 'center',
+ colKey: 'operation',
+ title: '操作',
+ width: 80,
+ fixed: 'right',
+ },
+];
+
+export const BUY_COLUMNS: TdBaseTableProps['columns'] = [
+ {
+ align: 'center',
+ colKey: 'index',
+ title: '排名',
+ width: 80,
+ fixed: 'left',
+ },
+ {
+ align: 'left',
+ ellipsis: true,
+ colKey: 'productName',
+ title: '分类',
+ minWidth: 200,
+ },
+ {
+ align: 'center',
+ colKey: 'growUp',
+ width: 100,
+ title: '较上周',
+ },
+ {
+ align: 'center',
+ colKey: 'count',
+ title: '阅读量',
+ width: 100,
+ },
+ {
+ align: 'center',
+ colKey: 'date',
+ width: 140,
+ title: '日期',
+ },
+ {
+ align: 'center',
+ colKey: 'operation',
+ title: '操作',
+ width: 80,
+ fixed: 'right',
+ },
+];
diff --git a/src/service/service-detail-base.ts b/src/service/service-detail-base.ts
new file mode 100644
index 0000000..df1edec
--- /dev/null
+++ b/src/service/service-detail-base.ts
@@ -0,0 +1,84 @@
+interface IAdvancedColumn {
+ name: string;
+ value: string;
+ type?: any;
+}
+class DetailBase {
+ /**
+ * 下拉框选项数据
+ *
+ * @returns
+ *
+ * @memberOf DetailBase
+ */
+ getBaseInfoData(): Array {
+ return [
+ {
+ name: '合同名称',
+ value: '总部办公用品采购项目',
+ },
+ {
+ name: '合同状态',
+ value: '履行中',
+ type: {
+ key: 'contractStatus',
+ value: 'inProgress',
+ },
+ },
+ {
+ name: '合同编号',
+ value: 'BH00010',
+ },
+ {
+ name: '合同类型',
+ value: '主合同',
+ },
+ {
+ name: '合同收付类型',
+ value: '付款',
+ },
+ {
+ name: '合同金额',
+ value: '5,000,000元',
+ },
+ {
+ name: '甲方',
+ value: '腾讯科技(深圳)有限公司',
+ },
+ {
+ name: '乙方',
+ value: '欧尚',
+ },
+ {
+ name: '合同签订日期',
+ value: '2020-12-20',
+ },
+ {
+ name: '合同生效日期',
+ value: '2021-01-20',
+ },
+ {
+ name: '合同结束日期',
+ value: '2022-12-20',
+ },
+ {
+ name: '合同附件',
+ value: '总部办公用品采购项目合同.pdf',
+ type: {
+ key: 'contractAnnex',
+ value: 'pdf',
+ },
+ },
+ {
+ name: '备注',
+ value: '--',
+ },
+ {
+ name: '创建时间',
+ value: '2020-12-22 10:00:00',
+ },
+ ];
+ }
+}
+
+export default new DetailBase();
diff --git a/src/service/service-detail-deploy.ts b/src/service/service-detail-deploy.ts
new file mode 100644
index 0000000..4b69eef
--- /dev/null
+++ b/src/service/service-detail-deploy.ts
@@ -0,0 +1,234 @@
+class DetailBase {
+ /**
+ * 下拉框选项数据
+ *
+ * @returns
+ *
+ * @memberOf DetailBase
+ */
+ getRadioOpetions() {
+ return [
+ {
+ label: 'Web',
+ value: 'Web',
+ },
+ {
+ label: 'Mobile',
+ value: 'Mobile',
+ },
+ ];
+ }
+
+ /**
+ * 弹窗数据
+ *
+ * @returns
+ *
+ * @memberOf DetailBase
+ */
+ getBaseInfoData() {
+ return [
+ {
+ name: '集群名',
+ value: 'helloworld',
+ },
+ {
+ name: '集群ID',
+ value: 'cls - 2ntelvxw',
+ type: {
+ key: 'color',
+ value: 'blue',
+ },
+ },
+ {
+ name: '状态',
+ value: '运行中',
+ type: {
+ key: 'color',
+ value: 'green',
+ },
+ },
+ {
+ name: 'K8S版本',
+ value: '1.7.8',
+ },
+ {
+ name: '配置',
+ value: '6.73 核 10.30 GB',
+ },
+ {
+ name: '所在地域',
+ value: '广州',
+ },
+ {
+ name: '新增资源所属项目',
+ value: '默认项目',
+ },
+ {
+ name: '节点数量',
+ value: '4 个',
+ },
+ {
+ name: '节点网络',
+ value: 'vpc - 5frmkm1x',
+ type: {
+ key: 'color',
+ value: 'blue',
+ },
+ },
+ {
+ name: '容器网络',
+ value: '172.16.0.0 / 16',
+ },
+ {
+ name: '集群凭证',
+ value: '显示凭证',
+ type: {
+ key: 'color',
+ value: 'blue',
+ },
+ },
+ {
+ name: '创建/更新',
+ value: '2018-05-31 22:11:44 2018-05-31 22:11:44',
+ type: {
+ key: 'contractAnnex',
+ value: 'pdf',
+ },
+ },
+ {
+ name: '描述',
+ value: 'istio_test',
+ },
+ ];
+ }
+
+ /**
+ * 表格定义基础数据
+ *
+ * @returns
+ *
+ * @memberOf DetailBase
+ */
+ getTableColumns() {
+ return [
+ {
+ minWidth: '448',
+ ellipsis: true,
+ colKey: 'name',
+ title: '项目名称',
+ sorter: (a, b) => a.name.substr(10) - b.name.substr(10),
+ },
+ {
+ width: '224',
+ ellipsis: true,
+ colKey: 'adminName',
+ title: '管理员',
+ },
+ {
+ width: '224',
+ ellipsis: true,
+ colKey: 'adminPhone',
+ title: '联系方式',
+ },
+ {
+ width: '224',
+ className: 'test',
+ ellipsis: true,
+ colKey: 'updateTime',
+ title: '创建时间',
+ sorter: (a, b) => Date.parse(a.updateTime) - Date.parse(b.updateTime),
+ },
+ {
+ align: 'left',
+ width: '200',
+ className: 'test2',
+ ellipsis: true,
+ colKey: 'op',
+ fixed: 'right',
+ title: '操作',
+ },
+ ];
+ }
+
+ /**
+ * 获取弹窗配置数据
+ *
+ * @memberOf DetailBase
+ */
+ getPropUpData() {
+ const INITIAL_DATA = {
+ name: '',
+ warning: '',
+ success: '',
+ failB: '',
+ warningB: '',
+ loading: '',
+ add: '',
+ help: '',
+ };
+
+ return {
+ formData: { ...INITIAL_DATA },
+ courseOptions: [
+ { label: '语文', value: '1' },
+ { label: '数学', value: '2' },
+ { label: '英语', value: '3' },
+ ],
+ options: [
+ {
+ label: '资源初始化后',
+ value: 'beijing',
+ },
+ {
+ label: '上海',
+ value: 'shanghai',
+ },
+ ],
+ options1: [
+ {
+ label: '资源初始化后',
+ value: 'guangzhou',
+ },
+ {
+ label: '深圳',
+ value: 'shenzhen',
+ },
+ {
+ label: '东莞',
+ value: 'dongguang',
+ },
+ ],
+ options2: [
+ {
+ label: '资源初始化后',
+ value: 'nanjing',
+ },
+ {
+ label: '苏州',
+ value: '苏州',
+ },
+ {
+ label: '无锡',
+ value: 'wuxi',
+ },
+ ],
+ tSelectOptions: [
+ {
+ label: 'Sanzhang',
+ value: '1',
+ },
+ {
+ label: 'ls',
+ value: '2',
+ },
+ {
+ label: 'James',
+ value: '3',
+ },
+ ],
+ };
+ }
+}
+
+export default new DetailBase();
diff --git a/src/service/service-detail.ts b/src/service/service-detail.ts
new file mode 100644
index 0000000..7678bd4
--- /dev/null
+++ b/src/service/service-detail.ts
@@ -0,0 +1,57 @@
+interface DashboardPanel {
+ title: string;
+ number: string | number;
+ leftType?: string;
+ upTrend?: string;
+ downTrend?: string;
+}
+
+export const PANE_LIST_DATA: Array = [
+ {
+ title: '总申请数(次)',
+ number: '1126',
+ upTrend: '10%',
+ },
+ {
+ title: '供应商数量(个)',
+ number: '13',
+ downTrend: '13%',
+ },
+ {
+ title: '采购商品品类(类)',
+ number: '4',
+ upTrend: '10%',
+ },
+ {
+ title: '申请人数量(人)',
+ number: 90,
+ downTrend: '44%',
+ leftType: 'icon-file-paste',
+ },
+ {
+ title: '申请完成率(%)',
+ number: 80.5,
+ upTrend: '70%',
+ },
+ {
+ title: '到货及时率(%)',
+ number: 78,
+ upTrend: '16%',
+ },
+];
+export const PRODUCT_LIST = [
+ {
+ description: 'SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部',
+ index: 1,
+ isSetup: true,
+ name: 'SSL证书',
+ type: 4,
+ },
+ {
+ description: 'SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部',
+ index: 1,
+ isSetup: true,
+ name: 'SSL证书',
+ type: 4,
+ },
+];
diff --git a/src/service/service-user.ts b/src/service/service-user.ts
new file mode 100644
index 0000000..7fdc255
--- /dev/null
+++ b/src/service/service-user.ts
@@ -0,0 +1,64 @@
+export const USER_INFO_LIST = [
+ {
+ title: '手机',
+ content: '+86 13923734567',
+ },
+ {
+ title: '座机',
+ content: '734567',
+ },
+ {
+ title: '办公室邮箱',
+ content: 'Account@qq.com',
+ },
+ {
+ title: '座位',
+ content: 'T32F 012',
+ },
+ {
+ title: '管理主体',
+ content: '腾讯集团',
+ },
+ {
+ title: '直属上级',
+ content: 'Michael Wang',
+ },
+ {
+ title: '职位',
+ content: '高级 UI 设计师',
+ },
+ {
+ title: '入职时间',
+ content: '2021-07-01',
+ },
+ {
+ title: '所属团队',
+ content: '腾讯/腾讯公司/某事业群/某产品部/某运营中心/商户服务组',
+ span: 6,
+ },
+];
+
+export const TEAM_MEMBERS = [
+ {
+ avatar: 'https://avatars.githubusercontent.com/Wen1kang',
+ title: 'Lovellzhong 钟某某',
+ description: '直客销售 港澳拓展组员工',
+ },
+ {
+ avatar: 'https://avatars.githubusercontent.com/pengYYYYY',
+ title: 'Jiajingwang 彭某某',
+ description: '前端开发 前台研发组员工',
+ },
+ {
+ avatar: 'https://avatars.githubusercontent.com/u/24469546?s=96&v=4',
+ title: 'cruisezhang 林某某',
+ description: '技术产品 产品组员工',
+ },
+ {
+ avatar: 'https://avatars.githubusercontent.com/u/88708072?s=96&v=4',
+ title: 'Lovellzhang 商某某',
+ description: '产品运营 港澳拓展组员工',
+ },
+];
+
+export const PRODUCT_LIST = ['a', 'b', 'c', 'd'];
diff --git a/src/store/index.ts b/src/store/index.ts
new file mode 100644
index 0000000..b69e5be
--- /dev/null
+++ b/src/store/index.ts
@@ -0,0 +1,22 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import user from './modules/user';
+import notification from './modules/notification';
+import setting from './modules/setting';
+import permission from './modules/permission';
+import tabRouter from './modules/tab-router'; // 多标签管理
+
+Vue.use(Vuex);
+
+const store = new Vuex.Store({
+ strict: import.meta.env.MODE === 'release',
+ modules: {
+ user,
+ setting,
+ notification,
+ permission,
+ tabRouter,
+ },
+});
+
+export default store;
diff --git a/src/store/modules/notification.ts b/src/store/modules/notification.ts
new file mode 100644
index 0000000..e42b808
--- /dev/null
+++ b/src/store/modules/notification.ts
@@ -0,0 +1,90 @@
+export interface msgDataItem {
+ id: string;
+ content: string;
+ type: string;
+ status: boolean;
+ collected: boolean;
+ date: string;
+ quality: string;
+}
+// 定义的state初始值
+const state: { msgData: Array } = {
+ msgData: [
+ {
+ id: '123',
+ content: '腾讯大厦一楼改造施工项目 已通过审核!',
+ type: '合同动态',
+ status: true,
+ collected: false,
+ date: '2021-01-01 08:00',
+ quality: 'high',
+ },
+ {
+ id: '124',
+ content: '三季度生产原材料采购项目 开票成功!',
+ type: '票务动态',
+ status: true,
+ collected: false,
+ date: '2021-01-01 08:00',
+ quality: 'low',
+ },
+ {
+ id: '125',
+ content: '2021-01-01 10:00的【国家电网线下签约】会议即将开始,请提前10分钟前往 会议室1 进行签到!',
+ type: '会议通知',
+ status: true,
+ collected: false,
+ date: '2021-01-01 08:00',
+ quality: 'middle',
+ },
+ {
+ id: '126',
+ content: '一季度生产原材料采购项目 开票成功!',
+ type: '票务动态',
+ status: true,
+ collected: false,
+ date: '2021-01-01 08:00',
+ quality: 'low',
+ },
+ {
+ id: '127',
+ content: '二季度生产原材料采购项目 开票成功!',
+ type: '票务动态',
+ status: true,
+ collected: false,
+ date: '2021-01-01 08:00',
+ quality: 'low',
+ },
+ {
+ id: '128',
+ content: '三季度生产原材料采购项目 开票成功!',
+ type: '票务动态',
+ status: true,
+ collected: false,
+ date: '2021-01-01 08:00',
+ quality: 'low',
+ },
+ ],
+};
+
+const mutations = {
+ setMsgData(state, data) {
+ // eslint-disable-next-line no-param-reassign
+ state.msgData = data;
+ },
+};
+
+const getters = {
+ unreadMsg: (state) => state.msgData.filter((item) => item.status),
+ readMsg: (state) => state.msgData.filter((item) => !item.status),
+};
+
+const actions = {};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+ getters,
+};
diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts
new file mode 100644
index 0000000..f4b2837
--- /dev/null
+++ b/src/store/modules/permission.ts
@@ -0,0 +1,65 @@
+import { resetRouter, asyncRouterList } from '@/router';
+
+function filterPermissionsRouters(routes, roles) {
+ const res = [];
+ routes.forEach((route) => {
+ const children = [];
+ route.children?.forEach((childRouter) => {
+ const roleCode = childRouter.meta?.roleCode || childRouter.name;
+ if (roles.indexOf(roleCode) !== -1) {
+ children.push(childRouter);
+ }
+ });
+ if (children.length > 0) {
+ route.children = children;
+ res.push(route);
+ }
+ });
+ return res;
+}
+
+const state = {
+ whiteListRouters: ['/login','/register'],
+ routers: [],
+};
+
+const mutations = {
+ setRouters: (state, routers) => {
+ state.routers = routers;
+ },
+};
+
+const getters = {
+ routers: (state) => state.routers,
+ whiteListRouters: (state) => state.whiteListRouters,
+};
+
+const actions = {
+ async initRoutes({ commit }, roles) {
+ let accessedRouters;
+ // special token
+ if (roles.includes('ALL_ROUTERS')) {
+ accessedRouters = asyncRouterList;
+ } else {
+ accessedRouters = filterPermissionsRouters(asyncRouterList, roles);
+ }
+
+ commit('setRouters', accessedRouters);
+
+ // register routers
+ // router.addRoutes(state.routers);
+ },
+ async restore({ commit }) {
+ // remove routers
+ resetRouter();
+ commit('setRouters', []);
+ },
+};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+ getters,
+};
diff --git a/src/store/modules/setting.ts b/src/store/modules/setting.ts
new file mode 100644
index 0000000..5f6e2e9
--- /dev/null
+++ b/src/store/modules/setting.ts
@@ -0,0 +1,122 @@
+/* eslint-disable no-param-reassign */
+import { Color } from 'tvision-color';
+import STYLE_CONFIG from '@/config/style';
+import { TColorSeries, TColorToken, LIGHT_CHART_COLORS, DARK_CHART_COLORS } from '@/config/color';
+import { insertThemeStylesheet, generateColorMap } from '@/utils/color';
+
+// 定义的state初始值
+const state = {
+ ...STYLE_CONFIG,
+ showSettingPanel: false,
+ colorList: {},
+ chartColors: LIGHT_CHART_COLORS,
+};
+
+type IInitStateType = typeof state;
+
+export interface IStateType extends IInitStateType {
+ isAsideFooter: boolean;
+ showSettingPanel: boolean;
+}
+
+// 定义的state的初始值方法,传入state或者额外的方法,然后利用 vuex 的双向数据驱动进行值的改变
+// 可通过this.$store.commit(' ')调用,但是触发的是同步事件
+const mutations = {
+ update(state: IStateType, payload: IStateType) {
+ state.showBreadcrumb = payload.showBreadcrumb;
+ state.mode = payload.mode;
+ state.layout = payload.layout;
+ state.isSidebarCompact = payload.isSidebarCompact;
+ state.splitMenu = payload.splitMenu;
+ state.isFooterAside = payload.isFooterAside;
+ state.isSidebarFixed = payload.isSidebarFixed;
+ state.isHeaderFixed = payload.isHeaderFixed;
+ state.showHeader = payload.showHeader;
+ state.showFooter = payload.showFooter;
+ state.backgroundTheme = payload.backgroundTheme;
+ state.brandTheme = payload.brandTheme;
+ state.isUseTabsRouter = payload.isUseTabsRouter;
+ },
+ toggleSidebarCompact(state: IStateType) {
+ state.isSidebarCompact = !state.isSidebarCompact;
+ },
+ toggleUseTabsRouter(state: IStateType) {
+ state.isUseTabsRouter = !state.isUseTabsRouter;
+ },
+ showSidebarCompact(state: IStateType, payload: boolean) {
+ state.isSidebarCompact = payload;
+ },
+ toggleSettingPanel(state: IStateType, payload: boolean) {
+ state.showSettingPanel = payload;
+ },
+ addColor(state: IStateType, payload: TColorSeries) {
+ state.colorList = { ...state.colorList, ...payload };
+ },
+ changeChartColor(state: IStateType, payload: TColorToken) {
+ state.chartColors = { ...payload };
+ },
+};
+
+const getters = {
+ showHeader: (state: IStateType) => state.showHeader,
+ showSidebar: (state: IStateType) => state.layout !== 'top',
+ showSidebarLogo: (state: IStateType) => state.layout === 'side',
+ showHeaderLogo: (state: IStateType) => state.layout !== 'side',
+ showFooter: (state: IStateType) => state.showFooter,
+ isUseTabsRouter: (state: IStateType) => state.isUseTabsRouter,
+ mode: (state: IStateType) => {
+ if (state.mode === 'auto') {
+ const media = window.matchMedia('(prefers-color-scheme:dark)');
+ if (media.matches) {
+ return 'dark';
+ }
+ return 'light';
+ }
+ return state.mode;
+ },
+};
+
+const actions = {
+ changeTheme({ commit, dispatch }, payload: IStateType) {
+ dispatch('changeMode', payload);
+ dispatch('changeBrandTheme', payload);
+ commit('update', payload);
+ },
+ changeMode({ commit }, payload: IStateType) {
+ let theme = payload.mode;
+ if (payload.mode === 'auto') {
+ const media = window.matchMedia('(prefers-color-scheme:dark)');
+ if (media.matches) {
+ theme = 'dark';
+ } else {
+ theme = 'light';
+ }
+ }
+ const isDarkMode = theme === 'dark';
+
+ document.documentElement.setAttribute('theme-mode', isDarkMode ? 'dark' : '');
+
+ commit('changeChartColor', isDarkMode ? DARK_CHART_COLORS : LIGHT_CHART_COLORS);
+ },
+ changeBrandTheme(_: { state: IStateType }, payload: IStateType) {
+ const { brandTheme, mode } = payload;
+ const { colors: newPalette, primary: brandColorIndex } = Color.getColorGradations({
+ colors: [brandTheme],
+ step: 10,
+ remainInput: false, // 是否保留输入 不保留会矫正不合适的主题色
+ })[0];
+ const colorMap = generateColorMap(brandTheme, newPalette, mode as 'light' | 'dark', brandColorIndex);
+
+ insertThemeStylesheet(brandTheme, colorMap, mode as 'light' | 'dark');
+
+ document.documentElement.setAttribute('theme-color', brandTheme);
+ },
+};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+ getters,
+};
diff --git a/src/store/modules/tab-router.ts b/src/store/modules/tab-router.ts
new file mode 100644
index 0000000..f592c00
--- /dev/null
+++ b/src/store/modules/tab-router.ts
@@ -0,0 +1,83 @@
+export type TRouterInfo = {
+ path: string;
+ routeIdx: number;
+ title: string;
+ name?: string;
+ isAlive?: boolean;
+ isHome?: boolean;
+};
+
+export type TTabRouterType = {
+ isRefreshing: boolean;
+ tabRouterList: Array;
+};
+
+const homeRoute: Array = [
+ {
+ path: '/dashboard/base',
+ routeIdx: 0,
+ title: '仪表盘',
+ name: 'DashboardBase',
+ isHome: true,
+ },
+];
+
+const state: TTabRouterType = {
+ tabRouterList: homeRoute,
+ isRefreshing: false,
+};
+
+const mutations = {
+ // 处理刷新
+ toggleTabRouterAlive(state: TTabRouterType, routeIdx: number) {
+ state.isRefreshing = !state.isRefreshing;
+ state.tabRouterList[routeIdx].isAlive = !state.tabRouterList[routeIdx].isAlive;
+ },
+ // 处理新增
+ appendTabRouterList(state: TTabRouterType, newRoute: TRouterInfo) {
+ if (!state.tabRouterList.find((route: TRouterInfo) => route.path === newRoute.path))
+ // eslint-disable-next-line no-param-reassign
+ state.tabRouterList = state.tabRouterList.concat({ ...newRoute, isAlive: true });
+ },
+ // 处理关闭当前
+ subtractCurrentTabRouter(state: TTabRouterType, newRoute: TRouterInfo) {
+ const { routeIdx } = newRoute;
+ state.tabRouterList = state.tabRouterList.slice(0, routeIdx).concat(state.tabRouterList.slice(routeIdx + 1));
+ },
+ // 处理关闭右侧
+ subtractTabRouterBehind(state: TTabRouterType, newRoute: TRouterInfo) {
+ const { routeIdx } = newRoute;
+ state.tabRouterList = state.tabRouterList.slice(0, routeIdx + 1);
+ },
+ // 处理关闭左侧
+ subtractTabRouterAhead(state: TTabRouterType, newRoute: TRouterInfo) {
+ const { routeIdx } = newRoute;
+ state.tabRouterList = homeRoute.concat(state.tabRouterList.slice(routeIdx));
+ },
+ // 处理关闭其他
+ subtractTabRouterOther(state: TTabRouterType, newRoute: TRouterInfo) {
+ const { routeIdx } = newRoute;
+ state.tabRouterList = homeRoute.concat([state.tabRouterList?.[routeIdx]]);
+ },
+ removeTabRouterList() {
+ state.tabRouterList = [];
+ },
+ initTabRouterList(state: TTabRouterType, newRoute: TRouterInfo[]) {
+ state.tabRouterList = newRoute;
+ },
+};
+
+const getters = {
+ tabRouterList: (state: TTabRouterType) => state.tabRouterList,
+ isRefreshing: (state: TTabRouterType) => state.isRefreshing,
+};
+
+const actions = {};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+ getters,
+};
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
new file mode 100644
index 0000000..93f6503
--- /dev/null
+++ b/src/store/modules/user.ts
@@ -0,0 +1,105 @@
+const InitUserInfo = {
+ roles: [],
+};
+
+// 定义的state初始值
+const state = {
+ token: localStorage.getItem('associationToken') || '', // 默认token不走权限
+ userInfo: InitUserInfo,
+ association: localStorage.getItem('associationInfo') || '',
+ //apiUrl:'http://192.168.3.130',
+ apiUrl: 'https://hnyea.0rui.cn'
+};
+
+const mutations = {
+ setToken(state, token) {
+ localStorage.setItem('associationToken', token);
+ state.token = token;
+ },
+ removeToken(state) {
+ localStorage.removeItem('associationToken');
+ state.token = '';
+ },
+ setUserInfo(state, userInfo) {
+ state.userInfo = userInfo;
+ },
+ setAssociation(state, Association) {
+ localStorage.setItem('associationInfo', JSON.stringify(Association));
+ state.association = Association;
+ },
+ removeAssociation(state) {
+ localStorage.removeItem('associationInfo');
+ state.association = '';
+ },
+};
+
+const getters = {
+ token: (state) => state.token,
+ roles: (state) => state.userInfo?.roles,
+};
+
+
+const actions = {
+ async login({commit}, userInfo) {
+ const mockLogin = async (userInfo) => {
+ // 登录请求流程
+ console.log(userInfo);
+ commit('setAssociation', userInfo);
+ return {
+ code: 200,
+ }
+ };
+
+ const res = await mockLogin(userInfo);
+ if (res.code === 200) {
+ commit('setToken', userInfo.token);
+ } else {
+ throw res;
+ }
+ },
+ async getUserInfo({commit, state}) {
+ const mockRemoteUserInfo = async (token) => {
+ if (typeof (token) == 'object') {
+ var key = token;
+ } else {
+ var key = JSON.parse(token);
+ }
+ if (key.group == 1) {
+ return {
+ name: 'td_main',
+ roles: ['ALL_ROUTERS'],
+ };
+ } else {
+ return {
+ name: 'td_dev',
+ roles: ['DashboardBase','newsIndex', 'login', 'activityIndex', 'userEditShen', 'userIndex', 'userInfo', 'userEdit'],
+ };
+ }
+ // if (key.group == 1) {
+ // return {
+ // name: 'td_main',
+ // roles: ['ALL_ROUTERS'],
+ // };
+ // } else {
+ // return {
+ // name: 'td_dev',
+ // roles: ['DashboardBase','newsIndex', 'login', 'activityIndex', 'userEditShen', 'userIndex', 'userInfo', 'userEdit'],
+ // };
+ // }
+ };
+ const res = await mockRemoteUserInfo(state.association);
+ commit('setUserInfo', res);
+ },
+ async logout({commit}) {
+ commit('removeToken');
+ commit('setUserInfo', []);
+ },
+};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+ getters,
+};
diff --git a/src/style/font-family.less b/src/style/font-family.less
new file mode 100644
index 0000000..c639e25
--- /dev/null
+++ b/src/style/font-family.less
@@ -0,0 +1,6 @@
+@font-face {
+ font-family: 'TencentSansW7';
+ src: url('data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAusAA4AAAAAEJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAALkAAAABwAAAAchqPqzUdERUYAAAtwAAAAHgAAAB4AKQAbT1MvMgAAAbgAAABZAAAAYGmceoNjbWFwAAACYAAAAJcAAAHsPmfPZmdhc3AAAAtkAAAADAAAAAwACAAbZ2x5ZgAAAywAAAW8AAAG/Ivn/ztoZWFkAAABRAAAADYAAAA2E+AL5GhoZWEAAAF8AAAAIAAAACQIawJ9aG10eAAAAhQAAABMAAAATCG/Auxsb2NhAAADAAAAACwAAAAsDjIQIm1heHAAAAGcAAAAGgAAACAAfgBDbmFtZQAACOgAAAIUAAAEm0zGvtJwb3N0AAAK/AAAAGYAAAB/4wuGdnByZXAAAAL4AAAACAAAAAhwAgESAAEAAAABBR/xlpGAXw889QALA+gAAAAA2Ac3gwAAAADY+IxB//L/HAPPAwAAAAAIAAIAAAAAAAB42mNgZGBgWf7vFAMD84v/n/7vZD7PABRBAYIAwxQH7XjaY2BkYGAQZXBiYGEAAUYGGEiBUAAMEQDCAAB42mNgYepm2sPAysDA1MUUwcDA4A2hGeMYjBjNgKI8HMxMTCz8TCwLGJj2CzCAgRiI8PX382d0YGBMEmQ2+u/FcIJlOVA9CwMjSI6JlekwkFJgYAQAR1kL+QAAAAJYAHYAAAAAAU0AAAEEAAACUAAhAlYAFQJUACACKgAdAZUANgEUABUBYAAkA5wAFQINABsBqAA0AnAAKgJYACoD6ACF//YANP/yACN42mNgYGBmgGAZBkYGEHgG5DGC+SwMp4C0HIMAUISPQYEhiSGNIZMhl6GUoZJhgeIkfS6/N4GpQQuSBP//B+tMZEgByucwFGOT/7/4/6L/C/7P+z/z/7T/yffqLrJvVFu3Zm3xPJBtcgz4ADPFkIGRDWgMIcBAIWBhZWBj52Bg4GRg4OIGi/Dw8gFJfgYqA/JcCgA99Se8ALgB/4W4AAGNAAAAFAAUABQAFABSAIIAsgD6ASIBOAFYAYIBxgHwAhQCRAJaAogCygMYA3542k1Ua2xTZRj+LmtP23Vdz2lPz3pZb2dr1+u2nq2H0d3Z2OhI5mC4AZMBo0gM98E0oRn1AqgoIYDG4BAkakDkJ4iyiCZGAiISUH8YjIQfEhNUMCoJrme+bTfkx/nxveec53ne533eDxE0Nn0V/0V2I4oYhATWw1ZKrDiGx5Vfzp6NkXPZ7mH8ECGCPNNXiZWokANVIYRjFt7MUI83iuvrWnAzTWA5Xl/nC2G/SZJFr7oUq3mzBaf7F5S0Kt+F59i1aq0j0tbwJmXcwUtsz3HHhEtQaYr0RFUbL0sqB8yRClvcG2uwa7hKg4VLKdFjZmeEN5SwwM0Dd4DcRaXAXuAuxQYqekwSIxRoqRRrxjLevrK/RNCUhXt7lYevpQMf6StjW1sz/gCrIqqm+Z7krsjCmJU67/zexrvMykE+CniA7wb8oUf4EhW9vtm2qGQSvQY808+t9Ov/5ih0zlhfyytfbGodd/ht2rJiH7k7dTtP0NQTYpUo3qDzSnsSVpc5j18O+DzRIzeqyel34nwDOISZHGoCM6I3SvKMRJppKM8pxeIy3tbU4S4y6Oc231Sp3OFLgXMV7dV2xq8L9K9IUZvY5XAZi4wfms2U6K21PoHvnVfvchitXEorhH2O4K253RUTnIYt0Xv4ITanB6M4zPwm9GuBQ4GIEaloEmVJzvXM4JeqXaxWfYg7tCi9qIddqNZZg53yKEv2lLgkEWaDr6fERHfEnEL5/mA+uJzcLmTIJEsMNUl0t5AR7o+kR8jqTCa7nsjZS3nuCvg2DtwcpC3ftQzfgg1ODMRfBjt8eiP8ZLAE7HNDsRJPUKhYTmqy13osvJGm4H/gomsgh8Ksk2oGpM+kAHqAh0wmuitpSWO6SWer2NOX7vu8D2SouFCACSSVk3hgjmBllRp8Takhck6THTT9DZjVoMkPprfgmSE8igHzKNOJ//MX4X4rN6m0VF022lan02g4R11DNngDahqoPQe1YoZ31SRiKWN5fammqNgddMiRcNheAoXIbKGlKsoXo7w3daDjFDmNbOAiM+uJOONSbjoSIzEPI1owpyO0oL6twlAcSbI9zrTzKIePTdeaeZamOHe4zJtA06kTJ3J+BSF7vdCbKZ/swsbGZzyHZvCN9BrlzmN+vUVU2UsFq/CAcjJnVV5bcNpB2gCnPI9jILDquZ1rwflleQzwqx1ri8PJzh+4K3GnUcPsg32pSdfAJmYA+dPm+a61rBj0N3Z5ktio3Gu1uAqZ3IVW0R2Ar4GDwIiyp97jJ5MXLuzbn71IGvYT1fXrR545kvdp+p/pNB0nvyI7QiqR+A2UEZupLPmjOK/KIlg4On741U6xf3hj49Ha0e2bov3tVFd6oOx2uVvb9dlLeOTjxt1797XUvDBx+snTOv1Sk/2y0g7YRTCDNP2WIqSHhLqQCHQGnEuYmpHhhvFYBNHnV8UsUPJLpjjwYZNA8ZC+yv7Uxu5QiG/vMWOfNzzq9uH7XqFoyz3byRWUv1ClnNowsoqi+CYp248fhN0TC94YXrSkYyRod03dWkYOmpdOfUAetGWTiE7/CRomQYML+VG0kHOG5AjjpjjE0kAYMc7JubMsqZnK3GvqMQmNOHcR4u9t5Woai31t3xXxYVrcaZQXt+5cOWZZV7ZXp94Io6u1C5Q+rZzY+pP62YEdZEmpx6QcUb4ZnMJ2nXbs2uWtb+P57w6sSoYytQYnl62juhVEnT1e2HURtF0EbQnUBsrAD9AADglwhfgLHkWxX2TiMqPOeyQzftinXHjhbVwuJVIdiOY9fvBRstDzyh9Ys6B6W2h0HnvO85DbvMsa2xJhNPgiPzBkaN4W/NF+0PaOd/ug7Yz+DNfVp3/v5+Jx8yRdT3F5dLMorLXik6PrnhhYfKAxM/hyb0Oanycm3+86bHMPC6JyZfB8YJnN8sngi4xqqdq3nN0//vzOTNXq5YsR+g8984WfeNq1Us1qFEEQ/npnk0X8IQGJIjnUSRLYLLt7MMlFCHvNKRvMuTPTmZ1kdib0zAY3ePMFfAAvigi5+Ry+gA8iiOLFr3tbTFZWcnGgu76qrvqqpqoAPMQ3KMy+A3wMWOGBehRwAy31LOAIayoPuEmfdwEv4Z76HPAy7quvAbfwqvEz4BXcjd4EvIpG9J5sqnmH2gfP7LDCOn4E3CD/04AjtNXzgJtYV68DXsJj9SngZTxRXwJu4XtDBbyCtehlwKtoRm8xQIlzTGGRIcUINQRXPH100cMOtgLape0QBgVif9dBjxlTkCPnSckj2MCQNudzGeQmrS5PB22ifcYmxII9RuWUf3JXXjOUhvKCt/PEoDyf2iwd1XIl/W5vZ4vXrhyaIjZFTRmPijIv06lsDEemuOTZlEHZact+nXRkL8/FR1diTWXshUnIefNnhtCULv0Rtvk4ox7qopKjbbcNhhVOWK1mXTgw6STX9t8kMh91k1RuRfJXJS98Zyp2rKSbcDIdzqfPB2OrrCyk1+n2F3HOMzrC+aFmPrcOg0i9XvukbhhCbPmaUBv73zqjrcTJf1gPV7PL6PK4yGN6L6oq882IvaWm/0w/ZfOt9014x3yZta1yS/V7fbJKNBcjzaraWJNIbXVixtqeSXly6x3TRSJjPZVjc50qKyQ2ttaUpxObVUkW15xRtXD9rg8Hs3FxRr8ATJnl93jaY2BiAIP/zQxGDNiAKBAzMjAxMjG4MLgyuDN4MHgy+DD4MwQwhDGEM0QwxDAyM7IwsjKyMbKzl+ZlGhgYGHIlFhXllxdlpmeUgISM3AwcQbSJq6sziDY1cjQA0WZGhoYAgBwU3AAAAAEAAgAIAAr//wAPAAEAAAAMAAAAFgAAAAIAAQADABQAAQAEAAAAAgAAAAAAAAABAAAAANWkJwgAAAAA2Ac3gwAAAADY+IxB') format('woff');
+ font-weight: normal;
+ font-style: normal;
+}
diff --git a/src/style/index.less b/src/style/index.less
new file mode 100644
index 0000000..7717225
--- /dev/null
+++ b/src/style/index.less
@@ -0,0 +1,5 @@
+@import './variables.less';
+
+@import './font-family.less';
+
+@import './reset.less';
diff --git a/src/style/layout.less b/src/style/layout.less
new file mode 100644
index 0000000..9a99ca6
--- /dev/null
+++ b/src/style/layout.less
@@ -0,0 +1,201 @@
+@import './variables.less';
+@import './font-family.less';
+
+// layout rewrite
+
+.t-layout__sider {
+ width: fit-content;
+}
+
+.t-layout__header {
+ height: auto;
+}
+
+.t-layout.t-layout--with-sider {
+ > .t-layout {
+ flex: 1;
+ min-width: 760px;
+ }
+}
+
+.t-layout.t-layout--with-sider {
+ > .t-layout__content {
+ flex: 1;
+ min-width: 760px;
+ }
+}
+
+.t-menu--dark .t-menu__operations .t-icon {
+ color: rgba(255, 255, 255, 0.55);
+ &:hover {
+ cursor: pointer;
+ }
+}
+.t-default-menu.t-menu--dark {
+ background: var(--td-gray-color-13);
+}
+.t-default-menu:not(.t-menu--dark) .t-menu__item.t-is-active:not(.t-is-opened) {
+ background-color: var(--td-brand-color-1);
+ color: var(--td-brand-color);
+ .t-icon {
+ color: var(--td-brand-color);
+ }
+}
+
+.t-alert--info {
+ background-color: var(--td-brand-color-1);
+}
+
+.@{starter-prefix} {
+ // 布局元素调整
+ &-wrapper {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ }
+
+ &-main-wrapper {
+ height: 500px;
+ overflow: scroll;
+ }
+
+ &-side-nav-layout {
+ &-relative {
+ height: 100%;
+ }
+ }
+
+ &-content-layout {
+ padding: var(--td-comp-paddingTB-xl) var(--td-comp-paddingLR-xl);
+ }
+
+ &-layout {
+ height: calc(100vh - var(--td-comp-size-xxxl));
+ overflow-y: scroll;
+
+ &-tabs-nav {
+ max-width: 100%;
+ position: fixed;
+ overflow: visible;
+ z-index: 100;
+ }
+ &-tabs-nav + .@{starter-prefix}-content-layout {
+ padding-top: var(--td-comp-paddingTB-xl);
+ }
+
+ &::-webkit-scrollbar {
+ width: 8px;
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ border-radius: 6px;
+ border: 2px solid transparent;
+ background-clip: content-box;
+ background-color: var(--td-scrollbar-color);
+ }
+ }
+
+ &-footer-layout {
+ padding: 0;
+ margin-bottom: var(--td-comp-margin-l);
+ }
+
+ // slideBar
+ &-sidebar-layout {
+ height: 100%;
+ }
+
+ &-sidebar-compact {
+ width: var(--td-comp-size-xxxl);
+ }
+
+ &-sidebar-layout-side {
+ z-index: 100;
+ }
+
+ &-side-nav {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ z-index: 200;
+ transition: all 0.3s;
+ min-height: 100%;
+
+ &-mix {
+ top: var(--td-comp-size-xxxl);
+
+ &-fixed {
+ top: var(--td-comp-size-xxxl);
+ z-index: 0;
+ }
+ }
+
+ &-no-fixed {
+ position: relative;
+ z-index: 1;
+ }
+
+ &-no-logo {
+ z-index: 1;
+ }
+
+ &-logo-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ &:hover {
+ cursor: pointer;
+ }
+ }
+
+ &-logo-t-logo {
+ height: 32px;
+ width: 100%;
+ }
+
+ &-logo-tdesign-logo {
+ padding: 0 24px;
+ height: 32px;
+ width: 100%;
+ color: var(--td-text-color-primary);
+ }
+
+ &-logo-normal {
+ color: var(--td-brand-color);
+ font: var(--td-font-body-large);
+ transition: all 0.3s;
+ }
+ }
+
+ &-side-nav-placeholder {
+ flex: 1 1 232px;
+ min-width: 232px;
+ transition: all 0.3s;
+
+ &-hidden {
+ flex: 1 1 72px;
+ min-width: 72px;
+ transition: all 0.3s;
+ }
+ }
+}
+
+.route-tabs-dropdown {
+ .t-icon {
+ margin-right: 8px;
+ }
+}
+
+.logo-container {
+ cursor: pointer;
+ display: inline-flex;
+ height: var(--td-comp-size-xxxl);
+ margin-left: 24px;
+}
+
+.version-container {
+ color: var(--td-text-color-primary);
+ opacity: 0.4;
+}
diff --git a/src/style/reset.less b/src/style/reset.less
new file mode 100644
index 0000000..f1e97fe
--- /dev/null
+++ b/src/style/reset.less
@@ -0,0 +1,78 @@
+body {
+ color: var(--td-text-color-secondary);
+ font-family: -apple-system, BlinkMacSystemFont, PingFang SC, Microsoft YaHei, Arial Regular;
+ font: var(--td-font-body-medium);
+ -webkit-font-smoothing: antialiased;
+ padding: 0;
+ margin: 0;
+}
+
+pre {
+ font-family: var(--td-font-family);
+}
+
+ul,
+dl,
+li,
+dd,
+dt {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+figure,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p {
+ margin: 0;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+.t-button-link,
+a {
+ color: var(--td-brand-color);
+ text-decoration: none;
+ margin-right: var(--td-comp-margin-xxl);
+ cursor: pointer;
+ transition: color @anim-duration-base @anim-time-fn-easing;
+
+ &:hover {
+ color: var(--td-brand-color-hover);
+ }
+
+ &:active {
+ color: var(--td-brand-color-active);
+ }
+
+ &--active {
+ color: var(--td-brand-color-active);
+ }
+
+ &:focus {
+ text-decoration: none;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+}
+
+.container-base-margin-top {
+ margin-top: 16px;
+}
+
+.card-date-picker-container {
+ width: 250px;
+}
diff --git a/src/style/variables.less b/src/style/variables.less
new file mode 100644
index 0000000..5c75320
--- /dev/null
+++ b/src/style/variables.less
@@ -0,0 +1,27 @@
+/** 公共前缀 */
+@starter-prefix: tdesign-starter;
+
+// 颜色、尺寸、阴影、圆角、字体 variables 请参考 https://tdesign.tencent.com/starter/docs/vue/design-token
+
+// 响应式断点
+@screen-sm: 768px;
+@screen-md: 992px;
+@screen-lg: 1200px;
+@screen-xl: 1400px;
+
+@screen-sm-min: @screen-sm;
+@screen-md-min: @screen-md;
+@screen-lg-min: @screen-lg;
+@screen-xl-min: @screen-xl;
+
+@screen-sm-max: (@screen-md-min - 1px);
+@screen-md-max: (@screen-lg-min - 1px);
+@screen-lg-max: (@screen-xl-min - 1px);
+
+// 动画
+@anim-time-fn-easing: cubic-bezier(0.38, 0, 0.24, 1);
+@anim-time-fn-ease-out: cubic-bezier(0, 0, 0.15, 1);
+@anim-time-fn-ease-in: cubic-bezier(0.82, 0, 1, 0.9);
+@anim-duration-base: 0.2s;
+@anim-duration-moderate: 0.24s;
+@anim-duration-slow: 0.28s;
diff --git a/src/utils/charts.ts b/src/utils/charts.ts
new file mode 100644
index 0000000..9c67eb4
--- /dev/null
+++ b/src/utils/charts.ts
@@ -0,0 +1,38 @@
+import dayjs from 'dayjs';
+
+/**
+ * @export
+ * @param {string[]} dateTime
+ * @param {number} divideNum
+ * @returns {string[]}
+ */
+export function getDateArray(dateTime: string[] = [], divideNum = 10): string[] {
+ const timeArray: string[] = [];
+ if (dateTime.length > 0) {
+ for (let i = 0; i < divideNum; i++) {
+ const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum;
+ const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i;
+ timeArray.push(dayjs(enhandTime).format('YYYY-MM-DD'));
+ }
+ }
+
+ return timeArray;
+}
+
+/**
+ * 获取随机数
+ *
+ * @param {number} [num=100]
+ * @returns
+ *
+ * @memberOf DashboardBase
+ */
+export function getRandomArray(num = 100): number {
+ let resultNum = Number((Math.random() * num).toFixed(0));
+
+ if (resultNum <= 1) {
+ resultNum = 1;
+ }
+
+ return resultNum;
+}
diff --git a/src/utils/color.ts b/src/utils/color.ts
new file mode 100644
index 0000000..92d5beb
--- /dev/null
+++ b/src/utils/color.ts
@@ -0,0 +1,118 @@
+import { Color } from 'tvision-color';
+import * as echarts from 'echarts/core';
+import trim from 'lodash/trim';
+import { TColorToken } from '@/config/color';
+
+/**
+ * 依据主题类型获取颜色
+ *
+ * @export
+ * @param {string} theme
+ * @returns {}
+ */
+export function getColorFromTheme(): Array {
+ const theme = trim(getComputedStyle(document.documentElement).getPropertyValue('--td-brand-color'));
+ const themeColorList = Color.getRandomPalette({
+ color: theme,
+ colorGamut: 'bright',
+ number: 8,
+ });
+
+ return themeColorList;
+}
+
+/** 图表颜色 */
+export function getChartListColor(): Array {
+ const res = getColorFromTheme();
+
+ return res;
+}
+
+/**
+ * 更改图表主题颜色
+ *
+ * @export
+ * @param {Array} chartsList
+ * @param {string} theme
+ */
+export function changeChartsTheme(chartsList: echarts.EChartsType[]): void {
+ if (chartsList && chartsList.length) {
+ const chartChangeColor = getChartListColor();
+
+ for (let index = 0; index < chartsList.length; index++) {
+ const elementChart = chartsList[index];
+
+ if (elementChart) {
+ const optionVal = elementChart.getOption();
+
+ // 更改主题颜色
+ optionVal.color = chartChangeColor;
+
+ elementChart.setOption(optionVal, true);
+ }
+ }
+ }
+}
+
+/**
+ * 根据当前主题色、模式等情景 计算最后生成的色阶
+ */
+export function generateColorMap(
+ theme: string,
+ colorPalette: Array,
+ mode: 'light' | 'dark',
+ brandColorIdx: number,
+) {
+ const isDarkMode = mode === 'dark';
+
+ if (isDarkMode) {
+ // eslint-disable-next-line no-use-before-define
+ colorPalette.reverse().map((color) => {
+ const [h, s, l] = Color.colorTransform(color, 'hex', 'hsl');
+ return Color.colorTransform([h, Number(s) - 4, l], 'hsl', 'hex');
+ });
+ brandColorIdx = 5;
+ colorPalette[0] = `${colorPalette[brandColorIdx]}20`;
+ }
+
+ const colorMap = {
+ '--td-brand-color': colorPalette[brandColorIdx], // 主题色
+ '--td-brand-color-1': colorPalette[0], // light
+ '--td-brand-color-2': colorPalette[1], // focus
+ '--td-brand-color-3': colorPalette[2], // disabled
+ '--td-brand-color-4': colorPalette[3],
+ '--td-brand-color-5': colorPalette[4],
+ '--td-brand-color-6': colorPalette[5],
+ '--td-brand-color-7': brandColorIdx > 0 ? colorPalette[brandColorIdx - 1] : theme, // hover
+ '--td-brand-color-8': colorPalette[brandColorIdx], // 主题色
+ '--td-brand-color-9': brandColorIdx > 8 ? theme : colorPalette[brandColorIdx + 1], // click
+ '--td-brand-color-10': colorPalette[9],
+ };
+ return colorMap;
+}
+
+/**
+ * 将生成的样式嵌入头部
+ */
+export function insertThemeStylesheet(theme: string, colorMap: TColorToken, mode: 'light' | 'dark') {
+ const isDarkMode = mode === 'dark';
+ const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;
+
+ const styleSheet = document.createElement('style');
+ styleSheet.type = 'text/css';
+ styleSheet.innerText = `${root}{
+ --td-brand-color: ${colorMap['--td-brand-color']};
+ --td-brand-color-1: ${colorMap['--td-brand-color-1']};
+ --td-brand-color-2: ${colorMap['--td-brand-color-2']};
+ --td-brand-color-3: ${colorMap['--td-brand-color-3']};
+ --td-brand-color-4: ${colorMap['--td-brand-color-4']};
+ --td-brand-color-5: ${colorMap['--td-brand-color-5']};
+ --td-brand-color-6: ${colorMap['--td-brand-color-6']};
+ --td-brand-color-7: ${colorMap['--td-brand-color-7']};
+ --td-brand-color-8: ${colorMap['--td-brand-color-8']};
+ --td-brand-color-9: ${colorMap['--td-brand-color-9']};
+ --td-brand-color-10: ${colorMap['--td-brand-color-10']};
+ }`;
+
+ document.head.appendChild(styleSheet);
+}
diff --git a/src/utils/date.ts b/src/utils/date.ts
new file mode 100644
index 0000000..bbfa47a
--- /dev/null
+++ b/src/utils/date.ts
@@ -0,0 +1,12 @@
+// 获取常用时间
+import dayjs from 'dayjs';
+
+export const LAST_7_DAYS = [
+ dayjs().subtract(7, 'day').format('YYYY-MM-DD'),
+ dayjs().subtract(1, 'day').format('YYYY-MM-DD'),
+];
+
+export const LAST_30_DAYS = [
+ dayjs().subtract(30, 'day').format('YYYY-MM-DD'),
+ dayjs().subtract(1, 'day').format('YYYY-MM-DD'),
+];
diff --git a/src/utils/request.ts b/src/utils/request.ts
new file mode 100644
index 0000000..ce8eb50
--- /dev/null
+++ b/src/utils/request.ts
@@ -0,0 +1,69 @@
+import axios from 'axios';
+import store from '../store'
+//const API_HOST = env === 'mock' ? '/' : proxy[env].API; // 如果是mock模式 就不配置host 会走本地Mock拦截
+const API_HOST ="https://hnyea.0rui.cn/api/";
+//const API_HOST ="/api/";
+const CODE = {
+ LOGIN_TIMEOUT: 100000,
+ REQUEST_SUCCESS: 0,
+ REQUEST_FOBID: 1001,
+};
+
+const instance = axios.create({
+ baseURL: API_HOST,
+ timeout: 10000,
+ withCredentials: true,
+});
+
+// eslint-disable-next-line
+// @ts-ignore
+// axios的retry ts类型有问题
+instance.interceptors.retry = 3;
+
+instance.interceptors.request.use((config) => {
+ // 在原有配置基础上添加新参数
+ if(store.state.user.association){
+ if(typeof (store.state.user.association)=='object'){
+ var association=store.state.user.association;
+ }else{
+ var association=JSON.parse(store.state.user.association);
+ }
+ const token = store.state.user.token;
+ if (token) {
+ // 添加token请求头
+ config.headers.token = token;
+ }
+ config.data = { ...config.data, association_id: association.association_id};
+ }
+ return config;
+});
+
+instance.interceptors.response.use(
+ (response) => {
+ const { data } = response;
+ return data;
+ },
+ (err) => {
+ const { config } = err;
+
+ if (!config || !config.retry) return Promise.reject(err);
+
+ config.retryCount = config.retryCount || 0;
+
+ if (config.retryCount >= config.retry) {
+ return Promise.reject(err);
+ }
+
+ config.retryCount += 1;
+
+ const backoff = new Promise((resolve) => {
+ setTimeout(() => {
+ resolve({});
+ }, config.retryDelay || 1);
+ });
+
+ return backoff.then(() => instance(config));
+ },
+);
+
+export default instance;
diff --git a/stylelint.config.js b/stylelint.config.js
new file mode 100644
index 0000000..1df359c
--- /dev/null
+++ b/stylelint.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ defaultSeverity: 'error',
+ extends: ['stylelint-config-prettier'],
+ plugins: ['stylelint-less'],
+};
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..b803498
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "target": "es2015",
+ "module": "esnext",
+ "lib": ["esnext", "dom"],
+ "allowJs": true,
+ "checkJs": false,
+ "noImplicitAny": false,
+ "isolatedModules": false,
+ "experimentalDecorators": true,
+ "esModuleInterop": true,
+ "noImplicitThis": false,
+ "strictNullChecks": false,
+ "skipLibCheck": true,
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "jsx": "preserve",
+ "noEmit": true,
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["**/*.ts", "**/*.tsx"],
+ "compileOnSave": false
+}
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..7752d70
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,59 @@
+import { loadEnv } from 'vite';
+import { viteMockServe } from 'vite-plugin-mock';
+import { createVuePlugin } from 'vite-plugin-vue2';
+import { createSvgPlugin } from 'vite-plugin-vue2-svg';
+
+import path from 'path';
+
+const CWD = process.cwd();
+
+export default ({ mode }) => {
+ const { VITE_BASE_URL } = loadEnv(mode, CWD);
+
+ return {
+ base: VITE_BASE_URL,
+ resolve: {
+ alias: {
+ '~': path.resolve(__dirname, './'),
+ '@': path.resolve(__dirname, './src'),
+ },
+ },
+
+ css: {
+ preprocessorOptions: {
+ less: {
+ modifyVars: {},
+ },
+ },
+ },
+
+ plugins: [
+ createVuePlugin({
+ jsx: true,
+ }),
+ viteMockServe({
+ mockPath: 'mock',
+ localEnabled: true,
+ }),
+ createSvgPlugin(),
+ ],
+
+ build: {
+ cssCodeSplit: false,
+ },
+
+ server: {
+ proxy: {
+ '/api': {
+ // 用于开发环境下的转发请求
+ // 更多请参考:https://vitejs.dev/config/#server-proxy
+ target: 'http://192.168.3.130/',
+ pathRewrite: {
+ '^/api': ''
+ },
+ changeOrigin: true,
+ },
+ },
+ },
+ };
+};