|
@@ -6,6 +6,7 @@
|
|
|
<el-tree
|
|
|
ref="treeRef"
|
|
|
show-checkbox
|
|
|
+ node-key="id"
|
|
|
:filter-node-method="filterTree"
|
|
|
:data="markerTree"
|
|
|
:props="treeProp"
|
|
@@ -18,7 +19,7 @@
|
|
|
<div class="flex items-center p-base message-info-header">
|
|
|
<div class="flex flex-1 items-center overflow-hidden send-user">
|
|
|
<span class="m-r-mini">收件人</span>
|
|
|
- <span class="flex flex-1 overflow-hidden items-center justify-between radius-base user-name">
|
|
|
+ <span class="flex flex-1 overflow-hidden items-center justify-between radius-base m-r-base user-name">
|
|
|
<span class="flex-1 checked-users"> {{ viewCheckedUser }}</span>
|
|
|
<el-button class="m-l-base" size="small" type="primary" @click="toggleCheckUser"> 选择收件人 </el-button>
|
|
|
</span>
|
|
@@ -29,46 +30,60 @@
|
|
|
</div>
|
|
|
<div class="flex-1 p-base overflow-hidden">
|
|
|
<div class="full-h radius-base scroll-y-auto message-info-content">
|
|
|
- <el-input
|
|
|
- v-model="messageContent"
|
|
|
- type="textarea"
|
|
|
- class="full-h"
|
|
|
- resize="none"
|
|
|
- :maxlength="1000"
|
|
|
- show-word-limit
|
|
|
- ></el-input>
|
|
|
+ <content-edit-able v-model="messageContent" class="full-h"></content-edit-able>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="p-base flex items-center justify-end">
|
|
|
<el-button size="small" plain @click="sendCurrentPaper">发送当前试卷</el-button>
|
|
|
- <el-button size="small" type="primary" @click="onSendMessage">发送</el-button>
|
|
|
+ <el-button size="small" type="primary" :disabled="!allowSend" :loading="loading" @click="onSendMessage">
|
|
|
+ 发送
|
|
|
+ </el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <image-preview v-model="previewModalVisible" :url="previewPath"></image-preview>
|
|
|
</template>
|
|
|
|
|
|
-<script setup lang="ts" name="MessageSend">
|
|
|
-import { reactive, ref, computed, watch } from 'vue'
|
|
|
-import { ElInput, ElButton, ElTree, ElIcon } from 'element-plus'
|
|
|
+<script setup lang="tsx" name="MessageSend">
|
|
|
+import { ref, computed, watch, nextTick, defineComponent, createApp } from 'vue'
|
|
|
+import { ElInput, ElButton, ElTree, ElIcon, ElMessage } from 'element-plus'
|
|
|
import { Close } from '@element-plus/icons-vue'
|
|
|
+import ContentEditAble from '@/components/common/ContentEditAble.vue'
|
|
|
+import ImagePreview from '../ImagePreview.vue'
|
|
|
import useFetch from '@/hooks/useFetch'
|
|
|
+import useVModel from '@/hooks/useVModel'
|
|
|
|
|
|
import type { ExtractApiResponse } from 'api-type'
|
|
|
|
|
|
type MarkerItem = ExtractArrayValue<ExtractApiResponse<'getUserGroup'>['chiffGroup']>
|
|
|
type TreeNode = ExtractArrayValue<ExtractApiResponse<'getUserGroup'>['markerGroup']> & { label: string }
|
|
|
|
|
|
-defineEmits(['close'])
|
|
|
+const props = defineProps<{
|
|
|
+ replyUserId: number
|
|
|
+}>()
|
|
|
|
|
|
-const showCheckUser = ref<boolean>(false)
|
|
|
+const emit = defineEmits(['close'])
|
|
|
|
|
|
-const messageContent = ref<string>()
|
|
|
+const replyUserId = useVModel(props, 'replyUserId')
|
|
|
|
|
|
-const checkedUsers = ref<MarkerItem[]>()
|
|
|
+/** 图片预览 */
|
|
|
+const previewModalVisible = ref<boolean>(false)
|
|
|
+
|
|
|
+const previewPath = ref<string>()
|
|
|
+
|
|
|
+const showCheckUser = ref<boolean>(true)
|
|
|
+
|
|
|
+const messageContent = ref<string>('')
|
|
|
+
|
|
|
+const checkedUsers = ref<MarkerItem[]>([])
|
|
|
|
|
|
const filterText = ref<string>('')
|
|
|
|
|
|
+const allowSend = computed<boolean>(() => {
|
|
|
+ return !!(messageContent.value && checkedUsers.value.length)
|
|
|
+})
|
|
|
+
|
|
|
const treeRef = ref<InstanceType<typeof ElTree>>()
|
|
|
|
|
|
const viewCheckedUser = computed(() => {
|
|
@@ -116,17 +131,55 @@ const markerTree = computed<TreeNode[]>(() => {
|
|
|
] as TreeNode[]
|
|
|
})
|
|
|
|
|
|
+watch(
|
|
|
+ [replyUserId, markerTree],
|
|
|
+ () => {
|
|
|
+ nextTick(() => {
|
|
|
+ replyUserId.value && markerTree.value.length && treeRef?.value?.setCheckedKeys([replyUserId.value])
|
|
|
+ })
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+)
|
|
|
+
|
|
|
const onCheckChange = () => {
|
|
|
checkedUsers.value = (treeRef?.value?.getCheckedNodes(true) as MarkerItem[]) || []
|
|
|
}
|
|
|
|
|
|
+const onPreviewImage = (path: string) => {
|
|
|
+ previewPath.value = path
|
|
|
+ previewModalVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
/** 发送当前试卷 */
|
|
|
const sendCurrentPaper = () => {
|
|
|
- console.log('发送当前试卷')
|
|
|
+ const ImgLink = defineComponent({
|
|
|
+ render() {
|
|
|
+ return (
|
|
|
+ <div class="inline" contenteditable={false}>
|
|
|
+ <span class="pointer" type="primary" link onClick={() => onPreviewImage('xxxxx')}>
|
|
|
+ 当前试卷
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ },
|
|
|
+ })
|
|
|
+ messageContent.value += createApp(ImgLink).mount(document.createElement('div')).$el.outerHTML
|
|
|
}
|
|
|
+
|
|
|
+const { fetch: sendMessage, loading } = useFetch('sendMessage')
|
|
|
+
|
|
|
/** 发送消息 */
|
|
|
-const onSendMessage = () => {
|
|
|
- console.log('发消息')
|
|
|
+const onSendMessage = async () => {
|
|
|
+ try {
|
|
|
+ await sendMessage({
|
|
|
+ content: messageContent.value,
|
|
|
+ receiveUserIds: checkedUsers.value.map((u) => u.id),
|
|
|
+ })
|
|
|
+ ElMessage.success('发送成功')
|
|
|
+ emit('close')
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
getUserGroup()
|