13 changed files with 1140 additions and 0 deletions
@ -0,0 +1,63 @@ |
|||||
|
import request from '@/utils/request'; |
||||
|
import { AxiosPromise } from 'axios'; |
||||
|
import { SettingVO, SettingForm, SettingQuery } from '@/api/im/setting/types'; |
||||
|
|
||||
|
/** |
||||
|
* 查询配置列表 |
||||
|
* @param query |
||||
|
* @returns {*} |
||||
|
*/ |
||||
|
|
||||
|
export const listSetting = (query?: SettingQuery): AxiosPromise<SettingVO[]> => { |
||||
|
return request({ |
||||
|
url: '/im/setting/list', |
||||
|
method: 'get', |
||||
|
params: query |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 查询配置详细 |
||||
|
* @param id |
||||
|
*/ |
||||
|
export const getSetting = (id: string | number): AxiosPromise<SettingVO> => { |
||||
|
return request({ |
||||
|
url: '/im/setting/' + id, |
||||
|
method: 'get' |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 新增配置 |
||||
|
* @param data |
||||
|
*/ |
||||
|
export const addSetting = (data: SettingForm) => { |
||||
|
return request({ |
||||
|
url: '/im/setting', |
||||
|
method: 'post', |
||||
|
data: data |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 修改配置 |
||||
|
* @param data |
||||
|
*/ |
||||
|
export const updateSetting = (data: any) => { |
||||
|
return request({ |
||||
|
url: '/im/setting/editSetting', |
||||
|
method: 'post', |
||||
|
data: data |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 删除配置 |
||||
|
* @param id |
||||
|
*/ |
||||
|
export const delSetting = (id: string | number | Array<string | number>) => { |
||||
|
return request({ |
||||
|
url: '/im/setting/' + id, |
||||
|
method: 'delete' |
||||
|
}); |
||||
|
}; |
||||
@ -0,0 +1,121 @@ |
|||||
|
export interface SettingVO { |
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
id: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 唯一token |
||||
|
*/ |
||||
|
uniqueToken: string; |
||||
|
|
||||
|
/** |
||||
|
* 配置名称 |
||||
|
*/ |
||||
|
settingName: string; |
||||
|
|
||||
|
/** |
||||
|
* 配置内容 |
||||
|
*/ |
||||
|
settingValue: string; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
remark: string; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
createdTime: string; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
updatedTime: string; |
||||
|
|
||||
|
/** |
||||
|
* 创建者ID |
||||
|
*/ |
||||
|
creatorId: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 更新者ID |
||||
|
*/ |
||||
|
updaterId: string | number; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface SettingForm extends BaseEntity { |
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
id?: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 唯一token |
||||
|
*/ |
||||
|
uniqueToken?: string; |
||||
|
|
||||
|
/** |
||||
|
* 配置名称 |
||||
|
*/ |
||||
|
settingName?: string; |
||||
|
|
||||
|
/** |
||||
|
* 配置内容 |
||||
|
*/ |
||||
|
settingValue?: string; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
remark?: string; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
createdTime?: string; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
updatedTime?: string; |
||||
|
|
||||
|
/** |
||||
|
* 创建者ID |
||||
|
*/ |
||||
|
creatorId?: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 更新者ID |
||||
|
*/ |
||||
|
updaterId?: string | number; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface SettingQuery extends PageQuery { |
||||
|
|
||||
|
/** |
||||
|
* 唯一token |
||||
|
*/ |
||||
|
uniqueToken?: string; |
||||
|
|
||||
|
/** |
||||
|
* 配置名称 |
||||
|
*/ |
||||
|
settingName?: string; |
||||
|
|
||||
|
/** |
||||
|
* 配置内容 |
||||
|
*/ |
||||
|
settingValue?: string; |
||||
|
|
||||
|
/** |
||||
|
* 日期范围参数 |
||||
|
*/ |
||||
|
params?: any; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
@ -0,0 +1,189 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<!-- <el-card class="box-card"> --> |
||||
|
<el-tabs v-model="activeTab" type="border-card"> |
||||
|
<el-tab-pane label="翻译配置" name="translation" lazy> |
||||
|
<el-form |
||||
|
ref="translationFormRef" |
||||
|
:model="translationSettingData" |
||||
|
:rules="translationRules" |
||||
|
label-width="120px" |
||||
|
style="max-width: 600px; margin-top: 20px" |
||||
|
> |
||||
|
<el-form-item label="翻译类型" prop="type"> |
||||
|
<el-select v-model="translationSettingData.type" placeholder="请选择翻译类型"> |
||||
|
<el-option label="默认配置" value="0"></el-option> |
||||
|
<el-option label="百度翻译" value="1"></el-option> |
||||
|
<!-- <el-option label="Google翻译" value="2"></el-option> --> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-if="translationSettingData.type === '1'" label="APP ID" prop="appId"> |
||||
|
<el-input v-model="translationSettingData.appId" placeholder="请输入APP ID"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-if="translationSettingData.type === '1'" label="密钥" prop="secretKey"> |
||||
|
<el-input v-model="translationSettingData.secretKey" :rows="4" placeholder="请输入密钥"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="submitTranslationForm">提交</el-button> |
||||
|
<el-button @click="resetTranslationForm">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</el-tab-pane> |
||||
|
|
||||
|
<!-- <el-tab-pane label="平台配置" name="platform" lazy> |
||||
|
<el-form |
||||
|
ref="platformFormRef" |
||||
|
:model="platformSettingData" |
||||
|
:rules="platformRules" |
||||
|
label-width="120px" |
||||
|
style="max-width: 600px; margin-top: 20px" |
||||
|
> |
||||
|
<el-form-item label="平台名称" prop="name"> |
||||
|
<el-input v-model="platformSettingData.name" placeholder="请输入平台名称"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="平台域名" prop="domain"> |
||||
|
<el-input v-model="platformSettingData.domain" placeholder="请输入平台域名"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="submitPlatformForm">提交</el-button> |
||||
|
<el-button @click="resetPlatformForm">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</el-tab-pane> --> |
||||
|
</el-tabs> |
||||
|
<!-- </el-card> --> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup name="Setting" lang="ts"> |
||||
|
import { listSetting, updateSetting } from '@/api/im/setting'; |
||||
|
import { getCurrentInstance, ref, onMounted, ComponentInternalInstance } from 'vue'; |
||||
|
import { ElMessage, ElMessageBox } from 'element-plus'; |
||||
|
|
||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
||||
|
|
||||
|
const buttonLoading = ref(false); |
||||
|
const loading = ref(true); |
||||
|
const activeTab = ref('translation'); |
||||
|
|
||||
|
const translationSettingData = ref({ |
||||
|
type: '', |
||||
|
appId: '', |
||||
|
secretKey: '' |
||||
|
}); |
||||
|
|
||||
|
const platformSettingData = ref({ |
||||
|
name: '', |
||||
|
domain: '' |
||||
|
}); |
||||
|
|
||||
|
// 翻译配置验证规则 |
||||
|
const translationRules = { |
||||
|
type: [{ required: true, message: '请选择翻译类型', trigger: 'change' }], |
||||
|
appId: [ |
||||
|
{ required: true, message: '请输入APP ID', trigger: 'blur' }, |
||||
|
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' } |
||||
|
], |
||||
|
secretKey: [ |
||||
|
{ required: true, message: '请输入密钥', trigger: 'blur' }, |
||||
|
{ min: 1, max: 200, message: '长度在 1 到 200 个字符', trigger: 'blur' } |
||||
|
] |
||||
|
}; |
||||
|
|
||||
|
// 平台配置验证规则 |
||||
|
const platformRules = { |
||||
|
name: [ |
||||
|
{ required: true, message: '请输入平台名称', trigger: 'blur' }, |
||||
|
{ min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur' } |
||||
|
], |
||||
|
domain: [ |
||||
|
{ required: true, message: '请输入平台域名', trigger: 'blur' }, |
||||
|
{ pattern: /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, message: '请输入正确的域名格式', trigger: 'blur' } |
||||
|
] |
||||
|
}; |
||||
|
|
||||
|
/** 查询配置列表 */ |
||||
|
const getList = async () => { |
||||
|
loading.value = true; |
||||
|
try { |
||||
|
const res = await listSetting(); |
||||
|
//转为json对象 |
||||
|
// 更新翻译配置数据 |
||||
|
if (res.TRANSLATION_SETTING) { |
||||
|
translationSettingData.value = JSON.parse(res.TRANSLATION_SETTING); |
||||
|
} |
||||
|
console.log('成功:', translationSettingData.value); |
||||
|
// 更新平台配置数据 |
||||
|
if (res.PLATFORM_SETTING) { |
||||
|
platformSettingData.value = JSON.parse(res.PLATFORM_SETTING); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
ElMessage.error('获取配置失败'); |
||||
|
} finally { |
||||
|
loading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/** 提交翻译配置表单 */ |
||||
|
const submitTranslationForm = async () => { |
||||
|
const formRef = proxy.$refs.translationFormRef as (typeof import('element-plus'))['ElForm']; |
||||
|
const isValid = await formRef.validate().catch(() => false); |
||||
|
|
||||
|
if (!isValid) return; |
||||
|
|
||||
|
try { |
||||
|
buttonLoading.value = true; |
||||
|
const params = { |
||||
|
settingName: 'TRANSLATION_SETTING', |
||||
|
type: translationSettingData.value.type, |
||||
|
appId: translationSettingData.value.appId, |
||||
|
secretKey: translationSettingData.value.secretKey |
||||
|
}; |
||||
|
await updateSetting(params); |
||||
|
ElMessage.success('翻译配置更新成功'); |
||||
|
} catch (error) { |
||||
|
console.error('更新翻译配置失败:', error); |
||||
|
ElMessage.error('更新翻译配置失败'); |
||||
|
} finally { |
||||
|
buttonLoading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/** 提交平台配置表单 */ |
||||
|
const submitPlatformForm = async () => { |
||||
|
const formRef = proxy.$refs.platformFormRef as (typeof import('element-plus'))['ElForm']; |
||||
|
const isValid = await formRef.validate().catch(() => false); |
||||
|
|
||||
|
if (!isValid) return; |
||||
|
|
||||
|
try { |
||||
|
buttonLoading.value = true; |
||||
|
const params = { |
||||
|
PLATFORM_SETTING: platformSettingData.value |
||||
|
}; |
||||
|
await updateSetting(params); |
||||
|
ElMessage.success('平台配置更新成功'); |
||||
|
} catch (error) { |
||||
|
console.error('更新平台配置失败:', error); |
||||
|
ElMessage.error('更新平台配置失败'); |
||||
|
} finally { |
||||
|
buttonLoading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/** 重置翻译配置表单 */ |
||||
|
const resetTranslationForm = () => { |
||||
|
const formRef = proxy.$refs.translationFormRef as (typeof import('element-plus'))['ElForm']; |
||||
|
formRef.resetFields(); |
||||
|
}; |
||||
|
|
||||
|
/** 重置平台配置表单 */ |
||||
|
const resetPlatformForm = () => { |
||||
|
const formRef = proxy.$refs.platformFormRef as (typeof import('element-plus'))['ElForm']; |
||||
|
formRef.resetFields(); |
||||
|
}; |
||||
|
|
||||
|
onMounted(() => { |
||||
|
getList(); |
||||
|
}); |
||||
|
</script> |
||||
@ -0,0 +1,104 @@ |
|||||
|
package org.dromara.im.controller; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
import cn.hutool.core.util.ObjectUtil; |
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
import jakarta.validation.constraints.*; |
||||
|
import cn.dev33.satoken.annotation.SaCheckPermission; |
||||
|
import org.dromara.common.satoken.utils.LoginHelper; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
import org.springframework.validation.annotation.Validated; |
||||
|
import org.dromara.common.idempotent.annotation.RepeatSubmit; |
||||
|
import org.dromara.common.log.annotation.Log; |
||||
|
import org.dromara.common.web.core.BaseController; |
||||
|
import org.dromara.common.mybatis.core.page.PageQuery; |
||||
|
import org.dromara.common.core.domain.R; |
||||
|
import org.dromara.common.core.validate.AddGroup; |
||||
|
import org.dromara.common.core.validate.EditGroup; |
||||
|
import org.dromara.common.log.enums.BusinessType; |
||||
|
import org.dromara.common.excel.utils.ExcelUtil; |
||||
|
import org.dromara.im.domain.vo.ImSettingVo; |
||||
|
import org.dromara.im.domain.bo.ImSettingBo; |
||||
|
import org.dromara.im.service.IImSettingService; |
||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo; |
||||
|
|
||||
|
/** |
||||
|
* 配置 |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @date 2026-04-23 |
||||
|
*/ |
||||
|
@Validated |
||||
|
@RequiredArgsConstructor |
||||
|
@RestController |
||||
|
@RequestMapping("/im/setting") |
||||
|
public class ImSettingController extends BaseController { |
||||
|
|
||||
|
private final IImSettingService imSettingService; |
||||
|
|
||||
|
/** |
||||
|
* 查询配置列表 |
||||
|
*/ |
||||
|
@SaCheckPermission("im:setting:list") |
||||
|
@GetMapping("/list") |
||||
|
public JSONObject list() { |
||||
|
return imSettingService.getAllSetting(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取配置详细信息 |
||||
|
* |
||||
|
* @param id 主键 |
||||
|
*/ |
||||
|
@SaCheckPermission("im:setting:query") |
||||
|
//@GetMapping("/{id}")
|
||||
|
public R<ImSettingVo> getInfo(@NotNull(message = "主键不能为空") |
||||
|
@PathVariable Long id) { |
||||
|
return R.ok(imSettingService.queryById(id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增配置 |
||||
|
*/ |
||||
|
@SaCheckPermission("im:setting:add") |
||||
|
@Log(title = "配置", businessType = BusinessType.INSERT) |
||||
|
//@RepeatSubmit()
|
||||
|
//@PostMapping()
|
||||
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody ImSettingBo bo) { |
||||
|
return toAjax(imSettingService.insertByBo(bo)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改配置 |
||||
|
*/ |
||||
|
@SaCheckPermission("im:setting:edit") |
||||
|
@Log(title = "修改配置", businessType = BusinessType.UPDATE) |
||||
|
@RepeatSubmit() |
||||
|
@PostMapping("/editSetting") |
||||
|
public R<Void> edit(@RequestBody JSONObject update) { |
||||
|
String settingName = update.getStr("settingName"); |
||||
|
|
||||
|
if((ObjectUtil.isEmpty(settingName)) || LoginHelper.isSuperAdmin()){ |
||||
|
return R.fail(); |
||||
|
} |
||||
|
|
||||
|
return toAjax(imSettingService.updateBySettingName(settingName,update)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除配置 |
||||
|
* |
||||
|
* @param ids 主键串 |
||||
|
*/ |
||||
|
@SaCheckPermission("im:setting:remove") |
||||
|
@Log(title = "配置", businessType = BusinessType.DELETE) |
||||
|
//@DeleteMapping("/{ids}")
|
||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
||||
|
@PathVariable Long[] ids) { |
||||
|
return toAjax(imSettingService.deleteWithValidByIds(List.of(ids), true)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
package org.dromara.im.domain; |
||||
|
|
||||
|
import com.fhs.core.trans.vo.TransPojo; |
||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity; |
||||
|
import com.baomidou.mybatisplus.annotation.*; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import java.util.Date; |
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
|
||||
|
import java.io.Serial; |
||||
|
|
||||
|
/** |
||||
|
* 配置对象 im_setting |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @date 2026-04-23 |
||||
|
*/ |
||||
|
@Data |
||||
|
@TableName("im_setting") |
||||
|
public class ImSetting implements TransPojo { |
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@TableId(value = "id") |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 唯一token |
||||
|
*/ |
||||
|
private String uniqueToken; |
||||
|
|
||||
|
/** |
||||
|
* 配置名称 |
||||
|
*/ |
||||
|
private String settingName; |
||||
|
|
||||
|
/** |
||||
|
* 配置内容 |
||||
|
*/ |
||||
|
private String settingValue; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
private String remark; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
private Date createdTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
private Date updatedTime; |
||||
|
|
||||
|
/** |
||||
|
* 创建者ID |
||||
|
*/ |
||||
|
private Long creatorId; |
||||
|
|
||||
|
/** |
||||
|
* 更新者ID |
||||
|
*/ |
||||
|
private Long updaterId; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
package org.dromara.im.domain.bo; |
||||
|
|
||||
|
import org.dromara.im.domain.ImSetting; |
||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity; |
||||
|
import org.dromara.common.core.validate.AddGroup; |
||||
|
import org.dromara.common.core.validate.EditGroup; |
||||
|
import io.github.linpeilie.annotations.AutoMapper; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import jakarta.validation.constraints.*; |
||||
|
import java.util.Date; |
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
|
||||
|
/** |
||||
|
* 配置业务对象 im_setting |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @date 2026-04-23 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@AutoMapper(target = ImSetting.class, reverseConvertGenerate = false) |
||||
|
public class ImSettingBo extends BaseEntity { |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 唯一token |
||||
|
*/ |
||||
|
@NotBlank(message = "唯一token不能为空", groups = { AddGroup.class, EditGroup.class }) |
||||
|
private String uniqueToken; |
||||
|
|
||||
|
/** |
||||
|
* 配置名称 |
||||
|
*/ |
||||
|
@NotBlank(message = "配置名称不能为空", groups = { AddGroup.class, EditGroup.class }) |
||||
|
private String settingName; |
||||
|
|
||||
|
/** |
||||
|
* 配置内容 |
||||
|
*/ |
||||
|
@NotBlank(message = "配置内容不能为空", groups = { AddGroup.class, EditGroup.class }) |
||||
|
private String settingValue; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
private String remark; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
private Date createdTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
private Date updatedTime; |
||||
|
|
||||
|
/** |
||||
|
* 创建者ID |
||||
|
*/ |
||||
|
private Long creatorId; |
||||
|
|
||||
|
/** |
||||
|
* 更新者ID |
||||
|
*/ |
||||
|
private Long updaterId; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
package org.dromara.im.domain.setting.domain; |
||||
|
|
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
public class TranslationSetting { |
||||
|
|
||||
|
/** |
||||
|
* 翻译类型 0-默认管理员配置 1-百度翻译 2-谷歌翻译 |
||||
|
*/ |
||||
|
private String type = "0"; |
||||
|
|
||||
|
private String appId = ""; |
||||
|
|
||||
|
private String secretKey = ""; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
package org.dromara.im.domain.vo; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
import org.dromara.im.domain.ImSetting; |
||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
||||
|
import com.alibaba.excel.annotation.ExcelProperty; |
||||
|
import org.dromara.common.excel.annotation.ExcelDictFormat; |
||||
|
import org.dromara.common.excel.convert.ExcelDictConvert; |
||||
|
import io.github.linpeilie.annotations.AutoMapper; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serial; |
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 配置视图对象 im_setting |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @date 2026-04-23 |
||||
|
*/ |
||||
|
@Data |
||||
|
@ExcelIgnoreUnannotated |
||||
|
@AutoMapper(target = ImSetting.class) |
||||
|
public class ImSettingVo implements Serializable { |
||||
|
|
||||
|
@Serial |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "主键ID") |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 唯一token |
||||
|
*/ |
||||
|
@ExcelProperty(value = "唯一token") |
||||
|
private String uniqueToken; |
||||
|
|
||||
|
/** |
||||
|
* 配置名称 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "配置名称") |
||||
|
private String settingName; |
||||
|
|
||||
|
/** |
||||
|
* 配置内容 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "配置内容") |
||||
|
private String settingValue; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "备注") |
||||
|
private String remark; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "创建时间") |
||||
|
private Date createdTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "更新时间") |
||||
|
private Date updatedTime; |
||||
|
|
||||
|
/** |
||||
|
* 创建者ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "创建者ID") |
||||
|
private Long creatorId; |
||||
|
|
||||
|
/** |
||||
|
* 更新者ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "更新者ID") |
||||
|
private Long updaterId; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
package org.dromara.im.enums; |
||||
|
|
||||
|
public enum SettingEnum { |
||||
|
//平台设置
|
||||
|
PLATFORM_SETTING, |
||||
|
//翻译配置
|
||||
|
TRANSLATION_SETTING, |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
package org.dromara.im.mapper; |
||||
|
|
||||
|
import org.dromara.im.domain.ImSetting; |
||||
|
import org.dromara.im.domain.vo.ImSettingVo; |
||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
||||
|
|
||||
|
/** |
||||
|
* 配置Mapper接口 |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @date 2026-04-23 |
||||
|
*/ |
||||
|
public interface ImSettingMapper extends BaseMapperPlus<ImSetting, ImSettingVo> { |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,91 @@ |
|||||
|
package org.dromara.im.service; |
||||
|
|
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import org.dromara.im.domain.ImSetting; |
||||
|
import org.dromara.im.domain.vo.ImSettingVo; |
||||
|
import org.dromara.im.domain.bo.ImSettingBo; |
||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo; |
||||
|
import org.dromara.common.mybatis.core.page.PageQuery; |
||||
|
|
||||
|
import java.util.Collection; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 配置Service接口 |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @date 2026-04-23 |
||||
|
*/ |
||||
|
public interface IImSettingService { |
||||
|
|
||||
|
/** |
||||
|
* 查询配置 |
||||
|
* |
||||
|
* @param id 主键 |
||||
|
* @return 配置 |
||||
|
*/ |
||||
|
ImSettingVo queryById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 分页查询配置列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @param pageQuery 分页参数 |
||||
|
* @return 配置分页列表 |
||||
|
*/ |
||||
|
TableDataInfo<ImSettingVo> queryPageList(ImSettingBo bo, PageQuery pageQuery); |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的配置列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 配置列表 |
||||
|
*/ |
||||
|
List<ImSettingVo> queryList(ImSettingBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 新增配置 |
||||
|
* |
||||
|
* @param bo 配置 |
||||
|
* @return 是否新增成功 |
||||
|
*/ |
||||
|
Boolean insertByBo(ImSettingBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 修改配置 |
||||
|
* |
||||
|
* @param bo 配置 |
||||
|
* @return 是否修改成功 |
||||
|
*/ |
||||
|
Boolean updateByBo(ImSettingBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 校验并批量删除配置信息 |
||||
|
* |
||||
|
* @param ids 待删除的主键集合 |
||||
|
* @param isValid 是否进行有效性校验 |
||||
|
* @return 是否删除成功 |
||||
|
*/ |
||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
||||
|
|
||||
|
/** |
||||
|
* 获取当前用户所有配置 |
||||
|
* @return 配置对象 |
||||
|
*/ |
||||
|
JSONObject getAllSetting(); |
||||
|
|
||||
|
/** |
||||
|
* 根据settingName获取配置 |
||||
|
* @param settingName 配置名称 |
||||
|
* @return 配置 |
||||
|
*/ |
||||
|
ImSetting get(String settingName); |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param settingName 配置名称 |
||||
|
* @param value 配置值 |
||||
|
* @return 是否更新成功 |
||||
|
*/ |
||||
|
boolean updateBySettingName(String settingName, JSONObject value); |
||||
|
} |
||||
@ -0,0 +1,290 @@ |
|||||
|
package org.dromara.im.service.impl; |
||||
|
|
||||
|
import cn.hutool.core.date.DateUtil; |
||||
|
import cn.hutool.core.util.ObjectUtil; |
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import cn.hutool.json.JSONUtil; |
||||
|
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; |
||||
|
import org.dromara.common.mybatis.core.page.PageQuery; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import org.dromara.common.satoken.utils.LoginHelper; |
||||
|
import org.dromara.im.constant.ImConstant; |
||||
|
import org.dromara.im.domain.ImSetting; |
||||
|
import org.dromara.im.domain.setting.domain.TranslationSetting; |
||||
|
import org.dromara.im.enums.SettingEnum; |
||||
|
import org.dromara.im.service.IImAgentService; |
||||
|
import org.dromara.im.util.LambdaQueryWrapperHelper; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.dromara.im.domain.bo.ImSettingBo; |
||||
|
import org.dromara.im.domain.vo.ImSettingVo; |
||||
|
import org.dromara.im.domain.ImSetting; |
||||
|
import org.dromara.im.mapper.ImSettingMapper; |
||||
|
import org.dromara.im.service.IImSettingService; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Collection; |
||||
|
|
||||
|
/** |
||||
|
* 配置Service业务层处理 |
||||
|
* |
||||
|
* @author Blue |
||||
|
* @date 2026-04-23 |
||||
|
*/ |
||||
|
@RequiredArgsConstructor |
||||
|
@Service |
||||
|
@DS(ImConstant.DS_IM_PLATFORM) |
||||
|
public class ImSettingServiceImpl implements IImSettingService { |
||||
|
|
||||
|
private final ImSettingMapper baseMapper; |
||||
|
|
||||
|
private final IImAgentService imAgentService; |
||||
|
|
||||
|
/** |
||||
|
* 查询配置 |
||||
|
* |
||||
|
* @param id 主键 |
||||
|
* @return 配置 |
||||
|
*/ |
||||
|
@Override |
||||
|
public ImSettingVo queryById(Long id){ |
||||
|
LambdaQueryWrapper<ImSetting> lqw = Wrappers.lambdaQuery(); |
||||
|
lqw.eq(ImSetting::getId, id); |
||||
|
|
||||
|
if(!LoginHelper.isSuperAdmin()) { |
||||
|
LambdaQueryWrapperHelper.appendToken(lqw, ImSetting::getUniqueToken); |
||||
|
} |
||||
|
|
||||
|
return baseMapper.selectVoOne(lqw); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 分页查询配置列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @param pageQuery 分页参数 |
||||
|
* @return 配置分页列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
public TableDataInfo<ImSettingVo> queryPageList(ImSettingBo bo, PageQuery pageQuery) { |
||||
|
LambdaQueryWrapper<ImSetting> lqw = buildQueryWrapper(bo); |
||||
|
Page<ImSettingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
||||
|
return TableDataInfo.build(result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的配置列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 配置列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<ImSettingVo> queryList(ImSettingBo bo) { |
||||
|
LambdaQueryWrapper<ImSetting> lqw = buildQueryWrapper(bo); |
||||
|
return baseMapper.selectVoList(lqw); |
||||
|
} |
||||
|
|
||||
|
private LambdaQueryWrapper<ImSetting> buildQueryWrapper(ImSettingBo bo) { |
||||
|
Map<String, Object> params = bo.getParams(); |
||||
|
LambdaQueryWrapper<ImSetting> lqw = Wrappers.lambdaQuery(); |
||||
|
lqw.eq(StringUtils.isNotBlank(bo.getUniqueToken()), ImSetting::getUniqueToken, bo.getUniqueToken()); |
||||
|
lqw.like(StringUtils.isNotBlank(bo.getSettingName()), ImSetting::getSettingName, bo.getSettingName()); |
||||
|
lqw.eq(StringUtils.isNotBlank(bo.getSettingValue()), ImSetting::getSettingValue, bo.getSettingValue()); |
||||
|
|
||||
|
if(!LoginHelper.isSuperAdmin()) { |
||||
|
LambdaQueryWrapperHelper.appendToken(lqw, ImSetting::getUniqueToken); |
||||
|
} |
||||
|
|
||||
|
return lqw; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增配置 |
||||
|
* |
||||
|
* @param bo 配置 |
||||
|
* @return 是否新增成功 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean insertByBo(ImSettingBo bo) { |
||||
|
ImSetting add = MapstructUtils.convert(bo, ImSetting.class); |
||||
|
|
||||
|
if (add == null) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
add.setCreatorId(LoginHelper.getUserId()); |
||||
|
add.setCreatedTime(DateUtil.date()); |
||||
|
add.setUpdaterId(LoginHelper.getUserId()); |
||||
|
add.setUpdatedTime(DateUtil.date()); |
||||
|
|
||||
|
// 如果不是超级管理员,则设置 uniqueToken
|
||||
|
if(!LoginHelper.isSuperAdmin()) { |
||||
|
add.setUniqueToken(imAgentService.getTokenByUserId()); |
||||
|
} |
||||
|
|
||||
|
validEntityBeforeSave(add); |
||||
|
boolean flag = baseMapper.insert(add) > 0; |
||||
|
if (flag) { |
||||
|
bo.setId(add.getId()); |
||||
|
} |
||||
|
return flag; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改配置 |
||||
|
* |
||||
|
* @param bo 配置 |
||||
|
* @return 是否修改成功 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean updateByBo(ImSettingBo bo) { |
||||
|
ImSetting update = MapstructUtils.convert(bo, ImSetting.class); |
||||
|
if (update == null) { |
||||
|
return false; |
||||
|
} |
||||
|
validEntityBeforeSave(update); |
||||
|
|
||||
|
LambdaUpdateWrapper<ImSetting> updateWrapper = new LambdaUpdateWrapper<>(); |
||||
|
updateWrapper.eq(ImSetting::getId, update.getId()); |
||||
|
|
||||
|
if(!LoginHelper.isSuperAdmin()) { |
||||
|
// 使用当前用户的 token 而不是从 bo 中获取,防止篡改
|
||||
|
updateWrapper.eq(ImSetting::getUniqueToken, imAgentService.getTokenByUserId()); |
||||
|
} |
||||
|
|
||||
|
updateWrapper.set(ImSetting::getSettingName, update.getSettingName()); |
||||
|
updateWrapper.set(ImSetting::getSettingValue, update.getSettingValue()); |
||||
|
updateWrapper.set(ImSetting::getRemark, update.getRemark()); |
||||
|
|
||||
|
updateWrapper.set(ImSetting::getUpdaterId, LoginHelper.getUserId()); |
||||
|
updateWrapper.set(ImSetting::getUpdatedTime, DateUtil.date()); |
||||
|
|
||||
|
return baseMapper.update(null, updateWrapper) > 0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存前的数据校验 |
||||
|
*/ |
||||
|
private void validEntityBeforeSave(ImSetting entity){ |
||||
|
//TODO 做一些数据校验,如唯一约束
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 校验并批量删除配置信息 |
||||
|
* |
||||
|
* @param ids 待删除的主键集合 |
||||
|
* @param isValid 是否进行有效性校验 |
||||
|
* @return 是否删除成功 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
||||
|
if(isValid){ |
||||
|
if (ids == null || ids.isEmpty()) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
LambdaUpdateWrapper<ImSetting> updateWrapper = new LambdaUpdateWrapper<>(); |
||||
|
updateWrapper.in(ImSetting::getId, ids); |
||||
|
|
||||
|
if(!LoginHelper.isSuperAdmin()) { |
||||
|
// 添加 uniqueToken 条件,确保只能删除当前用户的记录
|
||||
|
updateWrapper.eq(ImSetting::getUniqueToken, imAgentService.getTokenByUserId()); |
||||
|
} |
||||
|
|
||||
|
return baseMapper.delete(updateWrapper) > 0; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public JSONObject getAllSetting() { |
||||
|
//超级管理员无配置
|
||||
|
if(LoginHelper.isSuperAdmin()){ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
//获取翻译配置
|
||||
|
ImSetting translationSetting = get(SettingEnum.TRANSLATION_SETTING.name()); |
||||
|
if(translationSetting == null){//不存在则初始化
|
||||
|
createTranslationSetting(); |
||||
|
translationSetting = get(SettingEnum.TRANSLATION_SETTING.name()); |
||||
|
} |
||||
|
|
||||
|
JSONObject jsonObject = new JSONObject(); |
||||
|
jsonObject.set(SettingEnum.TRANSLATION_SETTING.name(), translationSetting.getSettingValue()); |
||||
|
|
||||
|
return jsonObject; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ImSetting get(String key) { |
||||
|
//超级管理员无配置
|
||||
|
if(LoginHelper.isSuperAdmin()){ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
LambdaQueryWrapper<ImSetting> lqw = Wrappers.lambdaQuery(); |
||||
|
|
||||
|
lqw.eq(ImSetting::getSettingName, key); |
||||
|
lqw.eq(ImSetting::getUniqueToken, imAgentService.getTokenByUserId()); |
||||
|
return baseMapper.selectOne(lqw); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//初始化翻译配置
|
||||
|
void createTranslationSetting() { |
||||
|
ImSetting newTranslationSetting = new ImSetting(); |
||||
|
newTranslationSetting.setSettingName(SettingEnum.TRANSLATION_SETTING.name()); |
||||
|
newTranslationSetting.setSettingValue(JSONUtil.toJsonStr(new TranslationSetting())); |
||||
|
newTranslationSetting.setUniqueToken(imAgentService.getTokenByUserId()); |
||||
|
newTranslationSetting.setCreatedTime(DateUtil.date()); |
||||
|
newTranslationSetting.setCreatorId(LoginHelper.getUserId()); |
||||
|
newTranslationSetting.setUpdatedTime(DateUtil.date()); |
||||
|
newTranslationSetting.setUpdaterId(LoginHelper.getUserId()); |
||||
|
baseMapper.insert(newTranslationSetting); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean updateBySettingName(String settingName, JSONObject value) { |
||||
|
switch (SettingEnum.valueOf(settingName)) { |
||||
|
case TRANSLATION_SETTING: |
||||
|
return updateTranslationSetting(value); |
||||
|
default: |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
boolean updateTranslationSetting(JSONObject value) { |
||||
|
//获取翻译配置
|
||||
|
ImSetting translationSetting = get(SettingEnum.TRANSLATION_SETTING.name()); |
||||
|
if(translationSetting == null){ |
||||
|
return false; |
||||
|
} |
||||
|
TranslationSetting origin = JSONUtil.toBean(translationSetting.getSettingValue(), TranslationSetting.class); |
||||
|
|
||||
|
String type = value.getStr("type"); |
||||
|
|
||||
|
if(type.equals("0")){//不使用翻译配置
|
||||
|
origin.setType("0"); |
||||
|
} else if (type.equals("1")) {//使用百度翻译
|
||||
|
if(ObjectUtil.isEmpty(value.getStr("appId")) || ObjectUtil.isEmpty(value.getStr("secretKey"))){ |
||||
|
return false; |
||||
|
} |
||||
|
origin.setType("1"); |
||||
|
origin.setAppId(value.getStr("appId")); |
||||
|
origin.setSecretKey(value.getStr("secretKey")); |
||||
|
}else{//其余情况 异常
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
translationSetting.setSettingValue((JSONUtil.toJsonStr(origin))); |
||||
|
return baseMapper.updateById(translationSetting) > 0; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<!DOCTYPE mapper |
||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="org.dromara.im.mapper.ImSettingMapper"> |
||||
|
|
||||
|
</mapper> |
||||
Loading…
Reference in new issue