This commit is contained in:
吴红兵
2025-12-02 10:37:49 +08:00
commit 1f645dad3e
1183 changed files with 147673 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
export default {
flowApplication: {
index: '#',
importflowApplicationTip: 'import FlowApplication',
id: 'id',
flowKey: 'flowKey',
icon: 'icon',
formName: 'formName',
groupName: 'groupName',
tableName: 'tableName',
permission: 'permission',
remark: 'remark',
status: 'status',
version: 'version',
createUser: 'createUser',
createTime: 'createTime',
defFlowId: 'defFlowId',
formInfo: 'formInfo',
type: 'type',
subTableName: 'subTableName',
subMainField: 'subMainField',
mainSubProp: 'mainSubProp',
sort: 'sort',
updateUser: 'updateUser',
updateTime: 'updateTime',
delFlag: 'delFlag',
inputIdTip: 'input id',
inputFlowKeyTip: 'input flowKey',
inputIconTip: 'input icon',
inputFormNameTip: 'input formName',
inputGroupNameTip: 'input groupName',
inputTableNameTip: 'input tableName',
inputPermissionTip: 'input permission',
inputRemarkTip: 'input remark',
inputStatusTip: 'input status',
inputVersionTip: 'input version',
inputCreateUserTip: 'input createUser',
inputCreateTimeTip: 'input createTime',
inputDefFlowIdTip: 'input defFlowId',
inputFormInfoTip: 'input formInfo',
inputTypeTip: 'input type',
inputSubTableNameTip: 'input subTableName',
inputSubMainFieldTip: 'input subMainField',
inputMainSubPropTip: 'input mainSubProp',
inputSortTip: 'input sort',
inputUpdateUserTip: 'input updateUser',
inputUpdateTimeTip: 'input updateTime',
inputDelFlagTip: 'input delFlag',
}
}

View File

@@ -0,0 +1,52 @@
export default {
flowApplication: {
index: '#',
importflowApplicationTip: '导入办公申请',
id: '主键id',
flowKey: '流程KEY',
icon: '表单图标',
formName: '表单名称',
groupName: '分组名称',
tableName: '关联表名称',
permission: '操作权限',
remark: '表单备注',
status: '状态',
version: '版本',
createUser: '创建人',
createTime: '创建时间',
defFlowId: '流程定义ID',
formInfo: '表单信息',
type: '表单类型',
subTableName: '关联子表名称',
subMainField: '关联主表列名',
mainSubProp: '关联子表属性',
sort: '排序值',
updateUser: '修改人',
updateTime: '修改时间',
delFlag: '删除标',
inputIdTip: '请输入主键id',
inputFlowKeyTip: '请输入流程KEY',
inputIconTip: '请输入表单图标',
inputFormNameTip: '请输入表单名称',
inputGroupNameTip: '请输入分组名称',
inputTableNameTip: '请输入关联表名称',
inputPermissionTip: '请选择操作角色, 默认所有人都可以发起该流程',
inputRemarkTip: '请输入表单备注',
inputStatusTip: '请输入状态',
inputVersionTip: '请输入版本',
inputCreateUserTip: '请输入创建人',
inputCreateTimeTip: '请输入创建时间',
inputDefFlowIdTip: '请输入流程定义ID',
inputFormInfoTip: '请输入表单信息',
inputTypeTip: '请选择表单类型',
inputSubTableNameTip: '请选择关联子表名称',
inputSubMainFieldTip: '请输入关联主表列名',
inputMainSubPropTip: '请输入关联子表属性',
inputSortTip: '请输入排序值',
inputUpdateUserTip: '请输入修改人',
inputUpdateTimeTip: '请输入修改时间',
inputDelFlagTip: '请输入删除标',
}
}

View File

