@@ -1344,4 +1369,12 @@ onMounted(() => {
color: #6b7280;
font-size: 13px;
}
+
+.sms-node-hint {
+ width: 100%;
+ margin-top: 4px;
+ color: #9ca3af;
+ font-size: 12px;
+ line-height: 1.5;
+}
diff --git a/frontend/src/features/admin/views/AdminSystemConfigsView.vue b/frontend/src/features/admin/views/AdminSystemConfigsView.vue
index 9273f7c..9750d02 100644
--- a/frontend/src/features/admin/views/AdminSystemConfigsView.vue
+++ b/frontend/src/features/admin/views/AdminSystemConfigsView.vue
@@ -19,6 +19,10 @@ import {
import type { OrderAgreements } from '@/features/orders/api/orders'
import { fetchSystemConfigs, type SystemConfig } from '@/features/admin/api/systemConfigs'
import { parseRenterGrowthConfig } from '@/features/admin/api/renterGrowth'
+import {
+ parseSmsBusinessTemplatesConfig,
+ smsNodeMetas,
+} from '@/features/admin/api/smsNodeTemplates'
import { formatDateTime } from '@/shared/utils/time'
import { safeParseJSON } from '@/shared/utils/json'
import { formatSystemConfigSelectValue } from '@/shared/utils/systemConfigOptions'
@@ -40,6 +44,7 @@ import OrderAgreementsDialog from '../components/OrderAgreementsDialog.vue'
import PostRentalNoticeDialog from '../components/PostRentalNoticeDialog.vue'
import GeneralConfigDialog from '../components/GeneralConfigDialog.vue'
import RenterGrowthConfigDialog from '../components/RenterGrowthConfigDialog.vue'
+import SmsNodeTemplatesDialog from '../components/SmsNodeTemplatesDialog.vue'
import AutoWelcomeConfig from '../components/AutoWelcomeConfig.vue'
import {
fetchAutoWelcomeMessage,
@@ -86,6 +91,7 @@ const agreementsVisible = ref(false)
const postRentalNoticeVisible = ref(false)
const generalVisible = ref(false)
const renterGrowthVisible = ref(false)
+const smsNodeTemplatesVisible = ref(false)
const publishConfig = computed(
() => configs.value.find(item => item.key === 'listing.publish_options') || null
@@ -99,6 +105,9 @@ const listingPublishCooldownConfig = computed(
const renterGrowthConfig = computed(
() => configs.value.find(item => item.key === 'renter.growth_level_rules') || null
)
+const smsNodeTemplatesConfig = computed(
+ () => configs.value.find(item => item.key === 'sms.business_templates') || null
+)
const homeAnnouncementsConfig = computed(
() => configs.value.find(item => item.key === 'mobile.home_announcements') || null
)
@@ -167,7 +176,8 @@ const regularConfigs = computed(() =>
item.key !== 'integration.paddle_ocr_token' &&
item.key !== 'integration.paddle_ocr_job_url' &&
item.key !== 'integration.paddle_ocr_model' &&
- item.key !== 'renter.growth_level_rules'
+ item.key !== 'renter.growth_level_rules' &&
+ item.key !== 'sms.business_templates'
)
)
@@ -227,6 +237,24 @@ const renterGrowthStats = computed(() => {
}
})
+const smsNodeStats = computed(() => {
+ const config = parseSmsBusinessTemplatesConfig(smsNodeTemplatesConfig.value?.value || '')
+ const configured = smsNodeMetas.filter(
+ meta => config.nodes[meta.code]?.template_code && config.nodes[meta.code]?.enabled
+ )
+ return {
+ enabled: config.enabled,
+ configuredCount: configured.length,
+ totalCount: smsNodeMetas.length,
+ nodes: smsNodeMetas,
+ statusOf: (code: string) => {
+ const node = config.nodes[code]
+ if (!node?.template_code) return '未配置'
+ return node.enabled ? '已配置' : '已停用'
+ },
+ }
+})
+
const agreementStats = computed(() => {
const agreements = parseOrderAgreements(orderAgreementsConfig.value?.value || '')
return {
@@ -295,6 +323,8 @@ function openEdit(row: SystemConfig) {
postRentalNoticeVisible.value = true
} else if (row.key === 'renter.growth_level_rules') {
renterGrowthVisible.value = true
+ } else if (row.key === 'sms.business_templates') {
+ smsNodeTemplatesVisible.value = true
} else if (row.key === 'chat.renter_retention_days_after_order_end') {
generalVisible.value = true
} else {
@@ -592,6 +622,36 @@ function formatConfigValue(row: SystemConfig) {
+
+
+
+
Node SMS
+
节点短信
+
审核未通过、被租用需辅助登录、上架多日未成交等节点给号主发短信;只填阿里云已报备的模板
+ CODE,文案由平台模板决定。分站可在「分销站点 → 短信配置」里配置自己的模板。
+
+
+ 编辑节点短信
+
+
+
+
+ {{ smsNodeStats.enabled ? '已启用' : '已停用' }}
+ 总开关
+
+
+ {{ smsNodeStats.configuredCount }} / {{ smsNodeStats.totalCount }}
+ 已配置节点
+
+
+ {{ smsNodeStats.statusOf(meta.code) }}
+ {{ meta.name }}
+
+
+
+
+
+