提交 453fee90 authored 作者: lidongxu's avatar lidongxu

Merge branch 'dev'

......@@ -207,8 +207,6 @@
<!-- 飞书SDK -->
<script src="https://lf-scm-cn.feishucdn.com/lark/op/h5-js-sdk-1.5.34.js"
type="text/javascript"></script>
<!-- 腾讯地图 SDK -->
<script src="https://map.qq.com/api/gljs?v=1.exp&key=UTEBZ-UJ3KG-OORQO-QT3PT-JDWU7-YRBZA"></script>
<% if
(systemConfig.env
!=='development'
......
......@@ -55,6 +55,7 @@
"unplugin-auto-import": "^0.17.6",
"unplugin-vue-components": "^28.4.1",
"unplugin-vue-setup-extend-plus": "1.0.1",
"vconsole": "^3.15.1",
"vite": "5.3.2",
"vite-plugin-compression": "0.5.1",
"vite-plugin-html": "^3.2.2",
......
......@@ -64,6 +64,15 @@ import OpenDialog from '@/components/OpenDialog'
// 版本通知组件
import VersionNotice from '@/components/VersionNotice'
// 引入vConsole
import VConsole from 'vconsole'
// 创建vConsole实例
// 生产环境不加载
if (import.meta.env.VITE_APP_ENV !== 'production') {
new VConsole()
}
const app = createApp(App)
// 注册移动端内容
......
......@@ -8,3 +8,4 @@ export const isMobile = () => {
}
return false;
}
// 获取文件扩展名
export function getFileTypeExt(url) {
const fileName = url.split('/').pop()
const fileType = fileName.split('.').pop()
return fileType
}
// 判断 URL 是一个图片还是视频
function isImage(url) {
const fileType = getFileTypeExt(url)
return ['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(fileType.toLowerCase())
}
// 判断 URL 是一个视频
function isVideo(url) {
const fileType = getFileTypeExt(url)
return ['mp4', 'avi', 'mov', 'wmv', 'flv', '3gp', 'mkv', 'webm'].includes(fileType.toLowerCase())
}
// 来个统一出口
export function getMediaType(url) {
if (isImage(url)) {
return 'image'
} else if (isVideo(url)) {
return 'video'
} else {
return 'unknown'
}
}
......@@ -6,6 +6,7 @@ export * from './device'
export * from './dict'
export * from './dynamicTitle'
export * from './errorCode'
export * from './file'
export * from './jsencrypt'
export * from './math'
export * from './permission'
......
<!-- 移动端上传图片/视频组件 -->
<template>
<div class="xl-mobile-upload">
<!-- 苹果设备上传组件 -->
<van-uploader ref="uploaderRef"
:max-count="maxCount"
:accept="supportedTypes"
:model-value="photoList"
:after-read="commitStorePhotosRead"
preview-size="2.13333rem"
@delete="deleteCommitStorePhotos"
:max-size="bigSize"
@oversize="onOversize">
<!-- 自定义上传按钮 -->
<template #default>
<!-- <div class="upload-btn">
<van-icon name="photograph" />
</div> -->
<div class="upload-btn"
@click.stop="customUploadClick">
<van-icon name="photograph" />
</div>
<!-- iOS设备或不支持视频的安卓设备:使用默认上传按钮(由van-uploader自动处理点击) -->
<!-- <div v-else
class="upload-btn">
<van-icon name="photograph" />
</div> -->
</template>
<!-- 自定义预览内容 -->
<template #preview-cover="{ url, index }">
<div class="preview-container"
@click.stop>
<!-- 图片预览 -->
<van-image v-if="getMediaType(url) === 'image'"
:src="url"
alt=""
class="preview-media"
fit="cover"
@click="previewImage(url)" />
<!-- 视频预览 -->
<div class="video-wrap"
v-else-if="getMediaType(url) === 'video'">
<video :src="url"
alt=""
ref="videoRef"
muted
autoplay
playsinline
preload="auto"
class="preview-media"
@loadeddata="handleVideoLoaded" />
<div class="play-hint"
@click.stop="showVideoFullscreen(url)">
</div>
</div>
<!-- 删除按钮 -->
<van-icon name="clear"
class="delete-icon" />
<!-- 类型标识 -->
<span v-if="getMediaType(url) === 'video'"
class="video-tag">
视频
</span>
</div>
</template>
</van-uploader>
<!-- 拍照方式选择 -->
<van-action-sheet v-model:show="show"
:actions="actions"
teleport="body"
@select="onSelect" />
</div>
</template>
<script setup>
import { showImagePreview } from 'vant'
import { getMobileType } from '@/views/mobile/utils'
import { getMediaType } from '@/utils'
const emits = defineEmits(['confirm', 'delete'])
const props = defineProps({
// 最多支持上传数量
maxCount: {
type: Number,
default: 1
},
// 支持视频上传
supportVideo: {
type: Boolean,
default: false
},
// 文件组回显
photoList: { // 回显
type: Array,
default: () => []
},
// 多张照片,本照片索引
name: {
type: [String, Number],
default: ''
}
})
/**************** 工具函数 ***************/
// 计算支持的文件类型
const supportedTypes = computed(() => {
if (props.supportVideo) {
// 判断安卓还是苹果设备返回不同的字符串
if (getMobileType() === 'ios') {
return 'image/*,video/*'
} else {
console.log('anzhuo2')
if (selectedMediaType.value === 'image') {
return 'image/*'
} else {
return 'video/*'
}
}
}
return 'image/*'
})
// 自定义点击拍照按钮效果
const customUploadClick = () => {
if (getMobileType() === 'ios') {
// 苹果设备:直接触发点击事件
nextTick(() => {
const inputElement = uploaderRef.value.$el.querySelector('input[type="file"]')
if (inputElement) {
inputElement.click()
}
})
} else {
// 安卓设备:显示拍照/录像方式确认菜单
console.log('anzhuo1')
show.value = true
}
}
/*************** android 拍照/录像方式确认 ***************/
// 显示菜单
const show = ref(false)
// 拍照/录像方式列表
const actions = ref([
{
name: '拍照片',
type: 'image'
},
{
name: '拍视频',
type: 'video'
}
])
// 安卓:拍照/录像方式确认
const onSelect = (item) => {
selectedMediaType.value = item.type
nextTick(() => {
if (uploaderRef.value) {
// 获取uploader组件实例
const uploaderInstance = uploaderRef.value
// 方法1: 如果组件暴露了open或click方法,则模拟一次点击上传
if (uploaderInstance.open) {
uploaderInstance.open()
} else if (uploaderInstance.click) {
uploaderInstance.click()
} else {
// 方法2: 直接查找内部的input元素并触发点击
// 查找uploader组件内的input[type="file"]元素
const inputElement = uploaderInstance.$el.querySelector('input[type="file"]')
if (inputElement) {
// 触发点击事件
inputElement.click()
} else {
console.error('未找到文件上传input元素')
}
}
} else {
console.error('uploader组件未加载完成')
}
// 隐藏底部选择菜单
show.value = false
})
}
// 上传组件和选择类型
const uploaderRef = ref(null)
const selectedMediaType = ref('')
/*************** 上传照片 ***************/
// 上传照片
const commitStorePhotosRead = async (file) => {
emits('confirm', file, { name: props.name })
}
// 删除照片
const deleteCommitStorePhotos = async (file, { name, index }) => {
emits('delete', '', { name: props.name, index })
}
// 文件大小限制
const bigSize = 50 * 1024 * 1024
const onOversize = (file) => {
showNotify({ type: 'danger', message: '文件大小不能超过 5 MB' })
}
/*************** 图片/视频预览 ***************/
// 图片预览
const previewImage = (url) => {
showImagePreview({
images: [url],
})
}
// 视频相关状态
const videoRef = ref(null)
const isPlaying = ref(true)
// 加载完第一帧暂停
const handleVideoLoaded = () => {
isPlaying.value = false
videoRef.value.pause()
}
// 全屏播放
const showVideoFullscreen = async (url) => {
const video = videoRef.value;
if (!video) return;
try {
// 先尝试播放视频
await video.play();
// 然后尝试全屏(跨浏览器兼容)
if (!document.fullscreenElement) {
await requestFullscreen(video).catch(err => {
console.error('全屏请求失败,但不影响播放:', err);
});
}
} catch (err) {
console.error('视频操作失败:', err);
}
};
// 跨浏览器请求全屏(保留之前的实现)
const requestFullscreen = (element) => {
if (!element) return Promise.reject(new Error('video 标签不存在'));
const methods = [
// 标准API
() => element.requestFullscreen(),
// WebKit (Safari, Chrome)
() => element.webkitRequestFullscreen(),
// iOS Safari特定API
() => {
if (element.webkitEnterFullscreen) {
element.webkitEnterFullscreen();
return Promise.resolve();
}
return Promise.reject(new Error('不支持全屏播放'));
}
];
// 尝试各种方法
return new Promise((resolve, reject) => {
for (const method of methods) {
try {
const result = method();
if (result && result.then) {
result.then(resolve).catch(() => { });
} else {
resolve();
return;
}
} catch (err) {
// 尝试下一个方法
continue;
}
}
reject(new Error('所有全屏播放方法失败'));
});
};
</script>
<style scoped
lang="scss">
.xl-mobile-upload {
.van-uploader {
::v-deep(.van-uploader__wrapper) {
gap: 10px;
/* 自定义上传区域样式 */
.van-uploader__input-wrapper {
width: 80px;
height: 80px;
.upload-btn {
display: flex;
align-items: center;
justify-content: center;
background-color: #f8f8f8;
width: 80px;
height: 80px;
border: 1px dashed #ccc;
border-radius: 4px;
color: #dcdee0;
font-size: 24px;
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
}
}
}
/* 预览区域 */
::v-deep(.van-uploader__preview) {
margin: 0;
.preview-container {
position: relative;
width: 100%;
height: 100%;
border-radius: 8px;
overflow: hidden;
.video-wrap {
width: 100%;
height: 100%;
.play-hint {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
.preview-media {
width: 100%;
height: 100%;
object-fit: cover;
}
.video-tag {
position: absolute;
bottom: 4px;
right: 4px;
background-color: rgba(0, 0, 0, 0.5);
color: white;
font-size: 12px;
padding: 2px 6px;
border-radius: 4px;
}
.delete-icon {
position: absolute;
top: -6px;
right: -6px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
}
}
}
/* 原来上传预览内容样式 */
::v-deep(.van-uploader__file) {
.van-badge__wrapper {
display: none;
}
.van-ellipsis {
display: none;
}
}
}
</style>
\ No newline at end of file
......@@ -4,6 +4,8 @@ import { isMobile } from '@/utils'
import PickerSearch from './components/PickerSearch'
// 选择日期
import PickerCalendar from './components/PickerCalendar'
// 上传照片和视频
import XLMobileUpload from './components/XLMobileUpload'
// 指令
import longPress from './directive/touch'
// 覆盖样式
......@@ -31,4 +33,6 @@ export default function (app) {
app.component('PickerSearch', PickerSearch);
app.component('PickerCalendar', PickerCalendar);
app.directive('longPress', longPress)
// 上传照片和视频
app.component('XLMobileUpload', XLMobileUpload)
}
\ No newline at end of file
......@@ -44,6 +44,7 @@
class="refresh-icon"
@click="handleClickLocation" />
</div>
<!-- 门头照上传 -->
<div class="header-photo-section">
<van-field label="门头照"
......@@ -60,6 +61,8 @@
</template>
</van-field>
</div>
<!-- 渠道类型选择 -->
<van-field label-width="150px"
label-position="top"
......@@ -182,9 +185,12 @@ import convention from './tabs/conventionalDisplay.vue'
import scheduleDisplay from './tabs/scheduleDisplay.vue'
import scheduleAdjustment from './tabs/scheduleAdjustment.vue'
import categoryInformation from './tabs/categoryInformation.vue'
import { showImagePreview } from 'vant';
import useUserStore from '@/store/modules/user'
import { v4 as uuidv4 } from 'uuid';
import { getFileTypeExt } from '@/utils'
import { getMobileType } from '@/views/mobile/utils'
// 引入必要的组件
import { showImagePreview } from 'vant';
const router = useRouter()
const route = useRoute()
......@@ -354,26 +360,28 @@ const handleClickLocation = () => {
}
/*************** 门头照上传 ***************/
// 上传照片
const commitStorePhotosRead = async (file) => {
form.commitStorePicture = [{
url: file.content,
status: 'uploading',
message: '上传中...'
message: '上传中...',
url: file.content
}]
const date = new Date()
const month = date.getMonth() + 1
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/storeFrontPhoto/${useUserStore().empInfo.empNo}/${uuidv4()}.png`, file.file)
form.commitStorePicture = [{
url: pictureUrl,
status: 'done'
}]
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/storeFrontPhoto/${useUserStore().empInfo.empNo}/${uuidv4()}.${getFileTypeExt(file.file.name)}`, file.file)
const targetObj = form.commitStorePicture[0]
targetObj.status = 'done'
targetObj.url = pictureUrl
await createInspectionTaskAPI({
storeCode: form.storeCode,
storeName: form.storeName,
rstId: form.rstId,
storePicture: pictureUrl
})
if (!form.storePicture) form.storePicture = pictureUrl
showNotify({ type: 'success', message: '门头照,上传成功' })
}
......@@ -390,6 +398,7 @@ const deleteCommitStorePhotos = async () => {
showNotify({ type: 'success', message: '门头照,删除成功' })
}
/*************** 渠道类型 ***************/
const typeOptions = ref(typeOption) // 渠道类型
const showTypePopup = ref(false)
......@@ -477,7 +486,6 @@ const deleteLongTimePictureArr = async (file, { name, index }) => {
})
showNotify({ type: 'success', message: '大日期产品照片,删除成功' })
}
</script>
<style scoped
......@@ -599,8 +607,21 @@ const deleteLongTimePictureArr = async (file, { name, index }) => {
justify-content: center;
background-color: #f8f8f8;
}
/* 原来上传预览内容样式 */
::v-deep(.van-uploader__file) {
.van-badge__wrapper {
display: none;
}
.van-ellipsis {
display: none;
}
}
}
/* 信息填写组 */
.tabs {
margin-top: 10px;
......@@ -638,5 +659,69 @@ const deleteLongTimePictureArr = async (file, { name, index }) => {
align-items: center;
justify-content: center;
}
/* 全屏预览 */
::v-deep(.fullscreen-video-dialog) {
width: 100%;
max-width: 100%;
height: 100% !important;
top: 0;
padding: 0;
margin: 0;
transform: translateY(0);
border-radius: 0;
.van-dialog__header {
display: none;
}
}
.fullscreen-video-dialog .van-dialog__content {
padding: 0 !important;
height: calc(100% - 50px);
/* 减去标题栏高度 */
display: flex;
align-items: center;
justify-content: center;
}
.video-container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #000;
/* 添加关闭按钮 */
.close-button {
position: absolute;
top: 10px;
right: 10px;
width: 30px;
height: 30px;
background-color: rgba(0, 0, 0, 0.5);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
}
.fullscreen-video {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
/* 预览中的视频样式 */
.preview-media {
width: 100%;
height: 100%;
object-fit: cover;
cursor: pointer;
}
}
</style>
\ No newline at end of file
......@@ -25,19 +25,16 @@
auto-complete="off"
:rules="[{ required: true, message: '请输入费用' }]"
@change="handleCostChange(index)" />
<van-field label="常规陈列照片"
<van-field label="常规陈列照片/视频"
label-align="top"
class="header-photo-section">
<template #input>
<van-uploader :max-count="2"
accept="image/*"
capture="camera"
:model-value="obj.photoArr"
<XLMobileUpload :max-count="5"
:photoList="obj.photoArr"
:name="index"
:after-read="displayPhotosRead"
preview-size="2.13333rem"
@delete="deletedisplayPhotos">
</van-uploader>
:supportVideo="true"
@confirm="displayPhotosRead"
@delete="deletedisplayPhotos" />
</template>
</van-field>
<van-field label="核查结果"
......@@ -80,6 +77,7 @@
import { uploadFileToOSSAPI, createInspectionTaskAPI, createInspectionTaskDetailAPI, deleteInspectionTaskAPI } from '@/api'
import useUserStore from '@/store/modules/user'
import { v4 as uuidv4 } from 'uuid'
import { getFileTypeExt } from '@/utils'
const route = useRoute()
const props = defineProps({
......@@ -184,7 +182,7 @@ const handleCostChange = async (index) => {
showNotify({ type: 'success', message: '费用,保存成功' })
}
// 上传照片
const displayPhotosRead = async (file, { name, index }) => {
const displayPhotosRead = async (file, { name }) => {
// name:是当前照片组件所在陈列组的索引
// index: 当前照片组的索引
const date = new Date()
......@@ -196,7 +194,7 @@ const displayPhotosRead = async (file, { name, index }) => {
status: 'uploading',
message: '上传中...'
}
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/displayPhoto/${useUserStore().empInfo.empNo}/${props.form.storeCode}/${uuidv4()}.png`, file.file)
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/displayPhoto/${useUserStore().empInfo.empNo}/${props.form.storeCode}/${uuidv4()}.${getFileTypeExt(file.file.name)}`, file.file)
target.photoArr[photoIndex] = {
url: pictureUrl,
status: 'done'
......@@ -210,7 +208,7 @@ const displayPhotosRead = async (file, { name, index }) => {
}
})
showNotify({ type: 'success', message: '常规陈列照片,上传成功' })
showNotify({ type: 'success', message: '常规陈列照片/视频,上传成功' })
}
// 删除照片
const deletedisplayPhotos = async (file, { name, index }) => {
......@@ -223,7 +221,7 @@ const deletedisplayPhotos = async (file, { name, index }) => {
photoArr: target.photoArr.map(o => o.url)
}
})
showNotify({ type: 'success', message: '常规陈列照片,删除成功' })
showNotify({ type: 'success', message: '常规陈列照片/视频,删除成功' })
}
// 核查结果
const handleVerifyChange = async (index) => {
......
......@@ -24,19 +24,16 @@
auto-complete="off"
:rules="[{ required: true, message: '请输入执行情况' }]"
@change="handleCostChange(index)" />
<van-field label="档期补差照片"
<van-field label="档期补差照片/视频"
label-align="top"
class="header-photo-section">
<template #input>
<van-uploader :max-count="3"
accept="image/*"
capture="camera"
:model-value="obj.photoArr"
<XLMobileUpload :max-count="5"
:photoList="obj.photoArr"
:name="index"
:after-read="displayPhotosRead"
preview-size="2.13333rem"
@delete="deletedisplayPhotos">
</van-uploader>
:supportVideo="true"
@confirm="displayPhotosRead"
@delete="deletedisplayPhotos" />
</template>
</van-field>
<van-field label="补差核查结果"
......@@ -79,6 +76,7 @@
import { uploadFileToOSSAPI, createInspectionTaskAPI, createInspectionTaskDetailAPI, deleteInspectionTaskAPI } from '@/api'
import useUserStore from '@/store/modules/user'
import { v4 as uuidv4 } from 'uuid'
import { getFileTypeExt } from '@/utils'
const route = useRoute()
const props = defineProps({
......@@ -194,7 +192,7 @@ const displayPhotosRead = async (file, { name, index }) => {
status: 'uploading',
message: '上传中...'
}
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/scheduleAdjustmentPhoto/${useUserStore().empInfo.empNo}/${props.form.storeCode}/${uuidv4()}.png`, file.file)
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/scheduleAdjustmentPhoto/${useUserStore().empInfo.empNo}/${props.form.storeCode}/${uuidv4()}.${getFileTypeExt(file.file.name)}`, file.file)
target.photoArr[targetIndex] = {
url: pictureUrl,
status: 'done'
......@@ -208,7 +206,7 @@ const displayPhotosRead = async (file, { name, index }) => {
}
})
showNotify({ type: 'success', message: '档期补差照片,上传成功' })
showNotify({ type: 'success', message: '档期补差照片/视频,上传成功' })
}
// 删除照片
const deletedisplayPhotos = async (file, { name, index }) => {
......@@ -221,7 +219,7 @@ const deletedisplayPhotos = async (file, { name, index }) => {
photoArr: target.photoArr.map(o => o.url)
}
})
showNotify({ type: 'success', message: '档期补差照片,删除成功' })
showNotify({ type: 'success', message: '档期补差照片/视频,删除成功' })
}
// 核查结果
const handleVerifyChange = async (index) => {
......
......@@ -24,19 +24,16 @@
auto-complete="off"
:rules="[{ required: true, message: '请输入费用' }]"
@change="handleCostChange(index)" />
<van-field label="档期陈列照片"
<van-field label="档期陈列照片/视频"
label-align="top"
class="header-photo-section">
<template #input>
<van-uploader :max-count="2"
accept="image/*"
capture="camera"
:model-value="obj.photoArr"
<XLMobileUpload :max-count="5"
:photoList="obj.photoArr"
:name="index"
:after-read="displayPhotosRead"
preview-size="2.13333rem"
@delete="deletedisplayPhotos">
</van-uploader>
:supportVideo="true"
@confirm="displayPhotosRead"
@delete="deletedisplayPhotos" />
</template>
</van-field>
<van-field label="核查结果"
......@@ -79,6 +76,7 @@
import { uploadFileToOSSAPI, createInspectionTaskAPI, createInspectionTaskDetailAPI, deleteInspectionTaskAPI } from '@/api'
import useUserStore from '@/store/modules/user'
import { v4 as uuidv4 } from 'uuid'
import { getFileTypeExt } from '@/utils'
const route = useRoute()
const props = defineProps({
......@@ -194,7 +192,7 @@ const displayPhotosRead = async (file, { name, index }) => {
status: 'uploading',
message: '上传中...'
}
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/scheduleDisplayPhoto/${useUserStore().empInfo.empNo}/${props.form.storeCode}/${uuidv4()}.png`, file.file)
const pictureUrl = await uploadFileToOSSAPI(`risk/${date.getFullYear()}-${month}/scheduleDisplayPhoto/${useUserStore().empInfo.empNo}/${props.form.storeCode}/${uuidv4()}.${getFileTypeExt(file.file.name)}`, file.file)
target.photoArr[targetIndex] = {
url: pictureUrl,
status: 'done'
......@@ -208,7 +206,7 @@ const displayPhotosRead = async (file, { name, index }) => {
}
})
showNotify({ type: 'success', message: '档期陈列照片,上传成功' })
showNotify({ type: 'success', message: '档期陈列照片/视频,上传成功' })
}
// 删除照片
const deletedisplayPhotos = async (file, { name, index }) => {
......@@ -221,7 +219,7 @@ const deletedisplayPhotos = async (file, { name, index }) => {
photoArr: target.photoArr.map(o => o.url)
}
})
showNotify({ type: 'success', message: '档期陈列照片,删除成功' })
showNotify({ type: 'success', message: '档期陈列照片/视频,删除成功' })
}
// 核查结果
const handleVerifyChange = async (index) => {
......
export const getMobileType = () => {
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.includes('iphone') || userAgent.includes('ipad')) {
return 'ios';
} else if (userAgent.includes('android')) {
return 'android';
}
return 'android';
}
......@@ -62,7 +62,7 @@ export default defineConfig(({ mode, command }) => {
rootValue: 37.5,
propList: ['*'],
exclude: file => {
const dirList = ["vant", "mobile/pages"]
const dirList = ["vant", "mobile/pages", "mobile/components"]
return !dirList.some(item => file.includes(item))
}
})
......
......@@ -6,9 +6,11 @@ export default function createAutoImportVant() {
return [
autoImport({
resolvers: [VantResolver()],
dts: false // 禁用auto-imports.d.ts生成
}),
Components({
resolvers: [VantResolver()],
dts: false // 禁用auto-imports.d.ts生成
}),
]
};
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论