Files
iot-device-management-frontend/apps/web-ele/src/views/mp/components/wx-reply/tab-voice.vue

161 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts" setup>
import type { UploadRawFile } from 'element-plus';
import type { Reply } from './types';
import { computed, reactive, ref } from 'vue';
import { IconifyIcon } from '@vben/icons';
import { useAccessStore } from '@vben/stores';
import {
ElButton,
ElCol,
ElDialog,
ElMessage,
ElRow,
ElUpload,
} from 'element-plus';
import { UploadType, useBeforeUpload } from '#/utils/useUpload';
import MaterialSelect from '#/views/mp/components/wx-material-select/wx-material-select.vue';
import VoicePlayer from '#/views/mp/components/wx-voice-play/wx-voice-play.vue';
defineOptions({ name: 'TabVoice' });
const props = defineProps<{
modelValue: Reply;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', v: Reply): void;
}>();
// TODO @hw用 ElMessage
const message = ElMessage;
const UPLOAD_URL = `${import.meta.env.VITE_BASE_URL}/admin-api/mp/material/upload-temporary`;
// TODO @hwantd 和 ele 写法的统一;
const HEADERS = { Authorization: `Bearer ${useAccessStore().accessToken}` };
const reply = computed<Reply>({
get: () => props.modelValue,
// TODO @hw这里要和 antd 统一么?还是 ele 和它统一
set: (val: Reply) => emit('update:modelValue', val),
});
const showDialog = ref(false);
const fileList = ref([]);
const uploadData = reactive({
accountId: reply.value.accountId,
introduction: '',
title: '',
type: 'voice',
});
/** 语音上传前校验 */
function beforeVoiceUpload(rawFile: UploadRawFile) {
return useBeforeUpload(UploadType.Voice, 10)(rawFile);
}
/** 上传成功 */
function onUploadSuccess(res: any) {
if (res.code !== 0) {
message.error(`上传出错:${res.msg}`);
return false;
}
// 清空上传时的各种数据
fileList.value = [];
uploadData.title = '';
uploadData.introduction = '';
// 上传好的文件,本质是个素材,所以可以进行选中
selectMaterial(res.data);
}
/** 删除语音 */
function onDelete() {
reply.value.mediaId = null;
reply.value.url = null;
reply.value.name = null;
}
/** 选择素材 */
function selectMaterial(item: Reply) {
showDialog.value = false;
// reply.value.type = ReplyType.Voice
reply.value.mediaId = item.mediaId;
reply.value.url = item.url;
reply.value.name = item.name;
}
</script>
<template>
<div>
<div
class="mx-auto mb-[10px] border border-[#eaeaea] p-[10px]"
v-if="reply.url"
>
<p
class="overflow-hidden text-ellipsis whitespace-nowrap text-center text-xs"
>
{{ reply.name }}
</p>
<ElRow class="w-full pt-[10px] text-center" justify="center">
<VoicePlayer :url="reply.url" />
</ElRow>
<ElRow class="w-full pt-[10px] text-center" justify="center">
<ElButton type="danger" circle @click="onDelete">
<IconifyIcon icon="ep:delete" />
</ElButton>
</ElRow>
</div>
<ElRow v-else class="text-center">
<!-- 选择素材 -->
<ElCol
:span="12"
class="h-[160px] w-[49.5%] border border-[rgb(234,234,234)] py-[50px]"
>
<ElButton type="success" @click="showDialog = true">
素材库选择<IconifyIcon icon="ep:circle-check" />
</ElButton>
<ElDialog
title="选择语音"
v-model="showDialog"
width="90%"
append-to-body
destroy-on-close
>
<MaterialSelect
type="voice"
:account-id="reply.accountId"
@select-material="selectMaterial"
/>
</ElDialog>
</ElCol>
<!-- 文件上传 -->
<ElCol
:span="12"
class="float-right h-[160px] w-[49.5%] border border-[rgb(234,234,234)] py-[50px]"
>
<ElUpload
:action="UPLOAD_URL"
:headers="HEADERS"
multiple
:limit="1"
:file-list="fileList"
:data="uploadData"
:before-upload="beforeVoiceUpload"
:on-success="onUploadSuccess"
>
<ElButton type="primary">点击上传</ElButton>
<template #tip>
<div class="text-center leading-[18px]">
格式支持 mp3/wma/wav/amr文件大小不超过 2M播放长度不超过 60s
</div>
</template>
</ElUpload>
</ElCol>
</ElRow>
</div>
</template>