qsh 1 month ago
parent 6ebe33e48c
commit 9b323b68f9
  1. 16
      src/api/okr/meeting.js
  2. 2
      src/components/Editor/src/Editor.vue
  3. 11
      src/views/Basic/Dept/DeptForm.vue
  4. 306
      src/views/OKR/Meeting/MeetingInfo.vue
  5. 10
      src/views/OKR/Meeting/index.vue

@ -43,3 +43,19 @@ export const getMeetingPage = (params) => {
// headers: { 'instance-id': 1016 }
})
}
// 刷新微信群列表
export const refreshWxGroupList = () => {
return request.get({
url: '/admin-api/system/wx/reFreshWeChatGroupList'
// headers: { 'instance-id': 1016 }
})
}
// 获取微信群聊列表
export const getWxGroupList = () => {
return request.get({
url: '/admin-api/system/wx/getWeChatGroupList'
// headers: { 'instance-id': 1016 }
})
}

@ -21,7 +21,7 @@ const props = defineProps({
height: propTypes.oneOfType([Number, String]).def('40vh'),
editorConfig: {
type: Object as PropType<Partial<IEditorConfig>>,
default: () => undefined
default: () => ({})
},
readonly: propTypes.bool.def(false),
modelValue: propTypes.string.def(''),

@ -1,5 +1,5 @@
<template>
<Dialog v-model="dialogVisible" :title="dialogTitle" width="800px">
<Dialog v-if="dialogVisible" v-model="dialogVisible" :title="dialogTitle" width="800px">
<el-form
ref="formRef"
v-loading="formLoading"
@ -30,7 +30,12 @@
<el-row :gutter="20">
<el-col :span="12" :offset="0">
<el-form-item label="负责人" prop="leaderUserId">
<el-select v-model="formData.leaderUserId" clearable placeholder="请输入负责人">
<el-select
v-model="formData.leaderUserId"
clearable
multiple
placeholder="请输入负责人"
>
<el-option
v-for="item in userList"
:key="item.id"
@ -59,7 +64,7 @@
<el-row :gutter="20">
<el-col :span="24" :offset="0">
<el-form-item label="备注" prop="remark">
<Editor v-model:modelValue="formData.remark" />
<Editor v-model="formData.remark" />
</el-form-item>
</el-col>
</el-row>

@ -1,9 +1,12 @@
<template>
<div>
<!-- <el-affix postion="top" :offset="95" target="#app" v-if="!isDetail"> -->
<!-- <el-affix postion="top" :offset="95" v-if="!isDetail"> -->
<div class="flex justify-between mb-4 bg-white" v-if="!isDetail">
<b class="text-20px">{{ form.meetingId ? '修改会议' : '新增会议' }}</b>
<el-button type="success" @click="submit()">保存</el-button>
<div>
<el-button @click="submit(true)">保存至草稿</el-button>
<el-button type="success" @click="submit(false)">保存</el-button>
</div>
</div>
<!-- </el-affix> -->
<el-form
@ -76,7 +79,6 @@
<el-select
v-model="form.expectUsers"
placeholder="选择参会人员"
clearable
filterable
style="width: 100%"
multiple
@ -87,7 +89,7 @@
:key="item.id"
:label="item.name"
:value="item.id"
:disabled="item.status == 1"
:disabled="item.status == 1 || item.id == userStore.getUser.id"
/>
</el-select>
</el-form-item>
@ -106,7 +108,7 @@
</el-checkbox-group>
</el-form-item>
</el-col>
<el-col :span="24" :offset="0" v-if="!isAllActived">
<el-col :span="24" :offset="0" v-if="form.meetingId && !isAllActived">
<el-form-item label="缺席原因" prop="absentReason">
<el-input v-model="form.absentReason" placeholder="请输入缺席原因" />
</el-form-item>
@ -114,32 +116,111 @@
</el-row>
<el-row :gutter="20">
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24">
<el-form-item label="会议内容" prop="meetingContent">
<div v-if="!!isDetail" v-dompurify-html="form.meetingContent" class="w-full"></div>
<Editor v-else v-model="form.meetingContent" height="500px" style="width: 100%" />
</el-form-item>
<el-tabs v-model="currentUserId" tab-position="top" @tab-click="userTabChange">
<el-tab-pane
v-for="item in form.meetingContentList"
:key="item.userId"
:label="item.userName"
:name="item.userId + ''"
/>
</el-tabs>
<el-tabs
v-model="currentContentId"
tab-position="left"
:addable="!isDetail"
@edit="handleTabsEdit"
>
<el-tab-pane
v-for="(item, index) in form.meetingContentList.find(
(it) => it.userId == currentUserId
)?.userMeetingContentList"
:key="index"
:label="'内容' + (index + 1)"
:name="index"
:closable="index > 0 && !isDetail"
>
<div v-if="!!isDetail" v-dompurify-html="item.content" class="w-full"></div>
<Editor v-else v-model="item.content" height="500px" style="width: 100%" />
</el-tab-pane>
</el-tabs>
</el-col>
<el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" v-if="!!form.meetingId">
<el-form-item label="会议纪要" prop="meetingSummary" label-width="80px">
<div v-if="!!isDetail" v-dompurify-html="form.meetingSummary" class="w-full"></div>
<div v-else>
<el-tabs v-model="summaryIdx" :addable="!isDetail" @edit="meetingSummaryEdit">
<el-tab-pane
v-for="(item, index) in form.meetingSummaryList"
:key="index"
:label="`会议纪要${index || ''}`"
:name="index"
:closable="index > 0 && !isDetail"
>
<Editor
v-else
v-model="form.meetingSummary"
v-model="item.summary"
:toolbarConfig="toolbarConfig"
height="500px"
height="350px"
placeholder="请输入会议纪要"
style="width: 100%"
/>
<!-- <div v-if="!!isDetail" class="w-full">{{ form.meetingSummary }}</div>
<el-input
v-else
v-model="form.meetingSummary"
type="textarea"
placeholder="请输入会议纪要"
:maxlength="-1"
:show-word-limit="false"
:autosize="{ minRows: 20 }"
/> -->
<div class="mt-10px">
<el-form-item label="是否创建待办" label-width="auto">
<el-radio-group v-model="item.isCreateAgentWork">
<el-radio :label="true" :value="true"> 创建待办 </el-radio>
<el-radio :label="false" :value="false"> 不创建待办 </el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="flex items-center" v-if="item.isCreateAgentWork">
<el-select
class="flex-1"
v-model="item.agentUserList"
placeholder="选择执行人"
clearable
filterable
multiple
>
<el-option
v-for="it in userOptions"
:key="it.id"
:label="it.name"
:value="it.id"
:disabled="it.status == 1"
/>
</el-select>
<el-date-picker
class="flex-1 ml-10px"
v-model="item.endDate"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择截止时间"
/>
</div>
</el-tab-pane>
</el-tabs>
<el-divider />
<div class="text-black text-12px">
如果选择创建待办请选择执行人及截止日期默认每天9:00循环提醒可于待办中修改
</div>
<div class="mt-10px">
<el-form-item label="会议纪要发送至群聊:" label-width="auto">
<el-select
filterable
clearable
v-model="form.wxId"
placeholder="请输入群聊名称"
style="width: 100%"
>
<el-option
v-for="item in groupOptions"
:key="item.wxGroupId"
:label="item.wxGroupName"
:value="item.wxGroupId"
/>
</el-select>
</el-form-item>
</div>
</div>
</el-col>
</el-row>
</el-form>
@ -153,14 +234,12 @@ import * as MeetingApi from '@/api/okr/meeting'
import { formatDate } from '@/utils/formatTime'
import { getEmployeeSimpleList } from '@/api/pers/employee'
import { useTagsViewStore } from '@/store/modules/tagsView'
import { useUserStore } from '@/store/modules/user'
const route = useRoute()
const message = useMessage()
const tagsViewStore = useTagsViewStore()
const toolbarConfig = {
toolbarKeys: []
}
const userStore = useUserStore()
const defaultProps = {
value: 'nodeId',
@ -169,14 +248,33 @@ const defaultProps = {
}
const isDetail = route.query.isDetail
const currentUserId = ref(undefined)
const currentContentId = ref(0) //
const summaryIdx = ref(0) //
const toolbarConfig = {
toolbarKeys: []
}
onMounted(async () => {
getWxGroupOptions()
await getOptions()
if (route.params.id && route.params.id != 0) {
// API
getMeetingInfo(route.params.id)
} else {
console.error('会议不存在')
form.value.meetingContentList = [
{
userId: userStore.getUser.id + '',
userName: userStore.getUser.nickname,
userMeetingContentList: [
{
content: ''
}
]
}
]
currentContentId.value = 0
}
})
@ -190,23 +288,13 @@ function getOptions() {
children: 'children'
})
userOptions.value = employeeResp.map((it) => ({ ...it, id: it.id + '' }))
// handleUserChange()
form.value.expectUsers = [userStore.getUser.id + ''] //
// form.value.actualUsers = [userStore.getUser.id + '']
currentUserId.value = userStore.getUser.id + '' //
})
.catch((error) => {
console.error('获取数据失败:', error)
})
// // OKR
// getAllNodeTree().then((resp) => {
// peroidList.value = listToTree(resp?.tree || [], {
// id: 'nodeId',
// pid: 'parentId',
// children: 'children'
// })
// })
// //
// getEmployeeSimpleList().then((data) => {
// userOptions.value = data.map((it) => ({ ...it, id: it.id + '' }))
// })
}
const form = ref({
@ -221,7 +309,9 @@ const form = ref({
status: '1',
meetingContent: '',
meetingSummary: '',
absentReason: ''
absentReason: '',
meetingContentList: [],
meetingSummaryList: []
})
const rules = {
meetingSubject: [{ required: true, message: '请输入会议主题', trigger: 'blur' }],
@ -249,15 +339,37 @@ const getMeetingInfo = async (meetingId) => {
const resp = await MeetingApi.getMeetingDetail({ meetingId })
loading.value = false
if (resp) {
let summaryList = []
if (resp.meetingSummaryList && resp.meetingSummaryList.length > 0) {
summaryList = resp.meetingSummaryList.map((item) => ({
...item,
isCreateAgentWork: !!item.isCreateAgentWork,
agentUserList: item.agentUserList ? item.agentUserList.map((it) => it + '') : []
}))
} else {
summaryList = [
{
summary: resp.meetingSummary || '',
agentUserList: [],
endDate: '',
isCreateAgentWork: true
}
]
}
form.value = {
...form.value,
...resp,
startTime: formatDate(resp.startTime, 'YYYY-MM-DD HH:mm'),
expectEndTime: formatDate(resp.expectEndTime, 'YYYY-MM-DD HH:mm'),
expectUsers: resp.expectUsers || [],
actualUsers: resp.actualUsers || []
actualUsers: resp.actualUsers || [],
meetingSummaryList: summaryList
}
handleUserChange()
currentContentId.value = 0
expectUserOptions.value = userOptions.value.filter((user) =>
form.value.expectUsers.some((it) => it == user.id)
)
}
} catch (error) {
loading.value = false
@ -265,7 +377,61 @@ const getMeetingInfo = async (meetingId) => {
}
}
function handleUserChange() {
const groupOptions = ref([])
function getWxGroupOptions() {
MeetingApi.refreshWxGroupList().then(() => {
MeetingApi.getWxGroupList()
.then((resp) => {
groupOptions.value = resp || []
})
.catch((error) => {
console.error('获取微信群列表失败:', error)
})
})
}
function userTabChange() {
currentContentId.value = 0
}
function handleTabsEdit(targetName, action) {
if (action === 'add') {
form.value.meetingContentList.forEach((item) => {
if (item.userId == currentUserId.value) {
item.userMeetingContentList.push({
content: ''
})
}
})
} else if (action === 'remove') {
form.value.meetingContentList.forEach((item) => {
if (item.userId == currentUserId.value) {
item.userMeetingContentList.splice(targetName, 1)
//
if (currentContentId.value == targetName) {
currentContentId.value = targetName - 1
}
}
})
}
}
function meetingSummaryEdit(targetName, action) {
if (action === 'add') {
form.value.meetingSummaryList.push({
summary: '',
agentUserList: [],
endDate: '',
isCreateAgentWork: true
})
} else if (action === 'remove') {
form.value.meetingSummaryList.splice(targetName, 1)
summaryIdx.value = targetName - 1
}
}
function handleUserChange(val) {
//
expectUserOptions.value = userOptions.value.filter((user) =>
form.value.expectUsers.some((it) => it == user.id)
@ -273,30 +439,68 @@ function handleUserChange() {
if (!isDetail) {
form.value.actualUsers = [...form.value.expectUsers]
}
//
form.value.meetingContentList = form.value.meetingContentList.filter((item) => {
return val.some((it) => it == item.userId)
})
//
val.map((item) => {
if (!form.value.meetingContentList.some((it) => it.userId == item)) {
form.value.meetingContentList.push({
userId: item,
userName: userOptions.value.find((it) => it.id == item).name,
userMeetingContentList: [
{
content: ''
}
]
})
}
})
}
const router = useRouter()
async function submit() {
async function submit(isDraft = false) {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
try {
form.value.isDraft = isDraft
//
if (form.value.meetingId) {
if (form.value.status == 2 && !form.value.meetingSummary) {
if (
form.value.status == 2 &&
form.value.meetingSummaryList.some((it) => it.summary.trim() == '')
) {
message.error('会议结束时,会议纪要不能为空')
return
} else {
let text = ''
form.value.meetingSummaryList.map((item, index) => {
if (form.value.meetingSummaryList.length > 1) {
text += '<p>会议纪要' + (index + 1) + ':</p>'
}
text += item.summary
if (item.isCreateAgentWork) {
text += `<p>执行人:`
item.agentUserList.map((it) => {
if (it) {
text += `${userOptions.value.find((user) => user.id == it).name} `
}
})
text += '</p>'
text += `<p>截止日期:${item.endDate}</p>`
}
text += '<p><br></p>'
})
form.value.meetingSummary = text
}
//
await MeetingApi.updateMeeting(form.value)
message.success('会议更新成功')
} else {
if (form.value.status == 1 && !form.value.meetingContent) {
message.error('预约会议时,会议内容不能为空')
return
}
form.value.actualUsers = []
//
await MeetingApi.createMeeting(form.value)

@ -11,6 +11,15 @@
@keyup.enter="handleSearch"
/>
</el-form-item>
<el-form-item>
<el-input
v-model="searchForm.creator"
placeholder="发起人"
style="width: 120px"
clearable
@keyup.enter="handleSearch"
/>
</el-form-item>
<el-form-item>
<el-select
v-model="searchForm.status"
@ -117,6 +126,7 @@ const message = useMessage()
const searchForm = ref({
meetingSubject: undefined,
creator: undefined,
status: '1',
dateRange: [],
nodeId: undefined,

Loading…
Cancel
Save