feat: mp
This commit is contained in:
@@ -7,7 +7,7 @@ import { DICT_TYPE } from '@vben/constants';
|
|||||||
|
|
||||||
import { WxAccountSelect } from '#/views/mp/modules/wx-account-select';
|
import { WxAccountSelect } from '#/views/mp/modules/wx-account-select';
|
||||||
|
|
||||||
import { MsgType } from './modules/types';
|
import { MsgType } from './components/types';
|
||||||
|
|
||||||
/** 获取表格列配置 */
|
/** 获取表格列配置 */
|
||||||
export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns {
|
export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns {
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
|||||||
import * as MpAutoReplyApi from '#/api/mp/autoReply';
|
import * as MpAutoReplyApi from '#/api/mp/autoReply';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
|
import ReplyContentCell from './components/ReplyTable.vue';
|
||||||
|
import { MsgType } from './components/types';
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
import Form from './modules/form.vue';
|
import Form from './modules/form.vue';
|
||||||
import ReplyContentCell from './modules/ReplyTable.vue';
|
|
||||||
import { MsgType } from './modules/types';
|
|
||||||
|
|
||||||
defineOptions({ name: 'MpAutoReply' });
|
defineOptions({ name: 'MpAutoReply' });
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import { useVbenModal } from '@vben/common-ui';
|
|||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
import * as MpAutoReplyApi from '#/api/mp/autoReply';
|
import { createAutoReply, updateAutoReply } from '#/api/mp/autoReply';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import { ReplyType } from '#/views/mp/modules/wx-reply/types';
|
import { ReplyType } from '#/views/mp/modules/wx-reply/types';
|
||||||
|
|
||||||
import ReplyForm from './ReplyForm.vue';
|
import ReplyForm from '../components/ReplyForm.vue';
|
||||||
import { MsgType } from './types';
|
import { MsgType } from '../components/types';
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
|
|
||||||
@@ -52,10 +52,10 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
try {
|
try {
|
||||||
if (replyForm.value.id === undefined) {
|
if (replyForm.value.id === undefined) {
|
||||||
await MpAutoReplyApi.createAutoReply(submitForm);
|
await createAutoReply(submitForm);
|
||||||
message.success('新增成功');
|
message.success('新增成功');
|
||||||
} else {
|
} else {
|
||||||
await MpAutoReplyApi.updateAutoReply(submitForm);
|
await updateAutoReply(submitForm);
|
||||||
message.success('修改成功');
|
message.success('修改成功');
|
||||||
}
|
}
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ function onUploadError(err: Error) {
|
|||||||
/>
|
/>
|
||||||
<IconifyIcon
|
<IconifyIcon
|
||||||
v-else
|
v-else
|
||||||
icon="ep:plus"
|
icon="lucide:plus"
|
||||||
class="avatar-uploader-icon"
|
class="avatar-uploader-icon"
|
||||||
:class="isFirst ? 'avatar' : 'avatar1'"
|
:class="isFirst ? 'avatar' : 'avatar1'"
|
||||||
/>
|
/>
|
||||||
@@ -11,15 +11,9 @@ const props = defineProps<{
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="draft-content">
|
<div class="p-2.5">
|
||||||
<div v-if="props.row.content && props.row.content.newsItem">
|
<div v-if="props.row.content && props.row.content.newsItem">
|
||||||
<WxNews :articles="props.row.content.newsItem" />
|
<WxNews :articles="props.row.content.newsItem" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.draft-content {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -109,7 +109,7 @@ function plusNews() {
|
|||||||
size="small"
|
size="small"
|
||||||
@click="() => moveDownNews(index)"
|
@click="() => moveDownNews(index)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:arrow-down-bold" />
|
<IconifyIcon icon="lucide:arrow-down" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-if="isCreating"
|
v-if="isCreating"
|
||||||
@@ -119,7 +119,7 @@ function plusNews() {
|
|||||||
size="small"
|
size="small"
|
||||||
@click="() => removeNews(index)"
|
@click="() => removeNews(index)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:delete" />
|
<IconifyIcon icon="lucide:trash-2" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -143,7 +143,7 @@ function plusNews() {
|
|||||||
size="small"
|
size="small"
|
||||||
@click="() => moveDownNews(index)"
|
@click="() => moveDownNews(index)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:arrow-down-bold" />
|
<IconifyIcon icon="lucide:arrow-down" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-if="index > 0"
|
v-if="index > 0"
|
||||||
@@ -152,7 +152,7 @@ function plusNews() {
|
|||||||
size="small"
|
size="small"
|
||||||
@click="() => moveUpNews(index)"
|
@click="() => moveUpNews(index)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:arrow-up-bold" />
|
<IconifyIcon icon="lucide:arrow-up" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-if="isCreating"
|
v-if="isCreating"
|
||||||
@@ -162,7 +162,7 @@ function plusNews() {
|
|||||||
shape="circle"
|
shape="circle"
|
||||||
@click="() => removeNews(index)"
|
@click="() => removeNews(index)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:delete" />
|
<IconifyIcon icon="lucide:trash-2" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -174,7 +174,7 @@ function plusNews() {
|
|||||||
@click="plusNews"
|
@click="plusNews"
|
||||||
v-if="newsList.length < 8 && isCreating"
|
v-if="newsList.length < 8 && isCreating"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:plus" />
|
<IconifyIcon icon="lucide:plus" />
|
||||||
</Button>
|
</Button>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { Article } from './modules/types';
|
import type { Article } from './components/types';
|
||||||
|
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
@@ -12,10 +12,10 @@ import { message } from 'ant-design-vue';
|
|||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import * as MpDraftApi from '#/api/mp/draft';
|
import * as MpDraftApi from '#/api/mp/draft';
|
||||||
import * as MpFreePublishApi from '#/api/mp/freePublish';
|
import * as MpFreePublishApi from '#/api/mp/freePublish';
|
||||||
import { createEmptyNewsItem } from '#/views/mp/draft/modules/types';
|
import { createEmptyNewsItem } from '#/views/mp/draft/components/types';
|
||||||
|
|
||||||
|
import DraftTableCell from './components/draft-table.vue';
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
import DraftTableCell from './modules/draft-table.vue';
|
|
||||||
import Form from './modules/form.vue';
|
import Form from './modules/form.vue';
|
||||||
|
|
||||||
defineOptions({ name: 'MpDraft' });
|
defineOptions({ name: 'MpDraft' });
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { NewsItem } from './types';
|
import type { NewsItem } from '../components/types';
|
||||||
|
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
@@ -7,9 +7,9 @@ import { confirm, useVbenModal } from '@vben/common-ui';
|
|||||||
|
|
||||||
import { message, Spin } from 'ant-design-vue';
|
import { message, Spin } from 'ant-design-vue';
|
||||||
|
|
||||||
import * as MpDraftApi from '#/api/mp/draft';
|
import { createDraft, updateDraft } from '#/api/mp/draft';
|
||||||
|
|
||||||
import NewsForm from './news-form.vue';
|
import NewsForm from '../components/news-form.vue';
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
try {
|
try {
|
||||||
if (formData.value.isCreating) {
|
if (formData.value.isCreating) {
|
||||||
await MpDraftApi.createDraft(formData.value.accountId, newsList.value);
|
await createDraft(formData.value.accountId, newsList.value);
|
||||||
message.success('新增成功');
|
message.success('新增成功');
|
||||||
} else if (formData.value.mediaId) {
|
} else if (formData.value.mediaId) {
|
||||||
await MpDraftApi.updateDraft(
|
await updateDraft(
|
||||||
formData.value.accountId,
|
formData.value.accountId,
|
||||||
formData.value.mediaId,
|
formData.value.mediaId,
|
||||||
newsList.value,
|
newsList.value,
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ function onChildDragEnd({ newIndex }: { newIndex: number }) {
|
|||||||
class="menu-item"
|
class="menu-item"
|
||||||
:class="{ active: props.activeIndex === `${x}` }"
|
:class="{ active: props.activeIndex === `${x}` }"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:fold" color="black" />{{ parent.name }}
|
<IconifyIcon icon="lucide:panel-right-open" color="black" />
|
||||||
|
{{ parent.name }}
|
||||||
</div>
|
</div>
|
||||||
<!-- 以下为二级菜单-->
|
<!-- 以下为二级菜单-->
|
||||||
<div class="submenu" v-if="props.parentIndex === x && parent.children">
|
<div class="submenu" v-if="props.parentIndex === x && parent.children">
|
||||||
@@ -164,7 +165,7 @@ function onChildDragEnd({ newIndex }: { newIndex: number }) {
|
|||||||
v-if="!parent.children || parent.children.length < 5"
|
v-if="!parent.children || parent.children.length < 5"
|
||||||
@click="addSubMenu(x, parent)"
|
@click="addSubMenu(x, parent)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:plus" class="plus" />
|
<IconifyIcon icon="lucide:plus" class="plus" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -177,7 +178,7 @@ function onChildDragEnd({ newIndex }: { newIndex: number }) {
|
|||||||
v-if="menuList.length < 3"
|
v-if="menuList.length < 3"
|
||||||
@click="addMenu"
|
@click="addMenu"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="ep:plus" class="plus" />
|
<IconifyIcon icon="lucide:plus" class="plus" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { handleTree } from '@vben/utils';
|
|||||||
|
|
||||||
import { Button, Form, message } from 'ant-design-vue';
|
import { Button, Form, message } from 'ant-design-vue';
|
||||||
|
|
||||||
import * as MpMenuApi from '#/api/mp/menu';
|
import { deleteMenu, getMenuList, saveMenu } from '#/api/mp/menu';
|
||||||
import { MenuEditor, MenuPreviewer } from '#/views/mp/menu/components';
|
import { MenuEditor, MenuPreviewer } from '#/views/mp/menu/components';
|
||||||
import { Level, MENU_NOT_SELECTED } from '#/views/mp/menu/data';
|
import { Level, MENU_NOT_SELECTED } from '#/views/mp/menu/data';
|
||||||
import { WxAccountSelect } from '#/views/mp/modules/wx-account-select';
|
import { WxAccountSelect } from '#/views/mp/modules/wx-account-select';
|
||||||
@@ -60,7 +60,7 @@ function onAccountChanged(id: number, name: string) {
|
|||||||
async function getList() {
|
async function getList() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
const data = await MpMenuApi.getMenuList(accountId.value);
|
const data = await getMenuList(accountId.value);
|
||||||
const menuData = menuListToFrontend(data);
|
const menuData = menuListToFrontend(data);
|
||||||
menuList.value = handleTree(menuData, 'id') as Menu[];
|
menuList.value = handleTree(menuData, 'id') as Menu[];
|
||||||
} finally {
|
} finally {
|
||||||
@@ -178,7 +178,7 @@ async function onSave() {
|
|||||||
duration: 0,
|
duration: 0,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await MpMenuApi.saveMenu(accountId.value, menuListToBackend());
|
await saveMenu(accountId.value, menuListToBackend());
|
||||||
getList();
|
getList();
|
||||||
message.success('发布成功');
|
message.success('发布成功');
|
||||||
} finally {
|
} finally {
|
||||||
@@ -198,7 +198,7 @@ async function onClear() {
|
|||||||
duration: 0,
|
duration: 0,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await MpMenuApi.deleteMenu(accountId.value);
|
await deleteMenu(accountId.value);
|
||||||
handleQuery();
|
handleQuery();
|
||||||
message.success('清空成功');
|
message.success('清空成功');
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
【微信消息 - 定位】TODO @Dhb52 目前未启用
|
【微信消息 - 定位】TODO @Dhb52 目前未启用
|
||||||
-->
|
-->
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
import { Col, Row } from 'ant-design-vue';
|
import { Col, Row } from 'ant-design-vue';
|
||||||
|
|
||||||
defineOptions({ name: 'WxLocation' });
|
defineOptions({ name: 'WxLocation' });
|
||||||
@@ -53,7 +55,7 @@ defineExpose({
|
|||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Icon icon="ep:location" />
|
<IconifyIcon icon="lucide:map-pin" />
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import { formatTime } from '@vben/utils';
|
|||||||
|
|
||||||
import { Button, Pagination, Row, Spin, Table } from 'ant-design-vue';
|
import { Button, Pagination, Row, Spin, Table } from 'ant-design-vue';
|
||||||
|
|
||||||
import * as MpDraftApi from '#/api/mp/draft';
|
import { getDraftPage } from '#/api/mp/draft';
|
||||||
import * as MpFreePublishApi from '#/api/mp/freePublish';
|
import { getFreePublishPage } from '#/api/mp/freePublish';
|
||||||
import * as MpMaterialApi from '#/api/mp/material';
|
import { getMaterialPage } from '#/api/mp/material';
|
||||||
import { WxNews } from '#/views/mp/modules/wx-news';
|
import { WxNews } from '#/views/mp/modules/wx-news';
|
||||||
import { WxVideoPlayer } from '#/views/mp/modules/wx-video-play';
|
import { WxVideoPlayer } from '#/views/mp/modules/wx-video-play';
|
||||||
import { WxVoicePlayer } from '#/views/mp/modules/wx-voice-play';
|
import { WxVoicePlayer } from '#/views/mp/modules/wx-voice-play';
|
||||||
@@ -69,7 +69,7 @@ async function getPage() {
|
|||||||
|
|
||||||
/** 获取素材分页 */
|
/** 获取素材分页 */
|
||||||
async function getMaterialPageFun() {
|
async function getMaterialPageFun() {
|
||||||
const data = await MpMaterialApi.getMaterialPage({
|
const data = await getMaterialPage({
|
||||||
...queryParams,
|
...queryParams,
|
||||||
type: props.type,
|
type: props.type,
|
||||||
});
|
});
|
||||||
@@ -79,7 +79,7 @@ async function getMaterialPageFun() {
|
|||||||
|
|
||||||
/** 获取已发布图文分页 */
|
/** 获取已发布图文分页 */
|
||||||
async function getFreePublishPageFun() {
|
async function getFreePublishPageFun() {
|
||||||
const data = await MpFreePublishApi.getFreePublishPage(queryParams);
|
const data = await getFreePublishPage(queryParams);
|
||||||
data.list.forEach((item: any) => {
|
data.list.forEach((item: any) => {
|
||||||
const articles = item.content.newsItem;
|
const articles = item.content.newsItem;
|
||||||
articles.forEach((article: any) => {
|
articles.forEach((article: any) => {
|
||||||
@@ -92,7 +92,7 @@ async function getFreePublishPageFun() {
|
|||||||
|
|
||||||
/** 获取草稿图文分页 */
|
/** 获取草稿图文分页 */
|
||||||
async function getDraftPageFun() {
|
async function getDraftPageFun() {
|
||||||
const data = await MpDraftApi.getDraftPage(queryParams);
|
const data = await getDraftPage(queryParams);
|
||||||
data.list.forEach((draft: any) => {
|
data.list.forEach((draft: any) => {
|
||||||
const articles = draft.content.newsItem;
|
const articles = draft.content.newsItem;
|
||||||
articles.forEach((article: any) => {
|
articles.forEach((article: any) => {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
import { WxLocation } from '#/views/mp/modules/wx-location';
|
import { WxLocation } from '#/views/mp/modules/wx-location';
|
||||||
import { WxMusic } from '#/views/mp/modules/wx-music';
|
import { WxMusic } from '#/views/mp/modules/wx-music';
|
||||||
import { WxNews } from '#/views/mp/modules/wx-news';
|
import { WxNews } from '#/views/mp/modules/wx-news';
|
||||||
@@ -47,7 +49,7 @@ const item = ref<any>(props.item);
|
|||||||
<div
|
<div
|
||||||
class="mb-3 text-base text-[rgba(0,0,0,0.85)] hover:text-[#1890ff]"
|
class="mb-3 text-base text-[rgba(0,0,0,0.85)] hover:text-[#1890ff]"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:link" />{{ item.title }}
|
<IconifyIcon icon="lucide:link" />{{ item.title }}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
export { createEmptyReply, NewsType, type Reply, ReplyType } from './types';
|
export * from './types';
|
||||||
|
|
||||||
export { default as WxReplySelect } from './wx-reply.vue';
|
export { default as WxReplySelect } from './wx-reply.vue';
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
import { Tag } from 'ant-design-vue';
|
import { Tag } from 'ant-design-vue';
|
||||||
// 因为微信语音是 amr 格式,所以需要用到 amr 解码器:https://www.npmjs.com/package/benz-amr-recorder
|
// 因为微信语音是 amr 格式,所以需要用到 amr 解码器:https://www.npmjs.com/package/benz-amr-recorder
|
||||||
import BenzAMRRecorder from 'benz-amr-recorder';
|
import BenzAMRRecorder from 'benz-amr-recorder';
|
||||||
@@ -35,7 +37,7 @@ const playing = ref(false);
|
|||||||
const duration = ref();
|
const duration = ref();
|
||||||
|
|
||||||
/** 处理点击,播放或暂停 */
|
/** 处理点击,播放或暂停 */
|
||||||
const playVoice = () => {
|
function playVoice() {
|
||||||
// 情况一:未初始化,则创建 BenzAMRRecorder
|
// 情况一:未初始化,则创建 BenzAMRRecorder
|
||||||
if (amr.value === undefined) {
|
if (amr.value === undefined) {
|
||||||
amrInit();
|
amrInit();
|
||||||
@@ -47,10 +49,10 @@ const playVoice = () => {
|
|||||||
} else {
|
} else {
|
||||||
amrPlay();
|
amrPlay();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 音频初始化 */
|
/** 音频初始化 */
|
||||||
const amrInit = () => {
|
function amrInit() {
|
||||||
amr.value = new BenzAMRRecorder();
|
amr.value = new BenzAMRRecorder();
|
||||||
// 设置播放
|
// 设置播放
|
||||||
amr.value.initWithUrl(props.url).then(() => {
|
amr.value.initWithUrl(props.url).then(() => {
|
||||||
@@ -61,26 +63,26 @@ const amrInit = () => {
|
|||||||
amr.value.onEnded(() => {
|
amr.value.onEnded(() => {
|
||||||
playing.value = false;
|
playing.value = false;
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 音频播放 */
|
/** 音频播放 */
|
||||||
const amrPlay = () => {
|
function amrPlay() {
|
||||||
playing.value = true;
|
playing.value = true;
|
||||||
amr.value.play();
|
amr.value.play();
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 音频暂停 */
|
/** 音频暂停 */
|
||||||
const amrStop = () => {
|
function amrStop() {
|
||||||
playing.value = false;
|
playing.value = false;
|
||||||
amr.value.stop();
|
amr.value.stop();
|
||||||
};
|
}
|
||||||
// TODO 芋艿:下面样式有点问题
|
// TODO 芋艿:下面样式有点问题
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="wx-voice-div" @click="playVoice">
|
<div class="wx-voice-div" @click="playVoice">
|
||||||
<Icon v-if="playing !== true" icon="ep:video-play" :size="32" />
|
<IconifyIcon v-if="playing !== true" icon="lucide:circle-play" :size="32" />
|
||||||
<Icon v-else icon="ep:video-pause" :size="32" />
|
<IconifyIcon v-else icon="lucide:circle-pause" :size="32" />
|
||||||
<span class="amr-duration" v-if="duration">{{ duration }} 秒</span>
|
<span class="amr-duration" v-if="duration">{{ duration }} 秒</span>
|
||||||
<div v-if="content">
|
<div v-if="content">
|
||||||
<Tag color="success" size="small">语音识别</Tag>
|
<Tag color="success" size="small">语音识别</Tag>
|
||||||
|
|||||||
Reference in New Issue
Block a user