Browse Source

修复指定客服功能

master
[yxf] 5 days ago
parent
commit
408c9ed6e3
  1. 2
      im-admin-ui/src/api/im/agent/index.ts
  2. 74
      im-admin-ui/src/views/im/code/index.vue
  3. 1
      im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImAgentController.java
  4. 8
      im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImAgentServiceImpl.java

2
im-admin-ui/src/api/im/agent/index.ts

@ -48,6 +48,6 @@ export function saveDefaultCustomer(kefuId: number | null): AxiosPromise<any> {
return request({ return request({
url: '/im/agent/saveDefaultCustomer', url: '/im/agent/saveDefaultCustomer',
method: 'post', method: 'post',
data: { defaultCustomerId: kefuId } data: { defaultKefuId: kefuId }
}); });
} }

74
im-admin-ui/src/views/im/code/index.vue

@ -5,41 +5,47 @@
<!-- 客服选择 --> <!-- 客服选择 -->
<div class="kefu-selector"> <div class="kefu-selector">
<span class="kefu-label">指定客服</span> <span class="kefu-label">指定客服</span>
<el-select <el-select v-model="selectedKefuId" placeholder="不指定(系统自动分配)" size="small" style="width: 240px" @change="onKefuChange">
v-model="selectedKefuId" <el-option v-for="item in kefuList" :key="item.id" :label="item.nickName" :value="item.id">
placeholder="不指定(系统自动分配)" <div style="display: flex; align-items: center; gap: 8px">
clearable
size="small"
style="width: 240px;"
@change="onKefuChange"
>
<el-option
v-for="item in kefuList"
:key="item.id"
:label="item.nickName"
:value="item.id"
>
<div style="display: flex; align-items: center; gap: 8px;">
<el-avatar :src="item.headImageThumb" :size="24" v-if="item.headImageThumb" /> <el-avatar :src="item.headImageThumb" :size="24" v-if="item.headImageThumb" />
<span>{{ item.nickName }}</span> <span>{{ item.nickName }}</span>
</div> </div>
</el-option> </el-option>
</el-select> </el-select>
<el-button
v-if="selectedKefuId !== ''"
size="small"
type="danger"
plain
@click="onClearKefu"
style="margin-left: 8px;"
>
清除
</el-button>
</div> </div>
<!-- 使用悬浮球设置组件 --> <!-- 使用悬浮球设置组件 -->
<FloatBallSetting <FloatBallSetting
ref="floatBallSettingRef" ref="floatBallSettingRef"
:token="uniqueToken" :token="uniqueToken"
@save="handleFloatBallConfigSaved" @save="handleFloatBallConfigSaved"
@update:config="handleFloatBallConfigUpdate" @update:config="handleFloatBallConfigUpdate"
/> />
<el-collapse v-model="activeName" accordion> <el-collapse v-model="activeName" accordion>
<el-collapse-item title="超链接" name="1"> <el-collapse-item title="超链接" name="1">
<alink :tokeninfo="token" :site-url="siteUrl" :unique-token="uniqueToken" @cget-copy="getCopy"></alink> <alink :tokeninfo="token" :site-url="siteUrl" :unique-token="uniqueToken" @cget-copy="getCopy"></alink>
</el-collapse-item> </el-collapse-item>
<el-collapse-item title="网页内嵌" name="2"> <el-collapse-item title="网页内嵌" name="2">
<wangye :tokeninfo="token" :site-url="siteUrl" :unique-token="uniqueToken" :kefu-id="selectedKefuId" :float-config="floatBallConfig" @cget-copy="getCopy"></wangye> <wangye
:tokeninfo="token"
:site-url="siteUrl"
:unique-token="uniqueToken"
:kefu-id="selectedKefuId"
:float-config="floatBallConfig"
@cget-copy="getCopy"
></wangye>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
</el-card> </el-card>
@ -52,6 +58,8 @@ import { ref, computed, onMounted, getCurrentInstance } from 'vue';
// import { useStore } from 'vuex'; // import { useStore } from 'vuex';
// import { adminAppCustomer, appReset } from '@/api/kefu'; // import { adminAppCustomer, appReset } from '@/api/kefu';
import alink from './components/alink.vue'; import alink from './components/alink.vue';
import { ElMessage } from 'element-plus';
import wangye from './components/wangye.vue'; import wangye from './components/wangye.vue';
import FloatBallSetting from './components/FloatBallSetting.vue'; import FloatBallSetting from './components/FloatBallSetting.vue';
import { listUser, listAllCustomer } from '@/api/im/user/customer'; import { listUser, listAllCustomer } from '@/api/im/user/customer';
@ -74,7 +82,7 @@ const { proxy } = getCurrentInstance() as any;
// 👇 // 👇
const floatBallConfig = ref<FloatBallConfig>({ const floatBallConfig = ref<FloatBallConfig>({
pcImage: '', pcImage: '',
mobileImage: '', mobileImage: ''
}); });
const token = ref<any>(''); const token = ref<any>('');
const canfrime = ref(false); const canfrime = ref(false);
@ -85,7 +93,7 @@ const canCustomerServer = ref('');
const selectedKefuId = ref<number | ''>(''); const selectedKefuId = ref<number | ''>('');
const kefuList = ref<any[]>([]); const kefuList = ref<any[]>([]);
const kefuSaving = ref(false);
const linkUrl = computed(() => `${location.origin}/chat/index?token=${token.value?.token_md5}&noCanClose=1`); const linkUrl = computed(() => `${location.origin}/chat/index?token=${token.value?.token_md5}&noCanClose=1`);
onMounted(() => { onMounted(() => {
// uniqueToken // uniqueToken
@ -132,7 +140,6 @@ async function loadKefuList() {
} }
} }
// ID // ID
async function loadDefaultKefu() { async function loadDefaultKefu() {
try { try {
@ -145,13 +152,30 @@ async function loadDefaultKefu() {
} }
} }
async function onKefuChange(val: number | '') { async function onKefuChange(val: number | '') {
if (kefuSaving.value) return;
kefuSaving.value = true;
try { try {
await saveDefaultCustomer(val || null); await saveDefaultCustomer(val || null);
proxy?.$Message?.success('已保存'); ElMessage.success('已保存');
} catch (e) { } catch (e) {
console.error('保存默认客服失败', e); console.error('保存默认客服失败', e);
} finally {
kefuSaving.value = false;
}
}
async function onClearKefu() {
if (kefuSaving.value) return;
selectedKefuId.value = '';
kefuSaving.value = true;
try {
await saveDefaultCustomer(null);
ElMessage.success('已清除');
} catch (e) {
console.error('清除默认客服失败', e);
} finally {
kefuSaving.value = false;
} }
} }
@ -167,7 +191,7 @@ function handleFloatBallConfigSaved(config: FloatBallConfig) {
floatBallConfig.value = config; floatBallConfig.value = config;
// //
console.log('悬浮球配置已保存:', config); console.log('悬浮球配置已保存:', config);
// API // API
// saveFloatBallConfigToServer(config); // saveFloatBallConfigToServer(config);
} }
@ -364,4 +388,4 @@ function copyToClipboard(elem: HTMLElement) {
height: 40px !important; height: 40px !important;
margin-right: 30px; margin-right: 30px;
} }
</style> </style>

