表单预览和修改

This commit is contained in:
cxc
2022-12-20 16:32:39 +08:00
parent a0c3e7bd00
commit 9b33e7e846
14 changed files with 743 additions and 223 deletions

8
jsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}

View File

@ -52,6 +52,7 @@
"unplugin-auto-import": "0.11.4", "unplugin-auto-import": "0.11.4",
"vite": "3.2.3", "vite": "3.2.3",
"vite-plugin-compression": "0.5.1", "vite-plugin-compression": "0.5.1",
"vite-plugin-node-polyfills": "^0.5.0",
"vite-plugin-svg-icons": "2.0.1", "vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-setup-extend": "0.4.0" "vite-plugin-vue-setup-extend": "0.4.0"
} }

View File

@ -1,8 +1,20 @@
import request from "@/utils/request"; import request from "@/utils/request";
export const listCategory = (query) => export const listAllCategory = (query) =>
request({ request({
url: "/flowable/category/list", url: "/flowable/category/list",
method: "get", method: "get",
params: query, params: query,
}); });
export const addCategory = (data) =>
request({
url: "/flowable/category",
method: "post",
data
});
export const delCategory = (ids) =>
request({
url: "/flowable/category",
method: "delete",
data: { ids }
});

View File

@ -0,0 +1,51 @@
import request from '@/utils/request'
// 查询流程部署列表
export function listDeploy(query) {
return request({
url: '/workflow/deploy/list',
method: 'get',
params: query
})
}
export function listPublish(query) {
return request({
url: '/workflow/deploy/publishList',
method: 'get',
params: query
})
}
// 获取流程模型流程图
export function getBpmnXml(definitionId) {
return request({
url: '/workflow/deploy/bpmnXml/' + definitionId,
method: 'get'
})
}
// 修改流程状态
export function changeState(params) {
return request({
url: '/workflow/deploy/changeState',
method: 'put',
params: params
})
}
// 删除流程部署
export function delDeploy(deployIds) {
return request({
url: '/workflow/deploy/' + deployIds,
method: 'delete'
})
}
// 查询流程部署关联表单信息
export function getFormByDeployId(deployId) {
return request({
url: '/workflow/deploy/form/' + deployId,
method: 'get',
})
}

View File

