Commit 10b99bbd by lijiabin

【需求 25171】refactor: 4 个页面接入 DeptUserPicker,替代企微选人 API

editDialog(后台案例编辑)、publishCase(投稿案例):只选部门,
value-type="string" 直接绑 deptId,@confirm 里拼 deptName。

publishLongArticle、publishVideo:部门+人员都能选,双 v-model 绑 id,
@confirm 拿完整详情拼 pushList。

顺手删掉了 wxUtil 里不再使用的 selectDepOrUser 及其相关类型。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
parent af06f8fb
......@@ -52,46 +52,3 @@ export function isWxShareCancel(error: unknown) {
msg?.includes('shareAppMessage:cancel'),
)
}
interface ISelectDepOrUser {
err_msg: string
result: IResult
}
interface IResult {
userList: ISelectUser[]
departmentList: ISelectDept[]
}
export interface ISelectUser {
id: string
name: string
avatar: string
}
export interface ISelectDept {
id: string
name: string
}
export async function selectDepOrUser(wxOption = {}): Promise<IResult> {
await initWxConfig()
const defaultOption = {
fromDepartmentId: -1,
mode: 'single',
type: ['user', 'department'],
}
const option = {
...defaultOption,
...wxOption,
}
return new Promise((resolve, reject) => {
ww.invoke('selectEnterpriseContact', option, function (res: ISelectDepOrUser) {
if (res.err_msg == 'selectEnterpriseContact:ok') {
resolve(res.result)
} else {
reject(res)
}
})
})
}
......@@ -2,9 +2,9 @@
import type { BackendCaseListItemDto, BackendEditCaseDto } from '@/api/backend/case/types'
import { useResetData } from '@/hooks'
import SelectTags from '@/components/common/SelectTags/index.vue'
import DeptUserPicker from '@/components/common/DeptUserPicker/index.vue'
import type { TagItemDto } from '@/api/tag/types'
import { TagLevelEnum, TagTypeEnum } from '@/constants'
import { selectDepOrUser } from '@/utils'
import { backendEditCase } from '@/api/backend'
import { push } from 'notivue'
const emit = defineEmits<{
......@@ -28,7 +28,8 @@ const [form] = useResetData<{
yearKeywordSecond: string
sceneKeywordMain: string
sceneKeywordSecond: number[]
departmentList: { id: string; name: string }[]
deptId: string
deptName: string
}>({
id: 0,
sourceProject: '',
......@@ -44,7 +45,8 @@ const [form] = useResetData<{
yearKeywordSecond: '',
sceneKeywordMain: '',
sceneKeywordSecond: [],
departmentList: [],
deptId: '',
deptName: '',
})
const visible = ref(false)
......@@ -71,10 +73,8 @@ const open = (row: BackendCaseListItemDto) => {
sceneKeywordMain: String(row.sceneKeywordMain[0]?.id || ''),
sceneKeywordSecond: row.sceneKeywordSecond.map((item) => item.id),
// 关联部门
departmentList: row.depIdList.map((id, index) => ({
id: String(id),
name: row.depNameList[index] || '',
})),
deptId: row.depIdList.join(','),
deptName: row.depNameList.join(','),
}
}
......@@ -89,24 +89,6 @@ const filterTagsFn = (tagType: TagTypeEnum, allTags: TagItemDto[]) => {
return allTags
}
// 选择部门
const selcetDept = async () => {
const { departmentList } = await selectDepOrUser({
mode: 'multi', // single multi
type: ['department'],
selectedDepartmentIds: form.value.departmentList.map((i) => i.id),
})
if (departmentList.length > 3) {
return push.warning('最多只能选择3个部门,请重新选择')
}
form.value.departmentList = departmentList
}
// 删除部门
const delDept = (id: string) => {
form.value.departmentList = form.value.departmentList.filter((i) => i.id !== id)
}
// 数据转换
const transformData = () => {
const {
......@@ -116,15 +98,12 @@ const transformData = () => {
yearKeywordSecond,
sceneKeywordMain,
sceneKeywordSecond,
departmentList,
...rest
} = form.value
const data: BackendEditCaseDto = {
...rest,
tagRelationDtoList: [],
deptId: departmentList.map((i) => i.id).join(','),
deptName: departmentList.map((i) => i.name).join(','),
}
// 添加文化关键词数据
......@@ -293,20 +272,21 @@ defineExpose({
</el-form-item>
<!-- 关联部门 -->
<el-form-item label="关联部门:">
<div class="flex items-start gap-3">
<el-button class="button-new-tag" size="small" @click="selcetDept">
+ 添加部门
</el-button>
<el-tag
v-for="tag in form.departmentList"
:key="tag.id"
closable
type="primary"
@close="() => delDept(tag.id)"
<DeptUserPicker
v-model:dept-value="form.deptId"
selection-mode="department"
value-type="string"
:max="3"
@confirm="(items) => (form.deptName = items.map((i) => i.valueName).join(','))"
v-slot="{ echoText }"
>
{{ tag.name }}
</el-tag>
</div>
<el-input
readonly
class="w-full cursor-pointer"
placeholder="请选择部门"
:model-value="echoText"
/>
</DeptUserPicker>
</el-form-item>
</el-form>
</el-scrollbar>
......
......@@ -66,20 +66,21 @@
</div>
</el-form-item>
<el-form-item label="关联部门" class="mb-6">
<div class="flex items-start gap-3">
<el-button class="button-new-tag" size="small" @click="selcetDept">
+ 添加部门
</el-button>
<el-tag
v-for="tag in form.departmentList"
:key="tag.id"
closable
type="primary"
@close="() => delDept(tag.id)"
<DeptUserPicker
v-model:dept-value="form.deptId"
selection-mode="department"
value-type="string"
:max="3"
@confirm="(items) => (form.deptName = items.map((i) => i.valueName).join(','))"
v-slot="{ echoText }"
>
{{ tag.name }}
</el-tag>
</div>
<el-input
readonly
class="w-full cursor-pointer"
placeholder="请选择部门"
:model-value="echoText"
/>
</DeptUserPicker>
</el-form-item>
<!-- 是否同步发布 -->
......@@ -126,10 +127,9 @@ import {
ReleaseStatusTypeEnum,
AuditStatusEnum,
} from '@/constants'
import { selectDepOrUser } from '@/utils'
import DeptUserPicker from '@/components/common/DeptUserPicker/index.vue'
import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
import type { ISelectDept } from '@/utils/wxUtil'
import BackButton from '@/components/common/BackButton/index.vue'
import { push } from 'notivue'
import { useMessageBox } from '@/hooks'
......@@ -155,25 +155,10 @@ const [form, resetForm] = useResetData({
relatedScenariosMainTagId: '',
relatedScenariosSubTagIds: [] as number[],
isSync: BooleanFlag.NO,
departmentList: [] as ISelectDept[],
deptId: '',
deptName: '',
})
// 选择部门
const selcetDept = async () => {
const { departmentList } = await selectDepOrUser({
mode: 'multi', // single multi
type: ['department'],
selectedDepartmentIds: form.value.departmentList.map((i) => i.id),
})
if (departmentList.length > 3) {
return push.warning('最多只能选择3个部门,请重新选择')
}
form.value.departmentList = departmentList
}
const delDept = (id: string) => {
form.value.departmentList = form.value.departmentList.filter((i) => i.id !== id)
}
// 取消
const handleCancel = () => {
resetForm()
......@@ -187,7 +172,6 @@ const transformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateCaseDto
subTagIds,
relatedScenariosMainTagId,
relatedScenariosSubTagIds,
departmentList,
...rest
} = form.value
const obj: AddOrUpdateCaseDto = {
......@@ -195,8 +179,6 @@ const transformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateCaseDto
releaseStatus,
tagRelationDtoList: [],
sourceUser: '',
deptId: '',
deptName: '',
}
// 添加文化标签内容
obj.tagRelationDtoList.push({
......@@ -225,10 +207,6 @@ const transformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateCaseDto
})
})
// 添加部门相关字段
obj.deptId = departmentList.map((i) => i.id).join(',')
obj.deptName = departmentList.map((i) => i.name).join(',')
obj.sourceUser = userInfo.value.userId
return obj
}
......@@ -357,10 +335,8 @@ onActivated(async () => {
.filter((i) => i.keywordType === TagLevelEnum.SUB_TAG)
.map((i) => i.tagId),
isSync: data.isSync,
departmentList: data.depIdList.map((id, index) => ({
id: String(id),
name: data.depNameList[index] || '',
})),
deptId: data.depIdList.join(','),
deptName: data.depNameList.join(','),
}
form.value = obj
......
......@@ -187,10 +187,21 @@
</el-radio-group>
</div>
<div v-show="form.isPushAll === BooleanFlag.NO" class="flex items-center gap-2">
<el-button class="button-new-tag" size="small" @click="handleSelectUserAndDept">
+ 添加部门/人员
</el-button>
<span class="ml-2 text-sm text-gray-600"> {{ selectedText }}</span>
<DeptUserPicker
v-model:dept-value="pushDeptIds"
v-model:user-value="pushUserIds"
selection-mode="both"
:initial-selected="pushInitialSelected"
@confirm="(items) => (pushSelection = items)"
v-slot="{ echoText }"
>
<el-input
readonly
class="w-80 cursor-pointer"
placeholder="请选择部门/人员"
:model-value="echoText"
/>
</DeptUserPicker>
</div>
</el-form-item>
<el-form-item label="推送类型" prop="pushType">
......@@ -251,10 +262,21 @@
</el-radio-group>
</div>
<div v-show="form.isPushAll === BooleanFlag.NO" class="flex items-center gap-2">
<el-button class="button-new-tag" size="small" @click="handleSelectUserAndDept">
+ 添加部门/人员
</el-button>
<span class="ml-2 text-sm text-gray-600"> {{ selectedText }}</span>
<DeptUserPicker
v-model:dept-value="pushDeptIds"
v-model:user-value="pushUserIds"
selection-mode="both"
:initial-selected="pushInitialSelected"
@confirm="(items) => (pushSelection = items)"
v-slot="{ echoText }"
>
<el-input
readonly
class="w-80 cursor-pointer"
placeholder="请选择部门/人员"
:model-value="echoText"
/>
</DeptUserPicker>
</div>
</el-form-item>
<el-form-item label="推送类型" prop="pushType">
......@@ -381,7 +403,8 @@ import { storeToRefs } from 'pinia'
import { addOrUpdateArticle, addOrUpdatePractice, getArticleDetail } from '@/api'
import { useRouter, useRoute } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { selectDepOrUser } from '@/utils'
import DeptUserPicker from '@/components/common/DeptUserPicker/index.vue'
import type { DepartmentUserSelection } from '@/components/common/DepartmentUserModal/types'
import type { FormItemRule } from 'element-plus'
import { push } from 'notivue'
import BackButton from '@/components/common/BackButton/index.vue'
......@@ -475,37 +498,13 @@ const rules: Record<string, FormItemRule[]> = {
pushList: [{ required: true, message: '请选择推送对象', trigger: 'trigger' }],
}
// 选中的部门
const selectedDepts = ref<{ id: string; name: string }[]>([])
// 选中的成员
const selectedUsers = ref<{ id: string; name: string }[]>([])
const selectedText = computed(() => {
let text = ''
if (selectedDepts.value.length > 0) {
text += `已选择${selectedDepts.value.length}个部门`
}
if (selectedUsers.value.length > 0) {
text += `已选择${selectedUsers.value.length}个成员`
}
return text
})
const handleSelectUserAndDept = async () => {
const { departmentList, userList } = await selectDepOrUser({
mode: 'multi',
type: ['user', 'department'],
selectedDepartmentIds: selectedDepts.value.map((item) => item.id),
selectedUserIds: selectedUsers.value.map((item) => item.id),
})
selectedDepts.value = departmentList.map((item) => ({
id: item.id,
name: item.name,
}))
selectedUsers.value = userList.map((item) => ({
id: item.id,
name: item.name,
}))
}
// “推送给”选中的部门/人员:*Ids 是给 DeptUserPicker 用的 id 数组,
// pushSelection 是 @confirm 拿到的完整详情(带名字),提交时直接用它拼 pushList。
const pushDeptIds = ref<string[]>([])
const pushUserIds = ref<string[]>([])
const pushSelection = ref<DepartmentUserSelection[]>([])
// 编辑回显用,给 DeptUserPicker 做首次回显的名字种子(不传的话首次打开只能看到 id)。
const pushInitialSelected = ref<DepartmentUserSelection[]>([])
const filterTagsFn = (allTags: any[]) => {
return allTags.filter((tag) => tag.id !== Number(form.value.mainTagId))
......@@ -541,18 +540,11 @@ const transFormData = (releaseStatus: ReleaseStatusTypeEnum) => {
},
]
} else {
data.pushList = [
...selectedDepts.value.map((item) => ({
valueId: item.id,
valueType: 1,
valueName: item.name,
})),
...selectedUsers.value.map((item) => ({
valueId: item.id,
valueType: 2,
valueName: item.name,
})),
]
data.pushList = pushSelection.value.map((item) => ({
valueId: item.valueId,
valueType: item.valueType,
valueName: item.valueName,
}))
}
}
......@@ -606,8 +598,10 @@ const isEdit = computed(() => !!route.query.id)
onActivated(async () => {
key.value++
resetForm()
selectedDepts.value = []
selectedUsers.value = []
pushDeptIds.value = []
pushUserIds.value = []
pushSelection.value = []
pushInitialSelected.value = []
await nextTick()
if (isEdit.value) {
......@@ -669,24 +663,21 @@ onActivated(async () => {
) {
if (data.pushList?.find((item) => item.valueId == '1')) {
form.value.isPushAll = BooleanFlag.YES
selectedDepts.value = []
selectedUsers.value = []
pushDeptIds.value = []
pushUserIds.value = []
pushSelection.value = []
pushInitialSelected.value = []
} else {
form.value.isPushAll = BooleanFlag.NO
selectedDepts.value =
data.pushList
?.filter((item) => item.valueType === 1)
.map((item) => ({
id: item.valueId,
name: item.valueName,
})) || []
selectedUsers.value =
data.pushList
?.filter((item) => item.valueType === 2)
.map((item) => ({
id: item.valueId,
name: item.valueName,
})) || []
const items: DepartmentUserSelection[] = (data.pushList || []).map((item) => ({
valueType: item.valueType as 1 | 2,
valueId: String(item.valueId),
valueName: item.valueName,
}))
pushDeptIds.value = items.filter((item) => item.valueType === 1).map((item) => item.valueId)
pushUserIds.value = items.filter((item) => item.valueType === 2).map((item) => item.valueId)
pushSelection.value = items
pushInitialSelected.value = items
}
}
......
......@@ -165,14 +165,21 @@
v-show="form.isPushAll === BooleanFlag.NO"
class="flex items-center gap-2"
>
<el-button
class="button-new-tag"
size="small"
@click="handleSelectUserAndDept"
<DeptUserPicker
v-model:dept-value="pushDeptIds"
v-model:user-value="pushUserIds"
selection-mode="both"
:initial-selected="pushInitialSelected"
@confirm="(items) => (pushSelection = items)"
v-slot="{ echoText }"
>
+ 添加部门
</el-button>
<span class="ml-2 text-sm text-gray-600"> {{ selectedText }}</span>
<el-input
readonly
class="w-80 cursor-pointer"
placeholder="请选择部门/人员"
:model-value="echoText"
/>
</DeptUserPicker>
</div>
</div>
</el-form-item>
......@@ -390,7 +397,8 @@ import SelectTags from '@/components/common/SelectTags/index.vue'
import type { TagItemDto, AddOrUpdateVideoDto} from '@/api'
import { useVideoStore, useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
import { selectDepOrUser } from '@/utils'
import DeptUserPicker from '@/components/common/DeptUserPicker/index.vue'
import type { DepartmentUserSelection } from '@/components/common/DepartmentUserModal/types'
import BackButton from '@/components/common/BackButton/index.vue'
import { push } from 'notivue'
......@@ -436,34 +444,13 @@ const disabledSecondsOnlyZero = () => Array.from({ length: 59 }, (_, i) => i + 1
const disabledMinutesOnlyTens = () =>
Array.from({ length: 60 }, (_, i) => i).filter((m) => m % 10 !== 0)
const selectedDepts = ref<{ id: string; name: string }[]>([])
const selectedUsers = ref<{ id: string; name: string }[]>([])
const selectedText = computed(() => {
let text = ''
if (selectedDepts.value.length > 0) {
text += `已选择${selectedDepts.value.length}个部门`
}
if (selectedUsers.value.length > 0) {
text += `已选择${selectedUsers.value.length}个成员`
}
return text
})
const handleSelectUserAndDept = async () => {
const { departmentList, userList } = await selectDepOrUser({
mode: 'multi',
type: ['user', 'department'],
selectedDepartmentIds: selectedDepts.value.map((item) => item.id),
selectedUserIds: selectedUsers.value.map((item) => item.id),
})
selectedDepts.value = departmentList.map((item) => ({
id: item.id,
name: item.name,
}))
selectedUsers.value = userList.map((item) => ({
id: item.id,
name: item.name,
}))
}
// “推送给”选中的部门/人员:*Ids 是给 DeptUserPicker 用的 id 数组,
// pushSelection 是 @confirm 拿到的完整详情(带名字),提交时直接用它拼 pushList。
const pushDeptIds = ref<string[]>([])
const pushUserIds = ref<string[]>([])
const pushSelection = ref<DepartmentUserSelection[]>([])
// 编辑回显用,给 DeptUserPicker 做首次回显的名字种子(不传的话首次打开只能看到 id)。
const pushInitialSelected = ref<DepartmentUserSelection[]>([])
// 封面选择相关
......@@ -588,18 +575,11 @@ const tansformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateVideoDto
},
]
} else {
data.pushList = [
...selectedDepts.value.map((item) => ({
valueId: item.id,
valueType: 1,
valueName: item.name,
})),
...selectedUsers.value.map((item) => ({
valueId: item.id,
valueType: 2,
valueName: item.name,
})),
]
data.pushList = pushSelection.value.map((item) => ({
valueId: item.valueId,
valueType: item.valueType,
valueName: item.valueName,
}))
}
}
return data as AddOrUpdateVideoDto
......@@ -607,8 +587,10 @@ const tansformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateVideoDto
const loading = ref(false)
const resetPageData = () => {
selectedDepts.value = []
selectedUsers.value = []
pushDeptIds.value = []
pushUserIds.value = []
pushSelection.value = []
pushInitialSelected.value = []
resetData()
locationVideoBlolUrl.value = ''
}
......@@ -676,24 +658,21 @@ onActivated(async () => {
// 回显推送的部门 这个后端没有返回相关数据 需要返回
if (data.pushList?.find((item) => item.valueId == '1')) {
form.value.isPushAll = BooleanFlag.YES
selectedDepts.value = []
selectedUsers.value = []
pushDeptIds.value = []
pushUserIds.value = []
pushSelection.value = []
pushInitialSelected.value = []
} else {
form.value.isPushAll = BooleanFlag.NO
selectedDepts.value =
data.pushList
?.filter((item) => item.valueType === 1)
.map((item) => ({
id: item.valueId,
name: item.valueName,
})) || []
selectedUsers.value =
data.pushList
?.filter((item) => item.valueType === 2)
.map((item) => ({
id: item.valueId,
name: item.valueName,
})) || []
const items: DepartmentUserSelection[] = (data.pushList || []).map((item) => ({
valueType: item.valueType as 1 | 2,
valueId: String(item.valueId),
valueName: item.valueName,
}))
pushDeptIds.value = items.filter((item) => item.valueType === 1).map((item) => item.valueId)
pushUserIds.value = items.filter((item) => item.valueType === 2).map((item) => item.valueId)
pushSelection.value = items
pushInitialSelected.value = items
}
}
})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment