Merge branch 'wyfMain-dev'
Some checks are pending
Check / lint (push) Waiting to run
Check / typecheck (push) Waiting to run
Check / build (build, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build, 18.x, windows-latest) (push) Waiting to run
Check / build (build:app, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:app, 18.x, windows-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Waiting to run

This commit is contained in:
wangyifeng 2025-03-15 09:42:33 +08:00
commit 894bb9bf28
17 changed files with 159 additions and 72 deletions

2
components.d.ts vendored
View File

@ -30,6 +30,8 @@ declare module 'vue' {
LoginMessage: typeof import('./src/components/talk/message/LoginMessage.vue')['default'] LoginMessage: typeof import('./src/components/talk/message/LoginMessage.vue')['default']
Message: typeof import('./src/components/x-message/message/index.vue')['default'] Message: typeof import('./src/components/x-message/message/index.vue')['default']
MixedMessage: typeof import('./src/components/talk/message/MixedMessage.vue')['default'] MixedMessage: typeof import('./src/components/talk/message/MixedMessage.vue')['default']
NButton: typeof import('naive-ui')['NButton']
NIcon: typeof import('naive-ui')['NIcon']
PageAnimation: typeof import('./src/components/page-animation/index.vue')['default'] PageAnimation: typeof import('./src/components/page-animation/index.vue')['default']
RevokeMessage: typeof import('./src/components/talk/message/RevokeMessage.vue')['default'] RevokeMessage: typeof import('./src/components/talk/message/RevokeMessage.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']

View File

@ -11,12 +11,12 @@ const userStore = useUserStore()
const root = document.documentElement const root = document.documentElement
root.style.setProperty('--statusBarHeight', `${statusBarHeight.value}px`) root.style.setProperty('--statusBarHeight', `${statusBarHeight.value}px`)
const handleWebview = () => { const handleWebview = () => {
let statusBarHeight = window?.plus?.navigator?.getStatusbarHeight() let statusBarHeight_ = window?.plus?.navigator?.getStatusbarHeight()
const webview = plus.webview.currentWebview() const webview = plus.webview.currentWebview()
webview.setStyle({ // webview.setStyle({
top: statusBarHeight, // top: statusBarHeight_,
bottom: 0, // bottom: 0,
}) // })
// console.log(webview) // console.log(webview)
token.value = webview.token token.value = webview.token
} }

View File

@ -684,6 +684,8 @@ const confirmSelectMembers = () => {
resp.then(({ code, data }) => { resp.then(({ code, data }) => {
console.log(data) console.log(data)
if (code == 200) { if (code == 200) {
// console.error(-selectedUserIds.split(',').length)
emits('updateSelectedMembersNum', -selectedUserIds.split(',').length)
useDialogueStore().updateGroupMembers() useDialogueStore().updateGroupMembers()
groupStore.ServeGroupDetail() groupStore.ServeGroupDetail()
} else { } else {

View File

@ -262,8 +262,10 @@ onLoad(async (options) => {
console.log(options.groupId) console.log(options.groupId)
state.groupId = Number(options.groupId) state.groupId = Number(options.groupId)
await groupStore.ServeGroupDetail() await groupStore.ServeGroupDetail()
if (dialogueParams.type === 2) {
await groupStore.ServeGetGroupNotices() await groupStore.ServeGetGroupNotices()
} }
}
if (options.sessionId) { if (options.sessionId) {
state.sessionId = Number(options.sessionId) state.sessionId = Number(options.sessionId)
if (talkParams.topItems.length > 0) { if (talkParams.topItems.length > 0) {

View File

@ -2,8 +2,11 @@
<div class="choose-deps-page"> <div class="choose-deps-page">
<zPaging ref="zPaging" :show-scrollbar="false"> <zPaging ref="zPaging" :show-scrollbar="false">
<template #top> <template #top>
<div :class="state.chooseMode === 3 ? 'top_bg': ''"> <div :class="state.chooseMode === 3 ? 'top_bg' : ''">
<customNavbar :class="state.chooseMode === 3 ? 'index_top_navbar': ''" :title="pageTitle"></customNavbar> <customNavbar
:class="state.chooseMode === 3 ? 'index_top_navbar' : ''"
:title="pageTitle"
></customNavbar>
<div class="pl-[32rpx] pr-[32rpx] pt-[32rpx] pb-[32rpx]"> <div class="pl-[32rpx] pr-[32rpx] pt-[32rpx] pb-[32rpx]">
<customInput <customInput
:searchText="searchVal" :searchText="searchVal"
@ -460,6 +463,7 @@ import downDep from '@/static/image/chatList/downDep.png'
import downDepDis from '@/static/image/chatList/downDepDis.png' import downDepDis from '@/static/image/chatList/downDepDis.png'
import checkBox from '@/components/checkBox/index.vue' import checkBox from '@/components/checkBox/index.vue'
import lodash from 'lodash' import lodash from 'lodash'
import { handleSetWebviewStyle } from '@/utils/common'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
@ -990,6 +994,7 @@ const checkCurrentItem = (item) => {
} }
onMounted(() => { onMounted(() => {
handleSetWebviewStyle()
init() init()
}) })
@ -1106,18 +1111,18 @@ const toUserDetail = (userItem) => {
height: 100%; height: 100%;
display: flex; display: flex;
} }
::v-deep .index_top_navbar .tmicon-angle-left{ ::v-deep .index_top_navbar .tmicon-angle-left {
color:#fff !important; color: #fff !important;
} }
::v-deep .index_top_navbar .text-weight-b{ ::v-deep .index_top_navbar .text-weight-b {
color:#fff !important; color: #fff !important;
} }
::v-deep .index_top_navbar .statusHeightTop > .noNvueBorder:first-child { ::v-deep .index_top_navbar .statusHeightTop > .noNvueBorder:first-child {
background: transparent !important; background: transparent !important;
border: none !important; border: none !important;
} }
.top_bg{ .top_bg {
background: url('@/static/image/mine/page_top.png') no-repeat; background: url('@/static/image/mine/page_top.png') no-repeat;
background-size: cover; background-size: cover;
background-position: bottom center; background-position: bottom center;

View File

@ -186,7 +186,7 @@ import customBtn from '@/components/custom-btn/custom-btn.vue'
import groupMemberList from '../chatSettings/components/groupMembersList.vue' import groupMemberList from '../chatSettings/components/groupMembersList.vue'
import avatarModule from '@/components/avatar-module/index.vue' import avatarModule from '@/components/avatar-module/index.vue'
import { ref, watch, computed } from 'vue' import { ref, watch, computed, onMounted } from 'vue'
import { onShow, onLoad } from '@dcloudio/uni-app' import { onShow, onLoad } from '@dcloudio/uni-app'
import { useChatList } from '@/store/chatList/index.js' import { useChatList } from '@/store/chatList/index.js'
import { useAuth } from '@/store/auth' import { useAuth } from '@/store/auth'
@ -195,6 +195,7 @@ import addCircle from '@/static/image/chatList/addCircle.png'
import cahtPopover from '@/static/image/chatList/cahtPopover.png' import cahtPopover from '@/static/image/chatList/cahtPopover.png'
import { ServeCreateGroup } from '@/api/group/index' import { ServeCreateGroup } from '@/api/group/index'
import { useGroupTypeStore } from '@/store/groupType' import { useGroupTypeStore } from '@/store/groupType'
import { handleSetWebviewStyle } from '@/utils/common'
const { const {
groupName, groupName,
@ -217,6 +218,10 @@ onLoad(()=> {
groupStore.$reset() groupStore.$reset()
}) })
onMounted(() => {
handleSetWebviewStyle()
})
// //
const groupType = computed(() => { const groupType = computed(() => {
let group_type = '' let group_type = ''

View File

@ -115,7 +115,7 @@ const state = reactive({
erpUserId: '', //erpid erpUserId: '', //erpid
userInfo: null, // userInfo: null, //
userBasicInfos: [], // userBasicInfos: [], //
isShowPhoneCall: true, // isShowPhoneCall: false, //
phoneNumber: '', // phoneNumber: '', //
}) })

View File

@ -24,7 +24,10 @@
<div class="text-[24rpx] text-[#999999]">公司群</div> <div class="text-[24rpx] text-[#999999]">公司群</div>
</template> </template>
<template #right> <template #right>
<div class="mr-[36rpx] toChatSetting_btn"> <div
class="mr-[36rpx] toChatSetting_btn"
v-if="!talkParams.isDismiss"
>
<tm-icon <tm-icon
color="rgb(51, 51, 51)" color="rgb(51, 51, 51)"
:font-size="36" :font-size="36"
@ -70,8 +73,17 @@
:datetime="item.created_at" :datetime="item.created_at"
:msg_id="item.msg_id" :msg_id="item.msg_id"
> >
<template v-if="canEditRevokedMessage(item) && item.user_id === userStore.uid"> <template
<span class="edit-revoked-message" @click="restoreRevokedMessage(item)">重新编辑</span> v-if="
canEditRevokedMessage(item) && item.user_id === userStore.uid
"
>
<span
class="edit-revoked-message"
@click="restoreRevokedMessage(item)"
>
重新编辑
</span>
</template> </template>
</revoke-message> </revoke-message>
</div> </div>
@ -133,7 +145,7 @@
<deepBubble <deepBubble
@clickMenu="(menuType) => onContextMenu(menuType, item)" @clickMenu="(menuType) => onContextMenu(menuType, item)"
:isShowCopy="isShowCopy(item)" :isShowCopy="isShowCopy(item)"
:isShowWithdraw="isRevoke(talkParams.uid, item)" :isShowWithdraw="isRevoke(talkParams.uid, item) || isLeader"
> >
<component <component
class="component-content" class="component-content"
@ -479,7 +491,7 @@ import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZ
import emojiPanel from './components/emojiPanel.vue' import emojiPanel from './components/emojiPanel.vue'
import filePanel from './components/filePanel.vue' import filePanel from './components/filePanel.vue'
import lodash from 'lodash' import lodash from 'lodash'
import { ServePublishMessage,detailGetRecordsContext } from '@/api/chat' import { ServePublishMessage, detailGetRecordsContext } from '@/api/chat'
import copy07 from '@/static/image/chatList/copy07@2x.png' import copy07 from '@/static/image/chatList/copy07@2x.png'
import multipleChoices from '@/static/image/chatList/multipleChoices@2x.png' import multipleChoices from '@/static/image/chatList/multipleChoices@2x.png'
import cite from '@/static/image/chatList/cite@2x.png' import cite from '@/static/image/chatList/cite@2x.png'
@ -522,6 +534,8 @@ const talkParams = reactive({
online: computed(() => dialogueStore.online), online: computed(() => dialogueStore.online),
keyboard: computed(() => dialogueStore.keyboard), keyboard: computed(() => dialogueStore.keyboard),
num: computed(() => dialogueStore.members.length), num: computed(() => dialogueStore.members.length),
isDismiss: computed(() => dialogueStore.isDismiss),
adminList: computed(() => dialogueStore.getAdminList),
}) })
const state = ref({ const state = ref({
@ -768,8 +782,8 @@ const onEditorChange = () => {
// emit('editor-event', emitCall('input_event', text)) // emit('editor-event', emitCall('input_event', text))
// 5 // 5
const now = new Date().getTime() const now = new Date().getTime()
Object.keys(state.value.revokedMessages).forEach(msgId => { Object.keys(state.value.revokedMessages).forEach((msgId) => {
if ((now - state.value.revokedMessages[msgId].revokeTime) > 5 * 60 * 1000) { if (now - state.value.revokedMessages[msgId].revokeTime > 5 * 60 * 1000) {
delete state.value.revokedMessages[msgId] delete state.value.revokedMessages[msgId]
} }
}) })
@ -932,27 +946,26 @@ const withdrawerConfirm = () => {
// //
const canEditRevokedMessage = (item) => { const canEditRevokedMessage = (item) => {
console.log( item) console.log(item)
if(item.is_revoke === 1 && item.msg_type === 1) { if (item.is_revoke === 1 && item.msg_type === 1) {
const now = new Date().getTime(); const now = new Date().getTime()
const revokeTime = new Date(item.created_at).getTime(); const revokeTime = new Date(item.created_at).getTime()
console.log(now) console.log(now)
// 5 // 5
return (now - revokeTime) <= 5 * 60 * 1000 return now - revokeTime <= 5 * 60 * 1000
} }
return false return false
} }
// //
const restoreRevokedMessage = async (item) => { const restoreRevokedMessage = async (item) => {
// //
const res = await detailGetRecordsContext({ const res = await detailGetRecordsContext({
msgId: item.msg_id msgId: item.msg_id,
}) })
console.log(res) console.log(res)
if(res.code == 200) { if (res.code == 200) {
const content = res.data.item?.extra?.content; const content = res.data.item?.extra?.content
const quill = getQuill() const quill = getQuill()
quill.setText(content) quill.setText(content)
// //
@ -970,7 +983,6 @@ const restoreRevokedMessage = async (item) => {
// //
} }
const actionDelete = (item) => { const actionDelete = (item) => {
console.log('删除') console.log('删除')
item.isCheck = true item.isCheck = true
@ -1290,7 +1302,32 @@ const queryRecordsByMsgInfo = (msgInfo) => {
} }
} }
//
const isLeader = computed(() => {
if (talkParams.adminList.length > 0) {
return (
talkParams.adminList.filter(
(adminItem) => adminItem.erp_user_id === useAuth()?.userInfo?.value?.ID,
).length > 0
)
}
return false
})
onMounted(async () => { onMounted(async () => {
if (typeof plus !== 'undefined') {
const webview = plus.webview.currentWebview()
webview.setStyle({
bottom: 0,
})
} else {
document.addEventListener('plusready', () => {
const webview = plus.webview.currentWebview()
webview.setStyle({
bottom: 0,
})
})
}
nextTick(() => { nextTick(() => {
state.value.mentionSelectHeight = pxTorPx( state.value.mentionSelectHeight = pxTorPx(
uni.getSystemInfoSync().windowHeight * 0.86, uni.getSystemInfoSync().windowHeight * 0.86,
@ -1340,7 +1377,7 @@ onUnmounted(() => {
.edit-revoked-message { .edit-revoked-message {
margin-left: 10rpx; margin-left: 10rpx;
color: #46299D; color: #46299d;
cursor: pointer; cursor: pointer;
font-size: 24rpx; font-size: 24rpx;

View File

@ -131,6 +131,7 @@ import addCircle from '@/static/image/chatList/addCircle.png'
import cahtPopover from '@/static/image/chatList/cahtPopover.png' import cahtPopover from '@/static/image/chatList/cahtPopover.png'
import zu3289 from '@/static/image/chatList/zu3289@2x.png' import zu3289 from '@/static/image/chatList/zu3289@2x.png'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue' import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import { handleSetWebviewStyle } from '@/utils/common'
const paging = ref() const paging = ref()
const isEmptyViewShow = ref(false) const isEmptyViewShow = ref(false)
const talkStore = useTalkStore() const talkStore = useTalkStore()
@ -214,6 +215,7 @@ const toAddressBookPage = () => {
); */ ); */
onShow(() => { onShow(() => {
handleSetWebviewStyle(true)
// //
talkStore talkStore
.loadTalkList() .loadTalkList()

View File

@ -14,6 +14,12 @@
<script setup> <script setup>
import searchList from './components/searchList.vue' import searchList from './components/searchList.vue'
import { ServeSeachQueryAll } from '@/api/search/index' import { ServeSeachQueryAll } from '@/api/search/index'
import { onMounted } from 'vue'
import { handleSetWebviewStyle } from '@/utils/common'
onMounted(() => {
handleSetWebviewStyle()
})
// //
const toMoreResultPage = (searchResultKey, searchText) => { const toMoreResultPage = (searchResultKey, searchText) => {

View File

@ -351,7 +351,7 @@ onMounted(() => {
const ServeQueryTalkDate = (month) => { const ServeQueryTalkDate = (month) => {
let params = { let params = {
month: month, month: month,
talk_type: 2, //12 talk_type: dialogueParams.talk_type, //12
receiver_id: state.receiver_id, //id receiver_id: state.receiver_id, //id
} }
const resp = ServeTalkDate(params) const resp = ServeTalkDate(params)
@ -477,12 +477,14 @@ const queryAllSearch = () => {
if (data?.items?.length > 0) { if (data?.items?.length > 0) {
data.items.forEach((item) => { data.items.forEach((item) => {
item.dateTime = parseTime(item?.created_at, '{m}/{d}') item.dateTime = parseTime(item?.created_at, '{m}/{d}')
if (item?.extra) {
item.extra.fileSize = fileFormatSize(item?.extra?.size) item.extra.fileSize = fileFormatSize(item?.extra?.size)
item.extra.typeText = item?.extra?.name item.extra.typeText = item?.extra?.name
? fileSuffix(item?.extra?.name) ? fileSuffix(item?.extra?.name)
: '' : ''
item.extra.file_avatar = fileTypeAvatar(item?.extra?.typeText) item.extra.file_avatar = fileTypeAvatar(item?.extra?.typeText)
console.log(item.extra.type) console.log(item.extra.type)
}
let year = new Date(item.created_at).getFullYear() let year = new Date(item.created_at).getFullYear()
let month = new Date(item.created_at).getMonth() + 1 let month = new Date(item.created_at).getMonth() + 1
let dateMonth = let dateMonth =

View File

@ -4,8 +4,8 @@ import { userInfoApi } from "@/api/user";
import {ref} from 'vue' import {ref} from 'vue'
export const useAuth = createGlobalState(() => { export const useAuth = createGlobalState(() => {
// const token = useStorage('token', '', uniStorage) const token = useStorage('token', '', uniStorage)
const token = ref("79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b8942f76b6f248056e8ae1134eda922b6ba0e5d75a00b2e866b08fec48a0d1de7e6dff8d8a40ac1eb46bf79c6331a1a3cd43209d09865bc0ee5dc9c23d2413e0d85d2380202ce4de1e128063926efae4cb1") // const token = ref("79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b899eade812a32201a0a025612a7615c43b1ac91d78661c4e9b7d0ca9701e2ea152073ff929e2cc3f2f29c1934a8873a44886758d3cf16439dfda105c00c3c2e0d8748163a63ce7ce8e44f599b42a89d2b6")
const refreshToken = useStorage('refreshToken', '', uniStorage) const refreshToken = useStorage('refreshToken', '', uniStorage)
const userInfo = useStorage('userInfo', {}, uniStorage) const userInfo = useStorage('userInfo', {}, uniStorage)
const leaderList = useStorage('leaderList', [], uniStorage) const leaderList = useStorage('leaderList', [], uniStorage)

View File

@ -48,6 +48,9 @@ export const useDialogueStore = defineStore('dialogue', {
// 是否显示会话列表 // 是否显示会话列表
isShowSessionList: true, isShowSessionList: true,
//是否已被解散
isDismiss: false,
// 群成员列表 // 群成员列表
members: [], members: [],
@ -98,6 +101,8 @@ export const useDialogueStore = defineStore('dialogue', {
this.unreadBubble = 0 this.unreadBubble = 0
this.isShowEditor = data?.is_robot === 0 this.isShowEditor = data?.is_robot === 0
this.isDismiss = data?.is_dismiss === 1 ? true : false
this.members = [] this.members = []
if (data.talk_type == 2) { if (data.talk_type == 2) {
this.updateGroupMembers() this.updateGroupMembers()

View File

@ -7,6 +7,7 @@ import { createGlobalState, useStorage } from '@vueuse/core'
import { uniStorage } from '@/utils/uniStorage.js' import { uniStorage } from '@/utils/uniStorage.js'
export const useDialogueListStore = createGlobalState(() => { export const useDialogueListStore = createGlobalState(() => {
// const dialogueList = useStorage('dialogueList', [], uniStorage)
const dialogueList = ref([]) const dialogueList = ref([])
const zpagingRef = ref() const zpagingRef = ref()
const virtualList = ref([]) const virtualList = ref([])

View File

@ -64,7 +64,7 @@ export function clipboard(text, callback) {
export async function clipboardImage(src, callback) { export async function clipboardImage(src, callback) {
const { state } = await navigator.permissions.query({ const { state } = await navigator.permissions.query({
name: 'clipboard-write' name: 'clipboard-write',
}) })
if (state != 'granted') return if (state != 'granted') return
@ -77,8 +77,8 @@ export async function clipboardImage(src, callback) {
if (blob.type == 'image/png') { if (blob.type == 'image/png') {
await navigator.clipboard.write([ await navigator.clipboard.write([
new ClipboardItem({ new ClipboardItem({
[blob.type]: blob [blob.type]: blob,
}) }),
]) ])
return callback() return callback()
@ -112,7 +112,7 @@ export async function clipboardImage(src, callback) {
URL.revokeObjectURL(objectURL) URL.revokeObjectURL(objectURL)
}, },
'image/png', 'image/png',
1 1,
) )
} }
} catch (err) { } catch (err) {
@ -180,13 +180,13 @@ export function getVideoImage(file, time = 1) {
width: video.videoWidth, width: video.videoWidth,
height: video.videoHeight, height: video.videoHeight,
duration: video.duration, duration: video.duration,
file: null file: null,
} }
canvas.toBlob((blob) => { canvas.toBlob((blob) => {
data.file = new File([blob], 'image.jpeg', { data.file = new File([blob], 'image.jpeg', {
type: blob.type, type: blob.type,
lastModified: Date.now() lastModified: Date.now(),
}) })
URL.revokeObjectURL(objectURL) URL.revokeObjectURL(objectURL)
@ -196,3 +196,20 @@ export function getVideoImage(file, time = 1) {
} }
}) })
} }
//处理webview样式
export function handleSetWebviewStyle(hasTabBar) {
const setWebviewStyle = () => {
const webview = plus.webview.currentWebview()
webview.setStyle({
bottom: hasTabBar ? webview.tabBarHeight : 0,
})
}
if (typeof plus !== 'undefined') {
setWebviewStyle()
} else {
document.addEventListener('plusready', () => {
setWebviewStyle()
})
}
}

View File

@ -38,13 +38,14 @@ export function formatTalkItem(params) {
is_disturb: 0, is_disturb: 0,
is_top: 0, is_top: 0,
is_online: 0, is_online: 0,
is_dismiss: 0,
is_robot: 0, is_robot: 0,
unread_num: 0, unread_num: 0,
content: '......', content: '......',
draft_text: '', draft_text: '',
msg_text: '', msg_text: '',
index_name: '', index_name: '',
updated_at: parseTime(new Date()) updated_at: parseTime(new Date()),
} }
options = { ...options, ...params } options = { ...options, ...params }

View File

@ -7,7 +7,7 @@ const request = axios.create({
baseURL: import.meta.env.VITE_BASEURL, baseURL: import.meta.env.VITE_BASEURL,
// 请求超时时间 // 请求超时时间
timeout: 10000 timeout: 60000
}) })
let once = false let once = false