davy66666 1 miesiąc temu
rodzic
commit
11b4dff5a1

+ 14 - 12
config/dev.env.ts

@@ -1,13 +1,15 @@
+const domian = 'openimhailiao.com'
+
 export default {
-	NODE_ENV: 'development',
-	CHAT_URL: 'https://openimadmin.app12345.cn/chat',
-	API_URL: 'https://openimadmin.app12345.cn/api',
-	WS_URL: 'wss://openimadmin.app12345.cn/msg_gateway',
-	//CHAT_URL: "http://120.77.93.35:10008",
-	//API_URL: "http://120.77.93.35:10002",
-	//WS_URL: "ws://120.77.93.35:10001",
-	OBJECT_STORAGE: 'minio',
-	AMAP_KEY: '36e6a7bb847411f06258d03b066ecc67',//jsapi
-	AMAP_SNAP_KEY: '39b41b2a48453d7e66007c6f45d26a12',
-	VERSION: 'HI.CHAT 1.0.50',
-}
+  NODE_ENV: 'development',
+  CHAT_URL: `https://${domian}/chat`,
+  API_URL: `https://${domian}/api`,
+  WS_URL: `wss://${domian}/msg_gateway`,
+  //CHAT_URL: "http://120.77.93.35:10008",
+  //API_URL: "http://120.77.93.35:10002",
+  //WS_URL: "ws://120.77.93.35:10001",
+  OBJECT_STORAGE: 'minio',
+  AMAP_KEY: '36e6a7bb847411f06258d03b066ecc67', //jsapi
+  AMAP_SNAP_KEY: '39b41b2a48453d7e66007c6f45d26a12',
+  VERSION: 'HI.CHAT 1.0.50',
+}

+ 5 - 3
config/prod.env.ts

@@ -1,8 +1,10 @@
+const domian = 'openimhailiao.com'
+
 export default {
 	NODE_ENV: 'development',
-	CHAT_URL: 'https://openimadmin.app12345.cn/chat',
-	API_URL: 'https://openimadmin.app12345.cn/api',
-	WS_URL: 'wss://openimadmin.app12345.cn/msg_gateway',
+	CHAT_URL: `https://${domian}/chat`,
+  API_URL: `https://${domian}/api`,
+  WS_URL: `wss://${domian}/msg_gateway`,
 	//CHAT_URL: "http://120.77.93.35:10008",
 	//API_URL: "http://120.77.93.35:10002",
 	//WS_URL: "ws://120.77.93.35:10001",

+ 68 - 0
package-lock.json

@@ -32,6 +32,7 @@
         "vite-plugin-vue-setup-extend": "^0.4.0",
         "vue": "^3.2.37",
         "vue-clipboard3": "^2.0.0",
+        "vue-dompurify-html": "^5.2.0",
         "vue-request": "^2.0.4",
         "vue-router": "^4.1.5",
         "vue3-qr-reader": "^1.0.0",
@@ -43,6 +44,7 @@
         "@types/md5": "^2.3.2",
         "@types/node": "^16.11.7",
         "@types/uuid": "^9.0.0",
+        "@vitejs/plugin-basic-ssl": "^1.2.0",
         "@vitejs/plugin-vue": "^4.0.0",
         "@vitejs/plugin-vue-jsx": "^3.0.0",
         "@vuemap/unplugin-resolver": "^2.0.0",
@@ -1230,6 +1232,12 @@
       "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==",
       "devOptional": true
     },
+    "node_modules/@types/trusted-types": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+      "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+      "optional": true
+    },
     "node_modules/@types/uuid": {
       "version": "9.0.0",
       "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz",
@@ -1254,6 +1262,18 @@
         "vue": "^3.0.0"
       }
     },
+    "node_modules/@vitejs/plugin-basic-ssl": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz",
+      "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=14.21.3"
+      },
+      "peerDependencies": {
+        "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
+      }
+    },
     "node_modules/@vitejs/plugin-vue": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz",
@@ -2328,6 +2348,14 @@
       "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
       "dev": true
     },
+    "node_modules/dompurify": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.5.tgz",
+      "integrity": "sha512-mLPd29uoRe9HpvwP2TxClGQBzGXeEC/we/q+bFlmPPmj2p2Ugl3r6ATu/UU1v77DXNcehiBg9zsr1dREyA/dJQ==",
+      "optionalDependencies": {
+        "@types/trusted-types": "^2.0.7"
+      }
+    },
     "node_modules/downloadjs": {
       "version": "1.4.7",
       "resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz",
@@ -4702,6 +4730,17 @@
         "clipboard": "^2.0.6"
       }
     },
