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