mirror of https://github.com/certd/certd
🔱: [client] sync upgrade with 8 commits [trident-sync]
perf: 增加自定义组件示例 Merge remote-tracking branch 'origin/main' refactor: fs-bpmn refactor: integration fs-bpmn refactor: 集成fs-bpmn refactor: refactor: 优化i18npull/14/head
parent
aebce2f241
commit
55e05afe0e
|
@ -29,6 +29,7 @@
|
||||||
"@fast-crud/fast-extends": "^1.12.0",
|
"@fast-crud/fast-extends": "^1.12.0",
|
||||||
"@fast-crud/ui-antdv": "^1.12.0",
|
"@fast-crud/ui-antdv": "^1.12.0",
|
||||||
"@fast-crud/ui-interface": "^1.12.0",
|
"@fast-crud/ui-interface": "^1.12.0",
|
||||||
|
"@fast-crud/fast-bpmn": "^1.0.3",
|
||||||
"@iconify/iconify": "^3.1.0",
|
"@iconify/iconify": "^3.1.0",
|
||||||
"@iconify/json": "^2.2.35",
|
"@iconify/json": "^2.2.35",
|
||||||
"@purge-icons/generated": "^0.9.0",
|
"@purge-icons/generated": "^0.9.0",
|
||||||
|
|
|
@ -1,21 +1,13 @@
|
||||||
import { createI18n } from "vue-i18n";
|
import { createI18n } from "vue-i18n";
|
||||||
//@ts-ignore
|
|
||||||
import enFsLocale from "@fast-crud/fast-crud/dist/locale/lang/en.js";
|
|
||||||
//@ts-ignore
|
|
||||||
import zhFsLocale from "@fast-crud/fast-crud/dist/locale/lang/zh-cn.js";
|
|
||||||
import en from "./locale/en";
|
import en from "./locale/en";
|
||||||
import zh from "./locale/zh_CN";
|
import zh from "./locale/zh_CN";
|
||||||
const messages = {
|
const messages = {
|
||||||
en: {
|
en: {
|
||||||
label: "English",
|
label: "English",
|
||||||
// 定义您自己的字典,但是请不要和 `fs` 重复,这样会导致 fast-crud 内部组件的翻译失效.
|
|
||||||
fs: enFsLocale.fs,
|
|
||||||
...en
|
...en
|
||||||
},
|
},
|
||||||
"zh-cn": {
|
"zh-cn": {
|
||||||
label: "简体中文",
|
label: "简体中文",
|
||||||
// 定义您自己的字典,但是请不要和 `fs` 重复,这样会导致 fast-crud 内部组件的翻译失效.
|
|
||||||
fs: zhFsLocale.fs,
|
|
||||||
...zh
|
...zh
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,6 @@ import components from "./components";
|
||||||
import plugin from "./plugin/";
|
import plugin from "./plugin/";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
// 尽量
|
|
||||||
app.use(Antd);
|
app.use(Antd);
|
||||||
app.use(router);
|
app.use(router);
|
||||||
app.use(i18n);
|
app.use(i18n);
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
import "@fast-crud/fast-bpmn/dist/style.css";
|
||||||
|
import FastBpmn, { FsBpmnSetupOptions, PanelComponentItem, Base, Shape } from "@fast-crud/fast-bpmn";
|
||||||
|
|
||||||
|
const fsBpmnOpts: FsBpmnSetupOptions = {
|
||||||
|
// 注册panel公共组件
|
||||||
|
// @ts-ignore
|
||||||
|
registerPanelComponents(element: Base): Record<string, PanelComponentItem> {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
//自定义增强contextPad
|
||||||
|
createEnhancementContextPadActions(provider) {
|
||||||
|
const actions: Record<string, any> = {};
|
||||||
|
const appendUserTask = (event: Event, element: Shape) => {
|
||||||
|
const shape = provider.elementFactory.createShape({ type: "bpmn:UserTask" });
|
||||||
|
provider.create.start(event, shape, {
|
||||||
|
source: element
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const append = provider.autoPlace
|
||||||
|
? // @ts-ignore
|
||||||
|
(event: Event, element: Shape) => {
|
||||||
|
const shape = provider.elementFactory.createShape({ type: "bpmn:UserTask" });
|
||||||
|
provider.autoPlace.append(element, shape);
|
||||||
|
}
|
||||||
|
: appendUserTask;
|
||||||
|
|
||||||
|
// 添加创建用户任务按钮
|
||||||
|
actions["append.append-user-task"] = {
|
||||||
|
group: "model",
|
||||||
|
className: "bpmn-icon-user-task",
|
||||||
|
title: "用户任务",
|
||||||
|
action: {
|
||||||
|
dragstart: appendUserTask,
|
||||||
|
click: append
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加一个与edit一组的按钮
|
||||||
|
actions["enhancement-op-1"] = {
|
||||||
|
group: "edit",
|
||||||
|
className: "enhancement-op",
|
||||||
|
title: "扩展操作1",
|
||||||
|
action: {
|
||||||
|
// @ts-ignore
|
||||||
|
click: function (e: Event) {
|
||||||
|
alert("点击 扩展操作1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加一个新分组的自定义按钮
|
||||||
|
actions["enhancement-op"] = {
|
||||||
|
group: "enhancement",
|
||||||
|
className: "enhancement-op",
|
||||||
|
title: "扩展操作2",
|
||||||
|
action: {
|
||||||
|
// @ts-ignore
|
||||||
|
click: function (e: Event) {
|
||||||
|
alert("点击 扩展操作2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
},
|
||||||
|
|
||||||
|
//自定义重写contextPad
|
||||||
|
// @ts-ignore
|
||||||
|
createRewriteContextPadActions(provider: any, element: Base) {
|
||||||
|
const actions: Record<string, any> = {};
|
||||||
|
|
||||||
|
// 添加一个与edit一组的按钮
|
||||||
|
actions["enhancement-op-1"] = {
|
||||||
|
group: "edit",
|
||||||
|
className: "enhancement-op",
|
||||||
|
title: "扩展操作1",
|
||||||
|
action: {
|
||||||
|
// @ts-ignore
|
||||||
|
click: function (e: Event) {
|
||||||
|
alert("点击 扩展操作1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加一个新分组的自定义按钮
|
||||||
|
actions["enhancement-op"] = {
|
||||||
|
group: "enhancement",
|
||||||
|
className: "enhancement-op",
|
||||||
|
title: "扩展操作2",
|
||||||
|
action: {
|
||||||
|
// @ts-ignore
|
||||||
|
click: function (e: Event) {
|
||||||
|
alert("点击 扩展操作2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
} as FsBpmnSetupOptions;
|
||||||
|
|
||||||
|
export default function (app: any, i18n: any) {
|
||||||
|
fsBpmnOpts.i18n = i18n.global;
|
||||||
|
app.use(FastBpmn, fsBpmnOpts);
|
||||||
|
}
|
|
@ -2,9 +2,12 @@ import "./iconify";
|
||||||
import "./iconfont";
|
import "./iconfont";
|
||||||
import FastCrud from "./fast-crud";
|
import FastCrud from "./fast-crud";
|
||||||
import permission from "./permission";
|
import permission from "./permission";
|
||||||
|
import FsBpmn from "./bpmn";
|
||||||
|
|
||||||
function install(app: any, options: any = {}) {
|
function install(app: any, options: any = {}) {
|
||||||
app.use(FastCrud, options);
|
app.use(FastCrud, options);
|
||||||
app.use(permission);
|
app.use(permission);
|
||||||
|
app.use(FsBpmn, options.i18n);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import LayoutFramework from "/src/layout/layout-framework.vue";
|
import LayoutFramework from "/src/layout/layout-framework.vue";
|
||||||
import { crudResources } from "/@/router/source/modules/crud";
|
import { crudResources } from "/@/router/source/modules/crud";
|
||||||
import { uiResources } from "/@/router/source/modules/ui";
|
import { uiResources } from "/@/router/source/modules/ui";
|
||||||
|
import { integrationResources } from "/@/router/source/modules/integration";
|
||||||
import { sysResources } from "/@/router/source/modules/sys";
|
import { sysResources } from "/@/router/source/modules/sys";
|
||||||
export const frameworkResource = [
|
export const frameworkResource = [
|
||||||
{
|
{
|
||||||
|
@ -25,6 +26,7 @@ export const frameworkResource = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
...crudResources,
|
...crudResources,
|
||||||
|
...integrationResources,
|
||||||
...sysResources
|
...sysResources
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,12 @@ export const crudResources = [
|
||||||
path: "/crud/basis/layout-custom",
|
path: "/crud/basis/layout-custom",
|
||||||
component: "/crud/basis/layout-custom/index.vue"
|
component: "/crud/basis/layout-custom/index.vue"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "自定义组件",
|
||||||
|
name: "BasisCustom",
|
||||||
|
path: "/crud/basis/custom",
|
||||||
|
component: "/crud/basis/custom/index.vue"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "列设置",
|
title: "列设置",
|
||||||
name: "BasisColumnsSet",
|
name: "BasisColumnsSet",
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
export const integrationResources = [
|
||||||
|
{
|
||||||
|
title: "集成",
|
||||||
|
name: "integration",
|
||||||
|
path: "/integration",
|
||||||
|
redirect: "/integration/bpmn",
|
||||||
|
meta: {
|
||||||
|
icon: "ion:apps-sharp"
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: "FsBpmn",
|
||||||
|
name: "FsBpmn",
|
||||||
|
path: "/integration/bpmn",
|
||||||
|
component: "/integration/bpmn/index.vue",
|
||||||
|
meta: {
|
||||||
|
icon: "ion:disc-outline"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { requestForMock } from "/src/api/service";
|
||||||
|
const request = requestForMock;
|
||||||
|
const apiPrefix = "/mock/BasisCustom";
|
||||||
|
export function GetList(query: any) {
|
||||||
|
return request({
|
||||||
|
url: apiPrefix + "/page",
|
||||||
|
method: "get",
|
||||||
|
data: query
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AddObj(obj: any) {
|
||||||
|
return request({
|
||||||
|
url: apiPrefix + "/add",
|
||||||
|
method: "post",
|
||||||
|
data: obj
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UpdateObj(obj: any) {
|
||||||
|
return request({
|
||||||
|
url: apiPrefix + "/update",
|
||||||
|
method: "post",
|
||||||
|
data: obj
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DelObj(id: any) {
|
||||||
|
return request({
|
||||||
|
url: apiPrefix + "/delete",
|
||||||
|
method: "post",
|
||||||
|
params: { id }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetObj(id: any) {
|
||||||
|
return request({
|
||||||
|
url: apiPrefix + "/info",
|
||||||
|
method: "get",
|
||||||
|
params: { id }
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
import * as api from "./api";
|
||||||
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
|
import { shallowRef } from "vue";
|
||||||
|
import VmodelCounter from "./vmodel-counter.vue";
|
||||||
|
import { message } from "ant-design-vue";
|
||||||
|
|
||||||
|
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
|
return await api.GetList(query);
|
||||||
|
};
|
||||||
|
const editRequest = async ({ form, row }: EditReq) => {
|
||||||
|
form.id = row.id;
|
||||||
|
return await api.UpdateObj(form);
|
||||||
|
};
|
||||||
|
const delRequest = async ({ row }: DelReq) => {
|
||||||
|
return await api.DelObj(row.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addRequest = async ({ form }: AddReq) => {
|
||||||
|
return await api.AddObj(form);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudOptions: {
|
||||||
|
request: {
|
||||||
|
pageRequest,
|
||||||
|
addRequest,
|
||||||
|
editRequest,
|
||||||
|
delRequest
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
id: {
|
||||||
|
title: "ID",
|
||||||
|
key: "id",
|
||||||
|
type: "number",
|
||||||
|
column: {
|
||||||
|
width: 50
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
counter: {
|
||||||
|
title: "自定义组件",
|
||||||
|
type: "text",
|
||||||
|
column: {
|
||||||
|
component: {
|
||||||
|
//引用自定义组件
|
||||||
|
name: shallowRef(VmodelCounter),
|
||||||
|
color: "blue",
|
||||||
|
slots: {
|
||||||
|
//插槽示例
|
||||||
|
default() {
|
||||||
|
return <span>counter on cell:</span>;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
//监听事件
|
||||||
|
onChange({ $event, row }) {
|
||||||
|
message.info("counter changed:" + $event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
//form表单
|
||||||
|
component: {
|
||||||
|
//引用自定义组件
|
||||||
|
name: shallowRef(VmodelCounter),
|
||||||
|
vModel: "modelValue",
|
||||||
|
color: "red",
|
||||||
|
on: {
|
||||||
|
//监听事件
|
||||||
|
onChange({ $event, form }) {
|
||||||
|
message.info("counter changed:" + $event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
slots: {
|
||||||
|
//插槽示例
|
||||||
|
default() {
|
||||||
|
return <span>counter on form:</span>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
show: true,
|
||||||
|
//form表单
|
||||||
|
component: {
|
||||||
|
color: "yellow",
|
||||||
|
slots: {
|
||||||
|
//插槽示例
|
||||||
|
default() {
|
||||||
|
return "counter:";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cellRender: {
|
||||||
|
title: "单元格render",
|
||||||
|
type: "text",
|
||||||
|
column: {
|
||||||
|
cellRender({ value }) {
|
||||||
|
return <a-tag>{value}</a-tag>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formAroundRender: {
|
||||||
|
title: "表单组件周围的render",
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
helper: "演示组件周围自定义render",
|
||||||
|
topRender({ value }) {
|
||||||
|
return <a-tag color="red">topRender</a-tag>;
|
||||||
|
},
|
||||||
|
bottomRender({ value }) {
|
||||||
|
return <a-tag color="red">bottomRender {value ?? ""}</a-tag>;
|
||||||
|
},
|
||||||
|
prefixRender({ value }) {
|
||||||
|
return <a-tag color="red">prefixRender</a-tag>;
|
||||||
|
},
|
||||||
|
suffixRender({ value }) {
|
||||||
|
return <a-tag color="red">suffixRender</a-tag>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formRender: {
|
||||||
|
title: "字段组件本身render",
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
helper: "组件本身render",
|
||||||
|
render({ form }) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<a-input v-model={[form.formRender, "value"]} />
|
||||||
|
render value : {form.formRender}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<fs-page>
|
||||||
|
<template #header>
|
||||||
|
<div class="title">自定义组件</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, onMounted } from "vue";
|
||||||
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "./crud.js";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "BasisCustom",
|
||||||
|
setup() {
|
||||||
|
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudBinding,
|
||||||
|
crudRef,
|
||||||
|
...context
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,22 @@
|
||||||
|
import mockUtil from "/src/mock/base";
|
||||||
|
const options: any = {
|
||||||
|
name: "BasisCustom",
|
||||||
|
idGenerator: 0
|
||||||
|
};
|
||||||
|
const list = [
|
||||||
|
{
|
||||||
|
counter: 1,
|
||||||
|
cellRender: "cellRender1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
counter: 2,
|
||||||
|
cellRender: "cellRender2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
counter: 3,
|
||||||
|
cellRender: "cellRender3"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
options.list = list;
|
||||||
|
const mock = mockUtil.buildMock(options);
|
||||||
|
export default mock;
|
|
@ -0,0 +1,45 @@
|
||||||
|
<template>
|
||||||
|
<a-tooltip title="点击我自增">
|
||||||
|
<a-tag :color="color" @click="onClick">
|
||||||
|
<!-- 插槽示例 -->
|
||||||
|
<slot></slot>
|
||||||
|
<span> {{ modelValue }}</span>
|
||||||
|
</a-tag>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, watch } from "vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "VmodelCounter",
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: "success"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["update:modelValue", "change"],
|
||||||
|
setup(props, ctx) {
|
||||||
|
function onClick() {
|
||||||
|
//发射modelValue更新事件,父组件引用时只需要v-model={xxx}即可
|
||||||
|
ctx.emit("update:modelValue", props.modelValue + 1);
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
(value) => {
|
||||||
|
ctx.emit("change", value);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
onClick
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,144 @@
|
||||||
|
<template>
|
||||||
|
<component :is="ui.collapseItem.name" name="element-documentations">
|
||||||
|
<template #header>
|
||||||
|
<collapse-title :title="$t('panel.userAssign')">
|
||||||
|
<lucide-icon name="FileText" />
|
||||||
|
</collapse-title>
|
||||||
|
</template>
|
||||||
|
<edit-item :label="$t('panel.userType')" :label-width="120">
|
||||||
|
<component
|
||||||
|
:is="ui.select.name"
|
||||||
|
class="w-full"
|
||||||
|
v-bind="
|
||||||
|
ui.select.builder({
|
||||||
|
props: {
|
||||||
|
options: userTypeOptions
|
||||||
|
},
|
||||||
|
vModel: vModeler('userType')
|
||||||
|
}).props
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</edit-item>
|
||||||
|
<edit-item v-if="formData.userType === 'assignUser'" :label="$t('panel.assignUser')" :label-width="120">
|
||||||
|
<component
|
||||||
|
:is="ui.select.name"
|
||||||
|
class="w-full"
|
||||||
|
v-bind="
|
||||||
|
ui.select.builder({
|
||||||
|
multiple: false,
|
||||||
|
options: userList,
|
||||||
|
valueName: 'id',
|
||||||
|
labelName: 'name',
|
||||||
|
vModel: vModeler('assignUser')
|
||||||
|
}).props
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</edit-item>
|
||||||
|
|
||||||
|
<edit-item v-if="formData.userType === 'candidateUsers'" :label="$t('panel.candidateUsers')" :label-width="120">
|
||||||
|
<component
|
||||||
|
:is="ui.select.name"
|
||||||
|
class="w-full"
|
||||||
|
v-bind="
|
||||||
|
ui.select.builder({
|
||||||
|
multiple: true,
|
||||||
|
options: userList,
|
||||||
|
valueName: 'id',
|
||||||
|
labelName: 'name',
|
||||||
|
vModel: vModeler('candidateUsers')
|
||||||
|
}).props
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</edit-item>
|
||||||
|
<edit-item v-if="formData.userType === 'candidateGroups'" :label="$t('panel.candidateGroups')" :label-width="120">
|
||||||
|
<component
|
||||||
|
:is="ui.select.name"
|
||||||
|
class="w-full"
|
||||||
|
v-bind="
|
||||||
|
ui.select.builder({
|
||||||
|
multiple: true,
|
||||||
|
options: groupList,
|
||||||
|
valueName: 'id',
|
||||||
|
labelName: 'name',
|
||||||
|
vModel: vModeler('candidateGroups')
|
||||||
|
}).props
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</edit-item>
|
||||||
|
</component>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, Ref, ref } from "vue";
|
||||||
|
import { useUi } from "@fast-crud/ui-interface";
|
||||||
|
import { useModelerStore, Base } from "@fast-crud/fast-bpmn";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "ElementUserAssign",
|
||||||
|
setup() {
|
||||||
|
const { ui } = useUi();
|
||||||
|
|
||||||
|
const userTypeOptions = ref([
|
||||||
|
{ value: "assignUser", label: "直接指派" },
|
||||||
|
{ value: "candidateUsers", label: "候选人" },
|
||||||
|
{ value: "candidateGroups", label: "候选组" }
|
||||||
|
]);
|
||||||
|
const userList = ref([
|
||||||
|
{ id: "1", username: "admin", name: "管理员" },
|
||||||
|
{ id: "2", username: "zhangsan", name: "张三" },
|
||||||
|
{ id: "3", username: "lisi", name: "李四" }
|
||||||
|
]);
|
||||||
|
const groupList = ref([
|
||||||
|
{ id: "1", name: "总经办" },
|
||||||
|
{ id: "2", name: "研发部" },
|
||||||
|
{ id: "3", name: "测试部" }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// import { injectModelerStore } from '../lib/store/modeler'
|
||||||
|
// import { getProcessProperty, setProcessProperty } from '../lib/bo-utils/processUtil'
|
||||||
|
const { injectModelerStore } = useModelerStore();
|
||||||
|
const modelerStore = injectModelerStore();
|
||||||
|
|
||||||
|
const getActive = computed(() => modelerStore!.getActive!);
|
||||||
|
// const getActiveId = computed(() => modelerStore!.getActiveId!)
|
||||||
|
|
||||||
|
const bpmnExpose = modelerStore.expose;
|
||||||
|
console.log("bpmnExpose", bpmnExpose);
|
||||||
|
const boUtils = bpmnExpose.boUtils;
|
||||||
|
const getProcessProperty = boUtils.processUtil.getProcessProperty;
|
||||||
|
const setProcessProperty = boUtils.processUtil.setProcessProperty;
|
||||||
|
|
||||||
|
const formData: Ref = ref({});
|
||||||
|
|
||||||
|
function loadFromModel() {
|
||||||
|
formData.value = {
|
||||||
|
userType: getProcessProperty(getActive.value as Base, "userType"),
|
||||||
|
assignUser: getProcessProperty(getActive.value as Base, "assignUser"),
|
||||||
|
candidateUsers: getProcessProperty(getActive.value as Base, "candidateUsers"),
|
||||||
|
candidateGroups: getProcessProperty(getActive.value as Base, "candidateGroups")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
modelerStore.eventer.on("element-update", () => {
|
||||||
|
loadFromModel();
|
||||||
|
});
|
||||||
|
|
||||||
|
function vModeler(key: string) {
|
||||||
|
const valueKey = key ? "value." + key : "value";
|
||||||
|
return {
|
||||||
|
ref: formData,
|
||||||
|
key: valueKey,
|
||||||
|
onChange: (value: any) => {
|
||||||
|
onPropertyChange(key, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPropertyChange(key: string, value: any) {
|
||||||
|
setProcessProperty(modelerStore, getActive.value as Base, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ui, userTypeOptions, vModeler, formData, userList, groupList };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,126 @@
|
||||||
|
<template>
|
||||||
|
<div class="fs-bpmn-demo-page">
|
||||||
|
<div class="header">
|
||||||
|
<component :is="ui.tabs.name" v-model:active-key="activeKey" type="card">
|
||||||
|
<component :is="ui.tabPane.name" key="designer" tab="设计器"> </component>
|
||||||
|
</component>
|
||||||
|
<div>
|
||||||
|
<span class="m-l"> showExtensionProperties <a-switch v-model:checked="binding.showExtensionProperties" /> </span>
|
||||||
|
<span class="m-l"> showNameAndCode<a-switch v-model:checked="binding.showNameAndCode" /> </span>
|
||||||
|
<span class="m-l"></span>
|
||||||
|
<span class="m-l"> showToolbar<a-switch v-model:checked="binding.showToolbar" /> </span>
|
||||||
|
<span class="m-l"> showMiniMap<a-switch v-model:checked="binding.showMinimap" /> </span>
|
||||||
|
<span class="m-l"> showPanel<a-switch v-model:checked="binding.showPanel" /> </span>
|
||||||
|
<span class="m-l"> showSettings<a-switch v-model:checked="binding.showSettings" /> </span>
|
||||||
|
<span class="m-l"> showPalette<a-switch v-model:checked="binding.showPalette" /> </span>
|
||||||
|
<span class="m-l"> showContextMenu<a-switch v-model:checked="binding.showContextMenu" /> </span>
|
||||||
|
<fs-bpmn-preview-demo></fs-bpmn-preview-demo>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<fs-bpmn v-model:xml="xmlRef" :panel="panelProps" v-bind="binding"></fs-bpmn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import zhCN from "ant-design-vue/es/locale/zh_CN";
|
||||||
|
|
||||||
|
import { defineComponent, Ref, ref } from "vue";
|
||||||
|
import FsBpmnPreviewDemo from "./preview.vue";
|
||||||
|
import { demoXml } from "./xml";
|
||||||
|
import { useUi } from "@fast-crud/ui-interface";
|
||||||
|
import { FsBpmnPanelProps, Base } from "@fast-crud/fast-bpmn";
|
||||||
|
import ElementUserAssign from "./ElementUserAssign.vue";
|
||||||
|
|
||||||
|
const FsBpmnDemo = defineComponent({
|
||||||
|
components: { FsBpmnPreviewDemo },
|
||||||
|
setup() {
|
||||||
|
const localRef = ref(zhCN);
|
||||||
|
const xmlRef = ref(demoXml);
|
||||||
|
const { ui } = useUi();
|
||||||
|
const activeKey = ref("designer");
|
||||||
|
const binding: Ref = ref({
|
||||||
|
showToolbar: true,
|
||||||
|
showMinimap: true,
|
||||||
|
showPanel: true,
|
||||||
|
showSettings: false,
|
||||||
|
showPalette: true,
|
||||||
|
showContextMenu: true,
|
||||||
|
showNameAndCode: true,
|
||||||
|
showExtensionProperties: true
|
||||||
|
});
|
||||||
|
const panelProps = ref<FsBpmnPanelProps>({
|
||||||
|
//注册自定义组件
|
||||||
|
registerComponents() {
|
||||||
|
//也可以写在 bpmn-setup进行全局注册
|
||||||
|
return {
|
||||||
|
ElementUserAssign: {
|
||||||
|
order: 3,
|
||||||
|
component: ElementUserAssign,
|
||||||
|
props: {},
|
||||||
|
show(element: any) {
|
||||||
|
//什么情况下显示此组件, element为当前选中的元素节点
|
||||||
|
return element.type === "bpmn:UserTask";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
//重新设置组件配置
|
||||||
|
resetComponents(elements, components) {
|
||||||
|
//ElementGenerations
|
||||||
|
//ElementDocumentations
|
||||||
|
//ElementJobExecution
|
||||||
|
//ElementExtensionProperties
|
||||||
|
//ElementExecutionListeners
|
||||||
|
//ElementAsyncContinuations
|
||||||
|
//ElementStartInitiator
|
||||||
|
//ElementUserAssign
|
||||||
|
components.ElementGenerations.props.showNameAndCode = binding.value.showNameAndCode;
|
||||||
|
|
||||||
|
components.ElementDocumentations.show = true;
|
||||||
|
|
||||||
|
if (binding.value.showExtensionProperties === false) {
|
||||||
|
components.ElementExtensionProperties.show = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
localRef,
|
||||||
|
xmlRef,
|
||||||
|
ui,
|
||||||
|
activeKey,
|
||||||
|
panelProps,
|
||||||
|
binding
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default FsBpmnDemo;
|
||||||
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
.fs-bpmn-demo-page {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.header {
|
||||||
|
padding: 20px 20px 0 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
.ant-tabs-nav {
|
||||||
|
padding: 0px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.ant-tabs-content {
|
||||||
|
height: 100%;
|
||||||
|
.ant-tabs-tabpane {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<component :is="ui.button.name" @click="openPreview">预览</component>
|
||||||
|
|
||||||
|
<component :is="ui.dialog.name" v-if="dialogShow" v-model:[ui.dialog.visible]="dialogShow" title="预览" :width="1200">
|
||||||
|
<fs-bpmn-preview v-if="processXmlRef" :xml="processXmlRef" :highlight="highlightRef" style="height: 600px"></fs-bpmn-preview>
|
||||||
|
</component>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="tsx">
|
||||||
|
import { defineComponent, Ref, ref } from "vue";
|
||||||
|
import { useUi } from "@fast-crud/ui-interface";
|
||||||
|
import { demoXml } from "./xml";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "FsBpmnPreviewDemo",
|
||||||
|
setup() {
|
||||||
|
const { ui } = useUi();
|
||||||
|
const processXmlRef: Ref = ref();
|
||||||
|
const highlightRef: Ref<any[]> = ref([]);
|
||||||
|
const dialogShow = ref(false);
|
||||||
|
function openPreview() {
|
||||||
|
processXmlRef.value = demoXml;
|
||||||
|
//type 暂时无所谓
|
||||||
|
highlightRef.value = [{ id: "Activity_1evmidl", type: "node", flicker: true }, { id: "Gateway_01mlwlp", type: "node" }, { id: "Event_0u7us6f", type: "node" }, { id: "Flow_0z7lqtc" }, { id: "Flow_1xxl1vf" }];
|
||||||
|
dialogShow.value = true;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
ui,
|
||||||
|
processXmlRef,
|
||||||
|
highlightRef,
|
||||||
|
openPreview,
|
||||||
|
dialogShow
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,27 @@
|
||||||
|
export const demoXml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_Process_1679537772748" targetNamespace="http://bpmn.io/schema/bpmn">
|
||||||
|
<bpmn:process id="Process_1679537772748" name="业务流程_1679537772748" isExecutable="true">
|
||||||
|
<bpmn:startEvent id="Event_0u7us6f"><bpmn:outgoing>Flow_0z7lqtc</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0z7lqtc" sourceRef="Event_0u7us6f" targetRef="Activity_1evmidl" />
|
||||||
|
<bpmn:userTask id="Activity_08zwh5z" name="二级审批" camunda:candidateGroups="1" camunda:userType="candidateGroups">
|
||||||
|
<bpmn:incoming>Flow_1rf2bmg</bpmn:incoming><bpmn:outgoing>Flow_06ulhtm</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1xxl1vf" sourceRef="Activity_1evmidl" targetRef="Gateway_01mlwlp" />
|
||||||
|
<bpmn:userTask id="Activity_1evmidl" name="一级审批" camunda:candidateGroups="2" camunda:userType="candidateGroups">
|
||||||
|
<bpmn:incoming>Flow_0z7lqtc</bpmn:incoming><bpmn:incoming>Flow_1p9en55</bpmn:incoming><bpmn:outgoing>Flow_1xxl1vf</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:endEvent id="Event_0lu13jx"><bpmn:incoming>Flow_06ulhtm</bpmn:incoming></bpmn:endEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_06ulhtm" sourceRef="Activity_08zwh5z" targetRef="Event_0lu13jx" />
|
||||||
|
<bpmn:exclusiveGateway id="Gateway_01mlwlp"><bpmn:incoming>Flow_1xxl1vf</bpmn:incoming><bpmn:outgoing>Flow_1rf2bmg</bpmn:outgoing><bpmn:outgoing>Flow_11pwko7</bpmn:outgoing></bpmn:exclusiveGateway>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1rf2bmg" sourceRef="Gateway_01mlwlp" targetRef="Activity_08zwh5z" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_11pwko7" sourceRef="Gateway_01mlwlp" targetRef="Activity_15z3qp6" />
|
||||||
|
<bpmn:userTask id="Activity_15z3qp6" name="修改" camunda:userType="assignUser" camunda:assignUser="2">
|
||||||
|
<bpmn:incoming>Flow_11pwko7</bpmn:incoming><bpmn:outgoing>Flow_1p9en55</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1p9en55" sourceRef="Activity_15z3qp6" targetRef="Activity_1evmidl" />
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1679537772748"><bpmndi:BPMNShape id="Event_0u7us6f_di" bpmnElement="Event_0u7us6f"><dc:Bounds x="252" y="172" width="36" height="36" /></bpmndi:BPMNShape><bpmndi:BPMNShape id="Activity_0qkxfyi_di" bpmnElement="Activity_1evmidl"><dc:Bounds x="388" y="130" width="120" height="120" /><bpmndi:BPMNLabel /></bpmndi:BPMNShape><bpmndi:BPMNShape id="Activity_08zwh5z_di" bpmnElement="Activity_08zwh5z"><dc:Bounds x="730" y="130" width="120" height="120" /><bpmndi:BPMNLabel /></bpmndi:BPMNShape><bpmndi:BPMNShape id="Gateway_01mlwlp_di" bpmnElement="Gateway_01mlwlp" isMarkerVisible="true"><dc:Bounds x="595" y="165" width="50" height="50" /></bpmndi:BPMNShape><bpmndi:BPMNShape id="Activity_0qiby6r_di" bpmnElement="Activity_15z3qp6"><dc:Bounds x="560" y="350" width="120" height="120" /><bpmndi:BPMNLabel /></bpmndi:BPMNShape><bpmndi:BPMNShape id="Event_0lu13jx_di" bpmnElement="Event_0lu13jx"><dc:Bounds x="952" y="172" width="36" height="36" /></bpmndi:BPMNShape><bpmndi:BPMNEdge id="Flow_0z7lqtc_di" bpmnElement="Flow_0z7lqtc"><di:waypoint x="288" y="190" /><di:waypoint x="388" y="190" /></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="Flow_1xxl1vf_di" bpmnElement="Flow_1xxl1vf"><di:waypoint x="508" y="190" /><di:waypoint x="595" y="190" /></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="Flow_06ulhtm_di" bpmnElement="Flow_06ulhtm"><di:waypoint x="850" y="190" /><di:waypoint x="952" y="190" /></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="Flow_1rf2bmg_di" bpmnElement="Flow_1rf2bmg"><di:waypoint x="645" y="190" /><di:waypoint x="730" y="190" /></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="Flow_11pwko7_di" bpmnElement="Flow_11pwko7"><di:waypoint x="620" y="215" /><di:waypoint x="620" y="350" /></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="Flow_1p9en55_di" bpmnElement="Flow_1p9en55"><di:waypoint x="560" y="410" /><di:waypoint x="448" y="410" /><di:waypoint x="448" y="250" /></bpmndi:BPMNEdge></bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>`;
|
|
@ -23,11 +23,11 @@ export default ({ command, mode }) => {
|
||||||
if (mode.startsWith("debug")) {
|
if (mode.startsWith("debug")) {
|
||||||
devAlias = [
|
devAlias = [
|
||||||
{ find: /@fast-crud\/fast-crud\/dist/, replacement: path.resolve("../../fast-crud/src/") },
|
{ find: /@fast-crud\/fast-crud\/dist/, replacement: path.resolve("../../fast-crud/src/") },
|
||||||
{ find: /@fast-crud\/fast-crud$/, replacement: path.resolve("../../fast-crud/src/") },
|
// { find: /@fast-crud\/fast-crud$/, replacement: path.resolve("../../fast-crud/src/") },
|
||||||
{ find: /@fast-crud\/fast-extends\/dist/, replacement: path.resolve("../../fast-extends/src/") },
|
{ find: /@fast-crud\/fast-extends\/dist/, replacement: path.resolve("../../fast-extends/src/") }
|
||||||
{ find: /@fast-crud\/fast-extends$/, replacement: path.resolve("../../fast-extends/src/") },
|
// { find: /@fast-crud\/fast-extends$/, replacement: path.resolve("../../fast-extends/src/") },
|
||||||
{ find: /@fast-crud\/ui-antdv$/, replacement: path.resolve("../../ui/ui-antdv/src/") },
|
// { find: /@fast-crud\/ui-antdv$/, replacement: path.resolve("../../ui/ui-antdv/src/") },
|
||||||
{ find: /@fast-crud\/ui-interface$/, replacement: path.resolve("../../ui/ui-interface/src/") }
|
// { find: /@fast-crud\/ui-interface$/, replacement: path.resolve("../../ui/ui-interface/src/") }
|
||||||
];
|
];
|
||||||
devServerFs = {
|
devServerFs = {
|
||||||
// 这里配置dev启动时读取的项目根目录
|
// 这里配置dev启动时读取的项目根目录
|
||||||
|
|
Loading…
Reference in New Issue