diff --git a/pgweb/src/api/businessManage/inquiry.js b/pgweb/src/api/businessManage/inquiry.js
index 0a9e54b..dccd227 100644
--- a/pgweb/src/api/businessManage/inquiry.js
+++ b/pgweb/src/api/businessManage/inquiry.js
@@ -140,3 +140,9 @@ export async function checkBusinessNoIsValid (params) {
const res = await post('admin/Bussiness/checkBusinessNoIsValid', params)
return res
}
+
+// 获取未回价数量(return_price_status=2)
+export async function getUnreturnedPriceCount (params) {
+ const res = await post('admin/Pending/getUnreturnedPriceCount', params)
+ return res
+}
diff --git a/pgweb/src/components/menu/nxIconMenu.vue b/pgweb/src/components/menu/nxIconMenu.vue
index f90f6c7..9fbf43d 100644
--- a/pgweb/src/components/menu/nxIconMenu.vue
+++ b/pgweb/src/components/menu/nxIconMenu.vue
@@ -1,9 +1,8 @@
-
+
-
-
+
-
-
+
+
-
+
-
+
\ No newline at end of file
+.push-value-badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 18px;
+ height: 18px;
+ line-height: 18px;
+ padding: 0 4px;
+ font-size: 11px;
+ color: #fff;
+ background-color: #f56c6c;
+ border-radius: 9px;
+ margin-left: 4px;
+ text-align: center;
+ flex-shrink: 0;
+}
+
diff --git a/pgweb/src/components/menu/nxMenu.vue b/pgweb/src/components/menu/nxMenu.vue
index c8861c1..387609d 100644
--- a/pgweb/src/components/menu/nxMenu.vue
+++ b/pgweb/src/components/menu/nxMenu.vue
@@ -3,27 +3,85 @@
-
+
{{ item.title }}
+
+
+
+ {{ unreturnedCount }}
-
+
-
+
@@ -37,4 +95,26 @@
:deep .el-menu-item.is-active.menu-custom {
color: var(--main-color);
}
-
\ No newline at end of file
+ .push-value-badge {
+ display: inline-block;
+ min-width: 20px;
+ height: 20px;
+ line-height: 20px;
+ padding: 0 6px;
+ font-size: 12px;
+ color: #fff;
+ background-color: #f56c6c;
+ border-radius: 10px;
+ margin-left: 8px;
+ text-align: center;
+ }
+ .push-dot-badge {
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ background-color: #f56c6c;
+ border-radius: 50%;
+ margin-left: 8px;
+ margin-top: 4px;
+ }
+
diff --git a/pgweb/src/libs/socket.js b/pgweb/src/libs/socket.js
index 7c74449..1910f28 100644
--- a/pgweb/src/libs/socket.js
+++ b/pgweb/src/libs/socket.js
@@ -1,9 +1,65 @@
import io from 'socket.io-client'
+// 使用 polling 模式以兼容 PHPSocketIO 1.1
const socket = io(process.env.VUE_APP_SOCKET_URL, {
- transports: ['websocket'],
- reconnection: true, // 是否自动重新建立连接,默认为true
- reconnectionAttempts: 1 // 尝试重连的次数,默认为无限次
+ transports: ['polling'],
+ reconnection: true,
+ reconnectionAttempts: 5,
+ autoConnect: false,
+ forceNew: true,
+ timeout: 10000,
+ jsonp: false,
+ query: {},
+ upgrade: false,
+ allowUpgrades: false,
+ rejectUnauthorized: false,
+ timestampRequests: true
})
+// 添加连接状态监听
+socket.on('connect', () => {
+ console.log('WebSocket已成功连接到服务器:', process.env.VUE_APP_SOCKET_URL)
+})
+
+socket.on('disconnect', (reason) => {
+ console.log('WebSocket连接断开,原因:', reason)
+})
+
+socket.on('connect_error', (error) => {
+ console.error('WebSocket连接失败:', error)
+})
+
+socket.on('connect_timeout', () => {
+ console.error('WebSocket连接超时')
+})
+
+// 连接方法
+export const connectSocket = () => {
+ console.log('尝试启动WebSocket连接...')
+ console.log('当前连接状态:', socket.connected)
+ console.log('连接状态详细:', socket.io && socket.io.engine ? socket.io.engine.transport.name : '未知')
+ console.log('目标地址:', process.env.VUE_APP_SOCKET_URL)
+
+ // 如果未连接或者正在断开连接,尝试连接
+ if (!socket.connected || socket.disconnected) {
+ socket.connect()
+ console.log('WebSocket连接请求已发送')
+ } else {
+ console.log('WebSocket已经处于连接状态')
+ }
+}
+
+// 断开连接方法
+export const disconnectSocket = () => {
+ console.log('尝试断开WebSocket连接...')
+ console.log('当前连接状态:', socket.connected)
+
+ if (socket.connected) {
+ socket.disconnect()
+ console.log('WebSocket连接已断开')
+ } else {
+ console.log('WebSocket未连接,无需断开')
+ }
+}
+
export default socket
diff --git a/pgweb/src/libs/unreturnedPrice.js b/pgweb/src/libs/unreturnedPrice.js
new file mode 100644
index 0000000..3260195
--- /dev/null
+++ b/pgweb/src/libs/unreturnedPrice.js
@@ -0,0 +1,26 @@
+import { EventBus } from './eventBus'
+import { getUnreturnedPriceCount } from '@/api/businessManage/inquiry'
+
+/**
+ * 获取并更新未回价数量
+ * 调用API获取最新数量,并通过EventBus广播给所有监听者
+ */
+export const fetchAndUpdateUnreturnedPriceCount = async () => {
+ console.log('fetchAndUpdateUnreturnedPriceCount: 开始获取未回价数量...')
+ try {
+ const response = await getUnreturnedPriceCount()
+ if (response && response.code === 1) {
+ const count = response.data.count || 0
+ console.log('fetchAndUpdateUnreturnedPriceCount: 获取到未回价数量:', count)
+ // 通过事件总线传递数量给菜单组件
+ EventBus.$emit('updateUnreturnedCount', count)
+ return count
+ } else {
+ console.warn('fetchAndUpdateUnreturnedPriceCount: 接口返回异常:', response)
+ return 0
+ }
+ } catch (error) {
+ console.error('fetchAndUpdateUnreturnedPriceCount: 获取未回价数量失败:', error)
+ return 0
+ }
+}
\ No newline at end of file
diff --git a/pgweb/src/router/index.js b/pgweb/src/router/index.js
index 46d61d8..d907be4 100644
--- a/pgweb/src/router/index.js
+++ b/pgweb/src/router/index.js
@@ -5,6 +5,8 @@ import iView from 'view-design'
import { getToken, canTurnTo, initRouter, isRefreshToken } from '@/libs/util'
import * as localStore from 'store'
import store from '@/store'
+import { connectSocket } from '@/libs/socket'
+import { fetchAndUpdateUnreturnedPriceCount } from '@/libs/unreturnedPrice'
Vue.use(Router)
let routers = routes
@@ -30,6 +32,14 @@ const HOME_PAGE_NAME = 'home' // 平台首页
router.beforeEach((to, from, next) => {
iView.LoadingBar.start()
const token = getToken()
+
+ // 如果用户已登录,确保WebSocket连接已建立并获取最新未回价数量
+ if (token && to.name !== LOGIN_PAGE_NAME) {
+ connectSocket()
+ // 每次刷新页面都获取最新的未回价数量
+ fetchAndUpdateUnreturnedPriceCount()
+ }
+
if (!token && to.name !== LOGIN_PAGE_NAME) {
localStore.clearAll()
// 未登录且要跳转的页面不是登录页
diff --git a/pgweb/src/store/modules/user.js b/pgweb/src/store/modules/user.js
index e7ac8ea..a7c835f 100644
--- a/pgweb/src/store/modules/user.js
+++ b/pgweb/src/store/modules/user.js
@@ -3,6 +3,7 @@ import { login, checkLogin } from '@/api/user'
import store from 'store'
import config from '@/config'
import Cookies from 'js-cookie'
+import { connectSocket } from '@/libs/socket'
export default {
state: {
@@ -33,8 +34,8 @@ export default {
login (state, data) {
console.log("user.js::login::userinfo",data.userinfo)
// store.set('indexMenuList', JSON.stringify(data.menu['index']))
- // store.set('busMenuList', JSON.stringify(data.menu))
- store.set('busMenuList', JSON.stringify(data.admmenu))
+ // store.set('busMenuList', JSON.stringify(data.menu))
+ store.set('busMenuList', JSON.stringify(data.admmenu))
store.set('userinfo', data.userinfo)
store.set('isAdmin',data.userinfo.roleCode.includes("ROLE_ADMIN"))
store.set('access', data.perFlags)
@@ -53,7 +54,7 @@ export default {
},
actions: {
handleLogin ({ commit }, { username, password }) {
-
+
username = username.trim()
return new Promise((resolve, reject) => {
login({ username, password, version: config.version }).then(res => {
@@ -61,6 +62,8 @@ export default {
store.clearAll()
commit('setToken', res.data.apiAuth)
commit('login', res.data)
+ // 登录成功后启动WebSocket连接
+ connectSocket()
}
resolve(res)
}).catch(err => {
diff --git a/pgweb/src/views/home/components/message.vue b/pgweb/src/views/home/components/message.vue
index ae8a47e..8d8de99 100644
--- a/pgweb/src/views/home/components/message.vue
+++ b/pgweb/src/views/home/components/message.vue
@@ -196,13 +196,10 @@ export default {
WorkflowProgressCount: 0 // 工作流进度-未读消息数量
},
label1: (h) => {
- return h('div', [
+ const count = this.formItem.inquiryPendingCount || 0
+ return h('div', { style: { display: 'flex', alignItems: 'center' } }, [
h('span', '询价待处理'),
- h('Badge', {
- props: {
- count: this.formItem.inquiryPendingCount
- }
- })
+ count > 0 ? h('span', { class: 'message-badge' }, count) : null
])
},
/* label2: (h) => {
@@ -321,6 +318,8 @@ export default {
getMessageList().then(res => {
if (res.code === 1) {
this.formItem = res.data
+ console.log('message.vue 获取消息列表成功:', this.formItem)
+ console.log('询价待处理数量:', this.formItem.inquiryPendingCount)
} else {
this.$Message.error(res.msg)
}
@@ -332,7 +331,7 @@ export default {
if (res.code === 1) {
if (row.message_type == 5 || row.message_type == 8 || row.message_type == 11 || row.message_type == 14 || row.message_type == 29 || row.message_type == 31){
this.getMessageList()
- }
+ }
} else {
this.$Message.error(res.msg)
}
@@ -372,4 +371,17 @@ export default {
.issee {
color: #ccc;
}
+.message-badge {
+ display: inline-block;
+ min-width: 18px;
+ height: 18px;
+ line-height: 18px;
+ padding: 0 4px;
+ font-size: 11px;
+ color: #fff;
+ background-color: #f56c6c;
+ border-radius: 9px;
+ margin-left: 6px;
+ text-align: center;
+}
diff --git a/pgweb/src/views/home/home.vue b/pgweb/src/views/home/home.vue
index 2b58a8a..aadaeb5 100644
--- a/pgweb/src/views/home/home.vue
+++ b/pgweb/src/views/home/home.vue
@@ -24,8 +24,33 @@
diff --git a/pgweb/src/views/main/components/avatar/avatar.vue b/pgweb/src/views/main/components/avatar/avatar.vue
index 5f8c1ab..ff23731 100644
--- a/pgweb/src/views/main/components/avatar/avatar.vue
+++ b/pgweb/src/views/main/components/avatar/avatar.vue
@@ -1,10 +1,10 @@
-
+
-
{{username}}
+
{{username}}
@@ -27,6 +27,7 @@ import './avatar.less'
import { logout } from '@/api/user'
import store from 'store'
import changePassword from './changePassword'
+import { disconnectSocket } from '@/libs/socket'
export default {
name: 'avatar',
props: {
@@ -123,6 +124,8 @@ export default {
switch (name) {
case 'logout':
logout({}).then(() => {
+ // 断开WebSocket连接
+ disconnectSocket()
this.$store.commit('logout')
location.reload()
})
diff --git a/pgweb/src/views/main/components/user/user.vue b/pgweb/src/views/main/components/user/user.vue
index 6dd01c0..4671b1e 100644
--- a/pgweb/src/views/main/components/user/user.vue
+++ b/pgweb/src/views/main/components/user/user.vue
@@ -4,7 +4,7 @@
{{username}}-[退出]
-
+
@@ -18,6 +18,7 @@
import './user.less'
import { logout } from '@/api/user'
import store from 'store'
+import { disconnectSocket } from '@/libs/socket'
export default {
name: 'user',
props: {
@@ -39,6 +40,8 @@ export default {
switch (name) {
case 'logout':
logout({}).then(() => {
+ // 断开WebSocket连接
+ disconnectSocket()
this.$store.commit('logout')
location.reload()
})