feat(customer-service): 新增客户服务问题反馈管理功能

- 重命名语言文件中相关关键字,统一改为 customer-service_feedbacks
- 新增客户服务反馈页面路由及组件导入,移除旧的 www_support_feedbacks 相关路由
- 实现客户服务反馈列表及详情查看,支持状态筛选、分页查询和消息对话展示
- 支持反馈状态变更,包括待处理、处理中和已解决状态切换
- 支持在对话中发送回复消息,且针对已解决状态自动停止轮询
- 优化状态标签样式,采用更易区分的颜色与视觉样式
- 组件及类型定义中新增 NCollapse 和 NCollapseItem 支持
- 移除旧的 www 支持反馈组件代码,清理无用路由及类型定义相关项
This commit is contained in:
eafonyang
2026-08-25 14:18:47 +08:00
parent 3702ad4163
commit f60255574e
10 changed files with 236 additions and 105 deletions
@@ -272,7 +272,7 @@ const local: App.I18n.Schema = {
www_contact_settings: 'Form Settings',
www_contact_submissions: 'Submissions',
'customer-service': 'Customer Service',
www_support_feedbacks: 'Support Feedback',
'customer-service_feedbacks': 'Support Feedback',
'www_page-seo': 'Page SEO'
},
page: {
@@ -268,8 +268,8 @@ const local: App.I18n.Schema = {
www_contact: '联系表单',
www_contact_settings: '表单配置',
www_contact_submissions: '提交记录',
'customer-service': '客服务',
www_support_feedbacks: '问题反馈',
'customer-service': '客服务',
'customer-service_feedbacks': '问题反馈',
'www_page-seo': '页面 SEO'
},
page: {
@@ -20,6 +20,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
500: () => import("@/views/_builtin/500/index.vue"),
"iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"),
login: () => import("@/views/_builtin/login/index.vue"),
"customer-service_feedbacks": () => import("@/views/customer-service/feedbacks/index.vue"),
headphone_brand: () => import("@/views/headphone/brand/index.vue"),
headphone_impedance: () => import("@/views/headphone/impedance/index.vue"),
headphone_model: () => import("@/views/headphone/model/index.vue"),
@@ -51,5 +52,4 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
www_product_detail: () => import("@/views/www/product/detail/index.vue"),
www_product_list: () => import("@/views/www/product/list/index.vue"),
www_product_series: () => import("@/views/www/product/series/index.vue"),
www_support_feedbacks: () => import("@/views/www/support/feedbacks/index.vue"),
};
+25 -25
View File
@@ -39,6 +39,31 @@ export const generatedRoutes: GeneratedRoute[] = [
hideInMenu: true
}
},
{
name: 'customer-service',
path: '/customer-service',
component: 'layout.base',
meta: {
title: 'customer-service',
i18nKey: 'route.customer-service',
icon: 'mdi:headset',
order: 7
},
children: [
{
name: 'customer-service_feedbacks',
path: '/customer-service/feedbacks',
component: 'view.customer-service_feedbacks',
meta: {
title: 'customer-service_feedbacks',
i18nKey: 'route.customer-service_feedbacks',
icon: 'mdi:message-alert-outline',
order: 1,
keepAlive: true
}
}
]
},
{
name: 'headphone',
path: '/headphone',
@@ -585,31 +610,6 @@ export const generatedRoutes: GeneratedRoute[] = [
}
}
]
},
]
},
{
name: 'customer-service',
path: '/www/support',
component: 'layout.base',
meta: {
title: 'customer-service',
i18nKey: 'route.customer-service',
icon: 'mdi:headset',
order: 7
},
children: [
{
name: 'www_support_feedbacks',
path: '/www/support/feedbacks',
component: 'view.www_support_feedbacks',
meta: {
title: 'www_support_feedbacks',
i18nKey: 'route.www_support_feedbacks',
icon: 'mdi:message-alert-outline',
order: 1,
keepAlive: true
}
}
]
}
@@ -166,6 +166,8 @@ const routeMap: RouteMap = {
"403": "/403",
"404": "/404",
"500": "/500",
"customer-service": "/customer-service",
"customer-service_feedbacks": "/customer-service/feedbacks",
"headphone": "/headphone",
"headphone_brand": "/headphone/brand",
"headphone_impedance": "/headphone/impedance",
@@ -210,9 +212,7 @@ const routeMap: RouteMap = {
"www_product": "/www/product",
"www_product_detail": "/www/product/detail",
"www_product_list": "/www/product/list",
"www_product_series": "/www/product/series",
"customer-service": "/www/support",
"www_support_feedbacks": "/www/support/feedbacks"
"www_product_series": "/www/product/series"
};
/**
+4
View File
@@ -41,6 +41,8 @@ declare module 'vue' {
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NCollapse: typeof import('naive-ui')['NCollapse']
NCollapseItem: typeof import('naive-ui')['NCollapseItem']
NColorPicker: typeof import('naive-ui')['NColorPicker']
NDataTable: typeof import('naive-ui')['NDataTable']
NDatePicker: typeof import('naive-ui')['NDatePicker']
@@ -132,6 +134,8 @@ declare global {
const NButton: typeof import('naive-ui')['NButton']
const NCard: typeof import('naive-ui')['NCard']
const NCheckbox: typeof import('naive-ui')['NCheckbox']
const NCollapse: typeof import('naive-ui')['NCollapse']
const NCollapseItem: typeof import('naive-ui')['NCollapseItem']
const NColorPicker: typeof import('naive-ui')['NColorPicker']
const NDataTable: typeof import('naive-ui')['NDataTable']
const NDatePicker: typeof import('naive-ui')['NDatePicker']
+4 -4
View File
@@ -20,6 +20,8 @@ declare module "@elegant-router/types" {
"403": "/403";
"404": "/404";
"500": "/500";
"customer-service": "/customer-service";
"customer-service_feedbacks": "/customer-service/feedbacks";
"headphone": "/headphone";
"headphone_brand": "/headphone/brand";
"headphone_impedance": "/headphone/impedance";
@@ -65,8 +67,6 @@ declare module "@elegant-router/types" {
"www_product_detail": "/www/product/detail";
"www_product_list": "/www/product/list";
"www_product_series": "/www/product/series";
"customer-service": "/www/support";
"www_support_feedbacks": "/www/support/feedbacks";
};
/**
@@ -101,6 +101,7 @@ declare module "@elegant-router/types" {
| "403"
| "404"
| "500"
| "customer-service"
| "headphone"
| "home"
| "iframe-page"
@@ -111,7 +112,6 @@ declare module "@elegant-router/types" {
| "toolbox"
| "upgrade"
| "www"
| "customer-service"
>;
/**
@@ -133,6 +133,7 @@ declare module "@elegant-router/types" {
| "500"
| "iframe-page"
| "login"
| "customer-service_feedbacks"
| "headphone_brand"
| "headphone_impedance"
| "headphone_model"
@@ -164,7 +165,6 @@ declare module "@elegant-router/types" {
| "www_product_detail"
| "www_product_list"
| "www_product_series"
| "www_support_feedbacks"
>;
/**
@@ -8,7 +8,7 @@ import {
fetchUpdateSupportFeedbackStatus,
} from '@/service/api';
defineOptions({ name: 'WwwSupportFeedbacks' });
defineOptions({ name: 'CustomerServiceFeedbacks' });
const POLL_INTERVAL_MS = 4000;