feat: 优化权益管理并完成一期验收

This commit is contained in:
2026-07-31 18:49:48 +08:00
parent b6aff78aac
commit a3946013f5
14 changed files with 740 additions and 284 deletions

View File

@@ -5,6 +5,7 @@ import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
import AdminLoginView from "./components/AdminLoginView.vue";
import AdminPagination from "./components/AdminPagination.vue";
import AgentManagementView from "./components/AgentManagementView.vue";
import EntitlementManagementView from "./components/EntitlementManagementView.vue";
import KnowledgeManagementView from "./components/KnowledgeManagementView.vue";
import TableRowActions from "./components/TableRowActions.vue";
import { systemSettingDefinitions, systemSettingSections, type SystemSettingValue } from "./config/systemSettings";
@@ -48,7 +49,6 @@ const userDetailLoading = ref(false);
const userReportGenerating = ref("");
const userKeyword = ref("");
const entitlementPlans = ref<EntitlementPlan[]>([]);
const editingEntitlementPlanId = ref<number | null>(null);
const models = ref<ModelItem[]>([]);
const configs = ref<SystemConfigItem[]>([]);
const chats = ref<ChatRecord[]>([]);
@@ -96,21 +96,6 @@ const studentImportFile = ref<File | null>(null);
const studentImportInput = ref<HTMLInputElement | null>(null);
const studentImportResult = ref<UserImportResult | null>(null);
const entitlementPlanForm = reactive({
name: "",
planType: "basic" as "basic" | "deep" | "addon",
description: "",
validityDays: null as number | null,
monthlyTopicLimit: 30 as number | null,
enableGrowthProfile: 0,
enablePeriodicReports: 0,
allowHelpCard: 1,
allowShareDraft: 1,
deductQuota: 1,
status: 1,
sortOrder: 10,
});
const knowledgeForm = reactive({
name: "",
feishuSpaceId: "",
@@ -349,67 +334,6 @@ async function loadEntitlementPlans() {
entitlementPlans.value = await api.entitlementPlans(true);
}
function planTypeLabel(type: string) {
return {
basic: "基础版",
deep: "深度陪伴版",
addon: "高频加购包",
}[type] || type;
}
async function saveEntitlementPlan() {
if (!entitlementPlanForm.name.trim()) {
ElMessage.warning("请填写权益版本名称");
return;
}
const payload = { ...entitlementPlanForm };
if (editingEntitlementPlanId.value) {
await api.updateEntitlementPlan(editingEntitlementPlanId.value, payload);
ElMessage.success("权益版本已更新");
} else {
await api.createEntitlementPlan(payload);
ElMessage.success("权益版本已新增");
}
resetEntitlementPlanForm();
await loadEntitlementPlans();
}
function editEntitlementPlan(row: EntitlementPlan) {
editingEntitlementPlanId.value = row.id;
Object.assign(entitlementPlanForm, {
name: row.name,
planType: row.planType,
description: row.description ?? "",
validityDays: row.validityDays ?? null,
monthlyTopicLimit: row.monthlyTopicLimit ?? null,
enableGrowthProfile: row.enableGrowthProfile ? 1 : 0,
enablePeriodicReports: row.enablePeriodicReports ? 1 : 0,
allowHelpCard: row.allowHelpCard ? 1 : 0,
allowShareDraft: row.allowShareDraft ? 1 : 0,
deductQuota: row.deductQuota ? 1 : 0,
status: row.status,
sortOrder: row.sortOrder,
});
}
function resetEntitlementPlanForm() {
editingEntitlementPlanId.value = null;
Object.assign(entitlementPlanForm, {
name: "",
planType: "basic",
description: "",
validityDays: null,
monthlyTopicLimit: 30,
enableGrowthProfile: 0,
enablePeriodicReports: 0,
allowHelpCard: 1,
allowShareDraft: 1,
deductQuota: 1,
status: 1,
sortOrder: 10,
});
}
async function assignUserEntitlement(row: AdminUser, planId: number) {
const entitlement = await api.assignUserEntitlement(row.id, { planId });
row.entitlement = entitlement;
@@ -1272,88 +1196,7 @@ function formatRecordDateTime(value: string, boundary: "start" | "end") {
</template>
<template v-if="activeMenu === 'entitlements'">
<div class="page-head">
<h2>权益管理</h2>
<p>配置不同服务版本的本月主题额度和可用能力学员可在用户管理里直接分配</p>
</div>
<section class="entitlement-editor">
<div class="entitlement-editor-head">
<div>
<h3>{{ editingEntitlementPlanId ? '编辑权益版本' : '新增权益版本' }}</h3>
<p>一期先接入主题额度成长档案/周期报告开关和转人工卡片/分享草稿能力位</p>
</div>
<el-button @click="resetEntitlementPlanForm">清空</el-button>
</div>
<el-form label-position="top" :model="entitlementPlanForm">
<div class="entitlement-form-grid">
<el-form-item label="版本名称">
<el-input v-model="entitlementPlanForm.name" placeholder="例如:五个月深度陪伴版" />
</el-form-item>
<el-form-item label="版本类型">
<el-select v-model="entitlementPlanForm.planType">
<el-option label="基础版" value="basic" />
<el-option label="深度陪伴版" value="deep" />
<el-option label="高频加购包" value="addon" />
</el-select>
</el-form-item>
<el-form-item label="有效天数">
<el-input-number v-model="entitlementPlanForm.validityDays" :min="1" :max="3650" placeholder="留空长期有效" />
</el-form-item>
<el-form-item label="本月主题额度">
<el-input-number v-model="entitlementPlanForm.monthlyTopicLimit" :min="0" :max="99999" placeholder="留空不限" />
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="entitlementPlanForm.sortOrder" :min="0" :max="9999" />
</el-form-item>
</div>
<el-form-item label="说明">
<el-input v-model="entitlementPlanForm.description" type="textarea" :rows="2" placeholder="给后台管理员看的说明,不展示给学员" />
</el-form-item>
<div class="entitlement-switch-grid">
<label><span>成长档案</span><el-switch v-model="entitlementPlanForm.enableGrowthProfile" :active-value="1" :inactive-value="0" /></label>
<label><span>周期报告</span><el-switch v-model="entitlementPlanForm.enablePeriodicReports" :active-value="1" :inactive-value="0" /></label>
<label><span>允许求助卡片</span><el-switch v-model="entitlementPlanForm.allowHelpCard" :active-value="1" :inactive-value="0" /></label>
<label><span>允许分享草稿</span><el-switch v-model="entitlementPlanForm.allowShareDraft" :active-value="1" :inactive-value="0" /></label>
<label><span>占用主题额度</span><el-switch v-model="entitlementPlanForm.deductQuota" :active-value="1" :inactive-value="0" /></label>
<label><span>启用版本</span><el-switch v-model="entitlementPlanForm.status" :active-value="1" :inactive-value="0" /></label>
</div>
<div class="actions">
<el-button type="primary" @click="saveEntitlementPlan">{{ editingEntitlementPlanId ? '保存权益版本' : '新增权益版本' }}</el-button>
<el-button @click="resetEntitlementPlanForm">取消编辑</el-button>
</div>
</el-form>
</section>
<el-table :data="entitlementPlans" stripe>
<el-table-column prop="name" label="版本名称" min-width="180" />
<el-table-column label="类型" width="130">
<template #default="{ row }">{{ planTypeLabel(row.planType) }}</template>
</el-table-column>
<el-table-column label="本月主题额度" width="130">
<template #default="{ row }">{{ row.monthlyTopicLimit ?? '不限' }}</template>
</el-table-column>
<el-table-column label="有效期" width="110">
<template #default="{ row }">{{ row.validityDays ? `${row.validityDays}` : '长期' }}</template>
</el-table-column>
<el-table-column label="能力" min-width="260">
<template #default="{ row }">
<div class="entitlement-capabilities">
<el-tag v-if="row.enableGrowthProfile" type="success" effect="plain">成长档案</el-tag>
<el-tag v-if="row.enablePeriodicReports" type="success" effect="plain">周期报告</el-tag>
<el-tag v-if="row.allowHelpCard" effect="plain">求助卡片</el-tag>
<el-tag v-if="row.allowShareDraft" effect="plain">分享草稿</el-tag>
<el-tag :type="row.deductQuota ? 'warning' : 'info'" effect="plain">{{ row.deductQuota ? '计入额度' : '不计额度' }}</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="状态" width="90">
<template #default="{ row }"><el-tag :type="row.status === 1 ? 'success' : 'info'">{{ row.status === 1 ? '启用' : '停用' }}</el-tag></template>
</el-table-column>
<el-table-column label="操作" width="100" fixed="right" align="center">
<template #default="{ row }"><el-button size="small" @click="editEntitlementPlan(row)">编辑</el-button></template>
</el-table-column>
</el-table>
<EntitlementManagementView :plans="entitlementPlans" @refreshed="loadEntitlementPlans" />
</template>
<template v-if="activeMenu === 'knowledge'">