1. 新增工单,功能,样式

main
赵培友 3 years ago
parent 2505df3e3c
commit 74831eb690
  1. 57
      src/api/plugin/workflow/form.js
  2. 2
      src/api/plugin/workflow/process.js
  3. 63
      src/styles/custom/custom.scss
  4. 42
      src/views/plugin/workflow/design/model.vue
  5. 4
      src/views/plugin/workflow/mixins/ex-form.js
  6. 6
      src/views/plugin/workflow/process/components/examForm.vue
  7. 190
      src/views/plugin/workflow/process/components/form.vue
  8. 259
      src/views/plugin/workflow/process/start.vue

@ -60,4 +60,59 @@ export const changeCategory = (row) => {
method: 'post',
data: row
})
}
}
export const downloadFile = (query) => {
return request({
url: '/api/blade-workflow/database/download',
method: 'get',
params: query,
responseType: 'blob'
})
}
// 运维公司
export const getCompany = () => {
return request({
url: '/api/blade-user/maintenanceCompany',
method: 'get',
})
}
// 运维部门
export const getDepts = (query) => {
return request({
url: '/api/blade-system/dept/getDepts',
method: 'get',
params:query
})
}
// 任务父类
export const getTaskParent = () => {
return request({
url: '/api/blade-system/dict-biz/dictionary?code=task_parent',
method: 'get',
})
}
// 任务种类
export const getTaskTypeData = (query) => {
return request({
url: '/api/blade-workflow/taskInfo/taskTypeData',
method: 'get',
params:query
})
}
// 系统名称/数据库
export const getTaskAndDataBase = () => {
return request({
url: '/api/blade-workflow/projectInfo/projectAndDataBase',
method: 'get',
})
}
// 系统名称/数据表
export const getModuleAndDataTable = (query) => {
return request({
url: '/api/blade-workflow/projectInfo/moduleAndDataTable',
method: 'get',
params:query
})
}

@ -300,4 +300,4 @@ export const userList = (current, size, params) => {
size,
}
})
}
}

@ -1,24 +1,10 @@
// // input输入框
// .el-input--small .el-input__inner {
// border-radius: 3px 3px 3px 3px;
// color: #333;
// position: relative;
// border: 1px solid #CFCFCF
// }
// // input输入框label
// .el-form--label-top .el-form-item__label {
// font-size: 16px;
// color: #273240;
// padding: 0!important;
// }
// 包裹容器
.cus-container {
margin: 0 38px;
height: 100%;
width: calc(100% - 76px);
}
// 表格
#avue-id {
// .el-table {
// height: 776px;
@ -41,7 +27,7 @@
// 分页
.avue-crud__pagination {
text-align: left;
background: #F0F2F5;
background: #f0f2f5;
}
// 自定义弹框样式只有父类包含 custom类才可使用
.custom {
@ -56,10 +42,10 @@
border-color: #e4e7ec;
}
.el-input--small {
width: 240px!important;
width: 240px !important;
}
.avue-form .el-date-editor.el-input {
width: 240px!important;
width: 240px !important;
}
.avue-form,
@ -93,12 +79,12 @@
margin-bottom: 21px;
}
.el-col-8 {
width: 240px;
width: 240px;
}
.el-col-8:nth-child(3n-1) {
margin: 0 45px;
}
.el-col-8:nth-child(3n+1) {
.el-col-8:nth-child(3n + 1) {
margin-left: 35px;
}
.avue-dynamic {
@ -106,4 +92,39 @@
margin: 0 33px;
margin-top: 10px;
}
}
}
// 工作流表单
.avue-skeleton {
.avue-crud .el-input--small input,
.avue-form .el-input--small input {
height: 50px;
line-height: 50px;
}
.el-col-md-8 {
width: 29%;
}
.el-col-md-8:nth-child(3n + 2) {
margin: 0 100px;
}
// input输入框
.el-input--small .el-input__inner {
border-radius: 3px 3px 3px 3px;
color: #333;
position: relative;
border: 1px solid #cfcfcf;
}
// input输入框label
.el-form-item__label {
font-size: 16px;
color: #273240;
padding: 0 !important;
margin-bottom: 10px;
}
.el-upload-dragger {
width: 82vw;
}
.el-upload-list__item-name {
display: none;
}
}