@ -127,7 +127,6 @@ import ElementProperties from "./properties/ElementProperties";
import ElementForm from "./form/ElementForm"; import ElementForm from "./form/ElementForm";
import UserTaskListeners from "./listeners/UserTaskListeners"; import UserTaskListeners from "./listeners/UserTaskListeners";
import { provide, toRefs, watch } from "vue"; import { provide, toRefs, watch } from "vue";
import useBpmnStore from "@/store/modules/bpmn";
const props = defineProps({ const props = defineProps({
bpmnModeler: Object, bpmnModeler: Object,

View File

@ -1,5 +1,3 @@
import useBpmnStore from "@/store/modules/bpmn";
const bpmnStore = useBpmnStore();
// 创建监听器实例 // 创建监听器实例
export function createListenerObject(options, isTask, prefix) { export function createListenerObject(options, isTask, prefix) {
const listenerObj = Object.create(null); const listenerObj = Object.create(null);

View File

@ -1,59 +1,66 @@
import { deepClone } from '@/utils/index'; import { deepClone } from "@/utils/index";
import { getToken } from '@/utils/auth'; import { getToken } from "@/utils/auth";
import render from '@/utils/generator/render'; import render from "@/utils/generator/render";
import axios from 'axios' import axios from "axios";
import Vue from 'vue'; import { defineComponent } from "vue";
Vue.prototype.$axios = axios // Vue.prototype.$axios = axios;
const ruleTrigger = { const ruleTrigger = {
'el-input': 'blur', "el-input": "blur",
'el-input-number': 'blur', "el-input-number": "blur",
'el-select': 'change', "el-select": "change",
'el-radio-group': 'change', "el-radio-group": "change",
'el-checkbox-group': 'change', "el-checkbox-group": "change",
'el-cascader': 'change', "el-cascader": "change",
'el-time-picker': 'change', "el-time-picker": "change",
'el-date-picker': 'change', "el-date-picker": "change",
'el-rate': 'change', "el-rate": "change",
'el-upload': 'change' "el-upload": "change",
} };
const layouts = { const layouts = {
colFormItem(h, scheme) { colFormItem(h, scheme) {
const config = scheme.__config__ const config = scheme.__config__;
const listeners = buildListeners.call(this, scheme) const listeners = buildListeners.call(this, scheme);
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null;
if (config.showLabel === false) labelWidth = '0' if (config.showLabel === false) labelWidth = "0";
return ( return (
<el-col span={config.span}> <el-col span={config.span}>
<el-form-item label-width={labelWidth} prop={scheme.__vModel__} <el-form-item
label={config.showLabel ? config.label : ''}> label-width={labelWidth}
prop={scheme.__vModel__}
label={config.showLabel ? config.label : ""}
>
<render conf={scheme} on={listeners} /> <render conf={scheme} on={listeners} />
</el-form-item> </el-form-item>
</el-col> </el-col>
) );
}, },
rowFormItem(h, scheme) { rowFormItem(h, scheme) {
let child = renderChildren.apply(this, arguments) let child = renderChildren.apply(this, arguments);
if (scheme.type === 'flex') { if (scheme.type === "flex") {
child = <el-row type={scheme.type} justify={scheme.justify} align={scheme.align}> child = (
{child} <el-row
</el-row> type={scheme.type}
justify={scheme.justify}
align={scheme.align}
>
{child}
</el-row>
);
} }
return ( return (
<el-col span={scheme.span}> <el-col span={scheme.span}>
<el-row gutter={scheme.gutter}> <el-row gutter={scheme.gutter}>{child}</el-row>
{child}
</el-row>
</el-col> </el-col>
) );
} },
} };
function renderFrom(h) { function renderFrom(h) {
const { formConfCopy } = this const { formConfCopy } = this;
return ( return (
<el-row gutter={formConfCopy.gutter}> <el-row gutter={formConfCopy.gutter}>
@ -71,173 +78,181 @@ function renderFrom(h) {
{formConfCopy.formBtns && formBtns.call(this, h)} {formConfCopy.formBtns && formBtns.call(this, h)}
</el-form> </el-form>
</el-row> </el-row>
) );
} }
function formBtns(h) { function formBtns(h) {
return <el-col> return (
<el-form-item size="large"> <el-col>
<el-button type="primary" onClick={this.submitForm}>提交</el-button> <el-form-item size="large">
<el-button onClick={this.resetForm}>重置</el-button> <el-button type="primary" onClick={this.submitForm}>
</el-form-item> 提交
</el-col> </el-button>
<el-button onClick={this.resetForm}>重置</el-button>
</el-form-item>
</el-col>
);
} }
function renderFormItem(h, elementList) { function renderFormItem(h, elementList) {
return elementList.map(scheme => { return elementList.map((scheme) => {
const config = scheme.__config__ const config = scheme.__config__;
const layout = layouts[config.layout] const layout = layouts[config.layout];
if (layout) { if (layout) {
return layout.call(this, h, scheme) return layout.call(this, h, scheme);
} }
throw new Error(`没有与${config.layout}匹配的layout`) throw new Error(`没有与${config.layout}匹配的layout`);
}) });
} }
function renderChildren(h, scheme) { function renderChildren(h, scheme) {
const config = scheme.__config__ const config = scheme.__config__;
if (!Array.isArray(config.children)) return null if (!Array.isArray(config.children)) return null;
return renderFormItem.call(this, h, config.children) return renderFormItem.call(this, h, config.children);
} }
function setValue(event, config, scheme) { function setValue(event, config, scheme) {
this.$set(config, 'defaultValue', event) this.$set(config, "defaultValue", event);
this.$set(this[this.formConf.formModel], scheme.__vModel__, event) this.$set(this[this.formConf.formModel], scheme.__vModel__, event);
} }
function buildListeners(scheme) { function buildListeners(scheme) {
const config = scheme.__config__ const config = scheme.__config__;
const methods = this.formConf.__methods__ || {} const methods = this.formConf.__methods__ || {};
const listeners = {} const listeners = {};
// 给__methods__中的方法绑定this和event // 给__methods__中的方法绑定this和event
Object.keys(methods).forEach(key => { Object.keys(methods).forEach((key) => {
listeners[key] = event => methods[key].call(this, event) listeners[key] = (event) => methods[key].call(this, event);
}) });
// 响应 render.js 中的 vModel $emit('input', val) // 响应 render.js 中的 vModel $emit('input', val)
listeners.input = event => setValue.call(this, event, config, scheme) listeners.input = (event) => setValue.call(this, event, config, scheme);
return listeners return listeners;
} }
export default { export default defineComponent({
components: { components: {
render render,
}, },
props: { props: {
formConf: { formConf: {
type: Object, type: Object,
required: true required: true,
} },
}, },
data() { data() {
const data = { const data = {
formConfCopy: deepClone(this.formConf), formConfCopy: deepClone(this.formConf),
[this.formConf.formModel]: {}, [this.formConf.formModel]: {},
[this.formConf.formRules]: {} [this.formConf.formRules]: {},
} };
this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel]) this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel]);
this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules]) this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules]);
return data return data;
}, },
methods: { methods: {
initFormData(componentList, formData) { initFormData(componentList, formData) {
componentList.forEach(cur => { componentList.forEach((cur) => {
this.buildOptionMethod(cur) this.buildOptionMethod(cur);
const config = cur.__config__; const config = cur.__config__;
if (cur.__vModel__) { if (cur.__vModel__) {
formData[cur.__vModel__] = config.defaultValue; formData[cur.__vModel__] = config.defaultValue;
// 初始化文件列表 // 初始化文件列表
if (cur.action && config.defaultValue) { if (cur.action && config.defaultValue) {
cur['file-list'] = config.defaultValue; cur["file-list"] = config.defaultValue;
} }
} }
if (cur.action) { if (cur.action) {
cur['headers'] = { cur["headers"] = {
Authorization: "Bearer " + getToken(), Authorization: "Bearer " + getToken(),
} };
cur['on-success'] = (res, file, fileList) => { cur["on-success"] = (res, file, fileList) => {
formData[cur.__vModel__] = fileList; formData[cur.__vModel__] = fileList;
if (res.code === 200 && fileList) { if (res.code === 200 && fileList) {
config.defaultValue = fileList; config.defaultValue = fileList;
config.defaultValue.forEach(val => { config.defaultValue.forEach((val) => {
val.url = file.response.data.url; val.url = file.response.data.url;
val.ossId = file.response.data.ossId; val.ossId = file.response.data.ossId;
val.response = null val.response = null;
}) });
} }
}; };
// 点击文件列表中已上传的文件时的钩子 // 点击文件列表中已上传的文件时的钩子
cur['on-preview'] = (file) => { cur["on-preview"] = (file) => {
this.$download.oss(file.ossId) this.$download.oss(file.ossId);
} };
} }
if (config.children) { if (config.children) {
this.initFormData(config.children, formData); this.initFormData(config.children, formData);
} }
}) });
}, },
// 特殊处理的 Option // 特殊处理的 Option
buildOptionMethod(scheme) { buildOptionMethod(scheme) {
const config = scheme.__config__; const config = scheme.__config__;
if (config && config.tag === 'el-cascader') { if (config && config.tag === "el-cascader") {
if (config.dataType === 'dynamic') { if (config.dataType === "dynamic") {
this.$axios({ this.$axios({
method: config.method, method: config.method,
url: config.url url: config.url,
}).then(resp => { }).then((resp) => {
var { data } = resp var { data } = resp;
scheme[config.dataConsumer] = data[config.dataKey] scheme[config.dataConsumer] = data[config.dataKey];
}); });
} }
} }
}, },
buildRules(componentList, rules) { buildRules(componentList, rules) {
componentList.forEach(cur => { componentList.forEach((cur) => {
const config = cur.__config__ const config = cur.__config__;
if (Array.isArray(config.regList)) { if (Array.isArray(config.regList)) {
if (config.required) { if (config.required) {
const required = { required: config.required, message: cur.placeholder } const required = {
required: config.required,
message: cur.placeholder,
};
if (Array.isArray(config.defaultValue)) { if (Array.isArray(config.defaultValue)) {
required.type = 'array' required.type = "array";
required.message = `请至少选择一个${config.label}` required.message = `请至少选择一个${config.label}`;
} }
required.message === undefined && (required.message = `${config.label}不能为空`) required.message === undefined &&
config.regList.push(required) (required.message = `${config.label}不能为空`);
config.regList.push(required);
} }
rules[cur.__vModel__] = config.regList.map(item => { rules[cur.__vModel__] = config.regList.map((item) => {
item.pattern && (item.pattern = eval(item.pattern)) item.pattern && (item.pattern = eval(item.pattern));
item.trigger = ruleTrigger && ruleTrigger[config.tag] item.trigger = ruleTrigger && ruleTrigger[config.tag];
return item return item;
}) });
} }
if (config.children) this.buildRules(config.children, rules) if (config.children) this.buildRules(config.children, rules);
}) });
}, },
resetForm() { resetForm() {
this.formConfCopy = deepClone(this.formConf) this.formConfCopy = deepClone(this.formConf);
this.$refs[this.formConf.formRef].resetFields() this.$refs[this.formConf.formRef].resetFields();
}, },
submitForm() { submitForm() {
this.$refs[this.formConf.formRef].validate(valid => { this.$refs[this.formConf.formRef].validate((valid) => {
if (!valid) return false if (!valid) return false;
const params = { const params = {
formData: this.formConfCopy, formData: this.formConfCopy,
valData: this[this.formConf.formModel] valData: this[this.formConf.formModel],
} };
this.$emit('submit', params) this.$emit("submit", params);
return true return true;
}) });
}, },
// 传值给父组件 // 传值给父组件
getData(){ getData() {
debugger debugger;
this.$emit('getData', this[this.formConf.formModel]) this.$emit("getData", this[this.formConf.formModel]);
// this.$emit('getData',this.formConfCopy) // this.$emit('getData',this.formConfCopy)
} },
}, },
render(h) { render(h) {
return renderFrom.call(this, h) return renderFrom.call(this, h);
} },
} });

