🎉 1.3.2.RELEASE

saber
ssc 4 years ago
parent d327299fa5
commit 4c9e833d7a
  1. 2
      public/cdn/avue-form-design/index.umd.min.js
  2. 4
      public/index.html
  3. 6
      src/views/plugin/workflow/components/wf-user-select/index.vue
  4. 2
      src/views/plugin/workflow/mixins/custom-fields.js
  5. 33
      src/views/plugin/workflow/mixins/ex-form.js
  6. 25
      src/views/plugin/workflow/ops/detail.vue
  7. 7
      src/views/plugin/workflow/process/components/detail.vue
  8. 17
      src/views/plugin/workflow/process/components/examForm.vue
  9. 14
      src/views/plugin/workflow/process/components/flow.vue
  10. 17
      src/views/plugin/workflow/process/components/form.vue
  11. 146
      src/views/plugin/workflow/process/components/search.vue
  12. 24
      src/views/plugin/workflow/process/todo.vue

File diff suppressed because one or more lines are too long

@ -15,7 +15,7 @@
<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/saber/iconfont.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@smallwei/avue@2.8.23/lib/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@smallwei/avue@2.8.24/lib/index.css">
<script src="<%= BASE_URL %>cdn/xlsx/FileSaver.min.js"></script>
<script src="<%= BASE_URL %>cdn/xlsx/xlsx.full.min.js"></script>
<link rel="icon" href="<%= BASE_URL %>favicon.png">
@ -109,7 +109,7 @@
<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/element-ui/2.15.1/index.js" charset="utf-8"></script>
<script src="https://cdn.jsdelivr.net/npm/@smallwei/avue@2.8.23" charset="utf-8"></script>
<script src="https://cdn.jsdelivr.net/npm/@smallwei/avue@2.8.24" 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>
</body>

