diff --git a/admin/src/api/config.ts b/admin/src/api/config.ts
index 0c09497..c7abbd1 100644
--- a/admin/src/api/config.ts
+++ b/admin/src/api/config.ts
@@ -192,9 +192,13 @@ export interface NotificationTemplatesConfig {
token?: string
encodingAESKey?: string
unlockTemplateId?: string
+ unlockFieldMapping?: string
favoriteTemplateId?: string
+ favoriteFieldMapping?: string
messageTemplateId?: string
+ messageFieldMapping?: string
dailyRecommendTemplateId?: string
+ dailyRecommendFieldMapping?: string
}
/**
diff --git a/admin/src/views/system/config.vue b/admin/src/views/system/config.vue
index b7abdfe..663b2db 100644
--- a/admin/src/views/system/config.vue
+++ b/admin/src/views/system/config.vue
@@ -340,6 +340,15 @@
有用户解锁我时,服务号发送相应通知
+
+
+ JSON格式,key为模板字段名,value为数据类型:title=标题, name=名称, content=内容, time=时间, remark=备注
+
+
有用户收藏我时,服务号发送相应通知
+
+
+ JSON格式,key为模板字段名,value为数据类型:title=标题, name=名称, content=内容, time=时间, remark=备注
+
+
首次沟通通知、5分钟未回复提醒共用此模板
+
+
+ JSON格式,key为模板字段名,value为数据类型:title=标题, name=名称, content=内容, time=时间, remark=备注
+
+
每天早上8~10点随机时间发送推荐更新通知
+
+
+ JSON格式,key为模板字段名,value为数据类型:title=标题, name=名称, content=内容, time=时间, remark=备注
+
+
保存模板配置
@@ -438,9 +474,13 @@ const templateForm = ref({
token: '',
encodingAESKey: '',
unlockTemplateId: '',
+ unlockFieldMapping: '',
favoriteTemplateId: '',
+ favoriteFieldMapping: '',
messageTemplateId: '',
- dailyRecommendTemplateId: ''
+ messageFieldMapping: '',
+ dailyRecommendTemplateId: '',
+ dailyRecommendFieldMapping: ''
})
const saving = ref(false)
@@ -718,9 +758,13 @@ const loadNotificationTemplates = async () => {
templateForm.value.token = res.token || ''
templateForm.value.encodingAESKey = res.encodingAESKey || ''
templateForm.value.unlockTemplateId = res.unlockTemplateId || ''
+ templateForm.value.unlockFieldMapping = res.unlockFieldMapping || ''
templateForm.value.favoriteTemplateId = res.favoriteTemplateId || ''
+ templateForm.value.favoriteFieldMapping = res.favoriteFieldMapping || ''
templateForm.value.messageTemplateId = res.messageTemplateId || ''
+ templateForm.value.messageFieldMapping = res.messageFieldMapping || ''
templateForm.value.dailyRecommendTemplateId = res.dailyRecommendTemplateId || ''
+ templateForm.value.dailyRecommendFieldMapping = res.dailyRecommendFieldMapping || ''
}
} catch (error) {
console.error('加载模板配置失败:', error)
@@ -734,9 +778,13 @@ const saveNotificationTemplates = async () => {
token: templateForm.value.token || undefined,
encodingAESKey: templateForm.value.encodingAESKey || undefined,
unlockTemplateId: templateForm.value.unlockTemplateId || undefined,
+ unlockFieldMapping: templateForm.value.unlockFieldMapping || undefined,
favoriteTemplateId: templateForm.value.favoriteTemplateId || undefined,
+ favoriteFieldMapping: templateForm.value.favoriteFieldMapping || undefined,
messageTemplateId: templateForm.value.messageTemplateId || undefined,
- dailyRecommendTemplateId: templateForm.value.dailyRecommendTemplateId || undefined
+ messageFieldMapping: templateForm.value.messageFieldMapping || undefined,
+ dailyRecommendTemplateId: templateForm.value.dailyRecommendTemplateId || undefined,
+ dailyRecommendFieldMapping: templateForm.value.dailyRecommendFieldMapping || undefined
})
ElMessage.success('模板配置保存成功')
} catch (error) {
diff --git a/server/src/XiangYi.Application/Services/NotificationService.cs b/server/src/XiangYi.Application/Services/NotificationService.cs
index 753487c..31b6135 100644
--- a/server/src/XiangYi.Application/Services/NotificationService.cs
+++ b/server/src/XiangYi.Application/Services/NotificationService.cs
@@ -544,6 +544,43 @@ public class NotificationService : INotificationService
return false;
}
+ // 从数据库读取字段映射
+ var fieldMapping = await GetServiceAccountFieldMappingAsync(templateType);
+ Dictionary data;
+
+ if (fieldMapping != null && fieldMapping.Count > 0)
+ {
+ // 使用后台配置的字段映射动态构建
+ // 映射格式: {"thing1":"title","thing2":"name","time3":"time","thing4":"content","thing5":"remark"}
+ // 值映射: title->标题, name->名称, content->内容, time->时间, remark->备注
+ data = new Dictionary();
+ foreach (var (fieldName, valueKey) in fieldMapping)
+ {
+ var value = valueKey?.ToLower() switch
+ {
+ "title" => title,
+ "name" => name,
+ "content" => content,
+ "time" => time,
+ "remark" => "点击查看详情",
+ _ => valueKey ?? ""
+ };
+ data[fieldName] = new TemplateDataItem { Value = value };
+ }
+ }
+ else
+ {
+ // 兜底:使用传统的 first/keyword 格式
+ data = new Dictionary
+ {
+ ["first"] = new TemplateDataItem { Value = title },
+ ["keyword1"] = new TemplateDataItem { Value = name },
+ ["keyword2"] = new TemplateDataItem { Value = content },
+ ["keyword3"] = new TemplateDataItem { Value = time },
+ ["remark"] = new TemplateDataItem { Value = "点击查看详情" }
+ };
+ }
+
var request = new ServiceAccountTemplateMessageRequest
{
ToUser = serviceAccountOpenId,
@@ -553,14 +590,7 @@ public class NotificationService : INotificationService
AppId = _weChatOptions.MiniProgram.AppId,
PagePath = page
},
- Data = new Dictionary
- {
- ["first"] = new TemplateDataItem { Value = title },
- ["keyword1"] = new TemplateDataItem { Value = name },
- ["keyword2"] = new TemplateDataItem { Value = content },
- ["keyword3"] = new TemplateDataItem { Value = time },
- ["remark"] = new TemplateDataItem { Value = "点击查看详情" }
- }
+ Data = data
};
var success = await _weChatService.SendServiceAccountTemplateMessageAsync(request);
@@ -576,6 +606,37 @@ public class NotificationService : INotificationService
}
}
+ ///
+ /// 获取服务号模板字段映射
+ ///
+ private async Task?> GetServiceAccountFieldMappingAsync(NotificationTemplateType templateType)
+ {
+ string? configKey = templateType switch
+ {
+ NotificationTemplateType.Unlock => SystemConfigService.SaUnlockFieldMappingKey,
+ NotificationTemplateType.Favorite => SystemConfigService.SaFavoriteFieldMappingKey,
+ NotificationTemplateType.FirstMessage => SystemConfigService.SaMessageFieldMappingKey,
+ NotificationTemplateType.MessageReminder => SystemConfigService.SaMessageFieldMappingKey,
+ NotificationTemplateType.DailyRecommend => SystemConfigService.SaDailyRecommendFieldMappingKey,
+ _ => null
+ };
+
+ if (configKey == null) return null;
+
+ var json = await _configService.GetConfigValueAsync(configKey);
+ if (string.IsNullOrEmpty(json)) return null;
+
+ try
+ {
+ return System.Text.Json.JsonSerializer.Deserialize>(json);
+ }
+ catch
+ {
+ _logger.LogWarning("解析字段映射失败: Key={Key}, Value={Value}", configKey, json);
+ return null;
+ }
+ }
+
#endregion
diff --git a/server/src/XiangYi.Application/Services/SystemConfigService.cs b/server/src/XiangYi.Application/Services/SystemConfigService.cs
index 888ea75..b468092 100644
--- a/server/src/XiangYi.Application/Services/SystemConfigService.cs
+++ b/server/src/XiangYi.Application/Services/SystemConfigService.cs
@@ -101,9 +101,13 @@ public class SystemConfigService : ISystemConfigService
public const string SaTokenKey = "sa_token";
public const string SaEncodingAesKeyKey = "sa_encoding_aes_key";
public const string SaUnlockTemplateIdKey = "sa_unlock_template_id";
+ public const string SaUnlockFieldMappingKey = "sa_unlock_field_mapping";
public const string SaFavoriteTemplateIdKey = "sa_favorite_template_id";
+ public const string SaFavoriteFieldMappingKey = "sa_favorite_field_mapping";
public const string SaMessageTemplateIdKey = "sa_message_template_id";
+ public const string SaMessageFieldMappingKey = "sa_message_field_mapping";
public const string SaDailyRecommendTemplateIdKey = "sa_daily_recommend_template_id";
+ public const string SaDailyRecommendFieldMappingKey = "sa_daily_recommend_field_mapping";
public SystemConfigService(
IRepository configRepository,
@@ -360,9 +364,13 @@ public class SystemConfigService : ISystemConfigService
Token = await GetConfigValueAsync(SaTokenKey),
EncodingAESKey = await GetConfigValueAsync(SaEncodingAesKeyKey),
UnlockTemplateId = await GetConfigValueAsync(SaUnlockTemplateIdKey),
+ UnlockFieldMapping = await GetConfigValueAsync(SaUnlockFieldMappingKey),
FavoriteTemplateId = await GetConfigValueAsync(SaFavoriteTemplateIdKey),
+ FavoriteFieldMapping = await GetConfigValueAsync(SaFavoriteFieldMappingKey),
MessageTemplateId = await GetConfigValueAsync(SaMessageTemplateIdKey),
- DailyRecommendTemplateId = await GetConfigValueAsync(SaDailyRecommendTemplateIdKey)
+ MessageFieldMapping = await GetConfigValueAsync(SaMessageFieldMappingKey),
+ DailyRecommendTemplateId = await GetConfigValueAsync(SaDailyRecommendTemplateIdKey),
+ DailyRecommendFieldMapping = await GetConfigValueAsync(SaDailyRecommendFieldMappingKey)
};
}
@@ -377,12 +385,20 @@ public class SystemConfigService : ISystemConfigService
await SetConfigValueAsync(SaEncodingAesKeyKey, templates.EncodingAESKey, "服务号消息加解密密钥");
if (!string.IsNullOrEmpty(templates.UnlockTemplateId))
await SetConfigValueAsync(SaUnlockTemplateIdKey, templates.UnlockTemplateId, "服务号解锁通知模板ID");
+ if (!string.IsNullOrEmpty(templates.UnlockFieldMapping))
+ await SetConfigValueAsync(SaUnlockFieldMappingKey, templates.UnlockFieldMapping, "服务号解锁通知字段映射");
if (!string.IsNullOrEmpty(templates.FavoriteTemplateId))
await SetConfigValueAsync(SaFavoriteTemplateIdKey, templates.FavoriteTemplateId, "服务号收藏通知模板ID");
+ if (!string.IsNullOrEmpty(templates.FavoriteFieldMapping))
+ await SetConfigValueAsync(SaFavoriteFieldMappingKey, templates.FavoriteFieldMapping, "服务号收藏通知字段映射");
if (!string.IsNullOrEmpty(templates.MessageTemplateId))
await SetConfigValueAsync(SaMessageTemplateIdKey, templates.MessageTemplateId, "服务号消息通知模板ID");
+ if (!string.IsNullOrEmpty(templates.MessageFieldMapping))
+ await SetConfigValueAsync(SaMessageFieldMappingKey, templates.MessageFieldMapping, "服务号消息通知字段映射");
if (!string.IsNullOrEmpty(templates.DailyRecommendTemplateId))
await SetConfigValueAsync(SaDailyRecommendTemplateIdKey, templates.DailyRecommendTemplateId, "服务号每日推荐通知模板ID");
+ if (!string.IsNullOrEmpty(templates.DailyRecommendFieldMapping))
+ await SetConfigValueAsync(SaDailyRecommendFieldMappingKey, templates.DailyRecommendFieldMapping, "服务号每日推荐通知字段映射");
return true;
}
catch (Exception ex)
@@ -439,18 +455,38 @@ public class NotificationTemplatesDto
///
public string? UnlockTemplateId { get; set; }
+ ///
+ /// 解锁通知字段映射JSON,如 {"thing1":"title","thing2":"name","time3":"time"}
+ ///
+ public string? UnlockFieldMapping { get; set; }
+
///
/// 收藏通知模板ID
///
public string? FavoriteTemplateId { get; set; }
+ ///
+ /// 收藏通知字段映射JSON
+ ///
+ public string? FavoriteFieldMapping { get; set; }
+
///
/// 消息通知模板ID(首次消息/未回复提醒共用)
///
public string? MessageTemplateId { get; set; }
+ ///
+ /// 消息通知字段映射JSON
+ ///
+ public string? MessageFieldMapping { get; set; }
+
///
/// 每日推荐通知模板ID
///
public string? DailyRecommendTemplateId { get; set; }
+
+ ///
+ /// 每日推荐通知字段映射JSON
+ ///
+ public string? DailyRecommendFieldMapping { get; set; }
}