chore: 同步Saber2.9.1

saber
ssc 4 years ago
parent cc792efe87
commit 6954b82584
  1. BIN
      .git.zip
  2. 2
      LICENSE
  3. 2
      README.md
  4. 4
      package.json
  5. 9
      public/cdn/avue/2.8.25/avue.min.js
  6. 1
      public/cdn/avue/2.8.25/index.css
  7. 9
      public/cdn/avue/2.9.5/avue.min.js
  8. 1
      public/cdn/avue/2.9.5/index.css
  9. 1
      public/cdn/element-ui/2.15.1/index.js
  10. 1
      public/cdn/element-ui/2.15.1/theme-chalk/index.css
  11. 1
      public/cdn/element-ui/2.15.6/index.js
  12. 0
      public/cdn/element-ui/2.15.6/theme-chalk/fonts/element-icons.ttf
  13. 0
      public/cdn/element-ui/2.15.6/theme-chalk/fonts/element-icons.woff
  14. 1
      public/cdn/element-ui/2.15.6/theme-chalk/index.css
  15. BIN
      public/cdn/nutflow/wf-design-base/fonts/bpmn.08b5f281.eot
  16. BIN
      public/cdn/nutflow/wf-design-base/fonts/bpmn.3c4c9f45.woff2
  17. BIN
      public/cdn/nutflow/wf-design-base/fonts/bpmn.acbc6cbd.woff
  18. BIN
      public/cdn/nutflow/wf-design-base/fonts/bpmn.f922519e.ttf
  19. BIN
      public/cdn/nutflow/wf-design-base/fonts/codicon.22349029.ttf
  20. BIN
      public/cdn/nutflow/wf-design-base/fonts/fontawesome-webfont.674f50d2.eot
  21. BIN
      public/cdn/nutflow/wf-design-base/fonts/fontawesome-webfont.af7ae505.woff2
  22. BIN
      public/cdn/nutflow/wf-design-base/fonts/fontawesome-webfont.b06871f2.ttf
  23. BIN
      public/cdn/nutflow/wf-design-base/fonts/fontawesome-webfont.fee66e71.woff
  24. 224
      public/cdn/nutflow/wf-design-base/img/bpmn.1381b44e.svg
  25. 2671
      public/cdn/nutflow/wf-design-base/img/fontawesome-webfont.912ec66d.svg
  26. 25
      public/cdn/nutflow/wf-design-base/index.umd.min.js
  27. BIN
      public/img/bg/bg.jpg
  28. BIN
      public/img/bg/img-logo.png
  29. 11
      public/index.html
  30. 3
      src/App.vue
  31. 13
      src/api/common.js
  32. 24
      src/api/flow/flow.js
  33. 123
      src/components/flow-design/main.vue
  34. 2
      src/config/website.js
  35. 2
      src/lang/en.js
  36. 2
      src/lang/zh.js
  37. 8
      src/main.js
  38. 1
      src/page/index/top/index.vue
  39. 23
      src/page/login/index.vue
  40. 1
      src/store/modules/user.js
  41. 7
      src/styles/login.scss
  42. 7
      src/util/date.js
  43. 24
      src/util/util.js
  44. 22
      src/views/base/region.vue
  45. 6
      src/views/desk/notice.vue
  46. 44
      src/views/flow/manager.vue
  47. 712
      src/views/flow/model.vue
  48. 2
      src/views/resource/attach.vue
  49. 2
      src/views/resource/oss.vue
  50. 2
      src/views/resource/sms.vue
  51. 9
      src/views/system/tenant.vue
  52. 41
      src/views/system/user.vue
  53. 6
      src/views/tool/datasource.vue
  54. 43
      src/views/wel/index.vue
  55. 46
      src/views/work/claim.vue
  56. 41
      src/views/work/done.vue
  57. 5
      src/views/work/process/leave/detail.vue
  58. 15
      src/views/work/process/leave/form.vue
  59. 5
      src/views/work/process/leave/handle.vue
  60. 41
      src/views/work/send.vue
  61. 39
      src/views/work/start.vue
  62. 46
      src/views/work/todo.vue

Binary file not shown.

@ -1,7 +1,7 @@
BladeX商业授权许可协议 BladeX商业授权许可协议
一、 知识产权: 一、 知识产权:
BladeX系列产品知识产权归上海布雷德网络科技独立所有 BladeX系列产品知识产权归上海布雷德科技有限公司独立所有
二、 许可: 二、 许可:
1. 在您完全接受并遵守本协议的基础上,本协议授予您使用BladeX的某些权利和非独占性许可。 1. 在您完全接受并遵守本协议的基础上,本协议授予您使用BladeX的某些权利和非独占性许可。

@ -1,5 +1,5 @@
## 版权声明 ## 版权声明
* BladeX是一个商业化软件,系列产品知识产权归**上海布雷德网络科技**独立所有 * BladeX是一个商业化软件,系列产品知识产权归**上海布雷德科技有限公司**独立所有
* 您一旦开始复制、下载、安装或者使用本产品,即被视为完全理解并接受本协议的各项条款 * 您一旦开始复制、下载、安装或者使用本产品,即被视为完全理解并接受本协议的各项条款
* 更多详情请看:[BladeX商业授权许可协议](/LICENSE) * 更多详情请看:[BladeX商业授权许可协议](/LICENSE)

@ -1,6 +1,6 @@
{ {
"name": "saber-admin", "name": "saber-admin",
"version": "2.9.0", "version": "2.9.1",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
@ -16,7 +16,7 @@
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"classlist-polyfill": "^1.2.0", "classlist-polyfill": "^1.2.0",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"element-ui": "^2.15.1", "element-ui": "^2.15.6",
"js-base64": "^2.5.1", "js-base64": "^2.5.1",
"js-cookie": "^2.2.0", "js-cookie": "^2.2.0",
"js-md5": "^0.7.3", "js-md5": "^0.7.3",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 130 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 123 KiB

@ -10,16 +10,16 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/element-ui/2.15.1/theme-chalk/index.css"> <link rel="stylesheet" href="<%= BASE_URL %>cdn/element-ui/2.15.6/theme-chalk/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/animate/3.5.2/animate.css"> <link rel="stylesheet" href="<%= BASE_URL %>cdn/animate/3.5.2/animate.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/index.css"> <link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/avue/iconfont.css"> <link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/avue/iconfont.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/saber/iconfont.css"> <link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/saber/iconfont.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/avue/2.8.25/index.css"> <link rel="stylesheet" href="<%= BASE_URL %>cdn/avue/2.9.5/index.css">
<script src="<%= BASE_URL %>cdn/xlsx/FileSaver.min.js"></script> <script src="<%= BASE_URL %>cdn/xlsx/FileSaver.min.js"></script>
<script src="<%= BASE_URL %>cdn/xlsx/xlsx.full.min.js"></script> <script src="<%= BASE_URL %>cdn/xlsx/xlsx.full.min.js"></script>
<link rel="icon" href="<%= BASE_URL %>favicon.png"> <link rel="icon" href="<%= BASE_URL %>favicon.png">
<title>Saber企业级开发平台</title> <title>Saber企业平台</title>
<style> <style>
html, html,
body, body,
@ -107,8 +107,9 @@
<script src="<%= BASE_URL %>cdn/vuex/3.1.1/vuex.min.js" charset="utf-8"></script> <script src="<%= BASE_URL %>cdn/vuex/3.1.1/vuex.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vue-router/3.0.1/vue-router.min.js" charset="utf-8"></script> <script src="<%= BASE_URL %>cdn/vue-router/3.0.1/vue-router.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/axios/1.0.0/axios.min.js" charset="utf-8"></script> <script src="<%= BASE_URL %>cdn/axios/1.0.0/axios.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/element-ui/2.15.1/index.js" charset="utf-8"></script> <script src="<%= BASE_URL %>cdn/element-ui/2.15.6/index.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/avue/2.8.25/avue.min.js" charset="utf-8"></script> <script src="<%= BASE_URL %>cdn/avue/2.9.5/avue.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/nutflow/wf-design-base/index.umd.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/avue-form-design/index.umd.min.js" charset="utf-8"></script> <script src="<%= BASE_URL %>cdn/avue-form-design/index.umd.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/wf-design/index.umd.min.js" charset="utf-8"></script> <script src="<%= BASE_URL %>cdn/wf-design/index.umd.min.js" charset="utf-8"></script>
</body> </body>

@ -24,4 +24,7 @@ export default {
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
} }
.avue--detail .el-col{
margin-bottom: 0;
}
</style> </style>

@ -0,0 +1,13 @@
import request from "@/router/axios";
/**
* 文件流返回
* @param url 接口地址
*/
export const exportBlob = (url) => {
return request({
url: url,
method: 'get',
responseType: 'blob'
})
}

@ -97,3 +97,27 @@ export const deleteProcessInstance = (params) => {
params params
}) })
} }
export const submitModel = (data) => {
return request({
url: '/api/blade-flow/model/submit',
method: 'post',
data
})
}
export const detail = (params) => {
return request({
url: '/api/blade-flow/model/detail',
method: 'get',
params
})
}
export const modelView = (params) => {
return request({
url: '/api/blade-flow/process/model-view',
method: 'get',
params
})
}

