chore: 合并远程 dev 分支代码

This commit is contained in:
YunaiV
2025-11-13 20:45:00 +08:00
108 changed files with 542 additions and 3074 deletions

View File

@@ -0,0 +1,32 @@
export enum ReplyType {
Image = 'image',
Music = 'music',
News = 'news',
Text = 'text',
Video = 'video',
Voice = 'voice',
}
export enum NewsType {
Draft = '2',
Published = '1',
}
export enum MaterialType {
Image = 'image',
News = 'news',
Video = 'video',
Voice = 'voice',
}
export enum MsgType {
Event = 'event',
Image = 'image',
Link = 'link',
Location = 'location',
Music = 'music',
News = 'news',
Text = 'text',
Video = 'video',
Voice = 'voice',
}

View File

@@ -0,0 +1,11 @@
export * from './constants';
export * from './wx-account-select';
export * from './wx-location';
export * from './wx-material-select';
export * from './wx-msg';
export * from './wx-music';
export * from './wx-news';
export * from './wx-reply';
export * from './wx-video-play';
export * from './wx-voice-play';

View File

@@ -3,7 +3,7 @@ import type { SelectValue } from 'ant-design-vue/es/select';
import type { MpAccountApi } from '#/api/mp/account';
import { onMounted, reactive, ref } from 'vue';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { message, Select } from 'ant-design-vue';
@@ -18,7 +18,7 @@ const emit = defineEmits<{
const { push } = useRouter();
const account: MpAccountApi.Account = reactive({
const account = ref<MpAccountApi.Account>({
id: -1,
name: '',
}); //
@@ -36,9 +36,9 @@ async function handleQuery() {
//
const first = accountList.value[0];
if (first) {
account.id = first.id;
account.name = first.name;
emit('change', account.id, account.name);
account.value.id = first.id;
account.value.name = first.name;
emit('change', account.value.id, account.value.name);
}
}
@@ -46,8 +46,8 @@ async function handleQuery() {
function onChanged(id: SelectValue) {
const found = accountList.value.find((v) => v.id === id);
if (found) {
account.name = found.name;
emit('change', account.id, account.name);
account.value.name = found.name;
emit('change', account.value.id, account.value.name);
}
}

View File

@@ -1,2 +1 @@
// TODO @dylanyudao-ui-admin-vben-v5/apps/web-antd/src/views/mp/components 要不加个 index.ts统一 export 所有的组件
export { default as WxAccountSelect } from './main.vue';
export { default as WxAccountSelect } from './account-select.vue';

View File

@@ -1 +1,2 @@
export { default as WxLocation } from './main.vue';
export * from './types';
export { default as WxLocation } from './wx-location.vue';

View File

@@ -0,0 +1,6 @@
export interface WxLocationProps {
label: string;
locationX: number;
locationY: number;
qqMapKey?: string;
}

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup>
import type { WxLocationProps } from './types';
import { computed } from 'vue';
import { IconifyIcon } from '@vben/icons';
@@ -8,17 +10,9 @@ import { Col, Row } from 'ant-design-vue';
defineOptions({ name: 'WxLocation' });
// TODO @dylanapps/web-antd/src/views/mall/trade/delivery/pickUpStore/modules/form.vue key
const props = withDefaults(
defineProps<{
label: string;
locationX: number;
locationY: number;
qqMapKey?: string;
}>(),
{
qqMapKey: 'TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E', // QQ https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
},
);
const props = withDefaults(defineProps<WxLocationProps>(), {
qqMapKey: 'TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E', // QQ https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
});
const mapUrl = computed(() => {
return `https://map.qq.com/?type=marker&isopeninfowin=1&markertype=1&pointx=${props.locationY}&pointy=${props.locationX}&name=${props.label}&ref=yudao`;
@@ -45,7 +39,7 @@ defineExpose({
<img :src="mapImageUrl" alt="地图位置" />
</Row>
<Row class="mt-2">
<IconifyIcon icon="mdi:map-marker" class="mr-1" />
<IconifyIcon icon="lucide:map-pin" class="mr-1" />
{{ label }}
</Row>
</Col>

View File

@@ -1,3 +1 @@
export { default as WxMaterialSelect } from './main.vue';
export { MaterialType, NewsType } from './types';
export { default as WxMaterialSelect } from './wx-material-select.vue';

View File

@@ -1,11 +0,0 @@
export enum NewsType {
Draft = '2',
Published = '1',
}
export enum MaterialType {
Image = 'image',
News = 'news',
Video = 'video',
Voice = 'voice',
}

View File

@@ -9,14 +9,12 @@ import { IconifyIcon } from '@vben/icons';
import { Button, Pagination, Row, Spin } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import * as MpDraftApi from '#/api/mp/draft';
import * as MpFreePublishApi from '#/api/mp/freePublish';
import * as MpMaterialApi from '#/api/mp/material';
import { WxNews } from '#/views/mp/components/wx-news';
import { WxVideoPlayer } from '#/views/mp/components/wx-video-play';
import { WxVoicePlayer } from '#/views/mp/components/wx-voice-play';
import { getDraftPage } from '#/api/mp/draft';
import { getFreePublishPage } from '#/api/mp/freePublish';
import { getMaterialPage } from '#/api/mp/material';
import { WxNews, WxVideoPlayer, WxVoicePlayer } from '#/views/mp/components';
import { NewsType } from './types';
import { NewsType } from '../constants';
defineOptions({ name: 'WxMaterialSelect' });
@@ -142,7 +140,7 @@ const [VoiceGrid, voiceGridApi] = useVbenVxeGrid({
return { list: [], total: 0 };
}
// TODO @dylan MpMaterialApi
return await MpMaterialApi.getMaterialPage({
return await getMaterialPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
accountId: finalAccountId,
@@ -178,7 +176,7 @@ const [VideoGrid, videoGridApi] = useVbenVxeGrid({
if (finalAccountId === undefined || finalAccountId === null) {
return { list: [], total: 0 };
}
return await MpMaterialApi.getMaterialPage({
return await getMaterialPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
accountId: finalAccountId,
@@ -202,7 +200,7 @@ function selectMaterialFun(item: any) {
}
async function getMaterialPageFun() {
const data = await MpMaterialApi.getMaterialPage({
const data = await getMaterialPage({
...queryParams,
type: props.type,
});
@@ -211,7 +209,7 @@ async function getMaterialPageFun() {
}
async function getFreePublishPageFun() {
const data = await MpFreePublishApi.getFreePublishPage(queryParams);
const data = await getFreePublishPage(queryParams);
data.list.forEach((item: any) => {
const articles = item.content.newsItem;
articles.forEach((article: any) => {
@@ -223,7 +221,7 @@ async function getFreePublishPageFun() {
}
async function getDraftPageFun() {
const data = await MpDraftApi.getDraftPage(queryParams);
const data = await getDraftPage(queryParams);
data.list.forEach((draft: any) => {
const articles = draft.content.newsItem;
articles.forEach((article: any) => {
@@ -301,7 +299,7 @@ watch(
<Button type="primary" @click="selectMaterialFun(item)">
选择
<template #icon>
<IconifyIcon icon="mdi:check-circle" />
<IconifyIcon icon="lucide:circle-check" />
</template>
</Button>
</Row>
@@ -328,7 +326,7 @@ watch(
<Button type="link" @click="selectMaterialFun(row)">
选择
<template #icon>
<IconifyIcon icon="mdi:plus" />
<IconifyIcon icon="lucide:plus" />
</template>
</Button>
</template>
@@ -345,7 +343,7 @@ watch(
<Button type="link" @click="selectMaterialFun(row)">
选择
<template #icon>
<IconifyIcon icon="mdi:plus-circle" />
<IconifyIcon icon="lucide:circle-plus" />
</template>
</Button>
</template>
@@ -363,7 +361,7 @@ watch(
<Button type="primary" @click="selectMaterialFun(item)">
选择
<template #icon>
<IconifyIcon icon="mdi:check-circle" />
<IconifyIcon icon="lucide:circle-check" />
</template>
</Button>
</Row>

View File

@@ -1,4 +1,4 @@
.avue-card {
.mp-card {
&__item {
box-sizing: border-box;
height: 200px;
@@ -99,18 +99,18 @@
}
/** joolun 额外加的 */
.avue-comment__main {
.mp-comment__main {
flex: unset !important;
margin: 0 8px !important;
border-radius: 5px !important;
}
.avue-comment__header {
.mp-comment__header {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.avue-comment__body {
.mp-comment__body {
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
}

View File

@@ -1,5 +1,5 @@
/* 来自 https://github.com/nmxiaowei/avue/blob/master/styles/src/element-ui/comment.scss */
.avue-comment {
.mp-comment {
display: flex;
align-items: flex-start;
margin-bottom: 30px;
@@ -7,7 +7,7 @@
&--reverse {
flex-direction: row-reverse;
.avue-comment__main {
.mp-comment__main {
&::before,
&::after {
right: -8px;

View File

@@ -1,3 +1,3 @@
export { default as WxMsg } from './main.vue';
export * from './types';
export { MsgType } from './types';
export { default as WxMsg } from './wx-msg.vue';

View File

@@ -1,8 +1,6 @@
<script lang="ts" setup>
import { Tag } from 'ant-design-vue';
// TODO @dylanvue + 线
defineOptions({ name: 'MsgEvent' });
defineProps<{

View File

@@ -1,12 +1,10 @@
<script lang="ts" setup>
import type { User } from '../types';
import type { User } from './types';
import { preferences } from '@vben/preferences';
import { formatDateTime } from '@vben/utils';
import Msg from './Msg.vue';
// TODO @dylanvue + 线
import Msg from './msg.vue';
defineOptions({ name: 'MsgList' });
@@ -15,6 +13,7 @@ const props = defineProps<{
list: any[];
user: User;
}>();
const SendFrom = {
MpBot: 2,
User: 1,
@@ -26,31 +25,30 @@ function getAvatar(sendFrom: number) {
: preferences.app.defaultAvatar;
}
// TODO @dylanSendFrom
function getNickname(sendFrom: SendFrom) {
function getNickname(sendFrom: number) {
return sendFrom === SendFrom.User ? props.user.nickname : '公众号';
}
</script>
<template>
<div class="execution" v-for="item in props.list" :key="item.id">
<div
class="avue-comment"
:class="{ 'avue-comment--reverse': item.sendFrom === SendFrom.MpBot }"
class="mp-comment"
:class="{ 'mp-comment--reverse': item.sendFrom === SendFrom.MpBot }"
>
<div class="avatar-div">
<img :src="getAvatar(item.sendFrom)" class="avue-comment__avatar" />
<div class="avue-comment__author">
<img :src="getAvatar(item.sendFrom)" class="mp-comment__avatar" />
<div class="mp-comment__author">
{{ getNickname(item.sendFrom) }}
</div>
</div>
<div class="avue-comment__main">
<div class="avue-comment__header">
<div class="avue-comment__create_time">
<div class="mp-comment__main">
<div class="mp-comment__header">
<div class="mp-comment__create_time">
{{ formatDateTime(item.createTime) }}
</div>
</div>
<div
class="avue-comment__body"
class="mp-comment__body"
:style="
item.sendFrom === SendFrom.MpBot ? 'background: #6BED72;' : ''
"
@@ -64,10 +62,11 @@ function getNickname(sendFrom: SendFrom) {
<style lang="scss" scoped>
/* 因为 joolun 实现依赖 avue 组件,该页面使用了 comment.scss、card.scc */
/** TODO @dylan看看有没适合 tindwind 的哈。 */
@import url('../comment.scss');
@import url('../card.scss');
@import url('./comment.scss');
@import url('./card.scss');
.avatar-div {
width: 80px;

View File

@@ -1,16 +1,16 @@
<script lang="ts" setup>
import { IconifyIcon } from '@vben/icons';
import { WxLocation } from '#/views/mp/components/wx-location';
import { WxMusic } from '#/views/mp/components/wx-music';
import { WxNews } from '#/views/mp/components/wx-news';
import { WxVideoPlayer } from '#/views/mp/components/wx-video-play';
import { WxVoicePlayer } from '#/views/mp/components/wx-voice-play';
import {
WxLocation,
WxMusic,
WxNews,
WxVideoPlayer,
WxVoicePlayer,
} from '#/views/mp/components';
import { MsgType } from '../types';
import MsgEvent from './MsgEvent.vue';
// TODO @dylanvue + 线
import { MsgType } from '../constants';
import MsgEvent from './msg-event.vue';
defineOptions({ name: 'Msg' });
@@ -45,7 +45,7 @@ defineProps<{
<div v-else-if="item.type === MsgType.Link" class="flex flex-col gap-2">
<a :href="item.url" target="_blank" class="text-success no-underline">
<div class="flex items-center text-sm font-medium text-[#52c41a]">
<IconifyIcon icon="mdi:link" class="mr-1" />
<IconifyIcon icon="lucide:link" class="mr-1" />
{{ item.title }}
</div>
</a>

View File

@@ -1,15 +1,3 @@
export enum MsgType {
Event = 'event',
Image = 'image',
Link = 'link',
Location = 'location',
Music = 'music',
News = 'news',
Text = 'text',
Video = 'video',
Voice = 'voice',
}
export interface User {
accountId: number;
avatar: string;

View File

@@ -9,9 +9,9 @@ import { Button, message, Spin } from 'ant-design-vue';
import { getMessagePage, sendMessage } from '#/api/mp/message';
import { getUser } from '#/api/mp/user';
import { WxReplySelect } from '#/views/mp/components/wx-reply';
import { WxReply } from '#/views/mp/components';
import MsgList from './components/MsgList.vue';
import MsgList from './msg-list.vue';
defineOptions({ name: 'WxMsg' });
@@ -43,7 +43,7 @@ const reply = ref<any>({
type: 'text',
}); //
const replySelectRef = ref<InstanceType<typeof WxReplySelect> | null>(null); // WxReplySelectref
const replySelectRef = ref<InstanceType<typeof WxReply> | null>(null); // WxReplyref
const msgDivRef = ref<HTMLDivElement | null>(null); // ref
/** 完成加载 */

View File

@@ -1 +1 @@
export { default as WxMusic } from './main.vue';
export { default as WxMusic } from './wx-music.vue';

View File

@@ -0,0 +1,7 @@
export interface WxMusicProps {
title?: string;
description?: string;
musicUrl?: string;
hqMusicUrl?: string;
thumbMediaUrl: string;
}

View File

@@ -1,23 +1,17 @@
<script lang="ts" setup>
import type { WxMusicProps } from './types';
import { computed } from 'vue';
defineOptions({ name: 'WxMusic' });
const props = withDefaults(
defineProps<{
description?: string;
hqMusicUrl?: string;
musicUrl?: string;
thumbMediaUrl: string;
title?: string;
}>(),
{
title: '',
description: '',
musicUrl: '',
hqMusicUrl: '',
},
);
const props = withDefaults(defineProps<WxMusicProps>(), {
title: '',
description: '',
musicUrl: '',
hqMusicUrl: '',
thumbMediaUrl: '',
});
const href = computed(() => props.hqMusicUrl || props.musicUrl);

View File

@@ -1 +1 @@
export { default as WxNews } from './main.vue';
export { default as WxNews } from './wx-news.vue';

View File

@@ -1,4 +1,3 @@
export type { NewsType, Reply, ReplyType } from './components/types';
export { createEmptyReply } from './components/types';
export * from './types';
export { default as WxReplySelect } from './main.vue';
export { default as WxReply } from './wx-reply.vue';

View File

@@ -10,11 +10,9 @@ import { useAccessStore } from '@vben/stores';
import { Button, Col, message, Modal, Row, Upload } from 'ant-design-vue';
import { WxMaterialSelect } from '#/views/mp/components/wx-material-select';
import { WxMaterialSelect } from '#/views/mp/components';
import { UploadType, useBeforeUpload } from '#/views/mp/hooks/useUpload';
// TODO @dylan
defineOptions({ name: 'TabImage' });
const props = defineProps<{
@@ -110,7 +108,7 @@ function selectMaterial(item: any) {
<Row class="ope-row" justify="center">
<Button danger shape="circle" @click="onDelete">
<template #icon>
<IconifyIcon icon="mdi:delete" />
<IconifyIcon icon="lucide:trash-2" />
</template>
</Button>
</Row>
@@ -123,7 +121,7 @@ function selectMaterial(item: any) {
<Button type="primary" @click="showDialog = true">
素材库选择
<template #icon>
<IconifyIcon icon="mdi:check-circle" />
<IconifyIcon icon="lucide:circle-check" />
</template>
</Button>
<Modal
@@ -154,7 +152,7 @@ function selectMaterial(item: any) {
<Button type="primary">
上传图片
<template #icon>
<IconifyIcon icon="mdi:upload" />
<IconifyIcon icon="lucide:upload" />
</template>
</Button>
</Upload>

View File

@@ -18,11 +18,9 @@ import {
Upload,
} from 'ant-design-vue';
import { WxMaterialSelect } from '#/views/mp/components/wx-material-select';
import { WxMaterialSelect } from '#/views/mp/components';
import { UploadType, useBeforeUpload } from '#/views/mp/hooks/useUpload';
// TODO @dylan
defineOptions({ name: 'TabMusic' });
const props = defineProps<{
@@ -116,7 +114,7 @@ function selectMaterial(item: any) {
/>
<IconifyIcon
v-else
icon="mdi:plus"
icon="lucide:plus"
:size="40"
class="text-gray-400"
/>

View File

@@ -7,12 +7,9 @@ import { IconifyIcon } from '@vben/icons';
import { Button, Col, Modal, Row } from 'ant-design-vue';
import { WxMaterialSelect } from '#/views/mp/components/wx-material-select';
import { WxNews } from '#/views/mp/components/wx-news';
import { WxMaterialSelect, WxNews } from '#/views/mp/components';
import { NewsType } from './types';
// TODO @dylan
import { NewsType } from '../constants';
defineOptions({ name: 'TabNews' });
@@ -53,7 +50,7 @@ function onDelete() {
<Col class="ope-row">
<Button danger shape="circle" @click="onDelete">
<template #icon>
<IconifyIcon icon="mdi:delete" />
<IconifyIcon icon="lucide:trash-2" />
</template>
</Button>
</Col>
@@ -70,7 +67,7 @@ function onDelete() {
: '选择草稿箱图文'
}}
<template #icon>
<IconifyIcon icon="mdi:check-circle" />
<IconifyIcon icon="lucide:circle-check" />
</template>
</Button>
</Col>

View File

@@ -3,8 +3,6 @@ import { computed } from 'vue';
import { Textarea } from 'ant-design-vue';
// TODO @dylan
const props = defineProps<{
modelValue?: null | string;
}>();

View File

@@ -18,12 +18,9 @@ import {
Upload,
} from 'ant-design-vue';
import { WxMaterialSelect } from '#/views/mp/components/wx-material-select';
import { WxVideoPlayer } from '#/views/mp/components/wx-video-play';
import { WxMaterialSelect, WxVideoPlayer } from '#/views/mp/components';
import { UploadType, useBeforeUpload } from '#/views/mp/hooks/useUpload';
// TODO @dylan
defineOptions({ name: 'TabVideo' });
const props = defineProps<{
@@ -143,7 +140,7 @@ function selectMaterial(item: any) {
<Button type="primary" @click="showDialog = true">
素材库选择
<template #icon>
<IconifyIcon icon="mdi:check-circle" />
<IconifyIcon icon="lucide:circle-check" />
</template>
</Button>
<Modal
@@ -174,7 +171,7 @@ function selectMaterial(item: any) {
<Button type="primary">
新建视频
<template #icon>
<IconifyIcon icon="mdi:upload" />
<IconifyIcon icon="lucide:upload" />
</template>
</Button>
</Upload>

View File

@@ -10,12 +10,9 @@ import { useAccessStore } from '@vben/stores';
import { Button, Col, message, Modal, Row, Upload } from 'ant-design-vue';
import { WxMaterialSelect } from '#/views/mp/components/wx-material-select';
import { WxVoicePlayer } from '#/views/mp/components/wx-voice-play';
import { WxMaterialSelect, WxVoicePlayer } from '#/views/mp/components';
import { UploadType, useBeforeUpload } from '#/views/mp/hooks/useUpload';
// TODO @dylan
defineOptions({ name: 'TabVoice' });
const props = defineProps<{
@@ -112,7 +109,7 @@ function selectMaterial(item: Reply) {
<Row class="ope-row" justify="center">
<Button danger shape="circle" @click="onDelete">
<template #icon>
<IconifyIcon icon="mdi:delete" />
<IconifyIcon icon="lucide:trash-2" />
</template>
</Button>
</Row>
@@ -124,7 +121,7 @@ function selectMaterial(item: Reply) {
<Button type="primary" @click="showDialog = true">
素材库选择
<template #icon>
<IconifyIcon icon="mdi:check-circle" />
<IconifyIcon icon="lucide:circle-check" />
</template>
</Button>
<Modal
@@ -155,7 +152,7 @@ function selectMaterial(item: Reply) {
<Button type="primary">
点击上传
<template #icon>
<IconifyIcon icon="mdi:upload" />
<IconifyIcon icon="lucide:upload" />
</template>
</Button>
</Upload>

View File

@@ -1,15 +1,8 @@
import type { Ref } from 'vue';
import { unref } from 'vue';
import type { ReplyType } from '../constants';
export enum ReplyType {
Image = 'image',
Music = 'music',
News = 'news',
Text = 'text',
Video = 'video',
Voice = 'voice',
}
import { unref } from 'vue';
export interface Reply {
accountId: number;
@@ -28,13 +21,8 @@ export interface Reply {
url?: null | string;
}
export enum NewsType {
Draft = '2',
Published = '1',
}
/** 利用旧的reply[accountId, type]初始化新的Reply */
export const createEmptyReply = (old: Ref<Reply> | Reply): Reply => {
export function createEmptyReply(old: Ref<Reply> | Reply): Reply {
return {
accountId: unref(old).accountId,
articles: [],
@@ -51,4 +39,4 @@ export const createEmptyReply = (old: Ref<Reply> | Reply): Reply => {
type: unref(old).type,
url: null,
};
};
}

View File

@@ -8,7 +8,7 @@
支持发送视频消息时支持新建视频
-->
<script lang="ts" setup>
import type { Reply } from './components/types';
import type { Reply } from './types';
import { computed, ref, unref, watch } from 'vue';
@@ -16,13 +16,14 @@ import { IconifyIcon } from '@vben/icons';
import { Row, Tabs } from 'ant-design-vue';
import TabImage from './components/TabImage.vue';
import TabMusic from './components/TabMusic.vue';
import TabNews from './components/TabNews.vue';
import TabText from './components/TabText.vue';
import TabVideo from './components/TabVideo.vue';
import TabVoice from './components/TabVoice.vue';
import { createEmptyReply, NewsType, ReplyType } from './components/types';
import { NewsType, ReplyType } from '../constants';
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';
import { createEmptyReply } from './types';
defineOptions({ name: 'WxReplySelect' });
@@ -88,7 +89,7 @@ defineExpose({
<Tabs.TabPane :key="ReplyType.Text">
<template #tab>
<Row align="middle">
<IconifyIcon icon="mdi:text" class="mr-1" />
<IconifyIcon icon="lucide:file-text" class="mr-1" />
文本
</Row>
</template>
@@ -99,7 +100,7 @@ defineExpose({
<Tabs.TabPane :key="ReplyType.Image">
<template #tab>
<Row align="middle">
<IconifyIcon icon="mdi:image" class="mr-1" />
<IconifyIcon icon="lucide:image" class="mr-1" />
图片
</Row>
</template>
@@ -110,7 +111,7 @@ defineExpose({
<Tabs.TabPane :key="ReplyType.Voice">
<template #tab>
<Row align="middle">
<IconifyIcon icon="mdi:microphone" class="mr-1" />
<IconifyIcon icon="lucide:mic" class="mr-1" />
语音
</Row>
</template>
@@ -121,7 +122,7 @@ defineExpose({
<Tabs.TabPane :key="ReplyType.Video">
<template #tab>
<Row align="middle">
<IconifyIcon icon="mdi:video" class="mr-1" />
<IconifyIcon icon="lucide:video" class="mr-1" />
视频
</Row>
</template>
@@ -132,7 +133,7 @@ defineExpose({
<Tabs.TabPane :key="ReplyType.News">
<template #tab>
<Row align="middle">
<IconifyIcon icon="mdi:newspaper" class="mr-1" />
<IconifyIcon icon="lucide:newspaper" class="mr-1" />
图文
</Row>
</template>
@@ -143,7 +144,7 @@ defineExpose({
<Tabs.TabPane :key="ReplyType.Music">
<template #tab>
<Row align="middle">
<IconifyIcon icon="mdi:music" class="mr-1" />
<IconifyIcon icon="lucide:music" class="mr-1" />
音乐
</Row>
</template>

View File

@@ -1 +1 @@
export { default as WxVideoPlayer } from './main.vue';
export { default as WxVideoPlayer } from './wx-video-play.vue';

View File

@@ -26,7 +26,7 @@ function playVideo() {
<div class="cursor-pointer" @click="playVideo()">
<!-- 提示 -->
<div class="flex items-center">
<IconifyIcon icon="mdi:play-circle" :size="32" class="mr-2" />
<IconifyIcon icon="lucide:circle-play" :size="32" class="mr-2" />
<p class="text-sm">点击播放视频</p>
</div>

View File

@@ -1 +1 @@
export { default as WxVoicePlayer } from './main.vue';
export { default as WxVoicePlayer } from './wx-voice-play.vue';

View File

@@ -68,8 +68,12 @@ function amrStop() {
<!-- 微信消息 - 语音播放 -->
<div class="wx-voice-div cursor-pointer" @click="playVoice">
<div class="flex items-center">
<IconifyIcon v-if="playing !== true" icon="mdi:play-circle" :size="32" />
<IconifyIcon v-else icon="mdi:pause-circle" :size="32" />
<IconifyIcon
v-if="playing !== true"
icon="lucide:circle-play"
:size="32"
/>
<IconifyIcon v-else icon="lucide:circle-pause" :size="32" />
<span v-if="duration" class="amr-duration">{{ duration }} </span>
</div>
<div v-if="content" class="mt-2">