feat:优化 bpm 相关代码,重点处理 back 逻辑,search 表单
This commit is contained in:
@@ -1,54 +1,55 @@
|
||||
<template>
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.processInstanceName }}
|
||||
</view>
|
||||
<wd-tag type="primary" plain>
|
||||
查看详情
|
||||
</wd-tag>
|
||||
</view>
|
||||
<view v-if="item.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ item.startUser.nickname?.[0] || '?' }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ item.startUser.nickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time">{{ formatDateTime(item.createTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无抄送任务" />
|
||||
</view>
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<view>
|
||||
<!-- 搜索组件 -->
|
||||
<CopySearchForm
|
||||
v-model="searchPopupVisible"
|
||||
:search-params="queryParams"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.processInstanceName }}
|
||||
</view>
|
||||
<wd-tag type="primary" plain>
|
||||
查看详情
|
||||
</wd-tag>
|
||||
</view>
|
||||
<view v-if="item.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ item.startUser.nickname?.[0] || '?' }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ item.startUser.nickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time">{{ formatDateTime(item.createTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无抄送任务" />
|
||||
</view>
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -64,17 +65,13 @@ import CopySearchForm from './copy-search-form.vue'
|
||||
import './index.scss'
|
||||
|
||||
const props = defineProps<{
|
||||
searchVisible?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:searchVisible': [value: boolean]
|
||||
active?: boolean
|
||||
}>()
|
||||
|
||||
const total = ref(0)
|
||||
const list = ref<ProcessInstanceCopy[]>([])
|
||||
const loadMoreState = ref<LoadMoreState>('loading')
|
||||
const searchPopupVisible = ref(false)
|
||||
const isFirstLoad = ref(true)
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
@@ -133,16 +130,18 @@ onReachBottom(() => {
|
||||
loadMore()
|
||||
})
|
||||
|
||||
watch(() => props.searchVisible, (val) => {
|
||||
searchPopupVisible.value = val ?? false
|
||||
})
|
||||
|
||||
watch(searchPopupVisible, (val) => {
|
||||
emit('update:searchVisible', val)
|
||||
/** 监听激活状态,刷新数据 */
|
||||
watch(() => props.active, (val) => {
|
||||
if (val && !isFirstLoad.value) {
|
||||
queryParams.pageNo = 1
|
||||
list.value = []
|
||||
getList()
|
||||
}
|
||||
})
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(() => {
|
||||
getList()
|
||||
isFirstLoad.value = false
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
<template>
|
||||
<!-- 搜索框入口 -->
|
||||
<wd-search
|
||||
:placeholder="searchPlaceholder"
|
||||
:hide-cancel="true"
|
||||
disabled
|
||||
@click="visible = true"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<wd-popup
|
||||
v-model="visible"
|
||||
position="top"
|
||||
@@ -93,19 +102,26 @@ export interface CopySearchFormData {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
searchParams?: Partial<CopySearchFormData>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
'search': [data: CopySearchFormData]
|
||||
'reset': []
|
||||
search: [data: CopySearchFormData]
|
||||
reset: []
|
||||
}>()
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val: boolean) => emit('update:modelValue', val),
|
||||
const visible = ref(false)
|
||||
|
||||
/** 搜索条件 placeholder 拼接 */
|
||||
const searchPlaceholder = computed(() => {
|
||||
const conditions: string[] = []
|
||||
if (props.searchParams?.processInstanceName) {
|
||||
conditions.push(`名称:${props.searchParams.processInstanceName}`)
|
||||
}
|
||||
if (props.searchParams?.createTime?.[0] && props.searchParams?.createTime?.[1]) {
|
||||
conditions.push(`时间:${formatDate(props.searchParams.createTime[0])}~${formatDate(props.searchParams.createTime[1])}`)
|
||||
}
|
||||
return conditions.length > 0 ? conditions.join(' | ') : '搜索抄送任务'
|
||||
})
|
||||
|
||||
const formData = reactive<CopySearchFormData>({
|
||||
@@ -141,7 +157,7 @@ function handleEndCancel() {
|
||||
}
|
||||
|
||||
/** 监听弹窗打开,同步外部参数 */
|
||||
watch(() => props.modelValue, (val) => {
|
||||
watch(visible, (val) => {
|
||||
if (val && props.searchParams) {
|
||||
formData.processInstanceName = props.searchParams.processInstanceName
|
||||
formData.createTime = props.searchParams.createTime ?? [undefined, undefined]
|
||||
|
||||
@@ -1,52 +1,53 @@
|
||||
<template>
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.processInstance?.name }}
|
||||
</view>
|
||||
<dict-tag :type="DICT_TYPE.BPM_TASK_STATUS" :value="item.status" />
|
||||
</view>
|
||||
<view v-if="item.processInstance?.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.processInstance.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ item.processInstance?.startUser?.nickname?.[0] || '?' }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ item.processInstance?.startUser?.nickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time">{{ formatDateTime(item.createTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无已办任务" />
|
||||
</view>
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<view>
|
||||
<!-- 搜索组件 -->
|
||||
<DoneSearchForm
|
||||
v-model="searchPopupVisible"
|
||||
:search-params="queryParams"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.processInstance?.name }}
|
||||
</view>
|
||||
<dict-tag :type="DICT_TYPE.BPM_TASK_STATUS" :value="item.status" />
|
||||
</view>
|
||||
<view v-if="item.processInstance?.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.processInstance.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ item.processInstance?.startUser?.nickname?.[0] || '?' }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ item.processInstance?.startUser?.nickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time">{{ formatDateTime(item.createTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无已办任务" />
|
||||
</view>
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -63,17 +64,13 @@ import DoneSearchForm from './done-search-form.vue'
|
||||
import './index.scss'
|
||||
|
||||
const props = defineProps<{
|
||||
searchVisible?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:searchVisible': [value: boolean]
|
||||
active?: boolean
|
||||
}>()
|
||||
|
||||
const total = ref(0)
|
||||
const list = ref<Task[]>([])
|
||||
const loadMoreState = ref<LoadMoreState>('loading')
|
||||
const searchPopupVisible = ref(false)
|
||||
const isFirstLoad = ref(true)
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
@@ -132,16 +129,18 @@ onReachBottom(() => {
|
||||
loadMore()
|
||||
})
|
||||
|
||||
watch(() => props.searchVisible, (val) => {
|
||||
searchPopupVisible.value = val ?? false
|
||||
})
|
||||
|
||||
watch(searchPopupVisible, (val) => {
|
||||
emit('update:searchVisible', val)
|
||||
/** 监听激活状态,刷新数据 */
|
||||
watch(() => props.active, (val) => {
|
||||
if (val && !isFirstLoad.value) {
|
||||
queryParams.pageNo = 1
|
||||
list.value = []
|
||||
getList()
|
||||
}
|
||||
})
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(() => {
|
||||
getList()
|
||||
isFirstLoad.value = false
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
<template>
|
||||
<!-- 搜索框入口 -->
|
||||
<wd-search
|
||||
:placeholder="searchPlaceholder"
|
||||
:hide-cancel="true"
|
||||
disabled
|
||||
@click="visible = true"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<wd-popup
|
||||
v-model="visible"
|
||||
position="top"
|
||||
@@ -126,7 +135,7 @@ import type { ProcessDefinition } from '@/api/bpm/definition'
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { getCategorySimpleList } from '@/api/bpm/category'
|
||||
import { getProcessDefinitionList } from '@/api/bpm/definition'
|
||||
import { getIntDictOptions } from '@/hooks/useDict'
|
||||
import { getDictLabel, getIntDictOptions } from '@/hooks/useDict'
|
||||
import { DICT_TYPE } from '@/utils/constants'
|
||||
import { formatDate } from '@/utils/date'
|
||||
|
||||
@@ -140,19 +149,29 @@ export interface DoneSearchFormData {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
searchParams?: Partial<DoneSearchFormData>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
'search': [data: DoneSearchFormData]
|
||||
'reset': []
|
||||
search: [data: DoneSearchFormData]
|
||||
reset: []
|
||||
}>()
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val: boolean) => emit('update:modelValue', val),
|
||||
const visible = ref(false)
|
||||
|
||||
/** 搜索条件 placeholder 拼接 */
|
||||
const searchPlaceholder = computed(() => {
|
||||
const conditions: string[] = []
|
||||
if (props.searchParams?.name) {
|
||||
conditions.push(`名称:${props.searchParams.name}`)
|
||||
}
|
||||
if (props.searchParams?.status !== undefined && props.searchParams.status !== -1) {
|
||||
conditions.push(`状态:${getDictLabel(DICT_TYPE.BPM_TASK_STATUS, props.searchParams.status)}`)
|
||||
}
|
||||
if (props.searchParams?.createTime?.[0] && props.searchParams?.createTime?.[1]) {
|
||||
conditions.push(`时间:${formatDate(props.searchParams.createTime[0])}~${formatDate(props.searchParams.createTime[1])}`)
|
||||
}
|
||||
return conditions.length > 0 ? conditions.join(' | ') : '搜索已办任务'
|
||||
})
|
||||
|
||||
const categoryList = ref<Category[]>([])
|
||||
@@ -211,7 +230,7 @@ async function getProcessDefinitions() {
|
||||
}
|
||||
|
||||
/** 监听弹窗打开,同步外部参数 */
|
||||
watch(() => props.modelValue, (val) => {
|
||||
watch(visible, (val) => {
|
||||
if (val && props.searchParams) {
|
||||
formData.name = props.searchParams.name
|
||||
formData.processDefinitionKey = props.searchParams.processDefinitionKey
|
||||
|
||||
@@ -1,61 +1,63 @@
|
||||
<template>
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="item.status" />
|
||||
</view>
|
||||
<view v-if="item.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ userNickname?.[0] }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ userNickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time">{{ formatDateTime(item.startTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无发起的流程" />
|
||||
</view>
|
||||
<!-- 加载更多 -->
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<view>
|
||||
<!-- 搜索组件 -->
|
||||
<MySearchForm
|
||||
v-model="searchPopupVisible"
|
||||
:search-params="queryParams"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
|
||||
<!-- 新增按钮 -->
|
||||
<view
|
||||
class="fixed bottom-100rpx right-32rpx z-10 h-100rpx w-100rpx flex items-center justify-center rounded-full bg-[#1890ff] shadow-lg"
|
||||
@click="handleCreate"
|
||||
>
|
||||
<wd-icon name="add" size="24px" color="#fff" />
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="item.status" />
|
||||
</view>
|
||||
<view v-if="item.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ userNickname?.[0] }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ userNickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time">{{ formatDateTime(item.startTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无发起的流程" />
|
||||
</view>
|
||||
<!-- 加载更多 -->
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
|
||||
<!-- 新增按钮 -->
|
||||
<!-- TODO @AI:换成 wd-fat:要注意,可能高度不对;晚点在改; -->
|
||||
<view
|
||||
class="fixed bottom-100rpx right-32rpx z-10 h-100rpx w-100rpx flex items-center justify-center rounded-full bg-[#1890ff] shadow-lg"
|
||||
@click="handleCreate"
|
||||
>
|
||||
<wd-icon name="add" size="24px" color="#fff" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -74,11 +76,7 @@ import MySearchForm from './my-search-form.vue'
|
||||
import './index.scss'
|
||||
|
||||
const props = defineProps<{
|
||||
searchVisible?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:searchVisible': [value: boolean]
|
||||
active?: boolean
|
||||
}>()
|
||||
|
||||
const userStore = useUserStore()
|
||||
@@ -87,7 +85,7 @@ const userNickname = computed(() => userStore.userInfo?.nickname || '')
|
||||
const total = ref(0)
|
||||
const list = ref<ProcessInstance[]>([])
|
||||
const loadMoreState = ref<LoadMoreState>('loading')
|
||||
const searchPopupVisible = ref(false)
|
||||
const isFirstLoad = ref(true)
|
||||
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
@@ -157,16 +155,18 @@ onReachBottom(() => {
|
||||
loadMore()
|
||||
})
|
||||
|
||||
watch(() => props.searchVisible, (val) => {
|
||||
searchPopupVisible.value = val ?? false
|
||||
})
|
||||
|
||||
watch(searchPopupVisible, (val) => {
|
||||
emit('update:searchVisible', val)
|
||||
/** 监听激活状态,刷新数据 */
|
||||
watch(() => props.active, (val) => {
|
||||
if (val && !isFirstLoad.value) {
|
||||
queryParams.pageNo = 1
|
||||
list.value = []
|
||||
getList()
|
||||
}
|
||||
})
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(() => {
|
||||
getList()
|
||||
isFirstLoad.value = false
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
<template>
|
||||
<!-- 搜索框入口 -->
|
||||
<wd-search
|
||||
:placeholder="searchPlaceholder"
|
||||
:hide-cancel="true"
|
||||
disabled
|
||||
@click="visible = true"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<wd-popup
|
||||
v-model="visible"
|
||||
position="top"
|
||||
@@ -126,7 +135,7 @@ import type { ProcessDefinition } from '@/api/bpm/definition'
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { getCategorySimpleList } from '@/api/bpm/category'
|
||||
import { getProcessDefinitionList } from '@/api/bpm/definition'
|
||||
import { getIntDictOptions } from '@/hooks/useDict'
|
||||
import { getDictLabel, getIntDictOptions } from '@/hooks/useDict'
|
||||
import { DICT_TYPE } from '@/utils/constants'
|
||||
import { formatDate } from '@/utils/date'
|
||||
|
||||
@@ -140,19 +149,29 @@ export interface MySearchFormData {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
searchParams?: Partial<MySearchFormData>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
'search': [data: MySearchFormData]
|
||||
'reset': []
|
||||
search: [data: MySearchFormData]
|
||||
reset: []
|
||||
}>()
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val: boolean) => emit('update:modelValue', val),
|
||||
const visible = ref(false)
|
||||
|
||||
/** 搜索条件 placeholder 拼接 */
|
||||
const searchPlaceholder = computed(() => {
|
||||
const conditions: string[] = []
|
||||
if (props.searchParams?.name) {
|
||||
conditions.push(`名称:${props.searchParams.name}`)
|
||||
}
|
||||
if (props.searchParams?.status !== undefined && props.searchParams.status !== -1) {
|
||||
conditions.push(`状态:${getDictLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, props.searchParams.status)}`)
|
||||
}
|
||||
if (props.searchParams?.createTime?.[0] && props.searchParams?.createTime?.[1]) {
|
||||
conditions.push(`时间:${formatDate(props.searchParams.createTime[0])}~${formatDate(props.searchParams.createTime[1])}`)
|
||||
}
|
||||
return conditions.length > 0 ? conditions.join(' | ') : '搜索我的流程'
|
||||
})
|
||||
|
||||
const categoryList = ref<Category[]>([])
|
||||
@@ -211,7 +230,7 @@ async function getProcessDefinitions() {
|
||||
}
|
||||
|
||||
/** 监听弹窗打开,同步外部参数 */
|
||||
watch(() => props.modelValue, (val) => {
|
||||
watch(visible, (val) => {
|
||||
if (val && props.searchParams) {
|
||||
formData.name = props.searchParams.name
|
||||
formData.processDefinitionId = props.searchParams.processDefinitionId
|
||||
|
||||
@@ -1,63 +1,64 @@
|
||||
<template>
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.processInstance?.name }}
|
||||
</view>
|
||||
<wd-tag type="primary" plain>
|
||||
待审批
|
||||
</wd-tag>
|
||||
</view>
|
||||
<view v-if="item.processInstance?.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.processInstance.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ item.processInstance?.startUser?.nickname?.[0] || '?' }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ item.processInstance?.startUser?.nickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time--warning">{{ formatPast(item.createTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-actions">
|
||||
<view class="bpm-action-btn" @click.stop="handleReject(item)">
|
||||
<text>拒绝</text>
|
||||
</view>
|
||||
<view class="bpm-action-btn" @click.stop="handleApprove(item)">
|
||||
<text>同意</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无待办任务" />
|
||||
</view>
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<view>
|
||||
<!-- 搜索组件 -->
|
||||
<TodoSearchForm
|
||||
v-model="searchPopupVisible"
|
||||
:search-params="queryParams"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
|
||||
<view class="bpm-list">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="bpm-card"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="bpm-card-content">
|
||||
<view class="bpm-card-header">
|
||||
<view class="bpm-card-title">
|
||||
{{ item.processInstance?.name }}
|
||||
</view>
|
||||
<wd-tag type="primary" plain>
|
||||
待审批
|
||||
</wd-tag>
|
||||
</view>
|
||||
<view v-if="item.processInstance?.summary?.length" class="bpm-summary">
|
||||
<view v-for="(s, idx) in item.processInstance.summary" :key="idx" class="bpm-summary-item">
|
||||
<text class="text-[#999]">{{ s.key }}:</text>
|
||||
<text>{{ s.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-card-info">
|
||||
<view class="bpm-user">
|
||||
<view class="bpm-avatar">
|
||||
{{ item.processInstance?.startUser?.nickname?.[0] || '?' }}
|
||||
</view>
|
||||
<text class="bpm-nickname">{{ item.processInstance?.startUser?.nickname }}</text>
|
||||
</view>
|
||||
<text class="bpm-time--warning">{{ formatPast(item.createTime) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bpm-actions">
|
||||
<view class="bpm-action-btn" @click.stop="handleReject(item)">
|
||||
<text>拒绝</text>
|
||||
</view>
|
||||
<view class="bpm-action-btn" @click.stop="handleApprove(item)">
|
||||
<text>同意</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
|
||||
<wd-status-tip image="content" tip="暂无待办任务" />
|
||||
</view>
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -73,17 +74,13 @@ import TodoSearchForm from './todo-search-form.vue'
|
||||
import './index.scss'
|
||||
|
||||
const props = defineProps<{
|
||||
searchVisible?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:searchVisible': [value: boolean]
|
||||
active?: boolean
|
||||
}>()
|
||||
|
||||
const total = ref(0)
|
||||
const list = ref<Task[]>([])
|
||||
const loadMoreState = ref<LoadMoreState>('loading')
|
||||
const searchPopupVisible = ref(false)
|
||||
const isFirstLoad = ref(true)
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
@@ -152,16 +149,18 @@ onReachBottom(() => {
|
||||
loadMore()
|
||||
})
|
||||
|
||||
watch(() => props.searchVisible, (val) => {
|
||||
searchPopupVisible.value = val ?? false
|
||||
})
|
||||
|
||||
watch(searchPopupVisible, (val) => {
|
||||
emit('update:searchVisible', val)
|
||||
/** 监听激活状态,刷新数据 */
|
||||
watch(() => props.active, (val) => {
|
||||
if (val && !isFirstLoad.value) {
|
||||
queryParams.pageNo = 1
|
||||
list.value = []
|
||||
getList()
|
||||
}
|
||||
})
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(() => {
|
||||
getList()
|
||||
isFirstLoad.value = false
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
<template>
|
||||
<!-- 搜索框入口 -->
|
||||
<wd-search
|
||||
:placeholder="searchPlaceholder"
|
||||
:hide-cancel="true"
|
||||
disabled
|
||||
@click="visible = true"
|
||||
/>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<wd-popup
|
||||
v-model="visible"
|
||||
position="top"
|
||||
@@ -126,7 +135,7 @@ import type { ProcessDefinition } from '@/api/bpm/definition'
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { getCategorySimpleList } from '@/api/bpm/category'
|
||||
import { getProcessDefinitionList } from '@/api/bpm/definition'
|
||||
import { getIntDictOptions } from '@/hooks/useDict'
|
||||
import { getDictLabel, getIntDictOptions } from '@/hooks/useDict'
|
||||
import { DICT_TYPE } from '@/utils/constants'
|
||||
import { formatDate } from '@/utils/date'
|
||||
|
||||
@@ -140,19 +149,29 @@ export interface TodoSearchFormData {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
searchParams?: Partial<TodoSearchFormData>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
'search': [data: TodoSearchFormData]
|
||||
'reset': []
|
||||
search: [data: TodoSearchFormData]
|
||||
reset: []
|
||||
}>()
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val: boolean) => emit('update:modelValue', val),
|
||||
const visible = ref(false)
|
||||
|
||||
/** 搜索条件 placeholder 拼接 */
|
||||
const searchPlaceholder = computed(() => {
|
||||
const conditions: string[] = []
|
||||
if (props.searchParams?.name) {
|
||||
conditions.push(`名称:${props.searchParams.name}`)
|
||||
}
|
||||
if (props.searchParams?.status !== undefined && props.searchParams.status !== -1) {
|
||||
conditions.push(`状态:${getDictLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, props.searchParams.status)}`)
|
||||
}
|
||||
if (props.searchParams?.createTime?.[0] && props.searchParams?.createTime?.[1]) {
|
||||
conditions.push(`时间:${formatDate(props.searchParams.createTime[0])}~${formatDate(props.searchParams.createTime[1])}`)
|
||||
}
|
||||
return conditions.length > 0 ? conditions.join(' | ') : '搜索待办任务'
|
||||
})
|
||||
|
||||
const categoryList = ref<Category[]>([])
|
||||
@@ -211,7 +230,7 @@ async function getProcessDefinitions() {
|
||||
}
|
||||
|
||||
/** 监听弹窗打开,同步外部参数 */
|
||||
watch(() => props.modelValue, (val) => {
|
||||
watch(visible, (val) => {
|
||||
if (val && props.searchParams) {
|
||||
formData.name = props.searchParams.name
|
||||
formData.processDefinitionKey = props.searchParams.processDefinitionKey
|
||||
|
||||
@@ -4,13 +4,7 @@
|
||||
<wd-navbar
|
||||
title="审批"
|
||||
placeholder safe-area-inset-top fixed
|
||||
>
|
||||
<template #right>
|
||||
<view class="flex items-center" @click="searchVisible = !searchVisible">
|
||||
<wd-icon name="search" size="20px" />
|
||||
</view>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
/>
|
||||
|
||||
<!-- Tabs 区域 -->
|
||||
<view class="bg-white">
|
||||
@@ -22,26 +16,10 @@
|
||||
</wd-tabs>
|
||||
</view>
|
||||
<!-- 列表内容 -->
|
||||
<TodoList
|
||||
v-show="tabType === 'todo'"
|
||||
:search-visible="searchVisible && tabType === 'todo'"
|
||||
@update:search-visible="searchVisible = $event"
|
||||
/>
|
||||
<DoneList
|
||||
v-show="tabType === 'done'"
|
||||
:search-visible="searchVisible && tabType === 'done'"
|
||||
@update:search-visible="searchVisible = $event"
|
||||
/>
|
||||
<MyList
|
||||
v-show="tabType === 'my'"
|
||||
:search-visible="searchVisible && tabType === 'my'"
|
||||
@update:search-visible="searchVisible = $event"
|
||||
/>
|
||||
<CopyList
|
||||
v-show="tabType === 'copy'"
|
||||
:search-visible="searchVisible && tabType === 'copy'"
|
||||
@update:search-visible="searchVisible = $event"
|
||||
/>
|
||||
<TodoList v-show="tabType === 'todo'" :active="tabType === 'todo'" />
|
||||
<DoneList v-show="tabType === 'done'" :active="tabType === 'done'" />
|
||||
<MyList v-show="tabType === 'my'" :active="tabType === 'my'" />
|
||||
<CopyList v-show="tabType === 'copy'" :active="tabType === 'copy'" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -63,12 +41,10 @@ definePage({
|
||||
const tabTypes: string[] = ['todo', 'done', 'my', 'copy']
|
||||
const tabIndex = ref(0)
|
||||
const tabType = computed<string>(() => tabTypes[tabIndex.value])
|
||||
const searchVisible = ref(false)
|
||||
|
||||
/** Tab 切换 */
|
||||
function handleTabChange({ index }: { index: number }) {
|
||||
tabIndex.value = index
|
||||
searchVisible.value = false
|
||||
}
|
||||
|
||||
/** 初始化:根据 tab 参数设置默认 tab */
|
||||
|
||||
Reference in New Issue
Block a user