mirror of
https://github.com/fugary/simple-element-plus-template.git
synced 2026-09-11 09:23:53 +00:00
308 lines
7.8 KiB
JavaScript
308 lines
7.8 KiB
JavaScript
import { provide, inject, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue'
|
|
import { isFunction, isNumber, uniqueId } from 'lodash-es'
|
|
import { useGlobalSearchParamStore } from '@/stores/GlobalSearchParamStore'
|
|
import { $coreHideLoading, $coreShowLoading } from '@/utils'
|
|
import { GLOBAL_LOADING } from '@/config'
|
|
import Sortable from 'sortablejs'
|
|
|
|
const defaultPageProcessor = (searchResult, searchParam) => {
|
|
const resultData = searchResult?.resultData || searchResult
|
|
const pageObj = searchResult?.page || resultData?.page || searchResult?.pageSetting || resultData?.pageSetting
|
|
if (pageObj && searchParam.value) {
|
|
if (searchParam.value.page) {
|
|
Object.assign(searchParam.value.page, pageObj)
|
|
} else if (searchParam.value.pageSetting) {
|
|
Object.assign(searchParam.value.pageSetting, pageObj)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 通用搜索表格表单封装
|
|
* @param {CommonTableAndSearchForm} param 参数
|
|
* @return {CommonTableAndSearchResult} 返回数据
|
|
*/
|
|
export const useTableAndSearchForm = ({
|
|
searchMethod,
|
|
defaultParam = {},
|
|
dataProcessor = searchResult => searchResult.resultData,
|
|
pageProcessor = defaultPageProcessor,
|
|
saveParam = true
|
|
}) => {
|
|
const globalSearchParamStore = useGlobalSearchParamStore()
|
|
const tableData = ref([])
|
|
const loading = ref(false)
|
|
const searchParam = ref(saveParam ? globalSearchParamStore.getCurrentParam(defaultParam) : defaultParam)
|
|
const searchTableItems = async (pageNumber, newParams = {}, saveConfig) => {
|
|
if (isNumber(pageNumber) && searchParam.value) {
|
|
if (searchParam.value.page) {
|
|
searchParam.value.page.pageNumber = pageNumber
|
|
} else if (searchParam.value.pageSetting) {
|
|
searchParam.value.pageSetting.pageNumber = pageNumber
|
|
}
|
|
}
|
|
loading.value = true
|
|
saveParam && globalSearchParamStore.saveCurrentParam(searchParam.value, saveConfig)
|
|
const searchResult = await searchMethod({ ...searchParam.value, ...newParams })
|
|
.finally(() => { loading.value = false })
|
|
loading.value = false
|
|
if (searchResult.success && searchResult.resultData) {
|
|
tableData.value = isFunction(dataProcessor) && dataProcessor?.(searchResult, searchParam)
|
|
pageProcessor?.(searchResult, searchParam)
|
|
}
|
|
return searchResult
|
|
}
|
|
return {
|
|
tableData,
|
|
loading,
|
|
searchParam,
|
|
searchMethod: searchTableItems
|
|
}
|
|
}
|
|
|
|
export const useInitLoadOnce = (loader, config = {}) => {
|
|
const initLoading = ref(false)
|
|
const initLoadOnce = async () => {
|
|
if (!initLoading.value) {
|
|
try {
|
|
initLoading.value = true
|
|
if (config.loading ?? GLOBAL_LOADING) {
|
|
$coreShowLoading()
|
|
}
|
|
await loader()
|
|
} finally {
|
|
initLoading.value = false
|
|
if (config.loading ?? GLOBAL_LOADING) {
|
|
$coreHideLoading()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
initLoading,
|
|
initLoadOnce
|
|
}
|
|
}
|
|
|
|
export const useDateStr = (watchFn) => {
|
|
const dateStr = ref(new Date().getTime())
|
|
watchFn && watch(watchFn, (update) => {
|
|
if (update) {
|
|
dateStr.value = new Date().getTime()
|
|
}
|
|
})
|
|
return { dateStr }
|
|
}
|
|
|
|
export const useGlobalSaveSearchParam = (defaultParam) => {
|
|
const globalSearchParamStore = useGlobalSearchParamStore()
|
|
const searchParam = ref(globalSearchParamStore.getCurrentParam(defaultParam))
|
|
return {
|
|
searchParam,
|
|
/**
|
|
* @param [path]
|
|
*/
|
|
saveSearchParam: (path) => {
|
|
globalSearchParamStore.saveCurrentParam(searchParam.value, path)
|
|
}
|
|
}
|
|
}
|
|
|
|
export const useManagedArrayItems = () => {
|
|
const managedItems = ref([])
|
|
const context = ref(false)
|
|
const startContext = () => (context.value = true)
|
|
const pushItem = (item) => {
|
|
const index = managedItems.value.findIndex(it => item.id === it.id)
|
|
if (index < 0) {
|
|
managedItems.value.push(item)
|
|
return item
|
|
} else {
|
|
return goToItem(index)
|
|
}
|
|
}
|
|
const goToItem = index => {
|
|
let result = null
|
|
if (index > -1 && (result = managedItems.value[index])) {
|
|
context.value = true
|
|
managedItems.value = managedItems.value.slice(0, index + 1)
|
|
}
|
|
return result
|
|
}
|
|
const clearItems = () => {
|
|
if (!context.value) {
|
|
managedItems.value = []
|
|
}
|
|
context.value = false
|
|
}
|
|
return {
|
|
managedItems,
|
|
startContext,
|
|
pushItem,
|
|
goToItem,
|
|
clearItems
|
|
}
|
|
}
|
|
|
|
export const useSortableParams = (params, selector, moveCls = '.move-indicator') => {
|
|
let sortable = null
|
|
const sortableRef = ref()
|
|
const dragging = ref(false)
|
|
const hoverIndex = ref(-1)
|
|
|
|
const initSortable = () => {
|
|
let el = sortableRef.value?.$el || sortableRef.value
|
|
if (el && !sortable) {
|
|
const tbody = el.querySelector('tbody')
|
|
if (tbody) {
|
|
el = tbody
|
|
}
|
|
sortable = new Sortable(el, {
|
|
animation: 150,
|
|
draggable: selector,
|
|
handle: moveCls,
|
|
onStart () {
|
|
hoverIndex.value = -1
|
|
dragging.value = true
|
|
},
|
|
onEnd (event) {
|
|
const { oldIndex, newIndex } = event
|
|
params.value.splice(newIndex, 0, params.value.splice(oldIndex, 1)[0]) // 插入到 newIndex 位置
|
|
setTimeout(() => {
|
|
dragging.value = false
|
|
hoverIndex.value = newIndex
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
const destroySortable = () => {
|
|
if (sortable) {
|
|
sortable.destroy()
|
|
sortable = null
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
initSortable()
|
|
})
|
|
|
|
watch(() => sortableRef.value, (val) => {
|
|
if (val) {
|
|
initSortable()
|
|
} else {
|
|
destroySortable()
|
|
}
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
destroySortable()
|
|
})
|
|
return {
|
|
dragging,
|
|
hoverIndex,
|
|
sortableRef
|
|
}
|
|
}
|
|
|
|
export const useRenderKey = () => {
|
|
const renderKeyMap = new WeakMap()
|
|
|
|
function renderKey (param) {
|
|
if (param.id != null) {
|
|
return `param-${param.id}`
|
|
}
|
|
if (!renderKeyMap.has(param)) {
|
|
renderKeyMap.set(param, uniqueId())
|
|
}
|
|
return `param-tmp-${renderKeyMap.get(param)}`
|
|
}
|
|
|
|
return {
|
|
renderKey
|
|
}
|
|
}
|
|
|
|
export const useProvideDataLoading = (loadingKey = 'dataLoading') => {
|
|
const dataLoading = ref(false)
|
|
const startLoading = (config = { delay: 100 }) => {
|
|
if (!dataLoading.value) {
|
|
dataLoading.value = true
|
|
$coreShowLoading(config)
|
|
}
|
|
}
|
|
provide(loadingKey, { dataLoading, startLoading })
|
|
return {
|
|
dataLoading,
|
|
startLoading
|
|
}
|
|
}
|
|
|
|
export const useInjectDataLoading = (loadingKey = 'dataLoading') => {
|
|
const { dataLoading, startLoading } = inject(loadingKey,
|
|
{ dataLoading: ref(false), startLoading: () => {} })
|
|
const endLoading = () => {
|
|
if (dataLoading?.value) {
|
|
setTimeout(() => {
|
|
$coreHideLoading()
|
|
dataLoading.value = false
|
|
})
|
|
} else {
|
|
$coreHideLoading()
|
|
}
|
|
}
|
|
return {
|
|
startLoading,
|
|
endLoading
|
|
}
|
|
}
|
|
|
|
export const useContextMenu = () => {
|
|
const showContextMenu = ref(false)
|
|
const contextMenuRef = ref(null)
|
|
const contextMenuHandlers = ref([])
|
|
const contextMenuItem = ref(null)
|
|
const contextMenuDropdownRef = ref()
|
|
|
|
const handleContextMenuVisibleChange = (visible) => {
|
|
if (!visible) {
|
|
showContextMenu.value = false
|
|
}
|
|
}
|
|
|
|
const handleRequestContextMenu = (event, item, buttons) => {
|
|
showContextMenu.value = false
|
|
contextMenuItem.value = item
|
|
contextMenuHandlers.value = buttons || []
|
|
contextMenuRef.value = {
|
|
getBoundingClientRect () {
|
|
return {
|
|
width: 0,
|
|
height: 0,
|
|
top: event.clientY,
|
|
bottom: event.clientY,
|
|
left: event.clientX,
|
|
right: event.clientX
|
|
}
|
|
}
|
|
}
|
|
nextTick(() => {
|
|
showContextMenu.value = true
|
|
nextTick(() => {
|
|
contextMenuDropdownRef.value?.handleOpen?.()
|
|
})
|
|
})
|
|
}
|
|
|
|
return {
|
|
showContextMenu,
|
|
contextMenuRef,
|
|
contextMenuHandlers,
|
|
contextMenuItem,
|
|
contextMenuDropdownRef,
|
|
handleContextMenuVisibleChange,
|
|
handleRequestContextMenu
|
|
}
|
|
}
|