@@ -0,0 +1,309 @@
<template>
<div class="layout-padding">
<div style="background: #f4f4f5; margin-bottom: 10px" class="el_result_layout">
<el-row :gutter="24">
<el-col :span="8">
<el-space class="el-space_container" @click="handleClickHref('TodoJobHash')">
<el-result style="width: 100px; padding: 0;">
<template #icon>
<el-icon :size="50" style="color: #409EFF;"><BellFilled /></el-icon>
</template>
</el-result>
<el-card shadow="never" class="el-card__title__" style="width: 220px; border: none">
<template #header> 待我审批 </template>
<div style="height: 23px; font-size: 30px; font-weight: bold;"> {{ useFlowJob().jobLen }} </div>
</el-card>
</el-space>
</el-col>
<el-col :span="4" style="padding: 0;">
<el-result class="el-result__style__" @click="handleClickHref('RunApplicationHash')"
title="我的申请">
<template #icon>
<el-icon :size="40" style="color: #409EFF;"><Promotion /></el-icon>
</template>
</el-result>
</el-col>
<el-col :span="4" style="padding: 0;">
<el-result class="el-result__style__" @click="handleClickHref('TodoJobHash', '?belongType=1')"
title="抄送我的">
<template #icon>
<el-icon :size="40" style="color: #409EFF;"><Avatar /></el-icon>
</template>
</el-result>
</el-col>
<el-col :span="4" style="padding: 0;">
<el-result class="el-result__style__" @click="handleClickHref('SignJobHash')"
title="待认领的">
<template #icon>
<el-icon :size="40" style="color: #409EFF;"><Opportunity /></el-icon>
</template>
</el-result>
</el-col>
<el-col :span="4" style="padding: 0 10px 0 0;">
<el-result class="el-result__style__" @click="handleClickHref('HiJobHash')"
title="我审批的">
<template #icon>
<el-icon :size="40" style="color: #409EFF;"><Stamp /></el-icon>
</template>
</el-result>
</el-col>
</el-row>
</div>
<div class="layout-padding-auto layout-padding-view" style="overflow-y: auto;">
<template v-for="(tabs, index) in data.tabsData" :key="index">
<el-collapse v-model="data.collapse">
<el-collapse-item :name="index">
<template #title>
<el-icon :size="24" style="margin-right: 8px; color: #409EFF;">
<CaretRight v-if="!data.collapse.includes(index)" />
<CaretBottom v-else />
</el-icon>
<div style="font-size: 14px;"> {{ tabs.groupName }} </div>
</template>
<div class="avue-view__avue-card">
<el-row
:span="24"
:gutter="20">
<el-col v-for="(item,index) in data.tableData.filter(f => f.groupName === tabs.groupName)"
:key="index"
:span="6">
<div class="avue-card__item">
<div class="avue-card__body">
<div class="avue-card__avatar2">
<i :class="item.icon" alt="" style="font-size: 38px!important;color: #409EFF;"/>
</div>
<div class="avue-card__detail">
<div class="avue-card__title">{{ item.formName }} V{{ item.version }}</div>
<div class="avue-card__info">{{ item.remark }}</div>
</div>
</div>
<div class="avue-card__menu">
<span
v-if="item.status === '1'" v-auth="'order_flowapplication_edit'"
@click.stop="handleInitiateOrder(item,index)">发起工单
</span>
<span v-auth="'order_flowapplication_edit'"
@click.stop="openPreview(item.defFlowId)">查看流程图
</span>
</div>
</div>
</el-col>
</el-row>
</div>
</el-collapse-item>
</el-collapse>
</template>
<!-- 发起工单 -->
<json-flow-predict ref="predict" :proxy="proxy" @handleInitiateOrder="handleInitiateOrder">
<template v-slot="slotProps" v-if="data.showInitiateOrder">
<flow-initiate ref="form" v-show="slotProps.currActive === 'form'" :curr-flow-form="data.currFlowForm"
@handleInitiateOrder="handleInitiateOrder"></flow-initiate>
</template>
<template v-slot="slotProps" v-if="data.showHandleForm">
<custom-form ref="form" v-show="slotProps.currActive === 'form'" :curr-job="data.currFlowForm"
@onHandleForm="handleInitiateOrder"></custom-form>
</template>
</json-flow-predict>
<!-- 查看流程图 -->
<el-drawer
class="flow-overflow-drawer" direction="rtl"
append-to-body size="90%"
v-model="data.showFlowPic"
>
<flow-photo v-if="data.showFlowPic" :curr-job="data.currFlowForm"></flow-photo>
</el-drawer>
</div>
</div>
</template>
<script setup lang="ts" name="systemFlowApplication">
import * as flowApplication from "/@/api/order/flow-application";
import {useI18n} from "vue-i18n";
import other, {deepClone} from "/@/utils/other";
import {useFlowJob} from "/@/flow/stores/flowJob";
import {windowLocationHrefParam} from "/@/flow/support/extend";
import {handleCustomForm, vueKey} from "/@/api/order/order-key-vue";
// 引入组件
const FlowPhoto = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/view.vue'));
const FlowInitiate = defineAsyncComponent(() => import('./initiate.vue'));
const CustomForm = defineAsyncComponent(() => import('/@/flow/components/custom-form/handle.vue'));
const JsonFlowPredict = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/predict.vue'));
const {t} = useI18n()
const {proxy} = getCurrentInstance();
const data = reactive({
tableData: [],
tabsData: [],
showInitiateOrder: false,
showFlowPic: false,
currFlowForm: {},
showHandleForm: false,
collapse: [0]
})
// 列表查询
function getList() {
flowApplication.listByPerms({}).then(response => {
data.tableData = response.data
data.tabsData = data.tableData.filter((value, i, arr) =>
arr.findIndex(x => x.groupName === value.groupName) === i
);
})
}
function handleInitiateOrder(row, index) {
if (row === false) {
openPredict({}, false)
data.showInitiateOrder = false
data.showHandleForm = false
return
}
data.currFlowForm = deepClone(row)
// 判断是否自定义首页
if (row.path !== vueKey.RunApplicationForm) {
handleCustomForm(data, row)
data.currFlowForm.operType = 'add'
data.showHandleForm = true
} else {
data.showInitiateOrder = true
}
openPredict(row, true)
}
function openPredict(row, bool) {
proxy.$refs.predict.open(row, bool)
}
function handleClickHref(hash, param = '') {
windowLocationHrefParam(hash, param)
}
function openPreview(defFlowId) {
data.currFlowForm = {defFlowId: defFlowId}
data.showFlowPic = true
}
onMounted(() => {
getList()
})
</script>
<style lang="scss">
@import "../../../flow/components/style/flow-drawer.scss";
</style>
<style lang="scss" scoped>
.avue-view__avue-card {
width: 100%;
-webkit-box-sizing: border-box;
box-sizing: border-box;
.avue-card__item:hover {
border-color: #409EFF;
}
.avue-card__item {
margin-bottom: 12px;
border: 1px solid #e8e8e8;
border-radius: 8px;
background-color: #fff;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: rgba(0, 0, 0, .65);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
list-style: none;
-webkit-font-feature-settings: "tnum";
font-feature-settings: "tnum";
cursor: pointer;
.avue-card__body {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
.avue-card__avatar2 {
width: 48px;
height: 48px;
border-radius: 48px;
overflow: hidden;
margin-right: 12px;
margin-left: 12px;
}
.avue-card__detail {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
.avue-card__title {
color: rgba(0, 0, 0, .85);
margin-top: 6px;
margin-bottom: 6px;
font-size: 16px;
}
.avue-card__info {
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
height: 64px;
}
}
}
.avue-card__menu {
border-radius: 8px;
display: -ms-flexbox;
display: flex;
-ms-flex-pack: distribute;
justify-content: space-around;
height: 50px;
background: #f7f9fa;
text-align: center;
line-height: 50px;
}
}
}
.el_result_layout {
cursor: pointer;
.el-space_container {
width: 100%;
background: white;
border-radius: 8px;
}
.el-card__title__:hover {
background: #f4f4f5;
}
.el-card__title__ {
// 居中不能适应屏幕大小
// display: grid;
// place-items: center;
margin: 0;
font-size: 20px;
}
.el-result__style__:hover {
background: #f4f4f5;
}
.el-result__style__ {
border-radius: 8px;
background: white;
padding: 10px;
}
}
</style>

