44 changed files with 713 additions and 334 deletions
@ -0,0 +1,27 @@ |
|||||
|
import type { OptionItemType } from '@/platform/types'; |
||||
|
import { i18n } from '@/platform/plugin'; |
||||
|
import { Tools } from '@/platform/utils'; |
||||
|
|
||||
|
class DictionaryFormater { |
||||
|
#dictionaryMap = {}; |
||||
|
|
||||
|
constructor(options: OptionItemType[]) { |
||||
|
for (const option of options) { |
||||
|
if (!Tools.isUndefinedOrNull(option.value)) { |
||||
|
this.#dictionaryMap[option.value] = option.label; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public formater() { |
||||
|
const dictionaryMap = this.#dictionaryMap; |
||||
|
return (value) => { |
||||
|
if (!Tools.isUndefinedOrNull(value)) { |
||||
|
return i18n.global.t(dictionaryMap[value]); |
||||
|
} |
||||
|
return ''; |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export { DictionaryFormater }; |
@ -0,0 +1,26 @@ |
|||||
|
import type { OptionItemType } from '@/platform/types'; |
||||
|
import { i18n } from '@/platform/plugin'; |
||||
|
|
||||
|
class DictionaryOptions { |
||||
|
#options; |
||||
|
|
||||
|
constructor(options: OptionItemType[]) { |
||||
|
this.#options = options; |
||||
|
} |
||||
|
|
||||
|
public options() { |
||||
|
if (this.#options) { |
||||
|
const result = []; |
||||
|
for (const option of this.#options) { |
||||
|
result.push({ |
||||
|
value: option.value, |
||||
|
label: i18n.global.t(option.label), |
||||
|
}); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
return []; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export { DictionaryOptions }; |
@ -0,0 +1,6 @@ |
|||||
|
import type {OptionItemType} from './OptionItemType'; |
||||
|
|
||||
|
export type DictionaryType = { |
||||
|
name: string; |
||||
|
items: OptionItemType[]; |
||||
|
}; |
@ -0,0 +1,21 @@ |
|||||
|
import type { DictionaryType } from '@/platform/types'; |
||||
|
import { axios, Environment } from '@/platform/plugin'; |
||||
|
|
||||
|
class DictionaryTools { |
||||
|
public static async fetch(code: string): DictionaryType { |
||||
|
const response = await axios.get(Environment.apiContextPath('/api/dictionary/list/') + code); |
||||
|
if (response) { |
||||
|
return { |
||||
|
name: code, |
||||
|
items: response.data, |
||||
|
}; |
||||
|
} else { |
||||
|
return { |
||||
|
name: code, |
||||
|
items: [], |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export { DictionaryTools }; |
@ -0,0 +1,33 @@ |
|||||
|
[appendix] |
||||
|
= ICCAP |
||||
|
ICAAP(Internal Capital Adequacy Assessment Process) 即内部资本充足率评估程序。 |
||||
|
|
||||
|
== 资本充足率(CAR: Capital adequacy ratio) |
||||
|
资本充足率是一个银行的资本总额对其风险加权资产的比率, 资本充足率反映商业银行在存款人和债权人的资产遭到损失之前, |
||||
|
该银行能以自有资本承担损失的程度。规定该项指标的目的在于抑制风险资产的过度膨胀,保护存款人和其他债权人的利益、 |
||||
|
保证银行等金融机构正常运营和发展。各国金融管理当局一般都有对商业银行资本充足率的管制,目的是监测银行抵御风险的能力。 |
||||
|
|
||||
|
资本充足率有不同的口径,主要比率有资本对存款的比率、资本对负债的比率、资本对总资产的比率、资本对风险资产的比率等。 |
||||
|
|
||||
|
资本充足率 =(资本-资本扣除项)/(信用风险加权资产+(操作风险资本+市场风险资本)*12.5) |
||||
|
|
||||
|
. 资本 =核心资本 + 附属资本(二级资本) |
||||
|
-- |
||||
|
核心资本包括: 实收资本或普通股股本、资本公积、盈余公积、未分配利润和少数股权。 |
||||
|
附属资本包括: 重估储备、未公开储备、普通呆账准备、混合债务工具和长期次级债务。 |
||||
|
-- |
||||
|
. 资本扣除项包括:(一)商誉;(二)商业银行对未并表金融机构的资本投资;(三)商业银行对非自用不动产和企业的资本投资。 |
||||
|
. 风险加权资产为对应资产负债表上的资产乘以相应风险系数求和所得到的带有风险的资产额。商业银行计算各项贷款的风险加权资产时,应首先从贷款账面价值中扣除专项准备;其他各类资产的减值准备,也应从相应资产的账面价值中扣除。 |
||||
|
|
||||
|
资产包含: |
||||
|
|
||||
|
. 第一类资产(实际贡献的所有者权益),即银行不用停止交易即可以化解风险的资产; |
||||
|
. 第二类资产(优先股加50%的附属债务),停业清理可以化解风险的资产,对储户提供相对较少额度的保护。 |
||||
|
|
||||
|
规定现金和政府债券没有风险,居民抵押贷款 50% 风险,其他所有类型资产 100% 风险。 |
||||
|
|
||||
|
|
||||
|
|
||||
|
== 所有者权益(Owners' Equity) |
||||
|
所有者权益 =资产 - 负债 |
||||
|
|
@ -1,6 +1,7 @@ |
|||||
{ |
{ |
||||
"includes":[ |
"includes":[ |
||||
"io/sc/platform/flowable/i18n/initializer", |
"io/sc/platform/flowable/i18n/initializer", |
||||
"io/sc/platform/flowable/i18n/enums" |
"io/sc/platform/flowable/i18n/enums", |
||||
|
"io/sc/platform/flowable/i18n/dictionary" |
||||
] |
] |
||||
} |
} |
@ -0,0 +1 @@ |
|||||
|
WORK_FLOW.SAMPLE=Example Workflow |
@ -0,0 +1 @@ |
|||||
|
WORK_FLOW.SAMPLE=\u793A\u4F8B\u6D41\u7A0B |
@ -0,0 +1 @@ |
|||||
|
WORK_FLOW.SAMPLE=\u793A\u4F8B\u6D41\u7A0B |
@ -1,24 +0,0 @@ |
|||||
<template> |
|
||||
<q-splitter :model-value="100" unit="px" class="w-full h-full"> |
|
||||
<template #before> |
|
||||
<q-tabs v-model="selectedTabRef" vertical> |
|
||||
<q-tab name="processDefine" icon="mail" label="流程定义" /> |
|
||||
<q-tab name="processInstance" icon="mail" label="流程实例" /> |
|
||||
<q-tab name="task" icon="mail" label="工作任务" /> |
|
||||
</q-tabs> |
|
||||
</template> |
|
||||
<template #after> |
|
||||
<q-tab-panels v-model="selectedTabRef" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up"> |
|
||||
<q-tab-panel name="processDefine"> |
|
||||
<ProcessDefine></ProcessDefine> |
|
||||
</q-tab-panel> |
|
||||
</q-tab-panels> |
|
||||
</template> |
|
||||
</q-splitter> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import ProcessDefine from './bpm/ProcessDefine.vue'; |
|
||||
|
|
||||
const selectedTabRef = ref('processDefine'); |
|
||||
</script> |
|
@ -0,0 +1,279 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-splitter :model-value="100" unit="px" class="w-full h-full"> |
||||
|
<template #before> |
||||
|
<q-tabs v-model="selectedTabRef" vertical> |
||||
|
<q-tab name="processDefine" icon="mail" label="流程定义" /> |
||||
|
<q-tab name="processInstance" icon="mail" label="流程实例" /> |
||||
|
<q-tab name="task" icon="mail" label="工作任务" /> |
||||
|
</q-tabs> |
||||
|
</template> |
||||
|
<template #after> |
||||
|
<q-tab-panels v-model="selectedTabRef" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up"> |
||||
|
<q-tab-panel name="processDefine"> |
||||
|
<w-grid |
||||
|
ref="processDefineGridRef" |
||||
|
title="流程定义列表" |
||||
|
:checkbox-selection="true" |
||||
|
:data-url="Environment.apiContextPath('/api/flowable/process')" |
||||
|
:pageable="true" |
||||
|
:pagination="{ sortBy: 'lastModifyDate', descending: true }" |
||||
|
:query-form-cols-num="3" |
||||
|
:query-form-fields="[ |
||||
|
{ name: 'key', label: $t('code'), type: 'text' }, |
||||
|
{ name: 'name', label: $t('name'), type: 'text' }, |
||||
|
{ name: 'status', label: $t('status'), queryOperator: 'equals', type: 'select', clearable: true, options: Options.enum(ProcessStatusEnum) }, |
||||
|
]" |
||||
|
:toolbar-actions="[ |
||||
|
'query', |
||||
|
'separator', |
||||
|
'refresh', |
||||
|
'separator', |
||||
|
'add', |
||||
|
'clone', |
||||
|
{ |
||||
|
extend: 'edit', |
||||
|
enableIf: (selecteds) => { |
||||
|
if (selecteds && selecteds.length > 0) { |
||||
|
const selected = selecteds[0]; |
||||
|
if ('SKETCH' === selected.status) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
extend: 'remove', |
||||
|
enableIf: (selecteds) => { |
||||
|
if (selecteds && selecteds.length > 0) { |
||||
|
const selected = selecteds[0]; |
||||
|
if ('SKETCH' === selected.status) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'design', |
||||
|
label: '设计', |
||||
|
icon: 'bi-brush', |
||||
|
enableIf: (selecteds) => { |
||||
|
if (selecteds && selecteds.length > 0) { |
||||
|
const selected = selecteds[0]; |
||||
|
if ('SKETCH' === selected.status) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (selecteds: object[]) => { |
||||
|
if (selecteds && selecteds.length > 0) { |
||||
|
const selected = selecteds[0]; |
||||
|
const title = '流程设计器 - ' + selected.name + (selected.version ? ' (' + selected.version + ')' : ''); |
||||
|
processDesignerDialogRef.open(title, selected.id); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'deployment', |
||||
|
label: '发布', |
||||
|
icon: 'bi-arrow-up-circle', |
||||
|
enableIf: (selecteds) => { |
||||
|
if (selecteds && selecteds.length > 0) { |
||||
|
const selected = selecteds[0]; |
||||
|
if ('SKETCH' === selected.status) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (selecteds: object[]) => { |
||||
|
DialogManager.confirm('您确定要发布流程吗?', () => { |
||||
|
axios.post(Environment.apiContextPath('api/flowable/process/deploy/') + selecteds[0].id).then(() => { |
||||
|
processDefineGridRef.refresh(); |
||||
|
NotifyManager.success(); |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'queryProcessInstance', |
||||
|
label: '查询流程实例', |
||||
|
enableIf: (selecteds) => { |
||||
|
if (selecteds && selecteds.length > 0) { |
||||
|
const selected = selecteds[0]; |
||||
|
if ('SKETCH' != selected.status) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (selecteds: object[]) => {}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'createProcessInstance', |
||||
|
label: '创建流程实例', |
||||
|
enableIf: (selecteds) => { |
||||
|
if (selecteds && selecteds.length > 0) { |
||||
|
const selected = selecteds[0]; |
||||
|
if ('RELEASE' === selected.status) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
click: (selecteds) => { |
||||
|
createProcessInstanceDialogRef.open(); |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
'view', |
||||
|
'separator', |
||||
|
'export', |
||||
|
]" |
||||
|
:columns="[ |
||||
|
{ width: 150, name: 'key', label: $t('code') }, |
||||
|
{ |
||||
|
width: '100%', |
||||
|
name: 'name', |
||||
|
label: $t('name'), |
||||
|
format: (value, row) => { |
||||
|
return Formater.dictionary(ProcessCategoryDictionaries)(row.key); |
||||
|
}, |
||||
|
}, |
||||
|
{ width: 60, name: 'version', label: $t('version') }, |
||||
|
{ width: 60, name: 'status', label: $t('status'), format: Formater.enum(ProcessStatusEnum) }, |
||||
|
{ width: 300, name: 'deployedId', label: $t('lcdp.bpm.deployId') }, |
||||
|
{ |
||||
|
width: 80, |
||||
|
name: 'canClaimTask', |
||||
|
label: $t('lcdp.bpm.canClaimTask'), |
||||
|
format: Formater.yesNo(), |
||||
|
}, |
||||
|
{ width: 80, name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ width: 100, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '610px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ |
||||
|
name: 'category', |
||||
|
label: $t('category'), |
||||
|
type: 'select', |
||||
|
defaultValue: 'SAMPLE', |
||||
|
options: Options.dictionary(ProcessCategoryDictionaries), |
||||
|
'onUpdate:modelValue': (value) => { |
||||
|
const form = processDefineGridRef.getEditorForm(); |
||||
|
form.setFieldValue('key', value); |
||||
|
form.setFieldValue('name', Formater.dictionary(ProcessCategoryDictionaries)(value)); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'key', |
||||
|
label: $t('code'), |
||||
|
type: 'text', |
||||
|
defaultValue: 'SAMPLE', |
||||
|
readonlyIf: () => { |
||||
|
return true; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'name', |
||||
|
label: $t('name'), |
||||
|
type: 'text', |
||||
|
required: true, |
||||
|
defaultValue: Formater.dictionary(ProcessCategoryDictionaries)('SAMPLE'), |
||||
|
readonlyIf: () => { |
||||
|
return true; |
||||
|
}, |
||||
|
}, |
||||
|
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 }, |
||||
|
{ name: 'xml', label: $t('xml'), type: 'textarea' }, |
||||
|
{ name: 'status', label: $t('status'), type: 'text', defaultValue: 'SKETCH', hidden: true }, |
||||
|
{ name: 'canClaimTask', label: $t('lcdp.bpm.canClaimTask'), type: 'checkbox', defaultValue: true, rule: [] }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'key', label: $t('code') }, |
||||
|
{ name: 'name', label: $t('name'), format: Formater.none() }, |
||||
|
{ name: 'version', label: $t('version') }, |
||||
|
{ name: 'status', label: $t('status'), format: Formater.enum(ProcessStatusEnum) }, |
||||
|
{ name: 'deployedId', label: $t('lcdp.bpm.deployId') }, |
||||
|
{ name: 'canClaimTask', label: $t('lcdp.bpm.canClaimTask'), format: Formater.none() }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
</q-tab-panel> |
||||
|
<q-tab-panel name="processInstance"> |
||||
|
<w-grid |
||||
|
ref="processInstanceGridRef" |
||||
|
title="流程实例列表" |
||||
|
:checkbox-selection="true" |
||||
|
:data-url="Environment.apiContextPath('/api/flowable/process')" |
||||
|
:pageable="true" |
||||
|
:pagination="{ sortBy: 'lastModifyDate', descending: true }" |
||||
|
:query-form-cols-num="3" |
||||
|
:query-form-fields="[]" |
||||
|
:toolbar-actions="['query', 'separator', 'refresh', 'separator', 'add', 'clone', 'separator', 'view', 'separator', 'export']" |
||||
|
:columns="[]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '610px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
</q-tab-panel> |
||||
|
<q-tab-panel name="task"></q-tab-panel> |
||||
|
</q-tab-panels> |
||||
|
</template> |
||||
|
</q-splitter> |
||||
|
|
||||
|
<ProcessDesigner ref="processDesignerDialogRef"> |
||||
|
<iframe ref="processDesignerIframeRef" src="#" style="width: 100%; height: 100%"></iframe> |
||||
|
</ProcessDesigner> |
||||
|
|
||||
|
<CreateProcessInstanceDialog ref="createProcessInstanceDialogRef"></CreateProcessInstanceDialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { Environment, DialogManager, NotifyManager, axios, EnumTools, DictionaryTools, Formater, Options } from 'platform-core'; |
||||
|
import ProcessDesigner from './ProcessDesigner.vue'; |
||||
|
import CreateProcessInstanceDialog from './CreateProcessInstanceDialog.vue'; |
||||
|
|
||||
|
const selectedTabRef = ref('processDefine'); |
||||
|
const processDefineGridRef = ref(); |
||||
|
const processDesignerDialogRef = ref(); |
||||
|
const processDesignerIframeRef = ref(); |
||||
|
const createProcessInstanceDialogRef = ref(); |
||||
|
const show = ref(true); |
||||
|
|
||||
|
const ProcessStatusEnum = await EnumTools.fetch('io.sc.platform.flowable.enums.ProcessStatus'); |
||||
|
const ProcessCategoryDictionaries = await DictionaryTools.fetch('WORK_FLOW'); |
||||
|
</script> |
@ -0,0 +1,22 @@ |
|||||
|
<template> |
||||
|
<q-dialog ref="dialogRef" title="ok" allow-focus-outside width="500px" height="230px" :can-maximize="false"> </q-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
|
||||
|
const open = () => { |
||||
|
dialogRef.value.show(); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
dialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
close, |
||||
|
}); |
||||
|
</script> |
@ -1,175 +0,0 @@ |
|||||
<template> |
|
||||
<platform-grid |
|
||||
ref="dataSupplementTypeGridRef" |
|
||||
:table-props="{ borderded: false, flat: true }" |
|
||||
:query-form-cols-number="dataSupplementTypeGrid.queryFormColsNumber" |
|
||||
:query-form-cols-auto="dataSupplementTypeGrid.queryFormColsAuto" |
|
||||
:table-title="dataSupplementTypeGrid.tableTitle" |
|
||||
:table-row-key="dataSupplementTypeGrid.tableRowKey" |
|
||||
:table-init-load-data="dataSupplementTypeGrid.tableInitLoadData" |
|
||||
:table-data-url="dataSupplementTypeGrid.tableDataUrl" |
|
||||
:table-show-sort-no="false" |
|
||||
:table-columns="dataSupplementTypeGrid.tableColumns" |
|
||||
:table-left-column-sticky-number="dataSupplementTypeGrid.tableLeftColumnStickyNumber" |
|
||||
:table-buttons="dataSupplementTypeGrid.tableButtons" |
|
||||
:query-form-fields="dataSupplementTypeGrid.queryFormFields" |
|
||||
:table-pagination="dataSupplementTypeGrid.tablePagination" |
|
||||
:add-form-props="dataSupplementTypeGrid.addFormProps" |
|
||||
:table-dense="true" |
|
||||
> |
|
||||
</platform-grid> |
|
||||
|
|
||||
<ProcessDesigner ref="processDesignerDialogRef" :title="processDesignerDialogTitleRef" :maximized="true" @show="afterShow"> |
|
||||
<iframe ref="processDesignerIframeRef" src="#" style="width: 100%; height: 100%"></iframe> |
|
||||
</ProcessDesigner> |
|
||||
</template> |
|
||||
|
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import { useI18n } from 'vue-i18n'; |
|
||||
import { Environment, DialogManager, axios, BackendTools } from 'platform-core'; |
|
||||
import ProcessDesigner from './ProcessDesigner.vue'; |
|
||||
|
|
||||
const { t } = useI18n(); |
|
||||
|
|
||||
const dataSupplementTypeGridRef = ref(); |
|
||||
const processDesignerDialogRef = ref(); |
|
||||
const processDesignerDialogTitleRef = ref(); |
|
||||
const processDesignerIframeRef = ref(); |
|
||||
|
|
||||
const processStatus = await BackendTools.enums('io.sc.platform.flowable.enums.ProcessStatus', t); |
|
||||
const ProcessStatusSelectOptions = processStatus.list; |
|
||||
const ProcessStatusMap = processStatus.map; |
|
||||
|
|
||||
const dataSupplementTypeGrid = { |
|
||||
queryFormColsNumber: 2, |
|
||||
queryFormColsAuto: false, |
|
||||
queryFormFields: [ |
|
||||
{ label: '流程定义代码', modelName: 'key', type: 'text' }, |
|
||||
{ label: '流程定义名称', modelName: 'name', type: 'text' }, |
|
||||
], |
|
||||
hideBottom: false, |
|
||||
tableInitLoadData: true, |
|
||||
tableLeftColumnStickyNumber: 0, |
|
||||
tableTitle: '流程定义列表', |
|
||||
tableRowKey: 'id', |
|
||||
tableDataUrl: Environment.apiContextPath('/api/flowable/process'), |
|
||||
tablePagination: { |
|
||||
sortBy: 'lastModifyDate', |
|
||||
descending: true, |
|
||||
reqPageStart: 0, |
|
||||
rowsPerPage: 10, |
|
||||
}, |
|
||||
tableButtons: [ |
|
||||
'query', |
|
||||
'reset', |
|
||||
'separator', |
|
||||
'refresh', |
|
||||
'add', |
|
||||
{ |
|
||||
name: 'clone', |
|
||||
label: '复制', |
|
||||
icon: 'bi-copy', |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
'edit', |
|
||||
'delete', |
|
||||
'separator', |
|
||||
'view', |
|
||||
'separator', |
|
||||
{ |
|
||||
name: '', |
|
||||
label: '设计', |
|
||||
icon: 'bi-brush', |
|
||||
click: (selectedRows: object[]) => { |
|
||||
const process = dataSupplementTypeGridRef.value.getSelectedRows()[0]; |
|
||||
processDesignerDialogTitleRef.value = '流程设计器 - ' + process.name + (process.version ? ' (' + process.version + ')' : ''); |
|
||||
processDesignerDialogRef.value.show(); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: '', |
|
||||
label: '发布', |
|
||||
icon: 'bi-arrow-up-circle', |
|
||||
enableIf: (selectedRow: object[]) => { |
|
||||
return selectedRow && selectedRow.length > 0; |
|
||||
}, |
|
||||
click: (selectedRow: object[]) => { |
|
||||
DialogManager.confirm('您确定要发布流程吗?', () => { |
|
||||
axios.post(Environment.apiContextPath('api/flowable/process/deploy/') + selectedRow[0].id).then(() => { |
|
||||
dataSupplementTypeGridRef.value.refreshTable(); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: '', |
|
||||
label: '查询流程实例', |
|
||||
icon: '', |
|
||||
click: (selectedRow: object[]) => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: '', |
|
||||
label: '创建流程实例', |
|
||||
icon: '', |
|
||||
click: (selectedRow: object[]) => {}, |
|
||||
}, |
|
||||
'inFullscreen', |
|
||||
], |
|
||||
tableColumns: [ |
|
||||
{ name: 'key', label: t('code'), width: 100 }, |
|
||||
{ |
|
||||
name: 'name', |
|
||||
label: t('name'), |
|
||||
width: '100px', |
|
||||
}, |
|
||||
{ name: 'version', label: t('version'), width: 80 }, |
|
||||
{ |
|
||||
name: 'status', |
|
||||
label: t('status'), |
|
||||
width: 80, |
|
||||
format: (val, row) => { |
|
||||
return ProcessStatusMap[val]; |
|
||||
}, |
|
||||
}, |
|
||||
{ name: 'deployedId', label: t('lcdp.bpm.deployId'), width: 150 }, |
|
||||
{ |
|
||||
name: 'canClaimTask', |
|
||||
label: t('lcdp.bpm.canClaimTask'), |
|
||||
width: 80, |
|
||||
format: (val, row) => { |
|
||||
if (val === true) { |
|
||||
return '允许'; |
|
||||
} else { |
|
||||
return '不允许'; |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
{ name: 'lastModifier', label: t('lastModifier'), width: 100 }, |
|
||||
{ name: 'lastModifyDate', label: t('lastModifyDate'), width: 120 }, |
|
||||
], |
|
||||
addFormProps: { |
|
||||
dialogInitWidth: '60%', |
|
||||
dialogInitHeight: '50%', |
|
||||
formColsNumber: 1, |
|
||||
formColsAuto: false, |
|
||||
formFields: [ |
|
||||
{ modelName: 'key', label: t('code'), type: 'text', required: true }, |
|
||||
{ modelName: 'name', label: t('name'), type: 'text', required: true }, |
|
||||
{ modelName: 'description', label: t('description'), type: 'textarea' }, |
|
||||
{ modelName: 'xml', label: t('xml'), type: 'textarea' }, |
|
||||
{ modelName: 'status', label: t('status'), type: 'text', defaultValue: 'SKETCH', hide: true }, |
|
||||
{ modelName: 'category', label: t('category'), type: 'text', defaultValue: 'Sample', hide: true }, |
|
||||
{ modelName: 'canClaimTask', label: t('lcdp.bpm.canClaimTask'), type: 'checkbox', defaultValue: true, rule: [] }, |
|
||||
], |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
const afterShow = () => { |
|
||||
const url = |
|
||||
Environment.getWebContextPath() + |
|
||||
'io.sc.platform.lcdp.frontend/flowable/modeler/index.html#/editor/' + |
|
||||
dataSupplementTypeGridRef.value.getSelectedRows()[0].id; |
|
||||
processDesignerIframeRef.value.src = url; |
|
||||
}; |
|
||||
</script> |
|
@ -1,62 +1,61 @@ |
|||||
<template> |
<template> |
||||
<div> |
<q-dialog ref="dialogRef" title="ok" allow-focus-outside maximized> |
||||
<q-dialog ref="dialogRef" allow-focus-outside v-bind="attrs"> |
<q-card |
||||
<q-card |
:style="{ |
||||
|
width: '100vw', |
||||
|
'max-width': '100vw', |
||||
|
height: '100vh', |
||||
|
'max-height': '100vh', |
||||
|
}" |
||||
|
> |
||||
|
<q-card-section class="q-pt-none" style="padding: 0px 0px 0px 0px; height: calc(100%)"> |
||||
|
<iframe ref="processDesignerIframeRef" src="#" style="width: 100%; height: 100%"></iframe> |
||||
|
</q-card-section> |
||||
|
|
||||
|
<q-card-section |
||||
|
class="fixed top-0 left-0" |
||||
:style="{ |
:style="{ |
||||
width: attrs.maximized ? '100vw' : width, |
width: '100%', |
||||
'max-width': '100vw', |
padding: '4px 8px 4px 16px', |
||||
height: attrs.maximized ? '100vh' : height, |
color: $gc.theme.topper.color, |
||||
'max-height': '100vh', |
'background-color': $gc.theme.topper.bgColor, |
||||
}" |
}" |
||||
> |
> |
||||
<q-card-section class="q-pt-none" :style="bodyStyle"> |
<div class="flex justify-between"> |
||||
<slot></slot> |
<div class="text-h6">{{ dialogTitle }}</div> |
||||
</q-card-section> |
<div class="flex justify-end"> |
||||
|
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn> |
||||
<q-card-section class="fixed top-0 left-0" :style="headerStyle"> |
|
||||
<div class="flex justify-between"> |
|
||||
<div class="text-h6">{{ title }}</div> |
|
||||
<div class="flex justify-end"> |
|
||||
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn> |
|
||||
</div> |
|
||||
</div> |
</div> |
||||
</q-card-section> |
</div> |
||||
</q-card> |
</q-card-section> |
||||
</q-dialog> |
</q-card> |
||||
</div> |
</q-dialog> |
||||
</template> |
</template> |
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { useAttrs, ref } from 'vue'; |
import { ref, nextTick } from 'vue'; |
||||
|
import { Environment } from 'platform-core'; |
||||
const attrs = useAttrs(); |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
headerStyle: { type: String, default: 'width:100%;padding: 4px 8px 4px 16px' }, |
|
||||
bodyStyle: { type: String, default: 'padding: 0px 8px 0px 8px;height:calc(100%)' }, |
|
||||
title: { type: String, default: '' }, |
|
||||
width: { type: String, default: '70%' }, |
|
||||
height: { type: String, default: '70%' }, |
|
||||
}); |
|
||||
|
|
||||
const emit = defineEmits<{ |
|
||||
( |
|
||||
e: 'maximize', // 全屏按钮点击事件 |
|
||||
maximized: boolean, // 第一个参数,true:全屏状态,false:退出全屏 |
|
||||
): void; |
|
||||
}>(); |
|
||||
|
|
||||
const dialogRef = ref(); |
const dialogRef = ref(); |
||||
|
const processDesignerIframeRef = ref(); |
||||
|
let dialogTitle = ''; |
||||
|
let processId = ''; |
||||
|
|
||||
const show = () => { |
const open = (title: string, id: string) => { |
||||
|
dialogTitle = title; |
||||
|
processId = id; |
||||
dialogRef.value.show(); |
dialogRef.value.show(); |
||||
|
nextTick(() => { |
||||
|
const url = Environment.getWebContextPath() + 'io.sc.platform.lcdp.frontend/flowable/modeler/index.html#/editor/' + processId; |
||||
|
processDesignerIframeRef.value.src = url; |
||||
|
}); |
||||
}; |
}; |
||||
|
|
||||
const hide = () => { |
const close = () => { |
||||
dialogRef.value.hide(); |
dialogRef.value.hide(); |
||||
}; |
}; |
||||
|
|
||||
defineExpose({ |
defineExpose({ |
||||
show, |
open, |
||||
hide, |
close, |
||||
}); |
}); |
||||
</script> |
</script> |
||||
|
@ -0,0 +1,38 @@ |
|||||
|
package io.sc.platform.system.dictionary.controller; |
||||
|
|
||||
|
import io.sc.platform.core.support.Option; |
||||
|
import io.sc.platform.mvc.controller.support.RestCrudController; |
||||
|
import io.sc.platform.system.api.dictionary.DictionaryVo; |
||||
|
import io.sc.platform.system.dictionary.jpa.entity.DictionaryEntity; |
||||
|
import io.sc.platform.system.dictionary.jpa.repository.DictionaryRepository; |
||||
|
import io.sc.platform.system.dictionary.service.DictionaryService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@RestController |
||||
|
@RequestMapping("api/dictionary") |
||||
|
public class DictionaryApiWebController extends RestCrudController<DictionaryVo,DictionaryEntity,String,DictionaryRepository, DictionaryService> { |
||||
|
@Autowired private DictionaryService dictionaryService; |
||||
|
|
||||
|
@GetMapping("list/{dictionaryCode}") |
||||
|
public Option[] list(@PathVariable(name = "dictionaryCode",required = false) String dictionaryCode) throws Exception{ |
||||
|
if(StringUtils.hasText(dictionaryCode)){ |
||||
|
List<String> values =dictionaryService.getValuesByCode(dictionaryCode); |
||||
|
if(values!=null && !values.isEmpty()){ |
||||
|
Option<String>[] result =new Option[values.size()]; |
||||
|
for(int i=0;i<values.size();i++){ |
||||
|
String value =values.get(i); |
||||
|
result[i] =new Option(value, dictionaryCode + "." + value); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
return new Option[]{}; |
||||
|
} |
||||
|
} |
@ -1,13 +1,24 @@ |
|||||
package io.sc.platform.system.dictionary.service; |
package io.sc.platform.system.dictionary.service; |
||||
|
|
||||
|
import io.sc.platform.core.support.KeyValue; |
||||
import io.sc.platform.mvc.support.OrderItem; |
import io.sc.platform.mvc.support.OrderItem; |
||||
import io.sc.platform.orm.service.DaoService; |
import io.sc.platform.orm.service.DaoService; |
||||
import io.sc.platform.system.dictionary.jpa.entity.DictionaryEntity; |
import io.sc.platform.system.dictionary.jpa.entity.DictionaryEntity; |
||||
import io.sc.platform.system.dictionary.jpa.repository.DictionaryRepository; |
import io.sc.platform.system.dictionary.jpa.repository.DictionaryRepository; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
|
||||
|
|
||||
import java.util.List; |
import java.util.List; |
||||
|
import java.util.Locale; |
||||
|
import java.util.Map; |
||||
|
import java.util.Set; |
||||
|
|
||||
public interface DictionaryService extends DaoService<DictionaryEntity, String, DictionaryRepository> { |
public interface DictionaryService extends DaoService<DictionaryEntity, String, DictionaryRepository> { |
||||
public void updateDictionariesOrder(List<OrderItem<String,Integer>> orderItems) throws Exception; |
public void updateDictionariesOrder(List<OrderItem<String,Integer>> orderItems) throws Exception; |
||||
|
|
||||
|
public List<String> getValuesByCode(String code) throws Exception; |
||||
|
|
||||
|
public Map<String, Set<String>> getValuesByCodes(Set<String> codes) throws Exception; |
||||
|
|
||||
|
public List<KeyValue<String,String>> getValuesByCodeWithMessage(String code, Locale locale) throws Exception; |
||||
|
|
||||
|
public Map<String, Set<KeyValue<String,String>>> getValuesByCodesWithMessage(Set<String> codes,Locale locale) throws Exception; |
||||
} |
} |
||||
|
Loading…
Reference in new issue