1
im-admin/ruoyi-im/src/main/java/org/dromara/im/controller/ImAgentController.java

@ -151,7 +151,6 @@ public class ImAgentController extends BaseController {
/** /**
* 保存默认客服ID * 保存默认客服ID
*/ */
@RepeatSubmit()
@PostMapping("/saveDefaultCustomer") @PostMapping("/saveDefaultCustomer")
public R<Void> saveDefaultCustomer(@RequestBody ImAgentBo bo) { public R<Void> saveDefaultCustomer(@RequestBody ImAgentBo bo) {
imAgentService.saveDefaultCustomerId(bo.getDefaultKefuId()); imAgentService.saveDefaultCustomerId(bo.getDefaultKefuId());

8
im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImAgentServiceImpl.java

@ -283,11 +283,11 @@ public class ImAgentServiceImpl implements IImAgentService {
if (agent == null) { if (agent == null) {
throw new RuntimeException("代理不存在"); throw new RuntimeException("代理不存在");
} }
LambdaUpdateWrapper<ImAgent> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(ImAgent::getId, agent.getId()); agent.setDefaultKefuId(customerId);
wrapper.set(ImAgent::getDefaultKefuId, customerId); baseMapper.updateById(agent);
baseMapper.update(null, wrapper);
} }
} }

Loading…
Cancel
Save