init
2
.browserslistrc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
> 1%
|
||||||
|
last 2 versions
|
||||||
7
.editorconfig
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[*.{js,jsx,ts,tsx,vue}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
max_line_length = 140
|
||||||
67
.eslintrc.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: false,
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/essential',
|
||||||
|
'@vue/airbnb',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'indent': 'off',
|
||||||
|
'no-tabs': 'off', // 禁用 no-tabs 规则
|
||||||
|
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||||
|
'array-element-newline': ['error', 'consistent'],
|
||||||
|
// 'indent': ['error',4,{ 'MemberExpression': 0, 'SwitchCase': 1 }],
|
||||||
|
'quotes': ['error', 'single'],
|
||||||
|
'comma-dangle': ['error', 'always-multiline'],
|
||||||
|
'semi': ['error', 'never'],
|
||||||
|
'object-curly-spacing': ['error', 'always'],
|
||||||
|
'max-len': ['error', 140],
|
||||||
|
'no-new': 'off',
|
||||||
|
'linebreak-style': 'off',
|
||||||
|
'import/extensions': 'off',
|
||||||
|
'eol-last': 'off',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'no-unused-vars': 'warn',
|
||||||
|
'import/no-cycle': 'off',
|
||||||
|
'arrow-parens': 'off',
|
||||||
|
'eqeqeq': 'off',
|
||||||
|
'no-param-reassign': 'off',
|
||||||
|
'import/prefer-default-export': 'off',
|
||||||
|
'no-use-before-define': 'off',
|
||||||
|
'no-continue': 'off',
|
||||||
|
'prefer-destructuring': 'off',
|
||||||
|
'no-plusplus': 'off',
|
||||||
|
'prefer-const': 'off',
|
||||||
|
'global-require': 'off',
|
||||||
|
'no-prototype-builtins': 'off',
|
||||||
|
'consistent-return': 'off',
|
||||||
|
'vue/require-component-is': 'off',
|
||||||
|
'prefer-template': 'off',
|
||||||
|
'one-var-declaration-per-line': 'off',
|
||||||
|
'one-var': 'off',
|
||||||
|
'import/named': 'off',
|
||||||
|
'object-curly-newline': 'off',
|
||||||
|
'default-case': 'off',
|
||||||
|
'import/no-dynamic-require': 'off',
|
||||||
|
'vue/no-parsing-error': [2, {
|
||||||
|
'x-invalid-end-tag': false
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
parser: 'babel-eslint',
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'**/__tests__/*.{j,t}s?(x)',
|
||||||
|
'**/tests/unit/**/*.spec.{j,t}s?(x)',
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
jest: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
21
.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 bin
|
||||||
|
|
||||||
|
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.
|
||||||
5
babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset',
|
||||||
|
],
|
||||||
|
};
|
||||||
3
jest.config.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
preset: '@vue/cli-plugin-unit-jest',
|
||||||
|
};
|
||||||
39300
package-lock.json
generated
Normal file
34
package.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "vue-admin-template",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint",
|
||||||
|
"test": "vue-cli-service test:unit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.19.0",
|
||||||
|
"core-js": "^3.31.0",
|
||||||
|
"echarts": "^6.0.0",
|
||||||
|
"element-ui": "^2.15.14",
|
||||||
|
"view-design": "^4.0.2",
|
||||||
|
"view-ui-plus": "^1.3.21",
|
||||||
|
"vue": "^2.6.10",
|
||||||
|
"vue-router": "^3.0.6",
|
||||||
|
"vuex": "^3.1.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "^4.1.0",
|
||||||
|
"@vue/cli-plugin-eslint": "^4.1.0",
|
||||||
|
"@vue/cli-plugin-unit-jest": "^4.1.0",
|
||||||
|
"@vue/cli-service": "^4.1.0",
|
||||||
|
"@vue/eslint-config-airbnb": "^4.0.0",
|
||||||
|
"@vue/test-utils": "1.0.0-beta.29",
|
||||||
|
"babel-eslint": "^10.0.3",
|
||||||
|
"eslint": "^5.16.0",
|
||||||
|
"eslint-plugin-vue": "^5.0.0",
|
||||||
|
"vue-template-compiler": "^2.6.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
17
public/index.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title>爱京科技</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but new doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
61
src/App.vue
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<router-view/>
|
||||||
|
<div class="global-loading" v-show="isShowLoading">
|
||||||
|
<Spin size="large"></Spin>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
keepAliveData: ['manage'],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState([
|
||||||
|
'isShowLoading',
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
li, ul, p, div, body, html, table {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
#app {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
/* loading */
|
||||||
|
.global-loading {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: rgba(255,255,255,.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
427
src/api/index.js
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function fetchUserData() {
|
||||||
|
return request.get('https://api.github.com/users/woai3c')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录
|
||||||
|
export function login(params) {
|
||||||
|
return request.post('/login_check', params)
|
||||||
|
}
|
||||||
|
// 修改密码
|
||||||
|
export function Modify(params) {
|
||||||
|
return request.post('/admin/update_password', params)
|
||||||
|
}
|
||||||
|
// 显示通知
|
||||||
|
export function showContent(params) {
|
||||||
|
return request.post('/user/DiscountInfo', params)
|
||||||
|
}
|
||||||
|
// 修改通知
|
||||||
|
export function EditContent(params) {
|
||||||
|
return request.post('/UpdateDiscount', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户
|
||||||
|
*/
|
||||||
|
// 用户列表
|
||||||
|
export function GetAdmin(params) {
|
||||||
|
return request.post('/admin_list', params)
|
||||||
|
}
|
||||||
|
// 查询用户
|
||||||
|
export function searchAdmin(params) {
|
||||||
|
return request.post('/admin/read', params)
|
||||||
|
}
|
||||||
|
// 编辑用户
|
||||||
|
export function editAdmin(params) {
|
||||||
|
return request.post('/admin/update', params)
|
||||||
|
}
|
||||||
|
// 用户删除
|
||||||
|
export function deleteAdmin(params) {
|
||||||
|
return request.post('/admin/delete', params)
|
||||||
|
}
|
||||||
|
// 用户新增
|
||||||
|
export function addAdmin(params) {
|
||||||
|
return request.post('/admin/save', params)
|
||||||
|
}
|
||||||
|
// 导出
|
||||||
|
export function exportAdminAll(params) {
|
||||||
|
return request.post('/admin/admin_all', params)
|
||||||
|
}
|
||||||
|
// 用户权限修改
|
||||||
|
export function PermissUpdate(params) {
|
||||||
|
return request.post('/UpdatePermission', params)
|
||||||
|
}
|
||||||
|
// 用户权限读取
|
||||||
|
export function PermissRead(params) {
|
||||||
|
return request.post('/UpdatePermission', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单
|
||||||
|
*/
|
||||||
|
// 潜江-------获取充电订单数据
|
||||||
|
export function getChargeOrder(params) {
|
||||||
|
return request.get('/getChargeOrder', { params })
|
||||||
|
}
|
||||||
|
// 潜江-------获取充值订单数据
|
||||||
|
export function getReChargeOrder(params) {
|
||||||
|
return request.get('/getRechargeOrder', { params })
|
||||||
|
}
|
||||||
|
// 获取订单信息
|
||||||
|
export function GetOrder(params) {
|
||||||
|
return request.post('/ChargeOrder/read_order', params)
|
||||||
|
}
|
||||||
|
// 获取大足地址信息
|
||||||
|
export function GetpositionData(params) {
|
||||||
|
return request.post('/ChargeOrder/StreetWithName', params)
|
||||||
|
}
|
||||||
|
// 订单号查询订单
|
||||||
|
export function GetOneOrder(params) {
|
||||||
|
return request.post('/ChargeOrder/read_order', params)
|
||||||
|
}
|
||||||
|
// 获取充电桩信息
|
||||||
|
export function GetChargeZ(params) {
|
||||||
|
return request.post('/ChargeOrder/read_equipment', params)
|
||||||
|
}
|
||||||
|
// 获取总量
|
||||||
|
export function GetTotal(params) {
|
||||||
|
return request.post('/ChargeOrder/read_total', params)
|
||||||
|
}
|
||||||
|
// 按照时间查询
|
||||||
|
export function GetTimeData(params) {
|
||||||
|
return request.post('/ChargeStation/Time_Data', params)
|
||||||
|
}
|
||||||
|
// 充值按照时间查询
|
||||||
|
export function ReGetTimeData(params) {
|
||||||
|
return request.post('/ChargeStation/Recharge_Total', params)
|
||||||
|
}
|
||||||
|
// 导出充电站信息
|
||||||
|
export function exportstationAll(params) {
|
||||||
|
return request.post('/ChargeStation/station_all', params)
|
||||||
|
}
|
||||||
|
// 导出订单
|
||||||
|
export function exportOrderAll(params) {
|
||||||
|
return request.post('/OrderExport', params)
|
||||||
|
}
|
||||||
|
// 导出充值
|
||||||
|
export function exportRecharge(params) {
|
||||||
|
return request.post('/RechargeAllExport', params)
|
||||||
|
}
|
||||||
|
// 按照范围查询
|
||||||
|
export function GetDatabyRound(params) {
|
||||||
|
return request.post('/ChargeStation/Order_Total', params)
|
||||||
|
}
|
||||||
|
// 按照范围查询
|
||||||
|
export function GetTotalround(params) {
|
||||||
|
return request.post('/ChargeStation/Time_Data_Total', params)
|
||||||
|
}
|
||||||
|
// 充值记录
|
||||||
|
export function GetRecharge(params) {
|
||||||
|
return request.post('/RechargeAll', params)
|
||||||
|
}
|
||||||
|
// 订单模糊查询
|
||||||
|
export function GetFuzzyOrder(params) {
|
||||||
|
return request.post('/FuzzyOrder', params)
|
||||||
|
}
|
||||||
|
// 订单模糊查询2
|
||||||
|
export function GetFuzzyOrder1(params) {
|
||||||
|
return request.post('/FuzzyOrder', params)
|
||||||
|
}
|
||||||
|
// 订单查询
|
||||||
|
export function GettheOrder(params) {
|
||||||
|
return request.post('/FuzzyOrder', params)
|
||||||
|
}
|
||||||
|
// /尖峰
|
||||||
|
export function Electricity(params) {
|
||||||
|
return request.post('/Electricity', params)
|
||||||
|
}
|
||||||
|
// /尖峰
|
||||||
|
export function ElectricityStation(params) {
|
||||||
|
return request.post('/Electricity', params)
|
||||||
|
}
|
||||||
|
export function FindRechargeOrder(params) {
|
||||||
|
return request.post('/FindRechargeOrder', params)
|
||||||
|
}
|
||||||
|
export function RefundQuery(params) {
|
||||||
|
return request.post('/RefundQuery', params)
|
||||||
|
}
|
||||||
|
export function RefundQuery1(params) {
|
||||||
|
return request.post('/RefundQuery', params)
|
||||||
|
}
|
||||||
|
// 退款可视化
|
||||||
|
export function RefundTotal(params) {
|
||||||
|
return request.post('/Refund_Total', params)
|
||||||
|
}
|
||||||
|
// 收支报表
|
||||||
|
export function AmountExcel(params) {
|
||||||
|
return request.post('/AmountExcel', params)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 车辆
|
||||||
|
*/
|
||||||
|
// 公交车报表
|
||||||
|
export function SearchBusMessage(params) {
|
||||||
|
return request.post('/Bus/BusOrderPark', params)
|
||||||
|
}
|
||||||
|
// 公交车总报表
|
||||||
|
export function SearchtotalBusMessage(params) {
|
||||||
|
return request.post('/Bus/SearchMessage', params)
|
||||||
|
}
|
||||||
|
// 公交车报表单个
|
||||||
|
export function SearchperBusMessage(params) {
|
||||||
|
return request.post('/Bus/SearchMessage', params)
|
||||||
|
}
|
||||||
|
// 公交车更新余额
|
||||||
|
export function ChangeSpecialUserBalance(params) {
|
||||||
|
return request.post('/Bus/ChangeSpecialUserBalance', params)
|
||||||
|
}
|
||||||
|
// 公交车汇总表
|
||||||
|
export function BusDataStatistics(params) {
|
||||||
|
return request.post('/Bus/DataStatistics', params)
|
||||||
|
}
|
||||||
|
// 展示VIN和车牌号
|
||||||
|
export function ShowVinLicense(params) {
|
||||||
|
return request.post('/Bus/ShowVinLicense', params)
|
||||||
|
}
|
||||||
|
export function ShowVinLicense1(params) {
|
||||||
|
return request.post('/Bus/ShowVinLicense', params)
|
||||||
|
}
|
||||||
|
// 绑定车辆和车牌号
|
||||||
|
export function AddVinLicense(params) {
|
||||||
|
return request.post('/Bus/AddVinLicense', params)
|
||||||
|
}
|
||||||
|
// 删除车辆和车牌号
|
||||||
|
export function DeleteVinLicense(params) {
|
||||||
|
return request.post('/Bus/DeleteVinLicense', params)
|
||||||
|
}
|
||||||
|
// 编辑车辆信息
|
||||||
|
export function UpdateVinLicense(params) {
|
||||||
|
return request.post('/Bus/UpdateVinLicense', params)
|
||||||
|
}
|
||||||
|
// 车辆列表
|
||||||
|
export function ParkNoShow(params) {
|
||||||
|
return request.post('/Bus/ParkNo', params)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* event
|
||||||
|
*/
|
||||||
|
// 活动列表
|
||||||
|
export function ShowEvent(params) {
|
||||||
|
return request.post('/ShowEvent', params)
|
||||||
|
}
|
||||||
|
// 新增列表
|
||||||
|
export function AddEvent(params) {
|
||||||
|
return request.post('/AddEvent', params)
|
||||||
|
}
|
||||||
|
// 编辑列表
|
||||||
|
export function EditEvent(params) {
|
||||||
|
return request.post('/EditEvent', params)
|
||||||
|
}
|
||||||
|
// 删除列表
|
||||||
|
export function DeleteEvent(params) {
|
||||||
|
return request.post('/DeleteEvent', params)
|
||||||
|
}
|
||||||
|
// 监控列表
|
||||||
|
export function MonitorList(params) {
|
||||||
|
return request.post('/MonitorList', params)
|
||||||
|
}
|
||||||
|
// 查询监控
|
||||||
|
export function ParkNoShowEvent(params) {
|
||||||
|
return request.post('/MonitorId', params)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* position
|
||||||
|
*/
|
||||||
|
// 获取位置信息
|
||||||
|
export function GetPosition(params) {
|
||||||
|
return request.post('/ChargeStation/index', params)
|
||||||
|
}
|
||||||
|
// 搜索充电站
|
||||||
|
export function searchStation(params) {
|
||||||
|
return request.post('/ChargeStation/index', params)
|
||||||
|
}
|
||||||
|
// 修改定价
|
||||||
|
export function ChangeCharge(params) {
|
||||||
|
return request.post('/StationPriceUpdate', params)
|
||||||
|
}
|
||||||
|
// 导出
|
||||||
|
export function exportAll(params) {
|
||||||
|
return request.post('/ChargeStation/station_all', params)
|
||||||
|
}
|
||||||
|
// 故障
|
||||||
|
export function Getwarning(params) {
|
||||||
|
return request.post('/ChargeStation/FaultInfo', params)
|
||||||
|
}
|
||||||
|
// 获取电站价格
|
||||||
|
export function GetPerPrice(params) {
|
||||||
|
return request.post('/StationPrice', params)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* table
|
||||||
|
*/
|
||||||
|
// 用户列表
|
||||||
|
export function GetUser(params) {
|
||||||
|
return request.post('/UserList', params)
|
||||||
|
}
|
||||||
|
// 查询用户
|
||||||
|
export function searchUser(params) {
|
||||||
|
return request.post('/user/read', params)
|
||||||
|
}
|
||||||
|
// 编辑用户
|
||||||
|
export function editUser(params) {
|
||||||
|
return request.post('/user/update', params)
|
||||||
|
}
|
||||||
|
// 用户删除
|
||||||
|
export function deleteUser(params) {
|
||||||
|
return request.post('/DeleteEnterpriseUser', params)
|
||||||
|
}
|
||||||
|
// 导出
|
||||||
|
export function exportUserAll(params) {
|
||||||
|
return request.post('/user/user_all', params)
|
||||||
|
}
|
||||||
|
// 查订单
|
||||||
|
export function OrderQuery(params) {
|
||||||
|
return request.post('/OrderQuery', params)
|
||||||
|
}
|
||||||
|
// 获取企业用户组
|
||||||
|
export function GetGroup(params) {
|
||||||
|
return request.post('/GetGroup', params)
|
||||||
|
}
|
||||||
|
// 获取企业列表
|
||||||
|
export function getEnterpriseList(params) {
|
||||||
|
return request.get('/enterprise/index', { params })
|
||||||
|
}
|
||||||
|
// 企业列表-添加
|
||||||
|
export function getEnterpriseSave(params) {
|
||||||
|
return request.post('/enterprise/save', params)
|
||||||
|
}
|
||||||
|
// 企业列表-只读
|
||||||
|
export function getEnterpriseRead(params) {
|
||||||
|
return request.post('/enterprise/read', params)
|
||||||
|
}
|
||||||
|
// 企业列表-编辑
|
||||||
|
export function getEnterpriseUpdate(params) {
|
||||||
|
return request.post('/enterprise/update', params)
|
||||||
|
}
|
||||||
|
// 企业列表-删除
|
||||||
|
export function getEnterpriseDelete(params) {
|
||||||
|
return request.post('/enterprise/delete', params)
|
||||||
|
}
|
||||||
|
// 获取企业用户列表
|
||||||
|
export function getEnterpriseUserList(params) {
|
||||||
|
return request.get('/enterpriseUser/index', { params })
|
||||||
|
}
|
||||||
|
// 企业用户-添加
|
||||||
|
export function getEnterpriseUserSave(params) {
|
||||||
|
return request.post('/enterpriseUser/save', params)
|
||||||
|
}
|
||||||
|
// 企业用户-只读
|
||||||
|
export function getEnterpriseUserRead(params) {
|
||||||
|
return request.post('/enterpriseUser/read', params)
|
||||||
|
}
|
||||||
|
// 企业用户-编辑
|
||||||
|
export function getEnterpriseUserUpdate(params) {
|
||||||
|
return request.post('/enterpriseUser/update', params)
|
||||||
|
}
|
||||||
|
// 企业用户-删除
|
||||||
|
export function getEnterpriseUserDelete(params) {
|
||||||
|
return request.post('/enterpriseUser/delete', params)
|
||||||
|
}
|
||||||
|
// 获取企业车辆列表
|
||||||
|
export function getEnterpriseCarList(params) {
|
||||||
|
return request.get('/enterpriseCar/index', { params })
|
||||||
|
}
|
||||||
|
// 企业车辆-添加
|
||||||
|
export function getEnterpriseCarSave(params) {
|
||||||
|
return request.post('/enterpriseCar/save', params)
|
||||||
|
}
|
||||||
|
// 企业车辆-只读
|
||||||
|
export function getEnterpriseCarRead(params) {
|
||||||
|
return request.post('/enterpriseCar/read', params)
|
||||||
|
}
|
||||||
|
// 企业车辆-编辑
|
||||||
|
export function getEnterpriseCarUpdate(params) {
|
||||||
|
return request.post('/enterpriseCar/update', params)
|
||||||
|
}
|
||||||
|
// 企业车辆-删除
|
||||||
|
export function getEnterpriseCarDelete(params) {
|
||||||
|
return request.post('/enterpriseCar/delete', params)
|
||||||
|
}
|
||||||
|
// 企业组搜索用户
|
||||||
|
export function NormalSearch(params) {
|
||||||
|
return request.post('/NormalSearch', params)
|
||||||
|
}
|
||||||
|
// 查询企业
|
||||||
|
export function EnterpriseGroupList(params) {
|
||||||
|
return request.post('/EnterpriseGroupAdd', params)
|
||||||
|
}
|
||||||
|
// 新增企业成员
|
||||||
|
export function NormalToEnterprise(params) {
|
||||||
|
return request.post('/NormalToEnterprise', params)
|
||||||
|
}
|
||||||
|
// 删除组
|
||||||
|
export function DeleteEnterpriseGroup(params) {
|
||||||
|
return request.post('/DeleteEnterpriseGroup', params)
|
||||||
|
}
|
||||||
|
// 电话查找
|
||||||
|
export function PhoneSearch(params) {
|
||||||
|
return request.post('/PhoneSearch', params)
|
||||||
|
}
|
||||||
|
// 修改组
|
||||||
|
export function EnterpriserUserEdit(params) {
|
||||||
|
return request.post('/EnterpriserUserEdit', params)
|
||||||
|
}
|
||||||
|
// 查询服务费
|
||||||
|
export function ShowServiceFee(params) {
|
||||||
|
return request.post('/ShowServiceFee', params)
|
||||||
|
}
|
||||||
|
// 更新服务费
|
||||||
|
export function UpdateServiceFee(params) {
|
||||||
|
return request.post('/UpdateServiceFee', params)
|
||||||
|
}
|
||||||
|
// 查看该用户充值详情
|
||||||
|
export function RechargeMessage(params) {
|
||||||
|
return request.post('/RechargeMessage', params)
|
||||||
|
}
|
||||||
|
// 查看该用户提现详情
|
||||||
|
export function RefundMessage(params) {
|
||||||
|
return request.post('/RefundMessage', params)
|
||||||
|
}
|
||||||
|
// 显示预约时间
|
||||||
|
export function ShowAppointmentTime(params) {
|
||||||
|
return request.post('/ShowAppointmentTime', params)
|
||||||
|
}
|
||||||
|
// 修改预约时间
|
||||||
|
export function ModifyAppointmentTime(params) {
|
||||||
|
return request.post('/ModifyAppointmentTime', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 活动
|
||||||
|
export function getEventList(params) {
|
||||||
|
return request.post('/eventList2', params)
|
||||||
|
}
|
||||||
|
// 退款订单
|
||||||
|
export function getRefundOrder(params) {
|
||||||
|
return request.get('/getRefundOrder', { params })
|
||||||
|
}
|
||||||
|
// 权限
|
||||||
|
export function GetRole(params) {
|
||||||
|
return request.get('/getRoleList', { params })
|
||||||
|
}
|
||||||
|
// 权限
|
||||||
|
export function getMenuList(params) {
|
||||||
|
return request.get('/getMenuList', { params })
|
||||||
|
}
|
||||||
|
// 日志
|
||||||
|
export function getLogList(params) {
|
||||||
|
return request.get('/getLogList', { params })
|
||||||
|
}
|
||||||
|
// 运营数据
|
||||||
|
export function getYunYingData(params) {
|
||||||
|
return request.get('/getYunYingData', { params })
|
||||||
|
}
|
||||||
|
// 财务数据
|
||||||
|
export function getCaiWuData(params) {
|
||||||
|
return request.get('/getCaiWuData', { params })
|
||||||
|
}
|
||||||
BIN
src/assets/imgs/404.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
src/assets/imgs/bg00.jpg
Normal file
|
After Width: | Height: | Size: 951 KiB |
BIN
src/assets/imgs/bg01.jpg
Normal file
|
After Width: | Height: | Size: 331 KiB |
BIN
src/assets/imgs/bg02.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
src/assets/imgs/bg03.jpg
Normal file
|
After Width: | Height: | Size: 343 KiB |
BIN
src/assets/imgs/bg04.jpg
Normal file
|
After Width: | Height: | Size: 308 KiB |
BIN
src/assets/imgs/bg05.jpg
Normal file
|
After Width: | Height: | Size: 405 KiB |
BIN
src/assets/imgs/bg06.jpg
Normal file
|
After Width: | Height: | Size: 405 KiB |
BIN
src/assets/imgs/logo.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
src/assets/imgs/user.jpg
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
49
src/components/404.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<img :src="img">
|
||||||
|
<p>未到找指定页面</p>
|
||||||
|
<Button class="back" @click="back">返回页面</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'error',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
img: require('../assets/imgs/404.jpg'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
back() {
|
||||||
|
this.$router.back()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #f8f5ec;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 40px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 100px;
|
||||||
|
}
|
||||||
|
.back {
|
||||||
|
position: absolute;
|
||||||
|
top: 40px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
702
src/components/Index.vue
Normal file
@@ -0,0 +1,702 @@
|
|||||||
|
<template>
|
||||||
|
<div class="index-vue">
|
||||||
|
<!-- 侧边栏 -->
|
||||||
|
<aside :class="asideClassName">
|
||||||
|
<!-- logo -->
|
||||||
|
<div class="logo-c">
|
||||||
|
<img src="../assets/imgs/logo.png" alt="logo" class="logo">
|
||||||
|
<span v-show="isShowAsideTitle">潜江市充电桩</span>
|
||||||
|
</div>
|
||||||
|
<!-- 菜单栏 -->
|
||||||
|
<Menu class="menu" ref="asideMenu" theme="dark" width="100%" @on-select="selectMenuCallback"
|
||||||
|
accordion :open-names="openMenus" :active-name="currentPage" @on-open-change="menuChange">
|
||||||
|
<!-- 动态菜单 -->
|
||||||
|
<div v-for="(item, index) in menuItems" :key="index">
|
||||||
|
<Submenu :class="isShowAsideTitle? '' : 'shrink'" v-if="item.children" :name="index">
|
||||||
|
<template slot="title">
|
||||||
|
<Icon :size="item.size" :type="item.type"/>
|
||||||
|
<span v-show="isShowAsideTitle">{{item.text}}</span>
|
||||||
|
</template>
|
||||||
|
<div v-for="(subItem, i) in item.children" :key="index + i">
|
||||||
|
<Submenu :class="isShowAsideTitle? '' : 'shrink'" v-if="subItem.children" :name="index + '-' + i">
|
||||||
|
<template slot="title">
|
||||||
|
<Icon :size="subItem.size" :type="subItem.type"/>
|
||||||
|
<span v-show="isShowAsideTitle">{{subItem.text}}</span>
|
||||||
|
</template>
|
||||||
|
<template v-for="(threeItem, k) in subItem.children">
|
||||||
|
<a href="https://www.baidu.com" target="_blank" :key="index + i + k" v-if="threeItem.isExternal">
|
||||||
|
<MenuItem :class="isShowAsideTitle? '' : 'shrink'" class="menu-level-3"
|
||||||
|
:name="'external-link-' + index + i + k">
|
||||||
|
<template v-if="!threeItem.hidden">
|
||||||
|
<a :href="threeItem.url" target="_blank" class="external">
|
||||||
|
<Icon :size="threeItem.size" :type="threeItem.type"/>
|
||||||
|
<span v-show="isShowAsideTitle">{{threeItem.text}}</span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</MenuItem>
|
||||||
|
</a>
|
||||||
|
<MenuItem v-else :class="isShowAsideTitle? '' : 'shrink'" class="menu-level-3"
|
||||||
|
:name="threeItem.name" :key="index + i + k">
|
||||||
|
<template v-if="!threeItem.hidden">
|
||||||
|
<Icon :size="threeItem.size" :type="threeItem.type"/>
|
||||||
|
<span v-show="isShowAsideTitle">{{threeItem.text}}</span>
|
||||||
|
</template>
|
||||||
|
</MenuItem>
|
||||||
|
</template>
|
||||||
|
</Submenu>
|
||||||
|
<template v-else-if="!subItem.hidden">
|
||||||
|
<a :href="subItem.url" v-if="subItem.isExternal" target="_blank" class="external">
|
||||||
|
<MenuItem :class="isShowAsideTitle? '' : 'shrink'"
|
||||||
|
:name="'external-link-' + index + '-' + i">
|
||||||
|
<Icon :size="subItem.size" :type="subItem.type"/>
|
||||||
|
<span v-show="isShowAsideTitle">{{subItem.text}}</span>
|
||||||
|
</MenuItem>
|
||||||
|
</a>
|
||||||
|
<MenuItem v-else :class="isShowAsideTitle? '' : 'shrink'" :name="subItem.name">
|
||||||
|
<Icon :size="subItem.size" :type="subItem.type"/>
|
||||||
|
<span v-show="isShowAsideTitle">{{subItem.text}}</span>
|
||||||
|
</MenuItem>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</Submenu>
|
||||||
|
<template v-else-if="!item.hidden">
|
||||||
|
<a :href="item.url" v-if="item.isExternal" target="_blank" class="external">
|
||||||
|
<MenuItem :class="isShowAsideTitle? '' : 'shrink'" :name="'external-link-' + index">
|
||||||
|
<Icon :size="item.size" :type="item.type"/>
|
||||||
|
<span v-show="isShowAsideTitle">{{item.text}}</span>
|
||||||
|
</MenuItem>
|
||||||
|
</a>
|
||||||
|
<MenuItem v-else :class="isShowAsideTitle? '' : 'shrink'" :name="item.name">
|
||||||
|
<Icon :size="item.size" :type="item.type" />
|
||||||
|
<span v-show="isShowAsideTitle">{{item.text}}</span>
|
||||||
|
</MenuItem>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</Menu>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<!-- 右侧部分 -->
|
||||||
|
<section class="sec-right">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<div class="top-c">
|
||||||
|
<header>
|
||||||
|
<div class="h-left">
|
||||||
|
<div class="pointer" @click="isShrinkAside" title="收缩/展开">
|
||||||
|
<Icon type="ios-apps" />
|
||||||
|
</div>
|
||||||
|
<!-- 面包屑功能 -->
|
||||||
|
<p class="crumbs">{{crumbs}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="h-right">
|
||||||
|
<!-- 消息 -->
|
||||||
|
<div class="notice-c" @click="info" title="查看新消息">
|
||||||
|
<div :class="{newMsg: hasNewMsg}"></div>
|
||||||
|
<Icon type="ios-notifications-outline" />
|
||||||
|
</div>
|
||||||
|
<!-- 用户头像 -->
|
||||||
|
<div class="user-img-c">
|
||||||
|
<img :src="userImg">
|
||||||
|
</div>
|
||||||
|
<!-- 下拉菜单 -->
|
||||||
|
<Dropdown trigger="click" @on-click="userOperate" @on-visible-change="showArrow">
|
||||||
|
<div class="pointer">
|
||||||
|
<span>{{userName}}</span>
|
||||||
|
<Icon v-show="arrowDown" type="md-arrow-dropdown"/>
|
||||||
|
<Icon v-show="arrowUp" type="md-arrow-dropup"/>
|
||||||
|
</div>
|
||||||
|
<DropdownMenu slot="list">
|
||||||
|
<!-- name标识符 -->
|
||||||
|
<DropdownItem name="1">修改密码</DropdownItem>
|
||||||
|
<DropdownItem name="2">基本资料</DropdownItem>
|
||||||
|
<DropdownItem divided name="3">退出登陆</DropdownItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- 标签栏 -->
|
||||||
|
<div class="div-tags">
|
||||||
|
<ul class="ul-c">
|
||||||
|
<li v-for="(item, index) in tagsArry" :key="index" :class="{active: isActive(item.name)}" @click="activeTag(index)">
|
||||||
|
<a class="li-a">
|
||||||
|
{{item.text}}
|
||||||
|
</a>
|
||||||
|
<Icon size="16" @click="closeTag(index)" type="md-close" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- 标签栏相关功能 -->
|
||||||
|
<div class="div-icons">
|
||||||
|
<div class="refresh-c" @click="reloadPage" title="刷新当前标签页">
|
||||||
|
<Icon type="md-refresh" />
|
||||||
|
</div>
|
||||||
|
<div class="tag-options" title="关闭标签">
|
||||||
|
<Dropdown trigger="click" @on-click="closeTags">
|
||||||
|
<Icon type="ios-options" />
|
||||||
|
<DropdownMenu slot="list">
|
||||||
|
<DropdownItem name="1">关闭其他标签</DropdownItem>
|
||||||
|
<DropdownItem name="2">关闭所有标签</DropdownItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 页面主体 -->
|
||||||
|
<div class="main-content">
|
||||||
|
<div class="view-c">
|
||||||
|
<keep-alive :include="keepAliveData">
|
||||||
|
<!-- 子页面 -->
|
||||||
|
<router-view v-if="isShowRouter"/>
|
||||||
|
</keep-alive>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { resetTokenAndClearUser } from '../utils'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'index',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 用于储存页面路径
|
||||||
|
paths: {},
|
||||||
|
// 当前显示页面
|
||||||
|
currentPage: '',
|
||||||
|
openMenus: [], // 要打开的菜单名字 name属性
|
||||||
|
menuCache: [], // 缓存已经打开的菜单
|
||||||
|
hasNewMsg: true, // 是否有新消息
|
||||||
|
isShowRouter: true,
|
||||||
|
msgNum: '10', // 新消息条数
|
||||||
|
// 标签栏 标签标题 路由名称
|
||||||
|
// 数据格式 {text: '首页', name: 'home'}
|
||||||
|
// 用于缓存打开的路由 在标签栏上展示
|
||||||
|
tagsArry: [],
|
||||||
|
arrowUp: false, // 用户详情向上箭头
|
||||||
|
arrowDown: true, // 用户详情向下箭头
|
||||||
|
isShowAsideTitle: true, // 是否展示侧边栏内容
|
||||||
|
main: null, // 页面主要内容区域
|
||||||
|
asideClassName: 'aside-big', // 控制侧边栏宽度变化
|
||||||
|
asideArrowIcons: [], // 缓存侧边栏箭头图标 收缩时用
|
||||||
|
// 面包屑
|
||||||
|
crumbs: '主页',
|
||||||
|
userName: '',
|
||||||
|
userImg: '',
|
||||||
|
// 主页路由名称
|
||||||
|
home: 'home',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 第一个标签
|
||||||
|
const name = this.$route.name
|
||||||
|
this.currentPage = name
|
||||||
|
this.tagsArry.push({
|
||||||
|
text: this.nameToTitle[name],
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 根据路由打开对应的菜单栏
|
||||||
|
this.openMenus = this.getMenus(name)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.asideMenu.updateOpened()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 设置用户信息
|
||||||
|
this.userName = localStorage.getItem('userName')
|
||||||
|
this.userImg = localStorage.getItem('userImg')
|
||||||
|
|
||||||
|
this.main = document.querySelector('.sec-right')
|
||||||
|
this.asideArrowIcons = document.querySelectorAll('aside .ivu-icon-ios-arrow-down')
|
||||||
|
|
||||||
|
// 监听窗口大小 自动收缩侧边栏
|
||||||
|
this.monitorWindowSize()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(to) {
|
||||||
|
const name = to.name
|
||||||
|
this.currentPage = name
|
||||||
|
if (name == 'error') {
|
||||||
|
this.crumbs = '404'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.keepAliveData.includes(name)) {
|
||||||
|
// 如果标签超过8个 则将第一个标签删除
|
||||||
|
if (this.tagsArry.length == 8) {
|
||||||
|
this.tagsArry.shift()
|
||||||
|
}
|
||||||
|
this.tagsArry.push({ name, text: this.nameToTitle[name] })
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.crumbs = this.paths[name]
|
||||||
|
}, 0)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 菜单栏
|
||||||
|
menuItems() {
|
||||||
|
return this.$store.state.menuItems
|
||||||
|
},
|
||||||
|
// 需要缓存的路由
|
||||||
|
keepAliveData() {
|
||||||
|
return this.tagsArry.map(item => item.name)
|
||||||
|
},
|
||||||
|
// 由于iView的导航菜单比较坑 只能设定一个name参数
|
||||||
|
// 所以需要在这定义组件名称和标签栏标题的映射表 有多少个页面就有多少个映射条数
|
||||||
|
nameToTitle() {
|
||||||
|
const obj = {}
|
||||||
|
this.menuItems.forEach(e => {
|
||||||
|
this.processNameToTitle(obj, e)
|
||||||
|
})
|
||||||
|
|
||||||
|
return obj
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getMenus(name) {
|
||||||
|
let menus
|
||||||
|
const tagTitle = this.nameToTitle[name]
|
||||||
|
for (let i = 0, l = this.menuItems.length; i < l; i++) {
|
||||||
|
const item = this.menuItems[i]
|
||||||
|
menus = []
|
||||||
|
menus[0] = i
|
||||||
|
if (item.text == tagTitle) {
|
||||||
|
return menus
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.children) {
|
||||||
|
for (let j = 0, ll = item.children.length; j < ll; j++) {
|
||||||
|
const child = item.children[j]
|
||||||
|
menus[1] = i + '-' + j
|
||||||
|
menus.length = 2
|
||||||
|
if (child.text == tagTitle) {
|
||||||
|
return menus
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.children) {
|
||||||
|
for (let k = 0, lll = child.children.length; k < lll; k++) {
|
||||||
|
const grandson = child.children[k]
|
||||||
|
menus[2] = i + '-' + j + '-' + k
|
||||||
|
if (grandson.text == tagTitle) {
|
||||||
|
return menus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
monitorWindowSize() {
|
||||||
|
let w = document.documentElement.clientWidth || document.body.clientWidth
|
||||||
|
if (w < 1300) {
|
||||||
|
this.shrinkAside()
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onresize = () => {
|
||||||
|
// 可视窗口宽度太小 自动收缩侧边栏
|
||||||
|
if (w < 1300 && this.isShowAsideTitle
|
||||||
|
&& w > (document.documentElement.clientWidth || document.body.clientWidth)) {
|
||||||
|
this.shrinkAside()
|
||||||
|
}
|
||||||
|
|
||||||
|
w = document.documentElement.clientWidth || document.body.clientWidth
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 判断当前标签页是否激活状态
|
||||||
|
isActive(name) {
|
||||||
|
return this.$route.name === name
|
||||||
|
},
|
||||||
|
// 跳转页面 路由名称和参数
|
||||||
|
gotoPage(name, params) {
|
||||||
|
this.currentPage = name
|
||||||
|
this.crumbs = this.paths[name]
|
||||||
|
this.$router.push({ name, params })
|
||||||
|
|
||||||
|
if (!this.keepAliveData.includes(name)) {
|
||||||
|
// 如果标签超过8个 则将第一个标签删除
|
||||||
|
if (this.tagsArry.length == 8) {
|
||||||
|
this.tagsArry.shift()
|
||||||
|
}
|
||||||
|
this.tagsArry.push({ name, text: this.nameToTitle[name] })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 选择菜单回调函数
|
||||||
|
selectMenuCallback(name) {
|
||||||
|
if (name.includes('external-link')) return
|
||||||
|
this.gotoPage(name)
|
||||||
|
this.expandAside()
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isShowAsideTitle = true
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
|
// 用户操作
|
||||||
|
userOperate(name) {
|
||||||
|
switch (name) {
|
||||||
|
case '1':
|
||||||
|
// 修改密码
|
||||||
|
this.gotoPage('password')
|
||||||
|
break
|
||||||
|
case '2':
|
||||||
|
// 基本资料
|
||||||
|
this.gotoPage('userinfo')
|
||||||
|
break
|
||||||
|
case '3':
|
||||||
|
resetTokenAndClearUser()
|
||||||
|
this.$router.push({ name: 'login' })
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 控制用户三角箭头显示状态
|
||||||
|
showArrow(flag) {
|
||||||
|
this.arrowUp = flag
|
||||||
|
this.arrowDown = !flag
|
||||||
|
},
|
||||||
|
// 判断
|
||||||
|
isShrinkAside() {
|
||||||
|
if (this.isShowAsideTitle) {
|
||||||
|
this.shrinkAside()
|
||||||
|
} else {
|
||||||
|
this.expandAside()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 收缩
|
||||||
|
shrinkAside() {
|
||||||
|
for (let i = 0, len = this.asideArrowIcons.length; i < len; i++) {
|
||||||
|
this.asideArrowIcons[i].style.display = 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isShowAsideTitle = false
|
||||||
|
this.openMenus = []
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.asideMenu) {
|
||||||
|
this.$refs.asideMenu.updateOpened()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.asideClassName = ''
|
||||||
|
this.main.style.marginLeft = '90px'
|
||||||
|
}, 0)
|
||||||
|
},
|
||||||
|
// 展开
|
||||||
|
expandAside() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isShowAsideTitle = true
|
||||||
|
for (let i = 0, len = this.asideArrowIcons.length; i < len; i++) {
|
||||||
|
this.asideArrowIcons[i].style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.openMenus = this.menuCache
|
||||||
|
if (this.$refs.asideMenu) {
|
||||||
|
this.$refs.asideMenu.updateOpened()
|
||||||
|
}
|
||||||
|
}, 200)
|
||||||
|
this.asideClassName = 'aside-big'
|
||||||
|
this.main.style.marginLeft = '220px'
|
||||||
|
},
|
||||||
|
// 刷新当前标签页
|
||||||
|
reloadPage() {
|
||||||
|
let name = this.$route.name
|
||||||
|
let index = this.keepAliveData.indexOf(name)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.tagsArry.length) {
|
||||||
|
this.isShowRouter = false
|
||||||
|
this.tagsArry.splice(index, 1)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.tagsArry.splice(index, 0, { name, text: this.nameToTitle[name] })
|
||||||
|
this.gotoPage(name)
|
||||||
|
this.isShowRouter = true
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.isShowRouter = false
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.tagsArry.push({ name, text: this.nameToTitle[name] })
|
||||||
|
this.gotoPage(name)
|
||||||
|
this.isShowRouter = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 关闭单个标签
|
||||||
|
closeTag(i) {
|
||||||
|
let name = this.tagsArry[i].name
|
||||||
|
this.tagsArry.splice(i, 1)
|
||||||
|
window.event.stopPropagation()
|
||||||
|
// 如果关闭的是当前标签 则激活前一个标签
|
||||||
|
// 如果关闭的是第一个标签 则激活后一个标签
|
||||||
|
if (this.tagsArry.length) {
|
||||||
|
if (this.isActive(name)) {
|
||||||
|
if (i != 0) {
|
||||||
|
this.gotoPage(this.tagsArry[i - 1].name)
|
||||||
|
} else {
|
||||||
|
this.gotoPage(this.tagsArry[i].name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (name != this.home) {
|
||||||
|
// 如果没有标签则跳往首页
|
||||||
|
this.gotoPage(this.home)
|
||||||
|
} else {
|
||||||
|
this.reloadPage()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 根据路由名称关闭页面
|
||||||
|
closeName(name) {
|
||||||
|
for (let i = 0, len = this.tagsArry.length; i < len; i++) {
|
||||||
|
if (this.tagsArry[i].name == name) {
|
||||||
|
this.closeTag(i)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 批量关闭标签
|
||||||
|
closeTags(flag) {
|
||||||
|
if (flag == 1) {
|
||||||
|
// 关闭其他标签
|
||||||
|
this.tagsArry = []
|
||||||
|
this.gotoPage(this.$route.name)
|
||||||
|
} else {
|
||||||
|
// 关闭所有标签
|
||||||
|
this.tagsArry = []
|
||||||
|
this.gotoPage(this.home)
|
||||||
|
this.reloadPage()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 激活标签
|
||||||
|
activeTag(i) {
|
||||||
|
this.gotoPage(this.tagsArry[i].name)
|
||||||
|
},
|
||||||
|
// 消息通知
|
||||||
|
info() {
|
||||||
|
const self = this
|
||||||
|
this.$Notice.info({
|
||||||
|
title: `您有${this.msgNum}条消息`,
|
||||||
|
render(h) {
|
||||||
|
return h('Button', {
|
||||||
|
attrs: {
|
||||||
|
type: 'info',
|
||||||
|
size: 'small',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click() {
|
||||||
|
// 点击查看跳转到消息页
|
||||||
|
self.gotoPage('msg')
|
||||||
|
self.hasNewMsg = false
|
||||||
|
self.msgNum = 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, [
|
||||||
|
'点击查看',
|
||||||
|
])
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 菜单栏改变事件
|
||||||
|
menuChange(data) {
|
||||||
|
this.menuCache = data
|
||||||
|
},
|
||||||
|
processNameToTitle(obj, data, text) {
|
||||||
|
if (data.name) {
|
||||||
|
obj[data.name] = data.text
|
||||||
|
this.paths[data.name] = text ? `${text} / ${data.text}` : data.text
|
||||||
|
}
|
||||||
|
if (data.children) {
|
||||||
|
data.children.forEach(e => {
|
||||||
|
this.processNameToTitle(obj, e, text ? `${text} / ${data.text}` : data.text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.index-vue {
|
||||||
|
height: 100%;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
/* 侧边栏 */
|
||||||
|
aside {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 90px;
|
||||||
|
background: #20222A;
|
||||||
|
height: 100%;
|
||||||
|
transition: width .3s;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.logo-c {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: rgba(255,255,255,.8);
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 20px 0;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
width: 40px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.aside-big {
|
||||||
|
width: 220px;
|
||||||
|
}
|
||||||
|
/* 主体页面 */
|
||||||
|
.sec-right {
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 220px;
|
||||||
|
transition: margin-left .3s;
|
||||||
|
overflow: hidden;;
|
||||||
|
background: #f3f7fd;
|
||||||
|
}
|
||||||
|
/* 主体页面头部 */
|
||||||
|
header {
|
||||||
|
height: 50px;
|
||||||
|
border-bottom: none;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-right: 40px;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
header .ivu-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
.refresh-c {
|
||||||
|
margin: 0 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.h-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.h-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.user-img-c img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.notice-c {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.newMsg {
|
||||||
|
position: absolute;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #FF5722;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.user-img-c {
|
||||||
|
width: 34px;
|
||||||
|
height: 34px;
|
||||||
|
background: #ddd;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 40px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.tag-options {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.div-tags {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
.div-icons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
height: 34px;
|
||||||
|
width: 160px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
/* 标签栏 */
|
||||||
|
.ul-c {
|
||||||
|
height: 34px;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
width: calc(100% - 160px);
|
||||||
|
}
|
||||||
|
.ul-c li {
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 3px 5px 2px 3px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #666;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
.li-a {
|
||||||
|
max-width: 80px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.ul-c .ivu-icon {
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
background: #409eff;
|
||||||
|
border: 1px solid #409eff;
|
||||||
|
}
|
||||||
|
.active a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.active .ivu-icon {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
/* 主要内容区域 */
|
||||||
|
.main-content {
|
||||||
|
height: calc(100% - 88px);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.view-c {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.crumbs {
|
||||||
|
margin-left: 10px;
|
||||||
|
color: #97a8be;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.menu-level-3 .ivu-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.shrink {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.external {
|
||||||
|
color: rgba(255,255,255,.7);
|
||||||
|
}
|
||||||
|
.external > i {
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
167
src/components/Login.vue
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
<template>
|
||||||
|
<div class="login-vue" :style="bg">
|
||||||
|
<div class="container">
|
||||||
|
<p class="title">高新投绿源</p>
|
||||||
|
<div class="input-c">
|
||||||
|
<Input prefix="ios-contact" v-model="account" placeholder="用户名" clearable />
|
||||||
|
<p class="error">{{ accountError }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="input-c">
|
||||||
|
<Input type="password" v-model="pwd" prefix="md-lock" placeholder="密码" clearable
|
||||||
|
@keyup.enter.native="submit" />
|
||||||
|
<p class="error">{{ pwdError }}</p>
|
||||||
|
</div>
|
||||||
|
<Button :loading="isShowLoading" class="submit" type="primary" @click="submit">登陆</Button>
|
||||||
|
<!-- <p class="account"><span @click="register">注册账号</span> | <span @click="forgetPwd">忘记密码</span></p> -->
|
||||||
|
<p>@重庆爱京数字科技有限公司</p>
|
||||||
|
<div>
|
||||||
|
<a href=" " rel="noreferrer" target="_blank">渝公网安备50011502001173号</a >
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { login } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'login',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
account: '',
|
||||||
|
pwd: '',
|
||||||
|
accountError: '',
|
||||||
|
pwdError: '',
|
||||||
|
isShowLoading: false,
|
||||||
|
bg: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.bg.backgroundImage = 'url(' + require('../assets/imgs/bg0' + new Date().getDay() + '.jpg') + ')'
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route: {
|
||||||
|
handler(route) {
|
||||||
|
this.redirect = route.query && route.query.redirect
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
register() {
|
||||||
|
|
||||||
|
},
|
||||||
|
forgetPwd() {
|
||||||
|
|
||||||
|
},
|
||||||
|
async submit() {
|
||||||
|
this.accountError = ''
|
||||||
|
this.pwdError = ''
|
||||||
|
if (this.account == '') {
|
||||||
|
this.accountError = '请输入用户名'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.pwd == '') {
|
||||||
|
this.pwdError = '请输入密码'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await login({ username: this.account, password: this.pwd }).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
localStorage.setItem('permissions', res.permissions)
|
||||||
|
localStorage.setItem('authority', res.authority)
|
||||||
|
localStorage.setItem('adminId', res.adminId)
|
||||||
|
localStorage.setItem('token', res.token)
|
||||||
|
this.$router.push({ path: this.redirect || '/' })
|
||||||
|
} else {
|
||||||
|
this.$Message.error(res.message[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.login-vue {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .container {
|
||||||
|
background: rgba(255, 255, 255, .5);
|
||||||
|
width: 300px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .ivu-input {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #fff;
|
||||||
|
outline: #fff;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue ::-webkit-input-placeholder {
|
||||||
|
/* WebKit, Blink, Edge */
|
||||||
|
color: rgba(255, 255, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue :-moz-placeholder {
|
||||||
|
/* Mozilla Firefox 4 to 18 */
|
||||||
|
color: rgba(255, 255, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue ::-moz-placeholder {
|
||||||
|
/* Mozilla Firefox 19+ */
|
||||||
|
color: rgba(255, 255, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue :-ms-input-placeholder {
|
||||||
|
/* Internet Explorer 10-11 */
|
||||||
|
color: rgba(255, 255, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .title {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .input-c {
|
||||||
|
margin: auto;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .error {
|
||||||
|
color: red;
|
||||||
|
text-align: left;
|
||||||
|
margin: 5px auto;
|
||||||
|
font-size: 12px;
|
||||||
|
padding-left: 30px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .submit {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .account {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .account span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .ivu-icon {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-vue .ivu-icon-ios-close-circle {
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
20
src/main.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
import ViewUI from 'view-design'
|
||||||
|
import App from './App'
|
||||||
|
import store from './store'
|
||||||
|
import router from './router'
|
||||||
|
import 'view-design/dist/styles/iview.css'
|
||||||
|
import './permission'
|
||||||
|
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
Vue.use(ViewUI)
|
||||||
|
|
||||||
|
Vue.prototype.$axios = axios
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
router,
|
||||||
|
store,
|
||||||
|
render: h => h(App),
|
||||||
|
})
|
||||||
44
src/permission.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { LoadingBar } from 'view-design'
|
||||||
|
import router from './router'
|
||||||
|
import store from './store'
|
||||||
|
import createRoutes from '@/utils/createRoutes'
|
||||||
|
import { getDocumentTitle, resetTokenAndClearUser } from './utils'
|
||||||
|
|
||||||
|
// 是否有菜单数据
|
||||||
|
let hasMenus = false
|
||||||
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
document.title = getDocumentTitle(to.meta.title)
|
||||||
|
LoadingBar.start()
|
||||||
|
if (localStorage.getItem('token')) {
|
||||||
|
if (to.path === '/login') {
|
||||||
|
next({ path: '/' })
|
||||||
|
} else if (hasMenus) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// 这里可以用 await 配合请求后台数据来生成路由
|
||||||
|
// const data = await axios.get('xxx')
|
||||||
|
// const routes = createRoutes(data)
|
||||||
|
const routes = createRoutes(store.state.menuItems)
|
||||||
|
// 动态添加路由
|
||||||
|
router.addRoutes(routes)
|
||||||
|
hasMenus = true
|
||||||
|
next({ path: to.path || '/' })
|
||||||
|
} catch (error) {
|
||||||
|
resetTokenAndClearUser()
|
||||||
|
next(`/login?redirect=${to.path}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasMenus = false
|
||||||
|
if (to.path === '/login') {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
next(`/login?redirect=${to.path}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.afterEach(() => {
|
||||||
|
LoadingBar.finish()
|
||||||
|
})
|
||||||
290
src/router/index.js
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Router from 'vue-router'
|
||||||
|
|
||||||
|
Vue.use(Router)
|
||||||
|
|
||||||
|
const commonRoutes = [{
|
||||||
|
path: '/login',
|
||||||
|
name: 'login',
|
||||||
|
meta: {
|
||||||
|
title: '登录',
|
||||||
|
},
|
||||||
|
component: () => import('../components/Login.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/other', // 点击侧边栏跳到一个单独的路由页面,需要定义,层级和其他顶级路由一样
|
||||||
|
name: 'other',
|
||||||
|
meta: {
|
||||||
|
title: '单独的路由',
|
||||||
|
},
|
||||||
|
component: () => import('../views/Other.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/404',
|
||||||
|
name: '404',
|
||||||
|
meta: {
|
||||||
|
title: '404',
|
||||||
|
},
|
||||||
|
component: () => import('../components/404.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
redirect: '/charging_station',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// 本地所有的页面 需要配合后台返回的数据生成页面
|
||||||
|
export const asyncRoutes = {
|
||||||
|
// 充电桩
|
||||||
|
charging_station: {
|
||||||
|
path: 'charging_station',
|
||||||
|
name: 'charging_station',
|
||||||
|
meta: {
|
||||||
|
title: '站点管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/charging_pile/Station.vue'),
|
||||||
|
},
|
||||||
|
charging_pile: {
|
||||||
|
path: 'charging_pile',
|
||||||
|
name: 'charging_pile',
|
||||||
|
meta: {
|
||||||
|
title: '充电桩管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/charging_pile/Pile.vue'),
|
||||||
|
},
|
||||||
|
charging_price: {
|
||||||
|
path: 'charging_price',
|
||||||
|
name: 'charging_price',
|
||||||
|
meta: {
|
||||||
|
title: '电价管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/charging_pile/Price.vue'),
|
||||||
|
},
|
||||||
|
charging_fault: {
|
||||||
|
path: 'charging_fault',
|
||||||
|
name: 'charging_fault',
|
||||||
|
meta: {
|
||||||
|
title: '故障运维',
|
||||||
|
},
|
||||||
|
component: () => import('../views/charging_pile/Fault.vue'),
|
||||||
|
},
|
||||||
|
// 客户
|
||||||
|
corporate_client: {
|
||||||
|
path: 'corporate_client',
|
||||||
|
name: 'corporate_client',
|
||||||
|
meta: {
|
||||||
|
title: '企业客户',
|
||||||
|
},
|
||||||
|
component: () => import('../views/customer_center/CorporateClient.vue'),
|
||||||
|
},
|
||||||
|
wx_user: {
|
||||||
|
path: 'wx_user',
|
||||||
|
name: 'wx_user',
|
||||||
|
meta: {
|
||||||
|
title: '用户管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/customer_center/WxUser.vue'),
|
||||||
|
},
|
||||||
|
// 运营中心
|
||||||
|
activity: {
|
||||||
|
path: 'activity',
|
||||||
|
name: 'activity',
|
||||||
|
meta: {
|
||||||
|
title: '活动发布',
|
||||||
|
},
|
||||||
|
component: () => import('../views/operations_center/activity.vue'),
|
||||||
|
},
|
||||||
|
coupon: {
|
||||||
|
path: 'coupon',
|
||||||
|
name: 'coupon',
|
||||||
|
meta: {
|
||||||
|
title: '优惠券',
|
||||||
|
},
|
||||||
|
component: () => import('../views/operations_center/coupon.vue'),
|
||||||
|
},
|
||||||
|
user_vip: {
|
||||||
|
path: 'user_vip',
|
||||||
|
name: 'user_vip',
|
||||||
|
meta: {
|
||||||
|
title: '会员',
|
||||||
|
},
|
||||||
|
component: () => import('../views/operations_center/user_vip.vue'),
|
||||||
|
},
|
||||||
|
invoice: {
|
||||||
|
path: 'invoice',
|
||||||
|
name: 'invoice',
|
||||||
|
meta: {
|
||||||
|
title: '发票管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/operations_center/invoice.vue'),
|
||||||
|
},
|
||||||
|
// 订单
|
||||||
|
charge_order: {
|
||||||
|
path: 'charge_order',
|
||||||
|
name: 'charge_order',
|
||||||
|
meta: {
|
||||||
|
title: '充电订单',
|
||||||
|
},
|
||||||
|
component: () => import('../views/order/charge_order.vue'),
|
||||||
|
},
|
||||||
|
recharge_order: {
|
||||||
|
path: 'recharge_order',
|
||||||
|
name: 'recharge_order',
|
||||||
|
meta: {
|
||||||
|
title: '充值订单',
|
||||||
|
},
|
||||||
|
component: () => import('../views/order/recharge_order.vue'),
|
||||||
|
},
|
||||||
|
refund_order: {
|
||||||
|
path: 'refund_order',
|
||||||
|
name: 'refund_order',
|
||||||
|
meta: {
|
||||||
|
title: '充电退款订单',
|
||||||
|
},
|
||||||
|
component: () => import('../views/order/refund_order.vue'),
|
||||||
|
},
|
||||||
|
order_total: {
|
||||||
|
path: 'order_total',
|
||||||
|
name: 'order_total',
|
||||||
|
meta: {
|
||||||
|
title: '订单统计',
|
||||||
|
},
|
||||||
|
component: () => import('../views/order/order_total.vue'),
|
||||||
|
},
|
||||||
|
// 数据中心
|
||||||
|
yunying_reports: {
|
||||||
|
path: 'yunying_reports',
|
||||||
|
name: 'yunying_reports',
|
||||||
|
meta: {
|
||||||
|
title: '运营报表',
|
||||||
|
},
|
||||||
|
component: () => import('../views/reports/yunying_reports.vue'),
|
||||||
|
},
|
||||||
|
caiwu_reports: {
|
||||||
|
path: 'caiwu_reports',
|
||||||
|
name: 'caiwu_reports',
|
||||||
|
meta: {
|
||||||
|
title: '财务报表',
|
||||||
|
},
|
||||||
|
component: () => import('../views/reports/caiwu_reports.vue'),
|
||||||
|
},
|
||||||
|
yunwei_reports: {
|
||||||
|
path: 'yunwei_reports',
|
||||||
|
name: 'yunwei_reports',
|
||||||
|
meta: {
|
||||||
|
title: '运维报表',
|
||||||
|
},
|
||||||
|
component: () => import('../views/reports/yunwei_reports.vue'),
|
||||||
|
},
|
||||||
|
// 系统配置
|
||||||
|
system: {
|
||||||
|
path: 'system',
|
||||||
|
name: 'system',
|
||||||
|
meta: {
|
||||||
|
title: '参数设置',
|
||||||
|
},
|
||||||
|
component: () => import('../views/system/system.vue'),
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
path: 'admin',
|
||||||
|
name: 'admin',
|
||||||
|
meta: {
|
||||||
|
title: '系统用户',
|
||||||
|
},
|
||||||
|
component: () => import('../views/system/admin.vue'),
|
||||||
|
},
|
||||||
|
auth: {
|
||||||
|
path: 'auth',
|
||||||
|
name: 'auth',
|
||||||
|
meta: {
|
||||||
|
title: '权限管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/system/auth.vue'),
|
||||||
|
},
|
||||||
|
log: {
|
||||||
|
path: 'log',
|
||||||
|
name: 'log',
|
||||||
|
meta: {
|
||||||
|
title: '日志管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/system/log.vue'),
|
||||||
|
},
|
||||||
|
// 报表分析
|
||||||
|
rate: {
|
||||||
|
path: 'rate',
|
||||||
|
name: 'rate',
|
||||||
|
meta: {
|
||||||
|
title: '日志管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/reports/rate.vue'),
|
||||||
|
},
|
||||||
|
backup_and_repair: {
|
||||||
|
path: 'backup_and_repair',
|
||||||
|
name: 'backup_and_repair',
|
||||||
|
meta: {
|
||||||
|
title: '日志管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/reports/backup_and_repair.vue'),
|
||||||
|
},
|
||||||
|
activation: {
|
||||||
|
path: 'activation',
|
||||||
|
name: 'activation',
|
||||||
|
meta: {
|
||||||
|
title: '日志管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/reports/activation.vue'),
|
||||||
|
},
|
||||||
|
income_analysis: {
|
||||||
|
path: 'income_analysis',
|
||||||
|
name: 'income_analysis',
|
||||||
|
meta: {
|
||||||
|
title: '日志管理',
|
||||||
|
},
|
||||||
|
component: () => import('../views/reports/income_analysis.vue'),
|
||||||
|
},
|
||||||
|
t1: {
|
||||||
|
path: 't1',
|
||||||
|
name: 't1',
|
||||||
|
meta: {
|
||||||
|
title: '表格',
|
||||||
|
},
|
||||||
|
component: () => import('../views/T1.vue'),
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
path: 'password',
|
||||||
|
name: 'password',
|
||||||
|
meta: {
|
||||||
|
title: '修改密码',
|
||||||
|
},
|
||||||
|
component: () => import('../views/Password.vue'),
|
||||||
|
},
|
||||||
|
msg: {
|
||||||
|
path: 'msg',
|
||||||
|
name: 'msg',
|
||||||
|
meta: {
|
||||||
|
title: '通知消息',
|
||||||
|
},
|
||||||
|
component: () => import('../views/Msg.vue'),
|
||||||
|
},
|
||||||
|
userinfo: {
|
||||||
|
path: 'userinfo',
|
||||||
|
name: 'userinfo',
|
||||||
|
meta: {
|
||||||
|
title: '用户信息',
|
||||||
|
},
|
||||||
|
component: () => import('../views/UserInfo.vue'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const createRouter = () => new Router({
|
||||||
|
routes: commonRoutes,
|
||||||
|
})
|
||||||
|
|
||||||
|
const router = createRouter()
|
||||||
|
|
||||||
|
export function resetRouter() {
|
||||||
|
const newRouter = createRouter()
|
||||||
|
router.matcher = newRouter.matcher
|
||||||
|
}
|
||||||
|
|
||||||
|
export default router
|
||||||
252
src/store/index.js
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
const store = new Vuex.Store({
|
||||||
|
state: {
|
||||||
|
isShowLoading: false, // 全局 loading
|
||||||
|
// 左侧菜单栏数据
|
||||||
|
menuItems: [{
|
||||||
|
text: '充电桩管理',
|
||||||
|
type: 'ios-paper',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'msg',
|
||||||
|
text: '文档',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'charging_station',
|
||||||
|
text: '站点管理',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
name: 'charging_pile',
|
||||||
|
text: '充电桩管理',
|
||||||
|
// url: 'https://www.baidu.com',
|
||||||
|
// isExternal: true, // 外链 跳到一个外部的 URL 页面
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '电价管理',
|
||||||
|
name: 'charging_price',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '故障运维',
|
||||||
|
name: 'charging_fault',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-home', // icon类型
|
||||||
|
text: '客户中心', // 文本内容
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'corporate_client',
|
||||||
|
text: '企业客户',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
name: 'wx_user',
|
||||||
|
text: '用户管理',
|
||||||
|
// url: 'https://www.baidu.com',
|
||||||
|
// isExternal: true, // 外链 跳到一个外部的 URL 页面
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '钱包账户',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '车辆管理',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'ios-egg-outline', // icon类型
|
||||||
|
text: '运营中心', // 点击侧边栏跳到一个单独的路由页面,需要提前在 router.js 定义
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'activity',
|
||||||
|
text: '活动发布',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
name: 'coupon',
|
||||||
|
text: '优惠券',
|
||||||
|
// url: 'https://www.baidu.com',
|
||||||
|
// isExternal: true, // 外链 跳到一个外部的 URL 页面
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '会员',
|
||||||
|
name: 'user_vip',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '发票管理',
|
||||||
|
name: 'invoice',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
text: '订单管理',
|
||||||
|
// url: 'https://www.baidu.com',
|
||||||
|
// isExternal: true, // 外链 跳到一个外部的 URL 页面
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'charge_order',
|
||||||
|
text: '充电订单',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
name: 'recharge_order',
|
||||||
|
text: '充值订单',
|
||||||
|
// url: 'https://www.baidu.com',
|
||||||
|
// isExternal: true, // 外链 跳到一个外部的 URL 页面
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '充电退款订单',
|
||||||
|
name: 'refund_order',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '订单统计',
|
||||||
|
name: 'order_total',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '数据中心',
|
||||||
|
type: 'ios-paper',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'yunying_reports',
|
||||||
|
text: '运营报表',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
name: 'caiwu_reports',
|
||||||
|
text: '财务报表',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '运维报表',
|
||||||
|
name: 'yunwei_reports',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '系统设置',
|
||||||
|
type: 'ios-paper',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'system',
|
||||||
|
text: '参数设置',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
name: 'admin',
|
||||||
|
text: '系统用户',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '权限管理',
|
||||||
|
name: 'auth',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '日志管理',
|
||||||
|
name: 'log',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '报表分析',
|
||||||
|
type: 'ios-paper',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'rate',
|
||||||
|
text: '充电桩使用率',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'backup_and_repair',
|
||||||
|
text: '数据备份与修复',
|
||||||
|
// hidden 属性 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
// hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18, // icon大小
|
||||||
|
type: 'md-arrow-forward', // icon类型
|
||||||
|
name: 'activation',
|
||||||
|
text: '用户活跃度',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
text: '收入分析',
|
||||||
|
name: 'income_analysis',
|
||||||
|
type: 'ios-paper',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setMenus(state, items) {
|
||||||
|
state.menuItems = [...items]
|
||||||
|
},
|
||||||
|
setLoading(state, isShowLoading) {
|
||||||
|
state.isShowLoading = isShowLoading
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default store
|
||||||
34
src/utils/createRoutes.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { asyncRoutes } from '@/router'
|
||||||
|
|
||||||
|
// 将菜单信息转成对应的路由信息 动态添加
|
||||||
|
export default function createRoutes(data) {
|
||||||
|
const result = []
|
||||||
|
const children = []
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
path: '/',
|
||||||
|
component: () => import('../components/Index.vue'),
|
||||||
|
children,
|
||||||
|
})
|
||||||
|
|
||||||
|
data.forEach(item => {
|
||||||
|
generateRoutes(children, item)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 最后添加404页面 否则会在登陆成功后跳到404页面
|
||||||
|
result.push(
|
||||||
|
{ path: '*', redirect: '/404' },
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateRoutes(children, item) {
|
||||||
|
if (item.name) {
|
||||||
|
if (asyncRoutes[item.name]) children.push(asyncRoutes[item.name])
|
||||||
|
} else if (item.children) {
|
||||||
|
item.children.forEach(e => {
|
||||||
|
generateRoutes(children, e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/utils/index.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { resetRouter } from '@/router'
|
||||||
|
|
||||||
|
export function resetTokenAndClearUser() {
|
||||||
|
// 退出登陆 清除用户资料
|
||||||
|
localStorage.setItem('token', '')
|
||||||
|
localStorage.setItem('userImg', '')
|
||||||
|
localStorage.setItem('userName', '')
|
||||||
|
// 重设路由
|
||||||
|
resetRouter()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultDocumentTitle = '爱京科技'
|
||||||
|
export function getDocumentTitle(pageTitle) {
|
||||||
|
if (pageTitle) return `${defaultDocumentTitle} - ${pageTitle}`
|
||||||
|
return `${defaultDocumentTitle}`
|
||||||
|
}
|
||||||
19
src/utils/loading.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import store from '@/store'
|
||||||
|
|
||||||
|
let loadingCounter = 0
|
||||||
|
|
||||||
|
export function showLoading() {
|
||||||
|
if (loadingCounter === 0) {
|
||||||
|
store.commit('setLoading', true)
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingCounter++
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeLoading() {
|
||||||
|
loadingCounter--
|
||||||
|
if (loadingCounter <= 0) {
|
||||||
|
loadingCounter = 0
|
||||||
|
store.commit('setLoading', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/utils/request.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
import { Message } from 'view-design'
|
||||||
|
import router from '@/router'
|
||||||
|
import { showLoading, closeLoading } from '@/utils/loading'
|
||||||
|
import { resetTokenAndClearUser } from '@/utils'
|
||||||
|
|
||||||
|
const service = axios.create({
|
||||||
|
baseURL: '/chargingapi/',
|
||||||
|
timeout: 60000,
|
||||||
|
})
|
||||||
|
|
||||||
|
service.interceptors.request.use(config => {
|
||||||
|
showLoading()
|
||||||
|
if (localStorage.getItem('token')) {
|
||||||
|
config.headers.Authorization = localStorage.getItem('token')
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
}, (error) => Promise.reject(error))
|
||||||
|
|
||||||
|
service.interceptors.response.use(response => {
|
||||||
|
closeLoading()
|
||||||
|
const res = response.data
|
||||||
|
// 这里是接口处理的一个示范,可以根据自己的项目需求更改
|
||||||
|
// 错误处理
|
||||||
|
if (res.code != 0 && res.msg) {
|
||||||
|
Message.error({
|
||||||
|
content: res.msg,
|
||||||
|
})
|
||||||
|
|
||||||
|
// token 无效,清空路由,退出登录
|
||||||
|
if (res.code == 2) {
|
||||||
|
resetTokenAndClearUser()
|
||||||
|
router.push('login')
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject()
|
||||||
|
}
|
||||||
|
// 如果接口正常,直接返回数据
|
||||||
|
return res
|
||||||
|
}, (error) => {
|
||||||
|
closeLoading()
|
||||||
|
if (error.name == 'Error') {
|
||||||
|
Message.error({
|
||||||
|
content: error.msg,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Message.error({
|
||||||
|
content: error.response.data.data || error.message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default service
|
||||||
41
src/views/Home.vue
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div class="home-container">
|
||||||
|
<div class="home-content">
|
||||||
|
<Button @click="getUserData">ajax 测试</Button>
|
||||||
|
|
||||||
|
<Input :rows="30" style="margin-top: 20px" v-model="userInfo" type="textarea" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { fetchUserData } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'home',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userInfo: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getUserData() {
|
||||||
|
fetchUserData().then(res => {
|
||||||
|
this.userInfo = JSON.stringify(res, null, 4)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.home-container {
|
||||||
|
padding: 10px;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
.home-content {
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
86
src/views/Msg.vue
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div>按钮</div>
|
||||||
|
<Space direction="vertical">
|
||||||
|
<Space wrap>
|
||||||
|
<Button>Default</Button>
|
||||||
|
<Button type="primary">Primary</Button>
|
||||||
|
<Button type="dashed">Dashed</Button>
|
||||||
|
<Button type="text">Text</Button>
|
||||||
|
</Space>
|
||||||
|
<Space wrap>
|
||||||
|
<Button type="info">Info</Button>
|
||||||
|
<Button type="success">Success</Button>
|
||||||
|
<Button type="warning">Warning</Button>
|
||||||
|
<Button type="error">Error</Button>
|
||||||
|
</Space>
|
||||||
|
</Space>
|
||||||
|
<div>图标</div>
|
||||||
|
<Icon type="ios-checkmark" />
|
||||||
|
<div>
|
||||||
|
<Title>h1. View Design</Title>
|
||||||
|
<Title :level="2">h2. View Design</Title>
|
||||||
|
<Title :level="3">h3. View Design</Title>
|
||||||
|
<Title :level="4">h4. View Design</Title>
|
||||||
|
<Title :level="5">h5. View Design</Title>
|
||||||
|
</div>
|
||||||
|
<div>分页</div>
|
||||||
|
<Table border :columns="columns" :data="data"></Table>
|
||||||
|
<Page :total="100" show-sizer />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'msg',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: 'Name',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Age',
|
||||||
|
key: 'age',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Address',
|
||||||
|
key: 'address',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
23
src/views/Other.vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
单独的路由
|
||||||
|
<div>
|
||||||
|
<Button @click="reback" type="primary" style="margin-left: 100px">返回</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'other',
|
||||||
|
methods: {
|
||||||
|
reback() {
|
||||||
|
this.$router.back()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
21
src/views/Password.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
修改密码
|
||||||
|
<input type="text">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'password',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
284
src/views/T1.vue
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
<template>
|
||||||
|
<div style="padding: 10px">
|
||||||
|
<div style="background: #fff; border-radius: 8px; padding: 20px;">
|
||||||
|
<div class="query-c">
|
||||||
|
查询:
|
||||||
|
<Input search placeholder="请输入查询内容" style="width: auto" />
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<Table max-height="670" border stripe :columns="columns1" :data="data1"></Table>
|
||||||
|
<br>
|
||||||
|
<Page :total="100" show-sizer show-elevator/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 't1',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
columns1: [
|
||||||
|
{
|
||||||
|
title: 'Name',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Age',
|
||||||
|
key: 'age',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Address',
|
||||||
|
key: 'address',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data1: [
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 20,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'John Brown',
|
||||||
|
age: 18,
|
||||||
|
address: 'New York No. 1 Lake Park',
|
||||||
|
date: '2016-10-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jim Green',
|
||||||
|
age: 24,
|
||||||
|
address: 'London No. 1 Lake Park',
|
||||||
|
date: '2016-10-01',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Joe Black',
|
||||||
|
age: 30,
|
||||||
|
address: 'Sydney No. 1 Lake Park',
|
||||||
|
date: '2016-10-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Jon Snow',
|
||||||
|
age: 26,
|
||||||
|
address: 'Ottawa No. 2 Lake Park',
|
||||||
|
date: '2016-10-04',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
22
src/views/UserInfo.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
基本资料
|
||||||
|
<input type="text">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'userinfo',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
261
src/views/charging_pile/Fault.vue
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="充电桩名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="Common Modal dialog box title" :mask-closable="false" @on-ok="ok"
|
||||||
|
@on-cancel="cancel">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="Name" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="Enter your name" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="E-mail" prop="mail">
|
||||||
|
<Input v-model="formValidate.mail" placeholder="Enter your e-mail" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="City" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Date">
|
||||||
|
<Row>
|
||||||
|
<Col span="11">
|
||||||
|
<DatePicker type="date" placeholder="Select date" v-model="formValidate.date"></DatePicker>
|
||||||
|
</Col>
|
||||||
|
<Col span="2" style="text-align: center">-</Col>
|
||||||
|
<Col span="11">
|
||||||
|
<TimePicker type="time" placeholder="Select time" v-model="formValidate.time"></TimePicker>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Gender" prop="gender">
|
||||||
|
<RadioGroup v-model="formValidate.gender">
|
||||||
|
<Radio label="male">Male</Radio>
|
||||||
|
<Radio label="female">Female</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Hobby" prop="interest">
|
||||||
|
<CheckboxGroup v-model="formValidate.interest">
|
||||||
|
<Checkbox label="Eat"></Checkbox>
|
||||||
|
<Checkbox label="Sleep"></Checkbox>
|
||||||
|
<Checkbox label="Run"></Checkbox>
|
||||||
|
<Checkbox label="Movie"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Desc" prop="desc">
|
||||||
|
<Input v-model="formValidate.desc" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="Enter something..." />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit2('formValidate')">Submit</Button>
|
||||||
|
<Button @click="handleReset('formValidate')" style="margin-left: 8px">Reset</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { GetChargeZ } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '站点名称',
|
||||||
|
key: 'charge_station_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电桩编号',
|
||||||
|
key: 'ConnectorID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电桩类型',
|
||||||
|
key: 'EquipmentType',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
mail: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
|
interest: [],
|
||||||
|
date: '',
|
||||||
|
time: '',
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: 'The name cannot be empty', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
mail: [
|
||||||
|
{ required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: 'Incorrect email format', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
city: [
|
||||||
|
{ required: true, message: 'Please select the city', trigger: 'change' },
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{ required: true, message: 'Please select gender', trigger: 'change' },
|
||||||
|
],
|
||||||
|
interest: [
|
||||||
|
{ required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
|
||||||
|
{ type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' },
|
||||||
|
],
|
||||||
|
date: [
|
||||||
|
{ required: true, type: 'date', message: 'Please select the date', trigger: 'change' },
|
||||||
|
],
|
||||||
|
time: [
|
||||||
|
{ required: true, type: 'string', message: 'Please select time', trigger: 'change' },
|
||||||
|
],
|
||||||
|
desc: [
|
||||||
|
{ required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
|
||||||
|
{ type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await GetChargeZ({ page: 1, status: 'fault' }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
265
src/views/charging_pile/Pile.vue
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="充电桩名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="Common Modal dialog box title" :mask-closable="false" @on-ok="ok"
|
||||||
|
@on-cancel="cancel">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="Name" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="Enter your name" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="E-mail" prop="mail">
|
||||||
|
<Input v-model="formValidate.mail" placeholder="Enter your e-mail" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="City" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Date">
|
||||||
|
<Row>
|
||||||
|
<Col span="11">
|
||||||
|
<DatePicker type="date" placeholder="Select date" v-model="formValidate.date"></DatePicker>
|
||||||
|
</Col>
|
||||||
|
<Col span="2" style="text-align: center">-</Col>
|
||||||
|
<Col span="11">
|
||||||
|
<TimePicker type="time" placeholder="Select time" v-model="formValidate.time"></TimePicker>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Gender" prop="gender">
|
||||||
|
<RadioGroup v-model="formValidate.gender">
|
||||||
|
<Radio label="male">Male</Radio>
|
||||||
|
<Radio label="female">Female</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Hobby" prop="interest">
|
||||||
|
<CheckboxGroup v-model="formValidate.interest">
|
||||||
|
<Checkbox label="Eat"></Checkbox>
|
||||||
|
<Checkbox label="Sleep"></Checkbox>
|
||||||
|
<Checkbox label="Run"></Checkbox>
|
||||||
|
<Checkbox label="Movie"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Desc" prop="desc">
|
||||||
|
<Input v-model="formValidate.desc" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="Enter something..." />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit2('formValidate')">Submit</Button>
|
||||||
|
<Button @click="handleReset('formValidate')" style="margin-left: 8px">Reset</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { GetChargeZ } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '站点名称',
|
||||||
|
key: 'charge_station_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电桩编号',
|
||||||
|
key: 'ConnectorID',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电桩状态',
|
||||||
|
key: 'status_text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '位号',
|
||||||
|
key: 'no',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
mail: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
|
interest: [],
|
||||||
|
date: '',
|
||||||
|
time: '',
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: 'The name cannot be empty', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
mail: [
|
||||||
|
{ required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: 'Incorrect email format', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
city: [
|
||||||
|
{ required: true, message: 'Please select the city', trigger: 'change' },
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{ required: true, message: 'Please select gender', trigger: 'change' },
|
||||||
|
],
|
||||||
|
interest: [
|
||||||
|
{ required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
|
||||||
|
{ type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' },
|
||||||
|
],
|
||||||
|
date: [
|
||||||
|
{ required: true, type: 'date', message: 'Please select the date', trigger: 'change' },
|
||||||
|
],
|
||||||
|
time: [
|
||||||
|
{ required: true, type: 'string', message: 'Please select time', trigger: 'change' },
|
||||||
|
],
|
||||||
|
desc: [
|
||||||
|
{ required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
|
||||||
|
{ type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await GetChargeZ({ page: 1 }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
262
src/views/charging_pile/Price.vue
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="站点名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="Common Modal dialog box title" :mask-closable="false" @on-ok="ok"
|
||||||
|
@on-cancel="cancel">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="Name" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="Enter your name" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="E-mail" prop="mail">
|
||||||
|
<Input v-model="formValidate.mail" placeholder="Enter your e-mail" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="City" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Date">
|
||||||
|
<Row>
|
||||||
|
<Col span="11">
|
||||||
|
<DatePicker type="date" placeholder="Select date" v-model="formValidate.date"></DatePicker>
|
||||||
|
</Col>
|
||||||
|
<Col span="2" style="text-align: center">-</Col>
|
||||||
|
<Col span="11">
|
||||||
|
<TimePicker type="time" placeholder="Select time" v-model="formValidate.time"></TimePicker>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Gender" prop="gender">
|
||||||
|
<RadioGroup v-model="formValidate.gender">
|
||||||
|
<Radio label="male">Male</Radio>
|
||||||
|
<Radio label="female">Female</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Hobby" prop="interest">
|
||||||
|
<CheckboxGroup v-model="formValidate.interest">
|
||||||
|
<Checkbox label="Eat"></Checkbox>
|
||||||
|
<Checkbox label="Sleep"></Checkbox>
|
||||||
|
<Checkbox label="Run"></Checkbox>
|
||||||
|
<Checkbox label="Movie"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Desc" prop="desc">
|
||||||
|
<Input v-model="formValidate.desc" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="Enter something..." />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit2('formValidate')">Submit</Button>
|
||||||
|
<Button @click="handleReset('formValidate')" style="margin-left: 8px">Reset</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { GetPerPrice } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '站点名称',
|
||||||
|
key: 'charge_station_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电费',
|
||||||
|
key: 'ElectricityFee',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '服务费',
|
||||||
|
key: 'ServiceFee',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
mail: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
|
interest: [],
|
||||||
|
date: '',
|
||||||
|
time: '',
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: 'The name cannot be empty', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
mail: [
|
||||||
|
{ required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: 'Incorrect email format', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
city: [
|
||||||
|
{ required: true, message: 'Please select the city', trigger: 'change' },
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{ required: true, message: 'Please select gender', trigger: 'change' },
|
||||||
|
],
|
||||||
|
interest: [
|
||||||
|
{ required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
|
||||||
|
{ type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' },
|
||||||
|
],
|
||||||
|
date: [
|
||||||
|
{ required: true, type: 'date', message: 'Please select the date', trigger: 'change' },
|
||||||
|
],
|
||||||
|
time: [
|
||||||
|
{ required: true, type: 'string', message: 'Please select time', trigger: 'change' },
|
||||||
|
],
|
||||||
|
desc: [
|
||||||
|
{ required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
|
||||||
|
{ type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await GetPerPrice({ page: 1 }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
|
||||||
|
this.data = res.yuan
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
273
src/views/charging_pile/Station.vue
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="站点名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="添加站点" :mask-closable="false">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="站点名称" prop="charge_station_name">
|
||||||
|
<Input v-model="formValidate.charge_station_name" placeholder="站点名称" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="站点编号" prop="charge_station_number">
|
||||||
|
<Input v-model="formValidate.charge_station_number" placeholder="站点编号" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="城市" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="地址" prop="address">
|
||||||
|
<Input v-model="formValidate.address" placeholder="地址" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="联系电话" prop="charge_station_phone">
|
||||||
|
<Input v-model="formValidate.charge_station_phone" placeholder="联系电话" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="精度" prop="longitude">
|
||||||
|
<Input v-model="formValidate.longitude" placeholder="精度" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="纬度" prop="latitude">
|
||||||
|
<Input v-model="formValidate.latitude" placeholder="纬度" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="电费" prop="ElectricityFee">
|
||||||
|
<Input v-model="formValidate.ElectricityFee" placeholder="电费" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="服务费" prop="ServiceFee">
|
||||||
|
<Input v-model="formValidate.ServiceFee" placeholder="服务费" />
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
<div slot="footer">
|
||||||
|
<Button type="text" @click="cancel">取消</Button>
|
||||||
|
<Button type="primary" @click="ok">确定</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
GetPosition,
|
||||||
|
} from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [{
|
||||||
|
title: '站点名称',
|
||||||
|
key: 'charge_station_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '站点编号',
|
||||||
|
key: 'charge_station_number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '站点地址',
|
||||||
|
key: 'address',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '精度',
|
||||||
|
key: 'longitude',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '纬度',
|
||||||
|
key: 'latitude',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电价',
|
||||||
|
key: 'ElectricityFee',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '服务费',
|
||||||
|
key: 'ServiceFee',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
charge_station_name: '',
|
||||||
|
charge_station_number: '',
|
||||||
|
city: '',
|
||||||
|
charge_station_phone: '',
|
||||||
|
longitude: [],
|
||||||
|
latitude: '',
|
||||||
|
ElectricityFee: '',
|
||||||
|
ServiceFee: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
charge_station_name: [{
|
||||||
|
required: true,
|
||||||
|
message: 'The name cannot be empty',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
charge_station_number: [{
|
||||||
|
required: true,
|
||||||
|
message: 'Mailbox cannot be empty',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
city: [{
|
||||||
|
required: true,
|
||||||
|
message: 'Please select the city',
|
||||||
|
trigger: 'change',
|
||||||
|
}],
|
||||||
|
address: [{
|
||||||
|
required: true,
|
||||||
|
message: 'Please select gender',
|
||||||
|
trigger: 'change',
|
||||||
|
}],
|
||||||
|
longitude: [{
|
||||||
|
required: true,
|
||||||
|
message: 'Please select the date',
|
||||||
|
trigger: 'change',
|
||||||
|
}],
|
||||||
|
latitude: [{
|
||||||
|
required: true,
|
||||||
|
message: 'Please select time',
|
||||||
|
trigger: 'change',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await GetPosition({
|
||||||
|
page: 1,
|
||||||
|
}).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
702
src/views/customer_center/CorporateClient.vue
Normal file
@@ -0,0 +1,702 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="name" label="企业名称:">
|
||||||
|
<Input type="text" v-model="formInline.name" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="credit_code" label="企业代码:">
|
||||||
|
<Input type="text" v-model="formInline.credit_code" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
<Button type="primary" @click="resetSubmit('formInline')" style="margin-left: 8px">重置</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="add">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px"
|
||||||
|
@click="show_user_list(row.id)">员工账号</Button>
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show_car_list(row.id)">企业车辆</Button>
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show_rechage_list(row.id)">充值记录</Button>
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show_chage_list(row.id)">充电记录</Button>
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(row.id)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(row.id)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
|
||||||
|
@on-page-size-change="onChangePageSize" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" :title="formValidate.id ? '编辑企业' : '新增企业'" :mask-closable="false">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="企业名称" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="请输入企业名称" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="企业统一社会信用代码" prop="credit_code">
|
||||||
|
<Input v-model="formValidate.credit_code" placeholder="请输入企业统一社会信用代码" />
|
||||||
|
</FormItem>
|
||||||
|
<div style="display: flex;">
|
||||||
|
<FormItem label="联系人" prop="username">
|
||||||
|
<Input v-model="formValidate.username" placeholder="请输入联系人" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="联系电话" prop="phone">
|
||||||
|
<Input v-model="formValidate.phone" placeholder="请输入联系电话" />
|
||||||
|
</FormItem>
|
||||||
|
</div>
|
||||||
|
<FormItem label="折扣" prop="discount">
|
||||||
|
<RadioGroup v-model="formValidate.discount">
|
||||||
|
<Radio label="1">电费和服务费</Radio>
|
||||||
|
<Radio label="2">仅服务费</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="折扣范围" prop="range">
|
||||||
|
<Input v-model="formValidate.range" placeholder="请输入折扣">
|
||||||
|
<template #suffix>
|
||||||
|
<div style="line-height:32px;border-left:1px solid #c3b8b8;">%</div>
|
||||||
|
</template>
|
||||||
|
</Input>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="扣款账户" prop="account">
|
||||||
|
<RadioGroup v-model="formValidate.account">
|
||||||
|
<Radio label="1">企业账户</Radio>
|
||||||
|
<Radio label="2">个人钱包</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="备注" prop="marks">
|
||||||
|
<Input v-model="formValidate.marks" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="请输入备注信息..." />
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
<!--解决弹框自动关闭-->
|
||||||
|
<div slot="footer">
|
||||||
|
<Button type="text" @click="cancel">取消</Button>
|
||||||
|
<Button type="primary" @click="ok">确定</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<!-- 员工账号 -->
|
||||||
|
<Modal v-model="user_list_show_modal" title="员工账号" :mask-closable="false" :fullscreen="true"
|
||||||
|
:footer-hide="true">
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="addUser">添加</Button>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="user_columns" stripe :height="tableHeight" :data="user_data">
|
||||||
|
<template #group_id="{ row }">
|
||||||
|
<strong v-if="row.group_id == 1">管理员</strong>
|
||||||
|
</template>
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px"
|
||||||
|
@click="showUser(row.id)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="removeUser(row.id)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="user_total" show-total show-sizer class="page" @on-change="onChangeUserPage"
|
||||||
|
@on-page-size-change="onChangeUserPageSize" />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
<!-- 员工账号 添加、编辑 -->
|
||||||
|
<Modal v-model="user_show_modal" :title="formUserValidate.id ? '编辑员工账号' : '新增员工账号'" :mask-closable="false">
|
||||||
|
<Form ref="formUserValidate" :model="formUserValidate" :rules="ruleUserValidate" :label-width="80">
|
||||||
|
<FormItem label="联系电话" prop="phone">
|
||||||
|
<Input v-model="formUserValidate.phone" placeholder="请输入联系电话" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="管理员" prop="group_id">
|
||||||
|
<RadioGroup v-model="formUserValidate.group_id">
|
||||||
|
<Radio label="1">是</Radio>
|
||||||
|
<Radio label="0">否</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
<!--解决弹框自动关闭-->
|
||||||
|
<div slot="footer">
|
||||||
|
<Button type="text" @click="user_cancel">取消</Button>
|
||||||
|
<Button type="primary" @click="user_ok">确定</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<!-- 企业车辆 -->
|
||||||
|
<Modal v-model="car_list_show_modal" title="企业车辆" :mask-closable="false" :fullscreen="true"
|
||||||
|
:footer-hide="true">
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="addCar">添加</Button>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="car_columns" stripe :height="tableHeight" :data="car_data">
|
||||||
|
<template #vin_type="{ row }">
|
||||||
|
{{ row.vin_type == 2 ? '关闭' : '开启' }}
|
||||||
|
</template>
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px"
|
||||||
|
@click="showCar(row.id)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="removeCar(row.id)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="user_total" show-total show-sizer class="page" @on-change="onChangeUserPage"
|
||||||
|
@on-page-size-change="onChangeUserPageSize" />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
<!-- 企业车辆 添加、编辑 -->
|
||||||
|
<Modal v-model="car_show_modal" :title="formCarValidate.id ? '编辑车辆信息' : '新增企业车辆'" :mask-closable="false">
|
||||||
|
<Form ref="formCarValidate" :model="formCarValidate" :rules="ruleCarValidate" :label-width="80">
|
||||||
|
<FormItem label="车辆" prop="car_number">
|
||||||
|
<Input v-model="formCarValidate.car_number" placeholder="请输入车辆车牌号" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="VIN码" prop="car_vin">
|
||||||
|
<Input v-model="formCarValidate.car_vin" placeholder="请输入VIN码" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="内部编号" prop="car_no">
|
||||||
|
<Input v-model="formCarValidate.car_no" placeholder="请输入内部编号" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="车辆所有人" prop="car_user">
|
||||||
|
<Input v-model="formCarValidate.car_user" placeholder="请输入车辆所有人" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="VIN充电类型" prop="vin_type">
|
||||||
|
<RadioGroup v-model="formCarValidate.vin_type">
|
||||||
|
<Radio label="1">开启</Radio>
|
||||||
|
<Radio label="2">关闭</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
<!--解决弹框自动关闭-->
|
||||||
|
<div slot="footer">
|
||||||
|
<Button type="text" @click="car_cancel">取消</Button>
|
||||||
|
<Button type="primary" @click="car_ok">确定</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
getEnterpriseList, getEnterpriseSave, getEnterpriseDelete, getEnterpriseRead, getEnterpriseUpdate,
|
||||||
|
getEnterpriseUserList, getEnterpriseUserUpdate, getEnterpriseUserSave, getEnterpriseUserRead, getEnterpriseUserDelete,
|
||||||
|
getEnterpriseCarList, getEnterpriseCarUpdate, getEnterpriseCarSave, getEnterpriseCarRead, getEnterpriseCarDelete } from '@/api'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
name: '',
|
||||||
|
credit_code: '',
|
||||||
|
},
|
||||||
|
ruleInline: {
|
||||||
|
},
|
||||||
|
columns: [{
|
||||||
|
title: 'ID',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '企业名称',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '企业统一社会信用代码',
|
||||||
|
key: 'credit_code',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '账户余额',
|
||||||
|
key: 'money',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系人',
|
||||||
|
key: 'username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系电话',
|
||||||
|
key: 'phone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 300,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
id: null,
|
||||||
|
name: '',
|
||||||
|
credit_code: '',
|
||||||
|
username: '',
|
||||||
|
phone: '',
|
||||||
|
discount: '1',
|
||||||
|
range: '',
|
||||||
|
account: '1',
|
||||||
|
marks: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入企业名称',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
credit_code: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入企业统一社会信用代码',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
username: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入联系人',
|
||||||
|
trigger: 'change',
|
||||||
|
}],
|
||||||
|
phone: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入联系电话',
|
||||||
|
trigger: 'change',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
// 用户
|
||||||
|
user_list_show_modal: false,
|
||||||
|
user_show_modal: false,
|
||||||
|
user_columns: [{
|
||||||
|
title: 'ID',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户',
|
||||||
|
key: 'phone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '管理员',
|
||||||
|
slot: 'group_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 300,
|
||||||
|
align: 'center',
|
||||||
|
}],
|
||||||
|
formUserValidate: {
|
||||||
|
id: null,
|
||||||
|
phone: '',
|
||||||
|
group_id: '0',
|
||||||
|
enterprise_id: '',
|
||||||
|
},
|
||||||
|
ruleUserValidate: {
|
||||||
|
phone: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入联系电话',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
user_data: [],
|
||||||
|
user_total: 0,
|
||||||
|
userPage: 1,
|
||||||
|
userPageSize: 10,
|
||||||
|
// 车辆
|
||||||
|
car_list_show_modal: false,
|
||||||
|
car_show_modal: false,
|
||||||
|
car_columns: [{
|
||||||
|
title: 'ID',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '车辆',
|
||||||
|
key: 'car_number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'VIN码',
|
||||||
|
key: 'car_vin',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '内部编号',
|
||||||
|
key: 'car_no',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '车辆所有人',
|
||||||
|
key: 'car_user',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'VIN充电类型',
|
||||||
|
slot: 'vin_type',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 300,
|
||||||
|
align: 'center',
|
||||||
|
}],
|
||||||
|
formCarValidate: {
|
||||||
|
id: null,
|
||||||
|
car_number: '',
|
||||||
|
car_vin: '',
|
||||||
|
enterprise_id: '',
|
||||||
|
car_no: '',
|
||||||
|
car_user: '',
|
||||||
|
vin_type: '1',
|
||||||
|
},
|
||||||
|
ruleCarValidate: {
|
||||||
|
car_number: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入车辆车牌号',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
car_vin: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入车辆VIN码',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
car_data: [],
|
||||||
|
car_total: 0,
|
||||||
|
carPage: 1,
|
||||||
|
carPageSize: 10,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
// 列表
|
||||||
|
async getList() {
|
||||||
|
await getEnterpriseList({
|
||||||
|
page: this.page,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
...this.formInline,
|
||||||
|
}).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
resetSubmit() {
|
||||||
|
this.$refs.formInline.resetFields()
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
// 详情
|
||||||
|
async show(id) {
|
||||||
|
await getEnterpriseRead({ id }).then(res => {
|
||||||
|
this.formValidate = { ...res.data }
|
||||||
|
this.formValidate.discount = String(this.formValidate.discount)
|
||||||
|
this.formValidate.account = String(this.formValidate.account)
|
||||||
|
this.show_modal = true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 删除
|
||||||
|
async remove(id) {
|
||||||
|
const confirm = await new Promise(resolve => {
|
||||||
|
this.$Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '您确定要删除此项吗?',
|
||||||
|
onOk: () => resolve(true),
|
||||||
|
onCancel: () => resolve(false),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!confirm) {
|
||||||
|
this.$Message.info('已取消删除')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await getEnterpriseDelete({ id }).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 新增
|
||||||
|
async ok() {
|
||||||
|
const valid = await new Promise(resolve => this.$refs.formValidate.validate(resolve))
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
this.$Message.error('请正确填写表单')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.formValidate.id) {
|
||||||
|
await getEnterpriseUpdate(this.formValidate).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getList()
|
||||||
|
this.cancel()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await getEnterpriseSave(this.formValidate).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getList()
|
||||||
|
this.cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
add() {
|
||||||
|
this.show_modal = true
|
||||||
|
this.$refs.formValidate.resetFields()
|
||||||
|
this.formValidate.id = ''
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$refs.formValidate.resetFields()
|
||||||
|
this.show_modal = false
|
||||||
|
},
|
||||||
|
onChangePage(e) {
|
||||||
|
if (this.page != e) {
|
||||||
|
this.page = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangePageSize(e) {
|
||||||
|
if (this.pageSize != e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 员工账号列表
|
||||||
|
show_user_list(id) {
|
||||||
|
this.user_list_show_modal = true
|
||||||
|
this.formUserValidate.enterprise_id = id
|
||||||
|
this.getEnterpriseUserList()
|
||||||
|
},
|
||||||
|
async getEnterpriseUserList() {
|
||||||
|
await getEnterpriseUserList({
|
||||||
|
enterprise_id: this.formUserValidate.enterprise_id,
|
||||||
|
page: this.userPage,
|
||||||
|
pageSize: this.userPageSize,
|
||||||
|
}).then((res) => {
|
||||||
|
this.user_data = res.data
|
||||||
|
this.user_total = res.total
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 添加员工账号 弹窗显示
|
||||||
|
addUser() {
|
||||||
|
this.$refs.formUserValidate.resetFields()
|
||||||
|
this.formUserValidate.id = ''
|
||||||
|
this.user_show_modal = true
|
||||||
|
},
|
||||||
|
// 关闭新增弹窗
|
||||||
|
user_cancel() {
|
||||||
|
this.user_show_modal = false
|
||||||
|
this.$refs.formUserValidate.resetFields()
|
||||||
|
},
|
||||||
|
// 提交员工账号数据
|
||||||
|
async user_ok() {
|
||||||
|
const valid = await new Promise(resolve => this.$refs.formUserValidate.validate(resolve))
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
this.$Message.error('请正确填写表单')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.formUserValidate.id) {
|
||||||
|
await getEnterpriseUserUpdate(this.formUserValidate).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getEnterpriseUserList()
|
||||||
|
this.user_cancel()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await getEnterpriseUserSave(this.formUserValidate).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getEnterpriseUserList()
|
||||||
|
this.user_cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 编辑员工账号信息
|
||||||
|
async showUser(id) {
|
||||||
|
await getEnterpriseUserRead({ id }).then(res => {
|
||||||
|
this.formUserValidate = { ...res.data }
|
||||||
|
this.formUserValidate.group_id = String(this.formUserValidate.group_id)
|
||||||
|
this.user_show_modal = true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 删除员工账号信息
|
||||||
|
async removeUser(id) {
|
||||||
|
const confirm = await new Promise(resolve => {
|
||||||
|
this.$Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '您确定要删除此项吗?',
|
||||||
|
onOk: () => resolve(true),
|
||||||
|
onCancel: () => resolve(false),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!confirm) {
|
||||||
|
this.$Message.info('已取消删除')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await getEnterpriseUserDelete({ id }).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getEnterpriseUserList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChangeUserPage(e) {
|
||||||
|
if (this.userPage != e) {
|
||||||
|
this.userPage = e
|
||||||
|
this.getEnterpriseUserList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangeUserPageSize(e) {
|
||||||
|
if (this.userPageSize != e) {
|
||||||
|
this.userPage = 1
|
||||||
|
this.userPageSize = e
|
||||||
|
this.getEnterpriseUserList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 企业车辆列表
|
||||||
|
show_car_list(id) {
|
||||||
|
this.car_list_show_modal = true
|
||||||
|
this.formCarValidate.enterprise_id = id
|
||||||
|
this.getEnterpriseCarList()
|
||||||
|
},
|
||||||
|
async getEnterpriseCarList() {
|
||||||
|
await getEnterpriseCarList({
|
||||||
|
enterprise_id: this.formCarValidate.enterprise_id,
|
||||||
|
page: this.carPage,
|
||||||
|
pageSize: this.carPageSize,
|
||||||
|
}).then((res) => {
|
||||||
|
this.car_data = res.data
|
||||||
|
this.car_total = res.total
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 添加车辆信息 弹窗显示
|
||||||
|
addCar() {
|
||||||
|
this.$refs.formCarValidate.resetFields()
|
||||||
|
this.formCarValidate.id = ''
|
||||||
|
this.car_show_modal = true
|
||||||
|
},
|
||||||
|
// 关闭新增弹窗
|
||||||
|
car_cancel() {
|
||||||
|
this.car_show_modal = false
|
||||||
|
this.$refs.formCarValidate.resetFields()
|
||||||
|
},
|
||||||
|
// 提交车辆数据
|
||||||
|
async car_ok() {
|
||||||
|
const valid = await new Promise(resolve => this.$refs.formCarValidate.validate(resolve))
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
this.$Message.error('请正确填写表单')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.formCarValidate.id) {
|
||||||
|
await getEnterpriseCarUpdate(this.formCarValidate).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getEnterpriseCarList()
|
||||||
|
this.car_cancel()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await getEnterpriseCarSave(this.formCarValidate).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getEnterpriseCarList()
|
||||||
|
this.car_cancel()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 编辑车辆信息
|
||||||
|
async showCar(id) {
|
||||||
|
await getEnterpriseCarRead({ id }).then(res => {
|
||||||
|
this.formCarValidate = { ...res.data }
|
||||||
|
this.formCarValidate.vin_type = String(this.formCarValidate.vin_type)
|
||||||
|
this.car_show_modal = true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 删除车辆信息
|
||||||
|
async removeCar(id) {
|
||||||
|
const confirm = await new Promise(resolve => {
|
||||||
|
this.$Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '您确定要删除此项吗?',
|
||||||
|
onOk: () => resolve(true),
|
||||||
|
onCancel: () => resolve(false),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!confirm) {
|
||||||
|
this.$Message.info('已取消删除')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await getEnterpriseCarDelete({ id }).then(res => {
|
||||||
|
this.$Message.success(res.msg)
|
||||||
|
this.getEnterpriseCarList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChangeCarPage(e) {
|
||||||
|
if (this.carPage != e) {
|
||||||
|
this.carPage = e
|
||||||
|
this.getEnterpriseCarList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangeCarPageSize(e) {
|
||||||
|
if (this.carPageSize != e) {
|
||||||
|
this.carPage = 1
|
||||||
|
this.carPageSize = e
|
||||||
|
this.getEnterpriseCarList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
273
src/views/customer_center/WxUser.vue
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="客户名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="Common Modal dialog box title" :mask-closable="false" @on-ok="ok"
|
||||||
|
@on-cancel="cancel">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="Name" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="Enter your name" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="E-mail" prop="mail">
|
||||||
|
<Input v-model="formValidate.mail" placeholder="Enter your e-mail" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="City" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Date">
|
||||||
|
<Row>
|
||||||
|
<Col span="11">
|
||||||
|
<DatePicker type="date" placeholder="Select date" v-model="formValidate.date"></DatePicker>
|
||||||
|
</Col>
|
||||||
|
<Col span="2" style="text-align: center">-</Col>
|
||||||
|
<Col span="11">
|
||||||
|
<TimePicker type="time" placeholder="Select time" v-model="formValidate.time"></TimePicker>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Gender" prop="gender">
|
||||||
|
<RadioGroup v-model="formValidate.gender">
|
||||||
|
<Radio label="male">Male</Radio>
|
||||||
|
<Radio label="female">Female</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Hobby" prop="interest">
|
||||||
|
<CheckboxGroup v-model="formValidate.interest">
|
||||||
|
<Checkbox label="Eat"></Checkbox>
|
||||||
|
<Checkbox label="Sleep"></Checkbox>
|
||||||
|
<Checkbox label="Run"></Checkbox>
|
||||||
|
<Checkbox label="Movie"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Desc" prop="desc">
|
||||||
|
<Input v-model="formValidate.desc" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="Enter something..." />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit2('formValidate')">Submit</Button>
|
||||||
|
<Button @click="handleReset('formValidate')" style="margin-left: 8px">Reset</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { GetUser } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '区域',
|
||||||
|
key: 'area',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户名称',
|
||||||
|
key: 'username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'openid',
|
||||||
|
key: 'openid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '手机号',
|
||||||
|
key: 'phone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '余额',
|
||||||
|
key: 'account',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '冻结余额',
|
||||||
|
key: 'FrozenAccount',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
mail: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
|
interest: [],
|
||||||
|
date: '',
|
||||||
|
time: '',
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: 'The name cannot be empty', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
mail: [
|
||||||
|
{ required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: 'Incorrect email format', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
city: [
|
||||||
|
{ required: true, message: 'Please select the city', trigger: 'change' },
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{ required: true, message: 'Please select gender', trigger: 'change' },
|
||||||
|
],
|
||||||
|
interest: [
|
||||||
|
{ required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
|
||||||
|
{ type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' },
|
||||||
|
],
|
||||||
|
date: [
|
||||||
|
{ required: true, type: 'date', message: 'Please select the date', trigger: 'change' },
|
||||||
|
],
|
||||||
|
time: [
|
||||||
|
{ required: true, type: 'string', message: 'Please select time', trigger: 'change' },
|
||||||
|
],
|
||||||
|
desc: [
|
||||||
|
{ required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
|
||||||
|
{ type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await GetUser({ type: '', page: 1 }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
261
src/views/operations_center/activity.vue
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="充电桩名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="Common Modal dialog box title" :mask-closable="false" @on-ok="ok"
|
||||||
|
@on-cancel="cancel">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="Name" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="Enter your name" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="E-mail" prop="mail">
|
||||||
|
<Input v-model="formValidate.mail" placeholder="Enter your e-mail" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="City" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Date">
|
||||||
|
<Row>
|
||||||
|
<Col span="11">
|
||||||
|
<DatePicker type="date" placeholder="Select date" v-model="formValidate.date"></DatePicker>
|
||||||
|
</Col>
|
||||||
|
<Col span="2" style="text-align: center">-</Col>
|
||||||
|
<Col span="11">
|
||||||
|
<TimePicker type="time" placeholder="Select time" v-model="formValidate.time"></TimePicker>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Gender" prop="gender">
|
||||||
|
<RadioGroup v-model="formValidate.gender">
|
||||||
|
<Radio label="male">Male</Radio>
|
||||||
|
<Radio label="female">Female</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Hobby" prop="interest">
|
||||||
|
<CheckboxGroup v-model="formValidate.interest">
|
||||||
|
<Checkbox label="Eat"></Checkbox>
|
||||||
|
<Checkbox label="Sleep"></Checkbox>
|
||||||
|
<Checkbox label="Run"></Checkbox>
|
||||||
|
<Checkbox label="Movie"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Desc" prop="desc">
|
||||||
|
<Input v-model="formValidate.desc" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="Enter something..." />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit2('formValidate')">Submit</Button>
|
||||||
|
<Button @click="handleReset('formValidate')" style="margin-left: 8px">Reset</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getEventList } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '活动名称',
|
||||||
|
key: 'title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '活动状态',
|
||||||
|
key: 'statusMsg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
key: 'create_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
mail: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
|
interest: [],
|
||||||
|
date: '',
|
||||||
|
time: '',
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: 'The name cannot be empty', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
mail: [
|
||||||
|
{ required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: 'Incorrect email format', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
city: [
|
||||||
|
{ required: true, message: 'Please select the city', trigger: 'change' },
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{ required: true, message: 'Please select gender', trigger: 'change' },
|
||||||
|
],
|
||||||
|
interest: [
|
||||||
|
{ required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
|
||||||
|
{ type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' },
|
||||||
|
],
|
||||||
|
date: [
|
||||||
|
{ required: true, type: 'date', message: 'Please select the date', trigger: 'change' },
|
||||||
|
],
|
||||||
|
time: [
|
||||||
|
{ required: true, type: 'string', message: 'Please select time', trigger: 'change' },
|
||||||
|
],
|
||||||
|
desc: [
|
||||||
|
{ required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
|
||||||
|
{ type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getEventList({ page: 1 }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
261
src/views/operations_center/coupon.vue
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="优惠券名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="Common Modal dialog box title" :mask-closable="false" @on-ok="ok"
|
||||||
|
@on-cancel="cancel">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="Name" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="Enter your name" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="E-mail" prop="mail">
|
||||||
|
<Input v-model="formValidate.mail" placeholder="Enter your e-mail" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="City" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Date">
|
||||||
|
<Row>
|
||||||
|
<Col span="11">
|
||||||
|
<DatePicker type="date" placeholder="Select date" v-model="formValidate.date"></DatePicker>
|
||||||
|
</Col>
|
||||||
|
<Col span="2" style="text-align: center">-</Col>
|
||||||
|
<Col span="11">
|
||||||
|
<TimePicker type="time" placeholder="Select time" v-model="formValidate.time"></TimePicker>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Gender" prop="gender">
|
||||||
|
<RadioGroup v-model="formValidate.gender">
|
||||||
|
<Radio label="male">Male</Radio>
|
||||||
|
<Radio label="female">Female</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Hobby" prop="interest">
|
||||||
|
<CheckboxGroup v-model="formValidate.interest">
|
||||||
|
<Checkbox label="Eat"></Checkbox>
|
||||||
|
<Checkbox label="Sleep"></Checkbox>
|
||||||
|
<Checkbox label="Run"></Checkbox>
|
||||||
|
<Checkbox label="Movie"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Desc" prop="desc">
|
||||||
|
<Input v-model="formValidate.desc" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="Enter something..." />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit2('formValidate')">Submit</Button>
|
||||||
|
<Button @click="handleReset('formValidate')" style="margin-left: 8px">Reset</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getEventList } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '优惠券名称',
|
||||||
|
key: 'title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
key: 'statusMsg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
key: 'create_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
mail: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
|
interest: [],
|
||||||
|
date: '',
|
||||||
|
time: '',
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: 'The name cannot be empty', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
mail: [
|
||||||
|
{ required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: 'Incorrect email format', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
city: [
|
||||||
|
{ required: true, message: 'Please select the city', trigger: 'change' },
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{ required: true, message: 'Please select gender', trigger: 'change' },
|
||||||
|
],
|
||||||
|
interest: [
|
||||||
|
{ required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
|
||||||
|
{ type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' },
|
||||||
|
],
|
||||||
|
date: [
|
||||||
|
{ required: true, type: 'date', message: 'Please select the date', trigger: 'change' },
|
||||||
|
],
|
||||||
|
time: [
|
||||||
|
{ required: true, type: 'string', message: 'Please select time', trigger: 'change' },
|
||||||
|
],
|
||||||
|
desc: [
|
||||||
|
{ required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
|
||||||
|
{ type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getEventList({ page: 1 }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
9
src/views/operations_center/invoice.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<view>safsa</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
9
src/views/operations_center/user_vip.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<view>safsa</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
201
src/views/order/charge_order.vue
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="用户手机号">
|
||||||
|
<Input type="text" v-model="formInline.phone" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #order="{ row, index }">
|
||||||
|
订单编号: {{ row.order_number }}<br>
|
||||||
|
开始时间: {{ row.start_time }}<br>
|
||||||
|
结束时间: {{ row.end_time }}
|
||||||
|
</template>
|
||||||
|
<template #pile="{ row, index }">
|
||||||
|
充电站名称: {{ row.charge_station_name }}<br>
|
||||||
|
充电桩编号: {{ row.ConnectorID}}
|
||||||
|
</template>
|
||||||
|
<template #user="{ row, index }">
|
||||||
|
openId: {{ row.openid }}<br>
|
||||||
|
手机号: {{ row.phone}}<br>
|
||||||
|
VIN: {{ row.vin }}
|
||||||
|
</template>
|
||||||
|
<template #power="{ row, index }">
|
||||||
|
电量: {{ row.TotalPower }}<br>
|
||||||
|
电费: {{ row.ElecMoney}}<br>
|
||||||
|
服务费: {{ row.SeviceMoney }}<br>
|
||||||
|
总计: {{ row.TotalMoney }}<br>
|
||||||
|
</template>
|
||||||
|
<template #type="{ row, index }">
|
||||||
|
订单类型: {{ row.type_text }}<br>
|
||||||
|
<div v-if="row.type == 1">
|
||||||
|
充值金额: {{ row.WithholdingMoney }}<br>
|
||||||
|
退还金额: {{ row.FeedbackMoney }}<br>
|
||||||
|
{{row.is_wind == 0 ? '未结算' : '已结算'}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<!-- <Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">详情</Button> -->
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
|
||||||
|
@on-page-size-change="onChangePageSize"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getChargeOrder } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: 'id',
|
||||||
|
key: 'order_id',
|
||||||
|
width: '80',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单信息',
|
||||||
|
slot: 'order',
|
||||||
|
width: '280',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电站信息',
|
||||||
|
slot: 'pile',
|
||||||
|
width: '240',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户信息',
|
||||||
|
slot: 'user',
|
||||||
|
width: '310',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电信息',
|
||||||
|
slot: 'power',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电类型',
|
||||||
|
slot: 'type',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getChargeOrder({ page: this.page, pageSize: this.pageSize, ...this.formInline }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChangePage(e) {
|
||||||
|
if (this.page != e) {
|
||||||
|
this.page = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangePageSize(e) {
|
||||||
|
if (this.pageSize != e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
140
src/views/order/order_total.vue
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" :model="formInline" :rules="ruleInline" inline :label-width="120">
|
||||||
|
<FormItem prop="user" label="时间">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="Username"></Input>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="password" label="充电桩">
|
||||||
|
<Input type="password" v-model="formInline.password" placeholder="Password"></Input>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="password" label="充电站">
|
||||||
|
<Input type="password" v-model="formInline.password" placeholder="Password"></Input>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div id="main" ref="chartContainer" style="width: 100%; height: 400px;"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Total',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
chartInstance: null,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initChart()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.chartInstance) {
|
||||||
|
this.chartInstance.dispose()
|
||||||
|
}
|
||||||
|
window.removeEventListener('resize', this.handleResize)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initChart() {
|
||||||
|
if (!this.$refs.chartContainer) return
|
||||||
|
|
||||||
|
// 销毁旧实例
|
||||||
|
if (this.chartInstance) {
|
||||||
|
this.chartInstance.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chartInstance = echarts.init(this.$refs.chartContainer)
|
||||||
|
|
||||||
|
// 模拟数据
|
||||||
|
const xData = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
|
||||||
|
const orderData = [120, 132, 101, 134, 90, 230, 210]
|
||||||
|
const revenueData = [220, 182, 191, 234, 290, 330, 310]
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
text: '充电订单趋势',
|
||||||
|
left: 'center',
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['订单量', '收入'],
|
||||||
|
top: 30,
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: xData,
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
name: '订单量',
|
||||||
|
type: 'line',
|
||||||
|
data: orderData,
|
||||||
|
smooth: true,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#5470c6',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '收入',
|
||||||
|
type: 'line',
|
||||||
|
data: revenueData,
|
||||||
|
smooth: true,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#91cc75',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chartInstance.setOption(option)
|
||||||
|
|
||||||
|
// 响应式调整
|
||||||
|
window.addEventListener('resize', this.handleResize)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleResize() {
|
||||||
|
if (this.chartInstance) {
|
||||||
|
this.chartInstance.resize()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
#main {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 20px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
177
src/views/order/recharge_order.vue
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="openid">
|
||||||
|
<Input type="text" v-model="formInline.openid" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<!-- <Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">详情</Button> -->
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
|
||||||
|
@on-page-size-change="onChangePageSize" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getReChargeOrder } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
openid: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [{
|
||||||
|
title: 'id',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单编号',
|
||||||
|
key: 'out_trade_no',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户',
|
||||||
|
key: 'openid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充值金额',
|
||||||
|
key: 'total',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '已用金额',
|
||||||
|
key: 'total_used',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充值状态',
|
||||||
|
key: 'trade_state',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充值时间',
|
||||||
|
key: 'success_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getReChargeOrder({
|
||||||
|
page: this.page,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
...this.formInline,
|
||||||
|
}).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChangePage(e) {
|
||||||
|
if (this.page != e) {
|
||||||
|
this.page = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangePageSize(e) {
|
||||||
|
if (this.pageSize != e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
190
src/views/order/refund_order.vue
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="openid">
|
||||||
|
<Input type="text" v-model="formInline.openid" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<!-- <Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">详情</Button> -->
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
|
||||||
|
@on-page-size-change="onChangePageSize"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getRefundOrder } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
openid: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [{
|
||||||
|
title: 'id',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单编号',
|
||||||
|
key: 'out_trade_no',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户',
|
||||||
|
key: 'openid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户手机号',
|
||||||
|
key: 'phone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '退款金额',
|
||||||
|
key: 'refund_total',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '退还账户',
|
||||||
|
key: 'user_received_account',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '退款状态',
|
||||||
|
key: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '退款时间',
|
||||||
|
key: 'create_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getRefundOrder({
|
||||||
|
page: this.page,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
...this.formInline,
|
||||||
|
}).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
onChangePage(e) {
|
||||||
|
if (this.page != e) {
|
||||||
|
this.page = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangePageSize(e) {
|
||||||
|
if (this.pageSize != e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
9
src/views/reports/activation.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<view>11</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
9
src/views/reports/backup_and_repair.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<view>11</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
183
src/views/reports/caiwu_reports.vue.vue
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="用户">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="user" label="类型">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="user" label="起止时间">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<!-- <Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">详情</Button> -->
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
|
||||||
|
@on-page-size-change="onChangePageSize" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getCaiWuData } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [{
|
||||||
|
title: 'Id',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户',
|
||||||
|
key: 'openid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '类型',
|
||||||
|
key: 'type_text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '金额',
|
||||||
|
key: 'money',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '说明',
|
||||||
|
key: 'mark',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
key: 'createtime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getCaiWuData({
|
||||||
|
page: this.page,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
}).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChangePage(e) {
|
||||||
|
if (this.page != e) {
|
||||||
|
this.page = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangePageSize(e) {
|
||||||
|
if (this.pageSize != e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
9
src/views/reports/income_analysis.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<view>11</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
9
src/views/reports/rate.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<view>11</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
9
src/views/reports/yunwei_reports.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<view>322534</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
203
src/views/reports/yunying_reports.vue
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="站点">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="user" label="充电桩">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="user" label="起止时间">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<!-- <Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">详情</Button> -->
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
|
||||||
|
@on-page-size-change="onChangePageSize" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getYunYingData } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [{
|
||||||
|
title: '充电站名称',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '桩类型',
|
||||||
|
key: 'out_trade_no',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '桩数量',
|
||||||
|
key: 'openid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '枪数量',
|
||||||
|
key: 'total',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电次数',
|
||||||
|
key: 'total_used',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电电量(度)',
|
||||||
|
key: 'trade_state',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充电金额(元)',
|
||||||
|
key: 'success_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电费',
|
||||||
|
key: 'success_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '服务费',
|
||||||
|
key: 'success_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '总时长',
|
||||||
|
key: 'success_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '尖峰平谷电量',
|
||||||
|
key: 'success_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getYunYingData({
|
||||||
|
page: this.page,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
}).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChangePage(e) {
|
||||||
|
if (this.page != e) {
|
||||||
|
this.page = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangePageSize(e) {
|
||||||
|
if (this.pageSize != e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
273
src/views/system/admin.vue
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="用户名:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="show_modal = true">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="Common Modal dialog box title" :mask-closable="false" @on-ok="ok"
|
||||||
|
@on-cancel="cancel">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="Name" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="Enter your name" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="E-mail" prop="mail">
|
||||||
|
<Input v-model="formValidate.mail" placeholder="Enter your e-mail" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="City" prop="city">
|
||||||
|
<Select v-model="formValidate.city" placeholder="Select your city">
|
||||||
|
<Option value="beijing">New York</Option>
|
||||||
|
<Option value="shanghai">London</Option>
|
||||||
|
<Option value="shenzhen">Sydney</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Date">
|
||||||
|
<Row>
|
||||||
|
<Col span="11">
|
||||||
|
<DatePicker type="date" placeholder="Select date" v-model="formValidate.date"></DatePicker>
|
||||||
|
</Col>
|
||||||
|
<Col span="2" style="text-align: center">-</Col>
|
||||||
|
<Col span="11">
|
||||||
|
<TimePicker type="time" placeholder="Select time" v-model="formValidate.time"></TimePicker>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Gender" prop="gender">
|
||||||
|
<RadioGroup v-model="formValidate.gender">
|
||||||
|
<Radio label="male">Male</Radio>
|
||||||
|
<Radio label="female">Female</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Hobby" prop="interest">
|
||||||
|
<CheckboxGroup v-model="formValidate.interest">
|
||||||
|
<Checkbox label="Eat"></Checkbox>
|
||||||
|
<Checkbox label="Sleep"></Checkbox>
|
||||||
|
<Checkbox label="Run"></Checkbox>
|
||||||
|
<Checkbox label="Movie"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Desc" prop="desc">
|
||||||
|
<Input v-model="formValidate.desc" type="textarea" :autosize="{ minRows: 2, maxRows: 5 }"
|
||||||
|
placeholder="Enter something..." />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit2('formValidate')">Submit</Button>
|
||||||
|
<Button @click="handleReset('formValidate')" style="margin-left: 8px">Reset</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { GetAdmin } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: 'ID',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户名',
|
||||||
|
key: 'username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '账号',
|
||||||
|
key: 'nickname',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '手机号',
|
||||||
|
key: 'phone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '岗位',
|
||||||
|
key: 'position',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '角色名',
|
||||||
|
key: 'roles',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
mail: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
|
interest: [],
|
||||||
|
date: '',
|
||||||
|
time: '',
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: 'The name cannot be empty', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
mail: [
|
||||||
|
{ required: true, message: 'Mailbox cannot be empty', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: 'Incorrect email format', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
city: [
|
||||||
|
{ required: true, message: 'Please select the city', trigger: 'change' },
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{ required: true, message: 'Please select gender', trigger: 'change' },
|
||||||
|
],
|
||||||
|
interest: [
|
||||||
|
{ required: true, type: 'array', min: 1, message: 'Choose at least one hobby', trigger: 'change' },
|
||||||
|
{ type: 'array', max: 2, message: 'Choose two hobbies at best', trigger: 'change' },
|
||||||
|
],
|
||||||
|
date: [
|
||||||
|
{ required: true, type: 'date', message: 'Please select the date', trigger: 'change' },
|
||||||
|
],
|
||||||
|
time: [
|
||||||
|
{ required: true, type: 'string', message: 'Please select time', trigger: 'change' },
|
||||||
|
],
|
||||||
|
desc: [
|
||||||
|
{ required: true, message: 'Please enter a personal introduction', trigger: 'blur' },
|
||||||
|
{ type: 'string', min: 20, message: 'Introduce no less than 20 words', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await GetAdmin({ page: 1 }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
247
src/views/system/auth.vue
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<!-- <div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="充电桩名称:">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div> -->
|
||||||
|
<div class="action-btn">
|
||||||
|
<Button type="primary" @click="add">添加</Button>
|
||||||
|
<!-- <Button type="error">删除</Button> -->
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
<Button type="primary" size="small" style="margin-right: 5px" @click="show(index)">编辑</Button>
|
||||||
|
<Button type="error" size="small" @click="remove(index)">删除</Button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 添加、编辑 -->
|
||||||
|
<Modal v-model="show_modal" title="添加角色" :mask-closable="false">
|
||||||
|
<Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
|
||||||
|
<FormItem label="角色名" prop="name">
|
||||||
|
<Input v-model="formValidate.name" placeholder="请输入角色名" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="所属上级" prop="pid">
|
||||||
|
<Select v-model="formValidate.pid" style="width:200px">
|
||||||
|
<Option :value="0">无</Option>
|
||||||
|
<Option v-for="item in roles_data" :value="item.id" :key="item.id">{{ item.name }}</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="权限菜单" prop="roles">
|
||||||
|
<Tree :data="menu_data" ref="tree" show-checkbox style="height: 300px;overflow-y: auto;"></Tree>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
<div slot="footer">
|
||||||
|
<Button type="text" @click="cancel">取消</Button>
|
||||||
|
<Button type="primary" @click="ok">确定</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
GetRole,
|
||||||
|
getMenuList,
|
||||||
|
} from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [{
|
||||||
|
title: 'ID',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '角色名称',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
formValidate: {
|
||||||
|
name: '',
|
||||||
|
pid: 0,
|
||||||
|
roles: '',
|
||||||
|
},
|
||||||
|
ruleValidate: {
|
||||||
|
name: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入角色名',
|
||||||
|
trigger: 'blur',
|
||||||
|
}],
|
||||||
|
roles: [{
|
||||||
|
required: true,
|
||||||
|
message: '请选择权限菜单',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
cityList: [{
|
||||||
|
value: 'New York',
|
||||||
|
label: 'New York',
|
||||||
|
}],
|
||||||
|
menu_data: [{
|
||||||
|
title: 'parent 1',
|
||||||
|
expand: false,
|
||||||
|
children: [{
|
||||||
|
title: 'parent 1-1',
|
||||||
|
expand: true,
|
||||||
|
children: [{
|
||||||
|
title: 'leaf 1-1-1',
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'leaf 1-1-2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'parent 1-2',
|
||||||
|
expand: true,
|
||||||
|
children: [{
|
||||||
|
title: 'leaf 1-2-1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'leaf 1-2-1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await GetRole({
|
||||||
|
page: 1,
|
||||||
|
}).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
async ok() {
|
||||||
|
let menuIds = this.$refs.tree.getCheckedAndIndeterminateNodes()
|
||||||
|
this.formValidate.roles = menuIds.map(item => item.id)
|
||||||
|
const valid = await new Promise(resolve => this.$refs.formValidate.validate(resolve))
|
||||||
|
if (!valid) {
|
||||||
|
this.$Message.error('请正确填写表单')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if (this.formValidate.id) { } else { }
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.show_modal = false
|
||||||
|
this.$refs.formValidate.resetFields()
|
||||||
|
},
|
||||||
|
async add() {
|
||||||
|
this.show_modal = true
|
||||||
|
await this.getMenuList()
|
||||||
|
},
|
||||||
|
async getMenuList() {
|
||||||
|
await getMenuList().then((res) => {
|
||||||
|
this.menu_data = res
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
188
src/views/system/log.vue
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="search-area">
|
||||||
|
<Form ref="formInline" inline :label-width="120" :model="formInline" :rules="ruleInline">
|
||||||
|
<FormItem prop="user" label="时间">
|
||||||
|
<Input type="text" v-model="formInline.user" placeholder="" />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button type="primary" @click="handleSubmit('formInline')">搜索</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
<div class="table-container">
|
||||||
|
<Table border :columns="columns" stripe :height="tableHeight" :data="data">
|
||||||
|
<template #action="{ row, index }">
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
|
||||||
|
@on-page-size-change="onChangePageSize"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getLogList } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'charging_station',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show_modal: false,
|
||||||
|
total: 100,
|
||||||
|
tableHeight: 500,
|
||||||
|
formInline: {
|
||||||
|
user: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
ruleInline: {},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: 'ID',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ip',
|
||||||
|
key: 'ip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '类型',
|
||||||
|
key: 'method',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '参数',
|
||||||
|
key: 'params',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '地址',
|
||||||
|
key: 'url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
key: 'create_time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slot: 'action',
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.calculateTableHeight)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
// 计算表格高度 = 窗口高度 - 搜索区域高度 - 分页高度 - 其他间距
|
||||||
|
const searchHeight = document.querySelector('.search-area').offsetHeight
|
||||||
|
const actionBtnHeight = document.querySelector('.action-btn').offsetHeight
|
||||||
|
const pageHeight = 32 // 分页组件大约高度
|
||||||
|
const margins = 40 // 上下边距总和
|
||||||
|
this.tableHeight = window.innerHeight - actionBtnHeight - searchHeight - pageHeight - margins - 130
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
await getLogList({ page: this.page, pageSize: this.pageSize }).then((res) => {
|
||||||
|
this.total = res.total
|
||||||
|
this.data = res.data
|
||||||
|
this.page = res.current_page
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReset(name) {
|
||||||
|
this.$refs[name].resetFields()
|
||||||
|
},
|
||||||
|
handleSubmit2(name) {
|
||||||
|
this.$refs[name].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$Message.success('Success!')
|
||||||
|
} else {
|
||||||
|
this.$Message.error('Fail!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
show(index) {
|
||||||
|
this.$Modal.info({
|
||||||
|
title: 'User Info',
|
||||||
|
content: `Name:${this.data[index].name}<br>Age:${this.data[index].age}<br>Address:${this.data[index].address}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove(index) {
|
||||||
|
this.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
ok() {
|
||||||
|
this.$Message.info('Clicked ok')
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.$Message.info('Clicked cancel')
|
||||||
|
},
|
||||||
|
onChangePage(e) {
|
||||||
|
if (this.page != e) {
|
||||||
|
this.page = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangePageSize(e) {
|
||||||
|
if (this.pageSize != e) {
|
||||||
|
this.page = 1
|
||||||
|
this.pageSize = e
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.search-area{
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 20px;
|
||||||
|
border: 1px solid #F3F7FD;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
152
src/views/system/system.vue
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<!-- tab切换 -->
|
||||||
|
<div class="tab" ref="tabHeader">
|
||||||
|
<div v-for="(item, index) in tab" @click="changeTab(index)" :key="index" class="tab_children"
|
||||||
|
:class="{ active: item.check }">
|
||||||
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 内容区域(动态高度) -->
|
||||||
|
<div class="content" :style="{ height: tableHeight + 'px', overflow: 'auto' }">
|
||||||
|
<div v-if="currentTab === 'system'">系统参数内容</div>
|
||||||
|
<div v-else-if="currentTab === 'charge_sate'">充电费率内容</div>
|
||||||
|
<div v-else-if="currentTab === 'invoice'">发票配置内容</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 固定在底部的提交按钮 -->
|
||||||
|
<div class="footer">
|
||||||
|
<Button type="primary" @click="submitForm">提交</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: true,
|
||||||
|
tableHeight: 500, // 初始高度,单位px
|
||||||
|
currentTab: 'system',
|
||||||
|
tab: [{
|
||||||
|
type: 'system',
|
||||||
|
name: '系统参数',
|
||||||
|
check: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'charge_sate',
|
||||||
|
name: '充电费率',
|
||||||
|
check: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'invoice',
|
||||||
|
name: '发票配置',
|
||||||
|
check: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.calculateTableHeight()
|
||||||
|
window.addEventListener('resize', this.calculateTableHeight)
|
||||||
|
// 添加防抖处理,避免频繁计算
|
||||||
|
this.debouncedCalculate = this.$utils.debounce(this.calculateTableHeight, 100)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.debouncedCalculate)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
calculateTableHeight() {
|
||||||
|
try {
|
||||||
|
const container = this.$el
|
||||||
|
const tabHeader = this.$refs.tabHeader
|
||||||
|
const footer = container.querySelector('.footer')
|
||||||
|
|
||||||
|
if (!container || !tabHeader || !footer) return
|
||||||
|
|
||||||
|
// 计算可用高度 = 容器高度 - tab高度 - footer高度 - 内边距
|
||||||
|
const containerHeight = container.clientHeight
|
||||||
|
const tabHeight = tabHeader.offsetHeight
|
||||||
|
const footerHeight = footer.offsetHeight
|
||||||
|
const padding = 40 // 上下内边距总和
|
||||||
|
|
||||||
|
this.tableHeight = containerHeight - tabHeight - footerHeight - padding
|
||||||
|
|
||||||
|
// 设置最小高度,避免内容区域太小
|
||||||
|
this.tableHeight = Math.max(this.tableHeight, 200)
|
||||||
|
} catch (e) {
|
||||||
|
// console.error('计算高度出错:', e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleClose() {
|
||||||
|
this.show = false
|
||||||
|
},
|
||||||
|
changeTab(index) {
|
||||||
|
this.tab.forEach((item, i) => {
|
||||||
|
item.check = i === index
|
||||||
|
})
|
||||||
|
this.currentTab = this.tab[index].type
|
||||||
|
},
|
||||||
|
submitForm() {
|
||||||
|
// console.log('提交表单')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab_children {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: #ccc;
|
||||||
|
color: #000;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab_children:hover {
|
||||||
|
background: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
/* 防止内容区域被压缩 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: white;
|
||||||
|
padding: 15px 0;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
6
tests/unit/utils.spec.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { defaultDocumentTitle, getDocumentTitle } from '@/utils'
|
||||||
|
|
||||||
|
it('getDocumentTitle test', () => {
|
||||||
|
const title = '这是一个测试'
|
||||||
|
expect(getDocumentTitle(title)).toMatch(`${defaultDocumentTitle} - ${title}`)
|
||||||
|
})
|
||||||
124
update.md
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
## 更新日志
|
||||||
|
### 2020.8.30 更新
|
||||||
|
* build: 打包后的文件从绝对路径改成相对路径,也就是说打包后的文件不能放在服务器根目录下。
|
||||||
|
### 2020.8.14 更新
|
||||||
|
* new: loading 从 `components/Index.vue` 挪到了 `App.vue`。axios 从 `components/Index.vue` 挪到了 `utils/request.js`,并对其进行了封装,方便复用。
|
||||||
|
* new: 重构了 loading 和 axios 拦截器使用方式,并提供了一个 ajax DEMO 放在首页。
|
||||||
|
### 2020.6.5 更新
|
||||||
|
* new: 新增外链功能,点击菜单可以跳到一个新页面,地址为指定的 URL。
|
||||||
|
* new: 新增独立路由页面功能,点击侧边栏可以跳转到单独的路由页面(铺满屏幕,顶级路由)。
|
||||||
|
|
||||||
|
具体示例请查看源码 `src/store/index` 和 [demo](https://woai3c.github.io/)
|
||||||
|
### 2019.12.21 更新
|
||||||
|
* refactor: 将 `404` 页面独立出来,单独展示(占满屏幕)
|
||||||
|
* new: [新增 eslint,配合 vscode 可以自动格式化代码](https://github.com/woai3c/Front-end-articles/blob/master/eslint-vscode-format.md)
|
||||||
|
* new: 新增 jest 单元测试
|
||||||
|
* new: 页面标题 `document.title`,在 `src/utils/index` 下可设置默认的 `title`,在每个路由配置项上可设置对应的 `title`,具体示例请看代码
|
||||||
|
|
||||||
|
### 2019.12.13 更新
|
||||||
|
* fix: 修复在IE下关闭标签栏时,页面抖动的问题
|
||||||
|
* refactor: 同时将左右两栏的布局方式从 flex 布局更改为 fixed + margin 的方式
|
||||||
|
|
||||||
|
### 2019.10.30 更新
|
||||||
|
* new: 在对应的菜单项上添加 `hidden` 属性,即可隐藏对应的菜单项,但还是可以在地址栏上输入对应的 URL 来访问页面。
|
||||||
|
使用方法
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 't1',
|
||||||
|
text: '表格',
|
||||||
|
hidden: true, // 隐藏此菜单 可以通过在地址栏上输入对应的 URL 来显示页面
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2019.10.14 更新
|
||||||
|
* fix: 修复窗口宽度过小不会收缩侧边栏的问题
|
||||||
|
* new: 打开页面时,默认展开和路由对应的菜单栏
|
||||||
|
|
||||||
|
### 2019.8.19 更新
|
||||||
|
* fix: `components/Index.vue` 文件第 31 行代码的 `v-show="isShowAsideTitle"` 会造成侧边栏收缩时二级菜单隐藏,目前已修复。
|
||||||
|
### 2019.7.24 更新
|
||||||
|
* new: 增加页面进度条,跳转时显示
|
||||||
|
|
||||||
|
### 2019.6.25 更新
|
||||||
|
* fix: 修复路由表冲突问题
|
||||||
|
|
||||||
|
退出当前用户,换账号重新登陆时,上个账号和现在的账号路由表会有冲突的问题,解决办法是在退出登陆时重置路由表。
|
||||||
|
|
||||||
|
具体实现请查看 `router/index.js`、`Login.vue` 和 `Index.vue` 的退出登陆回调方法。
|
||||||
|
|
||||||
|
### 2019.6.18 更新
|
||||||
|
* new: 优化动态添加路由功能
|
||||||
|
|
||||||
|
以前的动态路由功能并不完善,首先要将所有的路由都添加到路由表里,然后根据后台返回的菜单栏数据来生成菜单。
|
||||||
|
|
||||||
|
导致的问题就是,虽然有页面在菜单栏上不显示,但由于已经添加到路由表里了,所以可以在地址栏上手动输入在菜单栏上不存在(但在路由表存在)的页面,进而可以越权访问。
|
||||||
|
|
||||||
|
现在除了必要的页面需要在一开始添加到路由表里,其他的页面都可以根据后台数据来自动生成。而且菜单栏上没有的页面,在地址栏上输入地址也是访问不了的。
|
||||||
|
|
||||||
|
另外,如果在未登陆时要访问某一指定页面,会重定向到登陆页,登陆成功后会自动跳到这个指定页面。
|
||||||
|
|
||||||
|
具体实现请看 `permission.js` 和 `util` 目录下的 `index.js` 文件
|
||||||
|
|
||||||
|
### 2019.3.14 更新
|
||||||
|
|
||||||
|
* new: 增加404页面
|
||||||
|
|
||||||
|
假如跳转到一个不存在的页面时会重定向到404页面
|
||||||
|
|
||||||
|
### 2019.3.8 更新
|
||||||
|
|
||||||
|
* new: 增加面包屑功能 用于展示当前页面的路径
|
||||||
|
|
||||||
|
* new: 增加权限控制功能,如果未登陆,访问所有页面都重定向到登陆页
|
||||||
|
|
||||||
|
### 2019.3.1 更新
|
||||||
|
* new: 增加动态菜单栏功能
|
||||||
|
|
||||||
|
菜单项中的 `icon` 使用的是 `iview` 组件的 `icon` 组件。
|
||||||
|
|
||||||
|
数据格式:
|
||||||
|
```js
|
||||||
|
// 左侧菜单栏数据
|
||||||
|
menuItems: [
|
||||||
|
{
|
||||||
|
name: 'Home', // 要跳转的路由名称 不是路径
|
||||||
|
size: 18, // icon大小 非必填
|
||||||
|
type: 'md-home', // icon类型 非必填
|
||||||
|
text: '主页' // 文本内容
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '二级菜单',
|
||||||
|
type: 'ios-paper',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-grid',
|
||||||
|
name: 'T1',
|
||||||
|
text: '表格',
|
||||||
|
hidden: true, // 可以在菜单中隐藏此菜单项,但还是可以访问此页面,只是不能在菜单栏中看见。
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '三级菜单',
|
||||||
|
type: 'ios-paper',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type: 'ios-notifications-outline',
|
||||||
|
name: 'Msg',
|
||||||
|
text: '查看消息'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'md-lock',
|
||||||
|
name: 'Password',
|
||||||
|
text: '修改密码'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'md-person',
|
||||||
|
name: 'UserInfo',
|
||||||
|
text: '基本资料',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
15
vue.config.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
module.exports = {
|
||||||
|
devServer: {
|
||||||
|
proxy: {
|
||||||
|
'/chargingapi': {
|
||||||
|
target: 'https://www.cqaijing.top', // 对应自己的接口
|
||||||
|
changeOrigin: true,
|
||||||
|
ws: true,
|
||||||
|
pathRewrite: {
|
||||||
|
'^/chargingapi': '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
publicPath: './',
|
||||||
|
}
|
||||||