+    "node_modules/vue-dompurify-html": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/vue-dompurify-html/-/vue-dompurify-html-5.2.0.tgz",
+      "integrity": "sha512-GX+BStkKEJ8wu/+hU1EK2nu/gzXWhb4XzBu6aowpsuU/3nkvXvZ2jx4nZ9M3jtS/Vu7J7MtFXjc7x3cWQ+zbVQ==",
+      "dependencies": {
+        "dompurify": "^3.2.1"
+      },
+      "peerDependencies": {
+        "vue": "^3.0.0"
+      }
+    },
     "node_modules/vue-i18n": {
       "version": "9.1.10",
       "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.1.10.tgz",
@@ -5773,6 +5812,12 @@
       "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==",
       "devOptional": true
     },
+    "@types/trusted-types": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+      "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+      "optional": true
+    },
     "@types/uuid": {
       "version": "9.0.0",
       "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz",
@@ -5795,6 +5840,13 @@
       "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
       "requires": {}
     },
+    "@vitejs/plugin-basic-ssl": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz",
+      "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==",
+      "dev": true,
+      "requires": {}
+    },
     "@vitejs/plugin-vue": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz",
@@ -6589,6 +6641,14 @@
       "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
       "dev": true
     },
+    "dompurify": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.5.tgz",
+      "integrity": "sha512-mLPd29uoRe9HpvwP2TxClGQBzGXeEC/we/q+bFlmPPmj2p2Ugl3r6ATu/UU1v77DXNcehiBg9zsr1dREyA/dJQ==",
+      "requires": {
+        "@types/trusted-types": "^2.0.7"
+      }
+    },
     "downloadjs": {
       "version": "1.4.7",
       "resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz",
@@ -8228,6 +8288,14 @@
         "clipboard": "^2.0.6"
       }
     },