View File

@@ -0,0 +1,125 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<form-render ref="formCreateRef" :currFlowForm="data.currFlowForm" :initFormPermPrint="initFormPermPrint">
</form-render>
</div>
<footer class="el-dialog__footer" v-if="data.submitBtn">
<span class="dialog-footer">
<el-button type="primary" @click="submitForm" :disabled="loading">{{
t('jfI18n.submit')
}}
</el-button>
<el-button type="primary" @click="handleTempStore" :disabled="loading">{{
t('jfI18n.temp')
}}
</el-button>
</span>
</footer>
</div>
</template>
<script setup lang="ts" name="FlowApplicationInitiate">
import * as flowApplication from '/@/api/order/flow-application'
import {useI18n} from "vue-i18n";
import {validateNull} from "/@/utils/validate";
import {deepClone} from "/@/utils/other";
import {setPropsNull} from "/@/flow/support/common";
import {doInitData, doInitiateForm, doTempStore, initFormMethods, initJobDataByApp} from "../index";
import {handleFormStartPerm} from "/@/flow/utils/form-perm";
import {currFormIsView} from "/@/api/order/order-key-vue";
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
const formCreateRef = ref(null)
const {t} = useI18n();
const $emit = defineEmits(['handleInitiateOrder']);
const loading = ref(false);
const props = defineProps({
currFlowForm: {
type: Object,
default: {},
}
});
const data = reactive({
// 兼容app端监听currFlowForm
currFlowForm: {
type: Object,
default: {},
},
submitBtn: true
});
const $route = useRoute();
function initJobData() {
initJobDataByApp($route, handleGetObj, () => {
data.currFlowForm = props.currFlowForm
})
}
function handleGetObj(id) {
flowApplication.getObj(id).then(resp => {
let form = resp.data ? resp.data : {}
Object.assign(data.currFlowForm, form);
})
}
async function submitForm() {
await doInitiateForm(loading, props, data, $route, formCreateRef, $emit, saveInitData, t)
}
function handleTempStore() {
doTempStore(loading, data, $route, formCreateRef, $emit, saveInitData)
}
const methods = initFormMethods(formCreateRef, data)
async function initFormPermPrint(formInfo) {
// 处理表单权限
let res = await handleFormStartPerm(null, null, formInfo, data.currFlowForm.defFlowId, null, data.currFlowForm.type)
await currFormIsView(methods, res.elTab, true, res.callback, res.widgetList)
return res.elTab
}
function saveInitData(form) {
data.currFlowForm.formData = validateNull(form) ? undefined : form
let formJson = deepClone(data.currFlowForm)
formJson.formData = JSON.stringify(formJson.formData)
formJson.formId = formJson.id
setPropsNull(formJson, 'id', 'status')
return formJson;
}
async function getFormData() {
return await doInitData(formCreateRef, saveInitData)
}
// 暴露变量
defineExpose({
getFormData,
})
// 监听双向绑定
watch(
() => props.currFlowForm.id,
() => {
initJobData();
}
);
onMounted(() => {
initJobData()
});
</script>
<style lang="scss" scoped>
.el-dialog__footer {
text-align: center;
margin-top: 10px;
.dialog-footer {
text-align: center;
}
}
</style>