Ver Fonte

Merge branch 'master' of gitee.com:xiaopubao/aizuda-web-vue3

xlsea há 1 ano atrás
pai
commit
1860ba748d

+ 111 - 0
src/components/EditPopover.vue

@@ -0,0 +1,111 @@
+<template>
+	<el-popover
+		v-bind="$attrs"
+		:trigger="$attrs.trigger || 'click'"
+		:width="$attrs.width || '240px'"
+		popper-class="le-edit-popper"
+		:visible="comp_visible"
+		@update:visible="visibleChange"
+	>
+		<template #reference>
+			<slot name="reference">
+				<el-button icon="Edit" />
+			</slot>
+		</template>
+		<div class="le-edit-popper_content-wrap">
+			<slot>
+				<div class="title">模拟标题</div>
+				<el-scrollbar max-height="400px">
+					<div class="content">
+						<div v-for="(_, i) of Array.from({ length: 40 })" :key="i">
+							我是内容 <br />
+							{{ i }}
+						</div>
+					</div>
+				</el-scrollbar>
+			</slot>
+			<div v-if="showFooter" class="footer">
+				<el-button @click="onCancel">{{ $t('le.btn.cancel') }}</el-button>
+				<el-button type="primary" style="margin-left: 8px" @click="onSubmit">{{ $t('le.btn.confirm') }}</el-button>
+			</div>
+		</div>
+	</el-popover>
+</template>
+<script setup name="LeEditPopover" lang="ts">
+defineOptions({ name: 'LeEditPopover' })
+import { computed, ref, watch } from 'vue'
+
+const emit = defineEmits(['update:visible', 'getCurRow'])
+const props = defineProps({
+	visible: {
+		type: Boolean,
+		default: null
+	},
+	showFooter: {
+		type: Boolean,
+		default: true
+	},
+	submit: {
+		type: Function,
+		default: () => console.warn('请添加 submit 进行确定')
+	},
+	cancel: {
+		type: Function
+	}
+})
+const localVisible = ref(false)
+const comp_visible = computed(() => {
+	if (typeof props.visible !== 'boolean') return localVisible.value
+	return props.visible
+})
+watch(
+	comp_visible,
+	(bool: boolean) => {
+		// 提示更新当前row数据
+		if (bool) {
+			emit('getCurRow')
+		}
+	},
+	{
+		immediate: true
+	}
+)
+const visibleChange = (visible: boolean) => {
+	emit('update:visible', visible)
+	localVisible.value = visible
+}
+const onCancel = () => {
+	if (props.cancel) props.cancel()
+	visibleChange(false)
+}
+const onSubmit = () => {
+	props.submit?.()
+	visibleChange(false)
+}
+</script>
+<style lang="scss">
+// le-edit-popper
+.#{$prefix}edit-popper {
+	&_content-wrap {
+		position: relative;
+		.title {
+			//border-bottom: 1px solid
+			//border-bottom: 1px solid var(--el-card-border-color);
+			border-bottom: 1px solid var(--el-border-color-light);
+			margin: -12px;
+			margin-bottom: 12px;
+			font-size: 15px;
+			padding: 10px 12px;
+			color: var(--el-text-color-primary);
+			font-weight: 500;
+			//margin-right: -12px;
+			//margin-left: - var(--el-popover-padding);
+			//margin-right: - var(--el-popover-padding);
+		}
+		.footer {
+			padding-top: 10px;
+			text-align: right;
+		}
+	}
+}
+</style>

+ 5 - 5
src/components/scWorkflow/nodes/branch.vue

@@ -8,13 +8,13 @@
 						<div class="condition-node-box">
 							<div class="auto-judge" @click="show(index)">
 								<div v-if="index != 0" class="sort-left" @click.stop="arrTransfer(index, -1)">
-									<el-icon><el-icon-arrow-left /></el-icon>
+									<el-icon><ArrowLeft /></el-icon>
 								</div>
 								<div class="title">
 									<span class="node-title">{{ item.nodeName }}</span>
 									<span class="priority-title">优先级{{ item.priorityLevel }}</span>
 									<el-icon class="close" @click.stop="delTerm(index)">