+    "vue-dompurify-html": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/vue-dompurify-html/-/vue-dompurify-html-5.2.0.tgz",
+      "integrity": "sha512-GX+BStkKEJ8wu/+hU1EK2nu/gzXWhb4XzBu6aowpsuU/3nkvXvZ2jx4nZ9M3jtS/Vu7J7MtFXjc7x3cWQ+zbVQ==",
+      "requires": {
+        "dompurify": "^3.2.1"
+      }
+    },
     "vue-i18n": {
       "version": "9.1.10",
       "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.1.10.tgz",

+ 3 - 1
package.json

@@ -5,7 +5,7 @@
   "type": "module",
   "scripts": {
     "dev": "vite",
-    "build": "vue-tsc --noEmit && vite build",
+    "build": "vite build",
     "preview": "vite preview",
     "format": "prettier --write .",
     "postinstall": "patch-package"
@@ -34,6 +34,7 @@
     "vite-plugin-vue-setup-extend": "^0.4.0",
     "vue": "^3.2.37",
     "vue-clipboard3": "^2.0.0",
+    "vue-dompurify-html": "^5.2.0",
     "vue-request": "^2.0.4",
     "vue-router": "^4.1.5",
     "vue3-qr-reader": "^1.0.0",
@@ -45,6 +46,7 @@
     "@types/md5": "^2.3.2",
     "@types/node": "^16.11.7",
     "@types/uuid": "^9.0.0",
+    "@vitejs/plugin-basic-ssl": "^1.2.0",
     "@vitejs/plugin-vue": "^4.0.0",
     "@vitejs/plugin-vue-jsx": "^3.0.0",
     "@vuemap/unplugin-resolver": "^2.0.0",

+ 1 - 1
src/layout/index.vue

@@ -30,7 +30,7 @@
 	})
 
 	router.beforeEach(async (to, from, next) => {
-		if (to.path === '/getCode') {
+		if (to.path === '/getCode' || to.path === '/register') {
 			next()
 			return
 		}

+ 2 - 0
src/main.ts

@@ -1,4 +1,5 @@
 import { createApp } from 'vue'
+import VueDOMPurifyHTML from 'vue-dompurify-html';
 import './style.scss'
 import App from './App.vue'
 import router from './router'
@@ -28,6 +29,7 @@ const app = createApp(App)
 app.use(router)
 app.use(store)
 app.use(i18n)
+app.use(VueDOMPurifyHTML);
 errorHandler(app)
 
 app.mount('#app')

+ 53 - 3
src/pages/contact/createGroup/index.vue

@@ -33,8 +33,23 @@
 			</div>
 		</div>
 
-		<van-uploader v-show="false" ref="uploaderRef" accept="image/*" capture="camcorder" :preview-image="false"
-			:multiple="false" :after-read="afterReadFile" reupload max-count="1" />
+		<van-uploader
+			v-show="false"
+			ref="uploaderRef"
+			:accept="uploadChooseOptions.accept"
+			:capture="uploadChooseOptions.capture"
+			:preview-image="false"
+			:multiple="false"
+			:after-read="afterReadFile"
+			reupload max-count="1"
+		/>
+
+		<van-action-sheet
+			v-model:show="isShowActionSheet"
+			teleport="body"
+			:actions="actionList"
+			@select="onActionSelect"
+		/>
 	</div>
 </template>
 
@@ -54,6 +69,12 @@
 	type CreateGroupProps = {
 		groupType : GroupType
 	}
+
+	enum ChooseGroupAvatarActionType {
+		Album,
+  	Shoot,
+	}
+
 	const props = defineProps<CreateGroupProps>()
 
 	const { toSpecifiedConversation } = useConversationToggle()
@@ -65,6 +86,25 @@
 		groupName: '',
 		groupFaceUrl: '',
 	})
+
+	const uploadChooseOptions = reactive({
+		accept: '*',
+		capture: undefined as any,
+	})
+
+	const isShowActionSheet = ref(false)
+
+	const actionList = [
+		{
+			name: t('picture'),
+			type: ChooseGroupAvatarActionType.Album,
+		},
+		{
+			name: t('photograph'),
+			type: ChooseGroupAvatarActionType.Shoot,
+		},
+	]
+
 	const checkedUserList = ref<PublicUserItem[]>([])
 	const createLoading = ref(false)
 	const uploaderRef = ref<UploaderInstance>()
@@ -131,7 +171,17 @@
 	}
 
 	const chooseAvatar = () => {
-		uploaderRef.value?.chooseFile()
+		isShowActionSheet.value = true
+	}
+
+	const onActionSelect = ({ type } : any, idx : number) => {
+		if (type === ChooseGroupAvatarActionType.Shoot) {
+			uploadChooseOptions.capture = 'camera'
+		} else {
+			uploadChooseOptions.accept = 'image/*'
+		}
+		nextTick(() => uploaderRef.value?.chooseFile())
+		isShowActionSheet.value = false
 	}
 
 	onBeforeMount(() => {

+ 7 - 7
src/pages/conversation/chat/components/ChatContent.vue

@@ -32,12 +32,12 @@
 
 			<template v-if="showMoreMember">
 				<div class="mt-3 flex w-full flex-row justify-start px-1">
-					<div class="flex w-1/6 justify-center" v-for="item in callingData!.participant!.slice(0, 5)"
+					<div class="flex w-1/6 justify-center" v-for="item in callingData?.participant?.slice(0, 5)"
 						:key="item.userInfo.userID">
-						<Avatar :size="44" :src="item!.groupMemberInfo!.faceURL"
-							:desc="item!.groupMemberInfo!.nickname" />
+						<Avatar :size="44" :src="item?.groupMemberInfo?.faceURL"
+							:desc="item?.groupMemberInfo?.nickname" />
 					</div>
-					<div class="flex w-1/6 justify-center" v-if="callingData!.participant!.length > 5">
+					<div class="flex w-1/6 justify-center" v-if="callingData?.participant?.length > 5">
 						<img :src="more" class="h-11 w-11" alt="more" />
 					</div>
 				</div>
@@ -49,7 +49,7 @@
 		<virtual-list :class="{ '!flex-col': overflow }" ref="vsl" class="my_scrollbar h-full overflow-y-auto"
 			:data-key="'clientMsgID'" :data-sources="messageStore.storeHistoryMessageList" :topThreshold="120"
 			:keeps="50" :data-component="
-        (message: MessageItem) =>
+        (message) =>
           checkIsNotification(message) ? SystemNotificationItem : MessageItemVue
       " :extra-props="{
         showCheck: multipleCheckVisible,
@@ -173,8 +173,8 @@
 
 	const joinRtc = () => {
 		emitter.emit('OPEN_RTC_MODAL', {
-			invitation: callingData!.value!.invitation,
-			participant: callingData!.value!.participant?.[0],
+			invitation: callingData?.value?.invitation,
+			participant: callingData?.value?.participant?.[0],
 			isJoin: true,
 		})
 	}

+ 12 - 3
src/pages/conversation/chat/components/ChatFooter/ChatFooter.vue

@@ -19,8 +19,8 @@
 				</div>
 			</div>
 			<img @click="clickEmojiBtn" class="ml-3 h-[26px] min-w-[26px]" :src="emoji" alt="" />
-			<img v-show="!messageContent" @click="clickAddBtn" class="ml-3 h-[26px] min-w-[26px]" :src="add" alt="" />
-			<div class="send ml-2" v-show="messageContent" @click="switchTextMessage">
+			<img v-show="!isInputMessageTyped" @click="clickAddBtn" class="ml-3 h-[26px] min-w-[26px]" :src="add" alt="" />
+			<div class="send ml-2" v-show="isInputMessageTyped" @click="switchTextMessage">
 				发送
 			</div>
 		</div>
@@ -79,7 +79,13 @@
 			? `${t('messageMenu.replay')}:${formatMessageByType(conversationStore.storeQuoteMessage)}`
 			: null,
 	)
-
+	const isInputMessageTyped = computed(() => {
+		// 清空输入框的时候 组件只会返回空的<br>而不是空字符串.
+		if (!messageContent.value) {
+			return false
+		}
+		return messageContent.value !== '<br>'
+	})
 	const clearQuoteMessage = () => {
 		conversationStore.updateQuoteMessage()
 	}
@@ -316,6 +322,9 @@
 	})
 
 	onActivated(() => {
+		if (!conversationStore.currentConversation?.draftText) {
+			return
+		}
 		inputRef.value.clear()
 		inputRef.value.inputRef.focus()
 		if (!conversationStore.currentConversation.conversationID) return

+ 5 - 5
src/pages/conversation/chat/components/ChatFooter/ChatFooterAction.vue

@@ -80,11 +80,11 @@
 			icon: card,
 			type: ChatFooterActionType.IDCard,
 		},
-		{
-			text: t('footerAction.location'),
-			icon: location,
-			type: ChatFooterActionType.Location,
-		},
+		// {
+		// 	text: t('footerAction.location'),
+		// 	icon: location,
+		// 	type: ChatFooterActionType.Location,
+		// },
 	]
 
 	const albumActions = [

+ 1 - 1
src/pages/conversation/index/components/ConversationListItem.vue

@@ -14,7 +14,7 @@
 					<span v-show="messagePrefix" class="mr-1" :class="{ 'text-[#02C25F]': activePrefix }">
 						{{ messagePrefix }}
 					</span>
-					<span>{{ formattedMessage }}</span>
+					<span v-dompurify-html="formattedMessage"></span>
 				</div>
 			</div>
 			<div class="flex h-12 flex-col items-end text-xs text-[#999]"

+ 2 - 2
src/pages/login/index/index.vue

@@ -248,8 +248,8 @@
 	const reSend = () => {
 		if (count.value > 0) return; // 倒计时未结束时不允许再次发送
 		sendSms({
-				email: formData.email,
-				phoneNumber: formData.phoneNumber,
+				email: isByEmail.value ? formData.email : undefined,
+				phoneNumber: !isByEmail.value ? formData.phoneNumber : undefined,
 				areaCode: formData.areaCode,
 				usedFor: UsedFor.Login // 用于登录的短信
 			})

+ 34 - 7
src/pages/login/register/index.vue

@@ -69,15 +69,15 @@
 				</div>
 
 				<!-- 服务协议 -->
-				<div class="tips">
+				<!-- <div class="tips">
 					<van-checkbox v-model="checked"></van-checkbox> 我已阅读并同意 <a
 						href="https://changliaoadmin.app12345.cn/contnent">《软件许可及服务协议》</a> 本页收集的信息仅用于注册账号
-				</div>
+				</div> -->
 
 				<!-- 提交按钮,只有勾选了服务协议才可以提交 -->
 				<van-button :loading="loading" :disabled="!checked || !validateForm()" block type="success"
 					native-type="submit">
-					同意并继续
+					注册
 				</van-button>
 			</van-form>
 
@@ -98,7 +98,8 @@
 	} from 'vant';
 	import {
 		register,
-		sendSms
+		sendSms,
+		login
 	} from '@/api/login';
 	import countryCode from '@/utils/areaCode';
 	import {
@@ -120,7 +121,7 @@
 		isByEmail: boolean
 	} > ()
 	const isByEmail = props.isByEmail; // 是否使用邮箱注册
-	const checked = ref(false); // 是否勾选服务协议
+	const checked = ref(true); // 是否勾选服务协议
 	const loading = ref(false); // 是否显示加载动画
 	const showAreaCode = ref(false); // 是否显示国家/地区选择弹窗
 	const count = ref(0); // 倒计时
@@ -145,6 +146,30 @@
 		birth: 0,
 	});
 
