diff --git a/src/pages.json b/src/pages.json index 30861c1..72973ae 100644 --- a/src/pages.json +++ b/src/pages.json @@ -8,17 +8,21 @@ "pages": [ { "path": "pages/index/index", - "type": "page" + "type": "page", + "style": { + "navigationStyle": "custom", + "enablePullDownRefresh":false + } }, - - + + { "path": "pages/login/index", "type": "page", "style": {} } - - + + ], "globalStyle": { "backgroundColor": "#FFFFFF", diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index 8645e19..b6f3d85 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -1,17 +1,111 @@ + - diff --git a/src/plugins/websocket.ts b/src/plugins/websocket.ts new file mode 100644 index 0000000..66eecbc --- /dev/null +++ b/src/plugins/websocket.ts @@ -0,0 +1,163 @@ +const cache = new Set() + +const maxAttempts = 100 + +const defaultEvent = { + onError: (evt: any) => console.error('WebSocket Error:', evt), + onOpen: (evt: any) => console.log('WebSocket Opened:', evt), + onClose: (evt: any) => console.log('WebSocket Closed:', evt) +} + +class WsSocket { + connect: WebSocket | null = null + + config: any = { + heartbeat: { + setInterval: null, + pingInterval: 20000, + pingTimeout: 60000 + }, + reconnect: { + lockReconnect: false, + setTimeout: null, + interval: [2000, 2500, 3000, 3000, 5000, 8000], // Exponential backoff + attempts: maxAttempts + } + } + + lastTime: number = 0 + + onCallBacks: Record = {} + + defaultEvent: Record = defaultEvent + + constructor( + private urlCallBack: () => string, + private events: Partial + ) { + this.events = { ...this.defaultEvent, ...events } + } + + on(event: string, callback: Function): this { + this.onCallBacks[event] = callback + return this + } + + loadSocket(): void { + this.connect = new WebSocket(this.urlCallBack()) + this.connect.onerror = this.onError.bind(this) + this.connect.onopen = this.onOpen.bind(this) + this.connect.onmessage = this.onMessage.bind(this) + this.connect.onclose = this.onClose.bind(this) + } + + connection(): void { + this.connect === null && this.loadSocket() + } + + reconnect(): void { + if (this.config.reconnect.lockReconnect || this.config.reconnect.attempts <= 0) return + + this.config.reconnect.lockReconnect = true + this.config.reconnect.attempts-- + + const delay = this.config.reconnect.interval.shift() + + this.config.reconnect.setTimeout = setTimeout(() => { + console.log(new Date().toLocaleString(), 'Attempting to reconnect to WebSocket...') + this.connection() + }, delay || 10000) + } + + onParse(evt: MessageEvent): any { + return JSON.parse(evt.data) + } + + onOpen(evt: Event): void { + this.lastTime = Date.now() + + this.events.onOpen?.(evt) + + this.config.reconnect.interval = [1000, 1000, 3000, 5000, 10000] + this.config.reconnect.lockReconnect = false + this.config.reconnect.attempts = maxAttempts + + this.heartbeat() + } + + onClose(evt: CloseEvent): void { + this.events.onClose?.(evt) + this.connect = null + + this.config.heartbeat.setInterval && clearInterval(this.config.heartbeat.setInterval) + + this.config.reconnect.lockReconnect = false + + if (evt.code !== 1000) { + this.reconnect() + } + } + + onError(evt: Event): void { + this.events.onError?.(evt) + } + + onMessage(evt: MessageEvent): void { + this.lastTime = Date.now() + + const data = this.onParse(evt) + + if (data.event === 'pong') { + return + } + + if (data.ackid) { + this.connect?.send(`{"event":"ack","ackid":"${data.ackid}"}`) + + if (cache.has(data.ackid)) return + + cache.add(data.ackid) + } + + if (this.onCallBacks[data.event]) { + this.onCallBacks[data.event](data.payload, evt.data) + } else { + console.warn(`WsSocket message event [${data.event}] not bound...`) + } + } + + heartbeat(): void { + this.config.heartbeat.setInterval && clearInterval(this.config.heartbeat.setInterval) + + this.config.heartbeat.setInterval = setInterval(() => { + this.ping() + }, this.config.heartbeat.pingInterval) + } + + ping(): void { + this.connect?.send(JSON.stringify({ event: 'ping' })) + } + + send(message: any): void { + if (this.connect && this.connect.readyState === WebSocket.OPEN) { + this.connect.send(typeof message === 'string' ? message : JSON.stringify(message)) + } else { + alert('WebSocket 连接已关闭') + } + } + + close(): void { + this.connect?.close() + this.config.heartbeat.setInterval && clearInterval(this.config.heartbeat.setInterval) + } + + emit(event: string, payload: any): void { + if (this.connect && this.connect.readyState === WebSocket.OPEN) { + this.connect.send(JSON.stringify({ event, payload })) + } else { + console.error('WebSocket connection closed...', this.connect) + } + } +} + +export default WsSocket diff --git a/src/static/image/chatList/zu4989@2x.png b/src/static/image/chatList/zu4989@2x.png new file mode 100644 index 0000000..36cccdd Binary files /dev/null and b/src/static/image/chatList/zu4989@2x.png differ diff --git a/src/static/image/chatList/zu4991@2x.png b/src/static/image/chatList/zu4991@2x.png new file mode 100644 index 0000000..7e106ea Binary files /dev/null and b/src/static/image/chatList/zu4991@2x.png differ diff --git a/src/static/image/chatList/zu4992@2x.png b/src/static/image/chatList/zu4992@2x.png new file mode 100644 index 0000000..7ff81a2 Binary files /dev/null and b/src/static/image/chatList/zu4992@2x.png differ diff --git a/src/static/image/chatList/zu5296@2x.png b/src/static/image/chatList/zu5296@2x.png new file mode 100644 index 0000000..124aac0 Binary files /dev/null and b/src/static/image/chatList/zu5296@2x.png differ diff --git a/src/store/auth/index.js b/src/store/auth/index.js index c914b6f..a26ecf5 100644 --- a/src/store/auth/index.js +++ b/src/store/auth/index.js @@ -7,12 +7,38 @@ export const useAuth = createGlobalState(() => { const refreshToken = useStorage('refreshToken', '', uniStorage) const userInfo = useStorage('userInfo', {}, uniStorage) const leaderList = useStorage('leaderList', [], uniStorage) + const myCompany = useStorage('myCompany','', uniStorage) const isLeader=ref(false) // const leaderList=ref([]) + const getUserInfo=async ()=>{ + const data={ + ID:userInfo.value.ID + } + const res= await userInfoApi(data) + if (res.status===0){ + userInfo.value=res.data + } + } + const getUserLeader=async ()=>{ + const data={ + departmentId:userInfo.value.PositionUsers?.map(x=>x.DepartmentId) + } + const res= await userLeaderApi(data) + if (res.status===0){ + isLeader.value=!!res.data.departmentLeaders?.find((x) => { + return x.userID === userInfo.value.ID + }) + leaderList.value=res.data.departmentLeaders + myCompany.value=res.data.company + } + + } return { leaderList, - + myCompany, + getUserLeader, + getUserInfo, userInfo, token, refreshToken, diff --git a/src/store/chatList/index.js b/src/store/chatList/index.js new file mode 100644 index 0000000..ae1744e --- /dev/null +++ b/src/store/chatList/index.js @@ -0,0 +1,20 @@ +import {createGlobalState,useStorage} from '@vueuse/core' +import {uniStorage} from "@/utils/uniStorage.js" + +import {ref} from 'vue' +export const useChatList = createGlobalState(() => { + // const token = useStorage('token', '', uniStorage) + // const refreshToken = useStorage('refreshToken', '', uniStorage) + // const userInfo = useStorage('userInfo', {}, uniStorage) + // const leaderList = useStorage('leaderList', [], uniStorage) + // const isLeader=ref(false) + // const leaderList=ref([]) + + return { + // leaderList, + + // userInfo, + // token, + // refreshToken, + } +})