View File

@ -145,7 +145,7 @@
<!-- 添加或修改请填写功能名称对话框 --> <!-- 添加或修改请填写功能名称对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="分类名称" prop="categoryName"> <el-form-item label="分类名称" prop="categoryName">
<el-input v-model="form.categoryName" placeholder="请输入分类名称" /> <el-input v-model="form.categoryName" placeholder="请输入分类名称" />
</el-form-item> </el-form-item>
@ -172,12 +172,13 @@
<script setup> <script setup>
import { import {
listCategory, listAllCategory,
// getCategory, // getCategory,
// delCategory, delCategory,
// addCategory, addCategory,
// updateCategory, // updateCategory,
} from "@/api/flowable/category"; } from "@/api/flowable/category";
import { ElMessage, ElMessageBox } from "element-plus";
import { ref } from "vue"; import { ref } from "vue";
// 按钮loading // 按钮loading
const buttonLoading = ref(false); const buttonLoading = ref(false);
@ -199,6 +200,8 @@ const categoryList = ref([]);
const title = ref(""); const title = ref("");
// 是否显示弹出层 // 是否显示弹出层
const open = ref(false); const open = ref(false);
const formRef = ref();
const data = reactive({ const data = reactive({
// 查询参数 // 查询参数
queryParams: { queryParams: {
@ -226,7 +229,7 @@ const { queryParams, form, rules } = toRefs(data);
/** 查询【请填写功能名称】列表 */ /** 查询【请填写功能名称】列表 */
function getList() { function getList() {
loading.value = true; loading.value = true;
listCategory(queryParams.value).then((response) => { listAllCategory(queryParams.value).then((response) => {
categoryList.value = response.rows; categoryList.value = response.rows;
total.value = response.total; total.value = response.total;
loading.value = false; loading.value = false;
@ -234,12 +237,12 @@ function getList() {
} }
// 取消按钮 // 取消按钮
function cancel() { function cancel() {
this.open = false; open.value = false;
this.reset(); reset();
} }
// 表单重置 // 表单重置
function reset() { function reset() {
this.form = { form.value = {
categoryId: undefined, categoryId: undefined,
categoryName: undefined, categoryName: undefined,
code: undefined, code: undefined,
@ -250,7 +253,9 @@ function reset() {
remark: undefined, remark: undefined,
delFlag: undefined, delFlag: undefined,
}; };
this.resetForm("form"); if (formRef.value) {
formRef.value.resetFields();
}
} }
/** 搜索按钮操作 */ /** 搜索按钮操作 */
function handleQuery() { function handleQuery() {
@ -270,9 +275,9 @@ function handleSelectionChange(selection) {
} }
/** 新增按钮操作 */ /** 新增按钮操作 */
function handleAdd() { function handleAdd() {
this.reset(); reset();
this.open = true; open.value = true;
this.title = "添加流程分类"; title.value = "添加流程分类";
} }
/** 修改按钮操作 */ /** 修改按钮操作 */
function handleUpdate(row) { function handleUpdate(row) {
@ -288,28 +293,28 @@ function handleUpdate(row) {
} }
/** 提交按钮 */ /** 提交按钮 */
function submitForm() { function submitForm() {
this.$refs["form"].validate((valid) => { formRef.value.validate((valid) => {
if (valid) { if (valid) {
this.buttonLoading = true; buttonLoading.value = true;
if (this.form.categoryId != null) { if (form.value.categoryId != null) {
updateCategory(this.form) updateCategory(form.value)
.then((response) => { .then((response) => {
this.$modal.msgSuccess("修改成功"); ElMessage.success("修改成功");
this.open = false; open.value = false;
this.getList(); getList();
}) })
.finally(() => { .finally(() => {
this.buttonLoading = false; buttonLoading.value = false;
}); });
} else { } else {
addCategory(this.form) addCategory(form.value)
.then((response) => { .then((response) => {
this.$modal.msgSuccess("新增成功"); ElMessage.success("新增成功");
this.open = false; open.value = false;
this.getList(); getList();
}) })
.finally(() => { .finally(() => {
this.buttonLoading = false; buttonLoading.value = false;
}); });
} }
} }
@ -317,22 +322,21 @@ function submitForm() {
} }
/** 删除按钮操作 */ /** 删除按钮操作 */
function handleDelete(row) { function handleDelete(row) {
const categoryIds = row.categoryId || this.ids; const categoryIds = [{ id: row.categoryId, uuid: row.uuid }] || ids.value;
this.$modal ElMessageBox.confirm(
.confirm( '是否确认删除【请填写功能名称】编号为"' + categoryIds + '"的数据项?'
'是否确认删除【请填写功能名称】编号为"' + categoryIds + '"的数据项?' )
)
.then(() => { .then(() => {
this.loading = true; loading.value = true;
return delCategory(categoryIds); return delCategory(categoryIds);
}) })
.then(() => { .then(() => {
this.loading = false; loading.value = false;
this.getList(); getList();
this.$modal.msgSuccess("删除成功"); ElMessage.success("删除成功");
}) })
.finally(() => { .finally(() => {
this.loading = false; loading.value = false;
}); });
} }
/** 导出按钮操作 */ /** 导出按钮操作 */

View File

@ -0,0 +1,429 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="流程标识" prop="processKey">
<el-input
v-model="queryParams.processKey"
placeholder="请输入流程标识"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="processName">
<el-input
v-model="queryParams.processName"
placeholder="请输入流程名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select
v-model="queryParams.category"
clearable
placeholder="请选择"
size="small"
>
<el-option
v-for="item in categoryOptions"
:key="item.categoryId"
:label="item.categoryName"
:value="item.code"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="state">
<el-select
v-model="queryParams.state"
size="small"
clearable
placeholder="请选择状态"
>
<el-option :key="1" label="激活" value="active" />
<el-option :key="2" label="挂起" value="suspended" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="search"
size="small"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="refresh" size="small" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="small"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['workflow:deploy:remove']"
>删除</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-row :gutter="10" class="mb8">
<el-table
v-loading="loading"
fit
:data="deployList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="流程标识"
align="center"
prop="processKey"
:show-overflow-tooltip="true"
/>
<el-table-column
label="流程名称"
align="center"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<el-button type="text" @click="handleProcessView(scope.row)">
<span>{{ scope.row.processName }}</span>
</el-button>
</template>
</el-table-column>
<el-table-column
label="流程分类"
align="center"
prop="categoryName"
:formatter="categoryFormat"
/>
<el-table-column label="流程版本" align="center">
<template slot-scope="scope">
<el-tag size="default">v{{ scope.row.version }}</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<el-tag type="success" v-if="!scope.row.suspended">激活</el-tag>
<el-tag type="warning" v-if="scope.row.suspended">挂起</el-tag>
</template>
</el-table-column>
<el-table-column
label="部署时间"
align="center"
prop="deploymentTime"
width="180"
/>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
type="text"
size="small"
icon="el-icon-price-tag"
@click.native="handlePublish(scope.row)"
v-hasPermi="['workflow:deploy:list']"
>版本管理</el-button
>
<el-button
type="text"
size="small"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['workflow:deploy:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-row>
<!-- 流程图 -->
<el-dialog
:title="processView.title"
v-model="processView.open"
width="70%"
append-to-body
>
<process-viewer
:key="`designer-${processView.index}`"
:xml="processView.xmlData"
:style="{ height: '400px' }"
/>
</el-dialog>
<!-- 版本管理 -->
<el-dialog
title="版本管理"
v-model="publish.open"
width="50%"
append-to-body
>
<el-table v-loading="publish.loading" :data="publish.dataList">
<el-table-column
label="流程标识"
align="center"
prop="processKey"
:show-overflow-tooltip="true"
/>
<el-table-column
label="流程名称"
align="center"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<el-button type="text" @click="handleProcessView(scope.row)">
<span>{{ scope.row.processName }}</span>
</el-button>
</template>
</el-table-column>
<el-table-column label="流程版本" align="center">
<template slot-scope="scope">
<el-tag size="default">v{{ scope.row.version }}</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<el-tag type="success" v-if="!scope.row.suspended">激活</el-tag>
<el-tag type="warning" v-if="scope.row.suspended">挂起</el-tag>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
type="text"
size="small"
icon="video-pause"
v-if="!scope.row.suspended"
@click.native="handleChangeState(scope.row, 'suspended')"
v-hasPermi="['workflow:deploy:status']"
>挂起</el-button
>
<el-button
type="text"
size="small"
icon="video-play"
v-if="scope.row.suspended"
@click.native="handleChangeState(scope.row, 'active')"
v-hasPermi="['workflow:deploy:status']"
>激活</el-button
>
<el-button
type="text"
size="small"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['workflow:deploy:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="publishTotal > 0"
:total="publishTotal"
v-model:page="publishQueryParams.pageNum"
v-model:limit="publishQueryParams.pageSize"
@pagination="getPublishList"
/>
</el-dialog>
</div>
</template>
<script setup name="Deploy">
import { listAllCategory } from "@/api/flowable/category";
import {
listDeploy,
listPublish,
getBpmnXml,
changeState,
delDeploy,
} from "@/api/flowable/deploy";
import ProcessViewer from "@/components/ProcessViewer";
import { ElMessage, ElMessageBox } from "element-plus";
import { ref } from "vue";
// 遮罩层
const loading = ref(true);
// 选中数组
const ids = ref([]);
// 非单个禁用
const single = ref(true);
// 非多个禁用
const multiple = ref(true);
// 显示搜索条件
const showSearch = ref(true);
// 总条数
const total = ref(0);
const deployList = ref([]);
const categoryOptions = ref([]);
const publishTotal = ref(0);
const data = reactive({
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: null,
processName: null,
category: null,
state: null,
},
processView: {
title: "",
open: false,
index: undefined,
xmlData: "",
},
publish: {
open: false,
loading: false,
dataList: [],
},
publishQueryParams: {
pageNum: 1,
pageSize: 10,
processKey: "",
},
});
const { queryParams, processView, publish, publishQueryParams } = toRefs(data);
getCategoryList();
getList();
/** 查询流程分类列表 */
function getCategoryList() {
listAllCategory().then((response) => (categoryOptions.value = response.data));
}
/** 查询流程部署列表 */
function getList() {
loading.value = true;
listDeploy(queryParams.value).then((response) => {
deployList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
// 表单重置
function reset() {
form.value = {
id: null,
processKey: null,
processName: null,
category: null,
state: null,
};
resetForm("form");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
resetForm("queryForm");
handleQuery();
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.deploymentId);
single.value = selection.length !== 1;
multiple.value = !selection.length;
}
/** 查看流程图 */
function handleProcessView(row) {
let definitionId = row.definitionId;
processView.value.title = "流程图";
processView.value.index = definitionId;
// 发送请求获取xml
getBpmnXml(definitionId).then((response) => {
processView.value.xmlData = response.data;
});
processView.value.open = true;
}
function getPublishList() {
publish.value.loading = true;
listPublish(publishQueryParams.value).then((response) => {
publish.value.dataList = response.rows;
publishTotal.value = response.total;
publish.value.loading = false;
});
}
function handlePublish(row) {
publishQueryParams.value.processKey = row.processKey;
publish.value.open = true;
getPublishList();
}
/** 挂起/激活流程 */
function handleChangeState(row, state) {
const params = {
definitionId: row.definitionId,
state: state,
};
changeState(params).then((res) => {
ElMessage.success(res.msg);
getPublishList();
});
}
function handleDelete(row) {
const deploymentIds = row.deploymentId || ids.value;
ElMessageBox.confirm("是否确认删除选中的数据项?")
.then(() => {
loading.value = true;
return delDeploy(deploymentIds);
})
.then(() => {
loading.value = false;
getList();
ElMessage.success("删除成功");
})
.finally(() => {
loading.value = false;
});
}
function categoryFormat(row, column) {
return (
categoryOptions.value.find((k) => k.code === row.category)?.categoryName ??
""
);
}
</script>
<style scoped></style>

View File

@ -19,12 +19,12 @@
<el-form-item> <el-form-item>
<el-button <el-button
type="primary" type="primary"
icon="el-icon-search" icon="search"
size="mini" size="small"
@click="handleQuery" @click="handleQuery"
>搜索</el-button >搜索</el-button
> >
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery" <el-button icon="refresh" size="small" @click="resetQuery"
>重置</el-button >重置</el-button
> >
</el-form-item> </el-form-item>
@ -35,10 +35,10 @@
<el-button <el-button
type="primary" type="primary"
plain plain
icon="el-icon-plus" icon="plus"
size="mini" size="small"
@click="handleAdd" @click="handleAdd"
v-hasPermi="['workflow:form:add']" v-hasPermi="['flowable:form:add']"
>新增</el-button >新增</el-button
> >
</el-col> </el-col>
@ -46,11 +46,11 @@
<el-button <el-button
type="success" type="success"
plain plain
icon="el-icon-edit" icon="edit"
size="mini" size="small"
:disabled="single" :disabled="single"
@click="handleUpdate" @click="handleUpdate"
v-hasPermi="['workflow:form:edit']" v-hasPermi="['flowable:form:edit']"
>修改</el-button >修改</el-button
> >
</el-col> </el-col>
@ -58,11 +58,11 @@
<el-button <el-button
type="danger" type="danger"
plain plain
icon="el-icon-delete" icon="delete"
size="mini" size="small"
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleDelete"
v-hasPermi="['workflow:form:remove']" v-hasPermi="['flowable:form:remove']"
>删除</el-button >删除</el-button
> >
</el-col> </el-col>
@ -70,15 +70,15 @@
<el-button <el-button
type="warning" type="warning"
plain plain
icon="el-icon-download" icon="download"
size="mini" size="small"
@click="handleExport" @click="handleExport"
v-hasPermi="['workflow:form:export']" v-hasPermi="['flowable:form:export']"
>导出</el-button >导出</el-button
> >
</el-col> </el-col>
<right-toolbar <right-toolbar
:showSearch.sync="showSearch" v-model:showSearch="showSearch"
@queryTable="getList" @queryTable="getList"
></right-toolbar> ></right-toolbar>
</el-row> </el-row>
@ -97,28 +97,26 @@
align="center" align="center"
class-name="small-padding fixed-width" class-name="small-padding fixed-width"
> >
<template slot-scope="scope"> <template #default="{ row }">
<el-button <el-button size="small" link icon="view" @click="handleDetail(row)"
size="mini"
link
icon="el-icon-view"
@click="handleDetail(scope.row)"
>详情</el-button >详情</el-button
> >
<el-button <el-button
size="mini" size="small"
type="warning"
link link
icon="el-icon-edit" icon="edit"
@click="handleUpdate(scope.row)" @click="handleUpdate(row)"
v-hasPermi="['workflow:form:edit']" v-hasPermi="['flowable:form:edit']"
>修改</el-button >修改</el-button
> >
<el-button <el-button
size="mini" size="small"
type="danger"
link link
icon="el-icon-delete" icon="delete"
@click="handleDelete(scope.row)" @click="handleDelete(row)"
v-hasPermi="['workflow:form:remove']" v-hasPermi="['flowable:form:remove']"
>删除</el-button >删除</el-button
> >
</template> </template>
@ -128,13 +126,13 @@
<pagination <pagination
v-show="total > 0" v-show="total > 0"
:total="total" :total="total"
:page.sync="queryParams.pageNum" v-model:page="queryParams.pageNum"
:limit.sync="queryParams.pageSize" v-model:limit="queryParams.pageSize"
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改流程表单对话框 --> <!-- 添加或修改流程表单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="表单名称" prop="formName"> <el-form-item label="表单名称" prop="formName">
<el-input v-model="form.formName" placeholder="请输入表单名称" /> <el-input v-model="form.formName" placeholder="请输入表单名称" />
@ -146,16 +144,18 @@
<el-input v-model="form.remark" placeholder="请输入备注" /> <el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <template #footer>
<el-button type="primary" @click="submitForm"> </el-button> <div class="dialog-footer">
<el-button @click="cancel"> </el-button> <el-button type="primary" @click="submitForm"> </el-button>
</div> <el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog> </el-dialog>
<!--表单配置详情--> <!--表单配置详情-->
<el-dialog <el-dialog
:title="formTitle" :title="formTitle"
:visible.sync="formConfOpen" v-model="formConfOpen"
width="60%" width="60%"
append-to-body append-to-body
> >
@ -176,6 +176,7 @@ import {
} from "@/api/flowable/form"; } from "@/api/flowable/form";
import Editor from "@/components/Editor"; import Editor from "@/components/Editor";
import Parser from "@/utils/generator/parser"; import Parser from "@/utils/generator/parser";
import { ElMessage, ElMessageBox } from "element-plus";
import { reactive } from "vue"; import { reactive } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
@ -272,19 +273,12 @@ function handleAdd() {
// this.reset(); // this.reset();
// this.open = true; // this.open = true;
// this.title = "添加流程表单"; // this.title = "添加流程表单";
router.push({ path: "/tool/build/index", query: { formId: null } }); router.push({ path: "/flowable/form/build", query: { formId: null } });
} }
/** 修改按钮操作 */ /** 修改按钮操作 */
function handleUpdate(row) { function handleUpdate(row) {
// this.reset();
// const formId = row.formId || this.ids
// getForm(formId).then(response => {
// this.form = response.data;
// this.open = true;
// this.title = "修改流程表单";
// });
router.push({ router.push({
path: "/tool/build/index", path: "/flowable/form/build",
query: { formId: row.formId }, query: { formId: row.formId },
}); });
} }
@ -310,8 +304,8 @@ function submitForm() {
} }
/** 删除按钮操作 */ /** 删除按钮操作 */
function handleDelete(row) { function handleDelete(row) {
const formIds = row.formId || this.ids; const formIds = row.formId || ids.value;
this.$confirm( ElMessageBox.confirm(
'是否确认删除流程表单编号为"' + formIds + '"的数据项?', '是否确认删除流程表单编号为"' + formIds + '"的数据项?',
"警告", "警告",
{ {
@ -324,8 +318,8 @@ function handleDelete(row) {
return delForm(formIds); return delForm(formIds);
}) })
.then(() => { .then(() => {
this.getList(); getList();
this.$modal.msgSuccess("删除成功"); ElMessage.success("删除成功");
}); });
} }
/** 导出按钮操作 */ /** 导出按钮操作 */

View File

@ -451,7 +451,7 @@ import {
delModel, delModel,
deployModel, deployModel,
} from "@/api/flowable/model"; } from "@/api/flowable/model";
import { listCategory } from "@/api/flowable/category"; import { listAllCategory } from "@/api/flowable/category";
import { ArrowDown } from "@element-plus/icons-vue"; import { ArrowDown } from "@element-plus/icons-vue";
import ProcessDesigner from "@/components/ProcessDesigner"; import ProcessDesigner from "@/components/ProcessDesigner";
import ProcessViewer from "@/components/ProcessViewer"; import ProcessViewer from "@/components/ProcessViewer";
@ -557,7 +557,7 @@ const {
/** 查询流程分类列表 */ /** 查询流程分类列表 */
function getCategoryList() { function getCategoryList() {
listCategory().then((response) => (categoryOptions.value = response.rows)); listAllCategory().then((response) => (categoryOptions.value = response.rows));
} }
/** 查询流程模型列表 */ /** 查询流程模型列表 */
function getList() { function getList() {
@ -608,12 +608,12 @@ function handleDeploy(row) {
.then((response) => { .then((response) => {
ElMessage.success(response.msg); ElMessage.success(response.msg);
let obj = { name: "Deploy", path: "/workflow/deploy" }; let obj = { name: "Deploy", path: "/workflow/deploy" };
return this.$store // return this.$store
.dispatch("tagsView/delCachedView", obj) // .dispatch("tagsView/delCachedView", obj)
.then(() => { // .then(() => {
this.$router.push(obj); // this.$router.push(obj);
}); // });
}) })
.finally(() => { .finally(() => {
loading.value = false; loading.value = false;
@ -826,6 +826,7 @@ getCategoryList();
<style scoped> <style scoped>
.model-operation { .model-operation {
display: flex; display: flex;
flex-wrap: wrap;
align-items: center; align-items: center;
} }
</style> </style>

View File

@ -165,6 +165,7 @@
</template> </template>
<script setup> <script setup>
import { addForm, getForm, updateForm } from "@/api/flowable/form";
import { debounce } from "throttle-debounce"; import { debounce } from "throttle-debounce";
import ClipboardJS from "clipboard"; import ClipboardJS from "clipboard";
import draggable from "vuedraggable"; import draggable from "vuedraggable";
@ -193,6 +194,7 @@ import {
} from "@/utils/generator/html"; } from "@/utils/generator/html";
import { makeUpJs } from "@/utils/generator/js"; import { makeUpJs } from "@/utils/generator/js";
import { makeUpCss } from "@/utils/generator/css"; import { makeUpCss } from "@/utils/generator/css";
import tab from "@/plugins/tab";
import { import {
getDrawingList, getDrawingList,
saveDrawingList, saveDrawingList,
@ -202,11 +204,12 @@ import {
} from "@/utils/db"; } from "@/utils/db";
import { nextTick, onMounted, reactive, ref, toRefs, watch } from "vue"; import { nextTick, onMounted, reactive, ref, toRefs, watch } from "vue";
import axios from "axios"; import axios from "axios";
import { useRoute } from "vue-router"; import { useRoute, useRouter } from "vue-router";
let tempActiveData; let tempActiveData;
let oldActiveId; let oldActiveId;
const route = useRoute(); const route = useRoute();
const router = useRouter();
const drawingListInDB = getDrawingList(); const drawingListInDB = getDrawingList();
const formConfInDB = getFormConf(); const formConfInDB = getFormConf();
const idGlobal = ref(getIdGlobal()); const idGlobal = ref(getIdGlobal());
@ -508,8 +511,8 @@ const refreshJson = (data) => {
/** 保存表单信息 */ /** 保存表单信息 */
const submitForm = () => { const submitForm = () => {
formRef.value.validate((valid) => { formRef.value.validate((valid) => {
console.log(formObj.value); // console.log(formObj.value);
return; // return;
if (valid) { if (valid) {
if (formObj.value.formId != null) { if (formObj.value.formId != null) {
updateForm(formObj.value).then((response) => { updateForm(formObj.value).then((response) => {
@ -524,8 +527,8 @@ const submitForm = () => {
idGlobal.value = 100; idGlobal.value = 100;
open.value = false; open.value = false;
//TODO: 关闭当前标签页并返回上个页面 //TODO: 关闭当前标签页并返回上个页面
// this.$store.dispatch("tagsView/delView", this.$route); tab.closeOpenPage();
// this.$router.go(-1); router.back();
} }
}); });
}; };

View File

@ -19,7 +19,7 @@ export default defineConfig(({ mode, command }) => {
"~": path.resolve(__dirname, "./"), "~": path.resolve(__dirname, "./"),
// 设置别名 // 设置别名
"@": path.resolve(__dirname, "./src"), "@": path.resolve(__dirname, "./src"),
stream: "stream-browserify", // stream: "stream-browserify",
}, },
// https://cn.vitejs.dev/config/#resolve-extensions // https://cn.vitejs.dev/config/#resolve-extensions
extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"], extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"],

View File

@ -5,6 +5,7 @@ import createSvgIcon from "./svg-icon";
import createCompression from "./compression"; import createCompression from "./compression";
import createSetupExtend from "./setup-extend"; import createSetupExtend from "./setup-extend";
import vueJsx from "@vitejs/plugin-vue-jsx"; import vueJsx from "@vitejs/plugin-vue-jsx";
import { nodePolyfills } from 'vite-plugin-node-polyfills'
export default function createVitePlugins(viteEnv, isBuild = false) { export default function createVitePlugins(viteEnv, isBuild = false) {
const vitePlugins = [ const vitePlugins = [
@ -13,6 +14,10 @@ export default function createVitePlugins(viteEnv, isBuild = false) {
transformOn: true, transformOn: true,
// include: ["src/**/*.vue", "src/**/*.jsx"], // include: ["src/**/*.vue", "src/**/*.jsx"],
}), }),
nodePolyfills({
// Whether to polyfill `node:` protocol imports.
protocolImports: true,
}),
]; ];
vitePlugins.push(createAutoImport()); vitePlugins.push(createAutoImport());
vitePlugins.push(createSetupExtend()); vitePlugins.push(createSetupExtend());