فهرست منبع

feat: #0000 流程模型 列表 100%

luoyali 1 سال پیش
والد
کامیت
40580d189b

+ 3 - 3
README.md

@@ -24,14 +24,14 @@
   - 扩展设置
 
 - 流程表单
-  - 列表
-  - 新增 编辑
+  - 列表
+  - 新增 编辑
   - 预览
   - 字段
   - 设计
 
 - 流程模型
-  - 列表
+  - 列表
   - 创建审批
   - 设计
   - 修改

+ 1 - 1
src/api/system/department.ts

@@ -3,7 +3,7 @@ import { AxiosPromise } from 'axios'
 
 // apiUrl 部门管理
 const api = {
-	page: '/sys/department/list-tree',
+	page: '/sys/department/form-tree',
 	create: '/sys/department/create',
 	update: '/sys/department/update',
 	delete: '/sys/department/delete'

+ 1 - 1
src/api/system/dict.ts

@@ -4,7 +4,7 @@ import { AxiosPromise } from 'axios'
 // apiUrl 字典管理
 const api = {
 	page: '/sys/dict/page',
-	listParent: '/sys/dict/list-parent',
+	listParent: '/sys/dict/form-parent',
 	create: '/sys/dict/create',
 	update: '/sys/dict/update',
 	delete: '/sys/dict/delete'

+ 1 - 1
src/api/system/region.ts

@@ -3,7 +3,7 @@ import { AxiosPromise } from 'axios'
 
 // apiUrl 行政区域
 const api = {
-	page: '/sys/region/list-tree',
+	page: '/sys/region/form-tree',
 	create: '/sys/region/create',
 	update: '/sys/region/update',
 	delete: '/sys/region/delete'

+ 2 - 2
src/api/system/resource.ts

@@ -4,8 +4,8 @@ import { AxiosPromise } from 'axios'
 // apiUrl 菜单管理
 const api = {
 	page: '/sys/resource/page',
-	listTree: '/sys/resource/list-tree',
-	listApi: '/sys/resource/list-api',
+	listTree: '/sys/resource/form-tree',
+	listApi: '/sys/resource/form-api',
 	create: '/sys/resource/create',
 	update: '/sys/resource/update',
 	delete: '/sys/resource/delete'

+ 2 - 2
src/api/system/role.ts

@@ -4,8 +4,8 @@ import { AxiosPromise } from 'axios'
 // apiUrl
 const api = {
 	page: '/sys/role/page',
-	listTree: '/sys/role/list-tree',
-	listAll: '/sys/role/list-all',
+	listTree: '/sys/role/form-tree',
+	listAll: '/sys/role/form-all',
 	create: '/sys/role/create',
 	update: '/sys/role/update',
 	delete: '/sys/role/delete',

+ 3 - 3
src/components/DraggableNest.vue

@@ -7,7 +7,7 @@ import Icon from '@/components/Icon'
 /*export type DraggableProps = {
 	level: number
 	value: any[]
-	list: any[]
+	form: any[]
 	options: any
 	setFixed: () => void
 	remove: (item, index, inputs) => void
@@ -25,7 +25,7 @@ const props = withDefaults(defineProps<DraggableProps>(), {
         fixed?: Boolean||String, // fixed 的不允许删除 disabled
         children?: Option[] // 同上配置
       }[] *!/
-	// list: undefined,
+	// form: undefined,
 	options: {},
 	setFixed: () => {},
 	remove: (item, index, inputs) => {
@@ -163,4 +163,4 @@ const DraggableNest = defineComponent({
 	}
 })
 export default DraggableNest
-</script>
+</script>

+ 2 - 2
src/components/Select/select-dropdown.tsx

@@ -2,7 +2,7 @@ import { computed, defineComponent, inject, ref, unref, watch } from 'vue'
 import { get } from 'lodash-unified'
 // import { isObject, isUndefined } from '@element-plus/utils'
 import { isObject, isUndefined } from 'element-plus/es/utils/index.mjs'
-// import { DynamicSizeList, FixedSizeList } from '@element-plus/components/virtual-list'
+// import { DynamicSizeList, FixedSizeList } from '@element-plus/components/virtual-form'
 import { DynamicSizeList, FixedSizeList } from 'element-plus/es/components/virtual-list/index.mjs'
 // import { useNamespace } from '@element-plus/hooks'
 import { useNamespace } from 'element-plus/es/hooks/index.mjs'
@@ -13,7 +13,7 @@ import OptionItem from './option-item.vue'
 
 import { selectV2InjectionKey } from './token'
 
-import type { ItemProps } from '@element-plus/components/virtual-list'
+import type { ItemProps } from '@element-plus/components/virtual-form'
 import type { Option, OptionItemProps } from './select.types'
 
 export default defineComponent({

+ 1 - 1
src/components/Table/index.vue

@@ -307,7 +307,7 @@ export default TableComponent
  */
 
 /* <TableComponent
-    :list="list" // 后台请求的列表数据
+    :form="form" // 后台请求的列表数据
     :total="total" // 该列表总共有多少数据
     :options="options" // table相关的 配置对象 // 配置参考 defaultOptions
     :columns="columns" // 需要展示的列配置 // 参考上面的 columns

+ 10 - 4
src/router/index.ts

@@ -158,10 +158,10 @@ export const constantRoutes: Array<AppRouteRecordRaw> = [
 				meta: { title: '流程组', icon: '' }
 			},
 			{
-				path: 'list',
-				component: () => import('@/views/flow/list/index.vue'),
-				name: 'list',
-				meta: { title: '流程表', icon: '' }
+				path: 'form',
+				component: () => import('@/views/flow/form/index.vue'),
+				name: 'form',
+				meta: { title: '流程表', icon: '' }
 			},
 			{
 				path: 'create',
@@ -180,6 +180,12 @@ export const constantRoutes: Array<AppRouteRecordRaw> = [
 				component: () => import('@/views/flow/instance/index.vue'),
 				name: 'instance',
 				meta: { title: '流程实例', icon: '' }
+			},
+			{
+				path: 'modal',
+				component: () => import('@/views/flow/modal/index.vue'),
+				name: 'modal',
+				meta: { title: '流程模型', icon: '' }
 			}
 		]
 	},

+ 3 - 3
src/views/components/components/SearchGroup2Popover.vue

@@ -168,8 +168,8 @@
 			</div>
 		</LePopover>-->
 		<div>-------分割--------</div>
-		<!--   模拟 查看更多下拉列表 类型 le-popover--list   -->
-		<!--      <LePopover trigger="click" :popperClass="`le-popover&#45;&#45;list ${'popperClass'}`" placement="right">
+		<!--   模拟 查看更多下拉列表 类型 le-popover--form   -->
+		<!--      <LePopover trigger="click" :popperClass="`le-popover&#45;&#45;form ${'popperClass'}`" placement="right">
 			<div class="labelWrap" style="width: 400px;background: #f00;" slot="reference">
 				可售:666(le-popover默认 click 触发le-popover-list展示)
 			</div>
@@ -193,7 +193,7 @@
 			</el-main>
 		</LePopover>-->
 		<div>-------分割--------</div>
-		<!--      <LePopover :first-load='true' trigger="click" :popperClass="`le-popover&#45;&#45;list ${'popperClass'}`" placement="right">
+		<!--      <LePopover :first-load='true' trigger="click" :popperClass="`le-popover&#45;&#45;form ${'popperClass'}`" placement="right">
 			<div class="labelWrap" style="width: 690px;background: #ff0;" slot="reference">
 				可售:666(le-popover默认 click 触发le-popover-list展示【slot default 内容未展示 就触发生命周期示例】)
 			</div>

+ 1 - 1
src/views/components/index.vue

@@ -84,7 +84,7 @@
     <div class="content">...</div>
     <div class="common_title">iconfont && LeIcon</div>
     <div class="content">
-      <el-card shadow="never" class="le-card-bg picking-list" header="Picking List">
+      <el-card shadow="never" class="le-card-bg picking-form" header="Picking List">
         <template slot="header">
           Picking List&#45;&#45;&#45;&#45;
           <el-button type="text">Clear</el-button>

+ 3 - 3
src/views/demo/pageConfig/index.vue

@@ -14,7 +14,7 @@
 			</template>
 		</LeSearchForm>
 		<!--  LeTable 组件使用 示例:  -->
-<!--		:list="tableOpts.list"
+<!--		:form="tableOpts.form"
 		:total="tableOpts.total"
 		:options="tableOpts.options"
 		:columns_="tableOpts.columns"
@@ -373,7 +373,7 @@ const queryList = () => {
 		.then((data: any) => {
 			const { total, data: list } = data
 			tableOpts.total = total
-			// list.push({})
+			// form.push({})
 			tableOpts.list = list
 		})
 		.finally(() => {
@@ -513,7 +513,7 @@ checkedColumns.value = columns.slice(0, 2)
 		roles: []
 	},
 	total: 0, // table数据总条数
-	list: [], // table数据
+	form: [], // table数据
 	// table 的参数
 	options: {
 		loading: false, // 是否添加表格loading加载动画

+ 275 - 0
src/views/flow/form/index.vue

@@ -0,0 +1,275 @@
+<template>
+	<div class="pageWrap">
+		<div class="content-warp flex-column-page-wrap">
+			<!-- 公用搜索组件 -->
+			<LeSearchForm ref="searchForm" v-model:searchData="searchData" :forms="forms" :loading="tableOpts.options.loading"> </LeSearchForm>
+
+			<!--  LeTable 组件使用  -->
+			<LeTable
+				ref="tableRef"
+				v-model:searchParams="tableOpts.searchParams"
+				v-bind="tableOpts"
+				v-model:curRow="tableOpts.curRow"
+				v-model:checked-options="checkedColumns"
+				:columns="activeColumns"
+			>
+				<template #toolLeft>
+					<el-button type="primary" @click="addHandler">
+						<el-icon class="btn-icon">
+							<Plus />
+						</el-icon>
+					</el-button>
+				</template>
+
+				<template #actionSlot="scope">
+					<el-link type="primary">编辑</el-link>
+					<el-divider direction="vertical"></el-divider>
+					<el-link type="primary">预览</el-link>
+					<el-divider direction="vertical"></el-divider>
+					<el-link type="primary">设计</el-link>
+					<el-divider direction="vertical"></el-divider>
+					<el-link type="primary">字段</el-link>
+				</template>
+			</LeTable>
+		</div>
+
+		<LeFormConfigDialog
+			v-if="visible"
+			ref="dialogUserRef"
+			v-model="visible"
+			:title="`${isCreate ? '新增' : '编辑'}应用`"
+			width="600px"
+			:form-data="activeData"
+			:form-options="formOptions"
+			@submit="submitHandler"
+		/>
+	</div>
+</template>
+<script lang="tsx" setup>
+import app from '@/api/system/app'
+import { computed, nextTick, ref, watch } from 'vue'
+import { ElMessage, ElTree } from 'element-plus'
+import { useTablePage } from '@/hooks/useTablePage'
+import { Plus, Edit } from '@element-plus/icons-vue'
+
+const visible = ref(false) // 弹窗显示隐藏
+const isCreate = ref(true)
+const activeData = ref({})
+const formsDialog = [
+	{
+		prop: 'identification',
+		label: '表单名称',
+		itemType: 'input',
+		rules: [{ required: true, message: '请输入表单名称', trigger: 'blur' }]
+	},
+	{
+		prop: 'name',
+		label: '表单编码',
+		itemType: 'input',
+		rules: [{ required: true, message: '请输入表单编码', trigger: 'blur' }]
+	},
+	{
+		prop: 'pid',
+		label: '分组',
+		itemType: 'select',
+		filterable: true,
+		options: [],
+		rules: [{ required: true, message: '请选择分组', trigger: 'blur' }]
+	},
+	{
+		prop: 'pid1',
+		label: '表单类型',
+		itemType: 'select',
+		filterable: true,
+		options: [],
+		rules: [{ required: true, message: '请选择表单类型', trigger: 'blur' }]
+	},
+]
+// 新增的表单 和 编辑的表单
+const formOptions = computed(() => {
+	return {
+		forms: formsDialog,
+		labelWidth: 120,
+		span: 30,
+		showResetBtn: true,
+		formConfig: {
+			submitLoading: false
+		}
+	}
+})
+const groupFilterText = ref('')
+const treeRef = ref<InstanceType<typeof ElTree>>()
+
+// 表格搜索条件
+const forms = ref([
+	{
+		prop: 'keyword',
+		label: '表单名称:',
+		itemType: 'input',
+		placeholder: '请输入表单名称'
+	}
+])
+
+// table列表数据请求
+const queryList = async () => {
+	const { options, searchParams } = tableOpts
+	options.loading = true
+	try {
+		const { records: list, total } = await app.appPageApi(searchParams)
+		tableOpts.total = total
+		tableOpts.list = list
+	} catch {
+		console.log('获取列表数据失败')
+		tableOpts.total = 0
+		tableOpts.list = []
+		options.loading = false // 更改加载中的 loading值
+	} finally {
+		options.loading = false
+	}
+}
+
+// table 参数
+const columns = [
+	{
+		prop: 'identification',
+		label: '表单名称',
+		minWidth: 80
+	},
+	{
+		prop: 'name',
+		label: '表单编码',
+		minWidth: 100
+	},
+	{
+		prop: 'secretKey',
+		label: '表单类型',
+		minWidth: 100
+	},
+	{
+		prop: 'sort',
+		label: '版本',
+		minWidth: 80
+	},
+	{
+		prop: 'action',
+		label: '操作',
+		width: 190,
+		fixed: 'right',
+		slots: {
+			default: 'actionSlot'
+		}
+	}
+]
+
+const { searchData, tableOpts, checkedColumns, activeColumns, curSelectionRows, updateParams } = useTablePage(
+	{
+		options: {
+			showIndex: false
+		},
+		// 需要展示的列
+		columns,
+		// 控制列配置
+		columnsConfig: {
+			columns
+		}
+	},
+	{
+		queryList,
+		fetchImmediate: false
+	}
+)
+
+// 删除
+const deleteItem = async ids => {
+	try {
+		await app.appDeleteApi(ids)
+		updateParams()
+	} catch (e) {
+		console.log('删除失败')
+		ElMessage.error(`删除失败~`)
+	}
+}
+
+// 单个删除
+const table_del = row => {
+	deleteItem([row.id])
+}
+
+//批量删除
+const batch_del = () => {
+	const ids = curSelectionRows.value.map(item => item.id) // 多选数据
+	deleteItem(ids)
+}
+
+const table_edit = async row => {
+	isCreate.value = false
+	activeData.value = { ...row, status: row.status ? true : false }
+	visible.value = true
+}
+
+// 弹窗事件
+const submitHandler = async params => {
+	formOptions.value.formConfig.submitLoading = true
+	try {
+		params.status = params.status ? 1 : 0
+		params.expire = params.expire + ' 00:00:00'
+		params.id = activeData.value.id ? activeData.value.id : null
+		await app.appAddOrEditSaveApi(params)
+		ElMessage.success(`${isCreate.value ? '新增' : '修改'}成功~`)
+		visible.value = false
+		updateParams()
+		formOptions.value.formConfig.submitLoading = false
+	} catch (e) {
+		console.log(e)
+		formOptions.value.formConfig.submitLoading = false
+	}
+}
+
+const addHandler = () => {
+	isCreate.value = true
+	activeData.value = {}
+	visible.value = true
+}
+
+nextTick(() => {
+	queryList()
+})
+
+watch(groupFilterText, val => {
+	treeRef.value!.filter(val)
+})
+</script>
+<style scoped lang="scss">
+.pageWrap {
+	flex: 1;
+	display: flex;
+	height: 100%;
+	//background: #fff;
+}
+.content-warp {
+	flex: 1;
+	//width: calc(100% - 250px);
+	width: calc(100% - 210px);
+}
+// 单独自己写的
+/*:deep(.box-card) {
+	height: 100%;
+	.el-card__body {
+		padding: 0;
+	}
+}*/
+
+// 应用的树结构样式
+:deep(.menu-tree) {
+	.el-tree-node__content {
+		height: 36px;
+	}
+	.el-tree-node__content .el-tree-node__label .icon {
+		margin-right: 5px;
+	}
+}
+
+.nopadding {
+	padding: 0px;
+}
+</style>

+ 0 - 11
src/views/flow/list/index.vue

@@ -1,11 +0,0 @@
-<template>
-	<h4>流程列表</h4>
-</template>
-
-<script>
-export default {
-	name: 'index'
-}
-</script>
-
-<style scoped></style>

+ 143 - 0
src/views/flow/modal/index.vue

@@ -0,0 +1,143 @@
+<template>
+	<div class="pageWrap">
+		<div style="padding: 10px">
+			<el-card class="box-card">
+				<el-row :gutter="20">
+					<el-col :span="6"><el-input v-model="input" placeholder="请输入名称和拼音" /> </el-col>
+					<el-col :span="6"> <el-button type="primary">创建审批</el-button></el-col>
+				</el-row>
+			</el-card>
+		</div>
+		<div style="padding: 10px">
+			<el-card class="box-card">
+				<el-collapse v-model="activeNames" @change="handleChange">
+					<el-collapse-item title="合同审批" name="1">
+						<el-row>
+							<el-col :span="6" v-for="i in 30" style="padding-left: 8px; padding-right: 8px; margin-bottom: 12px; cursor: pointer">
+								<div class="card-in">
+									<div class="flow-icon">
+										<img
+											src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAABwBAMAAAA0zul4AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAeUExURf///zKW+ur0/nO4+6XR/YvE/Eqi+5DG/Nnr/sPg/brnfYAAAAFMSURBVFjD7dfPSsNAEAbwNTGtuXVM09pbqCAeFV8gwYNXtU+wioI3FcFrLorH+OeBncYuSnYl+wUKEueDNmHhR8rO7myqqGOUQIECBQoUaDK5dsQD3ihXNtth6YTqtQ0mbqcGbXD8C4z6BYPFUSP3ftCawOVU+8ANezH5QXuVzDwnJ5g38nfruP/SSOYHh9bkjNdcjrDrAghOHhvJe7ettlab6RaFA9fDkTpOURivbi963OX+H/x4qLrA4IzHzjvA57pzVDCMsU7+nT0eKfiTofCQKF2SAxAGPLBdf4GQz63LXB1rHsVgRDtfD05BGLKofQJDOuXLHQyHdQm5mOhPjQ2coXXUXIiM6zFCYUGj3aTUlKMwpIQPOd9j7ufS0abDotsqMu+wcAd40nRV+sCp1W0ysxbW9GpNlRsWrTB9mzvyLn/KBAoUKFCgyScZMYmWkzKSDQAAAABJRU5ErkJggg=="
+											alt=""
+										/>
+									</div>
+									<div class="space space-vertical">
+										<div class="space-item">
+											<div class="first-edit">
+												<strong>合同审批 {{ i }} (1.2)</strong>
+												<el-dropdown>
+													<span class="el-dropdown-link">
+														配置
+														<el-icon class="el-icon--right">
+															<arrow-down />
+														</el-icon>
+													</span>
+													<template #dropdown>
+														<el-dropdown-menu>
+															<el-dropdown-item>设计</el-dropdown-item>
+															<el-dropdown-item>修改</el-dropdown-item>
+															<el-dropdown-item>复制</el-dropdown-item>
+															<el-dropdown-item>移动</el-dropdown-item>
+															<el-dropdown-item>停用</el-dropdown-item>
+														</el-dropdown-menu>
+													</template>
+												</el-dropdown>
+											</div>
+										</div>
+										<div class="space-item">
+											<div>2023-09-03 17:00:00</div>
+										</div>
+										<div class="space-item">
+											<div>钉钉</div>
+										</div>
+									</div>
+								</div>
+							</el-col>
+						</el-row>
+					</el-collapse-item>
+				</el-collapse>
+			</el-card>
+		</div>
+	</div>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+const input = ref('')
+const activeNames = ref(['1'])
+import { ArrowDown } from '@element-plus/icons-vue'
+const handleChange = val => {
+	console.log(val)
+}
+</script>
+
+<style scoped lang="scss">
+.pageWrap {
+	//height: 100%;
+	overflow-x: scroll;
+	//background: #fff;
+}
+.card-in {
+	height: 100px;
+	border-radius: 8px;
+	padding: 16px;
+	display: flex;
+	flex-direction: row;
+	width: 100%;
+	border: 1px solid #d9d9d9;
+	background: var(--component-background);
+	cursor: pointer;
+	> div:nth-child(1) {
+		vertical-align: middle;
+	}
+	> div:nth-child(2) {
+		flex: 0 1 100%;
+		margin-left: 12px;
+		text-overflow: ellipsis;
+		overflow: hidden;
+		.first-edit {
+			font-size: 14px;
+			display: flex;
+			flex-direction: row;
+			justify-content: space-between;
+			align-items: center;
+			cursor: pointer;
+		}
+		> div {
+			cursor: default;
+			width: 100%;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+			overflow: hidden;
+			font-size: 12px;
+		}
+	}
+	.flow-icon {
+		flex: 0 0 66px;
+
+		img {
+			flex: 0 0 auto;
+			height: 100%;
+			border-radius: 8px;
+			vertical-align: middle;
+			border-style: none;
+		}
+	}
+	.space {
+		display: inline-flex;
+	}
+	.space-vertical {
+		flex-direction: column;
+	}
+	&:hover {
+		border: 1px solid var(--el-color-primary);;
+		box-shadow: 0 0 4px #ddd;
+	}
+	.el-dropdown-link {
+		cursor: pointer;
+		color: var(--el-color-primary);
+		display: flex;
+		align-items: center;
+	}
+}
+</style>

+ 2 - 2
src/views/setting/department/index.vue

@@ -153,9 +153,9 @@ const queryList = async () => {
 		// tableOpts.total = total
 		tableOpts.list = list
 		formsDialog.value[0].options = list
-		// const test = replaceChildren(list)
+		// const test = replaceChildren(form)
 		// console.log(test);
-		// formsDialog.value[1].options = list
+		// formsDialog.value[1].options = form
 	} catch {
 		console.log('获取列表数据失败')
 		// tableOpts.total = 0

+ 2 - 2
src/views/setting/region/index.vue

@@ -140,9 +140,9 @@ const queryList = async () => {
 		// tableOpts.total = total
 		tableOpts.list = list
 		formsDialog.value[0].options = list
-		// const test = replaceChildren(list)
+		// const test = replaceChildren(form)
 		// console.log(test);
-		// formsDialog.value[1].options = list
+		// formsDialog.value[1].options = form
 	} catch {
 		console.log('获取列表数据失败')
 		// tableOpts.total = 0

+ 2 - 2
src/views/test/componentCommunication/components/Comp_Refs/index.vue

@@ -12,11 +12,11 @@
 <script setup>
 import { onMounted, ref } from 'vue'
 import ChildComponents from './child.vue'
-// const list = ref([])
+// const form = ref([])
 const childRef = ref(null)
 onMounted(() => {
 	console.error(childRef, 'childRef')
 	window.childRef = childRef
-	// list.value = childRef.list
+	// form.value = childRef.form
 })
 </script>

+ 1 - 1
src/views/test/testSetup.vue

@@ -103,7 +103,7 @@ const { loading, multiple, queryParams, brandList, total, dialog, formData, rule
 function handleQuery() {
 	state.loading = true
 	// listBrandPages(state.queryParams).then(({ data }) => {
-	//   state.brandList = data.list
+	//   state.brandList = data.form
 	//   state.total = data.total
 	//   state.loading = false
 	// })