init
26
.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
15
babel.config.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
'@babel/preset-env',
|
||||||
|
{
|
||||||
|
modules: false,
|
||||||
|
targets: {
|
||||||
|
browsers: ['>1%', 'last 2 versions', 'not ie <= 8']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'@vue/babel-preset-jsx'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
76
build.bat
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
echo ================================
|
||||||
|
echo Admin Framework 构建工具
|
||||||
|
echo ================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM 检查 Node.js 是否安装
|
||||||
|
where node >nul 2>nul
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo ❌ 错误: 未检测到 Node.js,请先安装 Node.js
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
for /f "tokens=*" %%i in ('node -v') do set NODE_VERSION=%%i
|
||||||
|
for /f "tokens=*" %%i in ('npm -v') do set NPM_VERSION=%%i
|
||||||
|
|
||||||
|
echo ✅ Node.js 版本: %NODE_VERSION%
|
||||||
|
echo ✅ NPM 版本: %NPM_VERSION%
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM 检查是否已安装依赖
|
||||||
|
if not exist "node_modules" (
|
||||||
|
echo 📦 正在安装依赖...
|
||||||
|
call npm install
|
||||||
|
if !errorlevel! neq 0 (
|
||||||
|
echo ❌ 依赖安装失败
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
echo ✅ 依赖安装成功
|
||||||
|
echo.
|
||||||
|
) else (
|
||||||
|
echo ✅ 依赖已安装
|
||||||
|
echo.
|
||||||
|
)
|
||||||
|
|
||||||
|
REM 执行打包
|
||||||
|
echo 🔨 正在打包框架...
|
||||||
|
call npm run build
|
||||||
|
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
echo.
|
||||||
|
echo ================================
|
||||||
|
echo ✅ 打包成功!
|
||||||
|
echo ================================
|
||||||
|
echo.
|
||||||
|
echo 📦 输出文件: dist\admin-framework.js
|
||||||
|
|
||||||
|
REM 显示文件大小
|
||||||
|
if exist "dist\admin-framework.js" (
|
||||||
|
for %%A in (dist\admin-framework.js) do (
|
||||||
|
set SIZE=%%~zA
|
||||||
|
set /a SIZE_KB=!SIZE! / 1024
|
||||||
|
echo 📊 文件大小: !SIZE_KB! KB
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo 📚 下一步:
|
||||||
|
echo 1. 将 dist\admin-framework.js 复制到你的项目
|
||||||
|
echo 2. 查看 QUICK_START.md 了解如何使用
|
||||||
|
echo 3. 查看 USAGE_EXAMPLE.md 了解详细示例
|
||||||
|
echo.
|
||||||
|
) else (
|
||||||
|
echo.
|
||||||
|
echo ❌ 打包失败,请检查错误信息
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
pause
|
||||||
|
|
||||||
65
build.sh
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Admin Framework 构建脚本
|
||||||
|
|
||||||
|
echo "================================"
|
||||||
|
echo " Admin Framework 构建工具"
|
||||||
|
echo "================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查 Node.js 是否安装
|
||||||
|
if ! command -v node &> /dev/null
|
||||||
|
then
|
||||||
|
echo "❌ 错误: 未检测到 Node.js,请先安装 Node.js"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Node.js 版本: $(node -v)"
|
||||||
|
echo "✅ NPM 版本: $(npm -v)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查是否已安装依赖
|
||||||
|
if [ ! -d "node_modules" ]; then
|
||||||
|
echo "📦 正在安装依赖..."
|
||||||
|
npm install
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ 依赖安装失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✅ 依赖安装成功"
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo "✅ 依赖已安装"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行打包
|
||||||
|
echo "🔨 正在打包框架..."
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "================================"
|
||||||
|
echo " ✅ 打包成功!"
|
||||||
|
echo "================================"
|
||||||
|
echo ""
|
||||||
|
echo "📦 输出文件: dist/admin-framework.js"
|
||||||
|
|
||||||
|
# 显示文件大小
|
||||||
|
if [ -f "dist/admin-framework.js" ]; then
|
||||||
|
SIZE=$(du -h dist/admin-framework.js | cut -f1)
|
||||||
|
echo "📊 文件大小: $SIZE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📚 下一步:"
|
||||||
|
echo " 1. 将 dist/admin-framework.js 复制到你的项目"
|
||||||
|
echo " 2. 查看 QUICK_START.md 了解如何使用"
|
||||||
|
echo " 3. 查看 USAGE_EXAMPLE.md 了解详细示例"
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "❌ 打包失败,请检查错误信息"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
4861
package-lock.json
generated
Normal file
49
package.json
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "admin-framework",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "通用后台管理系统框架 - 包含系统功能、登录、路由管理、布局等",
|
||||||
|
"main": "dist/admin-framework.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --mode production",
|
||||||
|
"dev": "webpack --mode development --watch"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"admin",
|
||||||
|
"framework",
|
||||||
|
"vue",
|
||||||
|
"management-system"
|
||||||
|
],
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"axios": "^0.21.0",
|
||||||
|
"view-design": "^4.0.0",
|
||||||
|
"vue": "^2.6.0",
|
||||||
|
"vue-router": "^3.0.0",
|
||||||
|
"vuex": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/babel-preset-jsx": "^1.4.0",
|
||||||
|
"brace": "^0.11.1",
|
||||||
|
"dayjs": "^1.10.0",
|
||||||
|
"js-cookie": "^2.2.1",
|
||||||
|
"vue2-ace-editor": "^0.0.15",
|
||||||
|
"vuex-persistedstate": "^4.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.12.0",
|
||||||
|
"@babel/preset-env": "^7.12.0",
|
||||||
|
"babel-loader": "^8.2.0",
|
||||||
|
"css-loader": "^5.0.0",
|
||||||
|
"file-loader": "^6.2.0",
|
||||||
|
"less": "^4.0.0",
|
||||||
|
"less-loader": "^7.0.0",
|
||||||
|
"style-loader": "^2.0.0",
|
||||||
|
"url-loader": "^4.1.0",
|
||||||
|
"vue-loader": "^15.9.0",
|
||||||
|
"vue-style-loader": "^4.1.0",
|
||||||
|
"vue-template-compiler": "^2.6.0",
|
||||||
|
"webpack": "^5.0.0",
|
||||||
|
"webpack-cli": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/api/system/fileServe.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class FileServe {
|
||||||
|
async upload_oos_img(row) {
|
||||||
|
let res = await http.postFormData("/sys_file/upload_oos_img", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async upload_Img(row) {
|
||||||
|
let res = await http.postFormData("/file/upload_Img", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileServe = new FileServe();
|
||||||
|
export default fileServe;
|
||||||
51
src/api/system/hot_city_qr_config_server.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import http from '@/utils/http';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 热门城市二维码配置相关API
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 获取配置列表
|
||||||
|
const getHotCityQrConfigList = (params) => {
|
||||||
|
return http.get('/wch_hot_city_qr_config/list', { params });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取所有配置
|
||||||
|
const getAllHotCityQrConfig = () => {
|
||||||
|
return http.get('/wch_hot_city_qr_config/all');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取配置详情
|
||||||
|
const getHotCityQrConfigDetail = (id) => {
|
||||||
|
return http.get(`/wch_hot_city_qr_config/detail/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建配置
|
||||||
|
const createHotCityQrConfig = (data) => {
|
||||||
|
return http.post('/wch_hot_city_qr_config/create', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新配置
|
||||||
|
const updateHotCityQrConfig = (id, data) => {
|
||||||
|
return http.post(`/wch_hot_city_qr_config/update/${id}`, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除配置
|
||||||
|
const deleteHotCityQrConfig = (id) => {
|
||||||
|
return http.post(`/wch_hot_city_qr_config/delete/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 批量删除配置
|
||||||
|
const batchDeleteHotCityQrConfig = (ids) => {
|
||||||
|
return http.post('/wch_hot_city_qr_config/batch_delete', { ids });
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getHotCityQrConfigList,
|
||||||
|
getAllHotCityQrConfig,
|
||||||
|
getHotCityQrConfigDetail,
|
||||||
|
createHotCityQrConfig,
|
||||||
|
updateHotCityQrConfig,
|
||||||
|
deleteHotCityQrConfig,
|
||||||
|
batchDeleteHotCityQrConfig
|
||||||
|
};
|
||||||
|
|
||||||
17
src/api/system/index.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// 系统 API 统一导出
|
||||||
|
|
||||||
|
export { default as fileServe } from './fileServe'
|
||||||
|
export { default as hotCityQrConfigServer } from './hot_city_qr_config_server'
|
||||||
|
export { default as plaAccountServer } from './pla_account_server'
|
||||||
|
export { default as rolePermissionServer } from './rolePermissionServer'
|
||||||
|
export { default as roleServer } from './roleServer'
|
||||||
|
export { default as shpProfitServer } from './shpProfitServer'
|
||||||
|
export { default as specificationServer } from './specificationServer'
|
||||||
|
export { default as sysAddressServer } from './sysAddressServer'
|
||||||
|
export { default as sysModuleServer } from './sysModuleServer'
|
||||||
|
export { default as sysLogServe } from './sys_log_serve'
|
||||||
|
export { default as systemTypeServer } from './systemType_server'
|
||||||
|
export { default as tableServer } from './tableServer'
|
||||||
|
export { default as userServer } from './userServer'
|
||||||
|
export { default as wchProfessionsServer } from './wch_professions_server'
|
||||||
|
|
||||||
38
src/api/system/pla_account_server.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import http from '@/utils/http'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// 获取所有平台账户
|
||||||
|
all(param) {
|
||||||
|
return http.get('/pla_account/all', param)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取平台账户详情
|
||||||
|
detail(param) {
|
||||||
|
return http.get('/pla_account/detail', param)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 分页查询平台账户
|
||||||
|
page(param) {
|
||||||
|
return http.post('/pla_account/page', param)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增平台账户
|
||||||
|
add(param) {
|
||||||
|
return http.post('/pla_account/add', param)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 编辑平台账户
|
||||||
|
edit(param) {
|
||||||
|
return http.post('/pla_account/edit', param)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除平台账户
|
||||||
|
del(param) {
|
||||||
|
return http.post('/pla_account/del', param)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出平台账户数据
|
||||||
|
exportCsv(param) {
|
||||||
|
return http.post('/pla_account/export', param)
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/api/system/rolePermissionServer.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import http from '@/utils/http'
|
||||||
|
class RolePermissionServer {
|
||||||
|
async getRoles(callback) {
|
||||||
|
let res = await http.get('/SysRolePermission/Query', {})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRole(row) {
|
||||||
|
let res = await http.get('/SysRolePermission/QueryByRoleId', row)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post('/SysRolePermission/add', row)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post('/SysRolePermission/edit', row)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post('/SysRolePermission/del', row)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rolePermissionServer = new RolePermissionServer()
|
||||||
|
export default rolePermissionServer
|
||||||
26
src/api/system/roleServer.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class RoleServer {
|
||||||
|
async list() {
|
||||||
|
let res = await http.get("/sys_role/index", {});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_role/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_role/edit", row);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_role/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const roleServer = new RoleServer();
|
||||||
|
export default roleServer;
|
||||||
15
src/api/system/shpProfitServer.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import http from '@/utils/http'
|
||||||
|
class ShpProfitServer {
|
||||||
|
async report(param) {
|
||||||
|
let res = await http.post('/shpProfit/report', param)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async list(param) {
|
||||||
|
let res = await http.post('/shpProfit/list', param)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shpProfitServer = new ShpProfitServer()
|
||||||
|
export default shpProfitServer
|
||||||
25
src/api/system/specificationServer.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import http from '@/utils/http'
|
||||||
|
class SpecificationServer {
|
||||||
|
async list() {
|
||||||
|
let res = await http.post('/specification/list', {})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post('/specification/add', row)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post('/specification/edit', row)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post('/specification/del', row)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const specificationServer = new SpecificationServer()
|
||||||
|
export default specificationServer
|
||||||
10
src/api/system/sysAddressServer.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class SysAddress {
|
||||||
|
async index(param) {
|
||||||
|
let res = await http.get("/sys_address/index", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sysAddress = new SysAddress();
|
||||||
|
export default sysAddress;
|
||||||
30
src/api/system/sysModuleServer.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class SysModuleServer {
|
||||||
|
async all() {
|
||||||
|
let res = await http.get("/sys_menu/all", {});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async list(row) {
|
||||||
|
let res = await http.get("/sys_menu/all", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_menu/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_menu/edit", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_menu/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sysModuleServer = new SysModuleServer();
|
||||||
|
export default sysModuleServer;
|
||||||
30
src/api/system/sys_log_serve.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class SysLogServe {
|
||||||
|
async all(param) {
|
||||||
|
let res = await http.get("/sys_log/all", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async detail(param) {
|
||||||
|
let res = await http.get("/sys_log/detail", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(param) {
|
||||||
|
let res = await http.get("/sys_log/delete", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete_all(param) {
|
||||||
|
let res = await http.get("/sys_log/delete_all", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async operates(param) {
|
||||||
|
let res = await http.get("/sys_log/operates", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sys_log_serve = new SysLogServe();
|
||||||
|
export default sys_log_serve;
|
||||||
38
src/api/system/systemType_server.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import http from '@/utils/http';
|
||||||
|
class systemTypeClServer {
|
||||||
|
async all(param) {
|
||||||
|
let res= await http.get('/sys_project_type/all', param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async page(row) {
|
||||||
|
let res= await http.post('/sys_project_type/page', row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async exportCsv(row) {
|
||||||
|
let res = http.fileExport("/sys_project_type/export", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res= await http.post('/sys_project_type/add', row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res= await http.post('/sys_project_type/edit', row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res= await http.post('/sys_project_type/del', row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const systemTypeServer = new systemTypeClServer();
|
||||||
|
export default systemTypeServer;
|
||||||
|
|
||||||
31
src/api/system/tableServer.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import http from '@/utils/http'
|
||||||
|
class TableServer {
|
||||||
|
async getAll(callback) {
|
||||||
|
return await http.get('/table/index', {})
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row, callback) {
|
||||||
|
return await http.post('/table/add', row)
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row, callback) {
|
||||||
|
return await http.post('/table/edit', row, function(res) {
|
||||||
|
callback && callback(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row, callback) {
|
||||||
|
return await http.post('/table/del', row)
|
||||||
|
}
|
||||||
|
|
||||||
|
async autoApi(id) {
|
||||||
|
return await http.get('/template/api', { id: id })
|
||||||
|
}
|
||||||
|
|
||||||
|
async autoDb(id) {
|
||||||
|
return await http.get('/template/autoDb', { id: id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableServer = new TableServer()
|
||||||
|
export default tableServer
|
||||||
40
src/api/system/userServer.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class UserServer {
|
||||||
|
async login(row) {
|
||||||
|
let res = await http.post("/sys_user/login", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async all() {
|
||||||
|
let res = await http.get("/sys_user/index", {});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async exportCsv(row) {
|
||||||
|
let res = http.fileExport("/sys_user/export", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async authorityMenus() {
|
||||||
|
let res = await http.post("/sys_user/authorityMenus", {});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_user/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_user/edit", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_user/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const userServer = new UserServer();
|
||||||
|
export default userServer;
|
||||||
33
src/api/system/wch_professions_server.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import http from '@/utils/http'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// 获取职业列表
|
||||||
|
page: (params) => {
|
||||||
|
return http.post('/wch_professions/page', params)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取所有职业
|
||||||
|
all: (params) => {
|
||||||
|
return http.post('/wch_professions/all', params)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增职业
|
||||||
|
add: (params) => {
|
||||||
|
return http.post('/wch_professions/add', params)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新职业
|
||||||
|
edit: (params) => {
|
||||||
|
return http.post('/wch_professions/edit', params)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除职业
|
||||||
|
del: (params) => {
|
||||||
|
return http.post('/wch_professions/del', params)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出职业数据
|
||||||
|
exportCsv: (params) => {
|
||||||
|
return http.post('/wch_professions/exportCsv', params)
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/api/system_high/formFieldServer.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class FormFieldServer {
|
||||||
|
async all(param) {
|
||||||
|
let res = await http.get("/sys_form_field/all", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async page(row) {
|
||||||
|
let res = await http.post("/sys_form_field/page", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_form_field/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_form_field/edit", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_form_field/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const formFieldServer = new FormFieldServer();
|
||||||
|
export default formFieldServer;
|
||||||
35
src/api/system_high/formServer.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class FormServer {
|
||||||
|
async all(param) {
|
||||||
|
let res = await http.get("/sys_form/all", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async page(row) {
|
||||||
|
let res = await http.post("/sys_form/page", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async generate(row) {
|
||||||
|
let res = await http.post("/sys_form/generate", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_form/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_form/edit", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_form/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const formServer = new FormServer();
|
||||||
|
export default formServer;
|
||||||
10
src/api/system_high/index.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// 高级系统 API 统一导出
|
||||||
|
|
||||||
|
export { default as formFieldServer } from './formFieldServer'
|
||||||
|
export { default as formServer } from './formServer'
|
||||||
|
export { default as menuServer } from './menuServer'
|
||||||
|
export { default as modelFieldServer } from './modelFieldServer'
|
||||||
|
export { default as modelServer } from './modelServer'
|
||||||
|
export { default as paramSetupServer } from './paramSetupServer'
|
||||||
|
export { default as sysControlTypeServer } from './sysControlTypeServer'
|
||||||
|
|
||||||
49
src/api/system_high/menuServer.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
|
||||||
|
class MenuServer {
|
||||||
|
async list(row) {
|
||||||
|
let res = await http.get("/sys_menu/index", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async generate(row) {
|
||||||
|
let res = await http.post("/sys_menu/generate", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_menu/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_menu/edit", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_menu/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async generate(row) {
|
||||||
|
let res = await http.post("/form/generate", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
async generateModel(row) {
|
||||||
|
let res = await http.post("/model/generate", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async modelAll(row) {
|
||||||
|
let res = await http.post("/model/all", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
async modelInterface(row) {
|
||||||
|
let res = await http.post("/model/interface", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const menuServer = new MenuServer();
|
||||||
|
export default menuServer;
|
||||||
32
src/api/system_high/modelFieldServer.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class ModelFieldServer {
|
||||||
|
async all(row) {
|
||||||
|
let res = await http.get("/sys_model_field/all", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async allByKey(row) {
|
||||||
|
let res = await http.get("/sys_model_field/allByKey", row, {
|
||||||
|
hideLoad: true
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_model_field/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_model_field/edit", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_model_field/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const modelFieldServer = new ModelFieldServer();
|
||||||
|
export default modelFieldServer;
|
||||||
40
src/api/system_high/modelServer.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class ModelServer {
|
||||||
|
async interface(row) {
|
||||||
|
let res = await http.post("/sys_model/interface", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async all() {
|
||||||
|
let res = await http.get("/sys_model/all", {});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async detail(row) {
|
||||||
|
let res = await http.get("/sys_model/detail", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async regenerate(row) {
|
||||||
|
let res = await http.post("/sys_model/regenerate", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
let res = await http.post("/sys_model/add", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
let res = await http.post("/sys_model/edit", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
let res = await http.post("/sys_model/del", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const modelServer = new ModelServer();
|
||||||
|
export default modelServer;
|
||||||
29
src/api/system_high/paramSetupServer.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class ParamSetupServer {
|
||||||
|
async getAll() {
|
||||||
|
return await http.get("/sys_parameter/index", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOne(key) {
|
||||||
|
return await http.get("/sys_parameter/key", { key });
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(row) {
|
||||||
|
return await http.post("/sys_parameter/add", row);
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(row) {
|
||||||
|
return await http.post("/sys_parameter/edit", row);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setSysConfig(row) {
|
||||||
|
return await http.post("/sys_parameter/setSysConfig", row);
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(row) {
|
||||||
|
return await http.post("/sys_parameter/del", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const paramSetupServer = new ParamSetupServer();
|
||||||
|
export default paramSetupServer;
|
||||||
29
src/api/system_high/sysControlTypeServer.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import http from "@/utils/http";
|
||||||
|
class SysControlTypeServer {
|
||||||
|
async all(param) {
|
||||||
|
let res = await http.get("/sys_control_type/all", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async page(row) {
|
||||||
|
let res = await http.post("/sys_control_type/page", row);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(param) {
|
||||||
|
let res = await http.post("/sys_control_type/add", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(param) {
|
||||||
|
let res = await http.post("/sys_control_type/edit", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
async del(param) {
|
||||||
|
let res = await http.post("/sys_control_type/del", param);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sysControlTypeServer = new SysControlTypeServer();
|
||||||
|
export default sysControlTypeServer;
|
||||||
3688
src/assets/css/animate.css
vendored
Normal file
149
src/assets/css/base.less
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
body,
|
||||||
|
div,
|
||||||
|
dl,
|
||||||
|
dt,
|
||||||
|
dd,
|
||||||
|
ul,
|
||||||
|
ol,
|
||||||
|
li,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
pre,
|
||||||
|
code,
|
||||||
|
form,
|
||||||
|
fieldset,
|
||||||
|
legend,
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
textarea,
|
||||||
|
p,
|
||||||
|
blockquote,
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #fff;
|
||||||
|
color: #495060;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th,
|
||||||
|
caption {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #495060;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
select,
|
||||||
|
button {
|
||||||
|
font: 14px Verdana, Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*滚动条整体样式*/
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
/*高宽分别对应横竖滚动条的尺寸*/
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
/*滚动条里面小方块*/
|
||||||
|
border-radius: 5px;
|
||||||
|
-webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.1);
|
||||||
|
background: #9ca6bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
/*滚动条里面轨道*/
|
||||||
|
-webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.1);
|
||||||
|
border-radius: 5px;
|
||||||
|
background: #dcdee2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml(@i) when(@i <= 300) {
|
||||||
|
.ml@{i} {
|
||||||
|
margin-left: @i + 0px;
|
||||||
|
}
|
||||||
|
.ml((@i + 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml(5);
|
||||||
|
|
||||||
|
.mt(@i) when(@i <= 100) {
|
||||||
|
.mt@{i} {
|
||||||
|
margin-top: @i + 0px;
|
||||||
|
}
|
||||||
|
.mt((@i + 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt(5);
|
||||||
|
|
||||||
|
.pa(@i) when(@i <= 100) {
|
||||||
|
.pa@{i} {
|
||||||
|
padding: @i + 0px;
|
||||||
|
}
|
||||||
|
.pa((@i + 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.pa(5);
|
||||||
|
|
||||||
|
.w(@i) when(@i <= 100) {
|
||||||
|
.w@{i} {
|
||||||
|
width: @i + 0%;
|
||||||
|
}
|
||||||
|
.w((@i + 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.w(5);
|
||||||
|
|
||||||
|
.h(@i) when(@i <= 100) {
|
||||||
|
.h@{i} {
|
||||||
|
height: @i + 0%;
|
||||||
|
}
|
||||||
|
.h((@i + 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.h(5);
|
||||||
322
src/assets/css/ivewExpand.less
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
.ace_print-margin-layer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-select-dropdown {
|
||||||
|
z-index: 999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-select-dropdown-list {
|
||||||
|
height: 200px !important;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-right {
|
||||||
|
float: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.ivu-tooltip-inner {
|
||||||
|
background: #fff;
|
||||||
|
color: #495060;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-left {
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-layout-header {
|
||||||
|
background-color: #f5f7f9;
|
||||||
|
|
||||||
|
padding: 0px 0.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt10 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt20 {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt30 {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml5 {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml10 {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml20 {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml30 {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml100 {
|
||||||
|
margin-left: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pa-5 {
|
||||||
|
padding: 0.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pa-10 {
|
||||||
|
padding: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pa-20 {
|
||||||
|
padding: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pa-30 {
|
||||||
|
padding: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buld {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-element {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-warp {
|
||||||
|
.ivu-card-body {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-e-text-container {
|
||||||
|
min-height: 800px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-card-body {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-btn {
|
||||||
|
margin: 0px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-tool-box {
|
||||||
|
padding: 5px;
|
||||||
|
background-color: #dcdee2;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h50 {
|
||||||
|
height: 0.5rem;
|
||||||
|
line-height: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr10 {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-view {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 5px;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.table-head-tool {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
line-height: 35px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.ivu-form-item {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-table-cell {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 自适应表格宽度 */
|
||||||
|
.ivu-table-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-table {
|
||||||
|
width: 100% !important;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移除 table-layout: auto,使用 iView 默认的 fixed 布局以确保列对齐 */
|
||||||
|
/* .ivu-table table {
|
||||||
|
table-layout: auto;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.ivu-table-body {
|
||||||
|
overflow-y: auto;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮风格一致 */
|
||||||
|
.ivu-btn {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-btn + .ivu-btn {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 常用按钮容器(可选) */
|
||||||
|
.btn-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrowBox {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
width: 13px;
|
||||||
|
height: 50px;
|
||||||
|
margin-top: -25px;
|
||||||
|
top: 49%;
|
||||||
|
right: 1px;
|
||||||
|
background-color: #043250;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.ivu-icon {
|
||||||
|
position: relative;
|
||||||
|
font-size: 36px;
|
||||||
|
color: #515a6e;
|
||||||
|
top: 8px;
|
||||||
|
left: -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-badge-count {
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetime-box {
|
||||||
|
.ivu-date-picker-cells-cell:not(.ivu-date-picker-cells-cell-disabled) {
|
||||||
|
background-color: rgba(10, 255, 0, 0.3);
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-info {
|
||||||
|
color: #ff9900;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tc {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seach-input {
|
||||||
|
width: 300px;
|
||||||
|
float: right;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-right {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-num {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
margin: 5px;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
&.ivu-icon-md-arrow-up {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ivu-icon-md-arrow-down {
|
||||||
|
color: indianred;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.view-log-info
|
||||||
|
{
|
||||||
|
|
||||||
|
background-color: #292A2A;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 5px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
37
src/assets/icons/iconfont.css
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
@font-face {font-family: "iconfont";
|
||||||
|
src: url('iconfont.eot?t=1541579316141'); /* IE9*/
|
||||||
|
src: url('iconfont.eot?t=1541579316141#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||||
|
url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAiEAAsAAAAADmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8eUnXY21hcAAAAYAAAACjAAACLi+YJuBnbHlmAAACJAAABAgAAAcg4dRWHmhlYWQAAAYsAAAAMQAAADYTL8piaGhlYQAABmAAAAAgAAAAJAfdA4xobXR4AAAGgAAAABQAAAAsLAD//2xvY2EAAAaUAAAAGAAAABgImgpGbWF4cAAABqwAAAAfAAAAIAEcAG5uYW1lAAAGzAAAAUUAAAJtPlT+fXBvc3QAAAgUAAAAbgAAAI54roygeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMTx/ytzwv4EhhrmBoRkozAiSAwDuUwzMeJzlkUEKwkAMRd/YabXFhQvxFF6qPYPrUujGY7jyIr1JoZNjtMnEhag3MOEN5MMk8D9QAoVyVSKEJwGrh6oh6wVN1iM3nc+cVImJVKdOehlklElmWdYVstp+ql8VdIv15a1NLW0zFXsO7Kjz3erH/3+rY37vr6kxnx1LKNWOJZlaxxJNnWOpSu+ot8jgqMvI6KjfyOSo88jsaAbI4tBsig89rQB4nLVUTWwbRRSeNzO767i2g7N/FP9s7MRrE5ON4/V6rSZyU0PiINSSNImES4IUoapWz6hEiqiMBDQqEojkAkiFStyKRC+9VSoFCeUEyqESVUAqEkcu3OAQb3hrJxAXwSGI3X0/szPz5vvm2x0i7O/vf8IJe5VkSJnUyUtklRBQJE1VIjRtUafkmk6pSu2ipleh4+xikkKxSksWTUeo8m8NoagpYtoslTmxrLl37z64e33esuJjU8P5Wd262LxoPVnPZ06Pxfe+C0YjkhSJygPhQCA8ABPOykwuN7NyuRvgUnAgLEnhATkaCQQiUe/7XKUyV6nQz+t2o7l66+rs7NVbq82GXTdrdjxjRGU5amTids2bUDMFtzCsqsMYMqr3IDY6OT05GjsI8Exv/6CSkOWEQigh+y3clxY5QVTcEZFIGtHLxDUJs6WsHR1y9SFKdr1HggCp3V1ICYL36OOpVmvKN9bC1u6R3vZ0qwWtVovgJfqOfUvfIYxIWL+fyETHNVJqSkIT1JTjW8ZWh3yDJDz0ctvsyt51etvrg9/QHhqGlzMM+vbmizPnDWPLMNbW19e7tffvsBzL99aWEfBRY46t+tbe3PypXv/IMDYN43WsQBe9HL2NC33RuxABrPsG+xH3o4bVRE2KgCRqulbWNf8W/UYVHM129aKra24VshZkq+CWD/Oy6Xt8cGYEthgHVlVliCfynAlqjo6oysTKlYUAD4docMI5/1ZioN+GwZNBcTwWUmTdBUqhTwX29QebXzF4An4JJMzwfMl+WQ01+IlQZVR4yhie53ycA16pOI/ODiYNGK4MChdCgXNnX5gIJXPCSYnf2OF850aQ+zJIyOs+u8+mMO8jQdwtg1TIWVRjKAnFcslMi8KfGUPoSUCergUyUk77dMyS69Ms6tijKZKYwUGKbpfdzu+iYeZYAHMFiOVi+MD7h9mb99qC0L7X8c+XatMfTj97KZ5IxJt/pd43tYYQKEjAnXMOB6kQEBrwg+LPjindAPOHNdC3q3ait0I3/ZIunZEARLNYNEUA6czSP3N/7j9wz6ZESdX0VNl1zGNS/szbQaQSIGk4DtVPcZf8AgXpf9A2OyTit5s2syZmand46bhEe2WtodLHkvaoqtTXuXN2/c42WADP9HGfbUcUW7JgqHss4xHtlMys679FqUomdP9VJBQBdnlPABBubpuNwqnmQj6/0HwNQzKxDUJFgKiXurBG6dqFjmeBzsvtRPJgGIZThYa5fdOvsReOticPh6JHHXxsv7ItJpOniYPYsmZ/x0QD/o5P105DeQwF6MH33ogoLi+KQp7zpY3HQV5bFMURzheXeds7gpP+jKNXljjHuYvXHke7cdCxLLZf6YX7B63UcCV4nGNgZGBgAOKAN2ZR8fw2Xxm4WRhA4AbHYRMY/f///1oWBuYGIJeDgQkkCgAvWgs2AAAAeJxjYGRgYG7438AQw8Lw/z8DAwsDA1AEBXADAHXiBHJ4nGNhYGBgYfj/nwVM48cATwECKwAAAAAAjAC6AOgBFAGAAf4CbgLqAzgDkHicY2BkYGDgZkhiYGcAASYg5gJCBob/YD4DABOmAYsAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicbYhdDoIwEAb3a6k/YIIX8VArWewmdJFWJOnpJTG+OQ+TzJCjLy39p4ODR4OAA4444YwWHS7U3IVzn6Voldtb8ksHnvohrlqjjmw1rmzXsvdT7fEbblnCmOfNfJIYStJJfGIL27yb6AOCGR89AAA=') format('woff'),
|
||||||
|
url('iconfont.ttf?t=1541579316141') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||||
|
url('iconfont.svg?t=1541579316141#iconfont') format('svg'); /* iOS 4.1- */
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family:"iconfont" !important;
|
||||||
|
font-size:16px;
|
||||||
|
font-style:normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bear:before { content: "\e600"; }
|
||||||
|
|
||||||
|
.icon-resize-vertical:before { content: "\e7c3"; }
|
||||||
|
|
||||||
|
.icon-chuizhifanzhuan:before { content: "\e661"; }
|
||||||
|
|
||||||
|
.icon-shuipingfanzhuan:before { content: "\e662"; }
|
||||||
|
|
||||||
|
.icon-qq:before { content: "\e609"; }
|
||||||
|
|
||||||
|
.icon-frown:before { content: "\e77e"; }
|
||||||
|
|
||||||
|
.icon-meh:before { content: "\e780"; }
|
||||||
|
|
||||||
|
.icon-smile:before { content: "\e783"; }
|
||||||
|
|
||||||
|
.icon-man:before { content: "\e7e2"; }
|
||||||
|
|
||||||
|
.icon-woman:before { content: "\e7e5"; }
|
||||||
|
|
||||||
BIN
src/assets/icons/iconfont.eot
Normal file
56
src/assets/icons/iconfont.svg
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||||
|
<!--
|
||||||
|
2013-9-30: Created.
|
||||||
|
-->
|
||||||
|
<svg>
|
||||||
|
<metadata>
|
||||||
|
Created by iconfont
|
||||||
|
</metadata>
|
||||||
|
<defs>
|
||||||
|
|
||||||
|
<font id="iconfont" horiz-adv-x="1024" >
|
||||||
|
<font-face
|
||||||
|
font-family="iconfont"
|
||||||
|
font-weight="500"
|
||||||
|
font-stretch="normal"
|
||||||
|
units-per-em="1024"
|
||||||
|
ascent="896"
|
||||||
|
descent="-128"
|
||||||
|
/>
|
||||||
|
<missing-glyph />
|
||||||
|
|
||||||
|
<glyph glyph-name="bear" unicode="" d="M1024 683.008q0-70.656-46.08-121.856 46.08-89.088 46.08-193.536 0-96.256-39.936-181.248t-109.568-147.968-162.816-99.328-199.68-36.352-199.68 36.352-162.304 99.328-109.568 147.968-40.448 181.248q0 104.448 46.08 193.536-46.08 51.2-46.08 121.856 0 37.888 13.824 71.168t37.376 58.368 55.808 39.424 68.096 14.336q43.008 0 78.848-18.432t59.392-50.176q46.08 17.408 96.256 26.624t102.4 9.216 102.4-9.216 96.256-26.624q24.576 31.744 59.904 50.176t78.336 18.432q36.864 0 68.608-14.336t55.296-39.424 37.376-58.368 13.824-71.168zM205.824 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512-31.744000000000028q53.248 0 99.84 13.312t81.408 35.84 54.784 52.736 19.968 65.024q0 33.792-19.968 64t-54.784 52.736-81.408 35.84-99.84 13.312-99.84-13.312-81.408-35.84-54.784-52.736-19.968-64q0-34.816 19.968-65.024t54.784-52.736 81.408-35.84 99.84-13.312zM818.176 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512 235.51999999999998q39.936 0 68.096-9.728t28.16-24.064-28.16-24.064-68.096-9.728-68.096 9.728-28.16 24.064 28.16 24.064 68.096 9.728z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="resize-vertical" unicode="" d="M512 896C229.248 896 0 666.752 0 384s229.248-512 512-512 512 229.248 512 512S794.752 896 512 896zM576 192l64 0-128-128-128 128 64 0L448 576l-64 0 128 128 128-128-64 0L576 192z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="chuizhifanzhuan" unicode="" d="M286.01856 645.08416l472.4224 0 0-146.2784-472.4224 0 0 146.2784ZM87.19872 420.37248l885.80096 0 0-70.87104-885.80096 0 0 70.87104ZM773.55008 268.05248l0-31.0016L270.6688 237.05088l0 31.0016L773.55008 268.05248zM773.55008 121.4208l0-31.0016L270.6688 90.4192l0 31.0016L773.55008 121.4208zM742.54848 240.75776l31.0016 0 0-123.04896-31.0016 0L742.54848 240.75776zM270.70464 240.57856l31.0016 0 0-123.04896-31.0016 0L270.70464 240.57856z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="shuipingfanzhuan" unicode="" d="M252.76928 596.096l146.2784 0 0-472.42752-146.2784 0 0 472.42752ZM477.48096 810.65472l70.87104 0 0-885.80608-70.87104 0 0 885.80608ZM629.80096 611.2l31.0016 0 0-502.88128-31.0016 0L629.80096 611.2zM776.42752 611.2l31.0016 0 0-502.88128-31.0016 0L776.42752 611.2zM657.09056 580.1984l0 31.0016 123.04896 0 0-31.0016L657.09056 580.1984zM657.27488 108.35456l0 31.0016 123.04896 0 0-31.0016L657.27488 108.35456z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="qq" unicode="" d="M147.372058 491.394284c-5.28997-13.909921 2.431986-22.698872 0-75.732573-0.682996-14.25092-62.165649-78.762555-86.569511-145.791177-24.192863-66.517625-27.519845-135.978232 9.811944-163.285078 37.419789-27.305846 72.191593 90.879487 76.757567 73.685584 1.961989-7.509958 4.436975-15.317914 7.423958-23.338868a331.945126 331.945126 0 0 1 61.140655-101.162429c5.929967-6.783962-36.009797-19.199892-61.140655-61.99365-25.173858-42.751759 7.209959-120.49032 132.223254-120.49032 161.27909 0 197.288886 56.70368 200.574868 56.447681 12.031932-0.895995 12.841928 0 25.599855 0 15.572912 0 9.129948-1.279993 23.593867 0 7.807956 0.682996 86.186514-67.839617 194.686901-56.447681 184.873956 19.45589 156.586116 81.40754 142.079198 120.48932-15.103915 40.83277-68.692612 59.946662-66.303626 62.549647 44.28775 48.938724 51.285711 79.018554 66.346626 123.9463 6.143965 18.473896 49.066723-101.674426 82.089537-73.685584 13.781922 11.690934 41.301767 60.24566 13.781922 163.285078-27.519845 102.996419-80.767544 126.505286-79.615551 145.791177 2.389987 40.191773 1.023994 68.436614-1.023994 75.732573-9.812945 35.4128-30.378829 27.604844-30.378829 35.4128C858.450044 730.752933 705.10691 896 515.966978 896s-342.398067-165.289067-342.398068-369.192916c0-16.169909-14.378919-4.223976-26.154852-35.4128z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="frown" unicode="" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM512 363c-85.5 0-155.6-67.3-160-151.6-0.2-4.6 3.4-8.4 8-8.4h48.1c4.2 0 7.8 3.2 8.1 7.4C420 259.9 461.5 299 512 299s92.1-39.1 95.8-88.6c0.3-4.2 3.9-7.4 8.1-7.4H664c4.6 0 8.2 3.8 8 8.4-4.4 84.3-74.5 151.6-160 151.6z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="meh" unicode="" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 331H360c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h304c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="smile" unicode="" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 363h-48.1c-4.2 0-7.8-3.2-8.1-7.4C604 306.1 562.5 267 512 267s-92.1 39.1-95.8 88.6c-0.3 4.2-3.9 7.4-8.1 7.4H360c-4.6 0-8.2-3.8-8-8.4 4.4-84.3 74.5-151.6 160-151.6s155.6 67.3 160 151.6c0.2 4.6-3.4 8.4-8 8.4z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="man" unicode="" d="M874 776H622c-3.3 0-6-2.7-6-6v-56c0-3.3 2.7-6 6-6h160.4L583.1 508.7c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S120 356.9 120 280s30-149.3 84.4-203.6C258.7 22 331.1-8 408-8s149.3 30 203.6 84.4C666 130.7 696 203.1 696 280c0 64.1-20.8 124.9-59.2 174.9L836 654.1V494c0-3.3 2.7-6 6-6h56c3.3 0 6 2.7 6 6V746c0 16.5-13.5 30-30 30zM408 68c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="woman" unicode="" d="M909.7 739.4l-42.2 42.2c-3.1 3.1-8.2 3.1-11.3 0L764 689.4l-84.2 84.2c-3.1 3.1-8.2 3.1-11.3 0l-42.1-42.1c-3.1-3.1-3.1-8.1 0-11.3l84.2-84.2-135.5-135.3c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S112 348.9 112 272s30-149.3 84.4-203.6C250.7 14 323.1-16 400-16s149.3 30 203.6 84.4C658 122.7 688 195.1 688 272c0 64.2-20.9 125.1-59.3 175.1l135.4 135.4 84.2-84.2c3.1-3.1 8.2-3.1 11.3 0l42.1 42.1c3.1 3.1 3.1 8.1 0 11.3l-84.2 84.2 92.2 92.2c3.1 3.1 3.1 8.2 0 11.3zM400 60c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</font>
|
||||||
|
</defs></svg>
|
||||||
|
After Width: | Height: | Size: 8.2 KiB |
BIN
src/assets/icons/iconfont.ttf
Normal file
BIN
src/assets/icons/iconfont.woff
Normal file
BIN
src/assets/images/administrato.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
src/assets/images/bigmeter.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/images/error-page/error-401.svg
Normal file
|
After Width: | Height: | Size: 31 KiB |
1
src/assets/images/error-page/error-404.svg
Normal file
|
After Width: | Height: | Size: 26 KiB |
1
src/assets/images/error-page/error-500.svg
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
src/assets/images/famen.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/images/flowarrow.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/assets/images/flowarrow2.png
Normal file
|
After Width: | Height: | Size: 1017 B |
BIN
src/assets/images/load.gif
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
src/assets/images/login-bg.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/images/logo.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/assets/images/meter.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/images/mincompanyLogo.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
src/assets/images/secondaryflowMeter.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/images/start.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/images/unbigmeter.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/images/unfamen.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/images/unmeter.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/unsecondaryflowMeter.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
1019
src/assets/three/OrbitControls.js
Normal file
49
src/components/asyncModal/index.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<Modal v-model="showModal" :width="width||80" :title="title" v-bind="$attrs">
|
||||||
|
<div class="asyncModal-box">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="footer">
|
||||||
|
<Button @click="hide">取消</Button>
|
||||||
|
<Button class="ml30" type="primary" @click="saveInfo">确定</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['title', 'width'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showModal: false,
|
||||||
|
callback: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
show(callback) {
|
||||||
|
this.showModal = true
|
||||||
|
this.callback = callback
|
||||||
|
},
|
||||||
|
hide() {
|
||||||
|
this.showModal = false
|
||||||
|
},
|
||||||
|
|
||||||
|
async saveInfo() {
|
||||||
|
if (this.callback) {
|
||||||
|
await this.callback()
|
||||||
|
}
|
||||||
|
this.$emit('on-ok')
|
||||||
|
this.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.asyncModal-box {
|
||||||
|
max-height: 90vh;
|
||||||
|
min-height: 20vh;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
42
src/components/common-icon/common-icon.vue
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<component :is="iconType" :type="iconName" :color="iconColor" :size="iconSize" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Icons from '@component/md-icons'
|
||||||
|
export default {
|
||||||
|
name: 'CommonIcon',
|
||||||
|
components: { Icons },
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
color: String,
|
||||||
|
size: Number,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
iconType() {
|
||||||
|
if (this.type) {
|
||||||
|
return this.type.indexOf('_') === 0 ? 'Icons' : 'Icon'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
iconName() {
|
||||||
|
return this.iconType === 'Icons' ? this.getCustomIconName(this.type) : this.type
|
||||||
|
},
|
||||||
|
iconSize() {
|
||||||
|
return this.size || (this.iconType === 'Icons' ? 12 : undefined)
|
||||||
|
},
|
||||||
|
iconColor() {
|
||||||
|
return this.color || ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getCustomIconName(iconName) {
|
||||||
|
return iconName.slice(1)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
2
src/components/common-icon/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import CommonIcon from './common-icon.vue'
|
||||||
|
export default CommonIcon
|
||||||
105
src/components/cron-input/index.vue
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<Dropdown trigger="click" style="width:100%" @on-visible-change="showDrop">
|
||||||
|
|
||||||
|
<Input :value="value" readonly placeholder="请选择" />
|
||||||
|
|
||||||
|
<Dropdown-menu slot="list">
|
||||||
|
<Form :model="cronForm" ref="cronForm" label-position="left" :label-width="160" class="cron-form">
|
||||||
|
|
||||||
|
<!-- Minute Input -->
|
||||||
|
<FormItem label="Minute">
|
||||||
|
<Select v-model="cronForm.minute" placeholder="Minute" class="scrollable-select">
|
||||||
|
<Option v-for="minute in minutes" :value="minute" :key="minute">{{ minute }}</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<!-- Hour Input -->
|
||||||
|
<FormItem label="Hour">
|
||||||
|
<Select v-model="cronForm.hour" placeholder="Hour" class="scrollable-select">
|
||||||
|
<Option v-for="hour in hours" :value="hour" :key="hour">{{ hour }}</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<!-- Day of Month Input -->
|
||||||
|
<FormItem label="Day">
|
||||||
|
<Select v-model="cronForm.day" placeholder="Day" class="scrollable-select">
|
||||||
|
<Option v-for="day in days" :value="day" :key="day">{{ day }}</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<!-- Month Input -->
|
||||||
|
<FormItem label="Month">
|
||||||
|
<Select v-model="cronForm.month" placeholder="Month" class="scrollable-select">
|
||||||
|
<Option v-for="month in months" :value="month" :key="month">{{ month }}</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<!-- Day of Week Input -->
|
||||||
|
<FormItem label="Week">
|
||||||
|
<Select v-model="cronForm.dayOfWeek" placeholder="Day of Week" class="scrollable-select">
|
||||||
|
<Option v-for="dayOfWeek in daysOfWeek" :value="dayOfWeek" :key="dayOfWeek">{{ dayOfWeek }}</Option>
|
||||||
|
</Select>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<Button type="primary" @click="applyCron">确定</Button>
|
||||||
|
|
||||||
|
</Form>
|
||||||
|
</Dropdown-menu>
|
||||||
|
</Dropdown>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['value'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cronForm: {
|
||||||
|
minute: '*',
|
||||||
|
hour: '*',
|
||||||
|
day: '*',
|
||||||
|
month: '*',
|
||||||
|
dayOfWeek: '*'
|
||||||
|
},
|
||||||
|
|
||||||
|
minutes: ['*', ...Array.from({ length: 60 }, (_, i) => i.toString())],
|
||||||
|
hours: ['*', ...Array.from({ length: 24 }, (_, i) => i.toString())],
|
||||||
|
days: ['*', ...Array.from({ length: 31 }, (_, i) => (i + 1).toString())],
|
||||||
|
months: ['*', ...Array.from({ length: 12 }, (_, i) => (i + 1).toString())],
|
||||||
|
daysOfWeek: ['*', '0', '1', '2', '3', '4', '5', '6']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showDrop(visible) {
|
||||||
|
if (visible && this.value) {
|
||||||
|
let timeArray = this.value.split(' ')
|
||||||
|
|
||||||
|
this.cronForm = {
|
||||||
|
minute: timeArray[0],
|
||||||
|
hour: timeArray[1],
|
||||||
|
day: timeArray[2],
|
||||||
|
month: timeArray[3],
|
||||||
|
dayOfWeek: timeArray[4]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applyCron() {
|
||||||
|
const { minute, hour, day, month, dayOfWeek } = this.cronForm
|
||||||
|
this.$emit('input', `${minute} ${hour} ${day} ${month} ${dayOfWeek}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.ivu-dropdown-menu {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.scrollable-select {
|
||||||
|
.ivu-select-dropdown {
|
||||||
|
max-height: 200px; /* Adjust this value to your needs */
|
||||||
|
overflow-y: auto; /* Enable vertical scrollbar */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
2
src/components/cropper/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import Cropper from './index.vue'
|
||||||
|
export default Cropper
|
||||||
36
src/components/cropper/index.less
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
.bg{
|
||||||
|
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")
|
||||||
|
}
|
||||||
|
.cropper-wrapper{
|
||||||
|
width:100%;
|
||||||
|
height: 100%;
|
||||||
|
.img-box{
|
||||||
|
height: 600px;
|
||||||
|
width: 600px;
|
||||||
|
border: 1px solid #ebebeb;
|
||||||
|
display: inline-block;
|
||||||
|
.bg;
|
||||||
|
img{
|
||||||
|
max-width: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-con{
|
||||||
|
display: inline-block;
|
||||||
|
width: 170px;
|
||||||
|
vertical-align: top;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 10px;
|
||||||
|
margin-left: 30px;
|
||||||
|
.preview-box{
|
||||||
|
height: 150px !important;
|
||||||
|
width: 100% !important;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #ebebeb;
|
||||||
|
.bg;
|
||||||
|
}
|
||||||
|
.button-box{
|
||||||
|
padding: 10px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
155
src/components/cropper/index.vue
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<template>
|
||||||
|
<div class="cropper-wrapper">
|
||||||
|
<div class="img-box">
|
||||||
|
<img class="cropper-image" :id="imgId" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="right-con">
|
||||||
|
<div v-if="preview" class="preview-box" :id="previewId"></div>
|
||||||
|
<div class="button-box">
|
||||||
|
<slot>
|
||||||
|
<CustomUpload @chage="beforeUpload"> </CustomUpload>
|
||||||
|
</slot>
|
||||||
|
<div v-show="insideSrc">
|
||||||
|
<Button type="primary" @click="rotate">
|
||||||
|
<Icon type="md-refresh" :size="18" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="text-align: right;margin-top: 20px;">
|
||||||
|
<Button style="width: 150px;margin-top: 10px;" type="primary" @click="crop">{{ cropButtonText }}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Cropper from 'cropperjs'
|
||||||
|
import './index.less'
|
||||||
|
import 'cropperjs/dist/cropper.min.css'
|
||||||
|
export default {
|
||||||
|
name: 'Cropper',
|
||||||
|
props: {
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
preview: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
moveStep: {
|
||||||
|
type: Number,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
cropButtonText: {
|
||||||
|
type: String,
|
||||||
|
default: '裁剪',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
actionUrl: window.rootVue.$config.apiUrl + 'sys_file/upload_oos_img',
|
||||||
|
cropper: null,
|
||||||
|
insideSrc: '',
|
||||||
|
file: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
imgId() {
|
||||||
|
return `cropper${this._uid}`
|
||||||
|
},
|
||||||
|
previewId() {
|
||||||
|
return `cropper_preview${this._uid}`
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
src(src) {
|
||||||
|
this.replace(src)
|
||||||
|
},
|
||||||
|
insideSrc(src) {
|
||||||
|
this.replace(src)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeUpload(file) {
|
||||||
|
this.file = file
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
reader.onload = async (event) => {
|
||||||
|
this.getSize(event.srcElement.result).then(({ width, height }) => {
|
||||||
|
if (width < 500 || height < 500) {
|
||||||
|
rootVue.$Message.error('图片尺寸小于 500*500 ,请更换图片')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this.insideSrc = event.srcElement.result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
getSize(src) {
|
||||||
|
let pro = new Promise((resolve, reject) => {
|
||||||
|
let img = new Image()
|
||||||
|
img.onload = function () {
|
||||||
|
let { width, height } = img
|
||||||
|
resolve({ width, height })
|
||||||
|
}
|
||||||
|
img.src = src
|
||||||
|
})
|
||||||
|
return pro
|
||||||
|
},
|
||||||
|
replace(src) {
|
||||||
|
this.cropper.replace(src)
|
||||||
|
this.insideSrc = src
|
||||||
|
},
|
||||||
|
rotate() {
|
||||||
|
this.cropper.rotate(90)
|
||||||
|
},
|
||||||
|
shrink() {
|
||||||
|
this.cropper.zoom(-0.1)
|
||||||
|
},
|
||||||
|
magnify() {
|
||||||
|
this.cropper.zoom(0.1)
|
||||||
|
},
|
||||||
|
scale(d) {
|
||||||
|
this.cropper[`scale${d}`](-this.cropper.getData()[`scale${d}`])
|
||||||
|
},
|
||||||
|
move(...argu) {
|
||||||
|
this.cropper.move(...argu)
|
||||||
|
},
|
||||||
|
crop() {
|
||||||
|
this.cropper.getCroppedCanvas({ fillColor: '#fff' }).toBlob(
|
||||||
|
(blob) => {
|
||||||
|
let file = new File([blob], this.file.name, {
|
||||||
|
type: this.file.type,
|
||||||
|
lastModified: Date.now(),
|
||||||
|
})
|
||||||
|
this.$emit('on-crop', file)
|
||||||
|
this.insideSrc = ''
|
||||||
|
this.filefile = null
|
||||||
|
},
|
||||||
|
'image/jpeg',
|
||||||
|
0.8
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
let dom = document.getElementById(this.imgId)
|
||||||
|
this.cropper = new Cropper(dom, {
|
||||||
|
preview: `#${this.previewId}`,
|
||||||
|
dragMode: 'move',
|
||||||
|
checkCrossOrigin: true,
|
||||||
|
aspectRatio: 5 / 5,
|
||||||
|
cropBoxResizable: false,
|
||||||
|
cropBoxMovable: false,
|
||||||
|
outputSize: 0.8,
|
||||||
|
minContainerWidth: 600, // 容器的最小宽度
|
||||||
|
minContainerHeight: 600, // 容器的最小高度
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
95
src/components/editor/index.vue
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div :id="id" class="edit-box"> </div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import WangEditor from 'wangeditor'
|
||||||
|
export default {
|
||||||
|
props: ['value'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
id: '',
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
let date = new Date()
|
||||||
|
this.id = 'wangeditor_' + date.getTime()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
let domId = `#${this.id}`
|
||||||
|
this.editor = new WangEditor(domId)
|
||||||
|
this.editor.config.uploadImgShowBase64 = true
|
||||||
|
|
||||||
|
this.editor.config.uploadImgServer = window.rootVue.$config.apiUrl + 'sys_file/upload_oos_img'
|
||||||
|
this.editor.config.uploadImgHooks = {
|
||||||
|
customInsert: (insertImg, result, editor) => {
|
||||||
|
var url = result.data.path
|
||||||
|
insertImg(url)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.config.menus = [
|
||||||
|
'head', // 标题
|
||||||
|
'bold', // 粗体
|
||||||
|
'fontSize', // 字号
|
||||||
|
'fontName', // 字体
|
||||||
|
'italic', // 斜体
|
||||||
|
'underline', // 下划线
|
||||||
|
'strikeThrough', // 删除线
|
||||||
|
'foreColor', // 文字颜色
|
||||||
|
'backColor', // 背景颜色
|
||||||
|
'link', // 插入链接
|
||||||
|
'list', // 列表
|
||||||
|
'justify', // 对齐方式
|
||||||
|
'image', // 插入图片
|
||||||
|
'fullscreen', // 全屏
|
||||||
|
]
|
||||||
|
|
||||||
|
this.editor.config.pasteTextHandle = function (content) {
|
||||||
|
if (content === '' && !content) return ''
|
||||||
|
var str = content
|
||||||
|
str = str.replace(/<xml>[\s\S]*?<\/xml>/gi, '')
|
||||||
|
str = str.replace(/<style>[\s\S]*?<\/style>/gi, '')
|
||||||
|
str = str.replace(/<\/?[^>]*>/g, '')
|
||||||
|
str = str.replace(/[ | ]*\n/g, '\n')
|
||||||
|
str = str.replace(/ /gi, '')
|
||||||
|
str = str.replace(/spanyes'/gi, 'div')
|
||||||
|
str = str.replace(/spanyes'/gi, '')
|
||||||
|
str = str.replace(/';/gi, '')
|
||||||
|
str = str.replace(/spanyes'/gi, 'span')
|
||||||
|
str = str.replace(/<\/font>/gi, '')
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.config.onchange = (newHtml) => {
|
||||||
|
this.$emit('input', newHtml)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.create()
|
||||||
|
|
||||||
|
this.editor.$textElem.css('text-align', 'left')
|
||||||
|
// 初始化设置值
|
||||||
|
if (this.value) {
|
||||||
|
this.setHtml(this.value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getHtml() {
|
||||||
|
return this.editor.txt.html()
|
||||||
|
},
|
||||||
|
setHtml(text) {
|
||||||
|
this.editor.txt.html(text)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.edit-box {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
2
src/components/info-card/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import InforCard from './infor-card.vue'
|
||||||
|
export default InforCard
|
||||||
94
src/components/info-card/infor-card.vue
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<Card :shadow="shadow" class="info-card-wrapper" :padding="0">
|
||||||
|
<div class="content-con">
|
||||||
|
<div class="left-area" :style="{background: color, width: leftWidth}">
|
||||||
|
<common-icon class="icon" :type="icon" :size="iconSize" color="#fff" />
|
||||||
|
</div>
|
||||||
|
<div class="right-area" :style="{width: rightWidth}">
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CommonIcon from '@component/common-icon'
|
||||||
|
export default {
|
||||||
|
name: 'InforCard',
|
||||||
|
components: {
|
||||||
|
CommonIcon,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
left: {
|
||||||
|
type: Number,
|
||||||
|
default: 36,
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#2d8cf0',
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
iconSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 20,
|
||||||
|
},
|
||||||
|
shadow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
leftWidth() {
|
||||||
|
return `${this.left}%`
|
||||||
|
},
|
||||||
|
rightWidth() {
|
||||||
|
return `${100 - this.left}%`
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.common {
|
||||||
|
float: left;
|
||||||
|
height: 100%;
|
||||||
|
display: table;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.size {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.middle-center {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.info-card-wrapper {
|
||||||
|
.size;
|
||||||
|
overflow: hidden;
|
||||||
|
.ivu-card-body {
|
||||||
|
.size;
|
||||||
|
}
|
||||||
|
.content-con {
|
||||||
|
.size;
|
||||||
|
position: relative;
|
||||||
|
.left-area {
|
||||||
|
.common;
|
||||||
|
& > .icon {
|
||||||
|
.middle-center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-area {
|
||||||
|
.common;
|
||||||
|
& > div {
|
||||||
|
.middle-center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
32
src/components/load-flower/index.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<div id="load-warp">
|
||||||
|
<div class="m-load"> </div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {}
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
#load-warp {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
z-index: 99999;
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-load {
|
||||||
|
position: relative;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -18px;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
background: url('../../assets/images/load.gif') center center no-repeat;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
2
src/components/login-form/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import LoginForm from './login-form.vue'
|
||||||
|
export default LoginForm
|
||||||
68
src/components/login-form/login-form.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<Form ref="loginForm" :model="form" :rules="rules" @keydown.enter.native="handleSubmit">
|
||||||
|
<FormItem prop="userName">
|
||||||
|
<Input v-model="form.userName" placeholder="请输入用户名">
|
||||||
|
<span slot="prepend">
|
||||||
|
<Icon :size="16" type="ios-person"></Icon>
|
||||||
|
</span>
|
||||||
|
</Input>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem prop="password">
|
||||||
|
<Input type="password" v-model="form.password" placeholder="请输入密码">
|
||||||
|
<span slot="prepend">
|
||||||
|
<Icon :size="14" type="md-lock"></Icon>
|
||||||
|
</span>
|
||||||
|
</Input>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem>
|
||||||
|
<Button style="margin-top:20px;" size="large" @click="handleSubmit" type="primary" long>登录</Button>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'LoginForm',
|
||||||
|
props: {
|
||||||
|
userNameRules: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return [{ required: true, message: '账号不能为空', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
passwordRules: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return [{ required: true, message: '密码不能为空', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
userName: '',
|
||||||
|
password: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
rules() {
|
||||||
|
return {
|
||||||
|
userName: this.userNameRules,
|
||||||
|
password: this.passwordRules
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSubmit() {
|
||||||
|
this.$refs.loginForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.$emit('on-success-valid', {
|
||||||
|
userName: this.form.userName,
|
||||||
|
password: this.form.password
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
2
src/components/main/components/a-back-top/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import ABackTop from './index.vue'
|
||||||
|
export default ABackTop
|
||||||
94
src/components/main/components/a-back-top/index.vue
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="classes" :style="styles" @click="back">
|
||||||
|
<slot>
|
||||||
|
<div :class="innerClasses">
|
||||||
|
<i class="ivu-icon ivu-icon-ios-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { scrollTop, on, off } from '@/utils/tools'
|
||||||
|
const prefixCls = 'ivu-back-top'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ABackTop',
|
||||||
|
props: {
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 400
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
type: Number,
|
||||||
|
default: 30
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
type: Number,
|
||||||
|
default: 30
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 1000
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
type: null,
|
||||||
|
default: window
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
backTop: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// window.addEventListener('scroll', this.handleScroll, false)
|
||||||
|
// window.addEventListener('resize', this.handleScroll, false)
|
||||||
|
on(this.containerEle, 'scroll', this.handleScroll)
|
||||||
|
on(this.containerEle, 'resize', this.handleScroll)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
// window.removeEventListener('scroll', this.handleScroll, false)
|
||||||
|
// window.removeEventListener('resize', this.handleScroll, false)
|
||||||
|
off(this.containerEle, 'scroll', this.handleScroll)
|
||||||
|
off(this.containerEle, 'resize', this.handleScroll)
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
classes() {
|
||||||
|
return [
|
||||||
|
`${prefixCls}`,
|
||||||
|
{
|
||||||
|
[`${prefixCls}-show`]: this.backTop
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
styles() {
|
||||||
|
return {
|
||||||
|
bottom: `${this.bottom}px`,
|
||||||
|
right: `${this.right}px`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
innerClasses() {
|
||||||
|
return `${prefixCls}-inner`
|
||||||
|
},
|
||||||
|
containerEle() {
|
||||||
|
return this.container === window
|
||||||
|
? window
|
||||||
|
: document.querySelector(this.container)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleScroll() {
|
||||||
|
this.backTop = this.containerEle.scrollTop >= this.height
|
||||||
|
},
|
||||||
|
back() {
|
||||||
|
let target =
|
||||||
|
typeof this.container === 'string'
|
||||||
|
? this.containerEle
|
||||||
|
: document.documentElement || document.body
|
||||||
|
const sTop = target.scrollTop
|
||||||
|
scrollTop(this.containerEle, sTop, 0, this.duration)
|
||||||
|
this.$emit('on-click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
90
src/components/main/components/fullscreen/fullscreen.vue
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="showFullScreenBtn" class="full-screen-btn-con">
|
||||||
|
<Tooltip :content="value ? '退出全屏' : '全屏'" placement="bottom">
|
||||||
|
<Icon @click.native="handleChange" :type="value ? 'md-contract' : 'md-expand'" :size="23"></Icon>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Fullscreen',
|
||||||
|
computed: {
|
||||||
|
showFullScreenBtn() {
|
||||||
|
return window.navigator.userAgent.indexOf('MSIE') < 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleFullscreen() {
|
||||||
|
let main = document.body
|
||||||
|
if (this.value) {
|
||||||
|
if (document.exitFullscreen) {
|
||||||
|
document.exitFullscreen()
|
||||||
|
} else if (document.mozCancelFullScreen) {
|
||||||
|
document.mozCancelFullScreen()
|
||||||
|
} else if (document.webkitCancelFullScreen) {
|
||||||
|
document.webkitCancelFullScreen()
|
||||||
|
} else if (document.msExitFullscreen) {
|
||||||
|
document.msExitFullscreen()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (main.requestFullscreen) {
|
||||||
|
main.requestFullscreen()
|
||||||
|
} else if (main.mozRequestFullScreen) {
|
||||||
|
main.mozRequestFullScreen()
|
||||||
|
} else if (main.webkitRequestFullScreen) {
|
||||||
|
main.webkitRequestFullScreen()
|
||||||
|
} else if (main.msRequestFullscreen) {
|
||||||
|
main.msRequestFullscreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleChange() {
|
||||||
|
this.handleFullscreen()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let isFullscreen =
|
||||||
|
document.fullscreenElement ||
|
||||||
|
document.mozFullScreenElement ||
|
||||||
|
document.webkitFullscreenElement ||
|
||||||
|
document.fullScreen ||
|
||||||
|
document.mozFullScreen ||
|
||||||
|
document.webkitIsFullScreen
|
||||||
|
isFullscreen = !!isFullscreen
|
||||||
|
document.addEventListener('fullscreenchange', () => {
|
||||||
|
this.$emit('input', !this.value)
|
||||||
|
this.$emit('on-change', !this.value)
|
||||||
|
})
|
||||||
|
document.addEventListener('mozfullscreenchange', () => {
|
||||||
|
this.$emit('input', !this.value)
|
||||||
|
this.$emit('on-change', !this.value)
|
||||||
|
})
|
||||||
|
document.addEventListener('webkitfullscreenchange', () => {
|
||||||
|
this.$emit('input', !this.value)
|
||||||
|
this.$emit('on-change', !this.value)
|
||||||
|
})
|
||||||
|
document.addEventListener('msfullscreenchange', () => {
|
||||||
|
this.$emit('input', !this.value)
|
||||||
|
this.$emit('on-change', !this.value)
|
||||||
|
})
|
||||||
|
this.$emit('input', isFullscreen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.full-screen-btn-con .ivu-tooltip-rel {
|
||||||
|
height: 64px;
|
||||||
|
line-height: 56px;
|
||||||
|
i {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
2
src/components/main/components/fullscreen/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import Fullscreen from './fullscreen.vue'
|
||||||
|
export default Fullscreen
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
.custom-bread-crumb{
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="custom-bread-crumb">
|
||||||
|
<Breadcrumb :style="{fontSize: `${fontSize}px`}">
|
||||||
|
<BreadcrumbItem v-for="item in list" :to="item.to" :key="`bread-crumb-${item.name}`">
|
||||||
|
<common-icon style="margin-right: 4px;" :type="item.icon || ''" />
|
||||||
|
{{ showTitle(item) }}
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { showTitle } from '@/utils/tools'
|
||||||
|
import CommonIcon from '@component/common-icon/common-icon'
|
||||||
|
import './custom-bread-crumb.less'
|
||||||
|
export default {
|
||||||
|
name: 'customBreadCrumb',
|
||||||
|
components: {
|
||||||
|
CommonIcon,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
fontSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 14,
|
||||||
|
},
|
||||||
|
showIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showTitle(item) {
|
||||||
|
return showTitle(item, this)
|
||||||
|
},
|
||||||
|
isCustomIcon(iconName) {
|
||||||
|
return iconName.indexOf('_') === 0
|
||||||
|
},
|
||||||
|
getCustomIconName(iconName) {
|
||||||
|
return iconName.slice(1)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
import customBreadCrumb from './custom-bread-crumb.vue'
|
||||||
|
export default customBreadCrumb
|
||||||
18
src/components/main/components/header-bar/header-bar.less
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
.header-bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
height: 64px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.custom-content-con {
|
||||||
|
height: 64px;
|
||||||
|
padding-right: 120px;
|
||||||
|
line-height: 64px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
39
src/components/main/components/header-bar/header-bar.vue
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<div class="header-bar">
|
||||||
|
<sider-trigger :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>
|
||||||
|
<custom-bread-crumb show-icon style="margin-left: 30px;" :list="breadCrumbList"></custom-bread-crumb>
|
||||||
|
<div class="custom-content-con">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import siderTrigger from './sider-trigger'
|
||||||
|
import customBreadCrumb from './custom-bread-crumb'
|
||||||
|
import './header-bar.less'
|
||||||
|
export default {
|
||||||
|
name: 'HeaderBar',
|
||||||
|
components: {
|
||||||
|
siderTrigger,
|
||||||
|
customBreadCrumb,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
collapsed: Boolean,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
breadCrumbList() {
|
||||||
|
let route = this.$route.matched.map((p) => {
|
||||||
|
let { name, path, meta } = p
|
||||||
|
return { name, path, meta }
|
||||||
|
})
|
||||||
|
route.shift()
|
||||||
|
return route
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleCollpasedChange(state) {
|
||||||
|
this.$emit('on-coll-change', state)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
2
src/components/main/components/header-bar/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import HeaderBar from './header-bar'
|
||||||
|
export default HeaderBar
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
import siderTrigger from './sider-trigger.vue'
|
||||||
|
export default siderTrigger
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
.trans{
|
||||||
|
transition: transform .2s ease;
|
||||||
|
}
|
||||||
|
@size: 40px;
|
||||||
|
.sider-trigger-a{
|
||||||
|
padding: 6px;
|
||||||
|
width: @size;
|
||||||
|
height: @size;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
color: #5c6b77;
|
||||||
|
margin-top: 12px;
|
||||||
|
i{
|
||||||
|
.trans;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
&.collapsed i{
|
||||||
|
transform: rotateZ(90deg);
|
||||||
|
.trans;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<a @click="handleChange" type="text" :class="['sider-trigger-a', collapsed ? 'collapsed' : '']"><Icon :type="icon" :size="size" /></a>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'siderTrigger',
|
||||||
|
props: {
|
||||||
|
collapsed: Boolean,
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: 'navicon-round'
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
default: 26
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange() {
|
||||||
|
this.$emit('on-change', !this.collapsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
@import './sider-trigger.less';
|
||||||
|
</style>
|
||||||
2
src/components/main/components/language/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import Language from './language.vue'
|
||||||
|
export default Language
|
||||||
51
src/components/main/components/language/language.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Dropdown trigger="click" @on-click="selectLang">
|
||||||
|
<a href="javascript:void(0)">
|
||||||
|
{{ title }}
|
||||||
|
<Icon :size="18" type="md-arrow-dropdown" />
|
||||||
|
</a>
|
||||||
|
<DropdownMenu slot="list">
|
||||||
|
<DropdownItem v-for="(value, key) in localList" :name="key" :key="`lang-${key}`">{{ value }}</DropdownItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Language',
|
||||||
|
props: {
|
||||||
|
lang: String
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
langList: {
|
||||||
|
'zh-CN': '语言',
|
||||||
|
'zh-TW': '語言',
|
||||||
|
'en-US': 'Lang'
|
||||||
|
},
|
||||||
|
localList: {
|
||||||
|
'zh-CN': '中文简体',
|
||||||
|
'zh-TW': '中文繁体',
|
||||||
|
'en-US': 'English'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
lang(lang) {
|
||||||
|
this.$i18n.locale = lang
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
title() {
|
||||||
|
return this.langList[this.lang]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectLang(name) {
|
||||||
|
this.$emit('on-lang-change', name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
58
src/components/main/components/side-menu/collapsed-menu.vue
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<Dropdown ref="dropdown" @on-click="handleClick" :class="hideTitle ? '' : 'collased-menu-dropdown'" :transfer="hideTitle" :placement="placement">
|
||||||
|
<a class="drop-menu-a" type="text" @mouseover="handleMousemove($event, children)" :style="{textAlign: !hideTitle ? 'left' : ''}">
|
||||||
|
<common-icon :size="rootIconSize" :color="textColor" :type="parentItem.meta.icon" /><span class="menu-title" v-if="!hideTitle">{{
|
||||||
|
showTitle(parentItem) }}</span>
|
||||||
|
<Icon style="float: right;" v-if="!hideTitle" type="ios-arrow-forward" :size="16" />
|
||||||
|
</a>
|
||||||
|
<DropdownMenu ref="dropdown" slot="list">
|
||||||
|
<template v-for="child in children">
|
||||||
|
<collapsed-menu v-if="showChildren(child)" :icon-size="iconSize" :parent-item="child" :key="`drop-${child.name}`"></collapsed-menu>
|
||||||
|
<DropdownItem v-else :key="`drop-${child.name}`" :name="child.name">
|
||||||
|
<common-icon :size="iconSize" :type="child.meta.icon" /><span class="menu-title">{{ showTitle(child) }}</span>
|
||||||
|
</DropdownItem>
|
||||||
|
</template>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import mixin from './mixin'
|
||||||
|
import itemMixin from './item-mixin'
|
||||||
|
import { findNodeUpperByClasses } from '@/utils/tools'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CollapsedMenu',
|
||||||
|
mixins: [mixin, itemMixin],
|
||||||
|
props: {
|
||||||
|
hideTitle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
rootIconSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
placement: 'right-end',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClick(name) {
|
||||||
|
this.$emit('on-click', name)
|
||||||
|
},
|
||||||
|
handleMousemove(event, children) {
|
||||||
|
const { pageY } = event
|
||||||
|
const height = children.length * 38
|
||||||
|
const isOverflow = pageY + height < window.innerHeight
|
||||||
|
this.placement = isOverflow ? 'right-start' : 'right-end'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let dropdown = findNodeUpperByClasses(this.$refs.dropdown.$el, ['ivu-select-dropdown', 'ivu-dropdown-transfer'])
|
||||||
|
if (dropdown) dropdown.style.overflow = 'visible'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
2
src/components/main/components/side-menu/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import SideMenu from './side-menu.vue'
|
||||||
|
export default SideMenu
|
||||||
21
src/components/main/components/side-menu/item-mixin.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentItem: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
theme: String,
|
||||||
|
iconSize: Number
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
parentName() {
|
||||||
|
return this.parentItem.name
|
||||||
|
},
|
||||||
|
children() {
|
||||||
|
return this.parentItem.children
|
||||||
|
},
|
||||||
|
textColor() {
|
||||||
|
return this.theme === 'dark' ? '#fff' : '#495060'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/components/main/components/side-menu/mixin.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import CommonIcon from "@component/common-icon";
|
||||||
|
import { showTitle } from "@/utils/tools";
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
CommonIcon
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showTitle(item) {
|
||||||
|
return showTitle(item, this);
|
||||||
|
},
|
||||||
|
showChildren(item) {
|
||||||
|
return item.type === "菜单";
|
||||||
|
},
|
||||||
|
getNameOrHref(item, children0) {
|
||||||
|
return item.href ? `isTurnByHref_${item.href}` : item.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
25
src/components/main/components/side-menu/side-menu-item.vue
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<Submenu :name="`${parentName}`">
|
||||||
|
<template slot="title">
|
||||||
|
<common-icon :type="parentItem.meta.icon || ''" />
|
||||||
|
<span>{{ showTitle(parentItem) }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-for="item in children">
|
||||||
|
<template v-if="item.is_show_menu">
|
||||||
|
<side-menu-item v-if="showChildren(item)" :key="`menu-${item.name}`" :parent-item="item"></side-menu-item>
|
||||||
|
<menu-item v-else :name="getNameOrHref(item)" :key="`menu-${item.name}`">
|
||||||
|
<common-icon :type="item.meta.icon || ''" /><span>{{ showTitle(item) }}</span>
|
||||||
|
</menu-item>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</Submenu>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import mixin from './mixin'
|
||||||
|
import itemMixin from './item-mixin'
|
||||||
|
export default {
|
||||||
|
name: 'SideMenuItem',
|
||||||
|
mixins: [mixin, itemMixin],
|
||||||
|
mounted() {},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
39
src/components/main/components/side-menu/side-menu.less
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
.side-menu-wrapper {
|
||||||
|
user-select: none;
|
||||||
|
.menu-collapsed {
|
||||||
|
padding-top: 10px;
|
||||||
|
|
||||||
|
.ivu-dropdown {
|
||||||
|
width: 100%;
|
||||||
|
.ivu-dropdown-rel a {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ivu-tooltip {
|
||||||
|
width: 100%;
|
||||||
|
.ivu-tooltip-rel {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-tooltip-popper .ivu-tooltip-content {
|
||||||
|
.ivu-tooltip-arrow {
|
||||||
|
border-right-color: #fff;
|
||||||
|
}
|
||||||
|
.ivu-tooltip-inner {
|
||||||
|
background: #fff;
|
||||||
|
color: #495060;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.drop-menu-a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 15px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
color: #495060;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.menu-title {
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
112
src/components/main/components/side-menu/side-menu.vue
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<div class="side-menu-wrapper">
|
||||||
|
<slot></slot>
|
||||||
|
<Menu ref="menu" v-show="!collapsed" :active-name="activeName" :open-names="openedNames" :accordion="true" :theme="theme" width="auto" @on-select="handleSelect">
|
||||||
|
<template v-for="item in menuList">
|
||||||
|
<template>
|
||||||
|
<side-menu-item v-if="showChildren(item)" :key="`menu-${item.name}`" :parent-item="item"></side-menu-item>
|
||||||
|
<menu-item v-else :name="getNameOrHref(item)" :key="`menu-${item.name}`">
|
||||||
|
<common-icon :type="item.meta.icon || ''" /><span>{{ showTitle(item) }}</span>
|
||||||
|
</menu-item>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</Menu>
|
||||||
|
<div class="menu-collapsed" v-show="collapsed" :list="menuList">
|
||||||
|
<template v-for="item in menuList">
|
||||||
|
<collapsed-menu v-if="item.type==='菜单'" @on-click="handleSelect" hide-title :root-icon-size="rootIconSize" :icon-size="iconSize" :theme="theme" :parent-item="item" :key="`drop-menu-${item.name}`">
|
||||||
|
</collapsed-menu>
|
||||||
|
<Tooltip transfer v-else :content="showTitle(item.children && item.children[0] ? item.children[0] : item)" placement="right" :key="`drop-menu-${item.name}`">
|
||||||
|
<a @click="handleSelect(getNameOrHref(item, true))" class="drop-menu-a" :style="{textAlign: 'center'}">
|
||||||
|
<common-icon :size="rootIconSize" :color="textColor" :type="item.meta.icon" />
|
||||||
|
</a>
|
||||||
|
</Tooltip>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import SideMenuItem from './side-menu-item.vue'
|
||||||
|
import CollapsedMenu from './collapsed-menu.vue'
|
||||||
|
import { getUnion } from '@/utils/tools'
|
||||||
|
import mixin from './mixin'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SideMenu',
|
||||||
|
mixins: [mixin],
|
||||||
|
components: {
|
||||||
|
SideMenuItem,
|
||||||
|
CollapsedMenu,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
menuList: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
collapsed: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
type: String,
|
||||||
|
default: 'light',
|
||||||
|
},
|
||||||
|
rootIconSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 20,
|
||||||
|
},
|
||||||
|
iconSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 16,
|
||||||
|
},
|
||||||
|
|
||||||
|
activeName: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
openNames: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
openedNames: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSelect(name) {
|
||||||
|
this.$emit('on-select', name)
|
||||||
|
},
|
||||||
|
getOpenedNamesByActiveName(name) {
|
||||||
|
let names = this.$route.matched.map((item) => item.name).filter((item) => item !== name)
|
||||||
|
return names
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
textColor() {
|
||||||
|
return this.theme === 'dark' ? '#fff' : '#495060'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeName(name) {
|
||||||
|
this.openedNames = this.getOpenedNamesByActiveName(name)
|
||||||
|
},
|
||||||
|
openNames(newNames) {
|
||||||
|
this.openedNames = newNames
|
||||||
|
},
|
||||||
|
openedNames() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.menu.updateOpened()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let openedNames = getUnion(this.openedNames, this.getOpenedNamesByActiveName(this.activeName))
|
||||||
|
this.openedNames = openedNames
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
@import './side-menu.less';
|
||||||
|
</style>
|
||||||
63
src/components/main/components/terminal/index.vue
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<div class="terminal-box">
|
||||||
|
<Icon :class="iconclass" type="ios-radio" @click="show" />
|
||||||
|
<asyncModal ref="asyncModal" title="终端" top="30" :footer-hide="true">
|
||||||
|
<Terminal></Terminal>
|
||||||
|
</asyncModal>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import Terminal from './terminal.vue'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Terminal
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
isServerRun: 'isServerRun'
|
||||||
|
}),
|
||||||
|
iconclass() {
|
||||||
|
let curClass = 'terminal-icon ml10 '
|
||||||
|
if (this.isServerRun) {
|
||||||
|
curClass += ' run'
|
||||||
|
}
|
||||||
|
return curClass
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
show() {
|
||||||
|
this.$refs['asyncModal'].show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.terminal-box {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
.terminal-icon {
|
||||||
|
color: #c5c8ce;
|
||||||
|
font-size: 22px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.run {
|
||||||
|
animation: colorChange 0.4s infinite; /* 调用颜色变化动画 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes colorChange {
|
||||||
|
0% {
|
||||||
|
color: #19be6b; /* 初始颜色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
color: red; /* 返回到初始颜色 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
62
src/components/main/components/terminal/terminal.vue
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content-view">
|
||||||
|
<div class="log-box">
|
||||||
|
<div class="pa5 flex" style="align-items: flex-end; justify-content: flex-end;">
|
||||||
|
<Button class="ml10" size="small" @click="reloadLog">重新加载日志</Button>
|
||||||
|
<Button type="error" size="small" @click="clearLog">清空日志</Button>
|
||||||
|
</div>
|
||||||
|
<div class="view-log-info" id="view-log-info" style="height:70vh;width: 100%;">{{ infoMsg }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import uiTool from '@/utils/uiTool'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
mounted() {},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
infoMsg: 'infoMsg'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
infoMsg: {
|
||||||
|
handler() {
|
||||||
|
this.scrollEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clearLog() {
|
||||||
|
this.$store.commit('clearInfoMsg')
|
||||||
|
},
|
||||||
|
reloadLog() {
|
||||||
|
this.$store.dispatch('setInteverLog')
|
||||||
|
},
|
||||||
|
scrollEnd() {
|
||||||
|
setTimeout(() => {
|
||||||
|
let outerDiv = document.querySelector('#view-log-info')
|
||||||
|
if (outerDiv) {
|
||||||
|
outerDiv.scrollTop = outerDiv.scrollHeight + 5
|
||||||
|
}
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.log-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
2
src/components/main/components/user/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import User from './user.vue'
|
||||||
|
export default User
|
||||||
12
src/components/main/components/user/user.less
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.user{
|
||||||
|
&-avator-dropdown{
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
// height: 64px;
|
||||||
|
vertical-align: middle;
|
||||||
|
// line-height: 64px;
|
||||||
|
.ivu-badge-dot{
|
||||||
|
top: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
src/components/main/components/user/user.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-avator-dropdown">
|
||||||
|
<label class="loginName-box">{{userName}}</label>
|
||||||
|
<Dropdown>
|
||||||
|
|
||||||
|
<Avatar :src="typeof userAvator === 'string' ? userAvator : userIcon" />
|
||||||
|
|
||||||
|
<Icon :size="18" type="md-arrow-dropdown"></Icon>
|
||||||
|
<DropdownMenu slot="list">
|
||||||
|
<a @click="logout">
|
||||||
|
<DropdownItem name="logout">
|
||||||
|
<Icon type="md-exit" />
|
||||||
|
退出登录
|
||||||
|
</DropdownItem>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import './user.less'
|
||||||
|
import { mapMutations, mapActions } from 'vuex'
|
||||||
|
|
||||||
|
const userIcon = require("@/assets/images/administrato.png").default
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'User',
|
||||||
|
props: {
|
||||||
|
userName: String,
|
||||||
|
userAvator: {
|
||||||
|
type: [String, Object],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
userIcon: userIcon
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(['handleLogOut']),
|
||||||
|
logout() {
|
||||||
|
this.handleLogOut(this)
|
||||||
|
},
|
||||||
|
|
||||||
|
message() {
|
||||||
|
this.$router.push({
|
||||||
|
name: 'message_page',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.user-avator-dropdown {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loginName-box {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #4b81d3;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
2
src/components/main/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import Main from './main.vue'
|
||||||
|
export default Main
|
||||||
109
src/components/main/main.less
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
.main {
|
||||||
|
.logo-con {
|
||||||
|
height: 64px;
|
||||||
|
padding: 10px;
|
||||||
|
padding-left: 0px;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-con {
|
||||||
|
padding: 0px 10px;
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content-con {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
color: darkgray;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-layout-con {
|
||||||
|
display: flex;
|
||||||
|
display: -webkit-flex;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-nav-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
height: 40px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
padding: 0px 0.05rem;
|
||||||
|
height: ~"calc(100% - 40px)";
|
||||||
|
display: flex;
|
||||||
|
display: -webkit-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-sider {
|
||||||
|
.ivu-layout-sider-children {
|
||||||
|
overflow-y: scroll;
|
||||||
|
margin-right: -10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-menu-item > i {
|
||||||
|
margin-right: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i {
|
||||||
|
margin-right: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collased-menu-dropdown {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
line-height: normal;
|
||||||
|
padding: 7px 0 6px 16px;
|
||||||
|
clear: both;
|
||||||
|
font-size: 12px !important;
|
||||||
|
white-space: nowrap;
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(100, 100, 100, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
& * {
|
||||||
|
color: #515a6e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-menu-item > i {
|
||||||
|
margin-right: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i {
|
||||||
|
margin-right: 8px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ivu-select-dropdown.ivu-dropdown-transfer {
|
||||||
|
max-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.police-box {
|
||||||
|
margin-left: 10px;
|
||||||
|
color: darkgoldenrod;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin: 0px 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
145
src/components/main/main.vue
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<Layout style="height: 100%" class="main">
|
||||||
|
|
||||||
|
<Sider hide-trigger collapsible :width="256" :collapsed-width="64" v-model="collapsed" class="left-sider" :style="{overflow: 'hidden'}">
|
||||||
|
<div class="sidebar-brand" @click="goHome" v-if="!collapsed">
|
||||||
|
<img style="width:50px" :src="sysFormModel.logoUrl" />
|
||||||
|
<span class="ml10">{{sysFormModel.title}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<side-menu class="mt30" theme="dark" ref="sideMenu" :active-name="$route.name" :collapsed="collapsed" @on-select="turnToPage" :menu-list="menuList"> </side-menu>
|
||||||
|
</Sider>
|
||||||
|
|
||||||
|
<Content class="main-content-con">
|
||||||
|
<Layout class="main-layout-con">
|
||||||
|
|
||||||
|
<Header>
|
||||||
|
<headerBar class="header-con" @on-coll-change="collpasedChange" :collapsed="collapsed">
|
||||||
|
<Terminal></Terminal>
|
||||||
|
<user :userName="userName" :user-avator="userAvator || ''" />
|
||||||
|
</headerBar>
|
||||||
|
</Header>
|
||||||
|
<Layout>
|
||||||
|
<Content class="content-wrapper">
|
||||||
|
|
||||||
|
<router-view />
|
||||||
|
<loadFlower> </loadFlower>
|
||||||
|
<ABackTop :height="100" :bottom="80" :right="50" container=".content-wrapper"></ABackTop>
|
||||||
|
</Content>
|
||||||
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
</Content>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
const { title } = require('../../config')
|
||||||
|
import SideMenu from './components/side-menu'
|
||||||
|
import HeaderBar from './components/header-bar'
|
||||||
|
|
||||||
|
import User from './components/user'
|
||||||
|
import ABackTop from './components/a-back-top'
|
||||||
|
import Fullscreen from './components/fullscreen'
|
||||||
|
import Language from './components/language'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import headerBar from './components/header-bar'
|
||||||
|
import loadFlower from '../load-flower/index'
|
||||||
|
import Terminal from './components/terminal'
|
||||||
|
|
||||||
|
import './main.less'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Main',
|
||||||
|
components: {
|
||||||
|
SideMenu,
|
||||||
|
HeaderBar,
|
||||||
|
Language,
|
||||||
|
|
||||||
|
Fullscreen,
|
||||||
|
User,
|
||||||
|
Terminal,
|
||||||
|
ABackTop,
|
||||||
|
loadFlower,
|
||||||
|
headerBar
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
collapsed: false,
|
||||||
|
isFullscreen: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
sysFormModel: 'sysFormModel',
|
||||||
|
menuList: 'menuList',
|
||||||
|
tagRouter: 'tagRouter',
|
||||||
|
userName: 'userName',
|
||||||
|
userAvator: 'avatorImgPath'
|
||||||
|
}),
|
||||||
|
cacheList() {
|
||||||
|
return ['ParentView']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async init() {
|
||||||
|
await this.$store.dispatch('getSysTitle')
|
||||||
|
},
|
||||||
|
collpasedChange(collapsed) {
|
||||||
|
this.collapsed = collapsed
|
||||||
|
},
|
||||||
|
goHome() {
|
||||||
|
this.$router.push({ path: '/' })
|
||||||
|
},
|
||||||
|
turnToPage(route) {
|
||||||
|
let { name, params, query } = {}
|
||||||
|
if (typeof route === 'string') name = route
|
||||||
|
else {
|
||||||
|
name = route.name
|
||||||
|
params = route.params
|
||||||
|
query = route.query
|
||||||
|
}
|
||||||
|
if (name.indexOf('isTurnByHref_') > -1) {
|
||||||
|
window.open(name.split('_')[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$router.push({
|
||||||
|
name,
|
||||||
|
params,
|
||||||
|
query
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCollapsedChange(state) {
|
||||||
|
this.collapsed = state
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClick(item) {
|
||||||
|
this.turnToPage(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.shop-select {
|
||||||
|
z-index: 999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-brand {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 25px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||