+	const loginHandle = async () => {
+		localStorage.setItem("IMAccount", formData.phoneNumber); // 保存手机号到本地存储
+			const {
+				data: {
+					chatToken,
+					imToken,
+					userID
+				}
+			} = await login({
+				email: formData.email,
+				phoneNumber: formData.phoneNumber,
+				verifyCode: formData.verificationCode,
+				password: formData.password ? md5(formData.password) : '', // 密码MD5加密
+				areaCode: formData.areaCode
+			});
+
+			setIMProfile({
+				chatToken,
+				imToken,
+				userID
+			}); // 保存登录信息
+			router.push('/conversation'); // 跳转到会话页面
+	}
+
 	// 表单提交时的处理逻辑
 	const onSubmit = async () => {
 		loading.value = true;
@@ -183,9 +208,11 @@
 			}); // 设置用户IM资料
 			feedbackToast({
 				message: t("注册成功"),
-				onClose: () => router.push('login'),
+				// onClose: () => router.push('login'),
+				onClose: () => loginHandle()
 			});
-			router.push('login'); // 注册成功后跳转至登录页面
+			// loginHandle()
+			// router.push('login'); // 注册成功后跳转至登录页面
 		} catch (error) {
 
 			const errorMessages: Record < number, string > = {

+ 2 - 2
src/pages/moments/index/components/MomentsHeader.vue

@@ -1,8 +1,8 @@
 <template>
 	<div>
-		<van-nav-bar placeholder fixed left-arrow :clickable="false" :border="false" @click-left="router.back()">
+		<van-nav-bar placeholder fixed left-arrow :clickable="false" :border="false" >
 			<template #left>
-				<img class="h-5 w-3" :src="arrows" alt="" />
+				<!-- <img class="h-5 w-3" :src="arrows" alt="" /> -->
 			</template>
 
 			<template #right>

+ 7 - 7
src/pages/profile/index/index.vue

@@ -84,11 +84,11 @@
 			title: t("profileMenu.accountSetting"),
 			route: 'accountSettings'
 		},
-		{
-			icon: about,
-			title: t("profileMenu.aboutUs"),
-			route: 'about'
-		},
+		// {
+		// 	icon: about,
+		// 	title: t("profileMenu.aboutUs"),
+		// 	route: 'about'
+		// },
 		{
 			icon: logout,
 			title: t("profileMenu.logOut"),
@@ -99,8 +99,8 @@
 	watch(locale, () => {
 		profileMenus1[0].title = t("profileMenu.personalInformation");
 		profileMenus[0].title = t("profileMenu.accountSetting");
-		profileMenus[1].title = t("profileMenu.aboutUs");
-		profileMenus[2].title = t("profileMenu.logOut");
+		// profileMenus[1].title = t("profileMenu.aboutUs");
+		profileMenus[1].title = t("profileMenu.logOut");
 	});
 
 	const router = useRouter()

+ 3 - 0
vite.config.ts

@@ -9,6 +9,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
 import { VueAmapResolver } from '@vuemap/unplugin-resolver'
 import userConfig from './config'
 import { visualizer } from 'rollup-plugin-visualizer'
+import basicSsl from '@vitejs/plugin-basic-ssl'
 
 // https://vitejs.dev/config/
 export default defineConfig({
@@ -20,6 +21,7 @@ export default defineConfig({
 		}
 	},
 	server: {
+		https: true,
 		port: 3003,
 		host: '0.0.0.0',
 		hmr: true,
@@ -29,6 +31,7 @@ export default defineConfig({
 			process.env.NODE_ENV === 'production' ? userConfig.buildEnv : userConfig.devEnv,
 	},
 	plugins: [
+		basicSsl(),
 		vue(),
 		vueJsx(),
 		VueSetupExtend(),