diff --git a/admin/dashboard/templates/contacts_management.html b/admin/dashboard/templates/contacts_management.html index 64058b7..8adbd2c 100644 --- a/admin/dashboard/templates/contacts_management.html +++ b/admin/dashboard/templates/contacts_management.html @@ -430,6 +430,53 @@ + + +
+ 进群欢迎配置(群级差异化) + 当前群:{% raw %}{{ currentGroup.name || currentGroup.wxid || '-' }}{% endraw %} +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ {nickname}{wxid}{group_id}{now}{head_url} +
+
+ +
+

文本:{% raw %}{{ previewGroupWelcomeText }}{% endraw %}

+

标题:{% raw %}{{ previewGroupWelcomeTitle }}{% endraw %}

+

描述:{% raw %}{{ previewGroupWelcomeDesc }}{% endraw %}

+

URL:{% raw %}{{ previewGroupWelcomeUrl }}{% endraw %}

+
+
+ + 保存欢迎配置 + 恢复默认 + +
+
@@ -786,6 +833,16 @@ managedGroupMap: {}, groupPermissions: [], groupPermissionsLoading: false, + groupWelcomeConfigLoading: false, + groupWelcomeConfig: { + welcome_text_enabled: true, + welcome_text_template: '👏欢迎 {nickname} 加入群聊!🎉', + welcome_card_enabled: true, + card_title_template: '👏欢迎 {nickname} 加入群聊!🎉', + card_desc_template: '⌚时间:{now}', + card_url: 'https://newsnow.busiyi.world/', + card_thumb_url: '{head_url}' + }, // 当前群基础资料:用于展示群主、群公告、管理员、成员数等信息。 currentGroupProfile: { owner_wxid: '', owner_name: '', announcement: '', member_count: 0, admin_count: 0, admins: [] }, // 群公告手动同步按钮的加载态,避免重复点击触发多次请求。 @@ -849,6 +906,18 @@ const keyword = (this.emojiKeyword || '').trim().toLowerCase(); if (!keyword) return this.emojiLibrary; return this.emojiLibrary.filter(item => (item.md5 || '').toLowerCase().includes(keyword)); + }, + previewGroupWelcomeText() { + return this.renderWelcomeTemplate(this.groupWelcomeConfig.welcome_text_template); + }, + previewGroupWelcomeTitle() { + return this.renderWelcomeTemplate(this.groupWelcomeConfig.card_title_template); + }, + previewGroupWelcomeDesc() { + return this.renderWelcomeTemplate(this.groupWelcomeConfig.card_desc_template); + }, + previewGroupWelcomeUrl() { + return this.renderWelcomeTemplate(this.groupWelcomeConfig.card_url); } }, mounted() { @@ -910,10 +979,100 @@ this.loadGroupMembers(group.wxid); this.loadGroupPermissions(group.wxid); this.loadGroupInsights(group.wxid); + this.loadGroupWelcomeConfig(group.wxid); }, viewUserDetails(user) { this.currentUser = user; this.userDetailDialogVisible = true; }, viewOfficialDetails(official) { this.currentOfficial = official; this.officialDetailDialogVisible = true; }, viewPublicDetails(publicFriend) { this.currentPublic = publicFriend; this.publicDetailDialogVisible = true; }, + getDefaultWelcomeConfig() { + return { + welcome_text_enabled: true, + welcome_text_template: '👏欢迎 {nickname} 加入群聊!🎉', + welcome_card_enabled: true, + card_title_template: '👏欢迎 {nickname} 加入群聊!🎉', + card_desc_template: '⌚时间:{now}', + card_url: 'https://newsnow.busiyi.world/', + card_thumb_url: '{head_url}' + }; + }, + normalizeWelcomeConfig(raw) { + const base = this.getDefaultWelcomeConfig(); + const cfg = raw && typeof raw === 'object' ? raw : {}; + return { + welcome_text_enabled: cfg.welcome_text_enabled !== undefined ? !!cfg.welcome_text_enabled : base.welcome_text_enabled, + welcome_text_template: String(cfg.welcome_text_template || base.welcome_text_template), + welcome_card_enabled: cfg.welcome_card_enabled !== undefined ? !!cfg.welcome_card_enabled : base.welcome_card_enabled, + card_title_template: String(cfg.card_title_template || base.card_title_template), + card_desc_template: String(cfg.card_desc_template || base.card_desc_template), + card_url: String(cfg.card_url || base.card_url), + card_thumb_url: String(cfg.card_thumb_url || base.card_thumb_url) + }; + }, + renderWelcomeTemplate(template) { + const vars = { + nickname: '张三', + wxid: 'wxid_demo_123', + group_id: (this.currentGroup && this.currentGroup.wxid) || '123456@chatroom', + now: '2026-04-20 12:00:00', + head_url: 'https://example.com/avatar.png' + }; + let text = String(template || ''); + Object.entries(vars).forEach(([k, v]) => { + text = text.replace(new RegExp(`\\{${k}\\}`, 'g'), String(v)); + }); + return text; + }, + loadGroupWelcomeConfig(groupId) { + if (!groupId) return; + this.groupWelcomeConfigLoading = true; + this.groupWelcomeConfig = this.getDefaultWelcomeConfig(); + axios.get('/group_plugin_config/api/list', { + params: { group_id: groupId, plugin_name: '群成员变更监控' } + }).then(response => { + if (!response.data || !response.data.success) { + this.$message.warning('加载欢迎配置失败,已使用默认值'); + return; + } + const rows = response.data.data || []; + const row = rows.find(item => String(item.config_key || '') === 'welcome'); + if (row && row.config_json) { + this.groupWelcomeConfig = this.normalizeWelcomeConfig(row.config_json); + } + }).catch(error => { + console.error('加载群欢迎配置失败:', error); + this.$message.warning('加载欢迎配置失败,已使用默认值'); + }).finally(() => { this.groupWelcomeConfigLoading = false; }); + }, + resetGroupWelcomeConfig() { + this.groupWelcomeConfig = this.getDefaultWelcomeConfig(); + this.$message.success('已恢复默认欢迎配置'); + }, + saveGroupWelcomeConfig() { + if (!this.currentGroup || !this.currentGroup.wxid) return; + const renderedUrl = this.renderWelcomeTemplate(this.groupWelcomeConfig.card_url); + if (!/^https?:\/\//i.test(renderedUrl)) { + this.$message.error('卡片URL必须是 http 或 https 开头'); + return; + } + this.groupWelcomeConfigLoading = true; + axios.post('/group_plugin_config/api/upsert', { + group_id: this.currentGroup.wxid, + plugin_name: '群成员变更监控', + config_key: 'welcome', + enabled: true, + config_json: this.groupWelcomeConfig, + updated_by: 'dashboard' + }).then(response => { + if (response.data && response.data.success) { + this.$message.success('群欢迎配置保存成功'); + } else { + this.$message.error((response.data && response.data.message) || '群欢迎配置保存失败'); + } + }).catch(error => { + console.error('保存群欢迎配置失败:', error); + this.$message.error('保存群欢迎配置失败'); + }).finally(() => { this.groupWelcomeConfigLoading = false; }); + }, loadGroupPermissions(groupId) { this.groupPermissionsLoading = true; this.groupPermissions = []; @@ -1537,6 +1696,7 @@ .pagination-container { margin-top: 20px; text-align: right; } .group-insight-section { margin-top: 20px; } .group-permission-section { margin-top: 20px; } + .welcome-config-card { margin-top: 14px; } .group-members-section { margin-top: 20px; } .section-title { margin: 20px 0 15px 0; border-bottom: 1px solid rgba(148,163,184,0.12); padding-bottom: 10px; @@ -1677,6 +1837,16 @@ border: 1px solid rgba(148,163,184,0.16); border-radius: 12px; padding: 8px; display: flex; flex-direction: column; gap: 8px; align-items: center; background: #fff; } + .form-tip{ + padding:10px 12px;border-radius:10px;background:#f8fbff;border:1px solid #d9e8f8;color:#4a6179 + } + .form-tip code{ + display:inline-block;margin-right:6px;background:#eef6ff;border:1px solid #d2e6ff;color:#12539a;padding:1px 6px;border-radius:6px;font-size:12px + } + .preview-box{ + padding:12px;border:1px dashed #c7d8ea;background:#f8fbff;border-radius:10px;color:#3f5c77;line-height:1.7 + } + .preview-box p{margin:0 0 4px 0} .emoji-thumb { width: 72px; height: 72px; object-fit: contain; border-radius: 8px; background: rgba(148,163,184,0.08); } .emoji-md5 { font-size: 11px; color: #64748b; word-break: break-all; text-align: center; min-height: 30px; } .emoji-actions { width: 100%; display: flex; justify-content: center; }