141 changed files with 3144 additions and 1158 deletions
@ -1,4 +1,169 @@ |
|||||
<template> |
<template> |
||||
<div>WorkflowApprovalComponent</div> |
<w-dialog |
||||
|
ref="dialogRef" |
||||
|
:title="task.processDefinitionName + ' - ' + task.businessDescription" |
||||
|
width="800px" |
||||
|
:can-maximize="false" |
||||
|
body-padding="8px 8px 8px 8px" |
||||
|
@hide=" |
||||
|
() => { |
||||
|
emit('close'); |
||||
|
} |
||||
|
" |
||||
|
> |
||||
|
<w-grid |
||||
|
ref="historyProcessTaskGridRef" |
||||
|
:title="$t('re.workflow.dialog.historyTask')" |
||||
|
:height="200" |
||||
|
hide-bottom |
||||
|
dense-body |
||||
|
:config-button="false" |
||||
|
selection="multiple" |
||||
|
:checkbox-selection="false" |
||||
|
:tree="false" |
||||
|
:fetch-data-url="Environment.apiContextPath('/api/re/resource/workflow/task/queryHistory?processInstanceId=' + task.processInstanceId)" |
||||
|
:pageable="false" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:columns="[ |
||||
|
{ width: 150, name: 'taskName', label: $t('re.workflow.task.grid.entity.taskName') }, |
||||
|
{ width: 100, name: 'taskAssignee', label: $t('re.workflow.task.grid.entity.taskAssignee') }, |
||||
|
{ width: 150, name: 'taskEndTime', label: $t('re.workflow.task.grid.entity.taskEndTime') }, |
||||
|
{ |
||||
|
width: '100%', |
||||
|
name: 'taskTreatment', |
||||
|
label: $t('re.workflow.task.grid.entity.taskTreatment'), |
||||
|
format: (value) => { |
||||
|
if (value) { |
||||
|
return value.replace(/(\r\n)|(\n)/g, '<br>'); |
||||
|
} |
||||
|
return ''; |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
></w-grid> |
||||
|
<div style="height: 10px"></div> |
||||
|
<template v-if="action === 'process'"> |
||||
|
<w-form |
||||
|
ref="formRef" |
||||
|
v-model="formModelValue" |
||||
|
:cols-num="1" |
||||
|
:fields="[{ name: 'treatment', label: $t('re.workflow.dialog.entity.treatment'), type: 'w-textarea', rows: 5, requiredIf: true }]" |
||||
|
> |
||||
|
</w-form> |
||||
|
<div style="height: 10px"></div> |
||||
|
</template> |
||||
|
<div class="row no-wrap items-center"> |
||||
|
<div class="q-gutter-md"> |
||||
|
<q-btn :label="$t('re.workflow.task.grid.toolbar.viewResource')" icon="bi-boxes" outline no-caps @click="viewResource" /> |
||||
|
<q-btn |
||||
|
:disable="!(currentSelectedResourceRef?.attachmentCount > 0)" |
||||
|
:label="$t('re.workflow.task.grid.toolbar.viewAttachment')" |
||||
|
icon="bi-boxes" |
||||
|
outline |
||||
|
no-caps |
||||
|
@click="viewAttachment" |
||||
|
/> |
||||
|
</div> |
||||
|
<q-space /> |
||||
|
<template v-if="action === 'process'"> |
||||
|
<w-workflow-action |
||||
|
ref="workflowActionRef" |
||||
|
:task-id="task.id" |
||||
|
:data="formModelValue" |
||||
|
:action-url="Environment.apiContextPath('/api/flowable/process/operation/complete')" |
||||
|
@before-submit="beforeSubmit" |
||||
|
@after-submit="afterSubmit" |
||||
|
> |
||||
|
</w-workflow-action> |
||||
|
</template> |
||||
|
</div> |
||||
|
<div style="height: 10px"> |
||||
|
<DesignerDialog ref="designerDialogRef"></DesignerDialog> |
||||
|
<AttachmentDialog |
||||
|
ref="attachmentDialogRef" |
||||
|
:fetch-data-url="Environment.apiContextPath('/api/system/attachment/findByBussinessKey')" |
||||
|
:data-url="Environment.apiContextPath('/api/system/attachment')" |
||||
|
foreign-key="bussinessKey" |
||||
|
:foreign-value="attachmentIdRef" |
||||
|
></AttachmentDialog> |
||||
|
</div> |
||||
|
</w-dialog> |
||||
</template> |
</template> |
||||
<script setup lang="ts"></script> |
<script setup lang="ts"> |
||||
|
import { ref, reactive, onMounted } from 'vue'; |
||||
|
import { axios, Environment, Tools, CorporationAuditorEntityManager } from 'platform-core'; |
||||
|
import DesignerDialog from '@/views/resources/designer/DesignerDialog.vue'; |
||||
|
import AttachmentDialog from '@/views/resources/AttachmentDialog.vue'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
task: { type: Object, default: undefined }, |
||||
|
action: { type: String, default: undefined }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits(['close', 'afterTaskCompleted']); |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
const formRef = ref(); |
||||
|
const currentSelectedResourceRef = ref(); |
||||
|
const historyProcessTaskGridRef = ref(); |
||||
|
const designerDialogRef = ref(); |
||||
|
const attachmentIdRef = ref(); |
||||
|
const attachmentDialogRef = ref(); |
||||
|
|
||||
|
const formModelValue = reactive({ |
||||
|
treatment: undefined, |
||||
|
}); |
||||
|
|
||||
|
const viewResource = () => { |
||||
|
designerDialogRef.value.open(currentSelectedResourceRef.value); |
||||
|
}; |
||||
|
|
||||
|
const viewAttachment = () => { |
||||
|
attachmentIdRef.value = currentSelectedResourceRef.value.id; |
||||
|
attachmentDialogRef.value.open(); |
||||
|
}; |
||||
|
|
||||
|
const beforeSubmit = async (action, callback) => { |
||||
|
formRef.value.validate().then((value) => { |
||||
|
if (value) { |
||||
|
action.transientVariables.task_treatment = formModelValue.treatment; |
||||
|
callback(true); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const afterSubmit = () => { |
||||
|
close(); |
||||
|
emit('afterTaskCompleted'); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
dialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
onMounted(() => { |
||||
|
dialogRef.value.show(); |
||||
|
|
||||
|
const businessKey = props.task.businessKey; |
||||
|
const splits = businessKey.split(':'); |
||||
|
const criteria = { |
||||
|
operator: 'and', |
||||
|
criteria: [ |
||||
|
{ |
||||
|
fieldName: 'code', |
||||
|
operator: 'equals', |
||||
|
value: splits[0], |
||||
|
}, |
||||
|
{ |
||||
|
fieldName: 'version', |
||||
|
operator: 'equals', |
||||
|
value: splits[1], |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
const criteriaQuery = encodeURIComponent(Tools.object2Json(criteria)); |
||||
|
axios.get(Environment.apiContextPath('/api/re/resource?criteria=' + criteriaQuery)).then((response: any) => { |
||||
|
currentSelectedResourceRef.value = response.data.content[0]; |
||||
|
}); |
||||
|
}); |
||||
|
</script> |
||||
|
@ -1,76 +0,0 @@ |
|||||
<template> |
|
||||
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
|
||||
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
|
||||
<q-card-section class="text-orange px-2 pt-1 pb-0"> |
|
||||
<div class="row no-wrap items-center"> |
|
||||
<q-icon name="bi-megaphone" size="1.3em" /> |
|
||||
<span class="text-weight-bolder px-2">{{ $t('home.card.announcement.title') }}</span> |
|
||||
<q-space /> |
|
||||
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :title="$t('refresh')" :loading="loadingRef" @click="refresh" /> |
|
||||
<q-btn |
|
||||
size="12px" |
|
||||
icon="bi-justify" |
|
||||
flat |
|
||||
no-caps |
|
||||
padding="2px 6px 2px 6px" |
|
||||
:title="$t('home.card.announcement.action.list')" |
|
||||
:to="{ name: 'route.workbench.announcement' }" |
|
||||
/> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
<q-card-section class="p-0"> |
|
||||
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
|
||||
<tbody> |
|
||||
<tr v-for="item in itemsRef" :key="item.id"> |
|
||||
<td width="100%" :title="item.content" class="truncate" :style="{ maxWidth: firstColMaxWidthRef + 'px' }"> |
|
||||
<a href="javascript:void(0);" style="cursor: pointer; color: blue" @click="handleTask(item)" v-html="item.content"></a> |
|
||||
</td> |
|
||||
<td width="80px" :title="item.lastModifyDate" class="smallFont truncate" style="max-width: 80px" align="right"> |
|
||||
{{ item.lastModifyDateAndNowDiff + $t(item.lastModifyDateAndNowDiffUnit) + $t('before') }} |
|
||||
</td> |
|
||||
</tr> |
|
||||
</tbody> |
|
||||
</q-markup-table> |
|
||||
<AnnouncementDialog ref="dialogRef"></AnnouncementDialog> |
|
||||
</q-card-section> |
|
||||
</q-card> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import { axios, Environment } from '@/platform'; |
|
||||
import AnnouncementDialog from './AnnouncementDialog.vue'; |
|
||||
|
|
||||
const cardRef = ref(); |
|
||||
const cardHeightRef = ref(300); |
|
||||
const tableHeightRef = ref(300 - 30); |
|
||||
const firstColMaxWidthRef = ref(100); |
|
||||
|
|
||||
const itemsRef = ref([]); |
|
||||
const loadingRef = ref(false); |
|
||||
const dialogRef = ref(); |
|
||||
|
|
||||
const changeFirstColMaxWidth = () => { |
|
||||
let width = Math.ceil(cardRef.value.$el.clientWidth); |
|
||||
width = width - 100; |
|
||||
firstColMaxWidthRef.value = width > 100 ? width : 100; |
|
||||
}; |
|
||||
|
|
||||
const refresh = () => { |
|
||||
loadingRef.value = true; |
|
||||
axios |
|
||||
.get(Environment.apiContextPath('/api/system/announcement/findUnReadedAnnouncements')) |
|
||||
.then((response: any) => { |
|
||||
itemsRef.value = response.data.content || []; |
|
||||
loadingRef.value = false; |
|
||||
}) |
|
||||
.catch(() => { |
|
||||
loadingRef.value = false; |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const handleTask = (item: any) => { |
|
||||
dialogRef.value.open(item); |
|
||||
}; |
|
||||
|
|
||||
refresh(); |
|
||||
</script> |
|
@ -1,93 +0,0 @@ |
|||||
<template> |
|
||||
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
|
||||
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
|
||||
<q-card-section class="text-secondary px-2 pt-1 pb-0"> |
|
||||
<div class="row no-wrap items-center"> |
|
||||
<q-icon name="bi-list-check" size="1.5em" /> |
|
||||
<span class="text-weight-bolder px-2">{{ $t('home.card.doneTask.title') }}</span> |
|
||||
<q-space /> |
|
||||
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :title="$t('refresh')" :loading="loadingRef" @click="refresh" /> |
|
||||
<q-btn |
|
||||
size="12px" |
|
||||
icon="bi-justify" |
|
||||
flat |
|
||||
no-caps |
|
||||
padding="2px 6px 2px 6px" |
|
||||
:title="$t('home.card.doneTask.action.list')" |
|
||||
:to="{ name: 'route.workbench.doneTask' }" |
|
||||
/> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
<q-card-section class="p-0"> |
|
||||
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
|
||||
<tbody> |
|
||||
<tr v-for="item in itemsRef" :key="item.id" @click="handleTask(item)"> |
|
||||
<td width="100%" :title="item.businessDescription" class="truncate" :style="{ maxWidth: firstColMaxWidthRef + 'px' }"> |
|
||||
<w-html-a :label="item.businessDescription" @click="handleTask(item)"></w-html-a> |
|
||||
</td> |
|
||||
<td width="80px" :title="item.processDefinitionName" class="smallFont truncate" style="max-width: 80px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.processDefinitionName }} |
|
||||
</td> |
|
||||
<td width="60px" :title="item.name" class="smallFont truncate" style="max-width: 60px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.name }} |
|
||||
</td> |
|
||||
<td width="60px" :title="item.previousAssignee" class="smallFont truncate" style="max-width: 60px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.previousAssignee }} |
|
||||
</td> |
|
||||
<td width="80px" :title="item.createTime" class="smallFont truncate" style="max-width: 80px; font-size: 0.8em; padding: 0px 4px" align="right"> |
|
||||
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }} |
|
||||
</td> |
|
||||
</tr> |
|
||||
</tbody> |
|
||||
</q-markup-table> |
|
||||
</q-card-section> |
|
||||
</q-card> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { h, ref, defineAsyncComponent, nextTick } from 'vue'; |
|
||||
import { axios, Environment, ComponentManager, Tools } from '@/platform'; |
|
||||
|
|
||||
const cardRef = ref(); |
|
||||
const cardHeightRef = ref(200); |
|
||||
const tableHeightRef = ref(200 - 30); |
|
||||
const firstColMaxWidthRef = ref(100); |
|
||||
|
|
||||
const itemsRef = ref([]); |
|
||||
const loadingRef = ref(false); |
|
||||
const componentRef = ref(); |
|
||||
|
|
||||
const changeFirstColMaxWidth = () => { |
|
||||
let width = Math.ceil(cardRef.value.$el.clientWidth); |
|
||||
width = width - 280; |
|
||||
firstColMaxWidthRef.value = width > 100 ? width : 100; |
|
||||
}; |
|
||||
|
|
||||
const refresh = () => { |
|
||||
loadingRef.value = true; |
|
||||
axios |
|
||||
.get(Environment.apiContextPath('/api/flowable/process/query/task')) |
|
||||
.then((response: any) => { |
|
||||
itemsRef.value = response.data.content || []; |
|
||||
loadingRef.value = false; |
|
||||
}) |
|
||||
.catch(() => { |
|
||||
loadingRef.value = false; |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const handleTask = async (item: any) => { |
|
||||
//删除已有组件 |
|
||||
componentRef.value = null; |
|
||||
//重新加载组件 |
|
||||
nextTick(() => { |
|
||||
const component = defineAsyncComponent(ComponentManager.getRemoteComponent(item.taskHandFrontendModelName, item.taskHandFrontendComponentName)); |
|
||||
const properties = Tools.mergeObject( |
|
||||
{ taskId: item.id, businessKey: item.businessKey, action: 'process' }, |
|
||||
Tools.json2Object(item.taskHandFrontendComponentProperties), |
|
||||
); |
|
||||
componentRef.value = h(component, properties); |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
refresh(); |
|
||||
</script> |
|
@ -1,93 +0,0 @@ |
|||||
<template> |
|
||||
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
|
||||
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
|
||||
<q-card-section class="text-info px-2 pt-1 pb-0"> |
|
||||
<div class="row no-wrap items-center"> |
|
||||
<q-icon name="bi-card-list" size="1.4em" /> |
|
||||
<span class="text-weight-bolder px-2">{{ $t('home.card.finishTask.title') }}</span> |
|
||||
<q-space /> |
|
||||
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :title="$t('refresh')" :loading="loadingRef" @click="refresh" /> |
|
||||
<q-btn |
|
||||
size="12px" |
|
||||
icon="bi-justify" |
|
||||
flat |
|
||||
no-caps |
|
||||
padding="2px 6px 2px 6px" |
|
||||
:title="$t('home.card.finishTask.action.list')" |
|
||||
:to="{ name: 'route.workbench.finishedTask' }" |
|
||||
/> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
<q-card-section class="p-0"> |
|
||||
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
|
||||
<tbody> |
|
||||
<tr v-for="item in itemsRef" :key="item.id" @click="handleTask(item)"> |
|
||||
<td width="100%" :title="item.businessDescription" class="truncate" :style="{ maxWidth: firstColMaxWidthRef + 'px' }"> |
|
||||
<w-html-a :label="item.businessDescription" @click="handleTask(item)"></w-html-a> |
|
||||
</td> |
|
||||
<td width="80px" :title="item.processDefinitionName" class="smallFont truncate" style="max-width: 80px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.processDefinitionName }} |
|
||||
</td> |
|
||||
<td width="60px" :title="item.name" class="smallFont truncate" style="max-width: 60px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.name }} |
|
||||
</td> |
|
||||
<td width="60px" :title="item.previousAssignee" class="smallFont truncate" style="max-width: 60px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.previousAssignee }} |
|
||||
</td> |
|
||||
<td width="80px" :title="item.createTime" class="smallFont truncate" style="max-width: 80px; font-size: 0.8em; padding: 0px 4px" align="right"> |
|
||||
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }} |
|
||||
</td> |
|
||||
</tr> |
|
||||
</tbody> |
|
||||
</q-markup-table> |
|
||||
</q-card-section> |
|
||||
</q-card> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { h, ref, defineAsyncComponent, nextTick } from 'vue'; |
|
||||
import { axios, Environment, ComponentManager, Tools } from '@/platform'; |
|
||||
|
|
||||
const cardRef = ref(); |
|
||||
const cardHeightRef = ref(200); |
|
||||
const tableHeightRef = ref(200 - 30); |
|
||||
const firstColMaxWidthRef = ref(100); |
|
||||
|
|
||||
const itemsRef = ref([]); |
|
||||
const loadingRef = ref(false); |
|
||||
const componentRef = ref(); |
|
||||
|
|
||||
const changeFirstColMaxWidth = () => { |
|
||||
let width = Math.ceil(cardRef.value.$el.clientWidth); |
|
||||
width = width - 280; |
|
||||
firstColMaxWidthRef.value = width > 100 ? width : 100; |
|
||||
}; |
|
||||
|
|
||||
const refresh = () => { |
|
||||
loadingRef.value = true; |
|
||||
axios |
|
||||
.get(Environment.apiContextPath('/api/flowable/process/query/task')) |
|
||||
.then((response: any) => { |
|
||||
itemsRef.value = response.data.content || []; |
|
||||
loadingRef.value = false; |
|
||||
}) |
|
||||
.catch(() => { |
|
||||
loadingRef.value = false; |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const handleTask = async (item: any) => { |
|
||||
//删除已有组件 |
|
||||
componentRef.value = null; |
|
||||
//重新加载组件 |
|
||||
nextTick(() => { |
|
||||
const component = defineAsyncComponent(ComponentManager.getRemoteComponent(item.taskHandFrontendModelName, item.taskHandFrontendComponentName)); |
|
||||
const properties = Tools.mergeObject( |
|
||||
{ taskId: item.id, businessKey: item.businessKey, action: 'process' }, |
|
||||
Tools.json2Object(item.taskHandFrontendComponentProperties), |
|
||||
); |
|
||||
componentRef.value = h(component, properties); |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
refresh(); |
|
||||
</script> |
|
@ -1,88 +0,0 @@ |
|||||
<template> |
|
||||
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
|
||||
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
|
||||
<q-card-section class="text-positive px-2 pt-1 pb-0"> |
|
||||
<div class="row no-wrap items-center"> |
|
||||
<q-icon name="bi-chat-text" size="1.5em" /> |
|
||||
<span class="text-weight-bolder px-2">{{ $t('home.card.message.title') }}</span> |
|
||||
<q-space /> |
|
||||
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :title="$t('refresh')" :loading="loadingRef" @click="refresh" /> |
|
||||
<q-btn |
|
||||
size="12px" |
|
||||
icon="bi-justify" |
|
||||
flat |
|
||||
no-caps |
|
||||
padding="2px 6px 2px 6px" |
|
||||
:title="$t('home.card.message.action.list')" |
|
||||
:to="{ name: 'route.workbench.myMessage' }" |
|
||||
/> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
<q-card-section class="p-0"> |
|
||||
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
|
||||
<tbody> |
|
||||
<tr v-for="item in itemsRef" :key="item.id"> |
|
||||
<td width="100%" :title="item.content" class="truncate" :style="{ maxWidth: firstColMaxWidthRef + 'px' }"> |
|
||||
<a href="javascript:void(0);" style="cursor: pointer; color: blue" @click="handleTask(item)" v-html="item.content"></a> |
|
||||
</td> |
|
||||
<td width="80px" :title="item.sender" class="smallFont truncate" style="max-width: 80px"> |
|
||||
{{ item.sender }} |
|
||||
</td> |
|
||||
<td width="80px" :title="item.sendDate" class="smallFont truncate" style="max-width: 80px" align="right"> |
|
||||
{{ item.sendDateAndNowDiff + $t(item.sendDateAndNowDiffUnit) + $t('before') }} |
|
||||
</td> |
|
||||
</tr> |
|
||||
</tbody> |
|
||||
</q-markup-table> |
|
||||
</q-card-section> |
|
||||
<ChatDialog ref="chatDialogRef"> </ChatDialog> |
|
||||
</q-card> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import { axios, Environment } from '@/platform'; |
|
||||
import ChatDialog from './ChatDialog.vue'; |
|
||||
|
|
||||
const cardRef = ref(); |
|
||||
const cardHeightRef = ref(310); |
|
||||
const tableHeightRef = ref(300 - 30); |
|
||||
const firstColMaxWidthRef = ref(100); |
|
||||
|
|
||||
const itemsRef = ref([]); |
|
||||
const loadingRef = ref(false); |
|
||||
const chatDialogRef = ref(); |
|
||||
|
|
||||
const changeFirstColMaxWidth = () => { |
|
||||
let width = Math.ceil(cardRef.value.$el.clientWidth); |
|
||||
width = width - 160; |
|
||||
firstColMaxWidthRef.value = width > 100 ? width : 100; |
|
||||
}; |
|
||||
|
|
||||
const refresh = () => { |
|
||||
loadingRef.value = true; |
|
||||
axios |
|
||||
.get(Environment.apiContextPath('/api/system/notification/findUnReadedNotifications')) |
|
||||
.then((response: any) => { |
|
||||
itemsRef.value = response.data.content || []; |
|
||||
loadingRef.value = false; |
|
||||
}) |
|
||||
.catch(() => { |
|
||||
loadingRef.value = false; |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const handleTask = (item: any) => { |
|
||||
chatDialogRef.value.open(item.sender); |
|
||||
}; |
|
||||
|
|
||||
refresh(); |
|
||||
</script> |
|
||||
<style scoped> |
|
||||
.q-markup-table td { |
|
||||
padding: 0px 4px; |
|
||||
} |
|
||||
|
|
||||
.smallFont { |
|
||||
font-size: 0.8em; |
|
||||
} |
|
||||
</style> |
|
@ -0,0 +1,86 @@ |
|||||
|
<template> |
||||
|
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
||||
|
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
||||
|
<q-card-section class="text-orange px-2 pt-1 pb-0"> |
||||
|
<div class="row no-wrap items-center"> |
||||
|
<q-icon name="bi-megaphone" size="1.3em" /> |
||||
|
<span class="text-weight-bolder px-2">{{ $t('home.card.myAnnouncement.title') }}</span> |
||||
|
<q-space /> |
||||
|
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :loading="loadingRef" @click="refresh"> |
||||
|
<q-tooltip :delay="1000">{{ $t('refresh') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
<q-btn size="12px" icon="bi-justify" flat no-caps padding="2px 6px 2px 6px" :to="{ name: 'route.workbench.announcement' }"> |
||||
|
<q-tooltip :delay="1000">{{ $t('home.card.myAnnouncement.action.list') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
</div> |
||||
|
</q-card-section> |
||||
|
<q-card-section style="padding: 0px 6px 0px 6px"> |
||||
|
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
||||
|
<tbody> |
||||
|
<tr v-for="item in itemsRef" :key="item.id"> |
||||
|
<td width="100%" style="padding: 0px 4px"> |
||||
|
<a href="javascript:void(0);" class="flex flex-nowrap" :style="{ color: $gc.theme.home.announcementTextColor }" @click="handle(item)"> |
||||
|
<q-icon :color="item.userReaded ? 'grey-4' : 'positive'" name="bi-dot" size="sm" /> |
||||
|
<div class="truncate" :style="{ width: firstColMaxWidthRef + 'px', maxWidth: firstColMaxWidthRef + 'px' }" v-html="item.title"></div> |
||||
|
</a> |
||||
|
<q-tooltip :delay="1000"><div v-html="item.title"></div></q-tooltip> |
||||
|
</td> |
||||
|
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right"> |
||||
|
<div class="truncate" style="width: 62px; max-width: 62px"> |
||||
|
{{ item.lastModifyDateAndNowDiff + $t(item.lastModifyDateAndNowDiffUnit) + $t('before') }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.lastModifyDate }}</q-tooltip> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</q-markup-table> |
||||
|
<AnnouncementDialog ref="dialogRef"></AnnouncementDialog> |
||||
|
</q-card-section> |
||||
|
</q-card> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { axios, Environment } from '@/platform'; |
||||
|
import AnnouncementDialog from './AnnouncementDialog.vue'; |
||||
|
|
||||
|
const cardRef = ref(); |
||||
|
const cardHeightRef = ref(300); |
||||
|
const tableHeightRef = ref(300 - 30); |
||||
|
const firstColMaxWidthRef = ref(100); |
||||
|
|
||||
|
const itemsRef = ref([]); |
||||
|
const loadingRef = ref(false); |
||||
|
const dialogRef = ref(); |
||||
|
|
||||
|
const changeFirstColMaxWidth = () => { |
||||
|
//card width |
||||
|
let width = Math.ceil(cardRef.value.$el.clientWidth); |
||||
|
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 70 /* other tds width*/ - 24 /* icon width */; |
||||
|
//min width |
||||
|
width = width >= 100 ? width : 100; |
||||
|
firstColMaxWidthRef.value = width; |
||||
|
}; |
||||
|
|
||||
|
const refresh = () => { |
||||
|
loadingRef.value = true; |
||||
|
axios |
||||
|
.get(Environment.apiContextPath('/api/system/announcement?page=1&size=10&pageable=true&sortBy=-lastModifyDate')) |
||||
|
.then((response: any) => { |
||||
|
itemsRef.value = response.data.content || []; |
||||
|
loadingRef.value = false; |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
loadingRef.value = false; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const handle = (item: any) => { |
||||
|
dialogRef.value.open(item); |
||||
|
}; |
||||
|
|
||||
|
refresh(); |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,125 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
||||
|
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
||||
|
<q-card-section class="text-secondary px-2 pt-1 pb-0"> |
||||
|
<div class="row no-wrap items-center"> |
||||
|
<q-icon name="bi-list-check" size="1.5em" /> |
||||
|
<span class="text-weight-bolder px-2">{{ $t('home.card.myDoneTask.title') }}</span> |
||||
|
<q-space /> |
||||
|
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :loading="loadingRef" @click="refresh"> |
||||
|
<q-tooltip :delay="1000">{{ $t('refresh') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
<q-btn size="12px" icon="bi-justify" flat no-caps padding="2px 6px 2px 6px" :to="{ name: 'route.workbench.doneTask' }"> |
||||
|
<q-tooltip :delay="1000">{{ $t('home.card.myDoneTask.action.list') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
</div> |
||||
|
</q-card-section> |
||||
|
<q-card-section style="padding: 0px 6px 0px 6px"> |
||||
|
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
||||
|
<tbody> |
||||
|
<tr v-for="item in itemsRef" :key="item.id"> |
||||
|
<td width="100%" style="padding: 0px 4px"> |
||||
|
<a href="javascript:void(0);" :style="{ color: $gc.theme.home.myDoneTaskTextColor }" @click="handle(item)"> |
||||
|
<div |
||||
|
class="truncate" |
||||
|
:style="{ width: firstColMaxWidthRef + 'px', maxWidth: firstColMaxWidthRef + 'px' }" |
||||
|
v-html="item.businessDescription" |
||||
|
></div> |
||||
|
</a> |
||||
|
<q-tooltip :delay="1000">{{ item.businessDescription }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="100px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 92px; max-width: 92px"> |
||||
|
{{ item.processDefinitionName }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.processDefinitionName }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="60px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.name }}</div> |
||||
|
<q-tooltip :delay="1000">{{ item.name }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="60px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.previousAssignee }}</div> |
||||
|
<q-tooltip :delay="1000">{{ item.previousAssignee }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right"> |
||||
|
<div class="truncate" style="width: 62px; max-width: 62px"> |
||||
|
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.createTime }}</q-tooltip> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</q-markup-table> |
||||
|
</q-card-section> |
||||
|
</q-card> |
||||
|
<div style="width: 0px; height: 0px"> |
||||
|
<component :is="componentRef" style="width: 1px; height: 1px"></component> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { h, ref, defineAsyncComponent, nextTick } from 'vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager } from '@/platform'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const cardRef = ref(); |
||||
|
const cardHeightRef = ref(200); |
||||
|
const tableHeightRef = ref(200 - 30); |
||||
|
const firstColMaxWidthRef = ref(100); |
||||
|
|
||||
|
const itemsRef = ref([]); |
||||
|
const loadingRef = ref(false); |
||||
|
const componentRef = ref(); |
||||
|
|
||||
|
const changeFirstColMaxWidth = () => { |
||||
|
//card width |
||||
|
let width = Math.ceil(cardRef.value.$el.clientWidth); |
||||
|
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 290 /* other tds width*/; |
||||
|
//min width |
||||
|
width = width >= 100 ? width : 100; |
||||
|
firstColMaxWidthRef.value = width; |
||||
|
}; |
||||
|
|
||||
|
const refresh = () => { |
||||
|
loadingRef.value = true; |
||||
|
axios |
||||
|
.get(Environment.apiContextPath('/api/flowable/process/query/myDoneTask')) |
||||
|
.then((response: any) => { |
||||
|
itemsRef.value = response.data.content || []; |
||||
|
loadingRef.value = false; |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
loadingRef.value = false; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const handle = async (item: any) => { |
||||
|
if (item.taskHandFrontendModelName && item.taskHandFrontendComponentName) { |
||||
|
//删除已有组件 |
||||
|
componentRef.value = null; |
||||
|
//重新加载组件 |
||||
|
nextTick(() => { |
||||
|
const component = defineAsyncComponent(ComponentManager.getRemoteComponent(item.taskHandFrontendModelName, item.taskHandFrontendComponentName)); |
||||
|
componentRef.value = h(component, { |
||||
|
action: 'view', |
||||
|
task: item, |
||||
|
properties: Tools.json2Object(item.taskHandFrontendComponentProperties), |
||||
|
onClose: refresh, |
||||
|
}); |
||||
|
}); |
||||
|
} else if (item.taskHandFrontendRouteName) { |
||||
|
router.push({ name: item.taskHandFrontendRouteName }); |
||||
|
} else { |
||||
|
NotifyManager.warn($t('home.card.task.action.notSetting.tip')); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
refresh(); |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,125 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
||||
|
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
||||
|
<q-card-section class="text-info px-2 pt-1 pb-0"> |
||||
|
<div class="row no-wrap items-center"> |
||||
|
<q-icon name="bi-card-list" size="1.4em" /> |
||||
|
<span class="text-weight-bolder px-2">{{ $t('home.card.myFinishTask.title') }}</span> |
||||
|
<q-space /> |
||||
|
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :loading="loadingRef" @click="refresh"> |
||||
|
<q-tooltip :delay="1000">{{ $t('refresh') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
<q-btn size="12px" icon="bi-justify" flat no-caps padding="2px 6px 2px 6px" :to="{ name: 'route.workbench.finishedTask' }"> |
||||
|
<q-tooltip :delay="1000">{{ $t('home.card.myFinishTask.action.list') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
</div> |
||||
|
</q-card-section> |
||||
|
<q-card-section style="padding: 0px 6px 0px 6px"> |
||||
|
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
||||
|
<tbody> |
||||
|
<tr v-for="item in itemsRef" :key="item.id"> |
||||
|
<td width="100%" style="padding: 0px 4px"> |
||||
|
<a href="javascript:void(0);" :style="{ color: $gc.theme.home.myFinishedTaskTextColor }" @click="handle(item)"> |
||||
|
<div |
||||
|
class="truncate" |
||||
|
:style="{ width: firstColMaxWidthRef + 'px', maxWidth: firstColMaxWidthRef + 'px' }" |
||||
|
v-html="item.businessDescription" |
||||
|
></div> |
||||
|
</a> |
||||
|
<q-tooltip :delay="1000">{{ item.businessDescription }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="100px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 92px; max-width: 92px"> |
||||
|
{{ item.processDefinitionName }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.processDefinitionName }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="60px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.name }}</div> |
||||
|
<q-tooltip :delay="1000">{{ item.name }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="60px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.previousAssignee }}</div> |
||||
|
<q-tooltip :delay="1000">{{ item.previousAssignee }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right"> |
||||
|
<div class="truncate" style="width: 62px; max-width: 62px"> |
||||
|
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.createTime }}</q-tooltip> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</q-markup-table> |
||||
|
</q-card-section> |
||||
|
</q-card> |
||||
|
<div style="width: 0px; height: 0px"> |
||||
|
<component :is="componentRef" style="width: 1px; height: 1px"></component> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { h, ref, defineAsyncComponent, nextTick } from 'vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager } from '@/platform'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const cardRef = ref(); |
||||
|
const cardHeightRef = ref(200); |
||||
|
const tableHeightRef = ref(200 - 30); |
||||
|
const firstColMaxWidthRef = ref(100); |
||||
|
|
||||
|
const itemsRef = ref([]); |
||||
|
const loadingRef = ref(false); |
||||
|
const componentRef = ref(); |
||||
|
|
||||
|
const changeFirstColMaxWidth = () => { |
||||
|
//card width |
||||
|
let width = Math.ceil(cardRef.value.$el.clientWidth); |
||||
|
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 290 /* other tds width*/; |
||||
|
//min width |
||||
|
width = width >= 100 ? width : 100; |
||||
|
firstColMaxWidthRef.value = width; |
||||
|
}; |
||||
|
|
||||
|
const refresh = () => { |
||||
|
loadingRef.value = true; |
||||
|
axios |
||||
|
.get(Environment.apiContextPath('/api/flowable/process/query/myFinishedTask')) |
||||
|
.then((response: any) => { |
||||
|
itemsRef.value = response.data.content || []; |
||||
|
loadingRef.value = false; |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
loadingRef.value = false; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const handle = async (item: any) => { |
||||
|
if (item.taskHandFrontendModelName && item.taskHandFrontendComponentName) { |
||||
|
//删除已有组件 |
||||
|
componentRef.value = null; |
||||
|
//重新加载组件 |
||||
|
nextTick(() => { |
||||
|
const component = defineAsyncComponent(ComponentManager.getRemoteComponent(item.taskHandFrontendModelName, item.taskHandFrontendComponentName)); |
||||
|
componentRef.value = h(component, { |
||||
|
action: 'view', |
||||
|
task: item, |
||||
|
properties: Tools.json2Object(item.taskHandFrontendComponentProperties), |
||||
|
onClose: refresh, |
||||
|
}); |
||||
|
}); |
||||
|
} else if (item.taskHandFrontendRouteName) { |
||||
|
router.push({ name: item.taskHandFrontendRouteName }); |
||||
|
} else { |
||||
|
NotifyManager.warn($t('home.card.task.action.notSetting.tip')); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
refresh(); |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,107 @@ |
|||||
|
<template> |
||||
|
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
||||
|
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
||||
|
<q-card-section class="text-positive px-2 pt-1 pb-0"> |
||||
|
<div class="row no-wrap items-center"> |
||||
|
<q-icon name="bi-chat-text" size="1.5em" /> |
||||
|
<span class="text-weight-bolder px-2">{{ $t('home.card.myMessage.title') }}</span> |
||||
|
<q-space /> |
||||
|
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :loading="loadingRef" @click="refresh"> |
||||
|
<q-tooltip :delay="1000">{{ $t('refresh') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
<q-btn size="12px" icon="bi-justify" flat no-caps padding="2px 6px 2px 6px" :to="{ name: 'route.workbench.myMessage' }"> |
||||
|
<q-tooltip :delay="1000">{{ $t('home.card.myMessage.action.list') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
</div> |
||||
|
</q-card-section> |
||||
|
<q-card-section style="padding: 0px 6px 0px 6px"> |
||||
|
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
||||
|
<tbody> |
||||
|
<tr v-for="item in itemsRef" :key="item.id"> |
||||
|
<td width="100%" style="padding: 0px 4px"> |
||||
|
<a href="javascript:void(0);" class="flex flex-nowrap" :style="{ color: $gc.theme.home.myMessageTextColor }" @click="handle(item)"> |
||||
|
<q-icon :color="item.receiveDate ? 'grey-4' : 'positive'" name="bi-dot" size="sm" /> |
||||
|
<div |
||||
|
class="truncate" |
||||
|
:style="{ width: firstColMaxWidthRef + 'px', maxWidth: firstColMaxWidthRef + 'px' }" |
||||
|
v-html="item.title ? item.title : item.content" |
||||
|
></div> |
||||
|
</a> |
||||
|
<q-tooltip :delay="1000"><div v-html="item.title ? item.title : item.content"></div></q-tooltip> |
||||
|
</td> |
||||
|
<td width="80px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 72px; max-width: 72px">{{ item.sender }}</div> |
||||
|
<q-tooltip :delay="1000">{{ item.sender }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right"> |
||||
|
<div class="truncate" style="width: 62px; max-width: 62px"> |
||||
|
{{ item.sendDateAndNowDiff + $t(item.sendDateAndNowDiffUnit) + $t('before') }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.sendDate }}</q-tooltip> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</q-markup-table> |
||||
|
</q-card-section> |
||||
|
<UserMessageDialog ref="userMessageDialogRef"> </UserMessageDialog> |
||||
|
<SystemMessageDialog ref="systemMessageDialogRef"></SystemMessageDialog> |
||||
|
</q-card> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { axios, Environment, SessionManager, Tools } from '@/platform'; |
||||
|
import UserMessageDialog from './UserMessageDialog.vue'; |
||||
|
import SystemMessageDialog from './SystemMessageDialog.vue'; |
||||
|
|
||||
|
const cardRef = ref(); |
||||
|
const cardHeightRef = ref(310); |
||||
|
const tableHeightRef = ref(300 - 30); |
||||
|
const firstColMaxWidthRef = ref(100); |
||||
|
|
||||
|
const itemsRef = ref([]); |
||||
|
const loadingRef = ref(false); |
||||
|
const userMessageDialogRef = ref(); |
||||
|
const systemMessageDialogRef = ref(); |
||||
|
|
||||
|
const changeFirstColMaxWidth = () => { |
||||
|
//card width |
||||
|
let width = Math.ceil(cardRef.value.$el.clientWidth); |
||||
|
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 150 /* other tds width*/ - 24 /* icon width */; |
||||
|
//min width |
||||
|
width = width >= 100 ? width : 100; |
||||
|
firstColMaxWidthRef.value = width; |
||||
|
}; |
||||
|
|
||||
|
const refresh = () => { |
||||
|
loadingRef.value = true; |
||||
|
const criteria = { |
||||
|
fieldName: 'receiver', |
||||
|
operator: 'equals', |
||||
|
value: SessionManager.getUser().loginName, |
||||
|
}; |
||||
|
const criteriaQuery = encodeURIComponent(Tools.object2Json(criteria)); |
||||
|
axios |
||||
|
.get(Environment.apiContextPath('/api/system/notification?page=1&size=10&pageable=true&sortBy=-sendDate&criteria=' + criteriaQuery)) |
||||
|
.then((response: any) => { |
||||
|
itemsRef.value = response.data.content || []; |
||||
|
loadingRef.value = false; |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
loadingRef.value = false; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const handle = (item: any) => { |
||||
|
if (item.sender === 'system') { |
||||
|
systemMessageDialogRef.value.open(item); |
||||
|
} else { |
||||
|
userMessageDialogRef.value.open(item.sender); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
refresh(); |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,64 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-card flat bordered> |
||||
|
<q-card-section class="text-secondary px-2 pt-1 pb-0"> |
||||
|
<div class="row no-wrap items-center"> |
||||
|
<q-icon name="bi-cursor" size="1.5em" /> |
||||
|
<span class="text-weight-bolder px-2">{{ $t('home.card.myShortcutmenu.title') }}</span> |
||||
|
<q-space /> |
||||
|
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :loading="loadingRef" @click="refresh"> |
||||
|
<q-tooltip :delay="1000">{{ $t('refresh') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
<q-btn size="12px" flat no-caps :label="$t('home.card.myShortcutmenu.action.config')" @click="setting(item)" /> |
||||
|
</div> |
||||
|
</q-card-section> |
||||
|
<q-card-section class="p-2"> |
||||
|
<div class="row"> |
||||
|
<div class="col-12"> |
||||
|
<div class="q-gutter-x-md q-gutter-y-md"> |
||||
|
<template v-for="item in shortcutMenusRef" :key="item.id"> |
||||
|
<q-btn stack :to="{ name: item.menu.routeName }"> |
||||
|
<q-icon :name="item.menu.icon" :color="item.menuIconColor" /> |
||||
|
<div>{{ item.shortcutMenuName }}</div> |
||||
|
</q-btn> |
||||
|
</template> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</q-card-section> |
||||
|
</q-card> |
||||
|
<ShortcutMenuSettingDialog ref="shortcutMenuSettingDialogRef" @close="refresh"></ShortcutMenuSettingDialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { axios, Environment, SessionManager, I18nMessageManager, AuthenticationManager, Tools } from '@/platform'; |
||||
|
import ShortcutMenuSettingDialog from './ShortcutMenuSettingDialog.vue'; |
||||
|
|
||||
|
const shortcutMenuSettingDialogRef = ref(); |
||||
|
const shortcutMenusRef = ref([]); |
||||
|
const loadingRef = ref(false); |
||||
|
|
||||
|
const refresh = () => { |
||||
|
loadingRef.value = true; |
||||
|
axios |
||||
|
.get(Environment.apiContextPath('/api/system/setttings/shortcutmenu/findShortcutMenus')) |
||||
|
.then((response) => { |
||||
|
shortcutMenusRef.value = response.data || []; |
||||
|
loadingRef.value = false; |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
loadingRef.value = false; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const setting = () => { |
||||
|
shortcutMenuSettingDialogRef?.value.open(); |
||||
|
}; |
||||
|
|
||||
|
refresh(); |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,128 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
||||
|
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
||||
|
<q-card-section class="text-warning px-2 pt-1 pb-0"> |
||||
|
<div class="row no-wrap items-center"> |
||||
|
<q-icon name="bi-list-ol" size="1.5em" /> |
||||
|
<span class="text-weight-bolder px-2">{{ $t('home.card.myTask.title') }}</span> |
||||
|
<q-space /> |
||||
|
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :loading="loadingRef" @click="refresh"> |
||||
|
<q-tooltip :delay="1000">{{ $t('refresh') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
<q-btn size="12px" icon="bi-justify" flat no-caps padding="2px 6px 2px 6px" :to="{ name: 'route.workbench.myTask' }"> |
||||
|
<q-tooltip :delay="1000">{{ $t('home.card.myTask.action.list') }}</q-tooltip> |
||||
|
</q-btn> |
||||
|
</div> |
||||
|
</q-card-section> |
||||
|
<q-card-section style="padding: 0px 6px 0px 6px"> |
||||
|
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
||||
|
<tbody> |
||||
|
<tr v-for="item in itemsRef" :key="item.id"> |
||||
|
<td width="100%" style="padding: 0px 4px"> |
||||
|
<a href="javascript:void(0);" :style="{ color: $gc.theme.home.myTaskTextColor }" @click="handle(item)"> |
||||
|
<div |
||||
|
class="truncate" |
||||
|
:style="{ width: firstColMaxWidthRef + 'px', maxWidth: firstColMaxWidthRef + 'px' }" |
||||
|
v-html="item.businessDescription" |
||||
|
></div> |
||||
|
</a> |
||||
|
<q-tooltip :delay="1000">{{ item.businessDescription }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="100px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 92px; max-width: 92px"> |
||||
|
{{ item.processDefinitionName }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.processDefinitionName }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="60px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.name }}</div> |
||||
|
<q-tooltip :delay="1000">{{ item.name }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="60px" style="font-size: 0.8em; padding: 0px 4px"> |
||||
|
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.previousAssignee }}</div> |
||||
|
<q-tooltip :delay="1000">{{ item.previousAssignee }}</q-tooltip> |
||||
|
</td> |
||||
|
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right"> |
||||
|
<div class="truncate" style="width: 62px; max-width: 62px"> |
||||
|
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }} |
||||
|
</div> |
||||
|
<q-tooltip :delay="1000">{{ item.createTime }}</q-tooltip> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</q-markup-table> |
||||
|
</q-card-section> |
||||
|
</q-card> |
||||
|
<div style="width: 0px; height: 0px"> |
||||
|
<component :is="componentRef" style="width: 1px; height: 1px"></component> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { h, ref, defineAsyncComponent, nextTick } from 'vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager } from '@/platform'; |
||||
|
|
||||
|
const emit = defineEmits(['afterRefresh']); |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const cardRef = ref(); |
||||
|
const cardHeightRef = ref(200); |
||||
|
const tableHeightRef = ref(200 - 30); |
||||
|
const firstColMaxWidthRef = ref(100); |
||||
|
|
||||
|
const itemsRef = ref([]); |
||||
|
const loadingRef = ref(false); |
||||
|
const componentRef = ref(); |
||||
|
|
||||
|
const changeFirstColMaxWidth = () => { |
||||
|
//card width |
||||
|
let width = Math.ceil(cardRef.value.$el.clientWidth); |
||||
|
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 290 /* other tds width*/; |
||||
|
//min width |
||||
|
width = width >= 100 ? width : 100; |
||||
|
firstColMaxWidthRef.value = width; |
||||
|
}; |
||||
|
|
||||
|
const refresh = () => { |
||||
|
loadingRef.value = true; |
||||
|
axios |
||||
|
.get(Environment.apiContextPath('/api/flowable/process/query/myTask')) |
||||
|
.then((response: any) => { |
||||
|
itemsRef.value = response.data.content || []; |
||||
|
loadingRef.value = false; |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
loadingRef.value = false; |
||||
|
}); |
||||
|
emit('afterRefresh'); |
||||
|
}; |
||||
|
|
||||
|
const handle = async (item: any) => { |
||||
|
if (item.taskHandFrontendModelName && item.taskHandFrontendComponentName) { |
||||
|
//删除已有组件 |
||||
|
componentRef.value = null; |
||||
|
//重新加载组件 |
||||
|
nextTick(() => { |
||||
|
const component = defineAsyncComponent(ComponentManager.getRemoteComponent(item.taskHandFrontendModelName, item.taskHandFrontendComponentName)); |
||||
|
componentRef.value = h(component, { |
||||
|
action: 'process', |
||||
|
task: item, |
||||
|
properties: Tools.json2Object(item.taskHandFrontendComponentProperties), |
||||
|
onClose: refresh, |
||||
|
}); |
||||
|
}); |
||||
|
} else if (item.taskHandFrontendRouteName) { |
||||
|
router.push({ name: item.taskHandFrontendRouteName }); |
||||
|
} else { |
||||
|
NotifyManager.warn($t('home.card.myTask.action.notSetting.tip')); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
refresh(); |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -1,40 +0,0 @@ |
|||||
<template> |
|
||||
<q-card flat bordered> |
|
||||
<q-card-section class="text-secondary px-2 pt-1 pb-0"> |
|
||||
<div class="row no-wrap items-center"> |
|
||||
<q-icon name="bi-cursor" size="1.5em" /> |
|
||||
<span class="text-weight-bolder px-2">{{ $t('home.card.shortcutmenu.title') }}</span> |
|
||||
<q-space /> |
|
||||
<q-btn size="12px" flat no-caps :label="$t('home.card.shortcutmenu.action.config')" :to="{ name: 'route.system.settings' }" /> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
<q-card-section class="p-2"> |
|
||||
<div class="row"> |
|
||||
<div class="col-12"> |
|
||||
<div class="q-gutter-x-md q-gutter-y-md"> |
|
||||
<template v-for="item in shortcutMenusRef" :key="item.id"> |
|
||||
<q-btn stack :to="{ name: item.menu.routeName }"> |
|
||||
<q-icon :name="item.menu.icon" :color="item.menuIconColor" /> |
|
||||
<div>{{ item.shortcutMenuName }}</div> |
|
||||
</q-btn> |
|
||||
</template> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
</q-card> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import { axios, Environment, SessionManager, I18nMessageManager, AuthenticationManager, Tools } from '@/platform'; |
|
||||
|
|
||||
const shortcutMenusRef = ref([]); |
|
||||
|
|
||||
const findShortcutMenus = () => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/setttings/shortcutmenu/findShortcutMenus')).then((response) => { |
|
||||
shortcutMenusRef.value = response.data || []; |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
findShortcutMenus(); |
|
||||
</script> |
|
@ -0,0 +1,168 @@ |
|||||
|
<template> |
||||
|
<w-dialog |
||||
|
ref="dialogRef" |
||||
|
:title="$t('settings.shortcutMenus')" |
||||
|
:can-maximize="false" |
||||
|
:maximized="false" |
||||
|
body-padding="4px 4px 4px 4px" |
||||
|
width="60%" |
||||
|
@hide=" |
||||
|
() => { |
||||
|
emit('close'); |
||||
|
} |
||||
|
" |
||||
|
> |
||||
|
<w-grid |
||||
|
:title="$t('settings.shortcutMenus')" |
||||
|
:height="400" |
||||
|
:config-button="true" |
||||
|
dnd-mode="server" |
||||
|
db-click-operation="edit" |
||||
|
selection="multiple" |
||||
|
:checkbox-selection="true" |
||||
|
:data-url="Environment.apiContextPath('/api/system/setttings/shortcutmenu')" |
||||
|
:sort-by="['order']" |
||||
|
:query-form-cols-num="2" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="['refresh', 'separator', 'add', 'edit', 'remove', 'separator', 'view', 'separator', 'export']" |
||||
|
:columns="[ |
||||
|
{ width: 200, name: 'shortcutMenuName', label: $t('settings.shortcutMenus.entity.shortcutMenuName'), sortable: false }, |
||||
|
{ |
||||
|
width: 100, |
||||
|
name: 'menuIconColor', |
||||
|
label: $t('settings.shortcutMenus.entity.menuIconColor'), |
||||
|
sortable: false, |
||||
|
format: (value, row) => { |
||||
|
return '<span class=\'text-' + value + '\'>' + value + '</span>'; |
||||
|
}, |
||||
|
}, |
||||
|
{ width: 70, name: 'order', label: $t('order'), sortable: false, align: 'right' }, |
||||
|
{ width: 300, name: 'menuCode', label: $t('code') }, |
||||
|
{ |
||||
|
width: 300, |
||||
|
name: 'menuName', |
||||
|
label: $t('name'), |
||||
|
format: (value, row) => { |
||||
|
return $t(row.menuCode); |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ |
||||
|
name: 'menuId', |
||||
|
label: $t('menu'), |
||||
|
type: 'w-grid-select', |
||||
|
requiredIf: true, |
||||
|
selectableIf: (args: any) => { |
||||
|
if (args.row.type === 'GROUP') { |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
displayValue: (args: any) => { |
||||
|
const data = args.data; |
||||
|
return $t(data.titleI18nKey); |
||||
|
}, |
||||
|
onUpdateValue: (args: any) => { |
||||
|
if (args.data) { |
||||
|
args.form.setFieldValue('menuCode', args.data.name); |
||||
|
args.form.setFieldValue('shortcutMenuName', $t(args.data.name)); |
||||
|
} |
||||
|
}, |
||||
|
grid: { |
||||
|
title: $t('system.menu.grid.title'), |
||||
|
height: 300, |
||||
|
denseBody: true, |
||||
|
hideBottom: true, |
||||
|
configButton: true, |
||||
|
checkboxSelection: false, |
||||
|
tree: true, |
||||
|
treeIcon: (row: any) => { |
||||
|
if (row.type === 'SEPARATOR') { |
||||
|
return { name: 'bi-dash-lg' }; |
||||
|
} else { |
||||
|
return { name: row.icon }; |
||||
|
} |
||||
|
}, |
||||
|
dataUrl: Environment.apiContextPath('/api/system/menu/listAllMenusByUser'), |
||||
|
pageable: false, |
||||
|
sortBy: ['order'], |
||||
|
toolbarConfigure: { noIcon: false }, |
||||
|
toolbarActions: ['refresh', 'expand'], |
||||
|
columns: [ |
||||
|
{ |
||||
|
width: '100%', |
||||
|
name: 'titleI18nKey', |
||||
|
label: $t('name'), |
||||
|
sortable: false, |
||||
|
format: (value, row) => { |
||||
|
if (row.type === 'SEPARATOR') { |
||||
|
return `<hr style='width:100px'/>`; |
||||
|
} else if (row.type === 'ROUTE_ACTION') { |
||||
|
return $t(row.i18nKey); |
||||
|
} else { |
||||
|
return $t(value); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
{ width: 80, name: 'type', label: $t('type'), sortable: false, format: Formater.menuType() }, |
||||
|
{ width: 80, name: 'order', label: $t('order'), align: 'right', sortable: false }, |
||||
|
{ width: 80, name: 'enable', label: $t('status'), sortable: false, format: Formater.enableTag() }, |
||||
|
], |
||||
|
}, |
||||
|
}, |
||||
|
{ name: 'menuCode', label: $t('menuCode'), type: 'w-text', showIf: false }, |
||||
|
{ name: 'shortcutMenuName', label: $t('settings.shortcutMenus.entity.shortcutMenuName'), type: 'w-text' }, |
||||
|
{ |
||||
|
name: 'menuIconColor', |
||||
|
label: $t('settings.shortcutMenus.entity.shortcutMenuName'), |
||||
|
type: 'w-color-input-palette', |
||||
|
defaultValue: 'primary', |
||||
|
}, |
||||
|
{ name: 'order', label: $t('order'), type: 'w-integer' }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'shortcutMenuName', label: $t('settings.shortcutMenus.entity.shortcutMenuName') }, |
||||
|
{ name: 'order', label: $t('order'), type: 'w-integer' }, |
||||
|
{ name: 'menuCode', label: $t('menuCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
> |
||||
|
</w-grid> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { Environment, Formater } from '@/platform'; |
||||
|
|
||||
|
const emit = defineEmits(['close']); |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
|
||||
|
const open = (item: any) => { |
||||
|
dialogRef.value.show(); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
dialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
close, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,45 @@ |
|||||
|
<template> |
||||
|
<w-dialog |
||||
|
ref="dialogRef" |
||||
|
:title="$t('home.card.message.systemMessageDialog.title')" |
||||
|
:can-maximize="false" |
||||
|
:maximized="false" |
||||
|
body-padding="2px 2px 2px 2px" |
||||
|
width="60%" |
||||
|
@hide=" |
||||
|
() => { |
||||
|
emit('close'); |
||||
|
} |
||||
|
" |
||||
|
> |
||||
|
<div class="p-2"> |
||||
|
<div class="text-h6 p-2">{{ itemRef.title }}</div> |
||||
|
<div class="p-2" v-html="itemRef.content"></div> |
||||
|
</div> |
||||
|
<div style="height: 20px"></div> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { axios, Environment, SessionManager } from '@/platform'; |
||||
|
|
||||
|
const emit = defineEmits(['close']); |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
const itemRef = ref(); |
||||
|
|
||||
|
const open = (item: any) => { |
||||
|
itemRef.value = item; |
||||
|
dialogRef.value.show(); |
||||
|
axios.post(Environment.apiContextPath('api/system/notification/updateReceiveDate/' + item.id)); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
dialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
close, |
||||
|
}); |
||||
|
</script> |
@ -1,94 +0,0 @@ |
|||||
<template> |
|
||||
<q-card ref="cardRef" flat bordered :style="{ width: '100%', height: cardHeightRef + 'px' }"> |
|
||||
<q-resize-observer @resize="changeFirstColMaxWidth" /> |
|
||||
<q-card-section class="text-warning px-2 pt-1 pb-0"> |
|
||||
<div class="row no-wrap items-center"> |
|
||||
<q-icon name="bi-list-ol" size="1.5em" /> |
|
||||
<span class="text-weight-bolder px-2">{{ $t('home.card.task.title') }}</span> |
|
||||
<q-space /> |
|
||||
<q-btn size="12px" icon="bi-arrow-repeat" flat no-caps padding="2px 6px 2px 6px" :title="$t('refresh')" :loading="loadingRef" @click="refresh" /> |
|
||||
<q-btn |
|
||||
size="12px" |
|
||||
icon="bi-justify" |
|
||||
flat |
|
||||
no-caps |
|
||||
padding="2px 6px 2px 6px" |
|
||||
:title="$t('home.card.task.action.list')" |
|
||||
:to="{ name: 'route.workbench.myTask' }" |
|
||||
/> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
<q-card-section class="px-0 py-0"> |
|
||||
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }"> |
|
||||
<tbody> |
|
||||
<tr v-for="item in itemsRef" :key="item.id"> |
|
||||
<td width="100%" :title="item.businessDescription" class="truncate" :style="{ maxWidth: firstColMaxWidthRef + 'px', padding: '0px 4px' }"> |
|
||||
<w-html-a :label="item.businessDescription" @click="handleTask(item)"></w-html-a> |
|
||||
</td> |
|
||||
<td width="100px" :title="item.processDefinitionName" class="smallFont truncate" style="max-width: 100px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.processDefinitionName }} |
|
||||
</td> |
|
||||
<td width="80px" :title="item.name" class="smallFont truncate" style="max-width: 80px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.name }} |
|
||||
</td> |
|
||||
<td width="80px" :title="item.previousAssignee" class="smallFont truncate" style="max-width: 80px; font-size: 0.8em; padding: 0px 4px"> |
|
||||
{{ item.previousAssignee }} |
|
||||
</td> |
|
||||
<td width="80px" :title="item.createTime" class="smallFont truncate" style="max-width: 80px; font-size: 0.8em; padding: 0px 4px" align="right"> |
|
||||
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }} |
|
||||
</td> |
|
||||
</tr> |
|
||||
</tbody> |
|
||||
</q-markup-table> |
|
||||
</q-card-section> |
|
||||
<component :is="componentRef"></component> |
|
||||
</q-card> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { h, ref, defineAsyncComponent, nextTick } from 'vue'; |
|
||||
import { axios, Environment, ComponentManager, Tools } from '@/platform'; |
|
||||
|
|
||||
const cardRef = ref(); |
|
||||
const cardHeightRef = ref(200); |
|
||||
const tableHeightRef = ref(200 - 30); |
|
||||
const firstColMaxWidthRef = ref(100); |
|
||||
|
|
||||
const itemsRef = ref([]); |
|
||||
const loadingRef = ref(false); |
|
||||
const componentRef = ref(); |
|
||||
|
|
||||
const changeFirstColMaxWidth = () => { |
|
||||
let width = Math.ceil(cardRef.value.$el.clientWidth); |
|
||||
width = width - 340; |
|
||||
firstColMaxWidthRef.value = width > 100 ? width : 100; |
|
||||
}; |
|
||||
|
|
||||
const refresh = () => { |
|
||||
loadingRef.value = true; |
|
||||
axios |
|
||||
.get(Environment.apiContextPath('/api/flowable/process/query/task')) |
|
||||
.then((response: any) => { |
|
||||
itemsRef.value = response.data.content || []; |
|
||||
loadingRef.value = false; |
|
||||
}) |
|
||||
.catch(() => { |
|
||||
loadingRef.value = false; |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const handleTask = async (item: any) => { |
|
||||
//删除已有组件 |
|
||||
componentRef.value = null; |
|
||||
//重新加载组件 |
|
||||
nextTick(() => { |
|
||||
const component = defineAsyncComponent(ComponentManager.getRemoteComponent(item.taskHandFrontendModelName, item.taskHandFrontendComponentName)); |
|
||||
const properties = Tools.mergeObject( |
|
||||
{ taskId: item.id, businessKey: item.businessKey, action: 'process' }, |
|
||||
Tools.json2Object(item.taskHandFrontendComponentProperties), |
|
||||
); |
|
||||
componentRef.value = h(component, properties); |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
refresh(); |
|
||||
</script> |
|
@ -0,0 +1,41 @@ |
|||||
|
package io.sc.platform.flowable.support; |
||||
|
|
||||
|
import io.sc.platform.util.DateUtil; |
||||
|
import io.sc.platform.util.support.DateDiff; |
||||
|
import org.springframework.jdbc.core.RowMapper; |
||||
|
|
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
import java.time.temporal.ChronoUnit; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class ProcessTaskWrapperMapper implements RowMapper<ProcessTaskWrapper> { |
||||
|
@Override |
||||
|
public ProcessTaskWrapper mapRow(ResultSet rs, int rowNum) throws SQLException { |
||||
|
ProcessTaskWrapper wrapper =new ProcessTaskWrapper(); |
||||
|
wrapper.setId(rs.getString("id")); |
||||
|
wrapper.setName(rs.getString("name")); |
||||
|
wrapper.setDescription(rs.getString("description")); |
||||
|
wrapper.setPriority(rs.getInt("priority")); |
||||
|
wrapper.setOwner(rs.getString("owner")); |
||||
|
wrapper.setAssignee(rs.getString("assignee")); |
||||
|
wrapper.setProcessInstanceId(rs.getString("processInstanceId")); |
||||
|
wrapper.setExecutionId(rs.getString("executionId")); |
||||
|
wrapper.setProcessDefinitionId(rs.getString("processDefinitionId")); |
||||
|
wrapper.setProcessDefinitionName(rs.getString("processDefinitionName")); |
||||
|
wrapper.setProcessDefinitionVersion(rs.getInt("processDefinitionVersion")); |
||||
|
wrapper.setScopeId(rs.getString("scopeId")); |
||||
|
wrapper.setSubScopeId(rs.getString("subScopeId")); |
||||
|
wrapper.setScopeType(rs.getString("scopeType")); |
||||
|
wrapper.setScopeDefinitionId(rs.getString("scopeDefinitionId")); |
||||
|
wrapper.setCreateTime(rs.getDate("createTime")); |
||||
|
wrapper.setTaskDefinitionKey(rs.getString("taskDefinitionKey")); |
||||
|
wrapper.setDueDate(rs.getDate("dueDate")); |
||||
|
wrapper.setCategory(rs.getString("category")); |
||||
|
wrapper.setParentTaskId(rs.getString("parentTaskId")); |
||||
|
wrapper.setTenantId(rs.getString("tenantId")); |
||||
|
wrapper.setFormKey(rs.getString("formKey")); |
||||
|
wrapper.setClaimTime(rs.getDate("claimTime")); |
||||
|
return wrapper; |
||||
|
} |
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
<template> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-4 col-md-6 col-sm-8 col-xs-10"> |
||||
|
<w-color-input v-model="$gc.theme.home['myTaskTextColor']" :label="$t('theme.home.myTaskTextColor')" class="p-1" dense outlined restore></w-color-input> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-4 col-md-6 col-sm-8 col-xs-10"> |
||||
|
<w-color-input |
||||
|
v-model="$gc.theme.home['myDoneTaskTextColor']" |
||||
|
:label="$t('theme.home.myDoneTaskTextColor')" |
||||
|
class="p-1" |
||||
|
dense |
||||
|
outlined |
||||
|
restore |
||||
|
></w-color-input> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-4 col-md-6 col-sm-8 col-xs-10"> |
||||
|
<w-color-input |
||||
|
v-model="$gc.theme.home['myFinishedTaskTextColor']" |
||||
|
:label="$t('theme.home.myFinishedTaskTextColor')" |
||||
|
class="p-1" |
||||
|
dense |
||||
|
outlined |
||||
|
restore |
||||
|
></w-color-input> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-4 col-md-6 col-sm-8 col-xs-10"> |
||||
|
<w-color-input |
||||
|
v-model="$gc.theme.home['myMessageTextColor']" |
||||
|
:label="$t('theme.home.myMessageTextColor')" |
||||
|
class="p-1" |
||||
|
dense |
||||
|
outlined |
||||
|
restore |
||||
|
></w-color-input> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-4 col-md-6 col-sm-8 col-xs-10"> |
||||
|
<w-color-input |
||||
|
v-model="$gc.theme.home['announcementTextColor']" |
||||
|
:label="$t('theme.home.announcementTextColor')" |
||||
|
class="p-1" |
||||
|
dense |
||||
|
outlined |
||||
|
restore |
||||
|
></w-color-input> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { Environment } from 'platform-core'; |
||||
|
|
||||
|
console.log(Environment.getConfigure().theme); |
||||
|
</script> |
@ -0,0 +1,49 @@ |
|||||
|
package io.sc.platform.lcdp.configure.api; |
||||
|
|
||||
|
public class Home { |
||||
|
private String myTaskTextColor ="black"; // 我的代办文本颜色
|
||||
|
private String myDoneTaskTextColor ="black"; // 我的已办文本颜色
|
||||
|
private String myFinishedTaskTextColor ="black"; // 我的办结文本颜色
|
||||
|
private String myMessageTextColor ="black"; // 我的消息文本颜色
|
||||
|
private String announcementTextColor ="black"; // 系统公告文本颜色
|
||||
|
|
||||
|
public String getMyTaskTextColor() { |
||||
|
return myTaskTextColor; |
||||
|
} |
||||
|
|
||||
|
public void setMyTaskTextColor(String myTaskTextColor) { |
||||
|
this.myTaskTextColor = myTaskTextColor; |
||||
|
} |
||||
|
|
||||
|
public String getMyDoneTaskTextColor() { |
||||
|
return myDoneTaskTextColor; |
||||
|
} |
||||
|
|
||||
|
public void setMyDoneTaskTextColor(String myDoneTaskTextColor) { |
||||
|
this.myDoneTaskTextColor = myDoneTaskTextColor; |
||||
|
} |
||||
|
|
||||
|
public String getMyFinishedTaskTextColor() { |
||||
|
return myFinishedTaskTextColor; |
||||
|
} |
||||
|
|
||||
|
public void setMyFinishedTaskTextColor(String myFinishedTaskTextColor) { |
||||
|
this.myFinishedTaskTextColor = myFinishedTaskTextColor; |
||||
|
} |
||||
|
|
||||
|
public String getMyMessageTextColor() { |
||||
|
return myMessageTextColor; |
||||
|
} |
||||
|
|
||||
|
public void setMyMessageTextColor(String myMessageTextColor) { |
||||
|
this.myMessageTextColor = myMessageTextColor; |
||||
|
} |
||||
|
|
||||
|
public String getAnnouncementTextColor() { |
||||
|
return announcementTextColor; |
||||
|
} |
||||
|
|
||||
|
public void setAnnouncementTextColor(String announcementTextColor) { |
||||
|
this.announcementTextColor = announcementTextColor; |
||||
|
} |
||||
|
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue