├── .gitignore
├── img
├── 1.png
├── 2.png
├── 3.png
└── 4.gif
├── client
├── babel.config.js
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── css
│ │ └── reset.css
├── src
│ ├── assets
│ │ ├── 404.gif
│ │ ├── bg.jpg
│ │ ├── logo.png
│ │ ├── showcase.png
│ │ ├── lockLogin.png
│ │ └── js
│ │ │ ├── Export2Excel.js
│ │ │ └── Blob.js
│ ├── store
│ │ ├── state.js
│ │ ├── mutation-type.js
│ │ ├── getters.js
│ │ ├── index.js
│ │ ├── actions.js
│ │ └── mutations.js
│ ├── common
│ │ ├── bus.js
│ │ ├── Tags.vue
│ │ └── theme.vue
│ ├── views
│ │ ├── Home
│ │ │ ├── echarts
│ │ │ │ ├── ListTypeData.vue
│ │ │ │ ├── Stacked.vue
│ │ │ │ └── Dotted.vue
│ │ │ ├── Home.vue
│ │ │ ├── BaseCharts.vue
│ │ │ └── HomeTop.vue
│ │ ├── information
│ │ │ ├── article
│ │ │ │ └── ShowFundArticle.vue
│ │ │ ├── Editor.vue
│ │ │ ├── Markdown.vue
│ │ │ ├── Clock.vue
│ │ │ └── InfoShow.vue
│ │ ├── 404.vue
│ │ ├── Lock.vue
│ │ ├── MapList.vue
│ │ ├── Index.vue
│ │ ├── Investment
│ │ │ ├── ChinaTabsList.vue
│ │ │ ├── tablist
│ │ │ │ └── ChinaTabsTable.vue
│ │ │ └── ChinaTouziList.vue
│ │ ├── logo
│ │ │ └── Login.vue
│ │ ├── ListUser.vue
│ │ ├── register
│ │ │ └── Register.vue
│ │ ├── fundmanagement
│ │ │ ├── PayList.vue
│ │ │ └── FundList.vue
│ │ ├── Staff.vue
│ │ └── capitalData
│ │ │ └── FundPosition.vue
│ ├── App.vue
│ ├── main.js
│ ├── http.js
│ ├── components
│ │ ├── Menu.vue
│ │ ├── UserDialong.vue
│ │ ├── Dialong.vue
│ │ ├── LeftMenu.vue
│ │ └── Header.vue
│ └── router.js
├── .gitignore
├── package.json
└── vue.config.js
├── config
├── keys.js
└── passport.js
├── models
├── User.js
├── Profile.js
└── Staff.js
├── package.json
├── server.js
├── README.md
├── yarn-error.log
└── routes
└── api
├── staff.js
├── users.js
└── profiles.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/img/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/img/1.png
--------------------------------------------------------------------------------
/img/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/img/2.png
--------------------------------------------------------------------------------
/img/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/img/3.png
--------------------------------------------------------------------------------
/img/4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/img/4.gif
--------------------------------------------------------------------------------
/client/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/src/assets/404.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/client/src/assets/404.gif
--------------------------------------------------------------------------------
/client/src/assets/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/client/src/assets/bg.jpg
--------------------------------------------------------------------------------
/client/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/client/src/assets/logo.png
--------------------------------------------------------------------------------
/client/src/assets/showcase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/client/src/assets/showcase.png
--------------------------------------------------------------------------------
/client/src/store/state.js:
--------------------------------------------------------------------------------
1 | export default {
2 | isAuthenticated: false, //授权
3 | user: {}, //用户登录
4 | };
--------------------------------------------------------------------------------
/client/src/assets/lockLogin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrZHLF/vue-admin/HEAD/client/src/assets/lockLogin.png
--------------------------------------------------------------------------------
/client/src/store/mutation-type.js:
--------------------------------------------------------------------------------
1 | export const SET_AUTHENTICATED = "SET_AUTHENTICATED";
2 | export const SET_USER = "SET_USER";
--------------------------------------------------------------------------------
/client/src/common/bus.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 |
3 | // 使用 Event Bus进行非父子组件传值
4 | const bus = new Vue();
5 |
6 | export default bus;
7 |
--------------------------------------------------------------------------------
/client/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export default {
2 | isAuthenticated: state => state.isAuthenticated,
3 | user: state => state.user,
4 | }
--------------------------------------------------------------------------------
/config/keys.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | mongoURI: "mongodb://test:Z123456@ds135233.mlab.com:35233/restful-api-vue",
3 | secretOrKey: "secret"
4 | };
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/client/src/views/Home/echarts/ListTypeData.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 123
4 |
5 |
6 |
16 |
18 |
--------------------------------------------------------------------------------
/client/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex);
5 |
6 | import actions from "./actions";
7 | import getters from "./getters";
8 | import mutations from "./mutations";
9 | import state from "./state";
10 |
11 | export default new Vuex.Store({
12 | state,
13 | actions,
14 | getters,
15 | mutations
16 | });
--------------------------------------------------------------------------------
/client/src/views/information/article/ShowFundArticle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 四级路由
4 |
5 |
6 |
7 |
21 |
22 |
25 |
--------------------------------------------------------------------------------
/client/src/views/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
13 |
24 |
--------------------------------------------------------------------------------
/client/src/store/actions.js:
--------------------------------------------------------------------------------
1 | import { SET_AUTHENTICATED, SET_USER} from "./mutation-type";
2 |
3 | export default {
4 | setAuthenticated({ commit }, isAuthenticated) {
5 | commit(SET_AUTHENTICATED, {isAuthenticated});
6 | },
7 | setUSER({ commit }, user) {
8 | commit(SET_USER, {user})
9 | },
10 | createUser: ({ commit }) => {
11 | commit(SET_AUTHENTICATED, false)
12 | // commit(SET_USER, null)
13 | },
14 | }
--------------------------------------------------------------------------------
/client/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | import { SET_AUTHENTICATED, SET_USER } from "./mutation-type";
2 |
3 | export default {
4 | //是否授权
5 | [SET_AUTHENTICATED](state, { isAuthenticated }) {
6 | if (isAuthenticated) {
7 | state.isAuthenticated = isAuthenticated;
8 | } else {
9 | state.isAuthenticated = false;
10 | }
11 | },
12 | [SET_USER](state, { user }) {
13 | if (user) {
14 | state.user = user;
15 | } else {
16 | state.user = {};
17 | }
18 | },
19 | [SET_AUTHENTICATED](state) {
20 | state.isAuthenticated = false; //退出登录
21 | }
22 | };
--------------------------------------------------------------------------------
/models/User.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 | const Schema = mongoose.Schema;
3 |
4 | // Create Schema
5 | const UserSchema = new Schema({
6 | name: {
7 | type: String,
8 | required: true
9 | },
10 | email: {
11 | type: String,
12 | required: true
13 | },
14 | password: {
15 | type: String,
16 | required: true
17 | },
18 | avatar: {
19 | type: String
20 | },
21 | identity: {
22 | type: String,
23 | required: true
24 | },
25 | date: {
26 | type: Date,
27 | default: Date.now
28 | }
29 | });
30 |
31 | module.exports = User = mongoose.model('users', UserSchema);
--------------------------------------------------------------------------------
/models/Profile.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 | const Schema = mongoose.Schema;
3 |
4 | // Create Schema
5 | const ProfileSchema = new Schema({
6 | type: {
7 | type: String,
8 | },
9 | describe: {
10 | type: String
11 | },
12 | income: {
13 | type: String,
14 | required: true
15 | },
16 | expend: {
17 | type: String,
18 | required: true
19 | },
20 | cash: {
21 | type: String,
22 | required: true
23 | },
24 | remark: {
25 | type: String,
26 | },
27 | date: {
28 | type: Date,
29 | default: Date.now
30 | }
31 | });
32 |
33 | module.exports = Profile = mongoose.model("profiles", ProfileSchema);
--------------------------------------------------------------------------------
/models/Staff.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 | const Schema = mongoose.Schema;
3 |
4 | // Create Schema
5 | const StaffSchema = new Schema({
6 | name: {
7 | type: String,
8 | required: true
9 | },
10 | sex: {
11 | type: String,
12 | required: true
13 | },
14 | state: {
15 | type: String
16 | },
17 | hobby: {
18 | type: String
19 | },
20 | marriage: {
21 | type: String,
22 | },
23 | birthday: {
24 | type: String,
25 | },
26 | address: {
27 | type: String,
28 | },
29 | date: {
30 | type: Date,
31 | default: Date.now
32 | }
33 | });
34 |
35 | module.exports = Staff = mongoose.model("staff", StaffSchema);
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api-element",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "client-install": "npm install --prefix client",
8 | "client": "npm start --prefix client",
9 | "start": "node server.js",
10 | "server": "nodemon server.js",
11 | "dev": "concurrently \"npm run server\" \"npm run client\""
12 | },
13 | "author": "",
14 | "license": "ISC",
15 | "dependencies": {
16 | "bcryptjs": "^2.4.3",
17 | "body-parser": "^1.18.3",
18 | "concurrently": "^4.0.1",
19 | "express": "^4.16.4",
20 | "gravatar": "^1.6.0",
21 | "jsonwebtoken": "^8.3.0",
22 | "mongoose": "^5.3.4",
23 | "passport": "^0.4.0",
24 | "passport-jwt": "^4.0.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/client/src/views/Home/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
24 |
43 |
--------------------------------------------------------------------------------
/config/passport.js:
--------------------------------------------------------------------------------
1 | const JwtStrategy = require('passport-jwt').Strategy,
2 | ExtractJwt = require('passport-jwt').ExtractJwt;
3 | const mongoose = require("mongoose");
4 | const User = mongoose.model("users");
5 | const keys = require("../config/keys");
6 |
7 | const opts = {}
8 | opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
9 | opts.secretOrKey = keys.secretOrKey;
10 |
11 | module.exports = passport => {
12 | passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
13 | // console.log(jwt_payload);
14 | User.findById(jwt_payload.id)
15 | .then(user => {
16 | if (user) {
17 | return done(null, user);
18 | }
19 |
20 | return done(null, false);
21 | })
22 | .catch(err => console.log(err));
23 | }));
24 | }
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 后台管理界面
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/client/src/views/Home/BaseCharts.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
34 |
45 |
--------------------------------------------------------------------------------
/client/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
30 |
31 |
32 |
42 |
--------------------------------------------------------------------------------
/client/src/views/Lock.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
21 |
22 |
58 |
--------------------------------------------------------------------------------
/client/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store/index'
5 | import axios from './http'
6 | import ElementUI from 'element-ui'
7 | import 'element-ui/lib/theme-chalk/index.css'
8 | import moment from 'moment'
9 | import echarts from 'echarts'
10 | import VueQuillEditor from 'vue-quill-editor'
11 | Vue.prototype.$echarts = echarts
12 | Vue.prototype.$moment = moment
13 | Vue.use(VueQuillEditor)
14 |
15 | import VueAMap from 'vue-amap';
16 |
17 |
18 | Vue.use(VueAMap);
19 | Vue.config.productionTip = false
20 |
21 | //百度地图
22 | VueAMap.initAMapApiLoader({
23 | key: ' 3f5bdc7cb6cfffbafe7fbbb18528d7bb',
24 | plugin: ['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor'],
25 | // 默认高德 sdk 版本为 1.4.4
26 | v: '1.4.4'
27 | });
28 |
29 | Vue.prototype.$axios = axios
30 |
31 | //全局时间格式化过滤
32 | Vue.filter('moment', function (value, formatString) {
33 | formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
34 | return moment(value).format('YYYY-MM-DD');
35 | });
36 |
37 |
38 | Vue.use(ElementUI)
39 | new Vue({
40 | router,
41 | store,
42 | render: h => h(App)
43 | }).$mount('#app')
44 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const mongoose = require('mongoose');
3 | const app = express();
4 | const bodyParser = require('body-parser');
5 | const passport = require("passport"); //验证token
6 | //引入users.js
7 | const users = require('./routes/api/users');
8 | //引入profiles.js
9 | const profiles = require("./routes/api/profiles");
10 | //staff.js
11 | const staff = require("./routes/api/staff");
12 |
13 |
14 | app.get('/', (req, res) => {
15 | res.send('Hello World');
16 | });
17 |
18 | // 引入DB config
19 | const db = require('./config/keys').mongoURI;
20 |
21 | //使用body-parser中间件
22 | app.use(bodyParser.urlencoded({ extended: false }));
23 | app.use(bodyParser.json());
24 |
25 | //链接MongoDB
26 | mongoose
27 | .connect(
28 | db,
29 | { useNewUrlParser: true }
30 | )
31 | .then(() => {
32 | console.log('MongoDB Connected链接成功');
33 | })
34 | .catch(err => console.log(err));
35 |
36 | //引入passport初始化
37 | app.use(passport.initialize());
38 | require("./config/passport")(passport);
39 |
40 | // 使用routes
41 | app.use('/api/users', users);
42 | app.use("/api/profiles", profiles);
43 | app.use("/api/staff", staff);
44 |
45 |
46 |
47 | const port = process.env.PORT || 5000; //地址
48 |
49 | app.listen(port, () => {
50 | console.log(`Server running on port ${port}`);
51 | });
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 基于vue3.0实现后台管理模板
2 |
3 | > 通过自己所学的vue知识,从0开始自己搭建的一个关于后台管理的模板界面,有时间就会更新新的内容,实现一些常用的功能,
4 | > 使用vue最新脚手架搭建环境,编写界面,使用axios请求接口,渲染界面,实现页面登录注册,数据的增删改查,数据部分存储到easy-mock数据中。
5 |
6 | ## 项目结构
7 | ```
8 | |——— client #vue项目入口文件
9 | |——— config #秘钥配置文件
10 | |——— node_modules #一些常用安装的依赖
11 | |——— models #接口模型
12 | |——— router #接口文档
13 | |——— package.json #项目配置文件
14 | |___ README.md #项目的说明文档,markdown 格式
15 | ```
16 | ## 相关技术
17 | 1. vuejs2.0:一套构建用户界面的渐进式框架,易用、灵活、高效。
18 | 2. vue-router:官方的路由组件,配合vue.js创建单页应用(SPA)非常简单。
19 | 3. axios: 基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 node.js 中使用。
20 |
21 | ## 功能介绍
22 | - Element-ui
23 | - 请求拦截和响应拦截
24 | - 富文本编辑器
25 | - Markdown编辑器
26 | - Echarts
27 | - tab数据切换
28 | - token本地存储
29 | - 表单
30 | - 高德地图引入
31 | - 登录注册
32 | - 路由守卫
33 | - vuex存储
34 | - 数据分页和查询
35 | - Excel表格导出
36 | - 递归组件
37 | - 主题更换
38 | - 404
39 |
40 | ## 项目编译和运行
41 | + 可以直接在git上下载项目源码。把github下载到本地,
42 | git clone [](https://github.com/MrZHLF/vue-admin.git)
43 | + 进入node-api-element当前页面初始化
44 | cnpm install
45 | + 进入client项目目录中
46 | cnpm install
47 | + 所有依赖安装成功后执行启动命令在当前目录启动,不要在client进行启动,已经配置好前后端联调
48 | npm run dev
49 | 如果显示一下内容说明安装成功
50 | I Your application is running here: http://localhost:8080
51 |
52 | ## 成果展示
53 | 
54 | 
55 | 
56 |
57 | 
58 | 更新中...
--------------------------------------------------------------------------------
/client/src/http.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import { Message, Loading } from "element-ui";
3 | import router from "./router";
4 |
5 | let loading; //定义loading变量
6 |
7 | function startLoading() {
8 | //使用Element loading-start 方法
9 | loading = Loading.service({
10 | lock: true,
11 | text: "加载中...",
12 | background: "rgba(0, 0, 0, 0.7)"
13 | });
14 | }
15 | function endLoading() {
16 | //使用Element loading-close 方法
17 | loading.close();
18 | }
19 |
20 | // 请求拦截 设置统一header
21 | axios.interceptors.request.use(
22 | config => {
23 | // 加载
24 | startLoading();
25 | if (localStorage.eleToken)
26 | config.headers.Authorization = localStorage.eleToken;
27 | return config;
28 | },
29 | error => {
30 | return Promise.reject(error);
31 | }
32 | );
33 |
34 | // 响应拦截 401 token过期处理
35 | axios.interceptors.response.use(
36 | response => {
37 | endLoading();
38 | return response;
39 | },
40 | error => {
41 | // 错误提醒
42 | endLoading();
43 | Message.error(error.response.data);
44 |
45 | const { status } = error.response;
46 | if (status == 401) {
47 | Message.error("token值无效,请重新登录");
48 | // 清除token
49 | localStorage.removeItem("eleToken");
50 |
51 | // 页面跳转
52 | router.push("/login");
53 | }
54 |
55 | return Promise.reject(error);
56 | }
57 | );
58 |
59 | export default axios;
60 |
--------------------------------------------------------------------------------
/client/src/views/information/Editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
51 |
52 |
53 |
69 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "start": "npm run serve"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "better-scroll": "^1.13.4",
14 | "echarts": "^4.2.0-rc.2",
15 | "element-ui": "^2.4.8",
16 | "file-saver": "^2.0.0",
17 | "js-cookie": "^2.2.0",
18 | "jwt-decode": "^2.2.0",
19 | "mavon-editor": "^2.6.17",
20 | "moment": "^2.22.2",
21 | "vue": "^2.5.17",
22 | "vue-amap": "^0.5.8",
23 | "vue-aplayer": "^1.6.1",
24 | "vue-i18n": "^8.3.2",
25 | "vue-quill-editor": "^3.0.6",
26 | "vue-router": "^3.0.1",
27 | "vuex": "^3.0.1",
28 | "xlsx": "^0.14.1"
29 | },
30 | "devDependencies": {
31 | "@vue/cli-plugin-babel": "^3.0.5",
32 | "@vue/cli-plugin-eslint": "^3.0.5",
33 | "@vue/cli-service": "^3.0.5",
34 | "@vue/eslint-config-standard": "^3.0.5",
35 | "script-loader": "^0.7.2",
36 | "vue-template-compiler": "^2.5.17"
37 | },
38 | "eslintConfig": {
39 | "root": true,
40 | "env": {
41 | "node": true
42 | },
43 | "extends": [
44 | "plugin:vue/essential",
45 | "@vue/standard"
46 | ],
47 | "rules": {},
48 | "parserOptions": {
49 | "parser": "babel-eslint"
50 | }
51 | },
52 | "postcss": {
53 | "plugins": {
54 | "autoprefixer": {}
55 | }
56 | },
57 | "browserslist": [
58 | "> 1%",
59 | "last 2 versions",
60 | "not ie <= 8"
61 | ]
62 | }
63 |
--------------------------------------------------------------------------------
/client/src/views/MapList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | location: lng = {{ lng }} lat = {{ lat }}
10 |
11 | 正在定位
12 |
13 |
14 |
15 |
16 |
59 |
60 |
--------------------------------------------------------------------------------
/client/public/css/reset.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 | /* HTML5 display-role reset for older browsers */
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, menu, nav, section {
29 | display: block;
30 | }
31 | body {
32 | line-height: 1;
33 | }
34 | ol, ul {
35 | list-style: none;
36 | }
37 | blockquote, q {
38 | quotes: none;
39 | }
40 | blockquote:before, blockquote:after,
41 | q:before, q:after {
42 | content: '';
43 | content: none;
44 | }
45 | table {
46 | border-collapse: collapse;
47 | border-spacing: 0;
48 | }
49 |
50 | .el-loading{
51 | position: absolute;
52 | z-index: 2000;
53 | background-color: rgba(255,255,255,.7);
54 | margin: 0;
55 | top: 0;
56 | right: 0;
57 | bottom: 0;
58 | left: 0;
59 | -webkit-transition: opacity .3s;
60 | transition: opacity .3s;
61 | }
62 | .el-loading-spinner{
63 | top: 50%;
64 | margin-top: -21px;
65 | width: 100%;
66 | text-align: center;
67 | position: absolute;
68 | }
69 |
--------------------------------------------------------------------------------
/client/src/views/Index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
56 |
83 |
--------------------------------------------------------------------------------
/client/src/views/information/Markdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
54 |
55 |
63 |
--------------------------------------------------------------------------------
/client/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const debug = process.env.NODE_ENV !== 'production'
3 |
4 | module.exports = {
5 | baseUrl: '/', // 根域上下文目录
6 | outputDir: 'dist', // 构建输出目录
7 | assetsDir: 'assets', // 静态资源目录 (js, css, img, fonts)
8 | lintOnSave: false, // 是否开启eslint保存检测,有效值:ture | false | 'error'
9 | runtimeCompiler: true, // 运行时版本是否需要编译
10 | transpileDependencies: [], // 默认babel-loader忽略mode_modules,这里可增加例外的依赖包名
11 | productionSourceMap: true, // 是否在构建生产包时生成 sourceMap 文件,false将提高构建速度
12 | configureWebpack: config => { // webpack配置,值位对象时会合并配置,为方法时会改写配置
13 | if (debug) { // 开发环境配置
14 | config.devtool = 'cheap-module-eval-source-map'
15 | } else { // 生产环境配置
16 | }
17 | // Object.assign(config, { // 开发生产共同配置
18 | // resolve: {
19 | // alias: {
20 | // '@': path.resolve(__dirname, './src'),
21 | // '@c': path.resolve(__dirname, './src/components'),
22 | // 'vue$': 'vue/dist/vue.esm.js'
23 | // }
24 | // }
25 | // })
26 | },
27 | chainWebpack: config => { // webpack链接API,用于生成和修改webapck配置,https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
28 | if (debug) {
29 | // 本地开发配置
30 | } else {
31 | // 生产开发配置
32 | }
33 | },
34 | parallel: require('os').cpus().length > 1, // 构建时开启多进程处理babel编译
35 | pluginOptions: { // 第三方插件配置
36 | },
37 | pwa: { // 单页插件相关配置 https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
38 | },
39 | devServer: {
40 | open: true,
41 | host: 'localhost',
42 | port: 8080,
43 | https: false,
44 | hotOnly: false,
45 | proxy: { // 配置跨域
46 | '/api': {
47 | target: 'http://localhost:5000/api/',
48 | ws: true,
49 | changOrigin: true,
50 | pathRewrite: {
51 | '^/api': ''
52 | }
53 | }
54 | },
55 | before: app => { }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/client/src/components/Menu.vue:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
44 |
95 |
--------------------------------------------------------------------------------
/yarn-error.log:
--------------------------------------------------------------------------------
1 | Arguments:
2 | C:\Program Files\nodejs\node.exe C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\bin\yarn.js install
3 |
4 | PATH:
5 | C:\Users\Administrator\bin;D:\git\Git\mingw64\bin;D:\git\Git\usr\local\bin;D:\git\Git\usr\bin;D:\git\Git\usr\bin;D:\git\Git\mingw64\bin;D:\git\Git\usr\bin;C:\Users\Administrator\bin;D:\nginx\nginx-1.15.7;D:\nvm\nvm-setup\nvm;C:\Users\Administrator\.nvm;F:\redis;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files (x86)\AMD\ATI.ACE\Core-Static;E:\mongodb\bin;D:\git\Git\cmd;D:\svn\bin;D:\nvm\nvm-setup\nvm;C:\Program Files\nodejs;D:\putty;C:\Users\Administrator\AppData\Roaming\npm;D:\前端开的工具\vscode\Microsoft VS Code\bin;D:\heroku\bin;D:\nvm\nvm-setup\nvm;C:\Program Files\nodejs;D:\git\Git\usr\bin\vendor_perl;D:\git\Git\usr\bin\core_perl
6 |
7 | Yarn version:
8 | 1.9.4
9 |
10 | Node version:
11 | 10.11.0
12 |
13 | Platform:
14 | win32 x64
15 |
16 | Trace:
17 | Error: ENOENT: no such file or directory, copyfile 'C:\Users\Administrator\AppData\Local\Yarn\Cache\v2\npm-ansi-regex-3.0.0-ed0317c322064f79466c02966bddb605ab37d998\package.json' -> 'D:\vue-list\vue-admin\node_modules\cliui\node_modules\ansi-regex\package.json'
18 |
19 | npm manifest:
20 | {
21 | "name": "api-element",
22 | "version": "1.0.0",
23 | "description": "",
24 | "main": "server.js",
25 | "scripts": {
26 | "client-install": "npm install --prefix client",
27 | "client": "npm start --prefix client",
28 | "start": "node server.js",
29 | "server": "nodemon server.js",
30 | "dev": "concurrently \"npm run server\" \"npm run client\""
31 | },
32 | "author": "",
33 | "license": "ISC",
34 | "dependencies": {
35 | "bcrypt": "^3.0.2",
36 | "body-parser": "^1.18.3",
37 | "concurrently": "^4.0.1",
38 | "express": "^4.16.4",
39 | "gravatar": "^1.6.0",
40 | "jsonwebtoken": "^8.3.0",
41 | "mongoose": "^5.3.4",
42 | "passport": "^0.4.0",
43 | "passport-jwt": "^4.0.0"
44 | }
45 | }
46 |
47 | yarn manifest:
48 | No manifest
49 |
50 | Lockfile:
51 | No lockfile
52 |
--------------------------------------------------------------------------------
/client/src/views/Investment/ChinaTabsList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{item.name}}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
67 |
68 |
73 |
--------------------------------------------------------------------------------
/client/src/views/Investment/tablist/ChinaTabsTable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
14 |
15 |
19 |
20 | {{ scope.row.provinces}}
21 |
22 |
23 |
28 |
29 | {{ scope.row.orderMoney}}
30 |
31 |
32 |
37 |
38 | {{'+' + scope.row.incomeMoney}}
39 |
40 |
41 |
45 |
46 |
47 | {{ scope.row.payType}}
48 |
49 |
50 |
51 |
56 |
57 | {{ scope.row.orderPeriod}}
58 |
59 |
60 |
65 |
66 | {{ scope.row.orderPersonConunt}}
67 |
68 |
69 |
73 |
74 | {{ scope.row.orderYearRate}}
75 |
76 |
77 |
81 |
82 | {{ scope.row.remarks}}
83 |
84 |
85 |
86 |
87 |
88 |
89 |
102 |
103 |
105 |
--------------------------------------------------------------------------------
/client/src/views/Home/HomeTop.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
+208.65
8 |
盈亏(千万)
9 |
10 |
11 |
12 |
13 |
+12.37
14 |
收益率(%)
15 |
16 |
17 |
18 |
19 |
686
20 |
潜在投资人(人)
21 |
22 |
23 |
24 |
25 |
264
26 |
意向投资人(人)
27 |
28 |
29 |
30 |
31 |
137
32 |
待审投资人(人)
33 |
34 |
35 |
36 |
37 |
100
38 |
审核中投资人(人)
39 |
40 |
41 |
42 |
43 |
86
44 |
审核通过投资人(人)
45 |
46 |
47 |
48 |
49 |
36
50 |
新增投资人(人)
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
64 |
111 |
--------------------------------------------------------------------------------
/client/src/views/Home/echarts/Stacked.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
123 |
124 |
127 |
--------------------------------------------------------------------------------
/client/src/components/UserDialong.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
40 |
41 |
42 |
43 |
44 |
87 |
89 |
--------------------------------------------------------------------------------
/client/src/components/Dialong.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 取消
38 | 提交
39 |
40 |
41 |
42 |
43 |
44 |
45 |
94 |
96 |
--------------------------------------------------------------------------------
/client/src/views/information/Clock.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
94 |
103 |
104 |
--------------------------------------------------------------------------------
/client/src/views/logo/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
75 |
76 |
--------------------------------------------------------------------------------
/routes/api/staff.js:
--------------------------------------------------------------------------------
1 | //主要用于Login登录 register 注册
2 | const express = require("express");
3 | const router = express.Router();
4 | const keys = require("../../config/keys");
5 | const Staff = require('../../models/Staff')
6 | const passport = require("passport");
7 |
8 | // $route GET api/staff/test
9 | // @desc 返回的请求的json数据
10 | // @access public
11 | router.get("/text", (req, res) => {
12 | res.json({ msg: "staff" });
13 | });
14 |
15 |
16 | // $route POST api/staff/add
17 | // @desc 添加数据内容
18 | // @access public
19 |
20 | router.post('/add',passport.authenticate('jwt', { session: false }),(req,res) => {
21 | const staffInformation = {};
22 | if(req.body.name) staffInformation.name = req.body.name;
23 | if(req.body.sex) staffInformation.sex = req.body.sex;
24 | if(req.body.state) staffInformation.state = req.body.state;
25 | if(req.body.hobby) staffInformation.hobby = req.body.hobby;
26 | if(req.body.marriage) staffInformation.marriage = req.body.marriage;
27 | if(req.body.birthday) staffInformation.birthday = req.body.birthday;
28 | if(req.body.address) staffInformation.address = req.body.address;
29 |
30 | new Staff(staffInformation).save().then(staff => {
31 | console.log(staff);
32 | res.json(staff);
33 | });
34 | })
35 |
36 | // $route GET api/staff
37 | // @desc 获取所有的数据
38 | // @access public
39 |
40 | router.get("/", passport.authenticate("jwt", { session: false }),(req,res) => {
41 | Staff.find().then(staff => {
42 | if(!staff) {
43 | return res.status(400).json("没有任何数据存在")
44 | }
45 | return res.json(staff)
46 | }).catch(err => {
47 | return res.status(404).json(err)
48 | })
49 | });
50 |
51 | // $route GET api/staff/:id
52 | // @desc 获取单个数据源数据内容
53 | // @access public
54 |
55 | router.get("/:id", passport.authenticate("jwt", { session: false }),(req,res) => {
56 | Staff.findOne({ _id: req.params.id }).then(staff =>{
57 | if(!staff) {
58 | return res.status(400).json("数据不存在")
59 | }
60 | res.json(staff)
61 | }).catch(err => {
62 | return res.status(404).json(err)
63 | })
64 | });
65 |
66 |
67 | // $route POST api/staff/edit/:id
68 | // @desc 编辑个人信息
69 | // @access public
70 |
71 | router.post("/edit/:id", passport.authenticate("jwt", { session: false }),(req,res) => {
72 |
73 | const staffInformation = {};
74 | if (req.body.name) staffInformation.name = req.body.name;
75 | if (req.body.sex) staffInformation.sex = req.body.sex;
76 | if (req.body.state) staffInformation.state = req.body.state;
77 | if (req.body.hobby) staffInformation.hobby = req.body.hobby;
78 | if (req.body.marriage) staffInformation.marriage = req.body.marriage;
79 | if (req.body.birthday) staffInformation.birthday = req.body.birthday;
80 | if (req.body.address) staffInformation.address = req.body.address;
81 |
82 | //更新数据内容
83 | Staff.findByIdAndUpdate({ _id: req.params.id }, { $set: staffInformation }, { new: true })
84 | .then(staff => {
85 | if (!staff) {
86 | return res.status(400).json("数据不存在");
87 | }
88 | res.json(staff);
89 | })
90 | .catch(err => {
91 | return res.status(404).json(err);
92 | });
93 | });
94 |
95 |
96 | // $route POST api/staff/delete/:id
97 | // @desc 删除单个信息
98 | // @access public
99 |
100 | router.delete("/delete/:id", passport.authenticate("jwt", { session: false }),(req,res) => {
101 |
102 | Staff.findByIdAndRemove({_id:req.params.id}).then(staff =>{
103 | staff.save().then(staff => {
104 | res.json(staff)
105 | })
106 | }).catch(err => {
107 | return res.status(404).json(err)
108 | })
109 |
110 | });
111 |
112 |
113 |
114 | module.exports = router;
--------------------------------------------------------------------------------
/routes/api/users.js:
--------------------------------------------------------------------------------
1 | //主要用于Login登录 register 注册
2 | const express = require("express");
3 | const router = express.Router();
4 | // const bcrypt = require("bcrypt"); //加密
5 | const bcrypt = require("bcryptjs"); //加密
6 | const User = require("../../models/User");
7 | const keys = require("../../config/keys");
8 | const gravatar = require('gravatar'); //头像
9 | const jwt = require("jsonwebtoken"); //token
10 | const passport = require("passport");
11 |
12 | // $route GET api/users/test
13 | // @desc 返回的请求的json数据
14 | // @access public
15 | router.get('/test',(req,res) => {
16 | res.json({msg:"logon users test"})
17 | })
18 |
19 | // $route POST /api/users/register
20 | // @desc 返回的请求的json数据
21 | // @access public
22 | router.post('/register', (req, res) => {
23 | // 查询数据库中是否拥有邮箱
24 | User.findOne({ email: req.body.email }).then(user => {
25 | if (user) {
26 | return res.status(400).json( '邮箱已被注册!');
27 | } else {
28 | const avatar = gravatar.url(req.body.email, {
29 | s: '200',
30 | r: 'pg',
31 | d: 'mm'
32 | });
33 |
34 | const newUser = new User({
35 | name: req.body.name,
36 | email: req.body.email,
37 | avatar,
38 | password: req.body.password,
39 | identity: req.body.identity
40 | });
41 |
42 | bcrypt.genSalt(10, function (err, salt) {
43 | bcrypt.hash(newUser.password, salt, (err, hash) => {
44 | if (err) throw err;
45 |
46 | newUser.password = hash;
47 |
48 | newUser
49 | .save()
50 | .then(user => res.json(user))
51 | .catch(err => console.log(err));
52 | });
53 | });
54 | }
55 | });
56 | });
57 |
58 | // $route POST /api/users/login
59 | // @desc 返回的请求的json数据 token jwt
60 | // @access public
61 |
62 | router.post('/login', (req, res) => {
63 |
64 | const email = req.body.email;
65 | const password = req.body.password;
66 |
67 | //查询数据库
68 | User.findOne({email:req.body.email}).then(user => {
69 | //判断用户是否存在
70 | if(!user){
71 | return res.status(404).json("用户不存在")
72 | }
73 | //密码匹配
74 | bcrypt.compare(password, user.password).then(isMath =>{
75 | if(isMath) {
76 | const rule = {
77 | id: user.id,
78 | name: user.name,
79 | avatar: user.avatar,
80 | identity: user.identity
81 | };
82 | jwt.sign(rule, keys.secretOrKey,{expiresIn:3600},(err,token) =>{
83 | if(err) throw err;
84 | res.json({
85 | success:true,
86 | token: "Bearer "+token //最后返回token值
87 | })
88 | })
89 | } else {
90 | return res.status(400).json("密码不存在")
91 | }
92 | })
93 | })
94 | })
95 |
96 | // $route GET /api/users/current
97 | // @desc 返回用户信息
98 | // @access private
99 |
100 | router.get('/current',passport.authenticate('jwt', { session: false }),
101 | (req, res) => {
102 | res.json({
103 | id: req.user.id,
104 | name: req.user.name,
105 | email: req.user.email,
106 | identity: req.user.identity
107 | });
108 | }
109 | );
110 |
111 | module.exports = router;
--------------------------------------------------------------------------------
/client/src/views/Home/echarts/Dotted.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
152 |
153 |
156 |
--------------------------------------------------------------------------------
/routes/api/profiles.js:
--------------------------------------------------------------------------------
1 | //主要用于Login登录 register 注册
2 | const express = require("express");
3 | const router = express.Router();
4 | const keys = require("../../config/keys");
5 | const Profile = require('../../models/Profile')
6 | const passport = require("passport");
7 |
8 | // $route GET api/profiles/test
9 | // @desc 返回的请求的json数据
10 | // @access public
11 | router.get("/text", (req, res) => {
12 | res.json({ msg: "profiles" });
13 | });
14 |
15 | // $route POST api/profiles/add
16 | // @desc 添加数据内容
17 | // @access public
18 |
19 | router.post('/add', passport.authenticate('jwt', { session: false }),
20 | (req, res) => {
21 | const ProfileFields = {};
22 |
23 | if(req.body.type) ProfileFields.type = req.body.type;
24 | if (req.body.describe) ProfileFields.describe = req.body.describe;
25 | if (req.body.income) ProfileFields.income = req.body.income;
26 | if (req.body.expend) ProfileFields.expend = req.body.expend;
27 | if (req.body.cash) ProfileFields.cash = req.body.cash;
28 | if (req.body.remark) ProfileFields.remark = req.body.remark;
29 |
30 | new Profile(ProfileFields).save().then(profile => {
31 | console.log(profile)
32 | res.json(profile);
33 | })
34 | }
35 | );
36 |
37 |
38 | // $route GET api/profiles
39 | // @desc 获取所有内容
40 | // @access public
41 |
42 | router.get("/", passport.authenticate("jwt", { session: false }),(req,res) => {
43 | Profile.find().then(profils => {
44 | if(!profils) {
45 | return res.status(404).json("没有任何数据存在")
46 | }
47 | res.json(profils);
48 | }).catch(err => {
49 | return res.status(404).json(err)
50 | })
51 | });
52 |
53 | // $route GET api/profiles/:id
54 | // @desc 获取所有单个数据内容
55 | // @access public
56 |
57 | router.get("/:id", passport.authenticate("jwt", { session: false }),(req,res) => {
58 | Profile.findOne({_id: req.params.id}).then(profils => {
59 | if(!profils) {
60 | return res.status(404).json("数据不存在")
61 | }
62 | res.json(profils)
63 | }).catch(err =>{
64 | return res.status(404).json(err)
65 | })
66 | });
67 |
68 | // $route POST api/profiles/edit/:id
69 | // @desc 编辑信息
70 | // @access public
71 |
72 | router.post('/edit/:id', passport.authenticate('jwt', { session: false }),
73 | (req, res) => {
74 | const ProfileFields = {};
75 |
76 | if (req.body.type) ProfileFields.type = req.body.type;
77 | if (req.body.describe) ProfileFields.describe = req.body.describe;
78 | if (req.body.income) ProfileFields.income = req.body.income;
79 | if (req.body.expend) ProfileFields.expend = req.body.expend;
80 | if (req.body.cash) ProfileFields.cash = req.body.cash;
81 | if (req.body.remark) ProfileFields.remark = req.body.remark;
82 |
83 | Profile.findByIdAndUpdate(
84 | {_id:req.params.id},
85 | { $set: ProfileFields},
86 | {new:true}
87 | ).then(profile => {
88 | if(!profile) {
89 | return res.status(404).json("此信息不存在")
90 | }
91 | res.json(profile)
92 | }).catch(err => {
93 | res.status(404).json(err)
94 | })
95 | }
96 | );
97 |
98 | // $route GET api/profiles/delete/:id
99 | // @desc 获取所有单个数据内容
100 | // @access public
101 |
102 | router.delete("/delete/:id", passport.authenticate("jwt", { session: false }), (req, res) => {
103 | Profile.findByIdAndRemove({_id:req.params.id}).then(profile =>{
104 | profile.save().then(profile => res.json(profile));
105 | }).catch(err => {
106 | return res.status(404).json(err)
107 | })
108 | });
109 |
110 | module.exports = router;
--------------------------------------------------------------------------------
/client/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 |
4 | Vue.use(Router)
5 |
6 | const router = new Router({
7 | routes: [
8 | {
9 | path: '/',
10 | redirect: 'index'
11 | },
12 | {
13 | path: '/index',
14 | name: 'Index',
15 | component: () => import('./views/Index.vue'),
16 | meta: { title: '首页' },
17 | redirect: '/home',
18 | children: [
19 | {
20 | path: '/home',
21 | name: 'home',
22 | component: () => import('./views/Home/Home'),
23 | meta: { title: '首页' }
24 | },
25 | {
26 | path: '/staff',
27 | name: 'staff',
28 | component: () => import('./views/Staff'),
29 | meta: { title: '用户信息' }
30 | },
31 | {
32 | path: '/listuser',
33 | name: 'listuser',
34 | component: () => import('./views/ListUser'),
35 | meta: { title: '信息列表' }
36 | },
37 | {
38 | path: '/fundList',
39 | name: 'fundList',
40 | component: () => import('./views/fundmanagement/FundList'),
41 | meta: { title: '资金流水' }
42 | },
43 | {
44 | path: '/payList',
45 | name: 'payList',
46 | component: () => import('./views/fundmanagement/PayList'),
47 | meta: { title: '支付单据' }
48 | },
49 | {
50 | path: '/Infoshow',
51 | name: 'Infoshow',
52 | component: () => import('./views/information/InfoShow'),
53 | meta: { title: '个人信息' }
54 | },
55 | {
56 | path: '/editor',
57 | name: 'editor',
58 | component: () => import('./views/information/Editor'),
59 | meta: { title: '富文本编辑器' }
60 | },
61 | {
62 | path: '/markdown',
63 | name: 'markdown',
64 | component: () => import('./views/information/Markdown'),
65 | meta: { title: 'Markdown编辑器' }
66 | },
67 | {
68 | path: '/showFundArticle',
69 | name: 'showFundArticle',
70 | component: () =>
71 | import('./views/information/article/ShowFundArticle'),
72 | meta: { title: '文章列表' }
73 | },
74 | {
75 | path: '/chinaTouziList',
76 | name: 'chinaTouziList',
77 | component: () => import('./views/Investment/ChinaTouziList'),
78 | meta: { title: '省份投资' }
79 | },
80 | {
81 | path: '/chinaTabsList',
82 | name: 'ChinaTabsList',
83 | component: () => import('./views/Investment/ChinaTabsList'),
84 | meta: { title: '区域投资' }
85 | },
86 | {
87 | path: '/fundPosition',
88 | name: 'fundPosition',
89 | component: () => import('./views/capitalData/FundPosition'),
90 | meta: { title: '投资分布' }
91 | },
92 | {
93 | path: '/maplist',
94 | name: 'maplist',
95 | component: () => import('./views/MapList'),
96 | meta: { title: '地图展示' }
97 | }
98 | ]
99 | },
100 | {
101 | path: '/register',
102 | name: 'register',
103 | component: () => import('./views/register/Register')
104 | },
105 | {
106 | path: '/login',
107 | name: 'login',
108 | component: () => import('./views/logo/Login')
109 | },
110 | {
111 | path: '/lock',
112 | name: 'lock',
113 | component: () => import('./views/Lock.vue')
114 | },
115 | {
116 | path: '*',
117 | name: 'Nofind',
118 | component: () => import('./views/404')
119 | }
120 | ]
121 | // mode: "history"
122 | })
123 |
124 | // 路由守卫
125 | router.beforeEach((to, from, next) => {
126 | const isLogin = !!localStorage.eleToken
127 |
128 | if (to.path === '/login' || to.path === '/register') {
129 | next()
130 | } else {
131 | isLogin ? next() : next('/login')
132 | }
133 | })
134 |
135 | export default router
136 |
--------------------------------------------------------------------------------
/client/src/common/Tags.vue:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
98 |
99 |
100 |
172 |
--------------------------------------------------------------------------------
/client/src/views/ListUser.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
14 |
15 |
19 |
20 | {{ scope.row.nickname }}
21 |
22 |
23 |
27 |
28 | {{ scope.row.touziyear }}
29 |
30 |
31 |
35 |
36 | {{ scope.row.email }}
37 |
38 |
39 |
43 |
44 |
45 | {{ scope.row.modifyTime | moment }}
46 |
47 |
48 |
51 |
52 | {{ scope.row.baseType }}
53 |
54 |
55 |
58 |
59 | {{ scope.row.changeType }}
60 |
61 |
62 |
63 |
64 |
65 |
73 |
74 |
75 |
76 |
77 |
143 |
144 |
--------------------------------------------------------------------------------
/client/src/views/register/Register.vue:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
32 |
94 |
95 |
--------------------------------------------------------------------------------
/client/src/views/Investment/ChinaTouziList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 导出excel
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{ scope.row.provinces}}
12 |
13 |
14 |
15 |
16 | {{ scope.row.orderMoney}}
17 |
18 |
19 |
20 |
21 | {{'+' + scope.row.incomeMoney}}
22 |
23 |
24 |
25 |
26 |
27 | {{ scope.row.payType}}
28 |
29 |
30 |
31 |
32 |
33 | {{ scope.row.orderPeriod}}
34 |
35 |
36 |
37 |
38 | {{ scope.row.orderPersonConunt}}
39 |
40 |
41 |
42 |
43 | {{ scope.row.orderYearRate}}
44 |
45 |
46 |
47 |
48 | {{ scope.row.remarks}}
49 |
50 |
51 |
52 |
53 | 删除
54 |
55 |
56 |
57 |
58 |
59 |
60 |
131 |
132 |
137 |
--------------------------------------------------------------------------------
/client/src/assets/js/Export2Excel.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('script-loader!file-saver');
3 | // require('script-loader!src/vendor/Blob');
4 | require('script-loader!../../assets/js/Blob');
5 | require('script-loader!xlsx/dist/xlsx.core.min');
6 |
7 | function generateArray(table) {
8 | var out = [];
9 | var rows = table.querySelectorAll('tr');
10 | var ranges = [];
11 | for (var R = 0; R < rows.length; ++R) {
12 | var outRow = [];
13 | var row = rows[R];
14 | var columns = row.querySelectorAll('td');
15 | for (var C = 0; C < columns.length; ++C) {
16 | var cell = columns[C];
17 | var colspan = cell.getAttribute('colspan');
18 | var rowspan = cell.getAttribute('rowspan');
19 | var cellValue = cell.innerText;
20 | if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
21 |
22 | //Skip ranges
23 | ranges.forEach(function (range) {
24 | if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
25 | for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
26 | }
27 | });
28 |
29 | //Handle Row Span
30 | if (rowspan || colspan) {
31 | rowspan = rowspan || 1;
32 | colspan = colspan || 1;
33 | ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
34 | }
35 | ;
36 |
37 | //Handle Value
38 | outRow.push(cellValue !== "" ? cellValue : null);
39 |
40 | //Handle Colspan
41 | if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
42 | }
43 | out.push(outRow);
44 | }
45 | return [out, ranges];
46 | };
47 |
48 | function datenum(v, date1904) {
49 | if (date1904) v += 1462;
50 | var epoch = Date.parse(v);
51 | return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
52 | }
53 |
54 | function sheet_from_array_of_arrays(data, opts) {
55 | var ws = {};
56 | var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
57 | for (var R = 0; R != data.length; ++R) {
58 | for (var C = 0; C != data[R].length; ++C) {
59 | if (range.s.r > R) range.s.r = R;
60 | if (range.s.c > C) range.s.c = C;
61 | if (range.e.r < R) range.e.r = R;
62 | if (range.e.c < C) range.e.c = C;
63 | var cell = {v: data[R][C]};
64 | if (cell.v == null) continue;
65 | var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
66 |
67 | if (typeof cell.v === 'number') cell.t = 'n';
68 | else if (typeof cell.v === 'boolean') cell.t = 'b';
69 | else if (cell.v instanceof Date) {
70 | cell.t = 'n';
71 | cell.z = XLSX.SSF._table[14];
72 | cell.v = datenum(cell.v);
73 | }
74 | else cell.t = 's';
75 |
76 | ws[cell_ref] = cell;
77 | }
78 | }
79 | if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
80 | return ws;
81 | }
82 |
83 | function Workbook() {
84 | if (!(this instanceof Workbook)) return new Workbook();
85 | this.SheetNames = [];
86 | this.Sheets = {};
87 | }
88 |
89 | function s2ab(s) {
90 | var buf = new ArrayBuffer(s.length);
91 | var view = new Uint8Array(buf);
92 | for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
93 | return buf;
94 | }
95 |
96 | export function export_table_to_excel(id) {
97 | var theTable = document.getElementById(id);
98 | console.log('a')
99 | var oo = generateArray(theTable);
100 | var ranges = oo[1];
101 |
102 | /* original data */
103 | var data = oo[0];
104 | var ws_name = "SheetJS";
105 | console.log(data);
106 |
107 | var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
108 |
109 | /* add ranges to worksheet */
110 | // ws['!cols'] = ['apple', 'banan'];
111 | ws['!merges'] = ranges;
112 |
113 | /* add worksheet to workbook */
114 | wb.SheetNames.push(ws_name);
115 | wb.Sheets[ws_name] = ws;
116 |
117 | var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
118 |
119 | saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
120 | }
121 |
122 | function formatJson(jsonData) {
123 | console.log(jsonData)
124 | }
125 |
126 | export function export_json_to_excel(th, jsonData, defaultTitle) {
127 |
128 | /* original data */
129 |
130 | var data = jsonData;
131 | data.unshift(th);
132 | var ws_name = "SheetJS";
133 |
134 | var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
135 |
136 |
137 | /* add worksheet to workbook */
138 | wb.SheetNames.push(ws_name);
139 | wb.Sheets[ws_name] = ws;
140 |
141 | var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
142 | var title = defaultTitle || '列表'
143 | saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
144 | }
145 |
--------------------------------------------------------------------------------
/client/src/components/LeftMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
155 |
218 |
219 |
--------------------------------------------------------------------------------
/client/src/views/fundmanagement/PayList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 | 筛选
15 |
16 |
17 |
18 |
19 |
22 |
25 |
26 |
31 |
32 | {{ scope.row.payNumber }}
33 |
34 |
35 |
39 |
40 | {{ scope.row.orderMoney }}
41 |
42 |
43 |
47 |
48 | +{{ scope.row.incomeMoney }}
49 |
50 |
51 |
57 |
58 |
59 | {{ scope.row.payType }}
60 |
61 |
62 |
63 |
67 |
68 |
69 | {{ scope.row.orderTime | moment}}
70 |
71 |
72 |
77 |
78 |
79 | {{ scope.row.payStatus === '0' ? "支付成功": ((scope.row.payStatus === '1' ? "待支付":"支付失败")) }}
80 |
81 |
82 |
83 |
86 |
87 | {{ scope.row.remarks }}
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
195 |
203 |
--------------------------------------------------------------------------------
/client/src/common/theme.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
132 |
133 |
142 |
--------------------------------------------------------------------------------
/client/src/views/Staff.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 添加
7 |
8 |
9 |
10 |
11 |
15 |
19 |
20 |
21 | {{ scope.row.date | moment }}
22 |
23 |
24 |
28 |
29 | {{ scope.row.name }}
30 |
31 |
32 |
36 |
37 | {{ scope.row.sex }}
38 |
39 |
40 |
44 |
45 | {{ scope.row.state }}
46 |
47 |
48 |
52 |
53 | {{ scope.row.hobby }}
54 |
55 |
56 |
60 |
61 | {{ scope.row.marriage }}
62 |
63 |
64 |
68 |
69 | {{ scope.row.birthday | moment }}
70 |
71 |
72 |
76 |
77 | {{ scope.row.address }}
78 |
79 |
80 |
81 |
82 | 编辑
85 | 删除
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
198 |
206 |
--------------------------------------------------------------------------------
/client/src/components/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
60 |
61 |
62 |
166 |
286 |
--------------------------------------------------------------------------------
/client/src/assets/js/Blob.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | /* Blob.js*/
3 |
4 | /*global self, unescape */
5 | /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
6 | plusplus: true */
7 |
8 | /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
9 |
10 | (function (view) {
11 | "use strict";
12 |
13 | view.URL = view.URL || view.webkitURL;
14 |
15 | if (view.Blob && view.URL) {
16 | try {
17 | new Blob;
18 | return;
19 | } catch (e) {
20 | }
21 | }
22 |
23 | // Internally we use a BlobBuilder implementation to base Blob off of
24 | // in order to support older browsers that only have BlobBuilder
25 | var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function (view) {
26 | var
27 | get_class = function (object) {
28 | return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
29 | }
30 | , FakeBlobBuilder = function BlobBuilder() {
31 | this.data = [];
32 | }
33 | , FakeBlob = function Blob(data, type, encoding) {
34 | this.data = data;
35 | this.size = data.length;
36 | this.type = type;
37 | this.encoding = encoding;
38 | }
39 | , FBB_proto = FakeBlobBuilder.prototype
40 | , FB_proto = FakeBlob.prototype
41 | , FileReaderSync = view.FileReaderSync
42 | , FileException = function (type) {
43 | this.code = this[this.name = type];
44 | }
45 | , file_ex_codes = (
46 | "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
47 | + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
48 | ).split(" ")
49 | , file_ex_code = file_ex_codes.length
50 | , real_URL = view.URL || view.webkitURL || view
51 | , real_create_object_URL = real_URL.createObjectURL
52 | , real_revoke_object_URL = real_URL.revokeObjectURL
53 | , URL = real_URL
54 | , btoa = view.btoa
55 | , atob = view.atob
56 |
57 | , ArrayBuffer = view.ArrayBuffer
58 | , Uint8Array = view.Uint8Array
59 |
60 | , origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
61 | ;
62 | FakeBlob.fake = FB_proto.fake = true;
63 | while (file_ex_code--) {
64 | FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
65 | }
66 | // Polyfill URL
67 | if (!real_URL.createObjectURL) {
68 | URL = view.URL = function (uri) {
69 | var
70 | uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
71 | , uri_origin
72 | ;
73 | uri_info.href = uri;
74 | if (!("origin" in uri_info)) {
75 | if (uri_info.protocol.toLowerCase() === "data:") {
76 | uri_info.origin = null;
77 | } else {
78 | uri_origin = uri.match(origin);
79 | uri_info.origin = uri_origin && uri_origin[1];
80 | }
81 | }
82 | return uri_info;
83 | };
84 | }
85 | URL.createObjectURL = function (blob) {
86 | var
87 | type = blob.type
88 | , data_URI_header
89 | ;
90 | if (type === null) {
91 | type = "application/octet-stream";
92 | }
93 | if (blob instanceof FakeBlob) {
94 | data_URI_header = "data:" + type;
95 | if (blob.encoding === "base64") {
96 | return data_URI_header + ";base64," + blob.data;
97 | } else if (blob.encoding === "URI") {
98 | return data_URI_header + "," + decodeURIComponent(blob.data);
99 | }
100 | if (btoa) {
101 | return data_URI_header + ";base64," + btoa(blob.data);
102 | } else {
103 | return data_URI_header + "," + encodeURIComponent(blob.data);
104 | }
105 | } else if (real_create_object_URL) {
106 | return real_create_object_URL.call(real_URL, blob);
107 | }
108 | };
109 | URL.revokeObjectURL = function (object_URL) {
110 | if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
111 | real_revoke_object_URL.call(real_URL, object_URL);
112 | }
113 | };
114 | FBB_proto.append = function (data/*, endings*/) {
115 | var bb = this.data;
116 | // decode data to a binary string
117 | if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
118 | var
119 | str = ""
120 | , buf = new Uint8Array(data)
121 | , i = 0
122 | , buf_len = buf.length
123 | ;
124 | for (; i < buf_len; i++) {
125 | str += String.fromCharCode(buf[i]);
126 | }
127 | bb.push(str);
128 | } else if (get_class(data) === "Blob" || get_class(data) === "File") {
129 | if (FileReaderSync) {
130 | var fr = new FileReaderSync;
131 | bb.push(fr.readAsBinaryString(data));
132 | } else {
133 | // async FileReader won't work as BlobBuilder is sync
134 | throw new FileException("NOT_READABLE_ERR");
135 | }
136 | } else if (data instanceof FakeBlob) {
137 | if (data.encoding === "base64" && atob) {
138 | bb.push(atob(data.data));
139 | } else if (data.encoding === "URI") {
140 | bb.push(decodeURIComponent(data.data));
141 | } else if (data.encoding === "raw") {
142 | bb.push(data.data);
143 | }
144 | } else {
145 | if (typeof data !== "string") {
146 | data += ""; // convert unsupported types to strings
147 | }
148 | // decode UTF-16 to binary string
149 | bb.push(unescape(encodeURIComponent(data)));
150 | }
151 | };
152 | FBB_proto.getBlob = function (type) {
153 | if (!arguments.length) {
154 | type = null;
155 | }
156 | return new FakeBlob(this.data.join(""), type, "raw");
157 | };
158 | FBB_proto.toString = function () {
159 | return "[object BlobBuilder]";
160 | };
161 | FB_proto.slice = function (start, end, type) {
162 | var args = arguments.length;
163 | if (args < 3) {
164 | type = null;
165 | }
166 | return new FakeBlob(
167 | this.data.slice(start, args > 1 ? end : this.data.length)
168 | , type
169 | , this.encoding
170 | );
171 | };
172 | FB_proto.toString = function () {
173 | return "[object Blob]";
174 | };
175 | FB_proto.close = function () {
176 | this.size = 0;
177 | delete this.data;
178 | };
179 | return FakeBlobBuilder;
180 | }(view));
181 |
182 | view.Blob = function (blobParts, options) {
183 | var type = options ? (options.type || "") : "";
184 | var builder = new BlobBuilder();
185 | if (blobParts) {
186 | for (var i = 0, len = blobParts.length; i < len; i++) {
187 | if (Uint8Array && blobParts[i] instanceof Uint8Array) {
188 | builder.append(blobParts[i].buffer);
189 | }
190 | else {
191 | builder.append(blobParts[i]);
192 | }
193 | }
194 | }
195 | var blob = builder.getBlob(type);
196 | if (!blob.slice && blob.webkitSlice) {
197 | blob.slice = blob.webkitSlice;
198 | }
199 | return blob;
200 | };
201 |
202 | var getPrototypeOf = Object.getPrototypeOf || function (object) {
203 | return object.__proto__;
204 | };
205 | view.Blob.prototype = getPrototypeOf(new view.Blob());
206 | }(
207 | typeof self !== "undefined" && self
208 | || typeof window !== "undefined" && window
209 | || this
210 | ));
211 |
--------------------------------------------------------------------------------
/client/src/views/information/InfoShow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
![]()
10 |
11 | {{users.name}}
12 | {{users.identity == 'manager' ? '管理员' : '普通员工'}}
13 |
14 |
15 |
16 | 登录地址:
17 | 郑州
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
JavaScript:
30 |
31 |
32 |
36 |
40 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
1234
60 |
用户访问量
61 |
62 |
63 |
64 |
65 |
66 |
67 |
74 |
75 |
76 |
77 |
78 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | 2019年目标
92 |
93 |
94 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | {{scope.row.title}}
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
155 |
266 |
--------------------------------------------------------------------------------
/client/src/views/fundmanagement/FundList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 | ---
12 |
16 |
17 |
18 |
19 | 查询
20 |
21 |
22 | 添加
23 |
24 |
25 |
26 |
27 |
34 |
39 |
40 |
45 |
46 |
47 | {{ scope.row.date | moment }}
48 |
49 |
50 |
54 |
55 | {{ scope.row.type}}
56 |
57 |
58 |
62 |
63 | {{ scope.row.describe }}
64 |
65 |
66 |
70 |
71 | {{ scope.row.income }}
72 |
73 |
74 |
78 |
79 | {{ scope.row.expend }}
80 |
81 |
82 |
87 |
88 | {{ scope.row.cash }}
89 |
90 |
91 |
95 |
96 | {{ scope.row.remark }}
97 |
98 |
99 |
102 |
103 | 编辑
107 | 删除
111 |
122 |
123 |
124 |
125 |
{{message}}
126 |
137 |
138 |
139 |
140 |
141 |
142 |
323 |
342 |
--------------------------------------------------------------------------------
/client/src/views/capitalData/FundPosition.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
850 |
859 |
860 |
--------------------------------------------------------------------------------