1.将部门修改为渠道,并且所有dice_表关联渠道表
2.将所有配置表,记录表设置关联渠道 3.优化后台页面设置
This commit is contained in:
6
saiadmin-artd/src/composables/useChannelConfigScope.ts
Normal file
6
saiadmin-artd/src/composables/useChannelConfigScope.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/** @deprecated 请使用 useChannelDeptScope */
|
||||
export {
|
||||
DEFAULT_CHANNEL_ID,
|
||||
useChannelDeptScope as useChannelConfigScope,
|
||||
type ChannelTreeNode
|
||||
} from './useChannelDeptScope'
|
||||
230
saiadmin-artd/src/composables/useChannelDeptScope.ts
Normal file
230
saiadmin-artd/src/composables/useChannelDeptScope.ts
Normal file
@@ -0,0 +1,230 @@
|
||||
import type { InjectionKey, Ref, ComputedRef } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import deptApi from '@/api/system/dept'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { isConfigChannelRoute, isRoleChannelRoute, isSuperAdminUser } from '@/utils/channelLayout'
|
||||
|
||||
export interface ChannelTreeNode {
|
||||
id: number
|
||||
label: string
|
||||
children?: ChannelTreeNode[]
|
||||
}
|
||||
|
||||
/** 默认配置模板(dept_id = 0) */
|
||||
export const DEFAULT_CHANNEL_ID = 0
|
||||
|
||||
export interface ChannelDeptScopeContext {
|
||||
treeData: Ref<ChannelTreeNode[]>
|
||||
selectedDeptId: Ref<number>
|
||||
loadingChannels: Ref<boolean>
|
||||
isSuperAdmin: Ref<boolean>
|
||||
selectedDeptLabel: Ref<string>
|
||||
deptQueryParams: ComputedRef<{ dept_id: number }>
|
||||
isConfigScope: ComputedRef<boolean>
|
||||
showDefaultTemplate: ComputedRef<boolean>
|
||||
}
|
||||
|
||||
export const CHANNEL_DEPT_SCOPE_KEY: InjectionKey<ChannelDeptScopeContext> =
|
||||
Symbol('channelDeptScope')
|
||||
|
||||
export function provideChannelDeptScope(ctx: ChannelDeptScopeContext) {
|
||||
provide(CHANNEL_DEPT_SCOPE_KEY, ctx)
|
||||
}
|
||||
|
||||
export function useInjectedChannelDept(): ChannelDeptScopeContext | null {
|
||||
return inject(CHANNEL_DEPT_SCOPE_KEY, null)
|
||||
}
|
||||
|
||||
/** 超管全局渠道栏:创建并 provide 渠道上下文 */
|
||||
export function useChannelDeptScope() {
|
||||
const route = useRoute()
|
||||
const userStore = useUserStore()
|
||||
const treeData = ref<ChannelTreeNode[]>([])
|
||||
const selectedDeptId = ref<number>(DEFAULT_CHANNEL_ID)
|
||||
const loadingChannels = ref(false)
|
||||
|
||||
const isConfigScope = computed(() => isConfigChannelRoute(route))
|
||||
const isRoleScope = computed(() => isRoleChannelRoute(route))
|
||||
const showDefaultTemplate = computed(() => isConfigScope.value || isRoleScope.value)
|
||||
|
||||
const isSuperAdmin = computed(() => isSuperAdminUser())
|
||||
|
||||
const selectedDeptLabel = computed(() => {
|
||||
const find = (nodes: ChannelTreeNode[]): string => {
|
||||
for (const n of nodes) {
|
||||
if (n.id === selectedDeptId.value) {
|
||||
return n.label
|
||||
}
|
||||
if (n.children?.length) {
|
||||
const sub = find(n.children)
|
||||
if (sub) return sub
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
return find(treeData.value)
|
||||
})
|
||||
|
||||
const deptQueryParams = computed(() => {
|
||||
const id = selectedDeptId.value
|
||||
if (!showDefaultTemplate.value && id <= 0) {
|
||||
return { dept_id: 0 }
|
||||
}
|
||||
return { dept_id: id }
|
||||
})
|
||||
|
||||
const loadChannels = async () => {
|
||||
loadingChannels.value = true
|
||||
try {
|
||||
const list = await deptApi.accessDept()
|
||||
const channels = Array.isArray(list) ? list : []
|
||||
const nodes: ChannelTreeNode[] = channels.map((item: Record<string, unknown>) => ({
|
||||
id: Number(item.id ?? item.value),
|
||||
label: String(item.label ?? item.name ?? item.id)
|
||||
}))
|
||||
if (isSuperAdmin.value) {
|
||||
if (showDefaultTemplate.value) {
|
||||
treeData.value = [{ id: DEFAULT_CHANNEL_ID, label: '' }, ...nodes]
|
||||
if (!treeData.value.some((n) => n.id === selectedDeptId.value)) {
|
||||
selectedDeptId.value = DEFAULT_CHANNEL_ID
|
||||
}
|
||||
} else {
|
||||
treeData.value = nodes
|
||||
if (nodes.length > 0) {
|
||||
const valid = nodes.some((n) => n.id === selectedDeptId.value)
|
||||
if (!valid || selectedDeptId.value <= 0) {
|
||||
selectedDeptId.value = nodes[0].id
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
treeData.value = nodes
|
||||
if (nodes.length > 0) {
|
||||
selectedDeptId.value = nodes[0].id
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
loadingChannels.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleChannelClick = (data: ChannelTreeNode) => {
|
||||
selectedDeptId.value = Number(data.id)
|
||||
}
|
||||
|
||||
const ctx: ChannelDeptScopeContext = {
|
||||
treeData,
|
||||
selectedDeptId,
|
||||
loadingChannels,
|
||||
isSuperAdmin,
|
||||
selectedDeptLabel,
|
||||
deptQueryParams,
|
||||
isConfigScope,
|
||||
showDefaultTemplate
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadChannels()
|
||||
})
|
||||
|
||||
return {
|
||||
...ctx,
|
||||
loadChannels,
|
||||
handleChannelClick,
|
||||
provideScope: () => provideChannelDeptScope(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
/** 将当前选中渠道写入列表查询参数并刷新 */
|
||||
export function bindChannelDeptToSearchParams(
|
||||
searchParams: Record<string, unknown>,
|
||||
refresh: () => void,
|
||||
options?: { immediate?: boolean; enabled?: boolean }
|
||||
) {
|
||||
const channel = useInjectedChannelDept()
|
||||
if (!channel || options?.enabled === false) {
|
||||
return
|
||||
}
|
||||
|
||||
const apply = (deptId: number) => {
|
||||
if (!channel.showDefaultTemplate.value && deptId <= 0) {
|
||||
return
|
||||
}
|
||||
searchParams.dept_id = deptId
|
||||
refresh()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => channel.selectedDeptId.value,
|
||||
(deptId) => apply(deptId),
|
||||
{ immediate: options?.immediate ?? true }
|
||||
)
|
||||
}
|
||||
|
||||
/** 工作台等非 useTable 页面:渠道切换时重新拉数 */
|
||||
export function useChannelDeptReload(loadFn: () => void | Promise<void>) {
|
||||
const channel = useInjectedChannelDept()
|
||||
if (!channel) {
|
||||
onMounted(() => {
|
||||
void loadFn()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
watch(
|
||||
() => channel.selectedDeptId.value,
|
||||
(deptId) => {
|
||||
if (!channel.showDefaultTemplate.value && deptId <= 0) {
|
||||
return
|
||||
}
|
||||
void loadFn()
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
}
|
||||
|
||||
/** 请求参数:业务页附带 dept_id;渠道管理员固定本渠道 */
|
||||
export function getChannelDeptRequestParams(): { dept_id?: number } {
|
||||
const channel = useInjectedChannelDept()
|
||||
if (channel?.isSuperAdmin.value) {
|
||||
const deptId = channel.selectedDeptId.value
|
||||
if (!channel.showDefaultTemplate.value && deptId <= 0) {
|
||||
return {}
|
||||
}
|
||||
if (deptId > 0) {
|
||||
return { dept_id: deptId }
|
||||
}
|
||||
if (channel.showDefaultTemplate.value) {
|
||||
return { dept_id: deptId }
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
const userStore = useUserStore()
|
||||
const dept = userStore.info?.department
|
||||
if (dept && Number(dept.id) > 0) {
|
||||
return { dept_id: Number(dept.id) }
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
/** 保存/更新时附带 dept_id(优先渠道栏选中值,其次表单/行数据中的 dept_id) */
|
||||
export function withChannelDeptParams<T extends Record<string, unknown>>(payload: T): T {
|
||||
const extra = getChannelDeptRequestParams()
|
||||
if ('dept_id' in extra) {
|
||||
return { ...payload, ...extra }
|
||||
}
|
||||
const rowDeptId = payload.dept_id
|
||||
if (rowDeptId !== undefined && rowDeptId !== null && rowDeptId !== '') {
|
||||
const num = Number(rowDeptId)
|
||||
if (num > 0) {
|
||||
return { ...payload, dept_id: num }
|
||||
}
|
||||
}
|
||||
const channel = useInjectedChannelDept()
|
||||
if (channel && channel.selectedDeptId.value > 0) {
|
||||
return { ...payload, dept_id: channel.selectedDeptId.value }
|
||||
}
|
||||
return payload
|
||||
}
|
||||
Reference in New Issue
Block a user