Commit dec59862 authored by 曾沂轮's avatar 曾沂轮

Feat: 添加项目

parents
node_modules
\ No newline at end of file
# svi-cli smart-web-router Template
> 一个基于[SmartWeb](http://172.16.10.132:8010/smartweb2/document/)应该库支撑的路由应用模板,提供给svi-cli脚手架获取.
> 提供内部平台或项目使用的初始模板
## Usage / 用法
``` bash
$ npm install -g svi-cli # 如果已安装,请跳过
$ svi init smart-web-router my-project
$ cd my-project
$ npm install
$ npm run serve
```
module.exports = {
renderFiles: [
'package.json',
'README.md'
],
filters: {
},
prompts: {
name: {
type: 'string',
required: true,
message: 'Project name'
},
description: {
type: 'string',
required: false,
message: 'Project description',
default: 'A Smart Web project',
}
}
}
\ No newline at end of file
{
"name": "vue-app",
"version": "0.0.1",
"description": "a svi CLI vue-app template.",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"template"
],
"author": "zengyl@southzn.com",
"license": "MIT"
}
> 1%
last 2 versions
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
NODE_ENV=development
VUE_APP_BASEURL='//172.16.10.132:8091/smartwebservice'
VUE_APP_SERVICE_APP='http://172.16.10.132:8010'
\ No newline at end of file
NODE_ENV=production
VUE_APP_BASEURL='//www.south-smart.com/smartwebservice'
VUE_APP_SERVICE_APP='http://www.south-smart.com'
NODE_ENV=production
VUE_APP_BASEURL='//172.16.10.132:8091/smartwebservice'
VUE_APP_SERVICE_APP='http://172.16.10.132:8010'
\ No newline at end of file
node_modules
/dist
/lib
/build
\ No newline at end of file
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'@smart/standard'
],
plugins: [
'vue'
],
rules: {
'comma-dangle': ['error', {
'arrays': 'never',
'objects': 'ignore',
'imports': 'ignore',
'exports': 'ignore',
'functions': 'ignore'
}],
'no-multi-spaces': ['error', {
'ignoreEOLComments': true
}],
'no-unused-vars': [2, { 'args': 'none' }],
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
};
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# {{name}}
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
module.exports = {
presets: [
'@vue/app'
]
};
// 接口地址
const baseUrl = process.env.VUE_APP_BASEURL;
// 服务发布地址,主要作用第三方服务
const serviceUrl = process.env.VUE_APP_SERVICE_APP;
if (typeof window !== 'undefined') window.baseUrl = baseUrl;
export {
baseUrl,
serviceUrl
};
<template>
<div id="formapp">
<form-view v-if="!pageId"></form-view>
<page-view v-else :id="pageId"></page-view>
</div>
</template>
<script>
import { getQueryString } from './utils/form';
import formView from './views/form.vue';
import pageView from './views/page.vue';
export default {
name: 'App',
components: {
formView,
pageView
},
data() {
return {
pageId: ''
};
},
created() {
this.pageId = getQueryString('pageId');
},
mounted() {
document.addEventListener('scroll', () => {
console.log(document.body.scrollTop);
});
}
};
</script>
import Vue from 'vue';
import axios from 'axios';
import qs from 'qs';
import './loginInterceptor';
import * as HTTP from '@config/http.config';
// 携带cookie信息
axios.defaults.withCredentials = true;
// 设置全局的请求次数,请求的间隙
axios.defaults.retry = 0;
axios.defaults.retryDelay = 1000;
// 请求超时拦截,重新请求
axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {
const config = err.config;
// If config does not exist or the retry option is not set, reject
if (!config || !config.retry) return Promise.reject(err);
// Set the variable for keeping track of the retry count
config.__retryCount = config.__retryCount || 0;
// Check if we've maxed out the total number of retries
if (config.__retryCount >= config.retry) {
// Reject with the error
return Promise.reject(err);
}
// Increase the retry count
config.__retryCount += 1;
// Create new promise to handle exponential backoff
const backoff = new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, config.retryDelay || 1);
});
// Return the promise in which recalls axios to retry the request
return backoff.then(function() {
return axios(config);
});
});
// 为Vue注册$http
Vue.prototype.$http = axios;
const CancelToken = axios.CancelToken;
let cancel;
const baseUrl = HTTP.baseUrl;
window.baseUrl = baseUrl;
const config = {
baseUrl,
/**
* get获取数据,通用方法
* @param {String} url
* @param {Object} params
* @param {Object} options
*/
doGetPromise(url, params, options = {}) {
const { timeout = 30000, ...arg } = options;
return new Promise((resolve, reject) => {
axios
.get(url, {
timeout: timeout,
...arg,
params: {
...params,
t: new Date().getTime() // 解决IE上get请求缓存问题
},
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
})
.then(response => {
resolve(response.data);
})
.catch(response => {
console.error('ajax error:', response);
reject(response);
});
});
},
/**
* FormData数据上传,文件上传必用
* @param {String} url
* @param {FormData} formData
*/
doPostPromiseForm(url, formData) {
return new Promise((resolve, reject) => {
axios
.post(url, formData, {
headers: {
'Content-type': 'multipart/form-data'
},
emulateJSON: false,
emulateHTTP: false,
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
})
.then(res => {
resolve(res.data);
})
.catch(res => {
console.log('post error:', res);
reject(res);
});
});
},
/**
* 默认方式提交from表单数据json
* @param {String} url
* @param {Object} data
*/
doPostPromise(url, data) {
return new Promise((resolve, reject) => {
axios
.post(url, qs.stringify(data), {
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
})
.then(res => {
resolve(res.data);
})
.catch(res => {
console.log('post error:', res);
reject(res);
});
});
},
/**
* 提交application/json方式
* @param {String} url
* @param {Object} data
*/
doPostPromiseJson(url, data) {
return new Promise((resolve, reject) => {
axios
.post(url, data, {
headers: {
'Content-type': 'application/json'
},
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
})
.then(res => {
resolve(res.data);
})
.catch(res => {
console.log('post error:', res);
reject(res);
});
});
}
};
// 切换页面强行中断请求 router.beforeEach中用到
Vue.prototype.$cancelAjax = function(msg) {
if (cancel) {
cancel(msg || '手动中断请求');
}
};
export default config;
import config from './config';
const baseUrl = config.baseUrl;
const Api = {
...config,
login(data) {
return config.doPostPromise(baseUrl + '/index/login', data);
},
checkLogin() {
return config.doGetPromise(baseUrl + '/index/checkLogin', {}, { retry: 0 });
},
logout() {
return config.doGetPromise(baseUrl + '/index/logout', {});
},
/**
*
* @param {*} taskId
* @param {*} linkId
* @param {*} linkKey
*/
getBusinessStartForm(businessDefinitionId) {
return config.doGetPromise(
baseUrl + '/v1.1.0/workflow/workflowForm/getBusinessStartForm',
{
businessDefinitionId
}
);
},
/**
* 获取渲染的表单数据
* @param {String} taskId
* @param {String} linkId linkInstanceId
* @param {String} linkKey linkDefinitionKey
*/
renderFormByTaskId(taskId, linkId, linkKey) {
return config.doGetPromise(
baseUrl + '/v1.1.0/workflow/workflowForm/renderFormByTaskId',
{
taskId: taskId,
linkInstanceId: linkId,
linkDefinitionKey: linkKey
}
);
},
/**
* 办结工作渲染表单
* @param {String} processId
*/
renderFinishForm(processId) {
return config.doGetPromise(
baseUrl + '/v1.1.0/workflow/workflowForm/renderFinishForm',
{
historyProcessInstanceId: processId
}
);
},
/**
* 通过获取表单ID获取表单模板
* @param {string} formid 表单ID
*/
getForm(formid) {
return config.doGetPromise(baseUrl + '/v1.1.0/form/getForm', {
rid: formid
});
},
getAdminDivisionTree() {
return config.doGetPromise(
baseUrl + '/administrativeDivisions/getAdministrativeDivisionTree'
);
},
/**
* 获取用户权限下的系统模块功能
* @param {String} id 子系统Id
*/
getSystemAllModules(id) {
return config.doGetPromise(
baseUrl + '/systemModule/privilege/getUserModulesTreeBySystemId',
{ systemId: id }
);
},
/**
* 获取组织结构的树状信息
* @param {Number} type 类型,1:只返回部门岗位信息; 2:返回部门岗位与人员信息; 3:返回角色信息; 4:返回部门(无岗位);5:返回人员;其他:返回所有组织项信息
* @param {Number} valid 是否可用, -1:审核中 1:可用(第一次登录,需要修改密码) 2:可用(非第一次登录,不需要修改密码)
*/
getOrganTree(type, valid) {
return config.doGetPromise(baseUrl + '/organization/manager/getOrganTree', {
type: type,
valid: valid
});
},
// 获取代码字典
getChildItemByRootCode(data) {
return config.doGetPromise(
baseUrl + '/codeDict/getChildItemByRootCode',
data
);
},
/**
* 提交前检查是否有下个环节处理人
* @param {string} taskId
* @param {FormData} data 表单数据
*/
checkAndSubmitTaskByFormData(taskId, data) {
return config.doPostPromiseForm(
baseUrl +
'/v1.1.0/workflow/workflowForm/checkAndSubmitTaskByFormData/' +
taskId,
data
);
},
/**
* 获取转办人的信息
* @param {string} taskId 流程ID
*/
getTranformUser(taskId) {
return config.doGetPromise(
baseUrl + '/workflow/linkInstance/findLinkInstanceByTaskIdPassto',
{
taskId: taskId
}
);
},
/**
* 退回 - 获取退回对话框处理人树数据
* @param {string} currentTaskId
* @param {string} processDefinitionId
* @param {string} nextLinkKey
*/
getRerunPeople(currentTaskId, processDefinitionId, nextLinkKey) {
return config.doGetPromise(
baseUrl + '/workflow/workflowForm/getRerunPeople',
{
currentTaskId,
processDefinitionId,
nextLinkKey
}
);
},
/**
* 退回 - 根据任务id获取执行流id(第三步)
*/
findExecutionIdByTaskId(taskId) {
return config.doGetPromise(
baseUrl + '/workflow/execution/findExecutionIdByTaskId',
{
taskId
}
);
},
/**
* 退回 - 当前环节跳转到指定环节(第四步)
* @param {*} executionId
* @param {*} linkDefinitionKey
* @param {*} rerunReason
* @param {*} operationType
* @param {*} isSendbackOldLink
* @param {*} anotherAssignee
*/
sendReturnTaks(
executionId,
linkDefinitionKey,
rerunReason = '',
operationType = 'reRun',
isSendbackOldLink = 0,
anotherAssignee
) {
return config.doGetPromise(
baseUrl + '/v1.1.0/workflow/workflowForm/sendback',
{
executionId,
linkDefinitionKey,
rerunReason,
operationType,
isSendbackOldLink,
anotherAssignee
}
);
}
};
export default Api;
import axios from 'axios';
import store from '@/store';
import router from '@/router';
/* const filters = ['webgisService']
const handleFilter = (key) => {
if (Array.isArray(filters)) {
filters.map(item => {
if (item === key) {}
})
}
} */
/**
* 登录判断失效
* 在所有经过axios请求中,拦截到登录失效
*
* @param {Object} response
*/
function loginInterceptor(response) {
// console.log(response)
// 通过状态码判断登录已经失效
if (response.data && response.data.status === 9) {
store.dispatch('setUserInfo', {});
router.replace({
name: 'Logindialog'
});
// response.data = null
return response;
} else {
return response;
}
}
axios.interceptors.response.use(loginInterceptor);
import config from '../api/config';
const url = config.baseUrl;
export default [
{
name: 'guidance',
text: '办理指南',
icon: 'el-icon-info',
api: url + '/workflowWebService/getProcessManagementGuide'
},
{
name: 'save',
text: '保存',
icon: 'el-icon-tickets',
api: url + '/v1.1.0/workflow/workflowForm/saveFormData'
},
{
name: 'sign',
text: '接办',
icon: 'el-icon-tickets',
api: url + '/workflow/workflowForm/receiveTasks'
// api: url + '/workflowWebService/claimTask'
},
{
name: 'forceSign',
text: '强制接办',
icon: 'el-icon-tickets',
api: url + '/workflowWebService/forceClaimForm'
},
{
name: 'submit',
text: '提交',
icon: 'el-icon-check',
api: url + '/v1.1.0/workflow/workflowForm/submitTaskOnDialog'
},
{
name: 'isSendBack',
text: '提交退回',
icon: 'el-icon-check',
api: url + '/v1.1.0/workflow/workflowForm/submitSendbackTask/'
},
/* {
id: 'backSend',
name: 'backsend',
text: '跳转',
icon: 'el-icon-news',
api: ''
}, */
{
name: 'finish',
text: '结档',
icon: 'el-icon-edit-outline',
api: url + '/workflowWebService/finishProcessInstanceByTaskId'
},
{
name: 'refund',
text: '退件',
icon: 'el-icon-back',
api: url + '/workflow/workflowForm/refundTasks'
},
{
name: 'urge',
text: '催办',
icon: 'el-icon-share',
api: url + '/workflow/workflowForm/remindTasks'
},
{
name: 'turn',
text: '转办',
icon: 'el-icon-refresh',
api: url + '/workflow/workflowForm/passTasksToSb'
},
{
name: 'unsign',
text: '撤办',
icon: 'el-icon-remove-outline',
api: url + '/workflow/workflowForm/unclaimTasks'
},
{
name: 'apply',
text: '申请挂起',
icon: 'el-icon-document',
api: url + '/workflow/workflowForm/applySuspendTasks'
},
{
name: 'suspend',
text: '挂起',
icon: 'el-icon-goods',
api: url + '/workflow/workflowForm/suspendProcesses'
},
{
name: 'activeSuspend',
text: '解除挂起',
icon: 'el-icon-sold-out',
api: url + '/workflow/workflowForm/activateProcesses'
},
{
name: 'withdraw',
text: '收回',
icon: 'el-icon-arrow-left',
api: url + '/workflow/workflowForm/withdrawTasks'
},
{
name: 'rerun',
text: '退回',
icon: 'el-icon-d-arrow-left',
api: url + '/workflowWebService/prepareJumpTo'
},
{
name: 'getdraw',
text: '流转情况',
icon: 'el-icon-sort'
},
{
name: 'isBRule',
text: '查看限制消息',
icon: 'el-icon-view',
api: url + '/workflowWebService/getBusinessRuleResults'
}
];
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" type="image/ico" href="<%= BASE_URL %>favicon.ico">
<title>表单渲染 - Smart Web</title>
<!-- <link rel="stylesheet" href="<%= BASE_URL %>iconfont/iconfont.css"> -->
<style type="text/css">
.maskbox {
border: 2px solid #ff0000;
background: #f8ecda;
opacity: 0.1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
}
</style>
</head>
<body>
<div id="formapp"></div>
<!-- built files will be auto injected -->
</body>
</html>
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import App from './App';
import './utils/init';
import ElemetUI from 'element-ui';
import 'element-ui/packages/theme-chalk/lib/index.css';
import VueProgressBar from 'vue-progressbar';
import SmartForm from 'smart-form';
import 'smart-form/lib/smartForm.css';
// import scss
import './styles/index.scss';
import './utils/expression';
Vue.config.productionTip = false;
Vue.use(ElemetUI, {
size: 'medium',
zIndex: 4000
});
Vue.use(SmartForm);
const vPopts = {
color: '#8fcdfc',
failedColor: '#874b4b',
thickness: '2px',
transition: {
speed: '0.1s',
opacity: '0.3s',
termination: 300
},
autoRevert: true,
location: 'top',
inverse: false,
autoFinish: true
};
Vue.use(VueProgressBar, vPopts);
/* eslint-disable no-new */
new Vue({
el: '#formapp',
components: {
App
},
template: '<App/>'
});
import Vuex from 'vuex';
const store = new Vuex.Store({
state: {
taskData: null
},
mutations: {
setTaskData(state, payload) {
state.taskData = payload;
}
},
actions: {
setTaskData({ commit }, payload) {
commit('setTaskData', payload);
}
}
});
export default store;
@import '@/styles/library.scss';
@import '@/styles/common/var.scss';
@import './mixins/mixins';
@import './reset';
.align-center {
text-align: center;
}
.fl {
float: left;
}
.flr {
float: right;
}
.clearfix {
clear: both;
&::after {
content: '';
display: block;
width: 0;
height: 0;
clear: both;
visibility: hidden;
}
}
html, body {
height: 100%;
}
body {
overflow-x: auto;
}
#formapp {
width: 100%;
height: 100%;
padding: 0;
overflow: auto;
// min-height: 100%;
// position: relative;
.app-loading {
position: fixed;
z-index: 29;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.form-header {
position: fixed;
top: 0;
left: 0;
z-index: 9;
width: 100%;
padding: 6px 12px;
background-color: #f2f2f2;
max-height: 44px;
overflow: auto;
}
.form-render {
padding-top: 28px;
width: 1000px;
margin: 0 auto;
}
.is-required {
.el-textarea__inner {
border-color: $--color-danger;
}
}
.page-view {
width: 100%;
height: 100%;
}
@include b(framework-tree) {
display: flex;
flex-direction: column;
width: 220px;
height: 100%;
padding-bottom: 10px;
border-right: $--border-base;
overflow: hidden;
background-color: rgba($color: mix($--color-black, $--color-primary-light-9), $alpha: 0.04);
@include e(header) {
padding: 0 4px 4px 4px;
}
@include e(wrapper) {
width: 100%;
height: 100%;
background-color: inherit;
overflow: auto;
@include b(custom-tree-node) {
flex: 1 1 auto;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.iconfont {
font-size: 16px;
margin-right: 4px;
}
@include b(tree-toolbar) {
display: none;
margin-right: 4px;
word-spacing: -5px;
.iconfont {
font-size: 16px;
margin-right: 0;
}
}
}
}
.el-tree-node__content {
font-size: 14px;
height: 30px;
&:hover {
background-color: rgba($color: mix($--color-black, $--color-primary-light-9), $alpha: 0.1);
.tree-toolbar {
display: block;
}
}
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background-color: $--color-primary-light-8;
position: relative;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
height: 100%;
border-left: 4px solid $--color-primary-light-4;
}
}
}
// 提交弹窗
@include b(submit-dialog) {
.el-dialog__body {
padding-top: 10px;
padding-bottom: 10px;
}
@include e(wrapper) {
display: flex;
flex-direction: row;
}
@include e(sidebar) {
width: 160px;
border-right: $--border-base;
@include m(title) {
padding: 6px 5px;
background: $--background-color-base;
}
@include m(content) {
padding: 10px 10px;
.el-checkbox {
display: block;
margin-bottom: 10px;
}
.el-checkbox + .el-checkbox {
margin-left: 0 !important;
}
}
}
@include e(content) {
margin-left: 6px;
flex: 1 1 auto;
overflow: hidden;
.users {
height: 300px;
border: $--border-base;
overflow: auto;
.title {
display: inline-block;
padding: 4px 8px;
background: $--background-color-base;
}
.cate-title {
display: block;
background-color: $--color-primary-light-9;
color: $--color-primary;
font-weight: 600;
}
.normal-users {
margin-top: 10px;
padding-top: 10px;
border-top: $--border-base;
border-color: $--border-color-extra-light;
}
}
.el-tree-node__content {
height: auto;
padding: 4px 0;
}
.custom-tree-node {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
padding-right: 10px;
& > span {
flex: 1 1 auto;
padding-right: 5px;
line-height: 1.1;
word-wrap: break-word;
white-space: normal;
}
.flr {
font-size: 12px;
}
}
.submit-reason {
margin-top: 10px;
}
}
.submit-dialog__footer {
padding-top: 20px;
padding-bottom: 10px;
}
}
// 转办
@include b(transform-work) {
@include e(dialog) {
.el-dialog {
max-height: 96%;
min-height: 400px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.el-dialog__body {
flex: 1 1 auto;
// display: flex;
// flex-direction: column;
padding: 10px 12px;
overflow: auto;
}
.el-tabs {
// flex: 1 1 auto;
// display: flex;
// flex-direction: column;
margin-bottom: 10px;
overflow: hidden;
.el-tabs__header {
margin-bottom: 0;
}
.el-tabs__content {
// flex: 1 1 auto;
border: $--border-base;
border-top: 0 none;
overflow: auto;
}
}
.framework-tree {
// flex: 1 1 auto;
width: 100%;
max-height: 50vh;
overflow: auto;
}
}
}
// 退回
@include b(return-work) {
@include e(dialog) {
.el-dialog {
max-height: 96%;
min-height: 450px;
display: flex;
flex-direction: column;
}
.el-dialog__body {
flex: 1 1 auto;
display: flex;
flex-direction: column;
padding: 10px 12px;
}
.el-container {
border: $--border-base;
.el-aside {
border-right: $--border-base;
li {
padding: 8px 10px;
cursor: pointer;
&.is-active {
color: #ffffff;
background-color: $--color-primary-light-4;
}
}
}
header {
padding: 6px 12px;
background-color: $--background-color-base;
}
.el-main {
display: flex;
flex-direction: column;
}
.el-tabs {
flex: 1 1 auto;
}
}
.el-tree-node__content {
height: auto;
padding: 4px 0;
}
.custom-tree-node {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
padding-right: 10px;
& > span {
flex: 1 1 auto;
padding-right: 5px;
line-height: 1.1;
word-wrap: break-word;
white-space: normal;
}
.flr {
font-size: 12px;
}
}
.framework-tree {
width: 100%;
border-right: 0;
background-color: transparent;
}
.submit-reason {
margin-top: 10px;
}
}
}
\ No newline at end of file
$namespace: '';
$element-separator: '__';
$modifier-separator: '--';
$state-prefix: 'is-';
@import "config";
/* BEM support Func
-------------------------- */
@function selectorToString($selector) {
$selector: inspect($selector);
$selector: str-slice($selector, 2, -2);
@return $selector;
}
@function containsModifier($selector) {
$selector: selectorToString($selector);
@if str-index($selector, $modifier-separator) {
@return true;
} @else {
@return false;
}
}
@function containWhenFlag($selector) {
$selector: selectorToString($selector);
@if str-index($selector, '.' + $state-prefix) {
@return true
} @else {
@return false
}
}
@function containPseudoClass($selector) {
$selector: selectorToString($selector);
@if str-index($selector, ':') {
@return true
} @else {
@return false
}
}
@function hitAllSpecialNestRule($selector) {
@return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector);
}
@import "function";
/* BEM
-------------------------- */
@mixin b($block) {
$B: $block !global;
.#{$B} {
@content;
}
}
@mixin e($element) {
$E: $element !global;
$selector: &;
$currentSelector: "";
@each $unit in $element {
$currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
}
@if hitAllSpecialNestRule($selector) {
@at-root {
#{$selector} {
#{$currentSelector} {
@content;
}
}
}
} @else {
@at-root {
#{$currentSelector} {
@content;
}
}
}
}
@mixin m($modifier) {
$selector: &;
$currentSelector: "";
@each $unit in $modifier {
$currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
}
@at-root {
#{$currentSelector} {
@content;
}
}
}
@mixin configurable-m($modifier, $E-flag: false) {
$selector: &;
$interpolation: '';
@if $E-flag {
$interpolation: $element-separator + $E-flag;
}
@at-root {
#{$selector} {
.#{$B+$interpolation+$modifier-separator+$modifier} {
@content;
}
}
}
}
@mixin spec-selector($specSelector: '', $element: $E, $modifier: false, $block: $B) {
$modifierCombo: '';
@if $modifier {
$modifierCombo: $modifier-separator + $modifier;
}
@at-root {
#{&}#{$specSelector}.#{$block+$element-separator+$element+$modifierCombo} {
@content
}
}
}
@mixin meb($modifier: false, $element: $E, $block: $B) {
$selector: &;
$modifierCombo: '';
@if $modifier {
$modifierCombo: $modifier-separator + $modifier;
}
@at-root {
#{$selector} {
.#{$block+$element-separator+$element+$modifierCombo} {
@content
}
}
}
}
@mixin when($state) {
@at-root {
&.#{$state-prefix + $state} {
@content;
}
}
}
@mixin extend-rule($name) {
@extend #{'%shared-'+$name};
}
@mixin share-rule($name) {
$rule-name: '%shared-'+$name;
@at-root #{$rule-name} {
@content
}
}
\ No newline at end of file
@mixin utils-user-select($value) {
-moz-user-select: $value;
-webkit-user-select: $value;
-ms-user-select: $value;
}
@mixin utils-clearfix {
$selector: &;
@at-root {
#{$selector}::before,
#{$selector}::after {
display: table;
content: "";
}
#{$selector}::after {
clear: both
}
}
}
@mixin utils-vertical-center {
$selector: &;
@at-root {
#{$selector}::after {
display: inline-block;
content: "";
height: 100%;
vertical-align: middle
}
}
}
@mixin utils-ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
\ No newline at end of file
blockquote,body,button,dd,dl,dt,fieldset,form,h1,h2,h3,h4,h5,h6,hr,html,iframe,input,legend,li,ol,p,pre,td,textarea,th,ul{
margin:0;
padding:0;
}
html, body {
width: 100%;
}
body {
min-width: 1200px;
font-size: 1rem;
font-family: -apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif;
color: #606266;
overflow: auto;
}
iframe {
width: 100%;
height: 100%;
border: 0;
outline: none;
}
a {
color: #0a6fe2;
text-decoration: none;
}
ul, ol, li {
list-style: none;
}
* {
scrollbar-base-color: #cecece;
scrollbar-3dlight-color: #eee;
scrollbar-highlight-color: #eee;
scrollbar-track-color: #f1f1f1;
// scrollbar-arrow-color: #000;
scrollbar-shadow-color: #eee;
// scrollbar-dark-shadow-color: #eee;
box-sizing: border-box;
}
*::-webkit-scrollbar {
width: 6px;
height: 6px;
}
*::-webkit-scrollbar-button {
display: none;
}
*::-webkit-scrollbar-track-piece {
background-color: #f2f2f2;
}
*::-webkit-scrollbar-thumb {
background-color: #C1C1C1;
border-radius: 6px;
}
\ No newline at end of file
const parentExpression = window.parent ? window.parent.$ : null;
const $ = {};
/**
* 引入平台表达式
* 扩展表单表达式
*/
// 合并父级表达式
if (parentExpression) {
Object.keys(parentExpression).forEach(function(key) {
$[key] = parentExpression[key];
});
}
/**
* @example
* $.form.xxx()
*/
$.form = {
/**
* 获取业务受理号
*/
getBusinessNumber() {
return window.taskData ? window.taskData.businessNumber : '';
},
/**
* 通过字段名获取表单的值
* @param {String} field 表单控件绑定字段,如JOB_YWB-RID
*/
getFormValue(field) {
const formData = window.formData;
if (formData) {
let value = null;
Object.keys(formData).forEach(key => {
if (key === field) value = formData[key];
});
return value;
} else {
return null;
}
},
/**
* 通过字段名设置表单的值
* @param {String} field 表单控件绑定字段,如JOB_YWB-RID
* @param {Any} value 传值
*/
setFormValue(field, value) {
const formData = window.formData;
if (formData) {
Object.keys(formData).forEach(key => {
if (key === field) formData[key] = value;
});
}
},
/**
* 获取任务ID
*/
getTaskId() {
return window.taskData ? window.taskData.taskId : '';
},
/**
* 获取环节ID
*/
getLinkId() {
return window.taskData ? window.taskData.linkId : '';
},
/**
* 获取环节KEY
*/
getLinkKey() {
return window.taskData ? window.taskData.linkKey : '';
},
/**
* 获取流程实例ID
*/
getProcessInstanceId() {
return window.taskData ? window.taskData.processInstanceId : '';
},
/**
* 获取流程定义ID
*/
getProcessDefinitionId() {
return window.taskData ? window.taskData.processDefinitionId : '';
}
};
window.$ = $;
import { Notification } from 'element-ui';
/**
* 处理数值,默认返回px单位
* @param {string|nubmer} val
* @returns {stirng}
*/
export const handleNumUnit = val => {
return isNaN(Number(val)) ? val : val + 'px';
};
/**
* 获取URL参数
* @param {string} name 参数名
*/
export function getQueryString(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
const r = window.location.search.substr(1).match(reg);
if (r !== null) return unescape(r[2]);
return null;
}
export function getBusinessDefinitionId() {
return getQueryString('businessDefinitionId');
}
export function getFormId() {
return getQueryString('formid');
}
export function getTaskId() {
return getQueryString('taskId');
}
export function getLinkId() {
return getQueryString('linkId');
}
export function getLinkKey() {
return getQueryString('linkKey');
}
export function getFinishForm() {
return getQueryString('historyProcessInstanceId');
}
/**
* 统一处理提示
* @param {string} type success warning error
* @param {string} message 提示文字
* @param {string} title 提示标题
*/
export function notification(type, message, title) {
// Message[type](message)
title = title || '';
if (!title) {
switch (type) {
case 'success':
title = '操作成功';
break;
case 'info':
title = '提示';
break;
case 'warning':
title = '操作失败';
break;
case 'error':
title = '操作错误';
break;
}
}
Notification({
type: type,
title: title,
message: message,
position: 'top-right'
});
}
/**
* 外部页面公共通知方法
* @param {Object} options 和element-ui Notification组件属性一样
*/
export function outerNotice(options) {
const parentWin = window.parent;
parentWin.notification && parentWin.notification(options);
}
/**
* 打开标签
* @param {Object} component 组件的对象,比如 {id:'', name:'组织构架管理', componentName:'frameworkManage'}
* @param {Object} param 参数
*/
export function openTab(component, param) {
window.$.menu.openTab(component, param);
}
/**
* 关闭标签
*/
export function closeTab() {
const parentWin = window.parent;
const tabId = parentWin.currentNavigation.id || '';
if (tabId) parentWin.removeTab && parentWin.removeTab(tabId);
}
/**
* 刷新标签页
*/
export function refreshTab(tabId) {
const parentWin = window.parent;
tabId =
tabId ||
(parentWin.currentNavigation &&
parentWin.currentNavigation.param &&
parentWin.currentNavigation.param.parent);
if (tabId) parentWin.refreshTab && parentWin.refreshTab(tabId);
}
// 设置高级或某此控件需要【数组】、【对象】类型
// 比如upload_list, sign
const checkObjectJson = data => {
const widgets = ['upload_list', 'sign', 'select'];
if (widgets.includes(data.type)) {
return data.model;
} else {
return '';
}
};
/**
* 遍历表单模板数据,返回需要【数组】、【对象】类型控件的models数据
* @param {Object} formdata
* @returns {Array} models
*/
export const transformFormData = formdata => {
if (!formdata.list) return;
const arr = [];
const fn = data => {
data.map(item => {
// console.log(item)
if (item.type === 'grid') {
item.columns.map(col => {
fn(col.list);
});
} else if (item.type !== 'text' && item.type !== 'button') {
const model = checkObjectJson(item);
if (model) arr.push(model);
}
});
};
fn(formdata.list);
return arr;
};
const utils = {
/**
* 判断数据是否为空,一般数据是object/array
* @param {Object/Array}
*/
isEmptyData(data) {
if (data === null || data === undefined) return true;
if (data instanceof Object) {
let t;
for (t in data) {
return false;
}
return true;
} else if (data instanceof Array) {
if (data.length === 0) return true;
return false;
}
},
/**
* 深拷贝
* @param {Object|Array} p
* @param {Object|Array} c [] or {}
*/
deepCopy(p, c) {
c = c || {};
for (const i in p) {
if (typeof p[i] === 'object') {
c[i] = p[i] ? (p[i] && p[i].constructor === Array ? [] : {}) : p[i];
this.deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
},
/**
* 随机生成唯一 ID
* @param {Number}
*/
generateId(len = 4) {
return Number(
Math.random()
.toString()
.substr(3, len) + Date.now()
).toString(36);
},
/**
* 优化遍历,数组去重
* @param {Array} array
*/
uniq(array, key) {
const temp = [];
const index = [];
const l = array.length;
for (let i = 0; i < l; i++) {
for (let j = i + 1; j < l; j++) {
if (array[i][key] && array[i][key] === array[j][key]) {
i++;
j = i;
}
}
temp.push(array[i]);
index.push(i);
}
return temp;
}
};
export default utils;
const $ = window.parent ? window.parent.$ : {};
/**
* 全局作用在表单库里内部读取window上的方法
*
* taskData 是请求表单数据后注册到window上的对象,
* 包含{taskId, linkId, linkKey, processDefinitionId, processDefinitionKey, processInstanceId, businessNumber}
*/
window.getUser = $.system.getUser;
window.getUserName = $.system.getUserName;
window.getBussinessId = function() {
return window.taskData ? window.taskData.businessNumber : '';
};
<template>
<el-dialog :visible.sync="dialogVisible" title="查看业务办理指南" fullscreen @closed="handleClosed">
<el-tabs tab-position="left">
<el-tab-pane label="操作指南" v-html="htmlContent.ManagementGuide"></el-tab-pane>
<el-tab-pane label="填写说明" v-html="htmlContent.LinkDefinitionDescription"></el-tab-pane>
</el-tabs>
</el-dialog>
</template>
<script>
import Api from '@form/api';
export default {
name: 'GuideDialog',
props: ['data'],
data() {
return {
dialogVisible: false,
htmlContent: {
ManagementGuide: '',
LinkDefinitionDescription: ''
}
};
},
mounted() {
this.dialogVisible = true;
this.init();
},
destroyed() {
this.dialogVisible = false;
},
methods: {
init() {
Api.doGetPromise(this.data.api, {
processDefinitionId: this.data.processDefinitionId,
taskKey: this.data.linkKey
}).then(res => {
this.htmlContent = res;
});
},
handleClosed() {
this.$emit('closed');
}
}
};
</script>
<template>
<div class="return-work">
<el-dialog
class="return-work__dialog"
:visible.sync="dialogVisible"
title="退回工作"
@closed="handleClosed"
>
<el-container>
<el-aside width="200px">
<header>选择退回环节</header>
<section>
<ul>
<li
v-for="item in linkEntity"
:key="item.definitionKey"
:class="{'is-active': item.definitionKey === currentKey}"
@click="handleLinkClick(item.definitionKey)"
>{{ item.definitionName }}</li>
</ul>
</section>
</el-aside>
<el-main v-loading="isLoadingPeople">
<el-tabs type="card" v-model="currentTab">
<el-tab-pane label="默认处理人" name="default">
<el-tree
ref="mainTree"
:data="currentData.defUsers"
:props="treeProps"
default-expand-all
show-checkbox
node-key="id"
check-on-click-node
:default-checked-keys="defChecked"
>
<div class="custom-tree-node" slot-scope="{node, data}">
<span>{{ node.label }}</span>
<div class="flr">
<span>
待处理任务:
<strong>{{ data.count ? data.count : 0 }}</strong>条,
在职状态:
<strong>{{ handleUserState(data.organInfo.status) }}</strong>
</span>
</div>
</div>
</el-tree>
</el-tab-pane>
<el-tab-pane label="另选处理人" name="another">
<div class="framework-tree">
<el-tree
class="framework-tree__wrapper"
ref="anotherTree"
:data="currentData.anoUsers"
:props="treeProps"
default-expand-all
node-key="id"
check-on-click-node
highlight-current
@current-change="handleAnoTreeCurrentChange"
>
<div class="custom-tree-node" slot-scope="{node, data}">
<span>{{ node.label }}</span>
<div class="flr">
<span>
待处理任务:
<strong>{{ data.count ? data.count : 0 }}</strong>条,
在职状态:
<strong>{{ handleUserState(data.organInfo.status) }}</strong>
</span>
</div>
</div>
</el-tree>
</div>
</el-tab-pane>
</el-tabs>
<div class="submit-reason">
<div class="title">退回原因:</div>
<el-tooltip effect="dark" placement="right" content="不能为空" :disabled="!!reason">
<el-input
type="textarea"
v-model="reason"
:class="{'is-required': !reason}"
:rows="3"
placeholder="原因必填"
></el-input>
</el-tooltip>
</div>
</el-main>
</el-container>
<div slot="footer">
<!-- <el-checkbox v-model="isUrgent" style="margin-right: 15px;">紧急</el-checkbox> -->
<span style="margin-right: 15px;">
退回环节处理完成后的操作:
<el-radio-group v-model="returnType">
<el-radio :label="0">按流程定义提交</el-radio>
<el-radio :label="1">提交到本环节</el-radio>
</el-radio-group>
</span>
<el-button
type="primary"
:disabled="!currentKey"
:loading="isSubmiting"
@click="submitTask"
>提交</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import Api from '@form/api';
import { notification } from '@form/utils/form';
export default {
name: 'returnTask',
props: ['data'],
data() {
return {
dialogVisible: false,
linkEntity: [], // 有下个环节的主体
isLoadingPeople: false, // 加载下个环节人
currentTab: 'default',
currentKey: '', // 选中当前环节的Key
currentData: {
defUsers: null,
anoUsers: null
},
treeProps: {
label: 'fullName',
children: 'children'
},
defChecked: [],
anoChecked: '',
reason: '',
returnType: 0,
isSubmiting: false
};
},
mounted() {
this.init();
},
methods: {
init() {
if (!this.data) return;
/* this.dialogVisible = true // 测试弹窗打开
this.linkEntity = [{
definitionKey: 'eq9jn2y97g0',
definitionName: '收件'
}] */
Api.doGetPromise(this.data.api, {
taskId: this.data.taskId,
opertionType: 1
})
.then(res => {
// console.log(res)
if (res.length === 0) {
notification(
'info',
res.message || '任务没有历史,不可执行退回操作!'
);
this.handleClosed();
} else {
if (res[0]) {
// 有历史的,可以执行退回
this.dialogVisible = true;
this.linkEntity = [];
res.map(item => {
this.linkEntity.push(item.linkDefinitionEntity);
});
} else {
notification('info', '任务没有历史,不可执行退回操作!');
this.handleClosed();
}
}
})
.catch(err => {
notification('error', err.message || '退回服务失败!');
this.handleClosed();
});
},
handleUserState(status) {
if (status === 1 || status === 2) return '在职';
return '离职';
},
// 另选处理人的选中监听
handleAnoTreeCurrentChange(data) {
this.anoChecked = data.id;
},
// 获取退回环节的人员
getRerunPeople(nextLink) {
this.isLoadingPeople = true;
// Api.getRerunPeople('110c73b6-54f5-11e9-ba9c-005056c00001', '9b498463-04bc-11e9-a8ab-005056c00001', 'eq9jn2y97g0')
Api.getRerunPeople(
this.data.taskId,
this.data.processDefinitionId,
nextLink
)
.then(res => {
this.isLoadingPeople = false;
// console.log('getRerunPeople: ', res)
if (res.status === 0) {
const defUsers = res.data.defaultUserInfos;
const anoUsers = res.data.anotherUserInfos;
this.currentData.defUsers = [];
this.currentData.anoUsers = [];
for (const key in defUsers) {
defUsers[key].disabled = true;
defUsers[key].id = key;
this.defChecked.push(key);
this.currentData.defUsers.push(defUsers[key]);
}
for (const key in anoUsers) {
anoUsers[key].id = key;
this.currentData.anoUsers.push(anoUsers[key]);
}
// this.currentData = res.data
} else {
notification('warning', res.message || '获取人员失败,请重试!');
}
})
.catch(err => {
this.isLoadingPeople = false;
notification('error', err.message || '网络有误,请重试!');
});
},
handleClosed() {
this.$emit('closed');
},
// 环节点击
handleLinkClick(key) {
this.currentKey = key;
this.getRerunPeople(key);
},
submitTask() {
if (this.currentTab === 'another' && !this.anoChecked) {
notification('warning', '请选择另选处理人!');
return;
}
if (!this.reason) {
notification('warning', '请填写退回原因!');
return;
}
this.isSubmiting = true;
// 提交前先获取执行流程ID
Api.findExecutionIdByTaskId(this.data.taskId)
.then(res => {
if (res.status === 0) {
// 第四步,发送
const another =
this.currentTab === 'another' ? this.anoChecked : '';
// console.log(res.data, this.data.linkKey, this.reason, undefined, this.returnType, another)
Api.sendReturnTaks(
res.data,
this.currentKey,
this.reason,
undefined,
this.returnType,
another
)
.then(res => {
this.isSubmiting = false;
if (res.status === 0) {
notification('success', '退回成功!');
this.$emit('done');
} else {
notification(
'warning',
res.message || '退回提交失败,请重试!'
);
}
})
.catch(err => {
this.isSubmiting = false;
notification('error', err.message || '退回提交失败,请重试!');
});
} else {
this.isSubmiting = false;
notification('warning', res.message || '退回提交失败,请重试!');
}
})
.catch(err => {
this.isSubmiting = false;
notification('error', err.message || '退回提交失败,请重试!');
});
}
}
};
</script>
<template>
<el-dialog
:visible.sync="submitDialogVisible"
top="5%"
width="750px"
class="submit-dialog"
:modal-append-to-body="false"
title="选择处理人"
:close-on-click-modal="false"
@closed="handleDialogClosed">
<div class="submit-dialog__wrapper">
<div class="submit-dialog__sidebar">
<div class="submit-dialog__sidebar--title">
<span>下一环节</span>
</div>
<div class="submit-dialog__sidebar--content">
<!-- <ul>
<li v-for="link in nextLinks" :key="link.definitionKey">
<el-radio v-model="currentLink" :label="link" border>{{ link.definitionName }}</el-radio>
</li>
</ul> -->
<el-checkbox-group v-model="checkedLink">
<el-checkbox v-for="link in nextLinks" :key="link.definitionKey" :label="link" @change="handleCrrentLink(link)">
<span @click.stop.prevent="handleCrrentLink(link)">{{ link.definitionName }}</span>
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div class="submit-dialog__content">
<div class="users">
<div class="main-users">
<span class="title cate-title">{{ currentLink.name }}</span>
<span class="title">主要处理人</span>
<el-tree
ref="mainTree"
:data="currentLink.masterMen"
:props="treeProps"
node-key="id"
default-expand-all
show-checkbox
check-on-click-node
:default-checked-keys="mainCheckedKeys"
@check-change="handleMainTreeCheckChange">
<div class="custom-tree-node" slot-scope="{node, data}">
<span>{{ node.label }}</span>
<div class="flr" >
<span>
待处理任务:<strong>{{ data.count ? data.count : 0 }}</strong>条,
在职状态:<strong>{{ handleUserState(data.organInfo.status) }}</strong>
</span>
</div>
</div>
</el-tree>
</div>
<div class="normal-users">
<span class="title">一般处理人</span>
<el-tree
ref="narmalTree"
:data="currentLink.normalMen"
:props="treeProps"
node-key="id"
default-expand-all
show-checkbox
check-on-click-node
:default-checked-keys="normalCheckedKeys"
@check-change="handleNorTreeCheckChange">
<div class="custom-tree-node" slot-scope="{node, data}">
<span>{{ node.label }}</span>
<div class="flr" >
<span>待处理任务:{{ data.count ? data.count : 0 }}条,在职状态:{{ handleUserState(data.organInfo.status) }}</span>
</div>
</div>
</el-tree>
</div>
</div>
<div class="submit-reason">
<span>提交原因:</span>
<div>
<el-input type="textarea" :rows="3" v-model="subReson"></el-input>
</div>
</div>
</div>
</div>
<div slot="footer" class="submit-dialog__footer">
<el-checkbox v-model="isUrgent" style="margin-right: 15px;">紧急</el-checkbox>
<el-button type="primary" :disabled="checkedLink.length === 0" :loading="isSubmiting" @click="saveTask">保存</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'SubmitTask',
props: {
data: Object,
nextLinks: {
type: Array,
default: () => []
},
nextLinkUsers: {
type: [Array, Object],
default: () => []
}
},
data() {
return {
submitDialogVisible: false,
currentLink: '', // 环节的选择
checkedLink: [],
userStack: [], // 存储环节用户栈
selectionLink: [],
treeProps: {
label: 'fullName',
children: 'children'
},
mainCheckedKeys: [],
normalCheckedKeys: [],
subReson: '',
isUrgent: false,
isSubmiting: false,
isCanceling: false, // 取消中。。。
closedAction: 'close'
};
},
watch: {
nextLinks: {
immediate: true,
deep: false,
handler(val) {
if (val.length === 0) {
this.currentLink = '';
this.userStack = [];
return;
}
// 初始时,先把数据整合好
this.nextLinks.forEach(link => {
const masterMen = [];
const normalMen = [];
for (const user in this.nextLinkUsers) {
if (link.masterMen.includes(user)) {
this.nextLinkUsers[user].id = this.nextLinkUsers[user].organInfo.rid;
masterMen.push(this.nextLinkUsers[user]);
}
if (link.normalMen.includes(user)) {
this.nextLinkUsers[user].id = this.nextLinkUsers[user].organInfo.rid;
normalMen.push(this.nextLinkUsers[user]);
}
}
this.userStack.push({
...link,
id: link.definitionKey,
name: link.definitionName,
masterMen: masterMen,
normalMen: normalMen
});
});
}
},
currentLink(val) { // 选中当前环节处理
if (!val) return;
this.mainCheckedKeys = [];
this.normalCheckedKeys = [];
this.currentLink.masterMen.forEach(user => {
this.$set(user, 'checked', true);
// 如果提交所有人,禁止状态,不能改变选中
if (val.completingToAll) this.$set(user, 'disabled', true);
this.mainCheckedKeys.push(user.organInfo.rid);
});
this.currentLink.normalMen.forEach(user => {
this.$set(user, 'checked', true);
// 如果提交所有人,禁止状态,不能改变选中
if (val.completingToAll) this.$set(user, 'disabled', true);
this.normalCheckedKeys.push(user.organInfo.rid);
});
},
checkedLink(val) { // 环节选择监听
this.handleCheckChange();
}
},
mounted() {
this.submitDialogVisible = true;
// 默认显示第一条
this.currentLink = this.userStack[0];
},
methods: {
handleCrrentLink(link) {
this.userStack.forEach(item => {
if (item.id === link.definitionKey) {
this.currentLink = item;
}
});
},
handleUserState(status) {
if (status === 1 || status === 2) return '在职';
return '离职';
},
handleMainTreeCheckChange(data, isCheck, isLeaf) {
data.checked = isCheck;
},
// 一般处理人选择改变
handleNorTreeCheckChange(data, isCheck) {
data.checked = isCheck;
},
// 下一环节选择
handleCheckChange() {
this.selectionLink = [];
this.checkedLink.forEach(link => {
this.userStack.forEach(stack => {
if (link.definitionKey === stack.id) {
this.selectionLink.push(stack);
}
});
});
},
saveTask() {
if (this.selectionLink.length === 0) return;
this.isSubmiting = true;
let data = [];
this.selectionLink.forEach(link => {
const masterMens = [];
const normalMens = [];
const obj = {};
link.masterMen.forEach(user => {
if (user.checked) masterMens.push(user.id);
});
link.normalMen.forEach(user => {
if (user.checked) normalMens.push(user.id);
});
obj[link.id] = {
masterMens: masterMens,
normalMens: normalMens,
resion: this.subReson,
emergencyLevel: this.isUrgent ? 1 : 0
};
data.push(JSON.stringify(obj));
});
data = data.join(',');
this.$emit('save', data);
},
handleDialogClosed() {
this.$emit('closed', this.closedAction);
}
}
};
</script>
<template>
<div class="transform-work">
<el-dialog
class="transform-work__dialog"
:visible.sync="showCheckPeople"
title="转办操作"
width="600px"
top="2%"
:modal-append-to-body="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
@opened="handleCheckOpened"
@closed="handleClosed"
>
<el-tabs type="card">
<el-tab-pane label="选择处理人">
<div class="framework-tree">
<el-tree
class="framework-tree__wrapper"
ref="frameTreeCheckFirst"
:data="framesFirstData"
:props="{
label: 'organName'
}"
node-key="treeNodeId"
empty-text="无选择处理人"
:expand-on-click-node="false"
default-expand-all
highlight-current
@current-change="handleCurrentFirstChange"
>
<span class="custom-tree-node" slot-scope="{node, data}">
<span>
<i :class="['iconfont', data.iconCls]"></i>
{{ node.label }}
</span>
</span>
</el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="另选处理人">
<div class="framework-tree">
<div class="framework-tree__header">
<el-input
placeholder="输入名称进行过滤"
v-model="filterText"
size="small"
prefix-icon="el-icon-search"
clearable
></el-input>
</div>
<el-tree
class="framework-tree__wrapper"
ref="frameTreeCheck"
:data="framesData"
:props="treeProps"
node-key="treeNodeId"
empty-text="无另选处理人"
:expand-on-click-node="false"
default-expand-all
highlight-current
:filter-node-method="filterNode"
@current-change="handleCurrentFirstChange"
>
<span class="custom-tree-node" slot-scope="{node, data}">
<span>
<i :class="['iconfont', data.iconCls]"></i>
{{ node.label }}
</span>
</span>
</el-tree>
</div>
</el-tab-pane>
</el-tabs>
<div class="transform-reason">
<div class="title">转办原因:</div>
<el-tooltip effect="dark" placement="right" content="不能为空" :disabled="!!reason">
<el-input
type="textarea"
v-model="reason"
:class="{'is-required': !reason}"
:rows="3"
placeholder="原因必填"
></el-input>
</el-tooltip>
</div>
<div slot="footer" class="transform-work__dialog--btns">
<el-checkbox
v-model="isEmergency"
:true-label="1"
:false-label="0"
style="margin-right: 10px;"
>紧急</el-checkbox>
<el-button type="primary" :loading="isSubmiting" @click="handleSave">保存</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import Api from '@form/api';
import { notification } from '@form/utils/form';
/**
* 转办
*/
export default {
name: 'transformWork',
props: ['data'],
data() {
return {
showCheckPeople: false,
filterText: '',
treeProps: {
label: 'text',
children: 'children'
},
framesFirstData: null,
framesData: null,
checkedUser: null,
reason: '',
isEmergency: 0,
isSubmiting: false
};
},
watch: {
filterText(val) {
this.$refs['frameTreeCheck'].filter(val);
}
},
mounted() {
this.init();
},
methods: {
init() {
this.getTansformUser();
this.getOrganTree();
this.showCheckPeople = true;
},
getTansformUser() {
Api.getTranformUser(this.data.taskId)
.then(res => {
// console.log(res)
if (res.status === 0) {
// this.framesData = res.data
const data = res.data;
if (data.userInfos) {
const _data = [];
for (const item in data.userInfos) {
_data.push(item.organInfo);
}
this.framesFirstData = _data;
} else {
this.framesFirstData = data;
}
} else {
notification('warning', res.message || '获取转办人失败,请重试');
}
})
.catch(err => {
notification('error', err.message || '获取转办人失败');
});
},
getOrganTree() {
Api.getOrganTree(2, 1).then(res => {
if (res.status === 0) {
this.framesData = res.data;
}
});
},
filterNode(value, data) {
if (!value) return true;
return data[this.treeProps.label].indexOf(value) !== -1;
},
handleCurrentFirstChange(data) {
this.checkedUser = data;
},
handleSave() {
if (!this.checkedUser || this.checkedUser.attributes.organType !== 10) {
this.$alert('请选择或只能选择处理人', '提示', {
type: 'warning'
});
return;
}
if (this.reason) {
this.submitTransform();
}
},
submitTransform() {
// console.log(this.checkedUser)
const submitData = [
{
taskId: this.data['taskId'],
assignee: this.checkedUser.id || this.checkedUser.rid,
passToReanson: this.reason,
emergencyLevel: this.isEmergency
}
];
this.isSubmiting = true;
Api.doPostPromiseJson(this.data.api, submitData)
.then(res => {
this.isSubmiting = false;
if (res.status === 0) {
notification('success', '转办成功!');
this.$emit('save', res);
} else {
notification('warning', res.message || '转办失败,请重试');
}
})
.catch(err => {
this.isSubmiting = false;
notification('error', '转办失败' + err.message);
});
},
handleCheckOpened() {
this.$refs['frameTreeCheck'].setCurrentKey(null);
this.reason = '';
},
handleClosed() {
this.$emit('closed');
}
}
};
</script>
<template>
<div class="form-app">
<div v-if="loadError" style="margin-top: 60px; text-align: center;">
<i class="el-icon-warning" style="color: red"></i> 表单获取失败
</div>
<div class="form-header">
<el-button
v-for="(item,index) in headBtnLists"
:key="item.id"
:id="item.id"
:icon="item.icon"
size="small"
@click="handleMethod(item, index)"
>{{item.text}}</el-button>
<!-- 自定义按钮 -->
<el-button
v-for="(item, index) in headCustomBtns"
:key="index"
size="small"
@click="handleCustomBtn(item)"
>{{ item.operationName }}</el-button>
</div>
<div class="form-render" v-if="isReRender">
<smart-form :data="formData" :value="values" ref="generateForm"></smart-form>
</div>
<template v-if="isLoading">
<div class="app-loading" v-loading="isLoading" element-loading-text="加载处理中..."></div>
</template>
<!-- 办理指南 -->
<guide-dialog
v-if="guideDialogVisible"
:data="childrenData"
@closed="guideDialogVisible = false"
></guide-dialog>
<!-- 提交弹窗选择环节处理人 -->
<submit-task
v-if="submitTaskDialogVisible"
:data="childrenData"
ref="submitTask"
:nextLinks="submitData.subTask"
:nextLinkUsers="submitData.userInfos"
@closed="submitTaskDialogVisible = false"
@save="handleSubmitTaskSave"
></submit-task>
<!-- 转办 -->
<transform-work
v-if="transformDialogVisible"
:data="childrenData"
@closed="transformDialogVisible = false"
@save="handleTransformTaskSave"
></transform-work>
<!-- 退回 -->
<return-task
v-if="returnTaskVisible"
:data="childrenData"
@closed="returnTaskVisible = false"
@done="handleReturnTaskDone"
></return-task>
</div>
</template>
<script>
import SubmitTask from './common/submitTask.vue';
import TransformWork from './common/transformWork.vue';
import GuideDialog from './common/guide.vue';
import ReturnTask from './common/returnTask.vue';
// import Utils from '@form/utils'
import {
transformFormData,
getBusinessDefinitionId,
getFormId,
getTaskId,
getLinkId,
getLinkKey,
getFinishForm,
notification,
outerNotice,
openTab,
closeTab,
refreshTab
} from '@form/utils/form';
import Api from '@form/api';
import btnsSourceMap from '@form/config/btnsSourceMap';
export default {
name: 'formView',
components: {
// generateForm
SubmitTask,
TransformWork,
GuideDialog,
ReturnTask
},
computed: {
loadError() {
return (
!this.isLoading &&
(!this.formData || Object.keys(this.formData).length === 0)
);
},
isSelect() {
return !!getFormId();
}
},
data() {
return {
apiFnName: '', // 加载API的方法名
isLoading: false, // 加载过渡
isReRender: true, // 重渲染
headBtnLists: [], // 头部的按钮列表
headCustomBtns: [], // 头部自定义按钮,一般包含表达式
formData: {},
values: {},
childrenData: {
taskId: getTaskId(),
linkId: getLinkId(),
linkKey: getLinkKey()
},
guideDialogVisible: false, // 办理指南dialog
submitTaskDialogVisible: false, // 提交dialog
submitData: {},
transformDialogVisible: false, // 转办dialog
returnTaskVisible: false // 退回dialog
};
},
created() {
this.init();
},
mounted() {
/* this.$refs['generateForm'].$on('form-item-click', (widget, isChecked) => {
console.log(widget, isChecked)
}) */
},
methods: {
init() {
this.fetch();
},
// 刷新
refresh() {
this.fetch();
},
handleResultHtml(data, key) {
try {
data = JSON.parse(data);
return data.data[key];
} catch (error) {
console.error(error);
return {};
}
},
fetch() {
let taskId = getTaskId() || this.childrenData.taskId;
const linkId = getLinkId() || this.childrenData.linkId;
const linkKey = getLinkKey() || this.childrenData.linkKey;
// console.log(taskId, linkId, linkKey)
let apiFn = 'renderFormByTaskId';
if (getBusinessDefinitionId()) {
// 创建时请求
taskId = getBusinessDefinitionId();
apiFn = 'getBusinessStartForm';
} else if (getFormId()) {
// 通过formid去获取表单值
taskId = getFormId();
apiFn = 'getForm';
} else if (getFinishForm()) {
taskId = getFinishForm();
apiFn = 'renderFinishForm';
}
this.isLoading = true;
Api[apiFn](taskId, linkId, linkKey)
.then(res => {
this.isLoading = false;
if (res.status === 0) {
// 判断是通过ID获取的模板渲染
if (getFormId()) {
const data = res.data.form;
this.formData = JSON.parse(data.templatejson) || {};
} else {
const detailMap = res.data.detailMap;
const ourselfOperationShow = detailMap.ourselfOperationShow;
const result = detailMap.result;
// 头部按钮初始化
if (ourselfOperationShow) {
const headBtnLists = [];
btnsSourceMap.forEach(item => {
if (ourselfOperationShow[item.name]) {
headBtnLists.push(item);
}
});
this.headBtnLists = headBtnLists;
// 自定义按钮
let operationConfigs;
try {
operationConfigs = JSON.parse(detailMap.operationConfigs);
} catch {
throw new Error('自定义按钮数据格式有误');
}
this.headCustomBtns = operationConfigs[0];
// console.log('header buttons: ', ourselfOperationShow, this.headCustomBtns)
}
// 其他属性赋值
this.childrenData['taskId'] = detailMap.taskId;
this.childrenData['linkId'] = detailMap.linkInstanceId;
this.childrenData['linkKey'] = detailMap.linkDefinitionKey;
this.childrenData['processDefinitionId'] =
detailMap.processDefinitionId;
this.childrenData['processDefinitionKey'] =
detailMap.processDefinitionKey;
this.childrenData['processInstanceId'] =
detailMap.processInstanceId;
this.childrenData['businessNumber'] = detailMap.businessNumber;
// window上注册 taskData 全局属性,主要表单内部使用
// this.$store.dispatch('setTaskData', this.childrenData)
window.taskData = this.childrenData;
if (result) {
const _data = this.handleResultHtml(
detailMap['result'],
'template'
);
this.formData = JSON.parse(_data) || {};
this.handleModels(
this.handleResultHtml(detailMap['result'], 'values')
);
}
}
} else {
this.$message({
type: 'warning',
message: res.message || '获取表单数据失败,请重试'
});
}
})
.catch(err => {
this.isLoading = false;
this.$message({
type: 'error',
message: err.message || '获取表单数据错误,服务连接错误'
});
});
},
// 绑定的models处理
handleModels(values) {
// console.log('handleModels:', values)
const obj = {};
// 表单数据处理,返回数据处理Array models
const models = transformFormData(this.formData);
// 主要处理JSON
Object.keys(values).forEach(key => {
// console.log(key, values[key])
if (models.indexOf(key) >= 0 && values[key] !== null) {
try {
obj[key] = JSON.parse(values[key]);
} catch {
obj[key] = values[key];
}
} else {
obj[key] = values[key];
}
});
this.values = obj;
// window上注册 formData 表单数据 全局属性
window.formData = this.values;
},
/**
* 统一处理data里的返回的错误
* 比如:data: [{status: 1, messaget: ''}]
*/
handleDataReturnErr(data, message) {
if (Array.isArray(data)) {
if (data[0].status === 0) {
notification('success', message);
// 刷新
this.refresh();
} else {
notification('warning', data[0].message);
}
} else {
notification('success', message);
}
},
// 头部按钮点击操作
handleMethod(item, index) {
this.childrenData.api = item.api;
switch (item.name) {
// 有一些操作不需要验证表单
case 'guidance':
this.openGuide(item.api);
break;
case 'save':
this.saveForm(item.api);
break;
case 'sign':
this.signTask(item.api);
break;
case 'forceSign':
this.forceSignTask(item.api);
break;
case 'finish':
this.finishTask(item.api);
break;
case 'refund':
this.refundTask(item.api);
break;
case 'urge':
this.remindTask(item.api);
break;
case 'turn':
this.transformTask(item.api);
break;
case 'unsign':
this.unclaimTask(item.api);
break;
case 'apply':
case 'suspend':
this.suspendTask(item.api, item.name);
break;
case 'activeSuspend':
this.activeSuspend(item.api);
break;
case 'withdraw':
this.withdrawTask(item.api);
break;
case 'rerun':
this.retrunTask(item.api);
break;
case 'getdraw':
this.checkTransfer();
break;
case 'isSendBack':
this.submitBackForm(item.api);
break;
case 'submit':
// this.submitForm(item.api)
this.handleValidate().then(valid => {
if (valid) this.submitForm(item.api);
});
break;
}
// console.log(this.$refs['generateForm'].getData())
},
/**
* 表单验证处理
*/
handleValidate() {
return new Promise((resolve, reject) => {
this.$refs['generateForm']
.validate()
.then(valid => {
if (valid) {
resolve(valid);
} else {
notification('warning', '表单未填写完整,请验证后再操作');
// reject(new Error('表单验证错误'))
}
})
.catch(err => {
notification('error', '表单未填写完整,请验证后再操作');
reject(err);
});
});
},
/**
* 处理表单数据,提交
*/
handleFormData() {
const formData = this.$refs['generateForm'].getData();
const fomrDataSub = new FormData();
Object.keys(formData).map(key => {
let value = formData[key];
// 转JSON字符串提交
if (typeof formData[key] === 'object' && formData[key] !== null) {
value = JSON.stringify(formData[key]);
}
fomrDataSub.append(key, value);
});
return fomrDataSub;
},
// 办理指南
openGuide(apiUrl) {
this.guideDialogVisible = true;
},
// 保存表单操作
saveForm(apiUrl) {
const fomrDataSub = this.handleFormData();
const taskId = getTaskId() || this.childrenData.taskId;
this.isLoading = true;
Api.doPostPromiseForm(apiUrl + '/' + taskId, fomrDataSub)
.then(res => {
this.isLoading = false;
// console.log(res)
if (res.status === 0) {
notification('success', '保存成功!');
} else {
notification('warning', res.message || '保存失败,请重试!');
}
})
.catch(err => {
this.isLoading = false;
notification('error', err.message || '保存失败,请重试!');
});
},
// 提示表单操作
submitForm(apiUrl) {
const fomrDataSub = this.handleFormData();
this.isLoading = true;
// 先检查是否需要弹窗选择下一处理人
Api.checkAndSubmitTaskByFormData(
getTaskId() || this.childrenData.taskId,
fomrDataSub
)
.then(res => {
this.isLoading = false;
if (res.status === 0) {
const data = res.data;
if (data.submitStatus === 1) {
// 需要选择处理人,弹窗处理
this.submitData.subTask = data.subTask;
this.submitData.userInfos = data.userInfos;
this.submitTaskDialogVisible = true;
} else {
// 关闭和刷新标签页
setTimeout(() => {
refreshTab();
closeTab();
outerNotice({
type: 'success',
title: '提交成功',
message: res.message
});
}, 150);
}
} else {
notification('warning', res.message || '提交失败!');
}
})
.catch(err => {
this.isLoading = false;
notification('error', err.message || '提交错误');
});
},
// 提交弹窗保存操作提交下一环节及处理人
handleSubmitTaskSave(data) {
Api.doPostPromise(this.childrenData.api, {
taskId: this.childrenData.taskId,
submitData: data
})
.then(res => {
if (this.$refs['submitTask']) {
this.$refs['submitTask'].$data.isSubmiting = false;
}
if (res.status === 0) {
this.submitTaskDialogVisible = false;
// 关闭标签
setTimeout(() => {
refreshTab();
closeTab();
outerNotice({
type: 'success',
title: '提交成功',
message: res.message
});
}, 150);
} else {
notification('warning', res.message || '提交失败!');
}
})
.catch(err => {
if (this.$refs['submitTask']) {
this.$refs['submitTask'].$data.isSubmiting = false;
}
notification('error', err.message || '提交错误');
});
},
// 提交返回操作
submitBackForm(apiUrl) {
notification('error', '功能暂时未开发');
},
// 接办
signTask(apiUrl) {
// console.log(apiUrl)
const submitData = [
{
taskId: getTaskId(),
jid: this.childrenData.businessNumber
}
];
this.isLoading = true;
this.isReRender = false;
Api.doPostPromiseJson(apiUrl, submitData)
.then(res => {
this.isLoading = false;
this.isReRender = true;
// console.log('signTasks', res)
if (res.status === 0) {
this.handleDataReturnErr(res.data, '接办成功');
// 刷新
this.refresh();
} else {
notification('warning', res.message || '接办失败,请重试');
}
})
.catch(err => {
this.isLoading = false;
this.isReRender = true;
notification('error', err.message || '接办失败!');
});
},
// 撤办
unclaimTask(apiUrl) {
const submitData = [
{
taskId: getTaskId(),
jid: this.childrenData.businessNumber
}
];
this.isLoading = true;
Api.doPostPromiseJson(apiUrl, submitData)
.then(res => {
this.isLoading = false;
// console.log('receiveTasks', res)
if (res.status === 0) {
this.handleDataReturnErr(res.data, '撤办成功');
} else {
notification('warning', res.message || '撤办失败,请重试');
}
})
.catch(err => {
this.isLoading = false;
notification('error', err.message || '撤办失败!');
});
},
// 强制接办
forceSignTask(apiUrl) {
notification('error', '功能暂时未开发');
},
// 结档
finishTask(apiUrl) {
notification('error', '功能暂时未开发');
},
// 退件
refundTask(apiUrl) {
this.$prompt('请输入退件原因', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValidator: function(value) {
if (!value) return false;
return true;
},
inputErrorMessage: '原因不能空!'
}).then(({ value }) => {
const submitData = [
{
taskId: getTaskId(),
refundReason: value,
jid: this.childrenData.businessNumber
}
];
this.isLoading = true;
Api.doPostPromiseJson(apiUrl, submitData)
.then(res => {
this.isLoading = false;
// console.log('receiveTasks', res)
if (res.status === 0) {
this.handleDataReturnErr(res.data, '退件成功');
} else {
notification('warning', res.message || '退件失败,请重试');
}
})
.catch(err => {
this.isLoading = false;
notification('error', err.message || '退件失败!');
});
});
},
// 催办
remindTask(apiUrl) {
this.$prompt('请输入催办信息', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValidator: function(value) {
if (!value) return false;
return true;
},
inputErrorMessage: '信息不能空!'
}).then(({ value }) => {
const submitData = [
{
taskId: getTaskId(),
message: value,
jid: this.childrenData.businessNumber
}
];
this.isLoading = true;
Api.doPostPromiseJson(apiUrl, submitData)
.then(res => {
this.isLoading = false;
// console.log('receiveTasks', res)
if (res.status === 0) {
this.handleDataReturnErr(res.data, '催办成功');
} else {
notification('warning', res.message || '催办失败,请重试');
}
})
.catch(err => {
notification('error', err.message || '催办失败!');
});
});
},
// 转办
transformTask(apiUrl) {
this.transformDialogVisible = true;
},
// 转办成功
handleTransformTaskSave(res) {
this.transformDialogVisible = false;
// 关闭和刷新
refreshTab();
closeTab();
// 外部提示通知
outerNotice({
type: 'success',
title: '转办成功',
message: res.message
});
},
// 申请挂起、挂起
suspendTask(apiUrl, type) {
const text = type === 'apply' ? '申请挂起' : '挂起';
this.$prompt(`请输入${text}原因`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValidator: function(value) {
if (!value) return false;
return true;
},
inputErrorMessage: '原因不能空!'
}).then(({ value }) => {
const submitData = [
{
taskId: getTaskId(),
suspendReason: value
}
];
this.isLoading = true;
Api.doPostPromiseJson(apiUrl, submitData)
.then(res => {
this.isLoading = false;
// console.log('receiveTasks', res)
if (res.status === 0) {
this.handleDataReturnErr(res.data, `${text}成功'`);
} else {
notification('warning', res.message || `${text}失败,请重试`);
}
})
.catch(err => {
this.isLoading = false;
notification('error', err.message || `${text}失败!`);
});
});
},
// 解除挂起
activeSuspend(apiUrl) {
const submitData = [
{
taskId: getTaskId()
}
];
this.isLoading = true;
Api.doPostPromiseJson(apiUrl, submitData)
.then(res => {
this.isLoading = false;
// console.log('receiveTasks', res)
if (res.status === 0) {
this.handleDataReturnErr(res.data, '解除挂起成功');
} else {
notification('warning', res.message || '解除挂起失败,请重试');
}
})
.catch(err => {
this.isLoading = false;
notification('error', err.message || '解除挂起失败!');
});
},
// 收回
withdrawTask(apiUrl) {
const submitData = [
{
processDefinitionId: this.childrenData.processDefinitionId,
processInstanceId: this.childrenData.processInstanceId,
// taskId: getTaskId(),
linkDefinitionKey: this.childrenData.linkKey
}
];
this.isLoading = true;
Api.doPostPromiseJson(apiUrl, submitData)
.then(res => {
this.isLoading = false;
// console.log('receiveTasks', res)
if (res.status === 0) {
this.handleDataReturnErr(res.data, '收回成功');
} else {
notification('warning', res.message || '收回失败,请重试');
}
})
.catch(err => {
this.isLoading = false;
notification('error', err.message || '收回失败!');
});
},
// 退回
retrunTask(apiUrl) {
this.returnTaskVisible = true;
},
// 退回成功操作提交
handleReturnTaskDone() {
this.returnTaskVisible = false;
// 刷新
this.refresh();
},
// 查看流转
checkTransfer() {
const component = {
id:
this.childrenData.taskId + '_' + this.childrenData.processInstanceId,
name: '查看流程窗口',
componentName: 'checkProcess'
};
const param = {
processInstanceId: this.childrenData.processInstanceId
};
openTab(component, param);
},
// 自定义按钮点击
handleCustomBtn(item) {
// console.log(item)
if (item.operation) {
/* eslint-disable no-eval */
eval(item.operation);
}
}
}
};
</script>
<template>
<div class="page-view">
<div v-if="loadError" style="margin-top: 60px; text-align: center;">
<i class="el-icon-warning" style="color: red"></i> 配置页获取失败
</div>
<template v-if="isLoading">
<div class="app-loading" v-loading="isLoading" element-loading-text="加载处理中..."></div>
</template>
<smart-page :data="templateData" :page-info="pageInfo"></smart-page>
</div>
</template>
<script>
/**
* 渲染快速功能配置页
* smart-page
*/
import { getQueryString } from '@form/utils/form';
import config from '@form/api/config';
export default {
name: 'PageView',
props: {
id: String
},
data() {
return {
isLoading: true,
loadError: false,
templateData: null,
pageInfo: null
};
},
mounted() {
if (!this.id) return;
this.getTemplate();
this.getAuthories();
},
methods: {
getTemplate() {
this.isLoading = true;
config.doGetPromise('/v1.1.0/report/searchTemplate', { rid: this.id }).then(res => {
this.isLoading = false;
if (res.status === 0) {
const data = res.data.reportInfo;
this.templateData = JSON.parse(data.templatejson);
delete data.templatejson;
this.pageInfo = { ...this.pageInfo, ...data };
} else {
this.$message.warning(res.message || '获取页面模板数据有误!');
this.loadError = true;
}
}).catch(err => {
this.$message.error(err.message || '获取页面模板数据有误!');
this.isLoading = false;
this.loadError = true;
});
},
// 获取模块权限,赋值到pageInfo
getAuthories() {
const systemInfo = window.$ ? window.$.system.getSystemInfo() : null;
const systemId = systemInfo ? systemInfo.systemId : '';
const moduleId = getQueryString('moduleId');
config.doGetPromise('/authorityManage/queryUserSysAuthorizeInfoList', {
systemId,
moduleId
}).then(res => {
if (res.status === 0) {
if (!this.pageInfo) this.pageInfo = {};
this.pageInfo.authorities = res.data.sysAuthorizeList;
} else {
this.$message.warning(res.message || '获取权限异常!');
}
});
}
}
};
</script>
{
"name": "smart-web-router",
"description": "{{description}}",
"version": "1.0.0",
"author": "zengyl@southzn.com",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"core-js": "^2.6.5",
"smart-web": "^2.2.1",
"vue": "^2.6.10",
"vue-router": "^3.1.3"
},
"devDependencies": {
"@smart/eslint-config-standard": "^0.1.0",
"@vue/cli-plugin-babel": "^3.10.0",
"@vue/cli-plugin-eslint": "^3.10.0",
"@vue/cli-plugin-unit-mocha": "^3.10.0",
"@vue/cli-service": "^3.10.0",
"@vue/test-utils": "1.0.0-beta.29",
"babel-eslint": "^10.0.1",
"chai": "^4.1.2",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.0",
"vue-template-compiler": "^2.6.10"
}
}
module.exports = {
plugins: {
autoprefixer: {}
}
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>smart web router sample.</title>
</head>
<body>
<noscript>
<strong>We're sorry but smart-web-router doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<vue-progress-bar></vue-progress-bar>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
};
</script>
import Vue from 'vue';
import axios from 'axios';
import qs from 'qs';
import store from '../store';
import * as _config from '@config/http.config';
import { Message } from 'element-ui';
// 携带cookie信息
axios.defaults.withCredentials = true;
// 设置全局的请求次数,请求的间隙
axios.defaults.retry = 1;
axios.defaults.retryDelay = 1000;
// 设置defaults.baseURL
axios.defaults.baseURL = _config.baseUrl;
// 请求超时拦截,重新请求
axios.interceptors.response.use(function(response) {
const status = response.status;
// const data = response.data;
if (status !== 200) {
Message({
type: 'error',
message: '请求服务好像出错了,' + status
});
return Promise.reject(response);
}/* else if (data.status === 2) {
Message({
type: 'error',
message: '请求服务后台处理出现了错误'
});
} else if (data.status === 1) {
Message({
type: 'warning',
message: '请求服务处理出现了异常,' + data.message
});
} */
return Promise.resolve(response);
}, function axiosRetryInterceptor(err) {
const config = err.config;
// If config does not exist or the retry option is not set, reject
if (!config || !config.retry) return Promise.reject(err);
// Set the variable for keeping track of the retry count
config.__retryCount = config.__retryCount || 0;
// Check if we've maxed out the total number of retries
if (config.__retryCount >= config.retry) {
const status = err.response.status;
Message({
type: 'error',
message: `请求服务好像出错了,状态码:${status}`
});
// Reject with the error
return Promise.reject(err);
}
// Increase the retry count
config.__retryCount += 1;
// Create new promise to handle exponential backoff
const backoff = new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, config.retryDelay || 1);
});
// Return the promise in which recalls axios to retry the request
return backoff.then(function() {
return axios(config);
});
});
const CancelToken = axios.CancelToken;
let cancel;
const config = {
/**
* get获取数据,通用方法
* @param {String} url
* @param {Object} params
* @param {Object} options
*/
doGetPromise(url, params, options = {}) {
const { timeout = 30000, ...arg } = options;
return new Promise((resolve, reject) => {
axios.get(url, {
timeout: timeout,
...arg,
params: {
systemId: store.state.platformInfo.systemId, // 全面接口添加systemId字段
...params,
t: new Date().getTime() // 解决IE上get请求缓存问题
},
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).then(response => {
resolve(response.data);
}).catch(response => {
// console.error('ajax error:', response)
reject(response);
});
});
},
/**
* FormData数据上传,文件上传必用
* @param {String} url
* @param {FormData} formData
*/
doPostPromiseForm(url, formData) {
return new Promise((resolve, reject) => {
// 全面接口添加systemId字段
if (formData.has) { // ie FormData没有has方法
if (formData.has('systemId')) formData.append('systemId', store.state.platformInfo.systemId);
}
axios.post(url, formData, {
headers: {
'Content-type': 'multipart/form-data'
},
emulateJSON: false,
emulateHTTP: false,
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).then(res => {
resolve(res.data);
}).catch(res => {
console.log('post error:', res);
reject(res);
});
});
},
/**
* 默认方式提交from表单数据
* @param {String} url
* @param {Object} data
*/
doPostPromise(url, data) {
return new Promise((resolve, reject) => {
// 全面接口添加systemId字段
if (!data.hasOwnProperty('systemId')) data.systemId = store.state.platformInfo.systemId;
axios.post(url, qs.stringify(data), {
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).then(res => {
resolve(res.data);
}).catch(res => {
// console.log('post error:', res)
reject(res);
});
});
},
/**
* 默认方式提交json数据
* @param {String} url
* @param {Object} data
*/
doPostPromiseJson(url, data) {
return new Promise((resolve, reject) => {
// 全面接口添加systemId字段
if (!data.hasOwnProperty('systemId')) data.systemId = store.state.platformInfo.systemId;
axios.post(url, data, {
headers: {
'Content-type': 'application/json'
},
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).then(res => {
resolve(res.data);
}).catch(res => {
console.log('post error:', res);
reject(res);
});
});
}
};
// 切换页面强行中断请求 router.beforeEach中用到
Vue.prototype.$cancelAjax = function(msg) {
if (cancel) {
cancel(msg || '手动中断请求');
}
};
export default config;
import config from './config';
const Api = {
/**
* 获取系统信息
* @param {String} sysCode 系统code
*/
getSystemInfo(sysCode) {
return config.doGetPromise('/index/getSystemCfgBeforeLogin', {sysCode});
},
login(data) {
return config.doPostPromise('/index/login', data);
},
checkLogin() {
return config.doGetPromise('/index/checkLogin', {}, { retry: 0 });
},
logout() {
return config.doGetPromise('/index/logout', {});
},
getAdminDivisionTree() {
return config.doGetPromise('/administrativeDivisions/getAdministrativeDivisionTree');
},
/**
* 获取用户权限下的系统模块功能
* @param {String} systemId 子系统Id
* @param {type} 类型:0-菜单,1-功能点
*/
getUserModulesTreeBySystemId(systemId, type = 0) {
return config.doGetPromise('/systemModule/getUserModulesTree', {
systemId,
type
});
},
/**
* 获取系统模块功能
* @param {String} id 子系统Id
* @param {Number(0,1)} 类型:0-菜单,1-功能点,默认是0
*/
getSystemAllModules(id, type = 0) {
return config.doGetPromise('/systemModule/getSystemAllModulesTree', {
systemId: id,
type
});
},
/**
* 获取组织结构的树状信息
* @param {Number} type 类型,1:只返回部门岗位信息; 2:返回部门岗位与人员信息; 3:返回角色信息; 4:返回部门(无岗位);5:返回人员;其他:返回所有组织项信息
* @param {Number} valid 是否可用, -1:审核中 1:可用(第一次登录,需要修改密码) 2:可用(非第一次登录,不需要修改密码)
*/
getOrganTree(type, valid) {
return config.doGetPromise('/organization/manager/getOrganTree', {
type: type,
valid: valid
});
},
// 获取代码字典
getChildItemByRootCode(data) {
return config.doGetPromise('/codeDict/getChildItemByRootCode', data);
},
/**
* 获取用户拥有的业务
* @param {String} userId
*/
getBusinessTree(userId) {
return config.doGetPromise('/business/system/businessDefTreeByUserId', {
userId: userId
});
},
/**
* 获取个人配置
* @param {String} type 配置信息类型;其中1:个人配置 ,2:业务配置,3:功能配置,4:主题配置
*/
getUserConfigTheme(type = 4) {
return config.doGetPromise('/personalConfigure/listAllInfo', {
infoType: type
});
},
/**
* 根据模块查询用户的权限
*/
getUserAuthories(moduleId) {
return config.doGetPromise('/authorityManage/queryUserSysAuthorizeInfoList', {
moduleId
});
}
};
export default Api;
import axios from 'axios';
import store from '@/store';
import router from '@/router';
import MessageBox from 'element-ui/lib/message-box';
/* const filters = ['webgisService']
const handleFilter = (key) => {
if (Array.isArray(filters)) {
filters.map(item => {
if (item === key) {}
})
}
} */
/**
* 登录判断失效
* 在所有经过axios请求中,拦截到登录失效
*
* @param {Object} response
*/
let isOtherLogin = false;
function loginInterceptor(response) {
// 9: 此账号在其他地方登陆
// 8: 账号登录已经失效
if (response.data && response.data.status === 8) {
if (!isOtherLogin) {
store.dispatch('setUserInfo', {});
router.replace({
name: 'Login',
query: router.currentRoute.query
});
isOtherLogin = false;
// response.data = null
}
return response;
} else if (response.data && response.data.status === 9) {
if (!isOtherLogin) {
isOtherLogin = true;
store.dispatch('setUserInfo', {});
MessageBox.alert('该账号在别的地方登录了,请重新登录', '提示', {
type: 'warning',
confirmButtonText: '登录',
callback: action => {
isOtherLogin = false;
if (action === 'confirm') {
router.replace({
name: 'Login',
query: router.currentRoute.query
});
}
}
});
}
return response;
} else {
return response;
}
}
axios.interceptors.response.use(loginInterceptor);
<template>
<div class="errorPage">
<p class="num">404</p>
<div class="des">
<h4>您的页面或组件找不到!</h4>
<p>1. 您的路由设置不正确</p>
<p>2. 您的组件未注册</p>
</div>
</div>
</template>
<template>
<div class="errorPage">
<p class="num">403</p>
<div class="des">
<h4>您的系统查找不到或无访问权限!!!</h4>
<h4>请检查您的系统代码或ID是否正确</h4>
</div>
</div>
</template>
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store';
import ElemetUI from 'element-ui';
import SmartWeb from 'smart-web';
import VueProgressBar from 'vue-progressbar';
import './styles/app.scss';
// import 'smart-web/packages/styles/lib/index.css';
import './plugins/expression';
import './utils/window';
import './api/loginInterceptor';
Vue.config.productionTip = false;
Vue.use(ElemetUI, { size: 'medium', zIndex: 4000 });
Vue.use(SmartWeb, {
baseUrl: process.env.VUE_APP_BASEURL,
systemId: '00000000-0000-0015-0001-000000000001'
});
const vPopts = {
color: '#3fe4be',
failedColor: '#874b4b',
thickness: '2px',
transition: {
speed: '0.1s',
opacity: '0.3s',
termination: 300
},
autoRevert: true,
location: 'top',
inverse: false,
autoFinish: true
};
Vue.use(VueProgressBar, vPopts);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: {
App
},
template: '<App/>'
});
import menu from './modules/menu';
import system from './modules/system';
/**
* 全局平台表达式
* @example
* $.menu.xxx()
* $.system.xxx()
* $.form.xxx() // 扩展表单, 表单页面调用才有效
*/
const SWE = {
menu,
system
};
window.$ = SWE;
export default SWE;
import store from '@/store';
import router from '@/router';
/**
* 菜单表达式函数
* 操作标签页
*/
export default {
/**
* 全局打开新标签页方法
* 利用的是store, id作为唯一性检查,没有id就会自动生成id
* @param {Object} data 组件的对象,比如 {id:'', name:'组织构架管理', componentName:'frameworkManage'}
* @param {Any} param 绑定到数据里的param
*/
openTab(data, param) {
console.log(data);
const componentName = data.componentName || data.router;
// 判断是否为http开头的外链
if (componentName.indexOf('http') === 0) {
router.push({
name: 'appIframe',
params: {
url: componentName
}
});
return;
}
// 菜单模块ID赋值,权限通过模块ID获取的
if (!data.moduleId) {
const menuList = store.getters['menu/menuList'];
if (menuList.length > 0) {
let menu;
const fn = (data) => {
const len = data.length;
for (let i = 0; i < len; i++) {
// console.log(data[i].router, componentName)
if (data[i].router === componentName) {
menu = data[i];
break;
} else {
if (data[i].children && data[i].children.length > 0) {
fn(data[i].children);
}
}
}
};
fn(menuList);
// 模块id赋值
if (menu) data.moduleId = menu.moduleId;
}
}
data.componentName = componentName;
data.param = param || {};
router.push({
name: data.componentName,
params: {
moduleId: data.moduleId,
...param
}
});
},
/**
* 打开一个外部链接的标签
* @param {String} name 标签名称
* @param {String} url 外部URL
* @param {Boolean|String} only 布尔值为true时,是固定使用externalLinkTab---1打开页面,当是string字符串时,自定义打开固定标签页
*/
openExternalLinkTab(name, url, only) {
/* const id = (typeof only === 'boolean' && only)
? 'externalLinkTab---1'
: (typeof only === 'string' && only)
? only : ''; */
router.push({
name: 'appIframe',
params: {
name,
url: url
}
});
}
};
import store from '@/store';
import { Notification } from 'element-ui';
/**
* 系统表达式函数
* 获取系统,用户, 全局通知等信息
*/
export default {
/**
* 获取用户信息
* @returns {Object | null}
*/
getUser() {
return store.state.userInfo || null;
},
/**
* 获取用户身份
* @returns {String}
*/
getUserName() {
return store.state.userInfo ? store.state.userInfo.RealName : '';
},
/**
* 获取系统信息
* @returns {Object}
*/
getSystemInfo() {
return store.state.platformInfo || null;
},
/**
* 获取用户身份
* @returns {String} admin | none
*/
getUserIdentity() {
return store.state.userIdentity || '';
},
/**
* 公共提示方法,一般用于组件内保存提交时提示
* @param {object} options 和element-ui Notification组件属性一样
* 例如:object = {type: 'success', title: '操作成功', message: '页面保存成功'}
*/
notification(options) {
const {
customClass = 'custom-notification',
position = 'bottom-right',
...opts
} = options;
const _opts = {
customClass,
position,
...opts
};
Notification(_opts);
}
};
### WEB平台前端表达式
```js
window.$ = {expression}
```
`$` 是 Smart Web Expression 的缩写
> 主要使用于表单工作流上设计,也可以用于某些组件内,但不建议,建议还是使用模块化引用开发
> 绑定在`window`全局上
\ No newline at end of file
import Vue from 'vue';
import Router from 'vue-router';
import routes from './routes';
import { removeLoading, getSystemInfo } from '../utils/global';
import Api from '../api';
import store from '../store';
const vm = new Vue();
Vue.use(Router);
const router = new Router({
// mode: 'history',
routes
});
function nextLogin(query) {
router.replace({
name: 'Login',
query: query
});
}
function filterRouteLogin(route) {
return ['Login', 'LoginDialog'].indexOf(route.name) >= 0;
}
function checkLogin(next) {
// 检查登录
Api.checkLogin().then(res => {
if (res.status === 0) {
const data = res.data;
// vuex store
const userState = {
...data.loginInfo,
userId: data.userId
};
// 设置vuex userInfo
store.dispatch('setUserInfo', userState);
next();
} else {
store.dispatch('setUserInfo', {});
nextLogin();
}
}).catch(() => {
store.dispatch('setUserInfo', {});
nextLogin();
});
}
router.beforeEach((to, from, next) => {
if (vm.$Progress) {
if (to.meta.progress !== undefined) {
const meta = to.meta.progress;
// parse meta tags
vm.$Progress.parseMeta(meta);
}
vm.$Progress.start();
}
if (to.name === '404' || to.name === 'Unfound') {
removeLoading();
next();
return;
}
if (filterRouteLogin(to)) {
next();
return;
}
if (store.state.platformInfo &&
store.state.platformInfo.systemId &&
to.query.sysCode === from.query.sysCode) {
checkLogin(next);
} else {
const sysCode = to.query.sysCode;
getSystemInfo(sysCode).then(_ => {
checkLogin(next);
}).catch(err => {
if (err.status === 1 || err.status === 2) {
// 获取系统信息错误
router.replace({
name: 'Unfound',
query: {
sysCode
}
});
} else {
router.replace({
name: 'Login',
query: {
sysCode
}
});
}
});
}
});
router.afterEach(() => {
vm.$Progress && vm.$Progress.finish();
});
export default router;
import Main from '@/views/Main';
import Login from '@/views/login/Login';
import ErrorPage from '@/components/404';
import UnfoundSys from '@/components/UnfoundSys';
import store from '@/store';
import Api from '@/api';
import appHome from '@/views/common/appHome';
import appIframe from '@/views/common/AppIframe.vue';
// 处理加载routes文件夹路由注入
let asyncComponents = [];
const files = require.context('./routes', false, /\.js$/);
files.keys().forEach(key => {
asyncComponents = asyncComponents.concat(files(key).default);
});
function checkLogin() {
return new Promise((resolve, reject) => {
Api.checkLogin().then(res => {
if (res.status === 0) {
const data = res.data;
// vuex store
const userState = {
...data.loginInfo,
userId: data.userId
};
// 设置vuex userInfo
store.dispatch('setUserInfo', userState);
// 路由跳转
resolve();
} else {
store.dispatch('setUserInfo', {});
reject(res);
}
}).catch((err) => {
store.dispatch('setUserInfo', {});
reject(err);
});
});
}
export default [
{
path: '/',
name: 'Main',
component: Main,
redirect: '/home',
props: (route) => ({ sysId: route.query.sysId }),
children: [
{
path: 'home',
name: 'Home',
component: appHome
}, {
path: 'appIframe',
name: 'appIframe',
component: appIframe
}, {
path: 'appMessage',
name: 'appMessage',
component: () => import('@/views/common/message')
}, {
path: 'configurePage/:moduleId',
name: 'configurePage',
component: () => import('@/views/common/ConfigurePage.vue')
},
...asyncComponents
]
}, {
path: '/login',
name: 'Login',
component: Login,
meta: {
igonreLogin: true
},
beforeEnter: (to, from, next) => {
checkLogin().then(_ => {
next({
name: 'Main',
query: to.query
});
}).catch(_ => {
next();
});
}
}, {
path: '/unfound',
name: 'Unfound',
component: UnfoundSys
}, {
path: '*',
name: '404',
component: ErrorPage
}
];
export default [
{
path: 'businessConfiguration',
name: 'businessConfiguration',
component: () => import('@/views/businessConfig/businessConfiguration'),
}
];
export default [
{
path: 'mapConfig',
name: 'mapConfig',
component: () => import('@/views/mapConfig/mapConfig'),
}, {
path: 'layerManage',
name: 'layerManage',
component: () => import('@/views/mapConfig/layerManage'),
}, {
path: 'mapSearchConfig',
name: 'mapSearchConfig',
component: () => import('@/views/mapConfig/mapSearchConfig'),
}, {
path: 'serviceRegister',
name: 'serviceRegister',
component: () => import('@/views/mapConfig/serviceRegister'),
}, {
path: 'catalogManagement',
name: 'catalogManagement',
component: () => import('@/views/mapConfig/catalogManagement'),
}
];
export default [
{
path: 'createWork',
name: 'createWork',
component: () => import('@/views/myWork/createWork'),
}, {
path: 'checkProcess/:processInstanceId',
name: 'checkProcess',
component: () => import('@/views/myWork/checkProcess'),
}, {
path: 'doingWork',
name: 'doingWork',
component: () => import('@/views/myWork/doingWork'),
}, {
path: 'handledWork',
name: 'handledWork',
component: () => import('@/views/myWork/handledWork'),
}, {
path: 'suspendWork',
name: 'suspendWork',
component: () => import('@/views/myWork/suspendWork'),
}, {
path: 'finishedWork',
name: 'finishedWork',
component: () => import('@/views/myWork/finishedWork'),
}, {
path: 'returnBox',
name: 'returnBox',
component: () => import('@/views/myWork/returnBox'),
}, {
path: 'deleteBox',
name: 'deleteBox',
component: () => import('@/views/myWork/deleteBox'),
}, {
path: 'monitorWork',
name: 'monitorWork',
component: () => import('@/views/myWork/monitorWork'),
}, {
path: 'settingColumn/:workType',
name: 'settingColumn',
component: () => import('@/views/myWork/settingColumn'),
}, {
path: 'formRender',
name: 'formRender',
component: () => import('@/views/common/formRender'),
}
];
export default [
{
path: 'interface',
name: 'interface',
component: () => import('@/views/personalConfig/interface'),
}, {
path: 'accountSetting',
name: 'accountSetting',
component: () => import('@/views/personalConfig/accountSetting'),
}
];
export default [
{
path: 'frameworkManage',
name: 'frameworkManage',
component: () => import('@/views/systemSetup/frameworkManage'),
}, {
path: 'childSystemManage',
name: 'childSystemManage',
component: () => import('@/views/systemSetup/childSystemManage'),
}, {
path: 'modulesManage',
name: 'modulesManage',
component: () => import('@/views/systemSetup/modulesManage'),
}, {
path: 'functionModulesManage',
name: 'functionModulesManage',
component: () => import('@/views/systemSetup/functionModulesManage'),
}, {
path: 'authorityManage',
name: 'authorityManage',
component: () => import('@/views/systemSetup/authorityManage'),
}, {
path: 'codeDictionary',
name: 'codeDictionary',
component: () => import('@/views/systemSetup/codeDictionary'),
}, {
path: 'workflowDesign',
name: 'workflowDesign',
component: () => import('@/views/systemSetup/workflowDesign'),
}, {
path: 'editProcess',
name: 'editProcess',
component: () => import('@/views/systemSetup/editProcess'),
}, {
path: 'SNamingManagement',
name: 'SNamingManagement',
component: () => import('@/views/systemSetup/SNamingManagement'),
}, {
path: 'stampdefManage',
name: 'stampdefManage',
component: () => import('@/views/systemSetup/stampdefManage'),
}, {
path: 'myComWord',
name: 'myComWord',
component: () => import('@/views/systemSetup/myComWord'),
}, {
path: 'compInformation',
name: 'compInformation',
component: () => import('@/views/systemSetup/compInformation'),
}, {
path: 'snBuilder',
name: 'snBuilder',
component: () => import('@/views/systemSetup/snBuilder'),
}, {
path: 'operationLog',
name: 'operationLog',
component: () => import('@/views/systemSetup/operationLog'),
}, {
path: 'holidayManagement',
name: 'holidayManagement',
component: () => import('@/views/systemSetup/holidayManagement'),
}, {
path: 'businessDefManager',
name: 'businessDefManager',
component: () => import('@/views/systemSetup/businessDefManager'),
}, {
path: 'checkExpression',
name: 'checkExpression',
component: () => import('@/views/systemSetup/checkExpression'),
}, {
path: 'adminDivision',
name: 'adminDivision',
component: () => import('@/views/systemSetup/adminDivision'),
}, {
path: 'iconView',
name: 'iconView',
component: () => import('@/views/common/iconView'),
}, {
path: 'environmentConfig',
name: 'environmentConfig',
component: () => import('@/views/systemSetup/environmentConfig'),
}, {
path: 'taskScheduling',
name: 'taskScheduling',
component: () => import('@/views/systemSetup/taskScheduling'),
}
];
import Vue from 'vue';
import Vuex from 'vuex';
const packageConfig = require('../../package.json');
Vue.use(Vuex);
const modules = {};
const files = require.context('./modules', false, /\.js$/);
files.keys().forEach(key => {
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default;
});
const store = new Vuex.Store({
namespaced: true,
modules,
state: {
platformInfo: {
moduleId: '#',
systemId: ''/* '00000000-0000-0015-0001-000000000001' */,
name: 'Smart Web 平台',
// name: '国土测绘院政务系统',
disabled: true,
version: packageConfig.version || ''
},
unreadMessage: 0, // 未读消息
userInfo: {
userId: '',
SysId: '',
OrganName: '',
RealName: ''
},
userIdentity: 'none', // 用户身份,admin, none
theme: {
format: 'left-right',
themeColor: 'deep'
}
},
mutations: {
setUserInfo(state, payload) {
state.userInfo = payload;
},
setUserIdentity(state, payload) {
state.userIdentity = payload;
},
setTheme(state, payload) {
state.theme = payload;
},
setUnreadMessage(state, count) {
state.unreadMessage = count;
}
},
actions: {
setUserInfo(context, payload) {
context.commit('setUserInfo', payload);
if (payload && payload.Qua === 99) {
context.commit('setUserIdentity', 'admin');
} else {
context.commit('setUserIdentity', 'none');
}
},
setTheme({ commit }, payload) {
commit('setTheme', payload);
},
setUnreadMessage(context, count) {
context.commit('setUnreadMessage', count);
}
}
});
export default store;
/**
* 菜单存储,菜单权限
*/
export default {
namespaced: true,
state: {
menuList: []
},
getters: {
menuList: state => {
return state.menuList;
}
},
mutations: {
setMenuList(state, payload) {
state.menuList = payload;
}
},
actions: {
setMenuList({ commit }, payload) {
commit('setMenuList', payload);
}
}
};
@import "./common/var";
@import './mixins/mixins';
@import './library';
@import './common/main';
@import './common/other/theme';
%placehodler {
width: 100%;
height: 100%;
}
#app, .app-main {
@extend %placehodler;
}
.app-main {
display: flex;
flex-direction: row;
}
.app-wrapper {
display: flex;
flex-direction: row;
flex: 1 1 0%;
width: 100%;
height: 100%;
}
.app-container {
display: flex;
flex-direction: column;
flex: 1 1 0%;
overflow: hidden;
}
.app_container-main {
position: relative;
display: flex;
flex-direction: column;
flex: 1 1 0%;
overflow: auto;
}
.app-header {
position: relative;
z-index: 9;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0 0.6em;
width: 100%;
height: $--header-height;
// line-height: $--height-header;
color: $--header-color;
background-color: $--header-background-color;
box-shadow: 0 1px 3px rgba($color: $--header-box-shadow-color, $alpha: 0.1);
border-bottom: 1px solid $--header-border-color;
a {
color: $--header-color;
&:hover {
opacity: 0.75;
}
}
.app-header--left {
display: flex;
align-items: center;
}
.app-header--right {
// margin-left: 2em;
flex: 1 1 auto;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.app-header--function {
display: inline-block;
padding: 0 20px;
margin-right: 20px;
// border-right: 1px solid rgba($color: $--header-background-color, $alpha: 0.5);
& > * {
margin-left: 20px;
}
}
}
.app-header__userinfo {
// margin-left: 1em;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
.gutter {
margin: 0 0.6em;
}
.message {
position: relative;
display: inline-block;
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
&:hover {
background-color: mix($--color-black, $--header-background-color, 10%);
}
.iconfont {
font-size: $--font-size-large;
}
.tips {
position: absolute;
right: 2px;
top: 2px;
width: 10px;
height: 10px;
text-indent: -999px;
background-color: $--color-danger;
border: 1px solid mix($--color-white, $--color-danger, 20%);
border-radius: 10px;
color: $--color-white;
font-size: $--font-size-mini;
overflow: hidden;
}
}
.user-name {
& > i {
margin-right: 4px;
}
span {
font-size: $--header-font-size;
font-weight: 600;
}
&:hover {
opacity: .75;
}
}
.quit-user {
&:hover {
opacity: .75;
}
}
}
.app-logo {
display: flex;
align-items: center;
height: $--header-height;
color: $--color-white;
background-color: $--color-primary;
.menu {
display: flex;
width: $--header-height;
height: $--header-height;
align-items: center;
justify-content: center;
}
.img {
width: 28px;
height: 28px;
display: inline-block;
vertical-align: middle;
background-image: url('../assets/img/logo-white.png');
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
}
.app-title {
display: inline-block;
margin-left: 4px;
font-size: 20px;
font-weight: 500;
}
.app-navigation {
display: flex;
flex-direction: column;
position: relative;
width: 240px;
height: 100%;
background-color: $--nav-background-color-light;
transition: width .3s ease-in-out;
::-webkit-scrollbar {
width: 4px;
}
::-webkit-scrollbar-track-piece {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: mix($--color-black, $--nav-background-color-light, 15%);
border-radius: 6px;
}
&.is-collapse {
width: 64px;
.app-logo {
justify-content: center;
}
.app-title {
display: none;
}
}
.app-navigation--menu {
flex: 1 1 auto;
border-right: 0 none;
background-color: $--nav-background-color-light;
overflow: auto;
.el-menu {
background-color: $--color-white;
}
.el-menu-item, .el-submenu__title {
color: $--nav-font-color;
}
.el-menu-item:hover, .el-menu-item:focus, .el-submenu__title:hover {
background-color: $--color-primary-light-8;
}
}
/* .el-menu {
border-right: 0 none;
background-color: $--nav-background-color;
} */
.navigation-controll {
position: absolute;
z-index: 2999;
top: 50%;
right: -14px;
transform: translateY(-30px);
width: 14px;
height: 60px;
line-height: 60px;
text-align: center;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
background-color: $--nav-background-color-light;
cursor: pointer;
.iconfont {
font-size: $--font-size-mini;
}
}
}
.el-menu--collapse .el-menu-item span,
.el-menu--collapse .el-submenu > .el-submenu__title span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
.el-menu--collapse .el-menu-item .el-submenu__icon-arrow,
.el-menu--collapse .el-submenu > .el-submenu__title .el-submenu__icon-arrow {
display: none;
}
.el-menu .iconfont {
font-size: $--font-size-large;
}
/* breadcrumb css */
.el-breadcrumb__inner.is-link:hover {
cursor: pointer;
}
/* breadcrumb css end */
/* login css */
.login__wrapper {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
// background-image: linear-gradient(180deg, hsla(0, 0%, 100%, 0) 60%, #232a38),
// linear-gradient(70deg, #303b41 32%, #333d52);
// background-image: linear-gradient(180deg, hsla(0, 0%, 100%, 0) 60%, #223a86),
// linear-gradient(70deg, #4e89e2 32%, #9ee6c2);
// background-color: #333d52;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -2;
background: url('../assets/img/login_bg.jpg') center center no-repeat;
background-size: cover;
filter: blur(8px);
}
&::after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
background-image: linear-gradient(180deg, hsla(0, 0%, 100%, 0) 60%, #768edb),
linear-gradient(70deg, #55667e 32%, #5ca397);
background-color: #333d52;
opacity: 0.35;
}
.login-form {
width: 450px;
}
.login-logo {
position: absolute;
top: 1rem;
left: 1rem;
color: #ffffff;
}
.login-logo__icon {
display: inline-block;
width: 40px;
height: 40px;
margin-right: 0.2rem;
background: url('../assets/img/logo-white.png') no-repeat;
background-size: contain;
vertical-align: middle;
}
.login-logo__title {
font-size: 28px;
vertical-align: middle;
}
}
.login-form {
width: 400px;
.login-form__close {
float: right;
color: $--color-info;
font-size: 16px;
cursor: pointer;
&:hover {
color: $--color-primary;
}
}
.submitBtn {
width: 100px;
}
}
.login-dialog__wrapper {
/* position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%; */
.el-dialog__header, .el-dialog__body {
padding: 0;
}
}
/* login css end */
/* loading spinner custom */
.loading-spinner {
display: block;
text-align: center;
}
.loading-spinner .el-icon-loading {
font-size: 20px;
}
.loading-spinner .circular {
height: 42px;
width: 42px;
animation: loading-rotate 2s linear infinite;
}
.loading-spinner .path {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: $--color-primary;
stroke-linecap: round;
}
.loading-spinner .text {
margin-top: 4px;
font-size: $--font-size-small;
}
@keyframes loading-rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes loading-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -40px;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -120px;
}
}
/* loading spinner custom end */
@import './var';
@import '../mixins/mixins';
@import './other/reset';
@import '../component/index';
/* error page css */
.errorPage {
width: 100%;
height: 100%;
padding-top: 20vh;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
background-image: linear-gradient(180deg, hsla(0, 0%, 100%, 0) 60%, #ffffff),
linear-gradient(60deg,#f0f8f6 32%,#f6f7ef);
.num {
font-size: 8rem;
color: $--color-primary;
font-family: 'Courier New', Courier, monospace;
}
.des {
text-align: left;
p {
font-size: $--font-size-small;
color: $--color-info;
}
h4 {
color: inherit;
font-weight: 500;
margin-bottom: 4px;
}
}
}
/* error page css end */
\ No newline at end of file
@import '../var.scss';
blockquote,body,button,dd,dl,dt,fieldset,form,h1,h2,h3,h4,h5,h6,hr,html,iframe,input,legend,li,ol,p,pre,td,textarea,th,ul{
margin:0;
padding:0;
}
html, body {
width: 100%;
height: 100%;
}
body {
min-width: 1200px;
min-height: 540px;
font-size: 1rem;
font-family: -apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif;
color: $--color-text-regular;
overflow: auto;
}
input, textarea {
font-family: -apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif;
}
iframe {
width: 100%;
height: 100%;
border: 0;
outline: none;
}
a {
color: $--color-primary;
text-decoration: none;
}
ul, ol, li {
list-style: none;
}
* {
scrollbar-base-color: #cecece;
scrollbar-3dlight-color: #eee;
scrollbar-highlight-color: #eee;
scrollbar-track-color: #f1f1f1;
scrollbar-arrow-color: #000;
scrollbar-shadow-color: #eee;
// scrollbar-dark-shadow-color: #eee;
box-sizing: border-box;
}
*::-webkit-scrollbar {
width: 6px;
height: 10px;
}
*::-webkit-scrollbar-button {
display: none;
}
*::-webkit-scrollbar-track-piece {
background-color: #f2f2f2;
}
*::-webkit-scrollbar-thumb {
background-color: #C1C1C1;
border-radius: 6px;
}
code {
font-family: Verdana, Geneva, Tahoma, Helvetica, sans-serif;
padding: 1px 4px;
color: $--color-danger;
background-color: rgba($color: $--color-warning, $alpha: 0.2);
}
pre {
font-family: 'Source Code Pro', Monaco, Consolas, Verdana, Geneva, Tahoma, Helvetica, sans-serif;
}
\ No newline at end of file
@import '../../mixins/mixins';
@import '../var';
@include b(app-main) {
display: flex;
position: relative;
&.left-right {
flex-direction: row;
}
&.top-bottom {
flex-direction: column;
@include b(app-header) {
@include when(light) {
color: $--color-white;
background-color: $--color-primary;
a, .el-button--text {
color:$--color-white;
}
.message .tips {
border-color: $--color-white;
}
.app-breadcrumb {
.el-breadcrumb__inner.is-link, .el-breadcrumb__inner a {
color: $--color-white;
}
.el-breadcrumb__inner {
color: mix($--color-white, $--nav-background-color, 85%);
}
}
}
@include when(deep) {
color: $--color-white;
background-color: mix($--color-black, $--nav-background-color, 5%);
a, .el-button--text {
color: mix($--color-white, $--nav-background-color, 85%);
}
.app-logo {
background-color: transparent;
}
.app-breadcrumb {
.el-breadcrumb__inner.is-link, .el-breadcrumb__inner a {
color: $--color-white;
}
.el-breadcrumb__inner {
color: mix($--color-white, $--nav-background-color, 85%);
}
}
}
}
.app-breadcrumb {
margin-left: 20px;
}
}
}
@include b(app-navigation) {
@include when(light) {
background-color: $--nav-background-color-light;
.app-logo {
display: flex;
align-items: center;
height: $--header-height;
background-color: $--color-primary;
color: $--color-white;
}
.app-navigation--menu {
background-color: $--nav-background-color-light;
border-right: $--border-base;
.el-menu {
background-color: $--color-white;
}
.el-menu-item, .el-submenu__title {
color: $--nav-font-color;
}
.el-menu-item:hover, .el-menu-item:focus, .el-submenu__title:hover {
background-color: $--color-primary-light-8;
}
}
.navigation-controll {
color: mix($--color-white, $--color-primary, 45%);
background-color: $--nav-background-color-light;
&:hover {
background-color: mix($--color-black, $--nav-background-color-light, 5%);
.iconfont {
color: $--color-primary;
}
}
}
}
@include when(deep) {
background-color: $--nav-background-color;
.app-logo {
display: flex;
align-items: center;
height: $--header-height;
background-color: $--color-primary;
color: $--color-white;
}
::-webkit-scrollbar-thumb {
background-color: mix($--color-white, $--nav-background-color, 35%);
}
.app-navigation--menu {
background-color: $--nav-background-color;
.el-tree {
color: $--color-primary-light-6;
i.iconfont {
color: $--color-primary-light-6;
}
.el-tree-node__content {
&:hover, &:focus {
background-color: mix($--color-white, $--nav-background-color, 8%);
}
}
&.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background-color: mix($--color-white, $--nav-background-color, 8%);
}
}
.el-menu {
background-color: mix($--color-white, $--nav-background-color, 10%);
}
.el-menu-item, .el-submenu__title {
color: $--color-primary-light-6;
i {
color: $--color-primary-light-6;
}
}
.el-menu-item:hover, .el-menu-item:focus,
.el-submenu__title:hover, .el-submenu__title:focus {
background-color: mix($--color-white, $--nav-background-color, 5%);
}
}
.navigation-controll {
background-color: mix($--color-black, $--nav-background-color, 10%);
color: mix($--color-white, $--nav-background-color, 45%);
&:hover {
background-color: mix($--color-black, $--nav-background-color, 20%);
.iconfont {
color: $--color-primary;
}
}
}
}
}
body {
&.is-light {
& > .el-menu--vertical {
background-color: $--nav-background-color-light;
max-height: 100%;
overflow: auto;
.el-menu {
background-color: $--nav-background-color-light;
}
.el-menu-item, .el-submenu__title {
color: $--nav-font-color;
}
.el-menu-item:hover, .el-menu-item:focus, .el-submenu__title:hover {
background-color: $--color-primary-light-8;
}
}
}
&.is-deep {
& > .el-menu--vertical {
background-color: $--nav-background-color;
max-height: 100%;
overflow: auto;
.el-menu {
background-color: $--nav-background-color;
}
.el-menu-item, .el-submenu__title {
color: $--color-primary-light-6;
i {
color: $--color-primary-light-6;
}
}
.el-menu-item:hover, .el-menu-item:focus, .el-submenu__title:hover {
background-color: mix($--color-white, $--nav-background-color, 20%);
}
}
}
}
\ No newline at end of file
$--color-white: #ffffff;
$--color-black: #142f3e;
/* 改变主题色变量 */
$--color-primary: #0a6fe2;
$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default;
$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default;
$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default;
$--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default;
$--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default;
$--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default;
$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default;
$--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default;
$--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default;
$--color-success: #52da0e !default;
$--color-warning: #df8d13 !default;
$--color-danger: #dd1616 !default;
$--color-info: #909499 !default;
$--color-success-light: mix($--color-white, $--color-success, 80%) !default;
$--color-warning-light: mix($--color-white, $--color-warning, 80%) !default;
$--color-danger-light: mix($--color-white, $--color-danger, 80%) !default;
$--color-info-light: mix($--color-white, $--color-info, 80%) !default;
$--color-success-lighter: mix($--color-white, $--color-success, 90%) !default;
$--color-warning-lighter: mix($--color-white, $--color-warning, 90%) !default;
$--color-danger-lighter: mix($--color-white, $--color-danger, 90%) !default;
$--color-info-lighter: mix($--color-white, $--color-info, 90%) !default;
$--color-text-primary: #303133 !default;
$--color-text-regular: #606266 !default;
$--color-text-secondary: #909399 !default;
$--color-text-placeholder: #c0c4cc !default;
/* 改变 icon 字体路径变量,必需 */
$--font-size-base: 14px !default;
$--font-size-small: 13px !default;
$--font-size-mini: 12px !default;
$--font-size-medium: 16px !default;
$--font-size-large: 18px!default;
$--font-color-disabled-base: #bbb !default;
$--font-weight-primary: 500 !default;
$--font-line-height-primary: 24px !default;
/* Link
-------------------------- */
$--link-color: $--color-primary-light-2 !default;
$--link-hover-color: $--color-primary !default;
/* Background
-------------------------- */
$--background-color-base: #f0f3f5 !default;
/* Border
-------------------------- */
$--border-width-base: 1px !default;
$--border-style-base: solid !default;
$--border-color-base: #dcdfe6 !default;
$--border-color-light: #e4e7ed !default;
$--border-color-lighter: #ebeef5 !default;
$--border-color-extra-light: #f2f6fc !default;
$--border-color-hover: $--color-text-placeholder !default;
$--border-base: $--border-width-base $--border-style-base $--border-color-base !default;
$--border-radius-base: 4px !default;
$--border-radius-small: 2px !default;
$--border-radius-circle: 100% !default;
/* Fill
-------------------------- */
$--fill-base: $--color-white !default;
/* Size
-------------------------- */
$--size-base: 14px !default;
/* z-index
-------------------------- */
$--index-normal: 1 !default;
$--index-top: 1000 !default;
$--index-popper: 2000 !default;
/* Disable base
-------------------------- */
$--disabled-fill-base: $--background-color-base !default;
$--disabled-color-base: $--color-text-placeholder !default;
$--disabled-border-base: $--border-color-light !default;
/* Box-shadow
-------------------------- */
$--box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) !default;
$--box-shadow-dark: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .12) !default;
$--box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !default;
/* Button
-------------------------- */
$--button-font-size: $--font-size-base !default;
$--button-font-weight: $--font-weight-primary !default;
$--button-border-radius: $--border-radius-base !default;
$--button-padding-vertical: 12px !default;
$--button-padding-horizontal: 20px !default;
$--button-medium-font-size: $--font-size-small !default;
$--button-medium-border-radius: $--border-radius-base !default;
$--button-medium-padding-vertical: 10px !default;
$--button-medium-padding-horizontal: 16px !default;
$--button-small-font-size: $--font-size-small !default;
$--button-small-border-radius: #{$--border-radius-base - 1} !default;
$--button-small-padding-vertical: 9px !default;
$--button-small-padding-horizontal: 14px !default;
$--button-mini-font-size: $--font-size-mini !default;
$--button-mini-border-radius: #{$--border-radius-base - 1} !default;
$--button-mini-padding-vertical: 7px !default;
$--button-mini-padding-horizontal: 10px !default;
/* Select
-------------------------- */
$--select-border-color-hover: $--border-color-hover !default;
$--select-disabled-border: $--disabled-border-base !default;
$--select-font-size: $--font-size-small !default;
$--select-close-hover-color: $--color-text-secondary !default;
$--select-input-color: $--color-text-placeholder !default;
$--select-multiple-input-color: #666 !default;
$--select-input-focus-background: $--color-primary !default;
$--select-input-font-size: 14px !default;
$--select-option-color: $--color-text-regular !default;
$--select-option-disabled-color: $--color-text-placeholder !default;
$--select-option-disabled-background: $--color-white !default;
$--select-option-height: 34px !default;
$--select-option-hover-background: $--background-color-base !default;
$--select-option-selected: $--color-primary !default;
$--select-option-selected-hover: $--background-color-base !default;
$--select-group-color: $--color-info !default;
$--select-group-height: 30px !default;
$--select-group-font-size: 12px !default;
$--select-dropdown-background: $--color-white !default;
$--select-dropdown-shadow: $--box-shadow-light !default;
$--select-dropdown-empty-color: #999 !default;
$--select-dropdown-max-height: 274px !default;
$--select-dropdown-padding: 6px 0 !default;
$--select-dropdown-empty-padding: 10px 0 !default;
$--select-dropdown-border: solid 1px $--border-color-light !default;
/* Message
-------------------------- */
$--message-close-size: 16px !default;
/* Message Box
-------------------------- */
$--msgbox-width: 420px !default;
$--msgbox-border-radius: 4px !default;
$--msgbox-font-size: $--font-size-medium !default;
$--msgbox-content-font-size: $--font-size-base !default;
$--msgbox-content-color: $--color-text-regular !default;
$--msgbox-error-font-size: 12px !default;
$--msgbox-padding-primary: 15px !default;
$--msgbox-success-color: $--color-success !default;
$--msgbox-info-color: $--color-info !default;
$--msgbox-warning-color: $--color-warning !default;
$--msgbox-danger-color: $--color-danger !default;
/* s dialog */
$--sdialog-background-color: #ffffff !default;
$--sdialog-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !default;
$--sdialog-close-hover-color: $--color-primary !default;
$--sdialog-title-font-size: $--font-size-base !default;
$--sdialog-font-size: 14px !default;
$--sdialog-line-height: $--font-line-height-primary !default;
$--sdialog-padding-primary: 20px !default;
/* s Message Box */
$--smsgbox-width: 420px !default;
$--smsgbox-border-radius: 4px !default;
$--smsgbox-font-size: $--font-size-large !default;
$--smsgbox-content-font-size: $--font-size-base !default;
$--smsgbox-content-color: $--color-text-regular !default;
$--smsgbox-error-font-size: 12px !default;
$--smsgbox-padding-primary: 15px !default;
$--smsgbox-success-color: $--color-success !default;
$--smsgbox-info-color: $--color-info !default;
$--smsgbox-warning-color: $--color-warning !default;
$--smsgbox-danger-color: $--color-danger !default;
/* s tabs */
$--stabs-header-height: 48px !default;
/* 头部变量 */
$--header-background-color: #f5f6f9 !default;
$--header-box-shadow-color: transparent !default;
$--header-border-color: transparent !default;
$--header-color: $--color-primary !default;
$--header-font-size: 16px !default;
$--header-height: 48px !default;
/* navigation */
$--nav-background-color: #2c2c47 !default;
$--nav-background-color-light: #f1f1f2 !default;
$--nav-border-color: #dcdbe0 !default;
$--nav-font-color: $--color-primary !default;
/* app tab */
$--app-tabs-height: $--stabs-header-height !default;
$--app-tabs-background-color: #eaedf1 !default;
$--app-tabs-border-color: #d0d7de !default;
$--app-tabs-text-color: #364250 !default;
$--app-tabs-active-color: $--color-white !default;
\ No newline at end of file
@import './tabs.scss';
@import './progress.scss';
\ No newline at end of file
@import "../mixins/mixins";
@import "../mixins/utils";
@import '../common/var';
@include b(sm-progress) {
position: relative;
line-height: 1;
@include e(text) {
font-size:14px;
color: $--color-text-regular;
display: inline-block;
vertical-align: middle;
margin-left: 10px;
line-height: 1;
i {
vertical-align: middle;
display: block;
}
}
@include m(circle) {
display: inline-block;
.sm-progress__text {
position: absolute;
top: 50%;
left: 0;
width: 100%;
text-align: center;
margin: 0;
transform: translate(0, -50%);
i {
vertical-align: middle;
display: inline-block;
}
}
}
@include m(without-text) {
.sm-progress__text {
display: none;
}
.sm-progress-bar {
padding-right: 0;
margin-right: 0;
display: block;
}
}
@include m(text-inside) {
.sm-progress-bar {
padding-right: 0;
margin-right: 0;
}
}
@include when(success) {
.sm-progress-bar__inner {
background-color: $--color-success;
}
.sm-progress__text {
color: $--color-success;
}
}
@include when(exception) {
.sm-progress-bar__inner {
background-color: $--color-danger;
}
.sm-progress__text {
color: $--color-danger;
}
}
}
@include b(sm-progress-bar) {
padding-right: 50px;
display: inline-block;
vertical-align: middle;
width: 100%;
margin-right: -55px;
box-sizing: border-box;
@include e(outer) {
height: 6px;
border-radius: 100px;
background-color: $--border-color-lighter;
overflow: hidden;
position: relative;
vertical-align: middle;
}
@include e(inner) {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: $--color-primary;
text-align: right;
border-radius: 100px;
line-height: 1;
white-space: nowrap;
@include utils-vertical-center;
@include when(animate) {
transition: width .4s ease;
&::before {
content: '';
position: absolute;
display: block;
width: 100%;
height: 100%;
background-image: linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
background-size: 40px 40px;
animation: reverse progress-bar-stripes 0.50s linear infinite, animate-positive 2s;
}
}
}
@include e(innerText) {
display: inline-block;
vertical-align: middle;
color: $--color-white;
font-size: 12px;
margin: 0 5px;
}
}
@keyframes progress {
0% {
background-position: 0 0;
}
100% {
background-position: 32px 0;
}
}
@keyframes progress-bar-stripes{
from {
background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
@keyframes animate-positive {
0% { width: 0; }
}
\ No newline at end of file
@import "../mixins/mixins";
@import '../common/var';
@include b(s-tabs) {
@include e(header) {
display: flex;
flex-direction: row;
padding: 0;
position: relative;
margin: 0 0 15px;
}
@include e(active-bar) {
position: absolute;
bottom: 0;
left: 0;
height: 2px;
background-color: $--color-primary;
z-index: 1;
transition: transform .3s cubic-bezier(.645,.045,.355,1);
list-style: none;
}
@include e(new-tab) {
float: right;
border: 1px solid #d3dce6;
height: 18px;
width: 18px;
line-height: 18px;
margin: 12px 0 9px 10px;
border-radius: 3px;
text-align: center;
font-size: 12px;
color: #d3dce6;
cursor: pointer;
transition: all .15s;
.s-icon-plus {
transform: scale(0.8, 0.8);
}
&:hover {
color: $--color-primary;
}
}
@include e(nav-wrap) {
flex: 1 1 0%;
overflow: hidden;
margin-bottom: -1px;
position: relative;
&::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 2px;
background-color: $--border-color-light;
z-index: $--index-normal;
}
@include when(scrollable) {
padding: 0 20px;
box-sizing: border-box;
}
}
@include e(nav-scroll) {
overflow: hidden;
}
@include e((nav-next, nav-prev)) {
position: absolute;
cursor: pointer;
line-height: 44px;
font-size: 12px;
color: $--color-text-secondary;
}
@include e(nav-next) {
right: 0;
}
@include e(nav-prev) {
left: 0;
}
@include e(nav) {
white-space: nowrap;
position: relative;
transition: transform .3s;
float: left;
z-index: #{$--index-normal + 1};
@include when(stretch) {
min-width: 100%;
display: flex;
& > * {
flex: 1 1 0%;
text-align: center;
}
}
}
@include e(item) {
padding: 0 20px;
height: $--stabs-header-height;
box-sizing: border-box;
line-height: $--stabs-header-height;
display: inline-block;
list-style: none;
font-size: 14px;
font-weight: 500;
color: $--color-text-primary;
position: relative;
&:focus, &:focus:active {
outline: none;
}
&:focus.is-active.is-focus:not(:active) {
box-shadow: 0 0 2px 2px #409eff inset;
border-radius: 3px;
}
& .s-icon-close {
border-radius: 50%;
text-align: center;
transition: all .3s cubic-bezier(.645,.045,.355,1);
margin-left: 5px;
&:before {
transform: scale(.9);
display: inline-block;
}
&:hover {
background-color: $--color-text-placeholder;
color: $--color-white;
}
}
@include when(active) {
color: $--color-primary;
}
&:hover {
color: $--color-primary;
cursor: pointer;
}
@include when(disabled) {
color: $--disabled-color-base;
cursor: default;
}
}
@include e(content) {
overflow: hidden;
position: relative;
}
@include m(card) {
> .s-tabs__header {
border-bottom: 1px solid $--border-color-light;
}
> .s-tabs__header .s-tabs__nav-wrap::after {
content: none;
}
> .s-tabs__header .s-tabs__nav {
border: 1px solid $--border-color-light;
border-bottom: none;
border-radius: 4px 4px 0 0;
box-sizing: border-box;
}
> .s-tabs__header .s-tabs__active-bar {
display: none;
}
> .s-tabs__header .s-tabs__item .s-icon-close {
position: relative;
font-size: 12px;
width: 0;
height: 14px;
vertical-align: middle;
line-height: 15px;
overflow: hidden;
top: -1px;
right: -2px;
transform-origin: 100% 50%;
}
> .s-tabs__header .s-tabs__item {
border-bottom: 1px solid transparent;
border-left: 1px solid $--border-color-light;
transition: color .3s cubic-bezier(.645,.045,.355,1), padding .3s cubic-bezier(.645,.045,.355,1);
&:first-child {
border-left: none;
}
&.is-closable {
&:hover {
padding-left: 13px;
padding-right: 13px;
& .s-icon-close {
width: 14px;
}
}
}
&.is-active {
border-bottom-color: $--color-white;
&.is-closable {
padding-left: 20px;
padding-right: 20px;
.s-icon-close {
width: 14px;
}
}
}
}
}
@include m(border-card) {
background: $--color-white;
border: 1px solid $--border-color-base;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12), 0 0 6px 0 rgba(0,0,0,0.04);
>.s-tabs__content {
padding: 15px;
}
>.s-tabs__header {
background-color: $--background-color-base;
border-bottom: 1px solid $--border-color-light;
margin: 0;
}
> .s-tabs__header .s-tabs__nav-wrap::after {
content: none;
}
>.s-tabs__header .s-tabs__item {
transition: all .3s cubic-bezier(.645,.045,.355,1);
border: 1px solid transparent;
margin: -1px -1px 0;
color: $--color-text-secondary;
&.is-active {
color: $--color-primary;
background-color: $--color-white;
border-right-color: $--border-color-base;
border-left-color: $--border-color-base;
}
&:not(.is-disabled):hover {
color: $--color-primary;
}
&.is-disabled {
color: $--disabled-color-base;
}
}
}
@include m((top, bottom)) {
.s-tabs__item.is-top:nth-child(2),
.s-tabs__item.is-bottom:nth-child(2) {
padding-left: 0;
}
.s-tabs__item.is-top:last-child,
.s-tabs__item.is-bottom:last-child {
padding-right: 0;
}
&.s-tabs--border-card, &.s-tabs--card,
.s-tabs--left, .s-tabs--right {
.s-tabs__item:nth-child(2) {
padding-left: 20px;
}
.s-tabs__item:last-child {
padding-right: 20px;
}
}
}
@include m(bottom) {
.s-tabs__header.is-bottom {
margin-bottom: 0;
margin-top: 10px;
}
&.s-tabs--border-card {
.s-tabs__header.is-bottom {
border-bottom: 0;
border-top: 1px solid $--border-color-base;
}
.s-tabs__nav-wrap.is-bottom {
margin-top: -1px;
margin-bottom: 0;
}
.s-tabs__item.is-bottom:not(.is-active) {
border: 1px solid transparent;
}
.s-tabs__item.is-bottom {
margin: 0 -1px -1px -1px;
}
}
}
@include m((left, right)) {
overflow: hidden;
.s-tabs__header.is-left,
.s-tabs__header.is-right {
flex-direction: column;
}
.s-tabs__header.is-left,
.s-tabs__header.is-right,
.s-tabs__nav-wrap.is-left,
.s-tabs__nav-wrap.is-right,
.s-tabs__nav-scroll {
height: 100%;
}
.s-tabs__active-bar.is-left,
.s-tabs__active-bar.is-right {
top: 0;
bottom: auto;
width: 2px;
height: auto;
}
.s-tabs__nav-wrap.is-left,
.s-tabs__nav-wrap.is-right {
margin-bottom: 0;
> .s-tabs__nav-prev,
> .s-tabs__nav-next {
height: 30px;
line-height: 30px;
width: 100%;
text-align: center;
cursor: pointer;
i {
transform: rotateZ(90deg);
}
}
> .s-tabs__nav-prev {
left: auto;
top: 0;
}
> .s-tabs__nav-next {
right: auto;
bottom: 0;
}
&.is-scrollable {
padding: 30px 0;
}
&::after {
height: 100%;
width: 2px;
bottom: auto;
top: 0;
}
}
.s-tabs__nav.is-left,
.s-tabs__nav.is-right {
float: none;
}
.s-tabs__item.is-left,
.s-tabs__item.is-right {
display: block;
}
}
@include m(left) {
.s-tabs__header.is-left {
float: left;
margin-bottom: 0;
margin-right: 10px;
}
.s-tabs__nav-wrap.is-left {
margin-right: -1px;
&::after {
left: auto;
right: 0;
}
}
.s-tabs__active-bar.is-left {
right: 0;
left: auto;
}
.s-tabs__item.is-left {
text-align: right;
}
&.s-tabs--card {
.s-tabs__active-bar.is-left {
display: none;
}
.s-tabs__item.is-left {
border-left: none;
border-right: 1px solid $--border-color-light;
border-bottom: none;
border-top: 1px solid $--border-color-light;
}
.s-tabs__item.is-left:first-child {
border-right: 1px solid $--border-color-light;
border-top: none;
}
.s-tabs__item.is-left.is-active {
border: 1px solid $--border-color-light;
border-right-color: #fff;
border-left: none;
border-bottom: none;
&:first-child {
border-top: none;
}
&:last-child {
border-bottom: none;
}
}
.s-tabs__nav {
border-radius: 4px 0 0 4px;
border-bottom: 1px solid $--border-color-light;
border-right: none;
}
.s-tabs__new-tab {
float: none;
}
}
&.s-tabs--border-card {
.s-tabs__header.is-left {
border-right: 1px solid #dfe4ed;
}
.s-tabs__item.is-left {
border: 1px solid transparent;
margin: -1px 0 -1px -1px;
&.is-active {
border-color: transparent;
border-top-color: rgb(209, 219, 229);
border-bottom-color: rgb(209, 219, 229);
}
}
}
}
@include m(right) {
.s-tabs__header.is-right {
float: right;
margin-bottom: 0;
margin-left: 10px;
}
.s-tabs__nav-wrap.is-right {
margin-left: -1px;
&::after {
left: 0;
right: auto;
}
}
.s-tabs__active-bar.is-right {
left: 0;
}
&.s-tabs--card {
.s-tabs__active-bar.is-right {
display: none;
}
.s-tabs__item.is-right {
border-bottom: none;
border-top: 1px solid $--border-color-light;
}
.s-tabs__item.is-right:first-child {
border-left: 1px solid $--border-color-light;
border-top: none;
}
.s-tabs__item.is-right.is-active {
border: 1px solid $--border-color-light;
border-left-color: #fff;
border-right: none;
border-bottom: none;
&:first-child {
border-top: none;
}
&:last-child {
border-bottom: none;
}
}
.s-tabs__nav {
border-radius: 0 4px 4px 0;
border-bottom: 1px solid $--border-color-light;
border-left: none;
}
}
&.s-tabs--border-card {
.s-tabs__header.is-right {
border-left: 1px solid #dfe4ed;
}
.s-tabs__item.is-right {
border: 1px solid transparent;
margin: -1px -1px -1px 0;
&.is-active {
border-color: transparent;
border-top-color: rgb(209, 219, 229);
border-bottom-color: rgb(209, 219, 229);
}
}
}
}
@include e(contextmenu) {
display: none;
position: absolute;
top: 0;
left: 0;
z-index: 2000;
padding: 6px 0;
font-size: 14px;
background-color: #fff;
box-shadow: $--select-dropdown-shadow;
@include m(item) {
padding: 10px 16px;
color: $--color-text-regular;
cursor: pointer;
&:hover {
background-color: $--select-option-hover-background;
}
}
}
}
.slideInRight-transition,
.slideInLeft-transition {
display: inline-block;
}
.slideInRight-enter {
animation: slideInRight-enter .3s;
}
.slideInRight-leave {
position: absolute;
left: 0;
right: 0;
animation: slideInRight-leave .3s;
}
.slideInLeft-enter {
animation: slideInLeft-enter .3s;
}
.slideInLeft-leave {
position: absolute;
left: 0;
right: 0;
animation: slideInLeft-leave .3s;
}
@keyframes slideInRight-enter {
0% {
opacity: 0;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(100%);
transform: translateX(100%)
}
to {
opacity: 1;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(0);
transform: translateX(0)
}
}
@keyframes slideInRight-leave {
0% {
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1
}
100% {
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(100%);
transform: translateX(100%);
opacity: 0
}
}
@keyframes slideInLeft-enter {
0% {
opacity: 0;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(-100%);
transform: translateX(-100%)
}
to {
opacity: 1;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(0);
transform: translateX(0)
}
}
@keyframes slideInLeft-leave {
0% {
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1
}
100% {
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
opacity: 0
}
}
@import "./common/var";
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index.scss";
@import "~smart-web/packages/styles/src/index.scss";
\ No newline at end of file
$namespace: '';
$element-separator: '__';
$modifier-separator: '--';
$state-prefix: 'is-';
@import "config";
/* BEM support Func
-------------------------- */
@function selectorToString($selector) {
$selector: inspect($selector);
$selector: str-slice($selector, 2, -2);
@return $selector;
}
@function containsModifier($selector) {
$selector: selectorToString($selector);
@if str-index($selector, $modifier-separator) {
@return true;
} @else {
@return false;
}
}
@function containWhenFlag($selector) {
$selector: selectorToString($selector);
@if str-index($selector, '.' + $state-prefix) {
@return true
} @else {
@return false
}
}
@function containPseudoClass($selector) {
$selector: selectorToString($selector);
@if str-index($selector, ':') {
@return true
} @else {
@return false
}
}
@function hitAllSpecialNestRule($selector) {
@return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector);
}
@import "function";
/* BEM
-------------------------- */
@mixin b($block) {
$B: $block !global;
.#{$B} {
@content;
}
}
@mixin e($element) {
$E: $element !global;
$selector: &;
$currentSelector: "";
@each $unit in $element {
$currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
}
@if hitAllSpecialNestRule($selector) {
@at-root {
#{$selector} {
#{$currentSelector} {
@content;
}
}
}
} @else {
@at-root {
#{$currentSelector} {
@content;
}
}
}
}
@mixin m($modifier) {
$selector: &;
$currentSelector: "";
@each $unit in $modifier {
$currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
}
@at-root {
#{$currentSelector} {
@content;
}
}
}
@mixin configurable-m($modifier, $E-flag: false) {
$selector: &;
$interpolation: '';
@if $E-flag {
$interpolation: $element-separator + $E-flag;
}
@at-root {
#{$selector} {
.#{$B+$interpolation+$modifier-separator+$modifier} {
@content;
}
}
}
}
@mixin spec-selector($specSelector: '', $element: $E, $modifier: false, $block: $B) {
$modifierCombo: '';
@if $modifier {
$modifierCombo: $modifier-separator + $modifier;
}
@at-root {
#{&}#{$specSelector}.#{$block+$element-separator+$element+$modifierCombo} {
@content
}
}
}
@mixin meb($modifier: false, $element: $E, $block: $B) {
$selector: &;
$modifierCombo: '';
@if $modifier {
$modifierCombo: $modifier-separator + $modifier;
}
@at-root {
#{$selector} {
.#{$block+$element-separator+$element+$modifierCombo} {
@content
}
}
}
}
@mixin when($state) {
@at-root {
&.#{$state-prefix + $state} {
@content;
}
}
}
@mixin extend-rule($name) {
@extend #{'%shared-'+$name};
}
@mixin share-rule($name) {
$rule-name: '%shared-'+$name;
@at-root #{$rule-name} {
@content
}
}
\ No newline at end of file
@mixin utils-user-select($value) {
-moz-user-select: $value;
-webkit-user-select: $value;
-ms-user-select: $value;
}
@mixin utils-clearfix {
$selector: &;
@at-root {
#{$selector}::before,
#{$selector}::after {
display: table;
content: "";
}
#{$selector}::after {
clear: both
}
}
}
@mixin utils-vertical-center {
$selector: &;
@at-root {
#{$selector}::after {
display: inline-block;
content: "";
height: 100%;
vertical-align: middle
}
}
}
@mixin utils-ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
\ No newline at end of file
import store from '../store';
import router from '../router';
import Api from '../api';
import Utils from './index';
import { Notification } from 'element-ui';
// 获取URL参数
export const getQueryString = (name) => {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
const r = window.location.search.substr(1).match(reg); // 查询?后面的参数,并匹配正则
if (r != null) return unescape(r[2]);
const param = getHashParameters();
// console.log(param)
if (param[name]) return param[name];
return null;
};
function getHashParameters() {
const arr = (location.hash || '').replace(/^#\/[a-zA-Z0-9]*\?/, '').split('&');
const params = {};
for (let i = 0; i < arr.length; i++) {
const data = arr[i].split('=');
if (data.length === 2) {
params[data[0]] = data[1];
}
}
return params;
}
// 改变初始化加载提示文字
const appLoadingSub = document.getElementById('app-loading-subtitle');
if (appLoadingSub) appLoadingSub.innerHTML = '正在获取系统信息中...';
// 移除加载页
export function removeLoading() {
const el = document.getElementById('app-loading');
if (el) {
el.className = 'app-loading app-loading-leave';
setTimeout(() => { el.parentNode && el.parentNode.removeChild(el); }, 251);
}
}
// 获取系统信息
export function getSystemInfo(sysCode) {
sysCode = sysCode || getQueryString('sysCode');
console.log('系统code:', sysCode);
return new Promise((resolve, reject) => {
Api.getSystemInfo(sysCode).then(res => {
removeLoading();
if (res.status === 0) {
// console.log(res.data)
store.state.platformInfo.systemId = res.data.systemId;
store.state.platformInfo.name = res.data.sysMainTitle;
resolve();
} else {
reject(res);
}
}).catch(err => {
removeLoading();
// 获取系统信息错误
router.replace({
name: 'Unfound'
});
reject(err);
});
});
}
/**
* 公共提示方法,一般用于组件内保存提交时提示
* @param {object} options 和element-ui Notification组件属性一样
*/
export const notification = (options = {}) => {
const {
customClass = 'custom-notification',
position = 'bottom-right',
...opts
} = options;
const _opts = {
customClass,
position,
...opts
};
Notification(_opts);
};
/**
* 改变皮肤的方法
* 为body添加is-class
* @param {Object} theme
*/
export const changeTheme = (theme) => {
document.body.className = theme.format + ' is-' + theme.themeColor;
store.dispatch('setTheme', theme);
localStorage.setItem('themeValue', JSON.stringify(theme));
};
/**
* 获取个人界面皮肤配置
*/
export const getTheme = () => {
Api.getUserConfigTheme().then(res => {
if (res.status === 0) {
const data = res.data;
if (!Utils.isEmptyData(data)) {
changeTheme(data);
}
}
});
};
/**
* 日期转成方法,注册到原型链上
* @param {Stirng} fmt yyyy-MM-dd hh:mm:ss
*/
/* eslint no-extend-native: "off" */
Date.prototype.format = function(fmt) {
const o = {
'M+': this.getMonth() + 1, // 月份
'd+': this.getDate(), // 日
'h+': this.getHours(), // 小时
'm+': this.getMinutes(), // 分
's+': this.getSeconds(), // 秒
'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
'S': this.getMilliseconds() // 毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
}
}
return fmt;
};
const utils = {
/**
* 判断数据是否为空,一般数据是object/array
* @param {Object/Array}
*/
isEmptyData(data) {
if (data === null || data === undefined) return true;
if (data instanceof Object) {
let t;
for (t in data) {
return false;
}
return true;
} else if (data instanceof Array) {
if (data.length === 0) return true;
return false;
}
},
/**
* 深拷贝
* @param {Object|Array} p
* @param {Object|Array} c [] or {}
*/
deepCopy(p, c) {
c = c || {};
for (const i in p) {
if (typeof p[i] === 'object') {
c[i] = p[i]
? (p[i] && p[i].constructor === Array) ? [] : {}
: p[i];
this.deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
},
/**
* 随机生成唯一 ID
* @param {Number}
*/
generateId(len = 4) {
return Number(Math.random().toString().substr(3, len) + Date.now()).toString(36);
},
/**
* 优化遍历,数组去重
* @param {Array} array
*/
uniq(array, key) {
const temp = [];
const index = [];
const l = array.length;
for (let i = 0; i < l; i++) {
for (let j = i + 1; j < l; j++) {
if (array[i][key] && array[i][key] === array[j][key]) {
i++;
j = i;
}
}
temp.push(array[i]);
index.push(i);
}
return temp;
}
};
export default utils;
import permissionMixin from '../permissionMixin';
/**
* 系统设置一般公共性权限
*/
export default {
mixins: [permissionMixin]
};
import Api from '@/api';
/**
* 组件混入统一权限
* data注入userAuthories存储接口或者管理权限
* userAuthories = {
* identity: 'admin', // 或者无
* defaultAuthority: '2', // 2-只读,4-操作,8-管理(后台约束)
* expandAuthorities: [] // 扩展的权限列表
* }
*/
export default {
computed: {
userInfo() {
return this.$store.state.userInfo;
},
defaultAuthority() {
return this.userAuthories ? this.userAuthories.defaultAuthority : '';
},
expandAuthorities() {
return this.userAuthories ? this.userAuthories.expandAuthorities : [];
}
},
data() {
return {
userAuthories: null
};
},
watch: {
userInfo: {
deep: true,
handler(val) {
if (val && val.userId) {
this.initPermission();
}
}
},
userAuthories: {
deep: true,
handler(val) {
this.hanldePermission && this.hanldePermission(val);
}
}
},
created() {
this.initPermission();
},
methods: {
initPermission() {
// 超级管理员特殊处理
if (this.$store.state.userIdentity === 'admin') {
this.userAuthories = {
defaultAuthority: 8,
expandAuthorities: []
};
return;
}
/**
* 一些模块的控件过滤
* 例如:没有存在的菜单的项的路由组件,不作权限控件
*/
if ([].indexOf(this.$route.name) >= 0
) {
return;
}
// 判断是否有moduleId,一般首页没有
if (!this.$route.params.moduleId) return;
Api.getUserAuthories(this.$route.params.moduleId).then(res => {
if (res.status === 0) {
this.userAuthories = {
defaultAuthority: res.data.defaultSysAuthorize,
expandAuthorities: res.data.sysAuthorizeList
};
}
});
}
}
};
import permissionMixin from '../permissionMixin';
/**
* 系统设置一般公共性权限
*/
export default {
mixins: [permissionMixin]
};
import { notification } from './global';
// 配置全局,可以在iframe等地方使用
window.notification = notification;
// window.getUser = getUser;
// window.getUserName = getUserName;
<template>
<div :class="['app-main', theme.format]">
<app-header v-if="theme.format === 'top-bottom'" :class="themeClrCls"></app-header>
<div class="app-wrapper">
<app-navigation></app-navigation>
<div class="app-container" ref="appContainer">
<app-header v-if="theme.format === 'left-right'"></app-header>
<div class="app_container-main">
<router-view></router-view>
</div>
</div>
</div>
<!-- <router-view name="loginDialog"></router-view> -->
</div>
</template>
<script>
import AppHeader from './common/Header';
import AppNavigation from './Navigation';
import { changeTheme } from '@/utils/global';
export default {
name: 'Main',
components: {
AppHeader,
AppNavigation
},
computed: {
theme() {
return this.$store.state.theme;
},
themeClrCls() {
return 'is-' + this.theme.themeColor;
}
},
data() {
return {
oldNavigation: null
};
},
watch: {
theme: {
immediate: true,
handler(val) {
changeTheme(val);
}
}
},
mounted() {
},
methods: {
hasOwnProperty(obj, key) {
return obj.hasOwnProperty(key);
}
}
};
</script>
<template>
<div :class="['app-navigation', {'is-collapse': isCollapse}, themeClrCls]" @mouseover="isShowControll = true" @mouseout="isShowControll = false">
<logo v-if="theme.format === 'left-right'" />
<span v-if="isLoading" style="position:absolute; top: 5px; text-align: center; color: #abb9d1;"><i class="el-icon-loading"></i></span>
<el-menu
:default-active="defaultActive"
class="app-navigation--menu"
:collapse="isCollapse"
:unique-opened="true">
<template v-for="subItem in navDatas">
<el-submenu
:key="subItem.moduleId"
v-if="subItem.children && subItem.children.length > 0"
:index="subItem.moduleId"
:disabled="subItem.disabled">
<template slot="title">
<i v-if="subItem.icon && !hasImage(subItem.icon)" :class="['iconfont', subItem.icon]"></i>
<img v-else-if="hasImage(subItem.icon)" class="imgIcon" :src="subItem.icon" width="16" height="16">
<span class="text">{{ subItem.name }}</span>
</template>
<el-menu-item
v-for="item in subItem.children"
:key="item.moduleId"
:index="item.moduleId"
:disabled="item.disabled"
@click.native="handleSelect(item)">
<i v-if="item.icon && !hasImage(item.icon)" :class="['iconfont', item.icon]"></i>
<img v-else-if="hasImage(item.icon)" class="imgIcon" :src="item.icon" width="16" height="16">
<span class="text">{{ item.name }}</span>
</el-menu-item>
</el-submenu>
<el-menu-item
v-else
:key="subItem.moduleId"
:index="subItem.moduleId"
:disabled="subItem.disabled"
@click.native="handleSelect(subItem)">
<i v-if="subItem.icon && !hasImage(subItem.icon)" :class="['iconfont', subItem.icon]"></i>
<img v-else-if="hasImage(subItem.icon)" class="imgIcon" :src="subItem.icon" width="16" height="16">
<span class="text">{{ subItem.name }}</span>
</el-menu-item>
</template>
</el-menu>
<!-- <div class="app-navigation--menu">
<el-tree
:data="navDatas"
:props="defaultProps"
empty-text="暂无或未取到系统模块"
node-key="moduleId"
highlight-current
@current-change="handleSelect">
<span class="nav-tree-node" slot-scope="{ node, data }">
<span>
<i v-if="data.icon && !hasImage(data.icon)" :class="['iconfont', data.icon]"></i>
<span v-else-if="hasImage(data.icon)" class="imgIcon">
<img :src="data.icon" width="18" height="18">
</span>
{{ node.label }}
</span>
</span>
</el-tree>
</div> -->
<div class="navigation-controll" v-show="isShowControll" @click="isCollapse = !isCollapse">
<i class="iconfont" :class="controllIcon"></i>
</div>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex';
import Utils from '@/utils';
import Api from '@/api';
import Logo from './common/Logo.vue';
export default {
name: 'Navigation',
components: {
Logo
},
computed: {
...mapState(['theme', 'platformInfo', 'userInfo']),
themeClrCls() {
return 'is-' + this.theme.themeColor;
},
controllIcon() {
return this.isCollapse ? 'icon-right' : 'icon-left';
}
},
data() {
return {
isLoading: false,
defaultProps: {
children: 'children',
label: 'name'
},
defaultActive: '',
isCollapse: false,
isShowControll: false,
navDatas: []
};
},
watch: {
userInfo(val) {
this.fecthData();
}
},
mounted() {
this.fecthData();
},
methods: {
...mapActions({
dispatchMenuList: 'menu/setMenuList'
}),
hasImage(val) {
return val && /(.jpg|.png|.jpeg|.ico|.gif)$/g.test(val.toString());
},
fecthData() {
if (Utils.isEmptyData(this.userInfo)) return;
this.isLoading = true;
Api.getUserModulesTreeBySystemId(this.platformInfo.systemId).then(res => {
this.isLoading = false;
// console.log(res)
if (res.status === 0) {
this.navDatas = res.data;
this.dispatchMenuList(this.navDatas);
} else {
this.$message({
type: 'warning',
message: '获取模块树失败,请重试'
});
}
}).catch(err => {
this.isLoading = false;
this.$message({
type: 'warning',
message: err.message || '获取模块树失败,请重试'
});
});
},
handleSelect(item) {
if (!item.router) {
this.$message({
type: 'warning',
message: '没有配置到路由',
duration: 2000
});
return;
}
this.defaultActive = item.moduleId;
// 以ID判断不再打开相同
if (this.$route.name === item.router && item.router !== 'configurePage') return;
// 判断是外链
if (/^(https?)/.test(item.router)) {
this.$router.push({
name: 'appIframe',
params: {
url: item.router
}
});
return;
}
delete item.children;
const route = {
name: item.router,
params: {
...item
}
};
this.$router.push(route);
}
}
};
</script>
<template>
<sw-business-configuration></sw-business-configuration>
</template>
<script>
export default {
name: 'businessConfiguration'
};
</script>
<template>
<div class="app-iframe" style="width:100%;height:100%;overflow: hidden;">
<ss-iframe :url="url" :name="name" @load="handleFrameLoaded"></ss-iframe>
</div>
</template>
<script>
export default {
name: 'AppIframe',
data() {
return {
url: '',
name: ''
};
},
mounted() {
this.init();
},
methods: {
init() {
this.$Progress.start();
if (!this.$route.params.url) {
this.$router.replace('/404');
return;
}
this.url = this.$route.params.url;
this.name = this.$route.params.name;
},
handleFrameLoaded() {
console.log('----------------------handleFrameLoaded');
this.$Progress.finish();
}
}
};
</script>
<template>
<el-breadcrumb separator-class="el-icon-arrow-right" class="app-breadcrumb">
<el-breadcrumb-item :to="$route.path !== '/home' ? { path: '/' } : null">首页</el-breadcrumb-item>
<el-breadcrumb-item
v-for="(item, index) in breadcrumbData"
:key="index"
:to="item.path ? { path: item.path } : item.path">
{{ item.text }}
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
name: 'AppBreadcrumb',
computed: {
menuList() {
return this.$store.state.menu.menuList;
}
},
data() {
return {
breadcrumbData: null
};
},
watch: {
'$route': {
handler() {
this.init();
}
},
menuList() {
this.init();
}
},
created() {
this.init();
},
methods: {
init() {
const currentRoute = this.$route;
this.breadcrumbData = [];
currentRoute.matched.map((item, idx) => {
if (item.path && item.path !== '/home') {
const text = this.getRouteZhName(currentRoute);
this.breadcrumbData.push({
path: currentRoute.path !== item.path ? item.path : null,
name: currentRoute.name,
text
});
}
});
},
getRouteZhName(route) {
let text = '未知模块';
if (route.name === 'formRender') text = '表单渲染';
if (route.name === 'settingColumn') text = '设置列';
if (route.name === 'checkProcess') text = '流程流转';
const fn = (data) => {
const len = data.length;
for (let i = 0; i < len; i++) {
if (route.params.moduleId) {
if (data[i].router === route.name && data[i].moduleId === route.params.moduleId) {
text = data[i].name;
break;
}
} else {
if (data[i].router === route.name) {
text = data[i].name;
break;
}
}
if (data[i].children && Array.isArray(data[i].children)) {
fn(data[i].children);
}
}
};
fn(this.menuList);
return text;
}
}
};
</script>
<template>
<ss-iframe :url="url"></ss-iframe>
</template>
<script>
/**
* 渲染快速功能配置页
* smart-page
*/
export default {
name: 'ConfigurePage',
data() {
return {
url: ''
};
},
watch: {
'$route.params': {
deep: true,
handler() {
this.init();
}
}
},
created() {
this.init();
},
methods: {
init() {
const tab = this.$route.params;
this.url = `./form.html?pageId=${tab.pageId}&moduleId=${tab.moduleId}`;
}
}
};
</script>
<template>
<div class="app-header">
<div class="app-header--left">
<logo v-if="theme.format === 'top-bottom'" />
<app-breadcrumb></app-breadcrumb>
</div>
<div class="app-header--right">
<div class="app-header__userinfo">
<!-- <a href="javascript:;" class="message gutter" @click="handleMessage">
<i class="iconfont icon-tongzhi"></i>
<div class="tips">9</div>
</a>-->
<div class="app-header--function">
<a class="el-button el-button--text"
:href="`${serviceUrl}/smartcharts`" target="_blank">
<span>图表设计器</span>
</a>
<a class="el-button el-button--text"
:href="`${serviceUrl}/smartform`" target="_blank">
<span>表单设计器</span>
</a>
</div>
<el-badge :value="unreadMessage"
:hidden="unreadMessage === 0 || unreadMessage === '0'"
style="margin-right: 10px;cursor: pointer;"
:max="99"
@click.native="handleMessage">
<i class="iconfont icon-tongzhi"></i>
</el-badge>
<a href="javascript:;" class="user-name gutter">
<i class="iconfont icon-touxiang"></i>
<span v-if="userInfo.RealName" @click="handleUserClick">{{ userInfo.RealName }}</span>
<span v-else @click="handleRelogin">登录</span>
</a>
<!-- <a href="javascript:;" class="quit-user gutter" @click="logout">
<i class="iconfont icon-tuichu"></i>
<span>退出</span>
</a> -->
<el-button v-if="userInfo.RealName" class="quit-user gutter" type="text"
size="small" icon="iconfont icon-tuichu" :loading="isLoadingout" @click="logout">
退出
</el-button>
</div>
</div>
</div>
</template>
<script>
import Api from '@/api';
import { baseUrl, serviceUrl } from '@config/http.config';
import Logo from './Logo.vue';
import AppBreadcrumb from './Breadcrumb';
export default {
name: 'AppHeader',
components: {
Logo,
AppBreadcrumb
},
computed: {
theme() {
return this.$store.state.theme;
},
themeClrCls() {
return 'is-' + this.theme.themeColor;
},
userInfo() {
return this.$store.state.userInfo;
},
organName() {
return this.userInfo.OrganName ? this.userInfo.OrganName : '无部门';
},
unreadMessage() {
return this.$store.state.unreadMessage || 0;
}
},
data() {
return {
serviceUrl,
isLoadingout: false,
websocket: null
};
},
watch: {
userInfo(val) {
if (val) {
this.init();
} else {
window.WebSocket && this.websocket && this.websocket.close();
}
}
},
mounted() {
this.init();
},
beforeDestroy() {
window.WebSocket && this.websocket && this.websocket.close();
},
methods: {
init() {
if (this.userInfo && this.userInfo.userId && window.WebSocket) {
this.websocket = new WebSocket(`ws:${baseUrl}/MessageWebsocket?userId=${this.userInfo.userId}`);
this.websocket.onopen = function(event) {
// console.log(event)
};
this.websocket.onclose = function(event) {
// console.log(event)
};
this.websocket.onmessage = (event) => {
// state.unreadMessage = event.data
// this.unreadMessage = event.data;
this.$store.dispatch('setUnreadMessage', event.data);
};
this.websocket.onerror = function(event) {
// console.log(event)
};
}
},
/**
* 查看消息
*/
handleMessage() {
this.$router.push({
name: 'appMessage'
});
},
handleRelogin() {
this.$router.push('/login');
},
handleUserClick() {
this.$router.push({
name: 'accountSetting'
});
},
logout() {
this.$confirm('是否要退出账户?', '退出', {
type: 'warning'
}).then(_ => {
this.isLoadingout = true;
Api.logout().then(res => {
this.isLoadingout = false;
if (res.status === 0) {
this.$message({
type: 'success',
message: '账户退出成功'
});
this.$router.replace({
path: '/login',
query: this.$route.query
});
} else {
this.$message({
type: 'warning',
message: res.message
});
}
}).catch(err => {
this.isLoadingout = false;
this.$message({
type: 'error',
message: err.message
});
});
}).catch(_ => {});
}
}
};
</script>
<template>
<div class="home-config">
</div>
</template>
<script>
export default {
name: 'HomeConfig'
};
</script>
<template>
<div class="app-logo" href="#">
<a class="menu" href="javascript:;" :title="platformInfo.name"><span class="img"></span></a>
<h2 class="app-title" :style="appTilteStl">{{ platformInfo.name }}</h2>
</div>
</template>
<script>
export default {
name: 'Logo',
computed: {
theme() {
return this.$store.state.theme;
},
platformInfo() {
return this.$store.state.platformInfo;
},
appTilteStl() {
if (this.theme.format === 'top-bottom') return { fontSize: '22px' };
let fontSize = '20px';
const getStrLen = (str) => {
if (str == null) return 0;
if (typeof str !== 'string') {
str += '';
}
/* eslint-disable */
return str.replace(/[^\x00-\xff]/g, '01').length
}
let len = getStrLen(this.platformInfo.name)
// console.log(len)
len >= 20 ? fontSize = '16px' : fontSize = '20px'
return { fontSize }
}
}
}
</script>
\ No newline at end of file
<template>
<sw-home
@statis-item-click="handleStatisClick"
@open-doing-work="handleOpenDoingWork"
@open-doing-work-more="handleDoingWorkMore">
</sw-home>
</template>
<script>
export default {
name: 'AppHome',
methods: {
handleStatisClick(item) {
this.$router.push({ name: item.router});
},
handleOpenDoingWork(row) {
this.$router.push({
name: 'doingWork',
params: {
jid: row['job_base-jid']
}
});
},
handleDoingWorkMore() {
this.$router.push({
name: 'doingWork'
});
}
}
};
</script>
<template>
<div class="form-render" style="width:100%;height:100%;overflow: hidden;">
<ss-iframe v-if="url" :url="url" :name="name" @load="handleFrameLoaded"></ss-iframe>
<template v-else>
<div style="padding: 20px;text-align:center;">
<span class="color-danger">表单渲染错误!</span>
<span>路由不能直接访问,需要从工作列表跳转</span>
</div>
</template>
</div>
</template>
<script>
export default {
name: 'FormRender',
data() {
return {
url: '',
name: ''
};
},
mounted() {
this.init();
},
methods: {
init() {
this.$Progress.start();
this.url = this.$route.params.url;
this.name = this.$route.params.name;
},
handleFrameLoaded() {
this.$Progress.finish();
}
}
};
</script>
<template>
<div class="function-module">
<div class="title">已有模块</div>
<div class="content">
<span class="module-item" v-for="module in componentsNames" :key="module">{{ module }}</span>
</div>
</div>
</template>
<script>
export default {
name: 'functionModule',
data() {
return {
componentsNames: null
};
},
created() {
const routes = this.$router.options.routes[0] && this.$router.options.routes[0].children;
this.componentsNames = [];
if (routes) {
routes.forEach(item => {
this.componentsNames.push(item.name);
});
}
}
};
</script>
<template>
<sw-icon></sw-icon>
</template>
<script>
export default {
name: 'iconView'
};
</script>
<template>
<sw-message
:user-info="userInfo"
@unread-message-change="handleUnreadMessageChange">
</sw-message>
</template>
<script>
export default {
name: 'AppMessage',
computed: {
userInfo() {
return this.$store.state.userInfo;
}
},
methods: {
handleUnreadMessageChange(val) {
this.$store.dispatch('setUnreadMessage', val);
}
}
};
</script>
<template>
<div class="login__wrapper" id="loginView">
<div class="login-logo">
<span class="login-logo__icon"></span>
<span class="login-logo__title">{{ systemTitle }}</span>
</div>
<login-form @submit="handleSubmited"></login-form>
</div>
</template>
<script>
import LoginForm from './LoginForm.vue';
export default {
name: 'Login',
components: {
LoginForm
},
computed: {
systemTitle() {
return this.$store.state.platformInfo.name;
}
},
methods: {
handleSubmited(userInfo) {
// console.log(userInfo);
}
}
};
</script>
<template>
<div class="login-dialog__wrapper">
<el-dialog
:visible.sync="dialogVisible"
width="400px"
:close-on-click-modal="false"
:close-on-press-escape="false"
@open="handleOpened"
@close="handleClose">
<span slot="title"></span>
<login-form @submit="handleSubmited"></login-form>
</el-dialog>
</div>
</template>
<script>
import LoginForm from './LoginForm';
// import { checkLogin } from '@/utils/global'
export default {
name: 'LoginDialog',
components: {
LoginForm
},
data() {
return {
dialogVisible: false
};
},
mounted() {
setTimeout(() => {
this.open();
}, 4);
},
methods: {
open() {
this.dialogVisible = true;
},
handleOpened() {
this.$nextTick(() => {
this.$message({
message: '账户登录已失效,请重新登录',
type: 'warning',
duration: 4000
});
});
},
handleClose() {
// this.$router.replace('/');
},
handleSubmited(userInfo) {
// console.log(userInfo)
this.$message.closeAll();
}
}
};
</script>
<template>
<div class="login-form">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span style="line-height: 36px;font-size:20px;">登录</span>
<span v-if="showClose" class="login-form__close" @click.stop="handleClose"><i class="el-icon-close"></i></span>
</div>
<el-form
ref="loginForm"
:model="loginForm"
:rules="rules"
label-width="100px"
@submit.native.prevent>
<el-form-item label="账户:" prop="name">
<el-input v-model="loginForm.name" placeholder="输入登录用户名" autofocus @change="handleInputChange"></el-input>
</el-form-item>
<el-form-item label="密码:" prop="password">
<el-input type="password"
v-model="loginForm.password"
placeholder="请输入密码"
@keyup.native.enter="onSubmit('loginForm')"
@change="handleInputChange"></el-input>
</el-form-item>
<el-form-item>
<el-checkbox label="记住账户" v-model="loginForm.remember"></el-checkbox>
</el-form-item>
<el-form-item class="buttons">
<el-button
type="primary"
size="large"
class="submitBtn"
:loading="loginForm.loading"
@click="onSubmit()" >
{{ loginForm.submitText }}
</el-button>
<el-button type="text" @click="resetFields()">重置</el-button>
</el-form-item>
<el-form-item v-if="loginForm.isSubmit" style="margin-bottom: 0;">
<el-alert type="error" :title="loginForm.errorText" :closable="true" style="line-height: 1.2;" @close="loginForm.isSubmit = false"></el-alert>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import sha1 from 'js-sha1';
import Api from '@/api';
export default {
name: 'LoginForm',
props: {
showClose: Boolean
},
data() {
return {
loginForm: {
name: '',
password: '',
remember: false,
loading: false,
isSubmit: false,
errorText: '用户名或密码错误',
submitText: '登录'
},
rules: {
name: [
{required: true, message: '请输入账户名称', trigger: 'change'}/* ,
{ min: 3, max: 12, message: '长度在 3 到 12 个字符', trigger: 'blur' } */
],
password: [
{required: true, message: '请输入密码', trigger: 'change'}/* ,
{ min: 3, max: 18, message: '长度在 3 到 18 个字符', trigger: 'blur' } */
]
}
};
},
mounted() {
this.init();
},
methods: {
init() {
if (window.localStorage) {
const rname = localStorage.getItem('rememberName');
this.loginForm.name = rname;
this.loginForm.remember = true;
}
},
handleInputChange() {
this.loginForm.isSubmit = false;
},
onSubmit() {
this.$refs['loginForm'].validate((valid) => {
this.loginForm.isSubmit = false;
if (valid) {
this.loginForm.loading = true;
const psw = sha1(this.loginForm.password).toUpperCase();
const uName = this.loginForm.name.replace(/\s/g, '');
Api.login({
username: uName,
password: psw
}).then(res => {
this.loginForm.loading = false;
const data = res.data;
if (res.status === 0) {
// 本地存储
if (this.loginForm.remember) {
localStorage.setItem('rememberName', uName);
}
// vuex store
const userState = {
...data.loginInfo,
userId: data.userId
};
this.$store.dispatch('setUserInfo', userState);
// notify
const message = '欢迎您,' + userState.RealName;
this.$notify({
title: '登录成功',
message: message,
type: 'success'
});
this.$emit('submit', userState);
this.$router.replace({
path: '/',
query: this.$route.query
});
} else {
this.loginForm.errorText = res.message || '用户名或密码错误';
this.loginForm.isSubmit = true;
}
}).catch(err => {
this.loginForm.loading = false;
this.loginForm.isSubmit = true;
this.loginForm.errorText = '提交失败,服务有误! ' + err.message;
});
} else {
console.log('error submit!!');
return false;
}
});
},
resetFields() {
this.$refs['loginForm'].resetFields();
},
handleClose() {
this.$emit('close');
}
}
};
</script>
<template>
<sw-catalog-management></sw-catalog-management>
</template>
<script>
export default {
name: 'catalogManagement'
};
</script>
<template>
<sw-layer-manage></sw-layer-manage>
</template>
<script>
export default {
name: 'layerManage'
};
</script>
<template>
<sw-map-config></sw-map-config>
</template>
<script>
export default {
name: 'mapConfig'
};
</script>
<template>
<sw-map-search></sw-map-search>
</template>
<script>
export default {
name: 'mapSearchConfig'
};
</script>
<template>
<sw-service-register></sw-service-register>
</template>
<script>
export default {
name: 'serviceRegister'
};
</script>
<template>
<sw-check-process
:user-authority="userAuthories"
:process-instance-id="processInstanceId">
</sw-check-process>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'checkProcess',
mixins: [permission],
data() {
return {
processInstanceId: ''
};
},
created() {
this.init();
},
methods: {
init() {
this.processInstanceId = this.$route.params.processInstanceId;
}
}
};
</script>
<template>
<sw-create-work
ref="createWork"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@create-work="handleCreateWork"
@setting-column="handleSetColumn">
</sw-create-work>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'CreateWork',
mixins: [permission],
methods: {
refresh() {
this.$refs.createWork.refresh();
},
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}`,
parent: 'createWork'
}
});
},
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'checkProcess',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
handleCreateWork(id) {
this.$router.push({
name: 'formRender',
params: {
url: `./form.html?businessDefinitionId=${id}`
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'create_list'
}
});
}
}
};
</script>
<template>
<sw-delete-box
ref="deleteBox"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@setting-column="handleSetColumn"></sw-delete-box>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'DeleteBox',
mixins: [permission],
methods: {
refresh() {
this.$refs.deleteBox.refresh();
},
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey,
historyProcessInstanceId
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}&historyProcessInstanceId=${historyProcessInstanceId}`,
parent: 'deleteBox'
}
});
},
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'delete_list'
}
});
}
}
};
</script>
<template>
<sw-doing-work
ref="doingWork"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@setting-column="handleSetColumn"></sw-doing-work>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'DoingWork',
mixins: [permission],
methods: {
refresh() {
this.$refs.doingWork.refresh();
},
// 打开
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}`,
parent: 'doingWork'
}
});
},
// 查看流转情况,流程
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'checkProcess',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'run_list'
}
});
}
}
};
</script>
<template>
<sw-finished-work
ref="finishedWork"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@setting-column="handleSetColumn"></sw-finished-work>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'FinishedWork',
mixins: [permission],
methods: {
refresh() {
this.$refs.finishedWork.refresh();
},
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}`,
parent: 'finishedWork'
}
});
},
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'checkProcess',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'finish_list'
}
});
}
}
};
</script>
<template>
<sw-handled-work
ref="handledWork"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@setting-column="handleSetColumn"></sw-handled-work>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'HandledWork',
mixins: [permission],
methods: {
refresh() {
this.$refs.handledWork.refresh();
},
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}`,
parent: 'handledWork'
}
});
},
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'checkProcess',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'handled_list'
}
});
}
}
};
</script>
<template>
<sw-monitor-work
ref="monitorWork"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@setting-column="handleSetColumn"></sw-monitor-work>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'MonitorWork',
mixins: [permission],
methods: {
refresh() {
this.$refs.monitorWork.refresh();
},
// 打开
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey,
historyProcessInstanceId
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}&historyProcessInstanceId=${historyProcessInstanceId}`,
parent: 'monitorWork'
}
});
},
// 查看流转情况,流程
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'checkProcess',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'monitor_run_list'
}
});
}
}
};
</script>
<template>
<sw-return-box
ref="returnBox"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@setting-column="handleSetColumn"></sw-return-box>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'ReturnBox',
mixins: [permission],
methods: {
refresh() {
this.$refs.returnBox.refresh();
},
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey,
historyProcessInstanceId
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}&historyProcessInstanceId=${historyProcessInstanceId}`,
parent: 'returnBox'
}
});
},
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'checkProcess',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'sendback_list'
}
});
}
}
};
</script>
<template>
<sw-setting-column
ref="settingColumn"
:user-authority="userAuthories"
:type="workType"></sw-setting-column>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'SettingColumn',
mixins: [permission],
data() {
return {
workType: ''
};
},
watch: {
$route(value) {
if (value.params.workType !== this.workType) {
this.refresh();
}
}
},
created() {
this.workType = this.$route.params.workType;
},
methods: {
refresh() {
this.workType = this.$route.params.workType;
this.$refs.settingColumn.refresh();
}
}
};
</script>
<template>
<sw-suspend-work
ref="suspendWork"
:user-authority="userAuthories"
@open-work="handleOpenWork"
@check-process="handleCheckProcess"
@setting-column="handleSetColumn"></sw-suspend-work>
</template>
<script>
import permission from '@/utils/mixins/myWork/permission';
export default {
name: 'suspendWork',
mixins: [permission],
methods: {
refresh() {
this.$refs.suspendWork.refresh();
},
// 打开
handleOpenWork(data) {
const {
businessId,
taskId,
linkInstanceId,
linkDefinitionKey
} = data;
this.$router.push({
name: 'formRender',
params: {
businessId,
url: `./form.html?taskId=${taskId}&linkInstanceId=${linkInstanceId}&linkDefinitionKey=${linkDefinitionKey}`,
parent: 'suspendWork'
}
});
},
// 查看流转情况,流程
handleCheckProcess(data) {
const {
businessId,
processInstanceId,
taskId
} = data;
this.$router.push({
name: 'checkProcess',
params: {
businessId,
processInstanceId: processInstanceId,
taskId: taskId
}
});
},
// 设置列
handleSetColumn() {
this.$router.push({
name: 'settingColumn',
params: {
name: this.$parent.label,
workType: 'handled_list'
}
});
}
}
};
</script>
<template>
<sw-account @user-change="handleUserChange"></sw-account>
</template>
<script>
export default {
name: 'accountSetting',
methods: {
handleUserChange(userInfo) {
this.$store.state.userInfo.RealName = userInfo.realName;
}
}
};
</script>
<template>
<sw-interface
:theme="theme"
@theme-change="handleThemeChange"></sw-interface>
</template>
<script>
import { changeTheme } from '@/utils/global';
export default {
name: 'interface',
computed: {
theme() {
return this.$store.state.theme;
}
},
methods: {
handleThemeChange(form) {
changeTheme(form);
}
}
};
</script>
<template>
<sw-sql-naming :authories="userAuthories"></sw-sql-naming>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'SNamingManagement',
mixins: [permission]
};
</script>
<template>
<sw-district :authories="userAuthories"></sw-district>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'adminDivision',
mixins: [permission]
};
</script>
<template>
<sw-authority
:authories="userAuthories"
:sysName="sysName"
:childSysId="childSysId">
</sw-authority>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'AuthorityManage',
mixins: [permission],
data() {
return {
sysName: '', // 系统名称
childSysId: '' // 系统ID
};
},
created() {
this._initData();
},
methods: {
// 初始化数据
_initData() { // 平台tab传值替换
this.sysName = this.$route.params.sysName;
this.childSysId = this.$route.params.childSysId;
}
}
};
</script>
<template>
<sw-business-definition :authories="userAuthories" @check-expression="checkExpresion">
</sw-business-definition>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'BusinessDefManager',
mixins: [permission],
methods: {
checkExpresion(node) {
this.$router.push({
name: 'checkExpression'
});
}
}
};
</script>
<template>
<sw-check-expression
:authories="userAuthories"
:business-node="businessNode"></sw-check-expression>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'CheckExpression',
mixins: [permission],
data() {
return {
businessNode: null
};
},
methods: {
// 初始和改变时处理拿到的页面传参
handleRouteParam() {
this.businessNode = this.$route.params.currentNode;
}
}
};
</script>
<template>
<sw-child-system
:authories="userAuthories"
@check-system="handleCheckSystem"
@modules-manage="handleModulesManage"
@funtion-modules-manage="handleChildFunctions"
@authority-manage="handleChildAuthority"></sw-child-system>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'ChildSystemManage',
mixins: [permission],
methods: {
handleCheckSystem(system) {
let url = system.visitUrl;
if (!url) url = location.protocol + '//' + location.host + location.pathname + (location.hash ? '#/' : '') + '?sysCode=' + system.sysCode;
window.open(url);
},
/**
* 子系统模块管理
*/
handleModulesManage(childSysId, sysName) {
this.$router.push({
name: 'modulesManage',
params: {
childSysId,
sysName
}
});
},
/**
* 子系统功能点管理
*/
handleChildFunctions(childSysId, sysName) {
this.$router.push({
name: 'functionModulesManage',
params: {
childSysId,
sysName
}
});
},
/**
* 子系统权限管理
*/
handleChildAuthority(childSysId, sysName) {
this.$router.push({
name: 'authorityManage',
params: {
childSysId,
sysName
}
});
}
}
};
</script>
<template>
<sw-code-dictionary :authories="userAuthories"></sw-code-dictionary>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'CodeDictionary',
mixins: [permission]
};
</script>
<template>
<sw-company :authories="userAuthories"></sw-company>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'compInformation',
mixins: [permission]
};
</script>
<template>
<sw-edit-process
:url="url"
@before-load="init"
@loaded="handleFrameLoaded">
<!-- <error-page slot="error"></error-page> -->
<div slot="error" class="color-danger">加载错误了!</div>
</sw-edit-process>
</template>
<script>
export default {
name: 'EditProcess',
data() {
return {
url: ''
};
},
watch: {
'$route.params'() {
this.init();
}
},
created() {
this.init();
},
methods: {
init() {
this.$Progress.start();
this.$Progress.increase(10);
this.url = this.$route.params.url;
},
handleFrameLoaded() {
this.$Progress.finish();
}
}
};
</script>
<template>
<sw-environment :authories="userAuthories"></sw-environment>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'EnvironmentConfig',
mixins: [permission]
};
</script>
<template>
<sw-framework :authories="userAuthories"></sw-framework>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'FrameworkManage',
mixins: [permission]
};
</script>
<template>
<sw-function-modules
:authories="userAuthories"
:childInfo="childInfo"
:platformInfo="platformInfo"
/>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'FunctoinModulesManage',
mixins: [permission],
computed: {
platformInfo() {
return this.$store.state.platformInfo;
}
},
data() {
return {
childInfo: null // 子系统信息
};
},
created() {
this._initData();
},
methods: {
// 初始化数据
_initData() {
if (this.$route.params.childSysId && this.$route.params.sysName) {
this.childInfo = {
systemId: this.$route.params.childSysId,
name: this.$route.params.sysName
};
} else {
this.childInfo = null;
}
}
}
};
</script>
<template>
<sw-holiday :authories="userAuthories"></sw-holiday>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'HolidayManagement',
mixins: [permission]
};
</script>
<template>
<sw-modules
:authories="userAuthories"
:childInfo="childInfo"
:platformInfo="platformInfo"
@check-icon="handleCheckMoreIcon">
<function-modules slot="modulesList"></function-modules>
</sw-modules>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
import FunctionModules from '@/views/common/functionModule';
export default {
name: 'ModulesManage',
mixins: [permission],
components: {
FunctionModules
},
computed: {
platformInfo() {
return this.$store.state.platformInfo;
}
},
data() {
return {
childInfo: null // 子系统信息
};
},
created() {
this._initData();
},
methods: {
_initData() {
if (this.$route.params.childSysId && this.$route.params.sysName) {
this.childInfo = {
systemId: this.$route.params.childSysId,
name: this.$route.params.sysName
};
} else {
this.childInfo = null;
}
},
handleCheckMoreIcon() {
this.$router.push({
name: 'iconView'
});
}
}
};
</script>
<template>
<sw-common-words :authories="userAuthories"></sw-common-words>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'myComWord',
mixins: [permission]
};
</script>
<template>
<sw-operation-log :authories="userAuthories"></sw-operation-log>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'operationLog',
mixins: [permission]
};
</script>
<template>
<sw-number-formula :authories="userAuthories"></sw-number-formula>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'snBuilder',
mixins: [permission]
};
</script>
<template>
<sw-stamp :authories="userAuthories"></sw-stamp>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'StampdefManage',
mixins: [permission]
};
</script>
<template>
<sw-task-scheduling :authories="userAuthories"></sw-task-scheduling>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
export default {
name: 'taskScheduling',
mixins: [permission]
};
</script>
<template>
<sw-workflow
:authories="userAuthories"
@create-workflow="handleCreateProcess"
@edit-workflow="handleEditProcess"
></sw-workflow>
</template>
<script>
import permission from '@/utils/mixins/systemSetup/permission';
import { baseUrl } from '@config/http.config';
export default {
name: 'WorkflowDesign',
mixins: [permission],
methods: {
handleCreateProcess(modelId) {
const url = baseUrl + '/modeler.html?modelId=' + modelId;
this.$router.push({
name: 'appIframe',
params: {
url
}
});
},
handleEditProcess(modelId) {
const url = baseUrl + '/modeler.html?modelId=' + modelId;
// let url = process.env.NODE_ENV === 'development' ? serviceUrl + '/smartweb2' : '.'
// url += '/workflow-designer/index.html?modelId=' + this.currentNode.id
this.$router.push({
name: 'editProcess',
params: {
url
}
});
}
}
};
</script>
module.exports = {
env: {
mocha: true
}
};
import { expect } from 'chai';
import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message';
const wrapper = shallowMount(HelloWorld, {
propsData: { msg }
});
expect(wrapper.text()).to.include(msg);
});
});
const webpack = require('webpack');
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir);
}
const pages = {
app: {
// page 的入口
entry: 'src/main.js',
// 模板来源
template: 'public/index.html',
// 在 dist/index.html 的输出
filename: 'index.html',
// 在这个页面中包含的块,默认情况下会包含
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-commons', 'element-ui', 'app']
},
form: {
entry: 'form/main.js',
template: 'form/form.html',
filename: 'form.html',
chunks: ['chunk-vendors', 'chunk-commons', 'element-ui', 'smart-form', 'form']
}
};
module.exports = {
publicPath: './',
runtimeCompiler: true,
devServer: {
host: '0.0.0.0',
port: '8022'
},
productionSourceMap: false,
pages: pages,
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
const configs = {};
configs.optimization = {
splitChunks: {
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // 只打包初始时依赖的第三方
},
elementUI: {
name: 'element-ui', // 单独将 elementUI 拆包
priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
test: /[\\/]node_modules[\\/]element-ui[\\/]/
},
smartForm: {
name: 'smart-form', // 单独将拆包
priority: 21, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
test: /[\\/]node_modules[\\/]smart-form[\\/]/
}/* ,
commons: {
name: 'chunk-comomns',
test: resolve('src/components'), // 可自定义拓展你的规则
minChunks: 2, // 最小共用次数
priority: 5,
reuseExistingChunk: true
} */
}
}
};
return configs;
}
},
chainWebpack: config => {
config.resolve.alias
.set('@', resolve('src'))
.set('@form', resolve('form'))
.set('@config', resolve('config'));
const arr = ['app', 'form'];
// TODO: Remove this workaround once https://github.com/vuejs/vue-cli/issues/2463 is fixed
// Remove preload plugins for multi-page build to prevent infinite recursion
arr.forEach(page => {
config.plugins.delete(`preload-${page}`);
config.plugins.delete(`prefetch-${page}`);
});
config.plugin('ignore')
.use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/));
},
// IE兼容
transpileDependencies: ['element-ui/src', 'element-ui/packages']
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment