feat(demo): auto local IP, HTTPS support, fix build
这个提交包含在:
父节点
28c1110344
当前提交
22f4982de4
1
.env.local
普通文件
1
.env.local
普通文件
@ -0,0 +1 @@
|
||||
VITE_LOCAL_IP=10.222.233.79
|
||||
1692
package-lock.json
自动生成的
普通文件
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({
|
||||
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/src/index.ts'),
|
||||
'@xuqm/vue3-sdk': resolve(__dirname, '../XuqmGroup-Vue3SDK/dist/index.es.js'),
|
||||
},
|
||||
},
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户