-										<el-icon-close />
+										<Close />
 									</el-icon>
 								</div>
 								<div class="content">
@@ -22,7 +22,7 @@
 									<span v-else class="placeholder"> 请设置条件 </span>
 								</div>
 								<div v-if="index != nodeConfig.conditionNodes.length - 1" class="sort-right" @click.stop="arrTransfer(index)">
-									<el-icon><el-icon-arrow-right /></el-icon>
+									<el-icon><ArrowRight /></el-icon>
 								</div>
 							</div>
 							<add-node v-model="item.childNode"></add-node>
@@ -43,7 +43,7 @@
 					<label v-if="!isEditTitle" @click="editTitle">
 						{{ form.nodeName }}
 						<div @click="rmConditionGroup(conditionGroup)">
-							<el-icon class="node-wrap-drawer__title-edit"><el-icon-edit /></el-icon>
+							<el-icon class="node-wrap-drawer__title-edit"><Edit /></el-icon>
 						</div>
 					</label>
 					<el-input v-if="isEditTitle" ref="nodeTitle" v-model="form.nodeName" clearable @blur="saveTitle" @keyup.enter="saveTitle"></el-input>
@@ -114,7 +114,7 @@
 
 <script>
 import addNode from './addNode.vue'
-import { Delete, Plus } from '@element-plus/icons-vue'
+import { Delete, Plus, ArrowLeft, Close, ArrowRight, Edit } from '@element-plus/icons-vue'
 
 export default {
 	components: {

+ 128 - 21
src/views/approve/components/approvedItem.vue

@@ -4,25 +4,72 @@
 		<!-- 搜索条件 -->
 		<div class="search-box">
 			<div class="search-segment" style="flex: 1 1 0%">
-				<el-input v-model="input3" placeholder="流程名称">
+				<el-input v-model="processName" placeholder="流程名称">
 					<template #append>
-						<el-button :icon="Search" />
+						<el-button icon="Search" @click="init" />
 					</template>
 				</el-input>
 			</div>
 			<div class="search-segment">
 				<el-tooltip effect="dark" content="重置" placement="top">
-					<el-button :icon="Refresh" />
+					<el-button icon="Refresh" @click="resetSearch('external')" />
 				</el-tooltip>
 			</div>
 			<div class="search-segment">
-				<el-button :icon="Filter" />
+				<EditPopover placement="right" :width="320" :showFooter="false" v-model:visible="searchMoreVisible">
+					<template #reference>
+						<el-button icon="Filter" />
+					</template>
+					<div class="title">高级筛选</div>
+					<el-scrollbar max-height="400px">
+						<!-- 发起人 -->
+						<el-select v-if="currentTaskType !== 'myApplication'" v-model="value" placeholder="发起人" style="margin-bottom: 10px; width: 240px">
+							<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+						</el-select>
+						<!-- 流程分组 -->
+						<el-select
+							v-if="currentTaskType !== 'pendingApproval'"
+							v-model="value1"
+							placeholder="流程分组"
+							style="margin-bottom: 10px; width: 240px"
+						>
+							<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+						</el-select>
+						<!-- 流程状态 -->
+						<el-select v-model="value2" placeholder="流程状态" style="margin-bottom: 10px; width: 240px">
+							<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+						</el-select>
+						<!-- 最小/大提交时间 -->
+						<el-date-picker
+							v-model="value3"
+							style="margin-bottom: 10px; width: 240px"
+							type="daterange"
+							start-placeholder="最小提交时间"
+							end-placeholder="最大提交时间"
+							:default-value="[new Date(2010, 9, 1), new Date(2010, 10, 1)]"
+						/>
+						<!-- 最小/大完成时间 -->
+						<el-date-picker
+							v-if="currentTaskType !== 'pendingApproval'"
+							v-model="value4"
+							style="width: 240px"
+							type="daterange"
+							start-placeholder="最小完成时间"
+							end-placeholder="最大完成时间"
+							:default-value="[new Date(2010, 9, 1), new Date(2010, 10, 1)]"
+						/>
+					</el-scrollbar>
+					<div class="footer">
+						<el-button plain @click="searchReset">重置</el-button>
+						<el-button type="primary" plain @click="searchSubmit">检索</el-button>
+					</div>
+				</EditPopover>
 			</div>
 		</div>
 		<!-- 内容值 -->
 		<div v-infinite-scroll="load" :infinite-scroll-disabled="disabledInfinite" class="flow-list-box">
 			<div
-				v-for="(i) in satelliteList"
+				v-for="i in satelliteList"
 				:key="i.instanceId"
 				class="item-box"
 				:class="[i.instanceId === taskProcessInfo.currentTaskRow.instanceId ? 'item-box-choosed' : '']"
@@ -34,14 +81,12 @@
 						<el-text tag="b">{{ i.processName }}</el-text>
 						<el-tag v-if="currentTaskType === 'pendingApproval'">待审批</el-tag>
 						<template v-else>
-							<el-tag>
-								<template v-if="i.instanceState === 0">审批中</template>
-								<template v-if="i.instanceState === 1">审批通过</template>
-								<template v-if="i.instanceState === 2">审批拒绝</template>
-								<template v-if="i.instanceState === 3">撤销审批</template>
-								<template v-if="i.instanceState === 4">超时结束</template>
-								<template v-if="i.instanceState === 5">强制终止</template>
-							</el-tag>
+							<el-tag v-if="i.instanceState === 0">审批中</el-tag>
+							<el-tag v-if="i.instanceState === 1" type="success">审批通过</el-tag>
+							<el-tag v-if="i.instanceState === 2" type="danger">审批拒绝</el-tag>
+							<el-tag v-if="i.instanceState === 3">撤销审批</el-tag>
+							<el-tag v-if="i.instanceState === 4" type="danger">超时结束</el-tag>
+							<el-tag v-if="i.instanceState === 5" type="danger">强制终止</el-tag>
 						</template>
 					</div>
 					<!--操作类容-->
@@ -50,7 +95,7 @@
 					<div class="footer">
 						<!-- 头像 -->
 						<div class="initiator">
-							<FlowNodeAvatar id="1" />
+							<FlowNodeAvatar :name="'等待后台补充用户'" />
 						</div>
 						<!-- 时间 -->
 						<div class="begin-time">提交于 {{ i.createTime }}</div>
@@ -66,7 +111,8 @@
 <script setup>
 import useTaskProcessStore from '@/store/modules/taskProcess'
 import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
-import { Search, Filter, Refresh } from '@element-plus/icons-vue'
+// import { Search, Filter, Refresh } from '@element-plus/icons-vue'
+import EditPopover from '@/components/EditPopover.vue'
 import { computed, onMounted, reactive, ref, watch } from 'vue'
 import {
 	processTaskPagePendingApprovalApi,
@@ -90,9 +136,52 @@ const props = defineProps({
 	}
 })
 
+/***
+ * 待审批:发起人 流程分组 最小提交时间 最大提交时间
+ * 我的申请:流程分组 流程状态 最小提交时间 最大提交时间 最小完成时间 最大完成时间
+ * 我收到的:发起人 流程分组 流程状态 最小提交时间 最大提交时间 最小完成时间 最大完成时间
+ * 已审批:发起人 流程分组 流程状态 最小提交时间 最大提交时间 最小完成时间 最大完成时间
+ */
+const options = [
+	{
+		value: 'Option1',
+		label: 'Option1'
+	},
+	{
+		value: 'Option2',
+		label: 'Option2'
+	},
+	{
+		value: 'Option3',
+		label: 'Option3'
+	},
+	{
+		value: 'Option4',
+		label: 'Option4'
+	},
+	{
+		value: 'Option5',
+		label: 'Option5'
+	}
+]
+const value = ref(null)
+const value1 = ref(null)
+const value2 = ref(null)
+const value3 = ref(null)
+const value4 = ref(null)
+const searchMoreVisible = ref(false)
+const searchReset = () => {
+	console.error('searchReset')
+	searchMoreVisible.value = false
+}
+const searchSubmit = () => {
+	console.error('searchSubmit')
+	searchMoreVisible.value = false
+}
+
 // store值
 const taskProcessInfo = useTaskProcessStore()
-const input3 = ref('')
+const processName = ref('') // 流程名称
 // 下拉滚动属性值 start
 const loading = ref(false) // loading
 const totalNumber = ref(0) // 总条数
@@ -128,16 +217,22 @@ const getPagedSatellites = async () => {
 	try {
 		let responseData = {}
 		const { currentTaskType } = props
+		const params = {
+			...condition,
+			data: {
+				processName: processName.value
+			}
+		}
 		if (currentTaskType === 'pendingApproval') {
-			responseData = await processTaskPagePendingApprovalApi(condition)
+			responseData = await processTaskPagePendingApprovalApi(params)
 		} else if (currentTaskType === 'myApplication') {
-			responseData = await processTaskPageMyApplicationApi(condition)
+			responseData = await processTaskPageMyApplicationApi(params)
 		} else if (currentTaskType === 'myReceived') {
-			responseData = await processTaskPageMyReceivedApi(condition)
+			responseData = await processTaskPageMyReceivedApi(params)
 		} else if (currentTaskType === 'pendingClaim') {
-			responseData = await processTaskPagePendingClaimApi(condition)
+			responseData = await processTaskPagePendingClaimApi(params)
 		} else if (currentTaskType === 'approved') {
-			responseData = await processTaskPageApprovedApi(condition)
+			responseData = await processTaskPageApprovedApi(params)
 		}
 		const { records, total, pages } = responseData
 		records.forEach(item => {
@@ -161,6 +256,18 @@ const getTaskDetail = item => {
 	taskProcessInfo.setCurrentTaskRow(item)
 }
 
+/**
+ * 重置搜索
+ * @param type external:重置输入框
+ * clear: 重置内部的值
+ */
+const resetSearch = type => {
+	if (type === 'external') {
+		processName.value = ''
+		init()
+	}
+}
+
 onMounted(() => {
 	taskProcessInfo.setCurrentTaskRow({})
 })

+ 20 - 49
src/views/approve/launch/ItemDrawer.vue

@@ -1,6 +1,7 @@
 <template>
-	<el-drawer class="local-launch_drawer-wrap" :title="record.processName" :model-value="modelValue" size="760px" @update:model-value="updateModelValue">
-		<!--    <div v-loading="loading" class="local_loading" element-loading-text="加载中..." element-loading-background="rgba(0, 0, 0, 0.1)" />-->
+	<el-drawer
+		:close-on-click-modal="false"
+		class="local-launch_drawer-wrap" :title="record.processName" :model-value="modelValue" size="760px" @update:model-value="updateModelValue">
 		<div class="info-wrap">
 			<el-divider content-position="left">{{ record.processName }}表单</el-divider>
 			<FormCreate class="form-wrap" :option="formOption" :rule="formRule" />
@@ -14,16 +15,19 @@
 					</template>
 					<template v-else>
 						<div style="padding-bottom: 6px">{{ v.name }}</div>
-						<!-- {{ v.local_name }} -->
 						<div v-if="v.type !== 0" style="display: flex; align-items: center; gap: 6px">
 							<el-button :icon="Plus" style="width: 32px" @click="selectHandler(v.name)" />
-							<FlowNodeAvatar v-for="(item, index) in userMap.get(v.name)" :key="index" :name="item.name" style="margin-top: 5px" />
+							<FlowNodeAvatar v-for="(item, index) in userMap.get(v.name).assignees" :key="index" :name="item.name" style="margin-top: 5px" />
 						</div>
 					</template>
 				</el-timeline-item>
 			</el-timeline>
 			<el-divider></el-divider>
 		</div>
+
+		<template #footer>
+		123
+		</template>
 	</el-drawer>
 	<use-select ref="useSelectRef"></use-select>
 </template>
@@ -35,15 +39,11 @@ import { ElMessage } from 'element-plus'
 import { Plus } from '@element-plus/icons-vue'
 import UseSelect from '@/components/scWorkflow/select.vue'
 import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
-import user from '@/api/system/user'
 type Props = {
 	modelValue: boolean
 	record: { processId: string; processName: string; [key: string]: any }
 }
 const props = defineProps<Props>()
-/*const props = withDefaults(defineProps<Props>(), {
-	modelValue: false
-})*/
 const emit = defineEmits<{
 	'update:modelValue': [bool: boolean] // 具名元组语法
 	update: [value: string]
@@ -53,13 +53,12 @@ const userMap = ref(new Map())
 const useSelectRef = ref()
 const selectHandler = (name: string) => {
 	if (!userMap.value.get(name)) {
-		userMap.value.set(name, [])
+		userMap.value.set(name, { assignees: [], type: 1 })
 	}
-	useSelectRef.value.open(1, userMap.value.get(name))
+	useSelectRef.value.open(1, userMap.value.get(name).assignees)
 }
 const FormCreate = viewForm.$form()
 const formOption = ref({
-	// resetBtn: { show: true },
 	onSubmit(formData) {
 		// console.error(formData, 'formData')
 		const processId = props.record.processId
@@ -69,18 +68,11 @@ const formOption = ref({
 			// 填写的数据存储(local_: 本地数据处理标识)
 			v.local_value = formData[v.field]
 		})
-		const assigneeMap = {}
-		userMap.value.forEach((v, k) => {
-			assigneeMap[k] = {
-				assigneeList: v,
-				type: 1
-			}
-		})
 		model
 			.processLaunchApi({
 				processId, // 流程ID
 				processForm: JSON.stringify(processForm), // 流程表单JSON内容 & local_value 保存
-				assigneeMap: assigneeMap // 流程节点审批人
+				assigneeMap: userMap.value // 流程节点审批人
 			})
 			.then(res => {
 				ElMessage.success('提交成功')
@@ -91,25 +83,8 @@ const formOption = ref({
 			})
 	},
 	submitBtn: { loading: false }
-	/*formData: {
-		local_workflow: {},
-		test_3: 'eeeee'
-	}*/
 })
-/*const formData = ref({
-	local_workflow: {}
-})*/
-/*const workflowItem = computed(() => {
-  return {
-    type:'ScWorkflow',
-    field: 'local_workflow'
-  }
-})*/
-/*const workflowItem = {
-	type: 'ScWorkflow',
-	field: 'local_workflow'
-}
-const formRule = shallowRef([workflowItem])*/
+
 // 当前form 表单数据字符串
 let cur_processForm_str = '[]'
 const formRule = shallowRef([])
@@ -123,11 +98,15 @@ const packageProcess = (data, list = []) => {
 	return data.reduce((_list, config) => {
 		if (config.conditionNode === 0) {
 			// console.log(config.name, 'name 普通节点名称', config)
-			if (!config.local_name) {
-				// 普通节点 展示 控制
-				config.local_name = (config.nodeAssigneeList || []).map(x => x.name).join(',') || config.name
+			// 默认用户
+			let type = 1
+			let assignees = config.nodeUserList
+			if (config.nodeRoleList) {
+				// 存在设置角色
+				type = 2
+				assignees = config.nodeRoleList
 			}
-			userMap.value.set(config.name, config.nodeAssigneeList)
+			userMap.value.set(config.name, { assignees: assignees, type: type })
 			_list.push(config)
 		} else if (config.conditionNode === 1) {
 			// 自定义标识key
@@ -164,26 +143,18 @@ const processTimelineList = computed(() => {
 })
 
 model.processListNodeMapApi(props.record.processId).then(res => {
-	// model.processListNodeMapApi('1747258191679991809').then((res: any[]) => {
 	localProcessData.value = res
-	// console.error(localProcessData, 'res..... processListNodeMapApi')
 })
 model.processDetailApi(props.record.processId).then(res => {
-	// model.processDetailApi('1747258191679991809').then(res => {
-	// console.error(res, '详情 process....', props.record)
-	// modelContent 审批流数据
 	let local_workflow = {}
 	try {
 		console.log(JSON.parse(res.modelContent))
 		const modelContent = JSON.parse(res.modelContent)
 		local_workflow = modelContent.nodeConfig ?? modelContent.childNode
 	} catch (e) {}
-	// formOption.value.formData = { local_workflow, test_3: 'eeeee' }
 	cur_processForm_str = res.processForm || '[]'
 	// processForm 动态表单
 	formRule.value = [...JSON.parse(cur_processForm_str) /*, { ...workflowItem, value: local_workflow }*/ /*, { type: 'input', field: 'test_3' }*/]
-	// loading.value = false
-	// console.error(formData.value, 'formData.value')
 })
 </script>
 <style lang="scss">

+ 1 - 1
src/views/flow/create/components/BasicInfo.vue

@@ -152,7 +152,7 @@ defineExpose({
 					</el-popover>
 				</el-form-item>
 				<el-form-item label="唯一标识 key" prop="flowInfo.processKey">
-					<el-input v-model="flowInfo.processKey" clearable maxlength="15"></el-input>
+					<el-input v-model="flowInfo.processKey" clearable maxlength="100"></el-input>
 				</el-form-item>
 				<el-form-item label="名称" prop="flowInfo.processName">
 					<el-input v-model="flowInfo.processName" clearable maxlength="15"></el-input>

+ 25 - 0
src/views/setting/department/index.vue

@@ -68,6 +68,7 @@ import { ElMessage, ElTree } from 'element-plus'
 import { useTablePage } from '@/hooks/useTablePage'
 import { Plus, Delete } from '@element-plus/icons-vue'
 import StatusIndicator from '@/components/StatusIndicator'
+import user from '@/api/system/user'
 
 const visible = ref(false) // 弹窗显示隐藏
 const isCreate = ref(true)
@@ -116,6 +117,13 @@ const formsDialog = ref([
 		label: '备注',
 		itemType: 'input',
 		rules: [{ required: true, message: '请输入备注', trigger: 'blur' }]
+	},
+	{
+		prop: 'headId',
+		label: '主管',
+		itemType: 'select',
+		filterable: true,
+		options: []
 	}
 ])
 // 新增的表单 和 编辑的表单
@@ -297,6 +305,7 @@ const submitHandler = async params => {
 	try {
 		params.status = params.status ? 1 : 0
 		params.id = activeData.value.id ? activeData.value.id : null
+		params.headName = formOptions.value.forms[6].options.find(item => item.value === params.headId).label
 		await department.departmentAddOrEditSaveApi(params)
 		ElMessage.success(`${isCreate.value ? '新增' : '修改'}成功~`)
 		visible.value = false
@@ -308,6 +317,21 @@ const submitHandler = async params => {
 	}
 }
 
+// 获取全部的人员信息
+const getUserList = async () => {
+	try {
+		var { records } = await user.userPageApi({
+			page: 1,
+			pageSize: 9999
+		})
+		formOptions.value.forms[6].options = records.map(item => {
+			return { value: item.id, label: item.realName }
+		})
+	} catch (e) {
+		console.log(e)
+	}
+}
+
 const addHandler = () => {
 	isCreate.value = true
 	activeData.value = {}
@@ -315,6 +339,7 @@ const addHandler = () => {
 }
 nextTick(() => {
 	queryList()
+	getUserList()
 })
 
 watch(groupFilterText, val => {

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

@@ -180,7 +180,7 @@ const formsDialog = [
 		options: []
 	},
 	{
-		prop: 'departments',
+		prop: 'departmentIds',
 		label: '所属部门',
 		itemType: 'select',
 		multiple: true,
@@ -409,7 +409,7 @@ const table_edit = async row => {
 	try {
 		const data = await user.userRoleIdsApi({ id: row.id })
 		isCreate.value = false
-		activeData.value = { ...row, status: row.status ? true : false, roleIds: data?.roleIds }
+		activeData.value = { ...row, status: row.status ? true : false, roleIds: data?.roleIds, departmentIds: data?.departmentIds }
 		visible.value = true
 	} catch (e) {
 		ElMessage.error(`获取用户所属角色失败~`)