feat(demo): auto local IP, HTTPS support, fix build

这个提交包含在:
徐勤民 2026-04-30 18:48:40 +08:00
父节点 28c1110344
当前提交 22f4982de4
共有 8 个文件被更改,包括 1761 次插入32 次删除

1
.env.local 普通文件
查看文件

@ -0,0 +1 @@
VITE_LOCAL_IP=10.222.233.79

1692
package-lock.json 自动生成的 普通文件

文件差异内容过多而无法显示 加载差异

查看文件

@ -5,7 +5,8 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"build": "vite build",
"typecheck": "vue-tsc -b --noEmit",
"preview": "vite preview"
},
"dependencies": {

查看文件

@ -4,12 +4,14 @@ import 'element-plus/dist/index.css'
import App from './App.vue'
import { init } from '@xuqm/vue3-sdk'
const localIP = import.meta.env.VITE_LOCAL_IP || '127.0.0.1'
init({
appKey: 'ak_demo_chat',
appSecret: 'as_demo_secret',
debug: true,
baseUrl: 'http://192.168.113.37:8082',
wsUrl: 'ws://192.168.113.37:8082/ws/im',
baseUrl: `http://${localIP}:8082`,
wsUrl: `ws://${localIP}:8082/ws/im`,
})
const app = createApp(App)

查看文件

@ -21,7 +21,7 @@
<el-tab-pane label="会话" name="conversations">
<div class="list-container">
<div
v-for="conv in conversations"
v-for="conv in im.conversations"
:key="conv.targetId"
:class="['conv-item', { active: currentTarget?.targetId === conv.targetId }]"
@click="selectConversation(conv)"
@ -35,7 +35,7 @@
<span class="conv-time">{{ formatTime(conv.lastMsgTime) }}</span>
</div>
</div>
<el-empty v-if="conversations.length === 0" description="暂无会话" />
<el-empty v-if="im.conversations.length === 0" description="暂无会话" />
</div>
</el-tab-pane>
@ -72,7 +72,7 @@
<div ref="msgContainer" class="message-list">
<div
v-for="msg in messages"
v-for="msg in im.messages"
:key="msg.id"
:class="['message-row', msg.fromId === userId ? 'self' : 'other']"
>
@ -97,7 +97,7 @@
</div>
</div>
</div>
<el-empty v-if="messages.length === 0 && currentTarget" description="暂无消息" />
<el-empty v-if="im.messages.length === 0 && currentTarget" description="暂无消息" />
</div>
<div v-if="currentTarget" class="input-area">
@ -175,7 +175,7 @@
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { User, ChatDotRound } from '@element-plus/icons-vue'
import { useIm } from '@xuqm/vue3-sdk'
import { useIm, http } from '@xuqm/vue3-sdk'
import type { ConversationView, ImGroup, FriendRequest } from '@xuqm/vue3-sdk'
import {
sendFriendRequest,
@ -189,12 +189,20 @@ import {
const props = defineProps<{ token: string; userId: string }>()
defineEmits<{ (e: 'logout'): void }>()
const {
connect, disconnect, send, revoke, messages, conversations, connected,
refreshConversations, loadHistory: fetchHistory, setConversationRead,
getFriends, getGroups, setConversationPinnedState, setConversationMutedState,
removeConversation,
} = useIm()
const im = useIm()
const connect = im.connect
const disconnect = im.disconnect
const send = im.send
const revoke = im.revoke
const connected = im.connected
const refreshConversations = im.refreshConversations
const fetchHistory = im.loadHistory
const setConversationRead = im.setConversationRead
const getFriends = im.getFriends
const getGroups = im.getGroups
const setConversationPinnedState = im.setConversationPinnedState
const setConversationMutedState = im.setConversationMutedState
const removeConversation = im.removeConversation
const activeTab = ref('conversations')
const activeCollapse = ref(['msg'])
@ -234,7 +242,7 @@ function statusType(s: string) {
function selectConversation(conv: ConversationView) {
currentTarget.value = conv
messages.value = [] // clear local messages when switching
im.im.messages.value = [] // clear local messages when switching
loadHistory()
}
@ -360,7 +368,7 @@ async function createGroup() {
try {
// Use http directly or API - demo uses simple approach
const { http } = await import('@xuqm/vue3-sdk')
const group = await http.post('/api/im/groups', {
const group = await http.post<{ id: string }>('/api/im/groups', {
name: `TestGroup_${Date.now()}`,
memberIds: ['user_b'],
groupType: 'WORK',
@ -448,7 +456,7 @@ async function getProfile() {
async function updateProfile() {
loading.value = true
try {
const p = await apiUpdateProfile(props.userId, `DemoUser_${Date.now()}`, null, 'MALE')
const p = await apiUpdateProfile(props.userId, `DemoUser_${Date.now()}`, undefined, 'MALE')
log(`更新昵称: ${p.nickname}`, 'success')
} catch (err: any) {
log(`更新失败: ${err.message}`, 'error')
@ -496,7 +504,7 @@ async function testAllApis() {
}
}
watch(messages, scrollToBottom, { deep: true })
watch(im.messages, scrollToBottom, { deep: true })
onMounted(() => {
connect()

查看文件

@ -60,7 +60,7 @@ function quickLogin(userId: string) {
async function doLogin(userId: string, password: string) {
loading.value = true
try {
const res = await fetch('http://192.168.113.37:8085/api/demo/auth/login', {
const res = await fetch('/api/demo/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ appId: 'ak_demo_chat', userId, password }),

查看文件

@ -13,7 +13,11 @@
"skipLibCheck": true,
"noEmit": true,
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
"paths": {
"@/*": ["src/*"],
"@xuqm/vue3-sdk": ["../XuqmGroup-Vue3SDK/dist/index.d.ts"]
},
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.vue"]
}

查看文件

@ -1,17 +1,38 @@
import { defineConfig } from 'vite'
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import fs from 'fs'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@xuqm/vue3-sdk': resolve(__dirname, '../XuqmGroup-Vue3SDK/src/index.ts'),
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
const localIP = env.VITE_LOCAL_IP || '127.0.0.1'
return {
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@xuqm/vue3-sdk': resolve(__dirname, '../XuqmGroup-Vue3SDK/dist/index.es.js'),
},
},
},
server: {
port: 5173,
host: true,
},
server: {
port: 5173,
host: true,
https: {
key: fs.readFileSync(resolve(__dirname, '../.certs/local-key.pem')),
cert: fs.readFileSync(resolve(__dirname, '../.certs/local.pem')),
},
proxy: {
'/api/demo': {
target: `http://${localIP}:8085`,
changeOrigin: true,
},
'/api/im': {
target: `http://${localIP}:8082`,
changeOrigin: true,
ws: true,
},
},
},
}
})