@ -152,12 +152,12 @@ export default {
searchMenuSpan: 6,
menuWidth: 280,
column: [
{
label: "图标",
prop: "icon",
type: 'upload',
width: 80
},
// {
// label: "",
// prop: "icon",
// type: 'upload',
// width: 80
// },
{
label: "模型key",
prop: "modelKey",
@ -170,21 +170,21 @@ export default {
overHidden: true,
search: true
},
{
label: '分类',
prop: 'categoryId',
type: 'tree',
props: {
label: 'name',
value: 'id'
},
dicData: [],
rules: [{
required: true,
message: "请选择分类",
trigger: "change"
}],
},
// {
// label: '',
// prop: 'categoryId',
// type: 'tree',
// props: {
// label: 'name',
// value: 'id'
// },
// dicData: [],
// rules: [{
// required: true,
// message: "",
// trigger: "change"
// }],
// },
{
label: "描述",
prop: "description",

@ -28,7 +28,7 @@ export default {
},
methods: {
// 动态路由跳转
dynamicRoute(row, type, async = false) {
dynamicRoute(row, type, async = false,parent) {
const { id, taskId, processInstanceId, processId, formKey, formUrl, processDefKey } = row
let param = Buffer.from(JSON.stringify({
processId: id,
@ -59,7 +59,7 @@ export default {
resolve({ row, type, param })
})
} else {
this.$router.push(`/workflow/process/${type}/${param}`)
this.$router.push(`/workflow/process/${type}/${param}?parent=${parent}`)
}
}
},

@ -36,6 +36,7 @@ export default {
examineForm: {},
examineOption: {
menuBtn: false,
labelPosition: "top",
column: [{
label: '批复意见',
prop: 'comment',
@ -61,9 +62,10 @@ export default {
label: 'name',
value: 'url'
},
action: '/api/blade-resource/oss/endpoint/put-file',
action: '/api/blade-workflow/database/upload',
span: 24,
display: true
display: true,
dragFile: true,
},
// {
// label: '',

@ -1,11 +1,11 @@
<template>
<basic-container>
<avue-skeleton :loading="waiting" avatar :rows="8">
<avue-title
<!-- <avue-title
style="margin-bottom: 20px"
:styles="{ fontSize: '20px' }"
:value="process.name"
></avue-title>
></avue-title> -->
<el-card shadow="never" style="margin-top: 20px">
<avue-form
v-if="
@ -20,27 +20,80 @@
:upload-preview="handleUploadPreview"
:upload-after="uploadAfter"
>
<template slot="yunweigongsi">
<el-select
v-model="form.yunweigongsi"
placeholder="请选择运维公司"
@change="companyChange"
:disabled="companyList.length===1"
>
<el-option
v-for="item in companyList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</template>
<template slot="renwufulei">
<el-select
v-model="form.renwufulei"
placeholder="请选择任务父类"
@change="taskParentChange"
>
<el-option
v-for="item in taskParentList"
:key="item.id"
:label="item.dictValue"
:value="item.id"
>
</el-option>
</el-select>
</template>
<template slot="xitongmingchengshujuku">
<el-select
v-model="form.xitongmingchengshujuku"
placeholder="请选择系统名称/数据库"
@change="systemChange"
>
<el-option
v-for="item in taskAndDataBaseList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</template>
<template slot="uploadrecord">
<el-table
v-if="tableData.length > 0"
:data="tableData"
style="width: 100%"
>
<el-table-column prop="name" label="附件名称" width="180">
<el-table-column prop="name" label="附件名称" width="250">
<template slot-scope="scope">
<span style="color: blue; cursor: pointer">{{
scope.row.name
}}</span>
<span
style="color: blue; cursor: pointer"
@click="download(scope.row)"
>{{ scope.row.name }}</span
>
</template>
</el-table-column>
<el-table-column prop="path" label="上传人" width="180">
<el-table-column prop="createUser" label="上传人" width="180">
</el-table-column>
<el-table-column prop="path" label="上传时间" width="180">
<el-table-column prop="createTime" label="上传时间" width="240">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<i class="el-icon-delete" style="cursor: pointer"></i>
<template>
<i
class="el-icon-delete"
style="cursor: pointer"
@click="deleteFile(index)"
></i>
</template>
</el-table-column>
</el-table>
@ -93,6 +146,15 @@
</template>
<script>
import {
downloadFile,
getCompany,
getDepts,
getTaskParent,
getTaskTypeData,
getTaskAndDataBase,
getModuleAndDataTable,
} from "@/api/plugin/workflow/form.js";
import WfExamineForm from "./examForm.vue";
import WfUserSelect from "./user-select";
import exForm from "../../mixins/ex-form";
@ -131,16 +193,101 @@ export default {
process: {},
loading: false,
tableData: [],
companyList: [], //
deptList: [], //
taskParentList: [], //
taskAndDataBaseList: [], //
};
},
mounted() {
//
getCompany().then((res) => {
this.companyList = res.data.data;
if (this.companyList.length > 0) {
const id = this.companyList[0].id
this.form.yunweigongsi = id;
this.companyChange(id)
}
});
getTaskParent().then((res) => {
this.taskParentList = res.data.data;
if(this.$route.query.parent) {
const id = this.$route.query.parent
this.form.renwufulei = id
this.taskParentChange(id)
}
});
getTaskAndDataBase().then((res) => {
this.taskAndDataBaseList = res.data.data;
});
},
methods: {
uploadAfter(file, column) {
this.tableData.push({
name: "文件流",
path: "/d:/sgh",
// -
companyChange(id) {
let obj = this.companyList.find(function (i) {
return i.id === id;
});
getDepts({ id: obj.deptId }).then((res) => {
const guanlibumen = this.findObject(this.option.column, "guanlibumen");
guanlibumen.dicData = res.data.data;
});
},
//
taskParentChange(id) {
getTaskTypeData({ parentId: id }).then((res) => {
const renwuzhonglei = this.findObject(
this.option.column,
"renwuzhonglei"
);
renwuzhonglei.dicData = res.data.data;
});
},
systemChange(id) {
let obj = this.taskAndDataBaseList.find(function (i) {
return i.id === id;
});
getModuleAndDataTable({ id: obj.id, type: obj.type }).then((res) => {
const xitongmokuaishujubiao = this.findObject(
this.option.column,
"xitongmokuaishujubiao"
);
xitongmokuaishujubiao.dicData = res.data.data;
});
},
//
async download(row) {
let res = await downloadFile({
path: row.path,
});
const fileName = res.headers["content-disposition"].split(";");
const filename2 = fileName[1].split("=");
const filename3 = decodeURIComponent(filename2[1]);
let blob = new Blob([res.data], {
type: res.type,
});
let downloadElement = document.createElement("a");
let href = window.URL.createObjectURL(blob);
downloadElement.href = href;
downloadElement.download = filename3;
document.body.appendChild(downloadElement);
downloadElement.click();
window.URL.revokeObjectURL(href);
},
//
uploadAfter(res, done, loading, column) {
this.tableData.push(res);
done();
this.$message.success("上传成功!");
},
//
deleteFile(index) {
this.$confirm("确定要删除附件吗?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
this.tableData.splice(index, 1);
});
console.log(file);
console.log(column);
},
getForm(processId, processDefKey) {
let param;
@ -172,7 +319,7 @@ export default {
option.column = columnArr;
option.group = groupArr;
this.option = option;
console.log(this.option)
// this.findObject(this.option.column, 'yunweigongsi').disabled = true
//
// const gongshimingcheng = this.findObject(
@ -218,11 +365,4 @@ export default {
-webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.aaa {
// .avue-crud .el-input--small input, .avue-form .el-input--small input {
// width: 420px;
// height: 50px;
// line-height: 50px;
// }
}
</style>

@ -1,59 +1,28 @@
<template>
<basic-container>
<el-container>
<el-aside width="200px">
<wf-category @node-click="nodeClick"
@list-change="findObject(option.column, 'category').dicData = $event"></wf-category>
</el-aside>
<el-main style="margin-left: 10px;">
<template v-if="mode == 'list'">
<avue-crud :class="['animated fadeIn']"
:option="option"
:table-loading="loading"
:data="data"
:page.sync="page"
:permission="permissionList"
v-model="form"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="onLoad(page, query)">
<template #menuLeft
v-if="isDev">
</template>
<template #menuRight>
<el-button size="mini"
circle
icon="el-icon-menu"
@click="handleChangeMode('grid')"></el-button>
</template>
<template slot="menu"
slot-scope="{row}">
<el-button v-if="permission.wf_process_start_flow"
type="text"
size="small"
icon="el-icon-video-play"
@click="dynamicRoute(row, 'start')">发起</el-button>
</template>
</avue-crud>
</template>
<wf-start-grid v-else-if="mode == 'grid'"
:data="data"
:form="query"
@route="dynamicRoute($event, 'start')"
@mode="handleChangeMode"
@search="searchChange"
@reset="searchReset"></wf-start-grid>
</el-main>
</el-container>
</basic-container>
<div class="cus-container">
<div class="content">
<div class="main">
<div class="item" v-for="(item, index) in homepageList" :key="index">
<div class="item-top">
<div>
<div class="title">{{ item.dictValue }}</div>
<div class="subTitle">{{ item.remark }}</div>
</div>
<div class="item-top-right">
<img :src="require(`@/assets/img/gdwel/${item.dictKey}.png`)" alt="" />
</div>
</div>
<div class="btn" @click="dynamicRoute(row, 'start',false,item.id)">立即创建</div>
</div>
</div>
</div>
</div>
</template>
<script>
// v-if="permission.wf_process_start_flow"
import { processList as getList } from "@/api/plugin/workflow/process";
import { getTaskParent } from "@/api/maintenance/task.js"
import { mapGetters } from "vuex";
import exForm from '../mixins/ex-form'
@ -65,143 +34,29 @@ export default {
components: { WfStartGrid, WfCategory },
data() {
return {
mode: 'list',
form: {},
query: {},
loading: true,
homepageList: [],
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
selectionList: [],
option: {
size: 'mini',
height: 'auto',
calcHeight: 30,
tip: false,
border: true,
selection: true,
dialogType: 'drawer',
addBtn: false,
editBtn: false,
delBtn: false,
align: 'center',
searchMenuSpan: 6,
searchSize: 'mini',
column: [
{
label: "流程名称",
prop: "name",
overHidden: true,
search: true
},
// {
// label: "",
// prop: "key",
// overHidden: true,
// search: true
// },
{
label: "流程分类",
row: true,
type: 'tree',
dicData: [],
props: {
label: 'name',
value: 'id'
},
prop: "category",
},
{
label: '版本',
prop: 'version',
width: 90
},
{
label: '状态',
prop: 'status',
dicData: [{
label: '激活',
value: 1
}, {
label: '挂起',
value: 2
}],
},
]
size: 10,
current: 1,
},
data: [],
row: {}
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.vaildData(this.permission.deployment_add, false),
viewBtn: this.vaildData(this.permission.deployment_view, false),
delBtn: this.vaildData(this.permission.deployment_delete, false),
editBtn: this.vaildData(this.permission.deployment_edit, false)
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
},
isDev() {
return process.env.NODE_ENV === "development"
}
},
created() {
this.handleChangeMode(localStorage.getItem("wf-start-mode") || 'list')
this.onLoad()
},
methods: {
handleChangeMode(mode) {
localStorage.setItem("wf-start-mode", mode)
this.mode = mode
if (this.mode == 'grid') this.page.pageSize = 9999
else this.page.pageSize = 10
this.onLoad(this.page, this.query)
},
nodeClick({ id }) {
this.categoryId = id
this.searchChange(this.query)
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.onLoad(this.page, params);
if (done && typeof done == 'function') done()
},
selectionChange(list) {
this.selectionList = list;
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page, this.query)
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page, this.query)
},
onLoad(page, params = {}) {
this.loading = true;
if (this.categoryId) params['category'] = this.categoryId
else delete params['category']
getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
onLoad() {
getTaskParent().then(res => {
this.homepageList = res.data.data
})
const {current,size} = this.page
getList(current,size).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.row = data.records[0];
});
}
}
@ -209,10 +64,52 @@ export default {
</script>
<style lang="scss" scoped>
/deep/ .avue-crud__img {
img {
width: 32px;
height: 32px;
.content {
background: #fff;
height: 760px;
min-height: 760px;
padding: 50px;
box-sizing: border-box;
border-radius: 3px;
}
.main {
display: flex;
flex-wrap: wrap;
.item {
padding: 32px 30px 26px 37px;
box-sizing: border-box;
width: 336px;
height: 184px;
border: 1px solid #cfcfcf;
margin-right: 50px;
margin-bottom: 50px;
.item-top {
margin-bottom: 34px;
display: flex;
justify-content: space-between;
}
.title {
font-size: 20px;
color: #333333;
}
.subTitle {
margin-top: 10px;
color: #999999;
font-size: 14px;
}
.btn {
width: 117px;
height: 37px;
border-radius: 100px 100px 100px 100px;
border: 1px solid #cfcfcf;
font-size: 16px;
color: #666;
text-align: center;
line-height: 37px;
}
}
.item:nth-child(4) {
margin-right: 0;
}
}
</style>
Loading…
Cancel
Save