Files
aiot-platform-ui/apps/web-ele/src/views/mp/components/reply/reply.vue

118 lines
3.3 KiB
Vue
Raw Normal View History

2025-11-03 14:04:00 +08:00
<!--
- Copyright (C) 2018-2019
- All rights reserved, Designed By www.joolun.com
芋道源码
移除多余的 rep 为前缀的变量 message 消息更简单
代码优化补充注释提升阅读性
优化消息的临时缓存策略发送消息时只清理被发送消息的 tab不会强制切回到 text 输入
支持发送视频消息时支持新建视频
-->
<script lang="ts" setup>
2025-11-07 17:58:24 +08:00
import type { Reply } from './types';
2025-11-03 14:04:00 +08:00
2025-11-12 16:56:18 +08:00
import { computed } from 'vue';
2025-11-03 14:04:00 +08:00
import { IconifyIcon } from '@vben/icons';
2025-11-13 18:35:10 +08:00
import { ElRow, ElTabPane, ElTabs } from 'element-plus';
2025-11-03 14:04:00 +08:00
2025-11-12 16:56:18 +08:00
import { NewsType } from '../material-select/types';
2025-11-07 17:58:24 +08:00
import TabImage from './tab-image.vue';
import TabMusic from './tab-music.vue';
import TabNews from './tab-news.vue';
import TabText from './tab-text.vue';
import TabVideo from './tab-video.vue';
import TabVoice from './tab-voice.vue';
2025-11-12 16:56:18 +08:00
import { createEmptyReply, ReplyType } from './types';
2025-11-03 14:04:00 +08:00
2025-11-12 16:56:18 +08:00
defineOptions({ name: 'ReplySelect' });
2025-11-03 14:04:00 +08:00
const props = withDefaults(
defineProps<{
2025-11-13 18:35:10 +08:00
modelValue: Reply | undefined;
2025-11-03 14:04:00 +08:00
newsType?: NewsType;
}>(),
{
newsType: () => NewsType.Published,
},
);
const emit = defineEmits<{
(e: 'update:modelValue', v: Reply): void;
}>();
2025-11-12 16:56:18 +08:00
// 提供一个默认的 Reply 对象,避免 undefined 导致的错误
const defaultReply: Reply = {
accountId: -1,
type: ReplyType.Text,
};
2025-11-03 14:04:00 +08:00
const reply = computed<Reply>({
2025-11-12 16:56:18 +08:00
get: () => props.modelValue || defaultReply,
2025-11-03 14:04:00 +08:00
set: (val) => emit('update:modelValue', val),
});
2025-11-03 14:04:00 +08:00
/** 清除除了`type`, `accountId`的字段 */
function clear() {
reply.value = createEmptyReply(reply);
}
defineExpose({
clear,
});
</script>
<template>
2025-11-13 18:35:10 +08:00
<ElTabs type="border-card" v-model="reply.type" @tab-change="clear">
2025-11-03 14:04:00 +08:00
<!-- 类型 1文本 -->
2025-11-13 18:35:10 +08:00
<ElTabPane :name="ReplyType.Text">
<template #label>
<ElRow align="middle"><IconifyIcon icon="ep:document" /> 文本</ElRow>
2025-11-03 14:04:00 +08:00
</template>
<TabText v-model="reply.content" />
2025-11-13 18:35:10 +08:00
</ElTabPane>
2025-11-03 14:04:00 +08:00
<!-- 类型 2图片 -->
2025-11-13 18:35:10 +08:00
<ElTabPane :name="ReplyType.Image">
<template #label>
<ElRow align="middle">
2025-11-03 14:04:00 +08:00
<IconifyIcon icon="ep:picture" class="mr-5px" /> 图片
2025-11-13 18:35:10 +08:00
</ElRow>
2025-11-03 14:04:00 +08:00
</template>
<TabImage v-model="reply" />
2025-11-13 18:35:10 +08:00
</ElTabPane>
2025-11-03 14:04:00 +08:00
<!-- 类型 3语音 -->
2025-11-13 18:35:10 +08:00
<ElTabPane :name="ReplyType.Voice">
<template #label>
<ElRow align="middle"><IconifyIcon icon="ep:phone" /> 语音</ElRow>
2025-11-03 14:04:00 +08:00
</template>
<TabVoice v-model="reply" />
2025-11-13 18:35:10 +08:00
</ElTabPane>
2025-11-03 14:04:00 +08:00
<!-- 类型 4视频 -->
2025-11-13 18:35:10 +08:00
<ElTabPane :name="ReplyType.Video">
<template #label>
<ElRow align="middle"><IconifyIcon icon="ep:share" /> 视频</ElRow>
2025-11-03 14:04:00 +08:00
</template>
<TabVideo v-model="reply" />
2025-11-13 18:35:10 +08:00
</ElTabPane>
2025-11-03 14:04:00 +08:00
<!-- 类型 5图文 -->
2025-11-13 18:35:10 +08:00
<ElTabPane :name="ReplyType.News">
<template #label>
<ElRow align="middle"><IconifyIcon icon="ep:reading" /> 图文</ElRow>
2025-11-03 14:04:00 +08:00
</template>
<TabNews v-model="reply" :news-type="newsType" />
2025-11-13 18:35:10 +08:00
</ElTabPane>
2025-11-03 14:04:00 +08:00
<!-- 类型 6音乐 -->
2025-11-13 18:35:10 +08:00
<ElTabPane :name="ReplyType.Music">
<template #label>
<ElRow align="middle"><IconifyIcon icon="ep:service" />音乐</ElRow>
2025-11-03 14:04:00 +08:00
</template>
<TabMusic v-model="reply" />
2025-11-13 18:35:10 +08:00
</ElTabPane>
</ElTabs>
2025-11-03 14:04:00 +08:00
</template>
2025-11-13 18:35:10 +08:00
<style lang="scss" scoped></style>