@ -3,7 +3,7 @@
<el-input v-model="name"
:size="size"
suffix-icon="el-icon-user"
placeholder="人员选择"
placeholder="人员选择(示例),谨慎使用"
readonly
:disabled="disabled"
@click.native="handleSelect"></el-input>
@ -222,6 +222,10 @@ export default {
checks.forEach(c => {
const row = this.data.find(d => d.id == c)
if (row) name.push(row.realName)
// TODO
// else {
//
// }
if (row && this.$refs.crud) {
this.$refs.crud.toggleRowSelection(row, true)
}

@ -4,7 +4,7 @@ export default {
customFields: [{
title: '业务字段',
list: [{
label: '人员选择',
label: '人员选择(示例)',
component: 'wf-user-select',
span: 24,
params: {

@ -63,7 +63,7 @@ export default {
}
},
// 根据可读可写,过滤avue column
filterAvueColumn(column, taskForm, props = { label: 'label', prop: 'prop' }) {
filterAvueColumn(column, taskForm, isExForm = false, props = { label: 'label', prop: 'prop' }) {
const _this = this
if (!column || column.length == 0) return { column, vars: [] }
@ -78,11 +78,12 @@ export default {
vars.push(col[props.prop])
if (col.value) col.value = _this.getDefaultValues(col.value)
// 处理事件
if (!isExForm) { // 非外置表单 处理事件
event.forEach(e => {
if (col[e]) col[e] = eval((col[e] + '').replace(/this/g, '_this'))
})
if (col.event) Object.keys(col.event).forEach(key => col.event[key] = eval((col.event[key] + '').replace(/this/g, '_this')))
}
} else { // 不可写,清除校验、默认值、事件
if (col.type == 'dynamic') {
col.children.addBtn = false
@ -132,17 +133,33 @@ export default {
* 发起流程
* @param form {"processId": "流程定义id", ...表单自定义字段变量}
*/
handleStartProcess(form) {
handleStartProcess() {
this.loading = true
this.$refs.form.validate((valid, done, msg) => {
let form = this.deepClone(this.form)
if (this.$refs.examineForm && this.$refs.examineForm.examineForm) {
const { copyUser, assignee } = this.$refs.examineForm.examineForm
form = { ...form, copyUser, assignee }
}
return new Promise((resolve, reject) => {
if (valid) {
startProcess(form).then(() => {
resolve()
this.$message.success("发起成功")
this.handleCloseTag('/plugin/workflow/process/send')
done()
this.loading = false
}).catch(() => {
reject()
done()
this.loading = false
})
} else {
done()
this.loading = false
if (msg) {
const key = Object.keys(msg)[0]
const rules = msg[key]
this.$message.error(rules.map(r => r.message).join(' | '))
}
}
})
},
/**
@ -178,7 +195,7 @@ export default {
*/
handleCompleteTask(pass, variables) {
return new Promise((resolve, reject) => {
const { comment, copyUser, assignee } = this.$refs.examineForm.examineForm
const { comment, copyUser, assignee, attachment } = this.$refs.examineForm.examineForm
if (!pass && !comment) {
this.$message.error("请填写批复意见")
this.submitLoading = false
@ -188,7 +205,7 @@ export default {
const { taskId, processInstanceId, processDefinitionName, processDefinitionId } = this.process
const param = {
taskId, processInstanceId, processDefinitionName, processDefinitionId, pass,
comment, copyUser, assignee, variables
comment, copyUser, assignee, variables, attachment
}
completeTask(param).then(() => {
resolve()

@ -76,10 +76,19 @@ export default {
option.menuBtn = false
const { column, group } = option
option.detail = true
let event = ['change', 'blur', 'click', 'focus']
if (column && column.length > 0) { // column
column.forEach(col => {
if (col.type == 'dynamic') col.children.column.forEach(cc => delete cc.value)
else delete col.value
if (col.type == 'dynamic') col.children.column.forEach(cc => {
delete cc.value
delete cc.event
event.forEach(e => delete cc[e])
})
else {
delete col.value
delete col.event
event.forEach(e => delete col[e])
}
})
}
@ -87,8 +96,16 @@ export default {
group.forEach(gro => {
if (gro.column && gro.column.length > 0) {
gro.column.forEach(col => {
if (col.type == 'dynamic') col.children.column.forEach(cc => delete cc.value)
else delete col.value
if (col.type == 'dynamic') col.children.column.forEach(cc => {
delete cc.value
delete cc.event
event.forEach(e => delete cc[e])
})
else {
delete col.value
delete col.event
event.forEach(e => delete col[e])
}
})
}
})

@ -219,7 +219,7 @@ export default {
//
handleExamine(pass) {
this.submitLoading = true
this.$refs.form.validate((valid, done) => {
this.$refs.form.validate((valid, done, msg) => {
if (valid) {
const variables = {}
this.vars.forEach(v => {
@ -236,6 +236,11 @@ export default {
} else {
done()
this.submitLoading = false
if (msg) {
const key = Object.keys(msg)[0]
const rules = msg[key]
this.$message.error(rules.map(r => r.message).join(' | '))
}
}
})
},

@ -21,6 +21,7 @@ export default {
if (!val) return
if (val.hideComment) {
this.findObject(this.examineOption.column, 'comment').display = false
this.findObject(this.examineOption.column, 'attachment').display = false
}
if (val.hideCopy) {
this.findObject(this.examineOption.column, '$copyUser').display = false
@ -55,6 +56,22 @@ export default {
}
},
display: true
}, {
label: '附件',
prop: 'attachment',
type: 'upload',
propsHttp: {
res: 'data',
url: 'link',
name: 'originalName'
},
props: {
label: 'name',
value: 'url'
},
action: '/api/blade-resource/oss/endpoint/put-file',
span: 24,
display: true
}, {
label: '抄送人',
prop: '$copyUser',

@ -9,8 +9,8 @@
<el-card shadow="never">
<p>{{item.assigneeName}} [{{item.createTime}}] 开始处理 [{{item.historyActivityType == 'endEvent'? '结束': (item.historyActivityName || '未命名')}}] 环节</p>
<p v-if="item.historyActivityDurationTime">任务历时 [{{item.historyActivityDurationTime}}]</p>
<template v-if="item.comments">
<p v-for="(comment, index) in item.comments"
<template v-if="item.comments && item.comments.length > 0">
<p v-for="(comment, index) in item.comments.filter(c => c.action === 'AddComment')"
:key="index">
<template v-if="index < 1">
<span v-if="commentMap[comment.type]">{{commentMap[comment.type]}}: [{{comment.fullMessage}}]</span>
@ -26,6 +26,14 @@
v-if="comment.time">{{comment.time}}</p>
</template>
</p>
<template v-if="item.attachments && item.attachments.length > 0">
<p style="display: flex; align-items: baseline;">附件:
<avue-upload :value="item.attachments"
:props="{label: 'name', value: 'url'}"
:upload-preview="handleUploadPreview"
disabled></avue-upload>
</p>
</template>
</template>
<p v-if="item.endTime">结束时间: [{{item.endTime}}]</p>
</el-card>
@ -36,8 +44,10 @@
</template>
<script>
import exForm from '../../mixins/ex-form'
export default {
name: 'wf-flow',
mixins: [exForm],
props: {
flow: {
type: Array,

@ -13,8 +13,6 @@
ref="form"
:option="option"
:defaults.sync="defaults"
@submit="handleSubmit"
@error="loading = false"
:upload-preview="handleUploadPreview">
</avue-form>
</el-card>
@ -33,10 +31,7 @@
<el-button type="primary"
size="medium"
v-loading="loading"
@click="() => {
loading = true;
$refs.form.submit()
}">发起</el-button>
@click="handleStartProcess">发起</el-button>
<el-button v-if="permission.wf_process_draft"
type="success"
size="medium"
@ -127,16 +122,6 @@ export default {
this.waiting = false
})
},
handleSubmit(form, done) {
this.handleStartProcess(form).then(() => {
this.$message.success("发起成功")
done()
this.handleCloseTag('/plugin/workflow/process/send')
}).catch(() => {
this.loading = false
done()
})
},
}
}
</script>

@ -0,0 +1,146 @@
<template>
<el-dialog ref="wf-dialog"
custom-class="wf-dialog"
:visible.sync="visible"
title="表单搜索条件"
width="60%"
append-to-body
v-dialogdrag>
<avue-form v-model="form"
:option="option"
@submit="handleSubmit"></avue-form>
</el-dialog>
</template>
<script>
export default {
name: 'wf-search',
props: {
value: Array,
default: () => {
return []
}
},
watch: {
value: {
handler(val) {
if (val) {
const arr = []
this.deepClone(val).split(',').forEach(s => {
const row = s.split(":")
arr.push({
column: row[0],
condition: row[1],
value: row[2]
})
})
this.form.search = arr
}
},
immediate: true
}
},
data() {
return {
visible: false,
form: {},
option: {
border: true,
submitText: '确定',
column: [
{
label: '',
labelWidth: 0,
span: 24,
prop: 'search',
type: 'dynamic',
children: {
align: 'center',
column: [
{
label: '字段',
prop: 'column'
},
{
label: '条件',
prop: 'condition',
type: 'select',
dicData: [{
label: '等于',
value: 'equal'
}, {
label: '不等于',
value: 'notEqual'
}, {
label: '包含',
value: 'like'
}, {
label: '存在',
value: 'exists'
}, {
label: '不存在',
value: 'notExists'
}, {
label: '大于',
value: 'greaterThan'
}, {
label: '小于',
value: 'lessThan'
}, {
label: '大于等于',
value: 'greaterThanOrEqual'
}, {
label: '小于等于',
value: 'lessThanOrEqual'
}],
placeholder: '条件,存在/不存在无需填值',
change: ({value, row}) => {
if (['exists', 'notExists'].includes(value)) row.value = ''
}
},
{
label: '值',
prop: 'value'
}
]
}
}
]
}
}
},
methods: {
handleSubmit(form, done) {
const { search } = form
if (search && search.length > 0) {
const arr = []
search.forEach(s => {
const { column, condition, value } = s
if (column && (['exists', 'notExists'].includes(condition) || (condition && value))) arr.push(`${column}:${condition}:${value}`)
})
this.$emit('input', arr.join(","))
}
this.visible = false
done()
}
}
}
</script>
<style lang="scss">
.wf-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>

@ -1,9 +1,10 @@
<template>
<basic-container>
<basic-container class="wf-container">
<avue-crud :option="option"
:table-loading="loading"
:data="data"
:page.sync="page"
:search.sync="query"
:permission="permissionList"
v-model="form"
@search-change="searchChange"
@ -26,6 +27,14 @@
icon="el-icon-search"
@click="handleFlow(row)">流程图</el-button>
</template>
<template #searchMenu
v-if="permission.wf_process_todo_search">
<el-badge :value="query.formSearch? query.formSearch.split(',').length: 0"
:hidden="!query.formSearch || query.formSearch.split(',').length == 0">
<el-button icon="el-icon-search"
@click="$refs['wf-search'].visible = true">表单</el-button>
</el-badge>
</template>
</avue-crud>
<el-dialog :visible.sync="bpmnVisible"
@ -38,6 +47,8 @@
style="height: 60vh;"
:options="bpmnOption"></wf-design>
</el-dialog>
<wf-search ref="wf-search"
v-model="query.formSearch"></wf-search>
</basic-container>
</template>
@ -47,8 +58,11 @@ import { mapGetters } from "vuex";
import exForm from '../mixins/ex-form'
import WfSearch from './components/search.vue'
export default {
mixins: [exForm],
components: { WfSearch },
data() {
return {
form: {},
@ -204,6 +218,14 @@ export default {
</script>
<style lang="scss">
.wf-container {
.el-collapse-item__content {
padding-top: 8px;
}
.el-badge__content.is-fixed {
right: 16px;
}
}
.wf-dialog {
display: flex;
flex-direction: column;

Loading…
Cancel
Save