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>
This diff is collapsed.
<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);
}
}
};
This diff is collapsed.
@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
This diff is collapsed.
@import './tabs.scss';
@import './progress.scss';
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
$namespace: '';
$element-separator: '__';
$modifier-separator: '--';
$state-prefix: 'is-';
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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