【招生小程序】 优化# 主账号-个人:封装查询组件

master
kaeery 2025-03-06 21:00:02 +08:00
parent 402b87b8b7
commit 56aa0125b8
12 changed files with 647 additions and 597 deletions

View File

@ -0,0 +1,58 @@
<template>
<u-popup :show="show" mode="bottom" :customStyle="{ padding: '20px' }" round="10px">
<view>
<dateDropdownPicker
ref="dateDropdownPickerRef"
:dropdownItem="dropdownMenuDateList"
@reset="handleReset"
@confirm="handleConfirm"
/>
</view>
</u-popup>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import dateDropdownPicker from '@/components/date-dropdown/daterange.vue'
import { useToggle } from '@/hooks/useLockFn'
import { formateDate, getCurDate } from '@/utils/util'
const { show, handleToggle } = useToggle()
const emit = defineEmits(['confirm', 'reset'])
const dateDropdownPickerRef = ref<InstanceType<typeof dateDropdownPicker>>()
const dropdownMenuDateList = ref({
showQuick: true,
title: '日期范围',
type: 'daterange',
prop: 'god6',
value: { start: getCurDate('start', 'YYYY-MM-DD'), end: getCurDate('end', 'YYYY-MM-DD') }
})
const openPopup = () => {
handleToggle()
}
//
const setDefaultValue = (payload: any) => {
if (payload.createTimeStart || payload.createTimeEnd) {
dropdownMenuDateList.value.value = {
start: formateDate(payload.createTimeStart, 'start', 'YYYY-MM-DD'),
end: formateDate(payload.createTimeEnd, 'end', 'YYYY-MM-DD')
}
dateDropdownPickerRef.value.initData(dropdownMenuDateList.value, false, payload.dateTag)
}
}
const handleConfirm = (value: string) => {
emit('confirm', value)
}
const handleReset = () => {
emit('reset')
}
defineExpose({
openPopup,
setDefaultValue,
handleToggle
})
</script>
<style scoped></style>

View File

