feat(permission): replace OA roles with post-bound roles and assignee posts
Unify effective roles via post-role bindings, remove dedicated OA role UI, and update OA assignee resolution plus related SQL/docs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
a3c73d76bb
commit
06db3bc966
66 files changed
+55337
-38647
No files matched your search
@@ -161,7 +161,7 @@ function buildConfirmationKitChildren() {
|
||||
|
||||
export const confirmationKitDragRule = {
|
||||
menu: 'kit' as const,
|
||||
icon: 'icon-user',
|
||||
icon: 'icon-idcard',
|
||||
label: '转正',
|
||||
name: 'confirmationKit',
|
||||
input: false,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import FcDesigner from '@form-create/designer'
|
||||
import OaConfirmationKit from '@/components/oa-approval/OaConfirmationKit.vue'
|
||||
import { ensureOaKitMenu } from '@/utils/oa-form-create-kit-menu'
|
||||
import { confirmationKitDragRule } from '@/utils/oa-confirmation-kit-rule'
|
||||
|
||||
const FLAG = '__oaConfirmationKitConfigured'
|
||||
@@ -9,14 +10,7 @@ export function setupOaConfirmationKit(formCreate?: {
|
||||
}) {
|
||||
if ((FcDesigner as any)[FLAG]) return
|
||||
|
||||
// kit 菜单可能已由请假套件注册;幂等再调一次无妨
|
||||
if (typeof FcDesigner.addMenu === 'function') {
|
||||
try {
|
||||
FcDesigner.addMenu({ name: 'kit', title: '套件', list: [] })
|
||||
} catch {
|
||||
/* already */
|
||||
}
|
||||
}
|
||||
ensureOaKitMenu()
|
||||
|
||||
FcDesigner.component('confirmationKit', OaConfirmationKit)
|
||||
if (typeof formCreate?.component === 'function') {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import FcDesigner from '@form-create/designer'
|
||||
|
||||
const FLAG = '__oaKitMenuConfigured'
|
||||
|
||||
/**
|
||||
* 确保「套件」左侧菜单只注册一次。
|
||||
* 全局 FcDesigner.addMenu 会无条件 push,多套件各自 addMenu 会导致同名分组重复,
|
||||
* 进而 appendMenuItem 把每个拖拽规则挂到所有同名分组上(N 套件 × N 分组)。
|
||||
*/
|
||||
export function ensureOaKitMenu() {
|
||||
if ((FcDesigner as any)[FLAG]) return
|
||||
if (typeof FcDesigner.addMenu === 'function') {
|
||||
FcDesigner.addMenu({ name: 'kit', title: '套件', list: [] })
|
||||
}
|
||||
;(FcDesigner as any)[FLAG] = true
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import FcDesigner from '@form-create/designer'
|
||||
import OaLeaveKit from '@/components/oa-approval/OaLeaveKit.vue'
|
||||
import { ensureOaKitMenu } from '@/utils/oa-form-create-kit-menu'
|
||||
import { leaveKitDragRule } from '@/utils/oa-leave-kit-rule'
|
||||
|
||||
const FLAG = '__oaLeaveKitConfigured'
|
||||
@@ -7,9 +8,7 @@ const FLAG = '__oaLeaveKitConfigured'
|
||||
export function setupOaLeaveKit(formCreate?: { component?: (name: string, c: unknown) => void }) {
|
||||
if ((FcDesigner as any)[FLAG]) return
|
||||
|
||||
if (typeof FcDesigner.addMenu === 'function') {
|
||||
FcDesigner.addMenu({ name: 'kit', title: '套件', list: [] })
|
||||
}
|
||||
ensureOaKitMenu()
|
||||
|
||||
FcDesigner.component('leaveKit', OaLeaveKit)
|
||||
if (typeof formCreate?.component === 'function') {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import FcDesigner from '@form-create/designer'
|
||||
import OaOvertimeKit from '@/components/oa-approval/OaOvertimeKit.vue'
|
||||
import { ensureOaKitMenu } from '@/utils/oa-form-create-kit-menu'
|
||||
import { overtimeKitDragRule } from '@/utils/oa-overtime-kit-rule'
|
||||
|
||||
const FLAG = '__oaOvertimeKitConfigured'
|
||||
@@ -7,13 +8,7 @@ const FLAG = '__oaOvertimeKitConfigured'
|
||||
export function setupOaOvertimeKit(formCreate?: { component?: (name: string, c: unknown) => void }) {
|
||||
if ((FcDesigner as any)[FLAG]) return
|
||||
|
||||
if (typeof FcDesigner.addMenu === 'function') {
|
||||
try {
|
||||
FcDesigner.addMenu({ name: 'kit', title: '套件', list: [] })
|
||||
} catch {
|
||||
/* kit menu may already exist */
|
||||
}
|
||||
}
|
||||
ensureOaKitMenu()
|
||||
|
||||
FcDesigner.component('overtimeKit', OaOvertimeKit)
|
||||
if (typeof formCreate?.component === 'function') {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import FcDesigner from '@form-create/designer'
|
||||
import OaResignationKit from '@/components/oa-approval/OaResignationKit.vue'
|
||||
import { ensureOaKitMenu } from '@/utils/oa-form-create-kit-menu'
|
||||
import { resignationKitDragRule } from '@/utils/oa-resignation-kit-rule'
|
||||
|
||||
const FLAG = '__oaResignationKitConfigured'
|
||||
@@ -9,13 +10,7 @@ export function setupOaResignationKit(formCreate?: {
|
||||
}) {
|
||||
if ((FcDesigner as any)[FLAG]) return
|
||||
|
||||
if (typeof FcDesigner.addMenu === 'function') {
|
||||
try {
|
||||
FcDesigner.addMenu({ name: 'kit', title: '套件', list: [] })
|
||||
} catch {
|
||||
/* already */
|
||||
}
|
||||
}
|
||||
ensureOaKitMenu()
|
||||
|
||||
FcDesigner.component('resignationKit', OaResignationKit)
|
||||
if (typeof formCreate?.component === 'function') {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import FcDesigner from '@form-create/designer'
|
||||
import OaTripKit from '@/components/oa-approval/OaTripKit.vue'
|
||||
import { ensureOaKitMenu } from '@/utils/oa-form-create-kit-menu'
|
||||
import { tripKitDragRule } from '@/utils/oa-trip-kit-rule'
|
||||
|
||||
const FLAG = '__oaTripKitConfigured'
|
||||
@@ -7,13 +8,7 @@ const FLAG = '__oaTripKitConfigured'
|
||||
export function setupOaTripKit(formCreate?: { component?: (name: string, c: unknown) => void }) {
|
||||
if ((FcDesigner as any)[FLAG]) return
|
||||
|
||||
if (typeof FcDesigner.addMenu === 'function') {
|
||||
try {
|
||||
FcDesigner.addMenu({ name: 'kit', title: '套件', list: [] })
|
||||
} catch {
|
||||
/* kit menu may already exist */
|
||||
}
|
||||
}
|
||||
ensureOaKitMenu()
|
||||
|
||||
FcDesigner.component('tripKit', OaTripKit)
|
||||
if (typeof formCreate?.component === 'function') {
|
||||
|
||||
@@ -96,7 +96,7 @@ function buildLeaveKitChildren() {
|
||||
/** FormCreate Designer DragRule:请假套件 */
|
||||
export const leaveKitDragRule = {
|
||||
menu: 'kit' as const,
|
||||
icon: 'icon-date',
|
||||
icon: 'icon-askforleave',
|
||||
label: '请假',
|
||||
name: 'leaveKit',
|
||||
input: false,
|
||||
|
||||
@@ -84,7 +84,7 @@ function buildOvertimeKitChildren() {
|
||||
/** FormCreate Designer DragRule:加班套件 */
|
||||
export const overtimeKitDragRule = {
|
||||
menu: 'kit' as const,
|
||||
icon: 'icon-date',
|
||||
icon: 'icon-time',
|
||||
label: '加班',
|
||||
name: 'overtimeKit',
|
||||
input: false,
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/** 加班套件运行时:时长仅手动填写,补齐数字框左对齐 */
|
||||
/** 加班套件运行时:时长仅手动填写,补齐数字框左对齐;加班人默认当前登录人 */
|
||||
|
||||
import {
|
||||
buildCurrentOwnerPerson,
|
||||
type OwnerUserSnapshot
|
||||
} from '@/utils/oa-owner-field-defaults'
|
||||
|
||||
function asRules(schema: unknown): Record<string, unknown>[] {
|
||||
if (Array.isArray(schema)) return schema.filter((r) => r && typeof r === 'object') as any
|
||||
@@ -11,12 +16,88 @@ function asRules(schema: unknown): Record<string, unknown>[] {
|
||||
return []
|
||||
}
|
||||
|
||||
function walk(rules: Record<string, unknown>[], out: Record<string, unknown>[]) {
|
||||
for (const r of rules) {
|
||||
out.push(r)
|
||||
if (Array.isArray(r.children)) {
|
||||
walk(r.children as any, out)
|
||||
}
|
||||
const props = r.props as any
|
||||
if (props && Array.isArray(props.rule)) walk(props.rule, out)
|
||||
}
|
||||
}
|
||||
|
||||
export type OvertimeKitBinding = {
|
||||
personField?: string
|
||||
durationField?: string
|
||||
}
|
||||
|
||||
function resolveBinding(kit: Record<string, unknown>): OvertimeKitBinding {
|
||||
const props = (kit.props && typeof kit.props === 'object' ? kit.props : {}) as Record<
|
||||
string,
|
||||
any
|
||||
>
|
||||
let personField = props.personField ? String(props.personField) : undefined
|
||||
let durationField = props.durationField ? String(props.durationField) : undefined
|
||||
const children = (
|
||||
Array.isArray(kit.children)
|
||||
? kit.children
|
||||
: Array.isArray(props.rule)
|
||||
? props.rule
|
||||
: []
|
||||
) as Record<string, any>[]
|
||||
for (const c of children) {
|
||||
if (!c?.field) continue
|
||||
const sem = String(c.props?._fc_kit_field || '')
|
||||
if (sem === 'overtimePerson' && !personField) personField = String(c.field)
|
||||
if (sem === 'overtimeDuration' && !durationField) durationField = String(c.field)
|
||||
}
|
||||
return { personField, durationField }
|
||||
}
|
||||
|
||||
export function listOvertimeKitBindings(schema: unknown): OvertimeKitBinding[] {
|
||||
const flat: Record<string, unknown>[] = []
|
||||
walk(asRules(schema), flat)
|
||||
return flat.filter((r) => String(r.type || '') === 'overtimeKit').map(resolveBinding)
|
||||
}
|
||||
|
||||
function isEmptyPersonValue(raw: unknown): boolean {
|
||||
if (raw == null || raw === '') return true
|
||||
if (Array.isArray(raw)) return raw.length === 0
|
||||
if (typeof raw === 'object') {
|
||||
const o = raw as Record<string, unknown>
|
||||
return !String(o.id || '').trim()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起页:加班人字段为空时写入当前登录人(人员组件为多选,值为数组)。
|
||||
*/
|
||||
export function applyOvertimeKitDefaults(
|
||||
schema: unknown,
|
||||
formData: Record<string, unknown>,
|
||||
user: OwnerUserSnapshot | null | undefined
|
||||
): Record<string, unknown> {
|
||||
const data = { ...formData }
|
||||
const person = buildCurrentOwnerPerson(user)
|
||||
if (!person) return data
|
||||
for (const kit of listOvertimeKitBindings(schema)) {
|
||||
const f = kit.personField
|
||||
if (f && isEmptyPersonValue(data[f])) {
|
||||
data[f] = [person]
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
function resolveDurationField(kit: Record<string, unknown>): string | undefined {
|
||||
const binding = resolveBinding(kit)
|
||||
if (binding.durationField) return binding.durationField
|
||||
const props = (kit.props && typeof kit.props === 'object' ? kit.props : {}) as Record<
|
||||
string,
|
||||
any
|
||||
>
|
||||
if (props.durationField) return String(props.durationField)
|
||||
const children = (
|
||||
Array.isArray(kit.children)
|
||||
? kit.children
|
||||
@@ -26,7 +107,6 @@ function resolveDurationField(kit: Record<string, unknown>): string | undefined
|
||||
) as Record<string, any>[]
|
||||
for (const c of children) {
|
||||
if (!c?.field) continue
|
||||
if (String(c.props?._fc_kit_field || '') === 'overtimeDuration') return String(c.field)
|
||||
const t = String(c.type || '')
|
||||
if ((t === 'inputNumber' || t === 'number') && String(c.title || '').includes('时长')) {
|
||||
return String(c.field)
|
||||
|
||||
@@ -90,7 +90,7 @@ function buildResignationKitChildren() {
|
||||
|
||||
export const resignationKitDragRule = {
|
||||
menu: 'kit' as const,
|
||||
icon: 'icon-user',
|
||||
icon: 'icon-transfer',
|
||||
label: '离职',
|
||||
name: 'resignationKit',
|
||||
input: false,
|
||||
|
||||
@@ -124,7 +124,7 @@ function buildTripKitChildren() {
|
||||
/** FormCreate Designer DragRule:出差套件 */
|
||||
export const tripKitDragRule = {
|
||||
menu: 'kit' as const,
|
||||
icon: 'icon-date',
|
||||
icon: 'icon-businesstrip',
|
||||
label: '出差',
|
||||
name: 'tripKit',
|
||||
input: false,
|
||||
|
||||
Reference in new issue
Block a user