@ -0,0 +1,123 @@
<template>
<div>
<el-dialog v-if="isDialog"
:visible.sync="visible"
append-to-body
destroy-on-close
title="流程图展示"
width="70%"
custom-class="flow-design-dialog">
<wf-design-base ref="bpmn"
style="height: 60vh;"
:options="option"></wf-design-base>
</el-dialog>
<div v-else>
<wf-design-base v-if="visible"
ref="bpmn"
style="height: 60vh;"
:options="option"></wf-design-base>
</div>
</div>
</template>
<script>
import {modelView} from '@/api/flow/flow'
export default {
name: 'flowDesign',
props: {
isDialog: {
type: Boolean,
default: false
},
isDisplay: {
type: Boolean,
default: false
},
processInstanceId: String,
processDefinitionId: String,
},
data() {
return {
visible: false,
option: {
mode: 'view'
}
}
},
watch: {
isDisplay: {
handler(val) {
this.visible = val
},
immediate: true
},
visible: {
handler(val) {
this.$emit('update:is-display', val)
}
},
processInstanceId: {
handler(val) {
if (!val) return
this.getDetail({processInstanceId: this.processInstanceId})
},
immediate: true
},
processDefinitionId: {
handler(val) {
if (!val) return
this.getDetail({processDefinitionId: this.processDefinitionId})
},
immediate: true
}
},
methods: {
getDetail(params) {
modelView(params).then(res => {
const data = res.data.data
const {xml, flow} = data
this.$set(this.option, 'xml', xml)
if (flow) {
const flows = []
flow.forEach(f => {
let {endTime} = f
const ff = {
id: f.historyActivityId,
class: (!endTime && f.historyActivityType !== 'candidate') ? 'nodePrimary' : ''
}
if (f.historyActivityType === 'sequenceFlow') ff.class = 'lineWarn'
else if (!ff.class && f.historyActivityType !== 'candidate') ff.class = 'nodeSuccess'
const index = flows.findIndex(fl => fl.id === f.historyActivityId)
if (index !== -1) flows.splice(index, 1, ff)
else flows.push(ff)
})
this.$set(this.option, 'flows', flows)
}
})
}
}
}
</script>
<style lang="scss">
.flow-design-dialog {
display: flex;
flex-direction: column;
margin: 0 !important;
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -40%);
max-height: calc(100% - 30px);
max-width: calc(100% - 30px);
.el-dialog__body {
flex: 1;
overflow: auto;
}
}
</style>

@ -42,8 +42,6 @@ export default {
}, },
// 第三方系统授权地址 // 第三方系统授权地址
authUrl: 'http://localhost/blade-auth/oauth/render', authUrl: 'http://localhost/blade-auth/oauth/render',
// 流程设计器地址
flowDesignUrl: 'http://localhost:9999',
// 报表设计器地址(cloud端口为8108,boot端口为80) // 报表设计器地址(cloud端口为8108,boot端口为80)
reportUrl: 'http://localhost:8108/ureport', reportUrl: 'http://localhost:8108/ureport',
} }

@ -67,7 +67,7 @@ export default {
}, },
login: { login: {
title: 'Login ', title: 'Login ',
info: 'Enterprise Development Platform', info: 'BladeX Development Platform',
tenantId: 'Please input tenantId', tenantId: 'Please input tenantId',
username: 'Please input username', username: 'Please input username',
password: 'Please input a password', password: 'Please input a password',

@ -1,6 +1,6 @@
export default { export default {
tip: '提示', tip: '提示',
title: 'Saber企业级开发平台', title: 'Saber企业平台',
logoutTip: '退出系统, 是否继续?', logoutTip: '退出系统, 是否继续?',
submitText: '确定', submitText: '确定',
cancelText: '取消', cancelText: '取消',

@ -19,9 +19,13 @@ import './styles/common.scss';
import basicBlock from './components/basic-block/main'; import basicBlock from './components/basic-block/main';
import basicContainer from './components/basic-container/main'; import basicContainer from './components/basic-container/main';
import thirdRegister from './components/third-register/main'; import thirdRegister from './components/third-register/main';
import flowDesign from './components/flow-design/main';
import avueUeditor from 'avue-plugin-ueditor'; import avueUeditor from 'avue-plugin-ueditor';
import website from '@/config/website'; import website from '@/config/website';
import crudCommon from '@/mixins/crud'; import crudCommon from '@/mixins/crud';
// 业务组件
import tenantPackage from './views/system/tenantpackage';
// 注册全局crud驱动 // 注册全局crud驱动
window.$crudCommon = crudCommon; window.$crudCommon = crudCommon;
// 加载Vue拓展 // 加载Vue拓展
@ -41,10 +45,14 @@ Vue.component('basicContainer', basicContainer);
Vue.component('basicBlock', basicBlock); Vue.component('basicBlock', basicBlock);
Vue.component('thirdRegister', thirdRegister); Vue.component('thirdRegister', thirdRegister);
Vue.use(avueUeditor); Vue.use(avueUeditor);
Vue.component('flowDesign', flowDesign);
Vue.component('tenantPackage', tenantPackage);
// 加载相关url地址 // 加载相关url地址
Object.keys(urls).forEach(key => { Object.keys(urls).forEach(key => {
Vue.prototype[key] = urls[key]; Vue.prototype[key] = urls[key];
}); });
// 加载NutFlow
Vue.use(window.WfDesignBase);
// 加载website // 加载website
Vue.prototype.website = website; Vue.prototype.website = website;
// 动态加载阿里云字体库 // 动态加载阿里云字体库

@ -232,6 +232,7 @@
submitSwitch (form, done) { submitSwitch (form, done) {
this.$store.dispatch("refreshToken", form).then(() => { this.$store.dispatch("refreshToken", form).then(() => {
this.userBox = false; this.userBox = false;
this.$router.push({path: "/"});
}) })
done(); done();
}, },

@ -8,8 +8,29 @@
<div class="login-time"> <div class="login-time">
{{time}} {{time}}
</div> </div>
<img class="img" src="/img/logo.png" alt="">
<p class="title">{{ $t('login.info') }}</p> <p class="title">{{ $t('login.info') }}</p>
<div style="font-size: 15px">
<span>----------------------------------------------</span>
<br>
<span>管理租户编号000000</span>
<br>
<span>超级管理员账号: admin / admin</span>
<br>
<span>人事账号: hr / hr</span>
<br>
<span>经理账号: manager / manager</span>
<br>
<span>老板账号: boss / boss</span>
<br>
<span>----------------------------------------------</span>
<br>
<span>普通租户编号详见租户管理模块</span>
<br>
<span>租户管理员账号: admin / admin</span>
<br>
<span>----------------------------------------------</span>
</div>
<!--<img class="img" src="/img/logo.png" alt="">-->
</div> </div>
<div class="login-border"> <div class="login-border">
<div class="login-main"> <div class="login-main">

@ -125,6 +125,7 @@ const user = {
const data = res.data; const data = res.data;
commit('SET_TOKEN', data.access_token); commit('SET_TOKEN', data.access_token);
commit('SET_REFRESH_TOKEN', data.refresh_token); commit('SET_REFRESH_TOKEN', data.refresh_token);
commit('SET_USER_INFO', data);
resolve(); resolve();
}).catch(error => { }).catch(error => {
reject(error) reject(error)

@ -32,7 +32,7 @@
border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
background-color: #409EFF; background-color: #8b9aac;
color: #fff; color: #fff;
float: left; float: left;
width: 50%; width: 50%;
@ -56,12 +56,11 @@
} }
.login-left .title { .login-left .title {
margin-top: 60px;
text-align: center; text-align: center;
color: #fff; color: #fff;
font-weight: 300; font-weight: bold;
font-size: 30px;
letter-spacing: 2px; letter-spacing: 2px;
font-size: 25px;
} }
.login-border { .login-border {

@ -49,3 +49,10 @@ export function dateFormat(date, format) {
return ''; return '';
} }
/**
* 当前时间戳
*/
export function dateNow() {
return dateFormat(new Date(), "yyyyMMddhhmmss");
}

@ -365,3 +365,27 @@ export const downloadFileBase64 = (path, name) => {
} }
}; };
} }
/**
* 下载excel
* @param {blob} fileArrayBuffer 文件流
* @param {String} filename 文件名称
*/
export const downloadXls = (fileArrayBuffer, filename) => {
let data = new Blob([fileArrayBuffer], {type: 'application/vnd.ms-excel,charset=utf-8'});
if (typeof window.chrome !== 'undefined') {
// Chrome
var link = document.createElement('a');
link.href = window.URL.createObjectURL(data);
link.download = filename;
link.click();
} else if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE
var blob = new Blob([data], {type: 'application/force-download'});
window.navigator.msSaveBlob(blob, filename);
} else {
// Firefox
var file = new File([data], filename, {type: 'application/force-download'});
window.open(URL.createObjectURL(file));
}
}