@ -1,6 +1,6 @@
<template> <template>
<view class="flex flex-col h-screen"> <view class="flex flex-col h-screen">
<view class="flex items-center justify-between"> <view class="flex items-center justify-between relative">
<view class="flex-1 overflow-auto"> <view class="flex-1 overflow-auto">
<u-tabs <u-tabs
:list="tabs" :list="tabs"
@ -12,7 +12,7 @@
@change="handleChangeTab" @change="handleChangeTab"
></u-tabs> ></u-tabs>
</view> </view>
<view class="mr-[32rpx]"> <view class="mr-[32rpx]" @click="handleShowPopup">
<TIcon name="icon-filter" color="#999" /> <TIcon name="icon-filter" color="#999" />
</view> </view>
</view> </view>
@ -37,6 +37,7 @@
/> />
</z-paging> </z-paging>
</view> </view>
<date-popup ref="datePopupRef" @confirm="handleConfirmDate" @reset="handleResetDate" />
</view> </view>
</template> </template>
@ -44,10 +45,13 @@
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { ref, shallowRef } from 'vue' import { ref, shallowRef } from 'vue'
import clueCard from './components/clue-card.vue' import clueCard from './components/clue-card.vue'
import datePopup from './components/date-popup.vue'
import { useZPaging } from '@/hooks/useZPaging' import { useZPaging } from '@/hooks/useZPaging'
import { apiTeleClueList } from '@/api/clue' import { apiTeleClueList } from '@/api/clue'
import { computed } from 'vue' import { computed } from 'vue'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import { nextTick } from 'vue'
import { formatDate, formateDate, getCurDate } from '@/utils/util'
const queryParams = ref({ const queryParams = ref({
likeWork: '' likeWork: ''
@ -83,13 +87,47 @@ const searchChange = debounce(() => {
}, 300) }, 300)
const type = ref('') const type = ref('')
onLoad(option => { const dateTagFlag = ref('')
if (option.id) { onLoad(async options => {
uni.setNavigationBarTitle({ setFormData(options)
title: '张三' dateTagFlag.value = options?.dateTag ?? ''
}) await nextTick()
type.value = option.type ?? '' datePopupRef.value?.setDefaultValue({ ...form.value, dateTag: dateTagFlag.value })
} // if (option.id) {
// uni.setNavigationBarTitle({
// title: ''
// })
type.value = options.type ?? ''
// }
}) })
const form = ref()
//
const setFormData = options => {
form.value = Object.keys(options).reduce((acc, key) => {
if (key == 'id' || key == 'dateTag' || key == 'type') {
return acc
}
acc[key] = decodeURIComponent(options[key])
return acc
}, {})
}
const datePopupRef = ref<InstanceType<typeof datePopup>>()
const handleShowPopup = () => {
datePopupRef.value?.openPopup()
}
const handleConfirmDate = (date: { [key: string]: string }) => {
const { start, end } = date
form.value.createTimeStart = formateDate(start, 'start', 'YYYY-MM-DD')
form.value.createTimeEnd = formateDate(end, 'end', 'YYYY-MM-DD')
datePopupRef.value?.handleToggle(true)
}
const handleResetDate = () => {
form.value.createTimeStart = getCurDate('start', 'YYYY-MM-DD')
form.value.createTimeEnd = getCurDate('end', 'YYYY-MM-DD')
console.log(form.value)
datePopupRef.value?.handleToggle(true)
}
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -1,5 +1,5 @@
<template> <template>
<view> <view class="flex flex-col h-screen">
<u-tabs <u-tabs
:list="tabs" :list="tabs"
:scrollable="false" :scrollable="false"
@ -18,20 +18,30 @@
@change="handleChangeTab" @change="handleChangeTab"
></u-tabs> ></u-tabs>
<dropdownPicker ref="dropdownPickerRef" v-model="form" @refresh-page="refreshPage" /> <dropdownPicker ref="dropdownPickerRef" v-model="form" @refresh-page="refreshPage" />
<template v-if="loading && !data.length"> <view class="flex-1 overflow-auto">
<view class="min-h-[200rpx] flex justify-center items-center"> <template v-if="loading && !data.length">
<u-loading-icon></u-loading-icon> <view class="min-h-[200rpx] flex justify-center items-center">
</view> <u-loading-icon></u-loading-icon>
</template> </view>
<template v-if="!loading && data.length > 0"> </template>
<TTable :columns="columns" :data="data"> <template v-else-if="!loading && data.length > 0">
<template #index="scope"> <TTable :columns="columns" :data="data">
<text class="px-[20rpx] py-[6rpx] rounded-[4px]" :style="rankStyle(scope.row)"> <template #index="scope">
{{ scope.row }} <text
</text> class="px-[20rpx] py-[6rpx] rounded-[4px]"
</template> :style="rankStyle(scope.row)"
</TTable> >
</template> {{ scope.row }}
</text>
</template>
</TTable>
</template>
<template v-else-if="!loading && data.length == 0">
<div class="pb-3">
<w-empty />
</div>
</template>
</view>
</view> </view>
</template> </template>
@ -45,7 +55,7 @@ import { IForm } from '@/components/widgets/admin/team/index.vue'
const dropdownPickerRef = ref<InstanceType<typeof dropdownPicker>>() const dropdownPickerRef = ref<InstanceType<typeof dropdownPicker>>()
const form = ref<IForm>() const form = ref<IForm>()
const { tabs, activeTab, columns, data, loading, rankStyle, handleChangeTab, fetchData } = useRank({ const { tabs, columns, data, loading, rankStyle, handleChangeTab, fetchData } = useRank({
width: 160, width: 160,
callback: () => { callback: () => {
fetchData(form.value) fetchData(form.value)
@ -63,6 +73,7 @@ onLoad(async options => {
) )
fetchData(form.value) fetchData(form.value)
}) })
//
const setFormData = options => { const setFormData = options => {
form.value = Object.keys(options).reduce((acc, key) => { form.value = Object.keys(options).reduce((acc, key) => {
if (key == 'dropdownIndex' || key == 'dateTag') { if (key == 'dropdownIndex' || key == 'dateTag') {

View File

@ -0,0 +1,170 @@
<template>
<view class="bg-white">
<u-dropdown ref="uDropdownRef" menu-icon="arrow-down-fill">
<u-dropdown-item title="岗位">
<view class="bg-white">
<position-tabs
@reset="handleReset('position')"
@confirm="value => handleConfirm('position', value)"
/>
</view>
</u-dropdown-item>
<u-dropdown-item title="组织">
<view class="bg-white">
<DropdownPicker
:dropdownItem="dropdownMenuOrgList"
@reset="() => handleReset('user')"
@confirm="value => handleConfirm('user', value)"
/>
</view>
</u-dropdown-item>
<u-dropdown-item title="日期">
<view class="bg-white p-[20rpx]">
<dateDropdownPicker
:dropdownItem="dropdownMenuDateList"
@reset="() => handleReset('date')"
@confirm="
(value, dropIndex, dateTag) => handleConfirm('date', value, dateTag)
"
/>
</view>
</u-dropdown-item>
</u-dropdown>
</view>
</template>
<script setup lang="ts">
import positionTabs from './position-tabs.vue'
import DropdownPicker from '../../orga-picker.vue'
import dateDropdownPicker from '@/components/date-dropdown/daterange.vue'
import { PropType, computed, ref } from 'vue'
import { apiOrganizationAllList } from '@/api/admin'
import { IForm } from '../../team/index.vue'
import { formateDate, getCurDate } from '@/utils/util'
const props = defineProps({
modelValue: {
type: Object as PropType<IForm>,
default: () => ({})
}
})
const emit = defineEmits(['update:modelValue', 'refreshPage', 'confirm', 'reset'])
const localValue = computed({
get() {
return props.modelValue
},
set(newValue) {
return emit('update:modelValue', newValue)
}
})
const uDropdownRef = ref()
const dropdownMenuDateList = ref({
dropdownIndex: 3,
showQuick: true,
title: '日期范围',
type: 'daterange',
prop: 'god6',
value: { start: getCurDate('start', 'YYYY-MM-DD'), end: getCurDate('end', 'YYYY-MM-DD') }
})
const dropdownMenuOrgList = ref<any[]>([])
//
const handleConfirm = (type: string, item, dateTag?: string) => {
switch (type) {
case 'user':
localValue.value = {
...localValue.value,
userId: item.value
}
break
case 'date':
localValue.value = {
...localValue.value,
createTimeStart: formateDate(item.start, 'start'),
createTimeEnd: formateDate(item.end, 'end')
}
break
case 'position':
localValue.value = {
...localValue.value,
postId: item
}
break
default:
break
}
emit('refreshPage')
emit('confirm', dateTag)
closeDropDown()
}
//
const handleReset = (type: string) => {
switch (type) {
case 'user':
localValue.value = {
...localValue.value,
userId: ''
}
break
case 'date':
localValue.value = {
...localValue.value,
createTimeStart: getCurDate('start'),
createTimeEnd: getCurDate('end')
}
break
case 'position':
localValue.value = {
...localValue.value,
postId: 0
}
break
default:
break
}
emit('refreshPage')
emit('reset')
closeDropDown()
}
const closeDropDown = () => {
uDropdownRef.value.close()
}
//
const fetchAllOrganizationList = async () => {
try {
const result = await apiOrganizationAllList()
dropdownMenuOrgList.value = renameFields(result)
} catch (error) {}
}
const renameFields = (data: any[]): any[] => {
return data.map(item => {
const newItem = { ...item }
newItem.label = item.name
newItem.value = item.id
if (newItem.organizationVoList) {
newItem.children = renameFields(newItem.organizationVoList)
delete newItem.organizationVoList
}
if (newItem.userVos) {
newItem.userVos.forEach(item => {
item.label = item.username
item.value = item.id
})
newItem.children = newItem.children
? [...newItem.children, ...newItem.userVos]
: newItem.userVos
delete newItem.userVos
}
if (!newItem.children.length) {
newItem.disabled = true
}
return newItem
})
}
fetchAllOrganizationList()
</script>
<style scoped></style>

View File

@ -35,7 +35,6 @@ const handleCellClick = (item: any) => {
const { id } = item const { id } = item
postId.value = id postId.value = id
emit('update:modelValue', id) emit('update:modelValue', id)
emit('confirm', item)
} }
const handleReset = () => { const handleReset = () => {
postId.value = 0 postId.value = 0

View File

@ -32,7 +32,9 @@
<text>{{ parseText(key) }}数据</text> <text>{{ parseText(key) }}数据</text>
<text class="text-primary" @click="handleMore(key)"></text> <text class="text-primary" @click="handleMore(key)"></text>
</view> </view>
<view class="flex gap-[12rpx] flex-wrap bg-[#f1f1f1] mx-[24rpx] py-[24rpx]"> <view
class="flex gap-[12rpx] flex-wrap bg-[#FAFAFE] mx-[24rpx] py-[24rpx] rounded-[12rpx]"
>
<view <view
class="w-[30%] flex justify-center items-center flex-col gap-[12rpx]" class="w-[30%] flex justify-center items-center flex-col gap-[12rpx]"
v-for="(item, indey) in value" v-for="(item, indey) in value"

View File

@ -1,36 +1,6 @@
<template> <template>
<view class="flex-1 h-full flex flex-col"> <view class="flex-1 h-full flex flex-col">
<view class="bg-white"> <dropdownPicker v-model="form" @confirm="confirm" @reset-page="resetPage" />
<u-dropdown ref="uDropdownRef" menu-icon="arrow-down-fill">
<u-dropdown-item title="岗位">
<view class="bg-white">
<position-tabs
v-model="postId"
@reset="handleReset('position')"
@confirm="value => handleConfirm('position', value)"
/>
</view>
</u-dropdown-item>
<u-dropdown-item title="组织">
<view class="bg-white">
<DropdownPicker
:dropdownItem="dropdownMenuOrgList"
@reset="() => handleReset('organization')"
@confirm="value => handleConfirm('organization', value)"
/>
</view>
</u-dropdown-item>
<u-dropdown-item title="日期">
<view class="bg-white p-[20rpx]">
<dateDropdownPicker
:dropdownItem="dropdownMenuList2"
@reset="() => handleReset('date')"
@confirm="value => handleConfirm('date', value)"
/>
</view>
</u-dropdown-item>
</u-dropdown>
</view>
<view class="flex-1 mt-3 px-[32rpx] overflow-auto bg-[#FAFAFE]"> <view class="flex-1 mt-3 px-[32rpx] overflow-auto bg-[#FAFAFE]">
<!-- <z-paging <!-- <z-paging
ref="paging" ref="paging"
@ -38,123 +8,70 @@
@query="queryList" @query="queryList"
:fixed="false" :fixed="false"
height="100%" height="100%"
> > -->
<template v-for="(item, index) in dataList" :key="`unique_${index}`"> <template v-for="(item, index) in dataList" :key="`unique_${index}`">
<telesale-card :item="item" @handleCardClick="handleCardClick" /> <telesale-card :item="item" @handleCardClick="handleCardClick" />
</template> </template>
</z-paging> --> <!-- </z-paging> -->
</view> </view>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import positionTabs from './components/position-tabs.vue'
import DropdownPicker from '../orga-picker.vue'
import telesaleCard from './components/telesale-card.vue' import telesaleCard from './components/telesale-card.vue'
import dateDropdownPicker from '@/components/date-dropdown/daterange.vue'
import { useZPaging } from '@/hooks/useZPaging' import { useZPaging } from '@/hooks/useZPaging'
import { apiTeleClueList } from '@/api/clue' import { apiTeleClueList } from '@/api/clue'
import { apiOrganizationAllList } from '@/api/admin' import { getCurDate } from '@/utils/util'
import dropdownPicker from './components/dropdown-picker.vue'
const dropdownMenuList2 = { const form = ref({
showQuick: true, postId: 0,
title: '日期范围', createTimeStart: getCurDate('start'),
type: 'daterange', createTimeEnd: getCurDate('end'),
prop: 'god6' userId: ''
// 2022-01-012022-02-01 })
// value: { start: '2022-01-01', end: '2022-02-01' },
}
const postId = ref()
const dropdownMenuOrgList = ref([])
const queryParams = ref({ const queryParams = ref({
likeWork: '' likeWork: ''
}) })
const dataList = ref([]) const dataList = ref([{ id: 1, postId: '5,6', studentName: '张三' }])
const { paging, queryList, refresh, changeApi, setParams } = useZPaging( const { paging, queryList, refresh, changeApi, setParams } = useZPaging(
queryParams.value, queryParams.value,
apiTeleClueList, apiTeleClueList,
() => {} () => {}
) )
const dateTagFlag = ref() //
const confirm = (dateTag?: string) => {
console.log(form.value, dateTag)
dateTagFlag.value = dateTag
}
const resetPage = () => {}
//
const handleCardClick = (type: string, item: any) => { const handleCardClick = (type: string, item: any) => {
const { id } = item const { id } = item
console.log(form.value)
const params = {
...form.value,
dateTag: encodeURIComponent(dateTagFlag.value),
id,
type
}
const queryString = Object.keys(params)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
.join('&')
switch (type) { switch (type) {
case 'telesale': case 'telesale':
case 'recruitsale': case 'recruitsale':
uni.navigateTo({ uni.navigateTo({
url: '/bundle/pages/clue-list/index?id=' + id + '&type=' + type url: '/bundle/pages/clue-list/index?id=' + queryString
}) })
break break
default: default:
break break
} }
} }
//
const handleConfirm = (type: string, item) => {
switch (type) {
case 'organization':
console.log(item)
break
case 'date':
console.log(item)
break
case 'position':
console.log(item)
break
default:
break
}
}
//
const handleReset = (type: string) => {
switch (type) {
case 'organization':
break
case 'date':
break
case 'position':
break
default:
break
}
}
const fetchAllOrganizationList = async () => {
try {
const result = await apiOrganizationAllList()
dropdownMenuOrgList.value = renameFields(result)
console.log(dropdownMenuOrgList.value)
} catch (error) {}
}
const renameFields = (data: any[]): any[] => {
return data.map(item => {
const newItem = { ...item }
newItem.label = item.name
newItem.value = item.id
if (newItem.organizationVoList) {
newItem.children = renameFields(newItem.organizationVoList)
delete newItem.organizationVoList
}
if (newItem.userVos) {
newItem.userVos.forEach(item => {
item.label = item.username
item.value = item.id
})
newItem.children = newItem.children
? [...newItem.children, ...newItem.userVos]
: newItem.userVos
delete newItem.userVos
}
if (!newItem.children.length) {
newItem.disabled = true
}
return newItem
})
}
fetchAllOrganizationList()
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@ -6,51 +6,6 @@
@refresh-page="refreshPage" @refresh-page="refreshPage"
@confirm="confirm" @confirm="confirm"
/> />
<!-- <view class="bg-white">
<u-dropdown ref="uDropdownRef" menu-icon="arrow-down-fill">
<u-dropdown-item title="团队">
<view class="bg-white">
<selectDropdown
ref="teamDropdownRef"
:dropdownItem="dropdownMenuTeamList"
:dropdownIndex="1"
@reset="() => handleReset('team')"
@confirm="
(value, dropdownIndex) =>
handleConfirm('team', value, dropdownIndex)
"
/>
</view>
</u-dropdown-item>
<u-dropdown-item title="组织">
<view class="bg-white">
<selectDropdown
ref="orgDropdownRef"
:dropdownItem="dropdownMenuAllOrgaList"
:dropdownIndex="2"
@reset="() => handleReset('organization')"
@confirm="
(value, dropdownIndex) =>
handleConfirm('organization', value, dropdownIndex)
"
/>
</view>
</u-dropdown-item>
<u-dropdown-item title="日期">
<view class="bg-white p-[20rpx]">
<dateDropdownPicker
:dropdownItem="dropdownMenuDateList"
:dropdownIndex="3"
@reset="() => handleReset('date')"
@confirm="
(value, dropdownIndex, dateTag) =>
handleConfirm('date', value, dropdownIndex, dateTag)
"
/>
</view>
</u-dropdown-item>
</u-dropdown>
</view> -->
<filter-value :form="form" :activeTab="activeTab" :organizationList="organizationList" /> <filter-value :form="form" :activeTab="activeTab" :organizationList="organizationList" />
<data-overview ref="dataOverviewRef" /> <data-overview ref="dataOverviewRef" />
<converted-overview ref="convertedOverviewRef" /> <converted-overview ref="convertedOverviewRef" />
@ -65,12 +20,9 @@ import dataOverview from './components/data-overview.vue'
import convertedOverview from './components/converted-overview.vue' import convertedOverview from './components/converted-overview.vue'
import rank from './components/rank.vue' import rank from './components/rank.vue'
import clueStatus from './components/clue-status.vue' import clueStatus from './components/clue-status.vue'
import dateDropdownPicker from '@/components/date-dropdown/daterange.vue'
import dropdownPicker from '../dropdown-picker.vue' import dropdownPicker from '../dropdown-picker.vue'
import selectDropdown from '@/components/select-dropdown/index.vue'
import filterValue from '../filter-value.vue' import filterValue from '../filter-value.vue'
import { apiOrganizationByIdList, apiOrganizationList, apiOrganizationTeamList } from '@/api/admin' import { getCurDate } from '@/utils/util'
import { formateDate, getCurDate } from '@/utils/util'
import { AdminTabEnum } from '@/enums' import { AdminTabEnum } from '@/enums'
export interface IForm { export interface IForm {
@ -78,6 +30,7 @@ export interface IForm {
createTimeStart: string createTimeStart: string
createTimeEnd: string createTimeEnd: string
userId: string userId: string
postId?: number
} }
defineProps({ defineProps({
@ -87,44 +40,17 @@ defineProps({
} }
}) })
const dropdownPickerRef = ref<InstanceType<typeof dropdownPicker>>() const dropdownPickerRef = ref<InstanceType<typeof dropdownPicker>>()
const teamDropdownRef = ref<InstanceType<typeof selectDropdown>>()
const orgDropdownRef = ref<InstanceType<typeof selectDropdown>>()
const clueStatusRef = ref<InstanceType<typeof clueStatus>>() const clueStatusRef = ref<InstanceType<typeof clueStatus>>()
const rankRef = ref<InstanceType<typeof rank>>() const rankRef = ref<InstanceType<typeof rank>>()
const convertedOverviewRef = ref<InstanceType<typeof convertedOverview>>() const convertedOverviewRef = ref<InstanceType<typeof convertedOverview>>()
const dataOverviewRef = ref<InstanceType<typeof dataOverview>>() const dataOverviewRef = ref<InstanceType<typeof dataOverview>>()
const uDropdownRef = ref()
const organizationList = ref([]) const organizationList = ref([])
const defaultValue = ref() //
const form = ref<IForm>({ const form = ref<IForm>({
organizationId: null, organizationId: null,
createTimeStart: getCurDate('start'), createTimeStart: getCurDate('start'),
createTimeEnd: getCurDate('end'), createTimeEnd: getCurDate('end'),
userId: '' userId: ''
}) })
const dropdownMenuDateList = {
showQuick: true,
title: '日期范围',
type: 'daterange',
prop: 'god6',
value: { start: getCurDate('start', 'YYYY-MM-DD'), end: getCurDate('end', 'YYYY-MM-DD') }
}
const dropdownMenuTeamList = ref({
title: '下拉',
type: 'cell',
prop: 'god1',
showAll: true,
showIcon: true,
options: []
})
const dropdownMenuAllOrgaList = ref({
title: '下拉',
type: 'cell',
prop: 'god1',
showAll: true,
showIcon: true,
options: []
})
const menuIndexArr = ref<number[]>([]) const menuIndexArr = ref<number[]>([])
const refreshPage = () => { const refreshPage = () => {
fetchAllData() fetchAllData()
@ -133,55 +59,10 @@ const confirm = payload => {
menuIndexArr.value = Array.from(new Set([...menuIndexArr.value, payload.dropdownIndex])) menuIndexArr.value = Array.from(new Set([...menuIndexArr.value, payload.dropdownIndex]))
rankRef.value?.setSelectedIndexArr(menuIndexArr.value, payload?.dateTag) rankRef.value?.setSelectedIndexArr(menuIndexArr.value, payload?.dateTag)
} }
//
const handleConfirm = (type: string, item, dropdownIndex: number, dateTag?: string) => {
switch (type) {
case 'organization':
case 'team':
//
dropdownIndex == 1
? orgDropdownRef.value.clearSelect()
: teamDropdownRef.value.clearSelect()
form.value.organizationId = item.value
break
case 'date':
form.value.createTimeStart = formateDate(item.start, 'start')
form.value.createTimeEnd = formateDate(item.end, 'end')
break
default:
break
}
fetchAllData()
closeDropDown()
menuIndexArr.value = Array.from(new Set([...menuIndexArr.value, dropdownIndex]))
rankRef.value?.setSelectedIndexArr(menuIndexArr.value, dateTag)
}
//
const handleReset = (type: string) => {
switch (type) {
case 'organization':
break
case 'date':
form.value.createTimeStart = getCurDate('start')
form.value.createTimeEnd = getCurDate('end')
break
case 'team':
form.value.organizationId = defaultValue.value
break
default:
break
}
fetchAllData()
closeDropDown()
}
const closeDropDown = () => {
uDropdownRef.value.close()
}
const refreshData = () => { const refreshData = () => {
rankRef.value?.fetchData(form.value) rankRef.value?.fetchData(form.value)
} }
onMounted(async () => { onMounted(async () => {
// await fetchOrganizationList()
await dropdownPickerRef.value?.fetchOrganizationList() await dropdownPickerRef.value?.fetchOrganizationList()
organizationList.value = dropdownPickerRef.value?.organizationList organizationList.value = dropdownPickerRef.value?.organizationList
fetchAllData() fetchAllData()
@ -192,45 +73,5 @@ const fetchAllData = () => {
rankRef.value?.fetchData(form.value) rankRef.value?.fetchData(form.value)
clueStatusRef.value?.fetchData(form.value) clueStatusRef.value?.fetchData(form.value)
} }
//
const fetchOrganizationList = async () => {
try {
const result = await apiOrganizationList()
organizationList.value = result ?? []
if (result.length > 0) {
form.value.organizationId = result[0].id
defaultValue.value = result[0].id
}
} catch (error) {}
}
//
const fetchTeamList = async () => {
try {
const result = await apiOrganizationTeamList()
dropdownMenuTeamList.value.options =
result.map(item => {
return {
label: item.name,
value: item.id
}
}) ?? []
} catch (error) {}
}
//
const fetchAllOrganizationList = async () => {
try {
const result = await apiOrganizationByIdList()
dropdownMenuAllOrgaList.value.options =
result.map(item => {
return {
label: item.name,
value: item.id
}
}) ?? []
} catch (error) {}
}
// fetchTeamList()
// fetchAllOrganizationList()
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -115,7 +115,7 @@ export function useRank({ width, callback }: { width: number; callback?: () => v
// 岗位 // 岗位
export function usePositions() { export function usePositions() {
const positionList = ref() const positionList = ref()
const postId = ref() const postId = ref(0)
const fetchPositions = async () => { const fetchPositions = async () => {
try { try {
const result = await postLists() const result = await postLists()
@ -126,7 +126,7 @@ export function usePositions() {
value: item.id value: item.id
} }
}) })
if (positionList.value.length > 0) postId.value = positionList.value[0].id // if (positionList.value.length > 0) postId.value = positionList.value[0].id
} catch (error) {} } catch (error) {}
} }

View File

@ -24,6 +24,7 @@ export default {
round: 0, round: 0,
zoom: true, zoom: true,
bgColor: '', bgColor: '',
overlayOpacity: 0.5 overlayOpacity: 0.5,
top: 0
} }
} }

View File

@ -76,6 +76,10 @@ export const props = defineMixin({
overlayOpacity: { overlayOpacity: {
type: [Number, String], type: [Number, String],
default: () => defProps.popup.overlayOpacity default: () => defProps.popup.overlayOpacity
},
top: {
type: Number,
default: () => defProps.popup.top
} }
} }
}) })

View File

@ -1,310 +1,319 @@
<template> <template>
<view class="u-popup" :class="[customClass]"> <view class="u-popup" :class="[customClass]">
<u-overlay <u-overlay
:show="show" :show="show"
@click="overlayClick" @click="overlayClick"
v-if="overlay" v-if="overlay"
:zIndex="zIndex" :zIndex="zIndex"
:duration="overlayDuration" :duration="overlayDuration"
:customStyle="overlayStyle" :customStyle="overlayStyle"
:opacity="overlayOpacity" :opacity="overlayOpacity"
></u-overlay> ></u-overlay>
<u-transition <u-transition
:show="show" :show="show"
:customStyle="transitionStyle" :customStyle="transitionStyle"
:mode="position" :mode="position"
:duration="duration" :duration="duration"
@afterEnter="afterEnter" @afterEnter="afterEnter"
@click="clickHandler" @click="clickHandler"
> >
<view <view class="u-popup__content" :style="[contentStyle]" @tap.stop="noop">
class="u-popup__content" <u-status-bar v-if="safeAreaInsetTop"></u-status-bar>
:style="[contentStyle]" <slot></slot>
@tap.stop="noop" <view
> v-if="closeable"
<u-status-bar v-if="safeAreaInsetTop"></u-status-bar> @tap.stop="close"
<slot></slot> class="u-popup__content__close"
<view :class="['u-popup__content__close--' + closeIconPos]"
v-if="closeable" hover-class="u-popup__content__close--hover"
@tap.stop="close" hover-stay-time="150"
class="u-popup__content__close" >
:class="['u-popup__content__close--' + closeIconPos]" <u-icon name="close" color="#909399" size="18" bold></u-icon>
hover-class="u-popup__content__close--hover" </view>
hover-stay-time="150" <u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom>
> </view>
<u-icon </u-transition>
name="close" </view>
color="#909399"
size="18"
bold
></u-icon>
</view>
<u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom>
</view>
</u-transition>
</view>
</template> </template>
<script> <script>
import { props } from './props'; import { props } from './props'
import { mpMixin } from '../../libs/mixin/mpMixin'; import { mpMixin } from '../../libs/mixin/mpMixin'
import { mixin } from '../../libs/mixin/mixin'; import { mixin } from '../../libs/mixin/mixin'
import { addUnit, addStyle, deepMerge, sleep, sys } from '../../libs/function/index'; import { addUnit, addStyle, deepMerge, sleep, sys } from '../../libs/function/index'
/** /**
* popup 弹窗 * popup 弹窗
* @description 弹出层容器用于展示弹窗信息提示等内容支持上右和中部弹出组件只提供容器内部内容由用户自定义 * @description 弹出层容器用于展示弹窗信息提示等内容支持上右和中部弹出组件只提供容器内部内容由用户自定义
* @tutorial https://ijry.github.io/uview-plus/components/popup.html * @tutorial https://ijry.github.io/uview-plus/components/popup.html
* @property {Boolean} show 是否展示弹窗 (默认 false ) * @property {Boolean} show 是否展示弹窗 (默认 false )
* @property {Boolean} overlay 是否显示遮罩 默认 true * @property {Boolean} overlay 是否显示遮罩 默认 true
* @property {String} mode 弹出方向默认 'bottom' * @property {String} mode 弹出方向默认 'bottom'
* @property {String | Number} duration 动画时长单位ms 默认 300 * @property {String | Number} duration 动画时长单位ms 默认 300
* @property {String | Number} overlayDuration 遮罩层动画时长单位ms 默认 350 * @property {String | Number} overlayDuration 遮罩层动画时长单位ms 默认 350
* @property {Boolean} closeable 是否显示关闭图标默认 false * @property {Boolean} closeable 是否显示关闭图标默认 false
* @property {Object | String} overlayStyle 自定义遮罩的样式 * @property {Object | String} overlayStyle 自定义遮罩的样式
* @property {String | Number} overlayOpacity 遮罩透明度0-1之间默认 0.5 * @property {String | Number} overlayOpacity 遮罩透明度0-1之间默认 0.5
* @property {Boolean} closeOnClickOverlay 点击遮罩是否关闭弹窗 默认 true * @property {Boolean} closeOnClickOverlay 点击遮罩是否关闭弹窗 默认 true
* @property {String | Number} zIndex 层级 默认 10075 * @property {String | Number} zIndex 层级 默认 10075
* @property {Boolean} safeAreaInsetBottom 是否为iPhoneX留出底部安全距离 默认 true * @property {Boolean} safeAreaInsetBottom 是否为iPhoneX留出底部安全距离 默认 true
* @property {Boolean} safeAreaInsetTop 是否留出顶部安全距离状态栏高度 默认 false * @property {Boolean} safeAreaInsetTop 是否留出顶部安全距离状态栏高度 默认 false
* @property {String} closeIconPos 自定义关闭图标位置默认 'top-right' * @property {String} closeIconPos 自定义关闭图标位置默认 'top-right'
* @property {String | Number} round 圆角值默认 0 * @property {String | Number} round 圆角值默认 0
* @property {Boolean} zoom 当mode=center时 是否开启缩放默认 true * @property {Boolean} zoom 当mode=center时 是否开启缩放默认 true
* @property {Object} customStyle 组件的样式对象形式 * @property {Object} customStyle 组件的样式对象形式
* @event {Function} open 弹出层打开 * @event {Function} open 弹出层打开
* @event {Function} close 弹出层收起 * @event {Function} close 弹出层收起
* @example <u-popup v-model="show"><text>出淤泥而不染濯清涟而不妖</text></u-popup> * @example <u-popup v-model="show"><text>出淤泥而不染濯清涟而不妖</text></u-popup>
*/ */
export default { export default {
name: 'u-popup', name: 'u-popup',
mixins: [mpMixin, mixin, props], mixins: [mpMixin, mixin, props],
data() { data() {
return { return {
overlayDuration: this.duration + 50 overlayDuration: this.duration + 50
} }
}, },
watch: { watch: {
show(newValue, oldValue) { show(newValue, oldValue) {
if (newValue === true) { if (newValue === true) {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
const children = this.$children const children = this.$children
this.retryComputedComponentRect(children) this.retryComputedComponentRect(children)
// #endif // #endif
} }
} }
}, },
computed: { computed: {
transitionStyle() { transitionStyle() {
const style = { const style = {
zIndex: this.zIndex, zIndex: this.zIndex,
position: 'fixed', position: 'fixed',
display: 'flex', display: 'flex'
} }
style[this.mode] = 0 style[this.mode] = 0
if (this.mode === 'left') { if (this.mode === 'left') {
return deepMerge(style, { return deepMerge(style, {
bottom: 0, bottom: 0,
top: 0, top: 0
}) })
} else if (this.mode === 'right') { } else if (this.mode === 'right') {
return deepMerge(style, { return deepMerge(style, {
bottom: 0, bottom: 0,
top: 0, top: 0
}) })
} else if (this.mode === 'top') { } else if (this.mode === 'top') {
return deepMerge(style, { return deepMerge(style, {
left: 0, left: 0,
right: 0 right: 0,
}) top: this.top + 'px'
} else if (this.mode === 'bottom') { })
return deepMerge(style, { } else if (this.mode === 'bottom') {
left: 0, return deepMerge(style, {
right: 0, left: 0,
}) right: 0
} else if (this.mode === 'center') { })
return deepMerge(style, { } else if (this.mode === 'center') {
alignItems: 'center', return deepMerge(style, {
'justify-content': 'center', alignItems: 'center',
top: 0, 'justify-content': 'center',
left: 0, top: 0,
right: 0, left: 0,
bottom: 0 right: 0,
}) bottom: 0
} })
}, }
contentStyle() { },
const style = {} contentStyle() {
// safeAreaInsets const style = {}
// 使cssnvuecssiPhoneX // safeAreaInsets
const { // 使cssnvuecssiPhoneX
safeAreaInsets const { safeAreaInsets } = sys()
} = sys() if (this.mode !== 'center') {
if (this.mode !== 'center') { style.flex = 1
style.flex = 1 }
} // transparent
// transparent if (this.bgColor) {
if (this.bgColor) { style.backgroundColor = this.bgColor
style.backgroundColor = this.bgColor }
} if (this.round) {
if(this.round) { const value = addUnit(this.round)
const value = addUnit(this.round) if (this.mode === 'top') {
if(this.mode === 'top') { style.borderBottomLeftRadius = value
style.borderBottomLeftRadius = value style.borderBottomRightRadius = value
style.borderBottomRightRadius = value } else if (this.mode === 'bottom') {
} else if(this.mode === 'bottom') { style.borderTopLeftRadius = value
style.borderTopLeftRadius = value style.borderTopRightRadius = value
style.borderTopRightRadius = value } else if (this.mode === 'center') {
} else if(this.mode === 'center') { style.borderRadius = value
style.borderRadius = value }
} }
} return deepMerge(style, addStyle(this.customStyle))
return deepMerge(style, addStyle(this.customStyle)) },
}, position() {
position() { if (this.mode === 'center') {
if (this.mode === 'center') { return this.zoom ? 'fade-zoom' : 'fade'
return this.zoom ? 'fade-zoom' : 'fade' }
} if (this.mode === 'left') {
if (this.mode === 'left') { return 'slide-left'
return 'slide-left' }
} if (this.mode === 'right') {
if (this.mode === 'right') { return 'slide-right'
return 'slide-right' }
} if (this.mode === 'bottom') {
if (this.mode === 'bottom') { return 'slide-up'
return 'slide-up' }
} if (this.mode === 'top') {
if (this.mode === 'top') { return 'slide-down'
return 'slide-down' }
} }
}, },
}, emits: ['open', 'close', 'click', 'update:show'],
emits: ["open", "close", "click", "update:show"], methods: {
methods: { //
// overlayClick() {
overlayClick() { if (this.closeOnClickOverlay) {
if (this.closeOnClickOverlay) { this.$emit('update:show', false)
this.$emit('update:show', false) this.$emit('close')
this.$emit('close') }
} },
}, close(e) {
close(e) { this.$emit('update:show', false)
this.$emit('update:show', false) this.$emit('close')
this.$emit('close') },
}, afterEnter() {
afterEnter() { this.$emit('open')
this.$emit('open') },
}, clickHandler() {
clickHandler() { // u-transition
// u-transition if (this.mode === 'center') {
if(this.mode === 'center') { this.overlayClick()
this.overlayClick() }
} this.$emit('click')
this.$emit('click') },
}, // #ifdef MP-WEIXIN
// #ifdef MP-WEIXIN retryComputedComponentRect(children) {
retryComputedComponentRect(children) { //
// const names = [
const names = ['u-calendar-month', 'u-album', 'u-collapse-item', 'u-dropdown', 'u-index-item', 'u-index-list', 'u-calendar-month',
'u-line-progress', 'u-list-item', 'u-rate', 'u-read-more', 'u-row', 'u-row-notice', 'u-scroll-list', 'u-album',
'u-skeleton', 'u-slider', 'u-steps-item', 'u-sticky', 'u-subsection', 'u-swipe-action-item', 'u-tabbar', 'u-collapse-item',
'u-tabs', 'u-tooltip' 'u-dropdown',
] 'u-index-item',
// 'u-index-list',
for (let i = 0; i < children.length; i++) { 'u-line-progress',
const child = children[i] 'u-list-item',
// 'u-rate',
const grandChild = child.$children 'u-read-more',
// init 'u-row',
if (names.includes(child.$options.name) && typeof child?.init === 'function') { 'u-row-notice',
// 'u-scroll-list',
sleep(50).then(() => { 'u-skeleton',
child.init() 'u-slider',
}) 'u-steps-item',
} 'u-sticky',
// 'u-subsection',
if (grandChild.length) { 'u-swipe-action-item',
this.retryComputedComponentRect(grandChild) 'u-tabbar',
} 'u-tabs',
} 'u-tooltip'
} ]
// #endif //
} for (let i = 0; i < children.length; i++) {
} const child = children[i]
//
const grandChild = child.$children
// init
if (names.includes(child.$options.name) && typeof child?.init === 'function') {
//
sleep(50).then(() => {
child.init()
})
}
//
if (grandChild.length) {
this.retryComputedComponentRect(grandChild)
}
}
}
// #endif
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "../../libs/css/components.scss"; @import '../../libs/css/components.scss';
$u-popup-flex:1 !default; $u-popup-flex: 1 !default;
$u-popup-content-background-color: #fff !default; $u-popup-content-background-color: #fff !default;
.u-popup { .u-popup {
flex: $u-popup-flex; flex: $u-popup-flex;
&__content { &__content {
background-color: $u-popup-content-background-color; background-color: $u-popup-content-background-color;
position: relative; position: relative;
&--round-top { &--round-top {
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
} }
&--round-left { &--round-left {
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 10px; border-top-right-radius: 10px;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
} }
&--round-right { &--round-right {
border-top-left-radius: 10px; border-top-left-radius: 10px;
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
} }
&--round-bottom { &--round-bottom {
border-top-left-radius: 10px; border-top-left-radius: 10px;
border-top-right-radius: 10px; border-top-right-radius: 10px;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
} }
&--round-center { &--round-center {
border-top-left-radius: 10px; border-top-left-radius: 10px;
border-top-right-radius: 10px; border-top-right-radius: 10px;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
} }
&__close { &__close {
position: absolute; position: absolute;
&--hover { &--hover {
opacity: 0.4; opacity: 0.4;
} }
} }
&__close--top-left { &__close--top-left {
top: 15px; top: 15px;
left: 15px; left: 15px;
} }
&__close--top-right { &__close--top-right {
top: 15px; top: 15px;
right: 15px; right: 15px;
} }
&__close--bottom-left { &__close--bottom-left {
bottom: 15px; bottom: 15px;
left: 15px; left: 15px;
} }
&__close--bottom-right { &__close--bottom-right {
right: 15px; right: 15px;
bottom: 15px; bottom: 15px;
} }
} }
} }
</style> </style>