diff --git a/im-admin-ui/src/api/im/agent/index.ts b/im-admin-ui/src/api/im/agent/index.ts index ee930ca..5ccc9d7 100644 --- a/im-admin-ui/src/api/im/agent/index.ts +++ b/im-admin-ui/src/api/im/agent/index.ts @@ -27,4 +27,27 @@ export function getAgentFloatBallConfig(token: string): AxiosPromise { method: 'get', params: { token } }); -} \ No newline at end of file +} + + +/** + * 获取默认客服ID + */ +export function getDefaultKefu(): AxiosPromise { + return request({ + url: '/im/agent/defaultKefu', + method: 'get' + }); +} + +/** + * 保存默认客服ID + * @param kefuId 客服ID,传null表示清除 + */ +export function saveDefaultKefu(kefuId: number | null): AxiosPromise { + return request({ + url: '/im/agent/saveDefaultKefu', + method: 'post', + data: { defaultKefuId: kefuId } + }); +} diff --git a/im-admin-ui/src/views/im/code/components/wangye.vue b/im-admin-ui/src/views/im/code/components/wangye.vue index 1073fe0..0c9e796 100644 --- a/im-admin-ui/src/views/im/code/components/wangye.vue +++ b/im-admin-ui/src/views/im/code/components/wangye.vue @@ -19,7 +19,7 @@ openUrl: '{{ siteUrl }}', token: '{{ uniqueToken }}', isShowTip: true, - kefuid: '', + kefuid: '{{ kefuId || "" }}', mobileIcon: '{{ floatConfig?.mobileImage || "" }}', pcIcon: '{{ floatConfig?.pcImage || "" }}', windowStyle:'', @@ -49,6 +49,7 @@ const props = defineProps<{ tokeninfo?: any; siteUrl?: string; uniqueToken: string; + kefuId?: number; floatConfig?: { // 新增 pcImage: string; mobileImage: string; diff --git a/im-admin-ui/src/views/im/code/index.vue b/im-admin-ui/src/views/im/code/index.vue index 9e5b2e4..1b890c2 100644 --- a/im-admin-ui/src/views/im/code/index.vue +++ b/im-admin-ui/src/views/im/code/index.vue @@ -2,6 +2,30 @@
+ +
+ 指定客服: + + +
+ + {{ item.nickName }} +
+
+
+
- +
@@ -30,8 +54,10 @@ import { ref, computed, onMounted, getCurrentInstance } from 'vue'; import alink from './components/alink.vue'; import wangye from './components/wangye.vue'; import FloatBallSetting from './components/FloatBallSetting.vue'; +import { listUser } from '@/api/im/user/customer'; import type { FloatBallConfig } from './components/FloatBallSetting.vue'; import { getInfo } from '@/api/login'; +import { getDefaultKefu, saveDefaultKefu } from '@/api/im/agent'; // import kaifa from './components/kaifa'; // import setting from './components/setting'; @@ -57,6 +83,9 @@ const siteUrl = ref(`${location.origin}`); const cloneTip = ref(false); const canCustomerServer = ref(''); +const selectedKefuId = ref(''); +const kefuList = ref([]); + const linkUrl = computed(() => `${location.origin}/chat/index?token=${token.value?.token_md5}&noCanClose=1`); onMounted(() => { // 页面加载就获取当前代理的 uniqueToken ✅ @@ -86,13 +115,45 @@ async function fetchAgentToken() { if (res.data?.tokenInfo?.uniqueToken) { // 拿到真正的 token! uniqueToken.value = res.data.tokenInfo.uniqueToken; - console.log('✅ 获取成功 uniqueToken =', uniqueToken.value); + await Promise.all([loadKefuList(), loadDefaultKefu()]); } } catch (e) { console.error('获取token失败', e); } } +async function loadKefuList() { + try { + const res = await listUser(); + const data = (res as any)?.rows || []; + kefuList.value = data; + } catch (e) { + console.error('获取客服列表失败', e); + } +} + +// 加载已保存的默认客服ID +async function loadDefaultKefu() { + try { + const kefuId = await getDefaultKefu(); + if (kefuId.data) { + selectedKefuId.value = kefuId.data; + } + } catch (e) { + console.error('获取默认客服失败', e); + } +} + + +async function onKefuChange(val: number | '') { + try { + await saveDefaultKefu(val || null); + proxy?.$Message?.success('已保存'); + } catch (e) { + console.error('保存默认客服失败', e); + } +} + // 处理悬浮球配置更新 function handleFloatBallConfigUpdate(config: FloatBallConfig) { floatBallConfig.value = config; diff --git a/im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImAgentController.java b/im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImAgentController.java index fcb7dff..31a67be 100644 --- a/im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImAgentController.java +++ b/im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImAgentController.java @@ -139,4 +139,23 @@ public class ImAgentController extends BaseController { public R>> getAllAgentNameList() { return R.ok(imAgentService.getAllAgentNameList()); } + + /** + * 获取默认客服ID + */ + @GetMapping("/defaultKefu") + public R getDefaultKefu() { + return R.ok(imAgentService.getDefaultKefuId()); + } + + /** + * 保存默认客服ID + */ + @RepeatSubmit() + @PostMapping("/saveDefaultKefu") + public R saveDefaultKefu(@RequestBody ImAgentBo bo) { + imAgentService.saveDefaultKefuId(bo.getDefaultKefuId()); + return R.ok(); + } + } diff --git a/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImAgent.java b/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImAgent.java index 595e8f5..0861f27 100644 --- a/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImAgent.java +++ b/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/ImAgent.java @@ -76,4 +76,9 @@ public class ImAgent implements TransPojo { */ private String mobileFloatBall; + /** + * 默认客服 + */ + private Long defaultKefuId; + } diff --git a/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/bo/ImAgentBo.java b/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/bo/ImAgentBo.java index 9541ee5..8a5be4c 100644 --- a/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/bo/ImAgentBo.java +++ b/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/bo/ImAgentBo.java @@ -75,4 +75,10 @@ public class ImAgentBo { * 移动端悬浮球图片 */ private String mobileFloatBall; + + /** + * 默认客服id + */ + private Long defaultKefuId; + } diff --git a/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/vo/ImAgentVo.java b/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/vo/ImAgentVo.java index a61700d..1626e6d 100644 --- a/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/vo/ImAgentVo.java +++ b/im-admin/ruoyi-im/src/main/java/org/dromara/im/domain/vo/ImAgentVo.java @@ -87,4 +87,10 @@ public class ImAgentVo implements Serializable { */ private String mobileFloatBall; + /** + * 默认客服 + */ + private Long defaultKefuId; + + } diff --git a/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImAgentService.java b/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImAgentService.java index 2049e0d..b9702ba 100644 --- a/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImAgentService.java +++ b/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/IImAgentService.java @@ -100,4 +100,15 @@ public interface IImAgentService { * 更新悬浮球图片配置 */ void updateFloatBall(ImAgentBo bo); + + /** + * 获取默认客服ID + */ + Long getDefaultKefuId(); + + /** + * 保存默认客服ID + */ + void saveDefaultKefuId(Long kefuId); + } diff --git a/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImAgentServiceImpl.java b/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImAgentServiceImpl.java index 97a4aac..91c834e 100644 --- a/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImAgentServiceImpl.java +++ b/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImAgentServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -257,4 +258,36 @@ public class ImAgentServiceImpl implements IImAgentService { agent.setMobileFloatBall(bo.getMobileFloatBall()); baseMapper.updateById(agent); } + + @Override + public Long getDefaultKefuId() { + Long userId = LoginHelper.getUserId(); + if (userId == null || LoginHelper.isSuperAdmin()) { + return null; + } + ImAgent agent = baseMapper.selectOne( + new LambdaQueryWrapper().eq(ImAgent::getSysId, userId) + ); + return agent != null ? agent.getDefaultKefuId() : null; + } + + @Override + public void saveDefaultKefuId(Long kefuId) { + Long userId = LoginHelper.getUserId(); + if (userId == null || LoginHelper.isSuperAdmin()) { + throw new RuntimeException("无权限操作"); + } + ImAgent agent = baseMapper.selectOne( + new LambdaQueryWrapper().eq(ImAgent::getSysId, userId) + ); + if (agent == null) { + throw new RuntimeException("代理不存在"); + } + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); + wrapper.eq(ImAgent::getId, agent.getId()); + wrapper.set(ImAgent::getDefaultKefuId, kefuId); + baseMapper.update(null, wrapper); + } + + }