@ -52,9 +52,14 @@
<script> <script>
import {getLazyTree, getDetail, submit, remove} from "@/api/base/region"; import {getLazyTree, getDetail, submit, remove} from "@/api/base/region";
import {exportBlob} from "@/api/common";
import {mapGetters} from "vuex"; import {mapGetters} from "vuex";
import {validatenull} from "@/util/validate"; import {validatenull} from "@/util/validate";
import {downloadXls} from "@/util/util";
import {dateNow} from "@/util/date";
import {getToken} from "@/util/auth"; import {getToken} from "@/util/auth";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default { export default {
data() { data() {
@ -239,7 +244,7 @@
label: 'name', label: 'name',
value: 'code' value: 'code'
}, },
cascaderItem: ['city', 'district'], cascader: ['city'],
dicUrl: '/api/blade-system/region/select', dicUrl: '/api/blade-system/region/select',
span: 24, span: 24,
}, },
@ -251,8 +256,9 @@
label: 'name', label: 'name',
value: 'code' value: 'code'
}, },
cascader: ['district'],
dicFlag: false, dicFlag: false,
dicUrl: '/api/blade-system/region/select?code={{key}}', dicUrl: '/api/blade-system/region/select?code={{province}}',
span: 24, span: 24,
}, },
{ {
@ -264,7 +270,7 @@
value: 'code' value: 'code'
}, },
dicFlag: false, dicFlag: false,
dicUrl: '/api/blade-system/region/select?code={{key}}', dicUrl: '/api/blade-system/region/select?code={{city}}',
span: 24, span: 24,
} }
] ]
@ -392,11 +398,17 @@
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(() => { }).then(() => {
window.open(`/api/blade-system/region/export-region?${this.website.tokenHeader}=${getToken()}`); NProgress.start();
exportBlob(`/api/blade-system/region/export-region?${this.website.tokenHeader}=${getToken()}`).then(res => {
downloadXls(res.data, `行政区划数据${dateNow()}.xlsx`);
NProgress.done();
})
}); });
}, },
handleTemplate() { handleTemplate() {
window.open(`/api/blade-system/region/export-template?${this.website.tokenHeader}=${getToken()}`); exportBlob(`/api/blade-system/region/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
downloadXls(res.data, "行政区划模板.xlsx");
})
}, },
} }
}; };

@ -267,18 +267,18 @@
const {releaseTimeRange} = this.query; const {releaseTimeRange} = this.query;
let values = { let values = {
...params, ...params,
...this.query
}; };
if (releaseTimeRange) { if (releaseTimeRange) {
values = { values = {
...params, ...values,
releaseTime_datege: releaseTimeRange[0], releaseTime_datege: releaseTimeRange[0],
releaseTime_datelt: releaseTimeRange[1], releaseTime_datelt: releaseTimeRange[1],
...this.query
}; };
values.releaseTimeRange = null; values.releaseTimeRange = null;
} }
this.loading = true; this.loading = true;
getList(page.currentPage, page.pageSize, Object.assign(values, this.query)).then(res => { getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data; const data = res.data.data;
this.page.total = data.total; this.page.total = data.total;
this.data = data.records; this.data = data.records;

@ -23,23 +23,20 @@
<template slot-scope="scope" slot="menu"> <template slot-scope="scope" slot="menu">
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-refresh"
v-if="permission.flow_manager_state" v-if="permission.flow_manager_state"
plain
class="none-border"
@click.stop="handleState(scope.row,scope.index)">变更状态 @click.stop="handleState(scope.row,scope.index)">变更状态
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-search"
v-if="permission.flow_manager_image" v-if="permission.flow_manager_image"
plain
class="none-border"
@click.stop="handleImage(scope.row,scope.index)">流程图 @click.stop="handleImage(scope.row,scope.index)">流程图
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-delete"
v-if="permission.flow_manager_remove" v-if="permission.flow_manager_remove"
plain
class="none-border"
@click.stop="handleSlotDelete(scope.row,scope.index)">删除 @click.stop="handleSlotDelete(scope.row,scope.index)">删除
</el-button> </el-button>
</template> </template>
@ -60,27 +57,7 @@
<el-tag>{{row.categoryName}}</el-tag> <el-tag>{{row.categoryName}}</el-tag>
</template> </template>
</avue-crud> </avue-crud>
<el-dialog title="流程图" <flow-design is-dialog :is-display.sync="flowBox" :process-definition-id="processDefinitionId"></flow-design>
append-to-body
:visible.sync="flowBox"
:fullscreen="true">
<iframe
:src=flowUrl
width="100%"
height="700"
title="流程图"
frameBorder="no"
border="0"
marginWidth="0"
marginHeight="0"
scrolling="no"
allowTransparency="yes">
</iframe>
<span slot="footer"
class="dialog-footer">
<el-button @click="flowBox = false"> </el-button>
</span>
</el-dialog>
<el-dialog title="流程变更" <el-dialog title="流程变更"
append-to-body append-to-body
:visible.sync="stateBox" :visible.sync="stateBox"
@ -128,8 +105,8 @@
currentPage: 1, currentPage: 1,
total: 0 total: 0
}, },
processDefinitionId: '',
flowBox: false, flowBox: false,
flowUrl: '',
stateBox: false, stateBox: false,
flowState: '', flowState: '',
stateOptions: [{ stateOptions: [{
@ -153,7 +130,7 @@
viewBtn: false, viewBtn: false,
delBtn: false, delBtn: false,
dialogWidth: 900, dialogWidth: 900,
menuWidth: 150, menuWidth: 250,
dialogClickModal: false, dialogClickModal: false,
column: [ column: [
{ {
@ -329,7 +306,7 @@
}) })
}, },
handleImage(row) { handleImage(row) {
this.flowUrl = `/api/blade-flow/process/resource-view?processDefinitionId=${row.id}`; this.processDefinitionId = row.id;
this.flowBox = true; this.flowBox = true;
}, },
currentChange(currentPage) { currentChange(currentPage) {
@ -359,10 +336,3 @@
} }
}; };
</script> </script>
<style>
.none-border {
border: 0;
background-color: transparent !important;
}
</style>

@ -15,388 +15,468 @@
@on-load="onLoad"> @on-load="onLoad">
<template slot="menuLeft"> <template slot="menuLeft">
<el-button type="primary" <el-button type="primary"
size="small" size="mini"
icon="el-icon-circle-plus" icon="el-icon-circle-plus"
v-if="permission.flow_model_create" v-if="permission.flow_model_create"
plain plain
@click="handleCreate"> @click="handleCreate">
</el-button> </el-button>
<el-button type="danger" <el-button type="danger"
size="small" size="mini"
icon="el-icon-delete" icon="el-icon-delete"
v-if="permission.flow_model_delete" v-if="permission.flow_model_delete"
plain plain
@click="handleDelete"> @click="handleDelete">
</el-button> </el-button>
</template> </template>
<template slot-scope="scope" slot="menu"> <template slot-scope="scope"
slot="menu">
<el-button type="text" <el-button type="text"
size="small" size="mini"
icon="el-icon-setting"
v-if="permission.flow_model_update" v-if="permission.flow_model_update"
plain
class="none-border"
@click.stop="handleUpdate(scope.row,scope.index)">配置 @click.stop="handleUpdate(scope.row,scope.index)">配置
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="mini"
icon="el-icon-upload2"
v-if="permission.flow_model_deploy" v-if="permission.flow_model_deploy"
plain
class="none-border"
@click.stop="handleDeploy(scope.row,scope.index)">部署 @click.stop="handleDeploy(scope.row,scope.index)">部署
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="mini"
v-if="permission.flow_model_download" icon="el-icon-delete"
plain
class="none-border"
@click.stop="handleDownload(scope.row,scope.index)">下载
</el-button>
<el-button type="text"
size="small"
v-if="permission.flow_model_delete" v-if="permission.flow_model_delete"
plain
class="none-border"
@click.stop="handleSlotDelete(scope.row,scope.index)">删除 @click.stop="handleSlotDelete(scope.row,scope.index)">删除
</el-button> </el-button>
</template> </template>
<template slot-scope="{row}" <template slot-scope="{row}"
slot="version"> slot="version">
<el-tag>v{{row.version}}</el-tag> <el-tag>v{{ row.version }}</el-tag>
</template> </template>
</avue-crud> </avue-crud>
<el-dialog title="流程配置" <el-dialog title="流程配置"
append-to-body append-to-body
destroy-on-close
:visible.sync="flowBox" :visible.sync="flowBox"
:fullscreen="true"> :close-on-press-escape="false"
<iframe :fullscreen="true"
:src=flowUrl :before-close="handleNutflowClose"
width="100%" custom-class="wf-dialog">
height="700" <wf-design-base v-if="nutflowOption.step === 1"
title="流程设计器" class="animated fadeIn"
frameBorder="no" style="height: calc(100vh - 108px);"
border="0" ref="wf-design"
marginWidth="0" :options="nutflowOption.step1"></wf-design-base>
marginHeight="0" <wf-design-base v-if="nutflowOption.step === 2"
scrolling="no" class="animated fadeIn"
allowTransparency="yes"> style="height: calc(100vh - 108px);"
</iframe> ref="wf-design-view"
:options="nutflowOption.step2"></wf-design-base>
<span slot="footer" <span slot="footer"
class="dialog-footer"> class="avue-dialog__footer">
<el-button @click="flowBox = false"> </el-button> <el-button size="small"
<el-button type="primary" @click="handleRefresh"> </el-button> @click="handleNutflowClose(() => {}, true)"> </el-button>
<el-button v-if="nutflowOption.step === 1"
size="small"
type="success"
@click="handleStep(1)"> </el-button>
<el-button v-if="nutflowOption.step === 2"
size="small"
type="success"
@click="handleStep(-1)"> </el-button>
<el-button v-if="nutflowOption.step === 2"
size="small"
type="primary"
@click="handleSubmitModel"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="流程部署" <el-dialog title="流程部署"
append-to-body append-to-body
:visible.sync="deployBox" :visible.sync="deployBox"
width="20%"> width="20%">
<avue-form ref="form" :option="optionDeploy" v-model="form" @submit="handleSubmit"/> <avue-form ref="form"
:option="optionDeploy"
v-model="form"
@submit="handleSubmit"/>
<span slot="footer" <span slot="footer"
class="dialog-footer"> class="dialog-footer">
<el-button @click="deployBox = false"> </el-button> <el-button @click="deployBox = false"> </el-button>
<el-button type="primary" @click="handleDoDeploy" :loading="deployLoading"> </el-button> <el-button type="primary"
@click="handleDoDeploy"
:loading="deployLoading"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</basic-container> </basic-container>
</template> </template>
<script> <script>
import {mapGetters} from "vuex"; import {mapGetters} from "vuex";
import website from '@/config/website'; import {modelList, removeModel, deployModel, submitModel, detail} from "@/api/flow/flow";
import {modelList, removeModel, deployModel} from "@/api/flow/flow"; import {flowCategory} from "@/util/flow";
import {flowCategory} from "@/util/flow";
export default { export default {
data() { data() {
return { return {
form: {}, form: {},
optionDeploy: { optionDeploy: {
menuBtn: false, menuBtn: false,
column: [ column: [
{ {
label: "流程类型", label: "流程类型",
type: "select", type: "select",
dicUrl: "/api/blade-system/dict/dictionary?code=flow", dicUrl: "/api/blade-system/dict/dictionary?code=flow",
props: { props: {
label: "dictValue", label: "dictValue",
value: "dictKey" value: "dictKey"
},
dataType: "number",
slot: true,
prop: "categoryValue",
search: true,
span: 24,
rules: [{
required: true,
message: "请选择流程类型",
trigger: "blur"
}]
},
{
label: "流程模式",
prop: "flowMode",
type: "radio",
dicData: [
{
label: "通用流程",
value: 1
},
{
label: "定制流程",
value: 2
}
],
value: 1,
span: 24,
rules: [
{
required: true,
message: '请选择流程模式',
trigger: 'blur'
}
],
}, },
{ dataType: "number",
label: "所属租户", slot: true,
prop: "tenantId", prop: "categoryValue",
type: "tree", search: true,
multiple: true, span: 24,
dicUrl: "/api/blade-system/tenant/select", rules: [{
props: { required: true,
label: "tenantName", message: "请选择流程类型",
value: "tenantId" trigger: "blur"
}]
},
{
label: "流程模式",
prop: "flowMode",
type: "radio",
dicData: [
{
label: "通用流程",
value: 1
}, },
display: false, {
span: 24, label: "定制流程",
rules: [ value: 2
{ }
required: true, ],
message: '请选择所属租户', value: 1,
trigger: 'blur' span: 24,
} rules: [
], {
}, required: true,
], message: '请选择流程模式',
}, trigger: 'blur'
selectionId: '', }
selectionList: [], ],
query: {}, },
loading: true, {
deployLoading: false, label: "所属租户",
page: { prop: "tenantId",
pageSize: 10, type: "tree",
currentPage: 1, multiple: true,
total: 0 dicUrl: "/api/blade-system/tenant/select",
}, props: {
deployBox: false, label: "tenantName",
flowBox: false, value: "tenantId"
flowUrl: '',
option: {
height: 'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
selection: true,
editBtn: false,
addBtn: false,
viewBtn: false,
delBtn: false,
dialogWidth: 900,
menuWidth: 150,
dialogClickModal: false,
column: [
{
label: '模型主键',
prop: 'id',
},
{
label: '模型标识',
prop: 'modelKey',
search: true,
width: 150,
},
{
label: '模型名称',
prop: 'name',
search: true,
width: 150,
},
{
label: '流程版本',
prop: 'version',
slot: true,
width: 80,
},
{
label: '创建时间',
prop: 'created',
width: 165,
},
{
label: '更新时间',
prop: 'lastUpdated',
width: 165,
}, },
] display: false,
span: 24,
rules: [
{
required: true,
message: '请选择所属租户',
trigger: 'blur'
}
],
},
],
},
selectionId: '',
selectionList: [],
query: {},
loading: true,
deployLoading: false,
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
deployBox: false,
flowBox: false,
option: {
height: 'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
selection: true,
editBtn: false,
addBtn: false,
viewBtn: false,
delBtn: false,
dialogWidth: 900,
menuWidth: 200,
dialogClickModal: false,
size: 'mini',
searchSize: 'mini',
column: [
{
label: '模型主键',
prop: 'id',
},
{
label: '模型标识',
prop: 'modelKey',
search: true,
overHidden: true
},
{
label: '模型名称',
prop: 'name',
search: true,
overHidden: true
},
{
label: '流程版本',
prop: 'version',
slot: true,
overHidden: true
},
{
label: '创建时间',
prop: 'created',
overHidden: true
},
{
label: '更新时间',
prop: 'lastUpdated',
overHidden: true
},
]
},
data: [],
nutflowOption: {
process: {},
step: 1,
step1: {
toolbar: ['open', 'create', 'fit', 'zoom-in', 'zoom-out', 'undo', 'redo', 'import', 'preview'],
}, },
data: [] step2: {
}; mode: 'view',
}, simulation: true,
watch: { minimap: true,
'form.flowMode'() { }
this.$refs.form.option.column.filter(item => {
if (item.prop === "tenantId") {
item.display = this.form.flowMode === 2;
}
});
} }
}, };
computed: { },
...mapGetters(["permission"]), watch: {
ids() { 'form.flowMode'() {
let ids = []; this.$refs.form.option.column.filter(item => {
this.selectionList.forEach(ele => { if (item.prop === "tenantId") {
ids.push(ele.id); item.display = this.form.flowMode === 2;
}); }
return ids.join(","); });
}
},
computed: {
...mapGetters(["permission"]),
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
handleSubmitModel() {
const registry = this.$refs['wf-design-view'].getElementRegistry().getAll()
const {businessObject} = registry[0]
const {id, name, documentation} = businessObject
const description = (documentation && documentation.length > 0) ? documentation[0].text : null
const params = {
...this.nutflowOption.process,
modelKey: id,
name,
description,
modelEditorXml: this.nutflowOption.process.xml
} }
submitModel(params).then(() => {
this.$message.success("操作成功")
this.handleNutflowClose()
this.onLoad(this.page, this.query)
})
}, },
methods: { handleStep(step) {
handleSubmit(form, done) { if (step === 1) { //
this.deployLoading = true; this.$refs['wf-design'].getData('xml').then(data => {
deployModel({ this.$set(this.nutflowOption.step1, 'xml', data)
modelId: this.selectionId, this.$set(this.nutflowOption.step2, 'xml', data)
category: flowCategory(form.categoryValue), this.$set(this.nutflowOption.process, 'xml', data)
tenantIds: form.tenantId.join(",") this.$set(this.nutflowOption, 'step', 2)
}).then(res => {
const data = res.data;
if (data.success) {
this.$message({
type: "success",
message: data.msg
});
done();
this.$refs.form.resetForm();
this.deployBox = false;
this.deployLoading = false;
} else {
done();
this.deployLoading = false;
this.$message({
type: "warn",
message: data.msg
});
}
}) })
}, } else this.$set(this.nutflowOption, 'step', 1)
searchReset() { },
this.query = {}; handleNutflowClose(done, flag) {
this.onLoad(this.page); const initOption = {
}, process: {},
searchChange(params, done) { step: 1,
this.query = params; step1: {
this.page.currentPage = 1; toolbar: ['open', 'create', 'fit', 'zoom-in', 'zoom-out', 'undo', 'redo', 'import', 'preview'],
this.onLoad(this.page, params); },
done(); step2: {
}, mode: 'view',
selectionChange(list) { simulation: true,
this.selectionList = list; minimap: true,
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
} }
this.$confirm("确定将选择数据删除?", { }
confirmButtonText: "确定", if (done || flag) {
cancelButtonText: "取消", this.$confirm('确定要关闭吗?关闭未保存的修改都会丢失。', '警告', {
type: "warning" type: 'warning'
}).then(() => {
this.$set(this, 'nutflowOption', initOption)
if (typeof done == 'function') done()
this.flowBox = false
}).catch(() => {
}) })
.then(() => { } else {
return removeModel(this.ids); this.$set(this, 'nutflowOption', initOption)
}) this.flowBox = false
.then(() => { }
this.$message({ },
type: "success", handleSubmit(form, done) {
message: "操作成功!" this.deployLoading = true;
}); deployModel({
this.$refs.crud.toggleSelection(); modelId: this.selectionId,
this.onLoad(this.page); category: flowCategory(form.categoryValue),
tenantIds: form.tenantId.join(",")
}).then(res => {
const data = res.data;
if (data.success) {
this.$message({
type: "success",
message: data.msg
}); });
}, done();
handleCreate() { this.$refs.form.resetForm();
this.flowUrl = `${website.flowDesignUrl}/index.html`; this.deployBox = false;
this.flowBox = true; this.deployLoading = false;
}, } else {
handleUpdate(row) { done();
this.flowUrl = `${website.flowDesignUrl}/index.html#/editor/${row.id}`; this.deployLoading = false;
this.$message({
type: "warn",
message: data.msg
});
}
})
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return removeModel(this.ids);
})
.then(() => {
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
this.onLoad(this.page);
});
},
handleCreate() {
this.flowBox = true;
},
handleUpdate(row) {
detail({id: row.id}).then(res => {
const data = res.data.data
const {modelEditorXml} = data
this.$set(this.nutflowOption.step1, 'xml', modelEditorXml)
this.$set(this.nutflowOption, 'process', data)
this.flowBox = true; this.flowBox = true;
}, })
handleDeploy(row) { },
this.deployBox = true; handleDeploy(row) {
this.selectionId = row.id; this.deployBox = true;
}, this.selectionId = row.id;
handleDoDeploy() { },
this.$refs.form.submit(); handleDoDeploy() {
}, this.$refs.form.submit();
handleDownload(row) { },
window.open(`${website.flowDesignUrl}/app/rest/models/${row.id}/bpmn20`); handleSlotDelete(row) {
}, this.$confirm("确定将选择数据删除?", {
handleSlotDelete(row) { confirmButtonText: "确定",
this.$confirm("确定将选择数据删除?", { cancelButtonText: "取消",
confirmButtonText: "确定", type: "warning"
cancelButtonText: "取消", })
type: "warning" .then(() => {
return removeModel(row.id);
}) })
.then(() => { .then(() => {
return removeModel(row.id); this.$message({
}) type: "success",
.then(() => { message: "操作成功!"
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
this.onLoad(this.page);
}); });
}, this.$refs.crud.toggleSelection();
handleRefresh() { this.onLoad(this.page);
this.flowBox = false;
this.onLoad(this.page);
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoad(page, params = {}) {
this.loading = true;
modelList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
}); });
} },
currentChange(currentPage) {
this.page.currentPage = currentPage;
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoad(page, params = {}) {
this.loading = true;
modelList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
} }
}; }
};
</script> </script>
<style> <style lang="scss">
.none-border {
border: 0; .wf-dialog {
background-color: transparent !important; .el-dialog__body {
padding: 5px;
}
.avue-dialog__footer {
text-align: center;
} }
}
</style> </style>

