feat: 完成申请审批成员及部门组件封装
This commit is contained in:
parent
1bdc3bdc87
commit
0c35f8742c
@ -31,6 +31,13 @@
|
|||||||
{{ title }}
|
{{ title }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view
|
||||||
|
v-if="rightButtonText"
|
||||||
|
class="text-3.5 font-normal pos-absolute right-5"
|
||||||
|
@click="rightButton"
|
||||||
|
>
|
||||||
|
{{ rightButtonText }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -59,16 +66,24 @@
|
|||||||
backUrl: {
|
backUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '/static/images/icon_back.png'
|
default: '/static/images/icon_back.png'
|
||||||
|
},
|
||||||
|
rightButtonText: {
|
||||||
|
type: [String, null],
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emits = defineEmits(['back'])
|
const emits = defineEmits(['back', 'rightButton'])
|
||||||
|
|
||||||
const back = () => {
|
const back = () => {
|
||||||
uni.navigateBack()
|
uni.navigateBack()
|
||||||
emits('back')
|
emits('back')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rightButton = () => {
|
||||||
|
emits('rightButton')
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
systemInfo.value = await $basic.getSystemInfo()
|
systemInfo.value = await $basic.getSystemInfo()
|
||||||
})
|
})
|
||||||
|
|||||||
@ -239,6 +239,14 @@
|
|||||||
},
|
},
|
||||||
"needLogin": false
|
"needLogin": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/select-member-or-department/select-member-or-department",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"disableScroll": true
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/workbench/workbench",
|
"path": "pages/workbench/workbench",
|
||||||
"type": "page"
|
"type": "page"
|
||||||
|
|||||||
@ -61,12 +61,21 @@
|
|||||||
@change="changeDate"
|
@change="changeDate"
|
||||||
></DatetimePicker>
|
></DatetimePicker>
|
||||||
<wd-divider color="#bcbfbe"></wd-divider>
|
<wd-divider color="#bcbfbe"></wd-divider>
|
||||||
<Images id="8" title="图片"></Images>
|
<Images :id="8" title="图片"></Images>
|
||||||
<wd-divider color="#bcbfbe"></wd-divider>
|
<wd-divider color="#bcbfbe"></wd-divider>
|
||||||
<Description
|
<Description
|
||||||
id="9"
|
:id="9"
|
||||||
title="图片21378912378923718982371217389712397837889713247893428793142897134728900978"
|
title="图片21378912378923718982371217389712397837889713247893428793142897134728900978"
|
||||||
></Description>
|
></Description>
|
||||||
|
<wd-divider color="#bcbfbe"></wd-divider>
|
||||||
|
<MemberOrDepartment :id="10" title="成员" type="member" :multiple="true"></MemberOrDepartment>
|
||||||
|
<wd-divider color="#bcbfbe"></wd-divider>
|
||||||
|
<MemberOrDepartment
|
||||||
|
:id="11"
|
||||||
|
title="部门"
|
||||||
|
type="department"
|
||||||
|
:multiple="true"
|
||||||
|
></MemberOrDepartment>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -78,6 +87,7 @@
|
|||||||
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
|
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
|
||||||
import Images from '@/pages/approval/components/Images.vue'
|
import Images from '@/pages/approval/components/Images.vue'
|
||||||
import Description from '@/pages/approval/components/Description.vue'
|
import Description from '@/pages/approval/components/Description.vue'
|
||||||
|
import MemberOrDepartment from '@/pages/approval/components/MemberOrDepartment.vue'
|
||||||
|
|
||||||
const columns = ref<Record<number, any>>([
|
const columns = ref<Record<number, any>>([
|
||||||
{
|
{
|
||||||
|
|||||||
65
src/pages/approval/components/MemberOrDepartment.vue
Normal file
65
src/pages/approval/components/MemberOrDepartment.vue
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<view class="px-2 text-3.5">
|
||||||
|
<view class="flex flex-items-center pos-relative">
|
||||||
|
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||||
|
<view>{{ title }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="py-2" @click="toSelect">
|
||||||
|
<view class="flex flex-items-center flex-justify-between">
|
||||||
|
<view>{{ text || placeholder }}</view>
|
||||||
|
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const text = ref<string | null>(null)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
multiple: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [Number, null],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '请输入'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const toSelect = () => {
|
||||||
|
const params = {
|
||||||
|
type: props.type,
|
||||||
|
multiple: props.multiple,
|
||||||
|
title: props.type === 'member' ? '选择审批用户' : '选择部门'
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/select-member-or-department/select-member-or-department?params=${JSON.stringify(params)}`,
|
||||||
|
events: {
|
||||||
|
change: res => {
|
||||||
|
console.log(1111, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<view class="flex flex-items-center py-2 text-4" @click="toClick">
|
||||||
|
<view
|
||||||
|
v-if="item.type === 'member'"
|
||||||
|
class="w-10 h-10 flex flex-justify-center flex-items-center"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
src="/static/images/icon_default_avatar.png"
|
||||||
|
class="w-8 h-8 rounded-2"
|
||||||
|
mode="aspectFill"
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
<view v-else class="w-10 h-10 flex flex-justify-center flex-items-center bg-#e4f1ff rounded-2">
|
||||||
|
<image src="/static/images/icon_file.png" class="w-6 h-6" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
<view class="ml-2 break-all max-w-40 overflow-hidden text-ellipsis line-clamp-1">
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
<view class="ml-a" v-if="item.type === 'department'">
|
||||||
|
<wd-divider vertical></wd-divider>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
v-if="item.type === 'department'"
|
||||||
|
:class="[disabled ? 'color-#87a9fb' : 'custom-color-blue']"
|
||||||
|
class="ml-1"
|
||||||
|
>
|
||||||
|
下级
|
||||||
|
</view>
|
||||||
|
<wd-icon
|
||||||
|
name="arrow-right"
|
||||||
|
size="14px"
|
||||||
|
class="ml-2"
|
||||||
|
:color="disabled ? '#87a9fb' : '#255cf7'"
|
||||||
|
v-if="item.type === 'department'"
|
||||||
|
></wd-icon>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const emits = defineEmits(['click'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const toClick = () => {
|
||||||
|
emits('click')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<view class="flex flex-items-center py-2 text-4" @click="toClick">
|
||||||
|
<view
|
||||||
|
v-if="item.type === 'member'"
|
||||||
|
class="w-10 h-10 flex flex-justify-center flex-items-center"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
src="/static/images/icon_default_avatar.png"
|
||||||
|
class="w-8 h-8 rounded-2"
|
||||||
|
mode="aspectFill"
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
<view v-else class="w-10 h-10 flex flex-justify-center flex-items-center bg-#e4f1ff rounded-2">
|
||||||
|
<image src="/static/images/icon_file.png" class="w-6 h-6" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
<view class="ml-2 break-all max-w-40 overflow-hidden text-ellipsis line-clamp-1">
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const emits = defineEmits(['click'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const toClick = () => {
|
||||||
|
emits('click')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,275 @@
|
|||||||
|
<route lang="json5">
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
disableScroll: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view v-if="showSearch" class="h-[calc(100vh-60px)] flex flex-col">
|
||||||
|
<view v-if="systemInfo" :style="{ marginTop: systemInfo.safeAreaInsets?.top + 'px' }">
|
||||||
|
<view class="h-12 pt-1 pb-2">
|
||||||
|
<wd-search
|
||||||
|
:placeholder-left="true"
|
||||||
|
:focus="false"
|
||||||
|
@change="changeSearch"
|
||||||
|
@cancel="showSearch = false"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="flex-1 box-border" :scroll-y="true">
|
||||||
|
<view class="bg-white">
|
||||||
|
<view
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
class="border-[#ebebeb] border-b-1 border-b-solid px-4 flex flex-items-center"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
v-if="!(type === 'member' && item.type === 'department')"
|
||||||
|
class="mr-3"
|
||||||
|
@click="toClick(item)"
|
||||||
|
>
|
||||||
|
<wd-icon
|
||||||
|
v-if="value.includes(item)"
|
||||||
|
name="check-circle-filled"
|
||||||
|
color="#255cf9"
|
||||||
|
size="26px"
|
||||||
|
></wd-icon>
|
||||||
|
<wd-icon v-else name="circle1" color="#838589" size="26px"></wd-icon>
|
||||||
|
</view>
|
||||||
|
<SearchItem class="flex-1" :item="item" @click="toClick(item)"></SearchItem>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!showSearch" class="h-[calc(100vh-60px-env(safe-area-inset-bottom))] flex flex-col">
|
||||||
|
<TopNavigation :title="title"></TopNavigation>
|
||||||
|
<view
|
||||||
|
@click="showSearch = true"
|
||||||
|
class="bg-white flex flex-justify-center flex-items-center rounded color-#a6a6a6 mx-4 mt-3 py-1.5"
|
||||||
|
>
|
||||||
|
<wd-icon name="search" size="16px" class="mr-2"></wd-icon>
|
||||||
|
<view>搜索</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-items-center m-4 text-3.5 break-all overflow-hidden whitespace-nowrap">
|
||||||
|
<view
|
||||||
|
v-for="(department, index) in organizationList"
|
||||||
|
:key="department.id"
|
||||||
|
class="flex flex-items-center"
|
||||||
|
@click="toOrganization(index)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
:class="[index === organizationList.length - 1 ? 'color-#838589' : 'custom-color-blue']"
|
||||||
|
>
|
||||||
|
{{ department.name }}
|
||||||
|
</span>
|
||||||
|
<span v-if="index !== organizationList.length - 1" class="mx-0.5">/</span>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="flex-1 box-border" :scroll-y="true">
|
||||||
|
<view class="bg-white">
|
||||||
|
<view
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
class="border-[#ebebeb] border-b-1 border-b-solid px-4 flex flex-items-center"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
v-if="!(type === 'member' && item.type === 'department')"
|
||||||
|
class="mr-3"
|
||||||
|
@click="toClick(item)"
|
||||||
|
>
|
||||||
|
<wd-icon
|
||||||
|
v-if="value.includes(item)"
|
||||||
|
name="check-circle-filled"
|
||||||
|
color="#255cf9"
|
||||||
|
size="26px"
|
||||||
|
></wd-icon>
|
||||||
|
<wd-icon v-else name="circle1" color="#838589" size="26px"></wd-icon>
|
||||||
|
</view>
|
||||||
|
<MemberOrDepartmentItem
|
||||||
|
class="flex-1"
|
||||||
|
:item="item"
|
||||||
|
:disabled="item.type === 'department' && value.includes(item)"
|
||||||
|
@click="toClick(item)"
|
||||||
|
></MemberOrDepartmentItem>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="py-5 px-15">
|
||||||
|
<wd-divider color="#838589">仅显示已开通账号的人员</wd-divider>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="pb-safe h-60px px-4 border-[#ebebeb] border-t-1 border-t-solid text-3.5 flex flex-items-center"
|
||||||
|
>
|
||||||
|
<view class="flex flex-items-center flex-justify-between w-full">
|
||||||
|
<view class="flex flex-items-center" v-if="value.length" @click="showSelected = true">
|
||||||
|
<view class="custom-color-blue">已选中:{{ value.length }}个人</view>
|
||||||
|
<wd-icon name="arrow-right" size="16px" class="ml-2" color="#255cf7"></wd-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else></view>
|
||||||
|
<view class="custom-bg-blue color-white py-1 px-5 rounded" @click="confirm">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<wd-popup v-model="showSelected" position="bottom">
|
||||||
|
<view class="h-100vh flex flex-col bg-#f3f5fa">
|
||||||
|
<TopNavigation
|
||||||
|
title="已选中"
|
||||||
|
:have-back="false"
|
||||||
|
right-button-text="确定"
|
||||||
|
@right-button="showSelected = false"
|
||||||
|
></TopNavigation>
|
||||||
|
<scroll-view class="flex-1 box-border" :scroll-y="true">
|
||||||
|
<view class="bg-white">
|
||||||
|
<view
|
||||||
|
v-for="item in value"
|
||||||
|
:key="item.id"
|
||||||
|
class="flex flex-items-center px-4 py-3 border-[#ebebeb] border-b-1 border-b-solid"
|
||||||
|
>
|
||||||
|
<image :src="item.avatar" class="w-10 h-10 rounded-2"></image>
|
||||||
|
<view class="ml-4 text-3.5">
|
||||||
|
<view>{{ item.name }}</view>
|
||||||
|
<view class="mt-1 color-#a6a6a6 text-3">{{ item.name }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="p-1 ml-a bg-#f3f5f8 rounded-50%" @click="deleteItem(item)">
|
||||||
|
<image src="/static/images/icon_delete.png" class="w-5 h-5"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</wd-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useBasicStore } from '@/store'
|
||||||
|
import MemberOrDepartmentItem from '@/pages/select-member-or-department/components/MemberOrDepartmentItem.vue'
|
||||||
|
import SearchItem from '@/pages/select-member-or-department/components/SearchItem.vue'
|
||||||
|
|
||||||
|
const instance = getCurrentInstance().proxy
|
||||||
|
const eventChannel = instance.getOpenerEventChannel()
|
||||||
|
|
||||||
|
const type = ref<string>('')
|
||||||
|
const multiple = ref<boolean>(false)
|
||||||
|
const title = ref<string>('')
|
||||||
|
const showSearch = ref<boolean>(false)
|
||||||
|
|
||||||
|
const organizationList = ref<Array<object>>([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
type: 'department',
|
||||||
|
name: '技术部'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const $basic = useBasicStore()
|
||||||
|
|
||||||
|
const systemInfo = ref(null)
|
||||||
|
|
||||||
|
const value = ref<Array>([])
|
||||||
|
const showSelected = ref<boolean>(false)
|
||||||
|
|
||||||
|
const list = ref<Array<object>>([
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
type: 'department',
|
||||||
|
name: 'xxx的互联',
|
||||||
|
avatar: '/static/images/icon_file.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
type: 'member',
|
||||||
|
name: '张三',
|
||||||
|
avatar: '/static/images/icon_default_avatar.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
type: 'member',
|
||||||
|
name: '李四',
|
||||||
|
avatar: '/static/images/icon_default_avatar.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
type: 'member',
|
||||||
|
name: '王五',
|
||||||
|
avatar: '/static/images/icon_default_avatar.png'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const toClick = item => {
|
||||||
|
if (value.value.includes(item)) {
|
||||||
|
value.value = value.value.filter(v => v !== item)
|
||||||
|
} else {
|
||||||
|
if (multiple.value || value.value.length === 0) {
|
||||||
|
value.value.push(item)
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '最多选择一个',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteItem = item => {
|
||||||
|
value.value = value.value.filter(v => v !== item)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
systemInfo.value = await $basic.getSystemInfo()
|
||||||
|
})
|
||||||
|
|
||||||
|
function changeSearch({ value }) {
|
||||||
|
console.log('输入', value)
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(options => {
|
||||||
|
const params = JSON.parse(options.params)
|
||||||
|
type.value = params.type
|
||||||
|
multiple.value = params.multiple
|
||||||
|
title.value = params.title
|
||||||
|
})
|
||||||
|
|
||||||
|
const toOrganization = index => {
|
||||||
|
if (index === organizationList.value.length - 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: organizationList.value.length - index - 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const change = e => {
|
||||||
|
console.log('change', e)
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = () => {
|
||||||
|
eventChannel.emit('change', { value: value.value })
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: organizationList.value.length
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
:deep(.wd-checkbox) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wd-search {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.wd-search__block) {
|
||||||
|
padding: 3px 0;
|
||||||
|
background-color: #e2e5ea;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.wd-search__cancel) {
|
||||||
|
color: #a6a6a6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
src/static/images/icon_delete.png
Normal file
BIN
src/static/images/icon_delete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/static/images/icon_file.png
Normal file
BIN
src/static/images/icon_file.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
1
src/types/uni-pages.d.ts
vendored
1
src/types/uni-pages.d.ts
vendored
@ -29,6 +29,7 @@ interface NavigateToOptions {
|
|||||||
"/pages/mine/mine" |
|
"/pages/mine/mine" |
|
||||||
"/pages/notification/notification" |
|
"/pages/notification/notification" |
|
||||||
"/pages/reset-password/reset-password" |
|
"/pages/reset-password/reset-password" |
|
||||||
|
"/pages/select-member-or-department/select-member-or-department" |
|
||||||
"/pages/workbench/workbench" |
|
"/pages/workbench/workbench" |
|
||||||
"/pages/attendance/attendance-add-group/attendance-add-group" |
|
"/pages/attendance/attendance-add-group/attendance-add-group" |
|
||||||
"/pages/attendance/attendance-add-group/attendance-device" |
|
"/pages/attendance/attendance-add-group/attendance-device" |
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user