mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-12-24 08:12:55 +08:00
优化审批流
This commit is contained in:
@@ -6,9 +6,9 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"dev:prod": "vite --mode prod",
|
||||
"prod": "vite build",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port 4173",
|
||||
"build": "node ./scripts/build.mjs",
|
||||
"build:all": "node ./scripts/build.mjs",
|
||||
"type-check": "vue-tsc --noEmit --checkJs true --skipLibCheck",
|
||||
"lint": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts src --fix --ignore-path .gitignore",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -19,17 +19,17 @@
|
||||
"@form-create/designer": "^3.3.1",
|
||||
"@form-create/element-ui": "^3.2.33",
|
||||
"@highlightjs/vue-plugin": "^2.1.0",
|
||||
"@logicflow/core": "^2.1.2",
|
||||
"@logicflow/extension": "^2.1.3",
|
||||
"@logicflow/core": "^2.2.0",
|
||||
"@logicflow/extension": "^2.2.0",
|
||||
"@vueuse/core": "^13.5.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"axios": "^1.11.0",
|
||||
"axios": "^1.13.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"css-color-function": "^1.3.3",
|
||||
"dayjs": "^1.11.18",
|
||||
"dayjs": "^1.11.19",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.11.1",
|
||||
"element-plus": "^2.12.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nprogress": "^0.2.0",
|
||||
@@ -37,8 +37,7 @@
|
||||
"query-string": "^9.2.2",
|
||||
"rolldown-vite": "^7.2.7",
|
||||
"spark-md5": "^3.0.2",
|
||||
"vform3-builds": "^3.0.10",
|
||||
"vue": "^3.5.21",
|
||||
"vue": "^3.5.25",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-echarts": "^7.0.3",
|
||||
"vue-router": "^4.5.1",
|
||||
@@ -52,12 +51,12 @@
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^22.14.1",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@vitejs/plugin-vue": "^6.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
||||
"@vitejs/plugin-vue": "^6.0.2",
|
||||
"@vitejs/plugin-vue-jsx": "^5.1.2",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^13.0.0",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"autoprefixer": "^10.4.22",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"execa": "^9.5.2",
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<div class="page__content" v-if="mockData">
|
||||
<div class="page__content" v-if="dialogVisible">
|
||||
<BasicSetting
|
||||
ref="basicSetting"
|
||||
:conf="mockData.basicSetting"
|
||||
@@ -60,12 +60,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, useTemplateRef, watch } from 'vue'
|
||||
import { ref, useTemplateRef, watch, defineAsyncComponent } from 'vue'
|
||||
// import XForm from './XForm/index.vue'
|
||||
// import XForm2 from './XForm2/index.vue'
|
||||
const XForm2 = () => import('./XForm2/index.vue')
|
||||
const XForm2 = defineAsyncComponent(() => import('./XForm2/index.vue'))
|
||||
// import FlowEdit from './flowEdit/index.vue'
|
||||
const FlowEdit = () => import('./flowEdit/index.vue')
|
||||
const FlowEdit = defineAsyncComponent(() => import('./flowEdit/index.vue'))
|
||||
import BasicSetting from './BasicSetting/index.vue'
|
||||
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
@@ -17,18 +17,26 @@ function setData(json: any[]) {
|
||||
// 使用 setRule和 setOptions方法回显数据。
|
||||
}
|
||||
function getFieldWidgets() {
|
||||
// const fieldList = designerRef.value.getFieldWidgets()
|
||||
// console.log('getFieldWidgets', fieldList)
|
||||
// return fieldList
|
||||
|
||||
const description = designerRef.value.getDescription()
|
||||
console.log('description', description)
|
||||
const fieldList: { id: string; name: string }[] = []
|
||||
description.forEach((item) => {
|
||||
fieldList.push({
|
||||
id: item.field,
|
||||
name: item.title
|
||||
function deepChild(item: any) {
|
||||
if (item.children) {
|
||||
item.children.forEach((child: any) => {
|
||||
deepChild(child)
|
||||
})
|
||||
} else {
|
||||
fieldList.push({
|
||||
id: item.field,
|
||||
name: item.title
|
||||
})
|
||||
}
|
||||
}
|
||||
description &&
|
||||
description.forEach((item) => {
|
||||
deepChild(item)
|
||||
})
|
||||
})
|
||||
|
||||
console.log('getFieldWidgets', fieldList)
|
||||
return fieldList
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, useTemplateRef } from 'vue'
|
||||
import { ref, onMounted, onBeforeUnmount, useTemplateRef } from 'vue'
|
||||
import { LogicFlow } from '@logicflow/core'
|
||||
|
||||
import { SelectionSelect, Menu, BpmnElement, MiniMap } from '@logicflow/extension'
|
||||
@@ -56,7 +56,14 @@ const PropertyPanelRef = useTemplateRef<InstanceType<typeof PropertyPanel>>('Pro
|
||||
onMounted(() => {
|
||||
initLogicFlow(props.conf)
|
||||
})
|
||||
|
||||
// Lifecycle hook to clean up LogicFlow when the component is unmounted
|
||||
onBeforeUnmount(() => {
|
||||
if (lf.value) {
|
||||
console.log('卸载LogicFlow')
|
||||
lf.value.destroy()
|
||||
lf.value = null
|
||||
}
|
||||
})
|
||||
// Function to initialize LogicFlow
|
||||
function initLogicFlow(data) {
|
||||
const logicFlowInstance = new LogicFlow({
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:fullscreen="false"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:destroy-on-close="true"
|
||||
:title="applyDetail.flowName"
|
||||
>
|
||||
<v-form-render
|
||||
:form-json="formJson"
|
||||
:form-data="formData"
|
||||
:option-data="optionData"
|
||||
ref="vFormRef"
|
||||
>
|
||||
</v-form-render>
|
||||
|
||||
<el-table size="large" :data="historyList" v-if="historyList.length">
|
||||
<el-table-column label="审批人" prop="approverNickname" />
|
||||
<el-table-column label="节点" prop="nodeLabel" />
|
||||
<el-table-column label="状态" prop="passStatus" />
|
||||
<el-table-column label="备注" prop="passRemark" />
|
||||
</el-table>
|
||||
|
||||
<!-- {{ historyList }} -->
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">关闭</el-button>
|
||||
<el-button
|
||||
v-if="applyDetail.status == 1 || applyDetail.status == 4"
|
||||
type="primary"
|
||||
@click="onSubmit"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import 'vform3-builds/dist/designer.style.css' //引入VForm3样式
|
||||
|
||||
import { flow_history_list_all } from '@/api/flow/flow_history'
|
||||
|
||||
const formJson = ref({})
|
||||
const formData = ref({})
|
||||
const optionData = reactive({})
|
||||
const vFormRef = ref(null)
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const applyDetail = ref({
|
||||
id: null,
|
||||
status: null,
|
||||
flowName: ''
|
||||
})
|
||||
|
||||
const historyList = ref([])
|
||||
|
||||
const props = defineProps({
|
||||
save: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
function open(row, form_json, form_data) {
|
||||
applyDetail.value = row
|
||||
getHistoryList(row.id)
|
||||
formData.value = form_data
|
||||
formJson.value = form_json
|
||||
console.log('open')
|
||||
dialogVisible.value = true
|
||||
}
|
||||
async function getHistoryList(applyId) {
|
||||
try {
|
||||
historyList.value = await flow_history_list_all({
|
||||
applyId: applyId
|
||||
})
|
||||
} catch (error) {
|
||||
historyList.value = []
|
||||
}
|
||||
}
|
||||
function closeFn() {
|
||||
dialogVisible.value = false
|
||||
applyDetail.value = {
|
||||
id: null,
|
||||
status: null,
|
||||
flowName: ''
|
||||
}
|
||||
formData.value = {}
|
||||
formJson.value = {}
|
||||
historyList.value = []
|
||||
}
|
||||
function onSubmit() {
|
||||
vFormRef.value.getFormData().then((formData) => {
|
||||
console.log('formData', formData)
|
||||
props
|
||||
.save(applyDetail.value?.id, formData)
|
||||
.then(() => {
|
||||
closeFn()
|
||||
})
|
||||
.catch(() => {})
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
// body {
|
||||
// margin: 0; /* 如果页面出现垂直滚动条,则加入此行CSS以消除之 */
|
||||
// }
|
||||
.el-range-editor.el-input__wrapper {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -1,114 +0,0 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:fullscreen="false"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:destroy-on-close="true"
|
||||
draggable
|
||||
:title="applyDetail.flowName"
|
||||
>
|
||||
<v-form-render
|
||||
:form-json="formJson"
|
||||
:form-data="formData"
|
||||
:option-data="optionData"
|
||||
ref="vFormRef"
|
||||
>
|
||||
</v-form-render>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">关闭</el-button>
|
||||
<el-button v-if="historyDetail.passStatus == 1" type="warning" @click="onBack">
|
||||
驳回
|
||||
</el-button>
|
||||
<el-button v-if="historyDetail.passStatus == 1" type="primary" @click="onSubmit">
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import 'vform3-builds/dist/designer.style.css' //引入VForm3样式
|
||||
|
||||
// import { flow_apply_detail } from '@/api/flow/flow_apply'
|
||||
|
||||
const formJson = ref({})
|
||||
const formData = ref({})
|
||||
const optionData = reactive({})
|
||||
const vFormRef = ref(null)
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const applyDetail = ref({
|
||||
flowName: ''
|
||||
})
|
||||
const historyDetail = ref({
|
||||
id: null,
|
||||
passStatus: null
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
save: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['back'])
|
||||
|
||||
function open(row, history, form_json, form_data) {
|
||||
applyDetail.value = row
|
||||
historyDetail.value = history
|
||||
formData.value = form_data
|
||||
formJson.value = form_json
|
||||
console.log('open')
|
||||
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function disableWidgets(widgetNames) {
|
||||
vFormRef.value.disableWidgets(widgetNames)
|
||||
}
|
||||
function hideWidgets(widgetNames) {
|
||||
vFormRef.value.hideWidgets(widgetNames)
|
||||
}
|
||||
function closeFn() {
|
||||
dialogVisible.value = false
|
||||
applyDetail.value = { flowName: '' }
|
||||
formData.value = {}
|
||||
formJson.value = {}
|
||||
historyDetail.value = {
|
||||
id: null,
|
||||
passStatus: null
|
||||
}
|
||||
}
|
||||
function onBack() {
|
||||
emit('back', historyDetail.value)
|
||||
}
|
||||
function onSubmit() {
|
||||
vFormRef.value.getFormData().then((formData) => {
|
||||
console.log('formData', formData)
|
||||
props
|
||||
.save(historyDetail.value?.id, formData)
|
||||
.then(() => {
|
||||
closeFn()
|
||||
})
|
||||
.catch(() => {})
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
disableWidgets,
|
||||
hideWidgets,
|
||||
closeFn
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
// body {
|
||||
// margin: 0; /* 如果页面出现垂直滚动条,则加入此行CSS以消除之 */
|
||||
// }
|
||||
.el-range-editor.el-input__wrapper {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -106,12 +106,12 @@ const { dictData } = useDictData<{
|
||||
// const handleOpen = async (row) => {
|
||||
// ApproveRef.value?.open(toRaw(row))
|
||||
// }
|
||||
const OpenViewForm = async (row: any) => {
|
||||
const applyDetail = await flow_apply_detail({ id: row.applyId })
|
||||
const OpenViewForm = async (history_row: type_flow_history) => {
|
||||
const applyDetail = await flow_apply_detail({ id: history_row.applyId })
|
||||
|
||||
let form_data = {}
|
||||
try {
|
||||
form_data = JSON.parse(row.formValue)
|
||||
form_data = JSON.parse(history_row.formValue)
|
||||
} catch (error) {
|
||||
// 解析失败
|
||||
}
|
||||
@@ -124,7 +124,7 @@ const OpenViewForm = async (row: any) => {
|
||||
|
||||
console.log(applyDetail, form_data, form_json)
|
||||
|
||||
viewFormRef.value?.open(applyDetail, row, form_json, form_data)
|
||||
viewFormRef.value?.open(applyDetail, history_row, form_json, form_data)
|
||||
}
|
||||
const SaveViewForm = (historyId, form_data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, shallowRef, reactive } from 'vue'
|
||||
import { ref, shallowRef, reactive, defineAsyncComponent } from 'vue'
|
||||
import {
|
||||
flow_template_delete,
|
||||
flow_template_lists,
|
||||
@@ -102,7 +102,7 @@ import { useDictData } from '@/hooks/useDictOptions'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
import EditPopup from './edit.vue'
|
||||
const Approver = () => import('@/components/flow/Approver.vue')
|
||||
const Approver = defineAsyncComponent(() => import('@/components/flow/Approver.vue'))
|
||||
|
||||
defineOptions({
|
||||
name: 'flow_template'
|
||||
|
||||
@@ -45,9 +45,9 @@ func swaggerJson(api *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// @Summary ws通用接口
|
||||
// @schemes ws
|
||||
// @schemes ws
|
||||
// @Tags 公共接口
|
||||
// @Success 101 {string} string "协议切换成功"
|
||||
// @Success 101 {string} string "ws连接成功"
|
||||
// @Router /api/ws [get]
|
||||
func wsHandler(api *gin.RouterGroup) {
|
||||
api.GET("/ws", middleware.LoginAuth(), controller.WsHandler)
|
||||
|
||||
Reference in New Issue
Block a user