@ -95,7 +95,7 @@
}, },
{ {
label: "附件域名", label: "附件域名",
prop: "domain", prop: "domainUrl",
search: true, search: true,
rules: [{ rules: [{
required: true, required: true,

@ -87,7 +87,7 @@
index: true, index: true,
viewBtn: true, viewBtn: true,
selection: true, selection: true,
menuWidth: 300, menuWidth: 350,
labelWidth: 100, labelWidth: 100,
dialogWidth: 880, dialogWidth: 880,
dialogClickModal: false, dialogClickModal: false,

@ -87,7 +87,7 @@
index: true, index: true,
viewBtn: true, viewBtn: true,
selection: true, selection: true,
menuWidth: 300, menuWidth: 350,
labelWidth: 100, labelWidth: 100,
dialogWidth: 880, dialogWidth: 880,
dialogClickModal: false, dialogClickModal: false,

@ -199,7 +199,7 @@ export default {
}, },
{ {
label: "绑定域名", label: "绑定域名",
prop: "domain", prop: "domainUrl",
span: 24, span: 24,
}, },
{ {
@ -273,12 +273,7 @@ export default {
props: { props: {
label: "packageName", label: "packageName",
value: "id" value: "id"
}, }
rules: [{
required: true,
message: "请选择产品包",
trigger: "blur"
}]
}, },
{ {
label: "菜单预览", label: "菜单预览",

@ -166,23 +166,28 @@
</template> </template>
<script> <script>
import { import {
getList, getList,
getUser, getUser,
getUserPlatform, getUserPlatform,
remove, remove,
update, update,
updatePlatform, updatePlatform,
add, add,
grant, grant,
resetPassword, unlock resetPassword, unlock
} from "@/api/system/user"; } from "@/api/system/user";
import {exportBlob} from "@/api/common";
import {getDeptTree, getDeptLazyTree} from "@/api/system/dept"; import {getDeptTree, getDeptLazyTree} from "@/api/system/dept";
import {getRoleTree} from "@/api/system/role"; import {getRoleTree} from "@/api/system/role";
import {getPostList} from "@/api/system/post"; import {getPostList} from "@/api/system/post";
import {mapGetters} from "vuex"; import {mapGetters} from "vuex";
import website from '@/config/website'; import website from '@/config/website';
import {getToken} from '@/util/auth'; import {getToken} from '@/util/auth';
import {downloadXls} from "@/util/util";
import {dateNow} from "@/util/date";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default { export default {
data() { data() {
@ -868,6 +873,10 @@ import {
this.platformBox = true; this.platformBox = true;
}, },
handleLock() { handleLock() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择账号解封?", { this.$confirm("确定将选择账号解封?", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
@ -898,11 +907,17 @@ import {
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(() => { }).then(() => {
window.open(`/api/blade-user/export-user?${this.website.tokenHeader}=${getToken()}&account=${this.search.account}&realName=${this.search.realName}`); NProgress.start();
exportBlob(`/api/blade-user/export-user?${this.website.tokenHeader}=${getToken()}&account=${this.search.account}&realName=${this.search.realName}`).then(res => {
downloadXls(res.data, `用户数据表${dateNow()}.xlsx`);
NProgress.done();
})
}); });
}, },
handleTemplate() { handleTemplate() {
window.open(`/api/blade-user/export-template?${this.website.tokenHeader}=${getToken()}`); exportBlob(`/api/blade-user/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
downloadXls(res.data, "用户数据模板.xlsx");
})
}, },
beforeOpen(done, type) { beforeOpen(done, type) {
if (["edit", "view"].includes(type)) { if (["edit", "view"].includes(type)) {

@ -84,6 +84,12 @@
}, { }, {
label: 'oracle.jdbc.OracleDriver', label: 'oracle.jdbc.OracleDriver',
value: 'oracle.jdbc.OracleDriver', value: 'oracle.jdbc.OracleDriver',
}, {
label: 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
value: 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
}, {
label: 'dm.jdbc.driver.DmDriver',
value: 'dm.jdbc.driver.DmDriver',
} }
], ],
width: 200, width: 200,

@ -9,7 +9,7 @@
<el-col :span="24"> <el-col :span="24">
<basic-container> <basic-container>
<p style="text-align: center"> <p style="text-align: center">
<img src="https://img.shields.io/badge/Release-V2.8.2-green.svg" alt="Downloads"/> <img src="https://img.shields.io/badge/Release-V2.9.1-green.svg" alt="Downloads"/>
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status"/> <img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status"/>
<img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR12-blue.svg" alt="Coverage Status"/> <img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR12-blue.svg" alt="Coverage Status"/>
<img src="https://img.shields.io/badge/Spring%20Boot-2.3.12.RELEASE-blue.svg" alt="Downloads"/> <img src="https://img.shields.io/badge/Spring%20Boot-2.3.12.RELEASE-blue.svg" alt="Downloads"/>
@ -119,8 +119,9 @@
<el-tag type="success" style="cursor: pointer" <el-tag type="success" style="cursor: pointer"
onclick="window.open('https://sns.bladex.vip/note/view/1.html')">免费版</el-tag> onclick="window.open('https://sns.bladex.vip/note/view/1.html')">免费版</el-tag>
<el-divider direction="vertical"/> <el-divider direction="vertical"/>
<el-tag type="danger" style="cursor: pointer" <el-tooltip class="item" effect="dark" content="前往商业群文件免费下载,每份授权有一个名额入群" placement="top">
onclick="window.open('https://www.kancloud.cn/@smallchill')">收费版</el-tag> <el-tag type="danger" style="cursor: pointer">收费版</el-tag>
</el-tooltip>
</span> </span>
<el-divider content-position="right"><i class="el-icon-star-off"/></el-divider> <el-divider content-position="right"><i class="el-icon-star-off"/></el-divider>
<span>获取源码</span> <span>获取源码</span>
@ -138,6 +139,40 @@
<el-row> <el-row>
<basic-container> <basic-container>
<el-collapse v-model="logActiveNames" @change="handleChange"> <el-collapse v-model="logActiveNames" @change="handleChange">
<el-collapse-item title="2.9.1.RELEASE发布,新增达梦数据库支持,集成NutFlow流程设计器" name="26">
<div>1.[升级]Mybatis-Plus 3.5.1</div>
<div>2.[升级]Mybatis-Plus-Generator 3.5.2</div>
<div>3.[升级]Nacos 2.0.4</div>
<div>4.[升级]Log4j2 2.17.2</div>
<div>5.[升级]FastJson 1.2.80</div>
<div>6.[升级]Sentinel 1.8.3</div>
<div>7.[升级]EasyExcel 2.2.11</div>
<div>8.[升级]JuatAuth 1.16.5</div>
<div>9.[升级]OkHttp 4.9.3</div>
<div>10.[升级]AliyunOss 3.14.0</div>
<div>11.[升级]Minio 8.3.7</div>
<div>12.[升级]Qiniu 7.9.4</div>
<div>13.[升级]TencentCOS 5.6.69</div>
<div>14.[升级]HuaweiOss 3.21.12</div>
<div>15.[升级]Avue 2.9.4</div>
<div>16.[升级]ElementUI 2.15.6</div>
<div>17.[新增]达梦数据库支持</div>
<div>18.[新增]NutFlow流程设计器集成</div>
<div>19.[新增]Sword升级至AntdV4版本</div>
<div>20.[优化]租户全局数据源拦截器逻辑</div>
<div>21.[优化]单人在线模式RefreshToken的处理逻辑</div>
<div>22.[优化]单元测试支持读取服务名不同环境的配置</div>
<div>23.[优化]租户产品包支持配置清空</div>
<div>24.[优化]配置解决oracle更新null值报错的问题</div>
<div>25.[优化]适配oss与sms操作栏不换行</div>
<div>26.[优化]提升excel导出功能的用户体验</div>
<div>27.[优化]主页部门切换逻辑</div>
<div>28.[修复]用户解封增加空数据判断逻辑</div>
<div>29.[修复]流程用户查询增加租户ID筛选</div>
<div>30.[修复]Oauth2授权码模式失效</div>
<div>31.[修复]登录锁定逻辑</div>
<div>32.[修复]通知公告日期段查询报错</div>
</el-collapse-item>
<el-collapse-item title="2.9.0.RELEASE发布,新增租户菜单产品包功能" name="25"> <el-collapse-item title="2.9.0.RELEASE发布,新增租户菜单产品包功能" name="25">
<div>1.[升级]SpringCloud Hoxton.SR12</div> <div>1.[升级]SpringCloud Hoxton.SR12</div>
<div>2.[升级]AlibabaCloud 2.2.7.RELEASE</div> <div>2.[升级]AlibabaCloud 2.2.7.RELEASE</div>
@ -695,7 +730,7 @@
data() { data() {
return { return {
activeNames: ['1', '2', '3', '5'], activeNames: ['1', '2', '3', '5'],
logActiveNames: ['25'] logActiveNames: ['26']
}; };
}, },
computed: { computed: {

@ -15,24 +15,21 @@
<template slot-scope="scope" slot="menu"> <template slot-scope="scope" slot="menu">
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-download"
v-if="permission.work_claim_sign" v-if="permission.work_claim_sign"
plain
class="none-border"
@click.stop="handleClaim(scope.row)">签收 @click.stop="handleClaim(scope.row)">签收
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-info"
v-if="permission.work_claim_detail" v-if="permission.work_claim_detail"
plain
class="none-border"
@click.stop="handleDetail(scope.row)">详情 @click.stop="handleDetail(scope.row)">详情
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-search"
v-if="permission.work_claim_follow" v-if="permission.work_claim_follow"
plain @click.stop="handleImage(scope.row,scope.index)">流程图
class="none-border"
@click.stop="handleImage(scope.row,scope.index)">跟踪
</el-button> </el-button>
</template> </template>
<template slot-scope="{row}" <template slot-scope="{row}"
@ -40,27 +37,7 @@
<el-tag>v{{row.processDefinitionVersion}}</el-tag> <el-tag>v{{row.processDefinitionVersion}}</el-tag>
</template> </template>
</avue-crud> </avue-crud>
<el-dialog title="流程图" <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
append-to-body
:visible.sync="flowBox"
:fullscreen="true">
<iframe
:src=flowUrl
width="100%"
height="700"
title="流程图"
frameBorder="no"
border="0"
marginWidth="0"
marginHeight="0"
scrolling="no"
allowTransparency="yes">
</iframe>
<span slot="footer"
class="dialog-footer">
<el-button @click="flowBox = false"> </el-button>
</span>
</el-dialog>
</basic-container> </basic-container>
</template> </template>
@ -82,8 +59,8 @@
currentPage: 1, currentPage: 1,
total: 0 total: 0
}, },
processInstanceId: '',
flowBox: false, flowBox: false,
flowUrl: '',
workBox: false, workBox: false,
option: { option: {
height: 'auto', height: 'auto',
@ -100,7 +77,7 @@
viewBtn: false, viewBtn: false,
delBtn: false, delBtn: false,
dialogWidth: 900, dialogWidth: 900,
menuWidth: 150, menuWidth: 200,
dialogClickModal: false, dialogClickModal: false,
column: [ column: [
{ {
@ -193,7 +170,7 @@
this.$router.push({path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`}); this.$router.push({path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`});
}, },
handleImage(row) { handleImage(row) {
this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`; this.processInstanceId = row.processInstanceId;
this.flowBox = true; this.flowBox = true;
}, },
currentChange(currentPage){ currentChange(currentPage){
@ -222,10 +199,3 @@
} }
}; };
</script> </script>
<style>
.none-border {
border: 0;
background-color: transparent !important;
}
</style>

@ -16,17 +16,15 @@
<template slot-scope="scope" slot="menu"> <template slot-scope="scope" slot="menu">
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-info"
v-if="permission.work_done_detail" v-if="permission.work_done_detail"
plain
class="none-border"
@click.stop="handleDetail(scope.row)">详情 @click.stop="handleDetail(scope.row)">详情
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-search"
v-if="permission.work_done_follow" v-if="permission.work_done_follow"
plain @click.stop="handleImage(scope.row,scope.index)">流程图
class="none-border"
@click.stop="handleImage(scope.row,scope.index)">跟踪
</el-button> </el-button>
</template> </template>
<template slot-scope="{row}" <template slot-scope="{row}"
@ -34,27 +32,7 @@
<el-tag>v{{row.processDefinitionVersion}}</el-tag> <el-tag>v{{row.processDefinitionVersion}}</el-tag>
</template> </template>
</avue-crud> </avue-crud>
<el-dialog title="流程图" <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
append-to-body
:visible.sync="flowBox"
:fullscreen="true">
<iframe
:src=flowUrl
width="100%"
height="700"
title="流程图"
frameBorder="no"
border="0"
marginWidth="0"
marginHeight="0"
scrolling="no"
allowTransparency="yes">
</iframe>
<span slot="footer"
class="dialog-footer">
<el-button @click="flowBox = false"> </el-button>
</span>
</el-dialog>
</basic-container> </basic-container>
</template> </template>
@ -76,8 +54,8 @@
currentPage: 1, currentPage: 1,
total: 0 total: 0
}, },
processInstanceId: '',
flowBox: false, flowBox: false,
flowUrl: '',
workBox: false, workBox: false,
option: { option: {
height: 'auto', height: 'auto',
@ -169,7 +147,7 @@
this.$router.push({path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`}); this.$router.push({path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}`});
}, },
handleImage(row) { handleImage(row) {
this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`; this.processInstanceId = row.processInstanceId;
this.flowBox = true; this.flowBox = true;
}, },
currentChange(currentPage){ currentChange(currentPage){
@ -198,10 +176,3 @@
} }
}; };
</script> </script>
<style>
.none-border {
border: 0;
background-color: transparent !important;
}
</style>

@ -50,8 +50,8 @@
<div slot="header"> <div slot="header">
<span>流程跟踪</span> <span>流程跟踪</span>
</div> </div>
<el-row type="flex" class="row-bg"> <el-row class="row-bg">
<img :src="src" alt="design"> <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
</el-row> </el-row>
</el-card> </el-card>
</el-form> </el-form>
@ -85,7 +85,6 @@
init() { init() {
this.processInstanceId = this.$route.params.processInstanceId; this.processInstanceId = this.$route.params.processInstanceId;
this.businessId = this.$route.params.businessId; this.businessId = this.$route.params.businessId;
this.src = `/api/blade-flow/process/diagram-view?processInstanceId=${this.$route.params.processInstanceId}&t=${new Date().getTime()}`;
historyFlowList(this.processInstanceId).then(res => { historyFlowList(this.processInstanceId).then(res => {
const data = res.data; const data = res.data;
if (data.success) { if (data.success) {

@ -1,7 +1,12 @@
<template> <template>
<basic-container> <div>
<avue-form :option="option" v-model="form" @submit="handleSubmit"/> <basic-container>
</basic-container> <avue-form :option="option" v-model="form" @submit="handleSubmit"/>
</basic-container>
<basic-container>
<flow-design :is-display="true" :process-definition-id="processDefinitionId"></flow-design>
</basic-container>
</div>
</template> </template>
<script> <script>
@ -10,6 +15,7 @@
export default { export default {
data() { data() {
return { return {
processDefinitionId: '',
form: {}, form: {},
option: { option: {
group: [ group: [
@ -81,6 +87,9 @@
} }
} }
}, },
created() {
this.processDefinitionId = this.$route.params.processDefinitionId;
},
methods: { methods: {
handleSubmit() { handleSubmit() {
const params = { const params = {

@ -55,8 +55,8 @@
<div slot="header"> <div slot="header">
<span>流程跟踪</span> <span>流程跟踪</span>
</div> </div>
<el-row type="flex" class="row-bg"> <el-row class="row-bg">
<img :src="src" alt="design"> <flow-design :is-display="true" :process-instance-id="processInstanceId"></flow-design>
</el-row> </el-row>
</el-card> </el-card>
</el-form> </el-form>
@ -104,7 +104,6 @@
this.taskId = this.$route.params.taskId; this.taskId = this.$route.params.taskId;
this.processInstanceId = this.$route.params.processInstanceId; this.processInstanceId = this.$route.params.processInstanceId;
this.businessId = this.$route.params.businessId; this.businessId = this.$route.params.businessId;
this.src = `/api/blade-flow/process/diagram-view?processInstanceId=${this.$route.params.processInstanceId}&t=${new Date().getTime()}`;
historyFlowList(this.processInstanceId).then(res => { historyFlowList(this.processInstanceId).then(res => {
const data = res.data; const data = res.data;
if (data.success) { if (data.success) {

@ -16,17 +16,15 @@
<template slot-scope="scope" slot="menu"> <template slot-scope="scope" slot="menu">
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-info"
v-if="permission.work_send_detail" v-if="permission.work_send_detail"
plain
class="none-border"
@click.stop="handleDetail(scope.row)">详情 @click.stop="handleDetail(scope.row)">详情
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-search"
v-if="permission.work_send_follow" v-if="permission.work_send_follow"
plain @click.stop="handleImage(scope.row,scope.index)">流程图
class="none-border"
@click.stop="handleImage(scope.row,scope.index)">跟踪
</el-button> </el-button>
</template> </template>
<template slot-scope="{row}" <template slot-scope="{row}"
@ -38,27 +36,7 @@
<el-tag>{{row.processIsFinished==='finished' ? '已完成' : '未完成'}}</el-tag> <el-tag>{{row.processIsFinished==='finished' ? '已完成' : '未完成'}}</el-tag>
</template> </template>
</avue-crud> </avue-crud>
<el-dialog title="流程图" <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
append-to-body
:visible.sync="flowBox"
:fullscreen="true">
<iframe
:src=flowUrl
width="100%"
height="700"
title="流程图"
frameBorder="no"
border="0"
marginWidth="0"
marginHeight="0"
scrolling="no"
allowTransparency="yes">
</iframe>
<span slot="footer"
class="dialog-footer">
<el-button @click="flowBox = false"> </el-button>
</span>
</el-dialog>
</basic-container> </basic-container>
</template> </template>
@ -80,8 +58,8 @@
currentPage: 1, currentPage: 1,
total: 0 total: 0
}, },
processInstanceId: '',
flowBox: false, flowBox: false,
flowUrl: '',
workBox: false, workBox: false,
option: { option: {
height: 'auto', height: 'auto',
@ -179,7 +157,7 @@
this.$router.push({ path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}` }); this.$router.push({ path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}` });
}, },
handleImage(row) { handleImage(row) {
this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`; this.processInstanceId = row.processInstanceId;
this.flowBox = true; this.flowBox = true;
}, },
currentChange(currentPage){ currentChange(currentPage){
@ -208,10 +186,3 @@
} }
}; };
</script> </script>
<style>
.none-border {
border: 0;
background-color: transparent !important;
}
</style>

@ -22,16 +22,14 @@
<template slot-scope="scope" slot="menu"> <template slot-scope="scope" slot="menu">
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-video-play"
v-if="permission.work_start_flow" v-if="permission.work_start_flow"
plain
class="none-border"
@click.stop="handleStart(scope.row)">发起 @click.stop="handleStart(scope.row)">发起
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-search"
v-if="permission.work_start_image" v-if="permission.work_start_image"
plain
class="none-border"
@click.stop="handleImage(scope.row,scope.index)">流程图 @click.stop="handleImage(scope.row,scope.index)">流程图
</el-button> </el-button>
</template> </template>
@ -52,27 +50,7 @@
<el-tag>{{row.categoryName}}</el-tag> <el-tag>{{row.categoryName}}</el-tag>
</template> </template>
</avue-crud> </avue-crud>
<el-dialog title="流程图" <flow-design is-dialog :is-display.sync="flowBox" :process-definition-id="processDefinitionId"></flow-design>
append-to-body
:visible.sync="flowBox"
:fullscreen="true">
<iframe
:src=flowUrl
width="100%"
height="700"
title="流程图"
frameBorder="no"
border="0"
marginWidth="0"
marginHeight="0"
scrolling="no"
allowTransparency="yes">
</iframe>
<span slot="footer"
class="dialog-footer">
<el-button @click="flowBox = false"> </el-button>
</span>
</el-dialog>
</basic-container> </basic-container>
</template> </template>
@ -95,8 +73,8 @@
currentPage: 1, currentPage: 1,
total: 0 total: 0
}, },
processDefinitionId: '',
flowBox: false, flowBox: false,
flowUrl: '',
workBox: false, workBox: false,
option: { option: {
height: 'auto', height: 'auto',
@ -204,7 +182,7 @@
this.$router.push({path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/form/${row.id}`}); this.$router.push({path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/form/${row.id}`});
}, },
handleImage(row) { handleImage(row) {
this.flowUrl = `/api/blade-flow/process/resource-view?processDefinitionId=${row.id}`; this.processDefinitionId = row.id;
this.flowBox = true; this.flowBox = true;
}, },
currentChange(currentPage) { currentChange(currentPage) {
@ -234,10 +212,3 @@
} }
}; };
</script> </script>
<style>
.none-border {
border: 0;
background-color: transparent !important;
}
</style>

@ -15,24 +15,21 @@
<template slot-scope="scope" slot="menu"> <template slot-scope="scope" slot="menu">
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-s-check"
v-if="permission.work_todo_handle" v-if="permission.work_todo_handle"
plain
class="none-border"
@click.stop="handleWork(scope.row)">处理 @click.stop="handleWork(scope.row)">处理
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-info"
v-if="permission.work_todo_detail" v-if="permission.work_todo_detail"
plain
class="none-border"
@click.stop="handleDetail(scope.row)">详情 @click.stop="handleDetail(scope.row)">详情
</el-button> </el-button>
<el-button type="text" <el-button type="text"
size="small" size="small"
icon="el-icon-search"
v-if="permission.work_todo_follow" v-if="permission.work_todo_follow"
plain @click.stop="handleImage(scope.row,scope.index)">流程图
class="none-border"
@click.stop="handleImage(scope.row,scope.index)">跟踪
</el-button> </el-button>
</template> </template>
<template slot-scope="{row}" <template slot-scope="{row}"
@ -40,27 +37,7 @@
<el-tag>v{{row.processDefinitionVersion}}</el-tag> <el-tag>v{{row.processDefinitionVersion}}</el-tag>
</template> </template>
</avue-crud> </avue-crud>
<el-dialog title="流程图" <flow-design is-dialog :is-display.sync="flowBox" :process-instance-id="processInstanceId"></flow-design>
append-to-body
:visible.sync="flowBox"
:fullscreen="true">
<iframe
:src=flowUrl
width="100%"
height="700"
title="流程图"
frameBorder="no"
border="0"
marginWidth="0"
marginHeight="0"
scrolling="no"
allowTransparency="yes">
</iframe>
<span slot="footer"
class="dialog-footer">
<el-button @click="flowBox = false"> </el-button>
</span>
</el-dialog>
</basic-container> </basic-container>
</template> </template>
@ -82,8 +59,8 @@
currentPage: 1, currentPage: 1,
total: 0 total: 0
}, },
processInstanceId: '',
flowBox: false, flowBox: false,
flowUrl: '',
workBox: false, workBox: false,
option: { option: {
height: 'auto', height: 'auto',
@ -100,7 +77,7 @@
viewBtn: false, viewBtn: false,
delBtn: false, delBtn: false,
dialogWidth: 900, dialogWidth: 900,
menuWidth: 150, menuWidth: 200,
dialogClickModal: false, dialogClickModal: false,
column: [ column: [
{ {
@ -179,7 +156,7 @@
this.$router.push({ path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}` }); this.$router.push({ path: `/work/process/${flowRoute(this.flowRoutes, row.category)}/detail/${row.processInstanceId}/${row.businessId}` });
}, },
handleImage(row) { handleImage(row) {
this.flowUrl = `/api/blade-flow/process/diagram-view?processInstanceId=${row.processInstanceId}`; this.processInstanceId = row.processInstanceId;
this.flowBox = true; this.flowBox = true;
}, },
currentChange(currentPage){ currentChange(currentPage){
@ -208,10 +185,3 @@
} }
}; };
</script> </script>
<style>
.none-border {
border: 0;
background-color: transparent !important;
}
</style>

Loading…
Cancel
Save