diff --git a/pages/champion/champion.vue b/pages/champion/champion.vue
index ebb7bfa..2fefdb6 100644
--- a/pages/champion/champion.vue
+++ b/pages/champion/champion.vue
@@ -70,15 +70,237 @@
-
- 陪练
- 这里是陪练相关的内容展示区域
+ v-if="activeTab === 'practice'"
+ @scrolltolower="onPracticeReachBottom">
+
+ 共{{ practiceTotal }}条
+
+
+
+
+
+ 刷新
+
+
+
+
+
+
+
+
+
+
+ 所属行业: {{ item.industry }}
+
+
+
+
+ 详情: {{ getContentPreview(item.content) }}
+
+
+ 备注: {{ item.remark }}
+
+
+
+
+
+
+
+ 暂无陪练
+
+
+ 正在加载更多...
+
+
+
+
+
+
+
+
= this.practiceTotal) return;
+ this.practicePage.current += 1;
+ this.fetchPracticeList();
+ },
+ async fetchPracticeList({ force = false } = {}) {
+ if (this.practiceLoading && !force) {
+ return;
+ }
+ this.practiceLoading = true;
+ try {
+ const queryParams = {
+ current: this.practicePage.current,
+ size: this.practicePage.size,
+ category: 'AI陪练虚拟人' // 默认添加知识分类参数
+ };
+ const trimmedTitle = this.practiceQuery?.title?.trim();
+ const trimmedIndustry = this.practiceQuery?.industry?.trim();
+ const trimmedCreator = this.practiceQuery?.creator?.trim();
+ const trimmedStatus = this.practiceQuery?.status?.trim();
+
+ if (trimmedTitle) {
+ queryParams.title = trimmedTitle;
+ }
+ if (trimmedIndustry) {
+ queryParams.industry = trimmedIndustry;
+ }
+ if (trimmedCreator) {
+ queryParams.creator = trimmedCreator;
+ }
+ if (trimmedStatus) {
+ queryParams.status = trimmedStatus;
+ }
+
+ const queryString = Object.keys(queryParams)
+ .map(key => `${key}=${encodeURIComponent(queryParams[key])}`)
+ .join('&');
+ const url = `${getApiUrl('/api/knowledgeBase/list')}?${queryString}`;
+
+ // 获取租户ID
+ const tenantId = getTenantId();
+ const headers = {};
+ if (tenantId) {
+ headers['X-Tenant-Id'] = tenantId;
+ }
+
+ const res = await uni.request({
+ url,
+ method: 'POST',
+ header: headers,
+ timeout: 10000
+ });
+
+ if (res.statusCode === 200 && res.data && res.data.success) {
+ const records = Array.isArray(res.data.data) ? res.data.data : [];
+ // 第一页或强制刷新时重置列表,否则追加
+ if (this.practicePage.current === 1 || force) {
+ this.practiceList = records;
+ } else {
+ this.practiceList = this.practiceList.concat(records);
+ }
+ this.practiceTotal = Number(res.data.total) || 0;
+ } else {
+ this.practiceList = [];
+ this.practiceTotal = 0;
+ uni.showToast({
+ title: res.data?.message || '获取陪练列表失败',
+ icon: 'none'
+ });
+ }
+ } catch (error) {
+ console.error('获取陪练列表失败:', error);
+ uni.showToast({
+ title: '获取陪练列表失败,请稍后重试',
+ icon: 'none'
+ });
+ } finally {
+ this.practiceLoading = false;
+ }
+ },
+ showPracticeContextMenu(item, index, event) {
+ // 阻止事件冒泡
+ if (event && event.stopPropagation) {
+ event.stopPropagation();
+ }
+ // 获取系统信息以计算位置
+ const systemInfo = uni.getSystemInfoSync();
+ // 获取点击位置 - 优先使用触摸事件坐标
+ let top = 100;
+ let left = systemInfo.windowWidth - 180;
+
+ if (event) {
+ if (event.touches && event.touches.length > 0) {
+ // 触摸事件
+ top = event.touches[0].clientY;
+ left = event.touches[0].clientX - 80;
+ } else if (event.detail && typeof event.detail.x === 'number') {
+ // tap事件坐标(单位:px,需要转换)
+ top = event.detail.y;
+ left = event.detail.x - 80;
+ } else if (event.clientY !== undefined) {
+ // 鼠标事件
+ top = event.clientY;
+ left = event.clientX - 80;
+ }
+ }
+
+ // 确保菜单不超出屏幕
+ if (left + 160 > systemInfo.windowWidth) {
+ left = systemInfo.windowWidth - 180;
+ }
+ if (left < 0) {
+ left = 10;
+ }
+
+ this.practiceContextMenuTop = top;
+ this.practiceContextMenuLeft = left;
+ // 显示菜单
+ this.practiceContextMenuIndex = index;
+ this.practiceContextMenuVisible = true;
+ },
+ closePracticeContextMenu() {
+ this.practiceContextMenuVisible = false;
+ this.practiceContextMenuIndex = -1;
+ },
+ handleEditPractice(item) {
+ this.closePracticeContextMenu();
+ // 填充编辑表单
+ this.editPracticeForm = {
+ id: item.id,
+ title: item.title || '',
+ category: item.category || '',
+ industry: item.industry || '',
+ content: item.content || '',
+ remark: item.remark || ''
+ };
+ this.showEditPracticePopup = true;
+ },
+ closeEditPracticePopup() {
+ this.showEditPracticePopup = false;
+ this.editPracticeForm = {
+ id: '',
+ title: '',
+ category: '',
+ industry: '',
+ content: '',
+ remark: ''
+ };
+ },
+ async submitEditPractice() {
+ // 表单验证
+ if (!this.editPracticeForm.title || !this.editPracticeForm.title.trim()) {
+ uni.showToast({
+ title: "请输入知识标题",
+ icon: "none"
+ });
+ return;
+ }
+
+ try {
+ uni.showLoading({
+ title: "保存中..."
+ });
+
+ // 获取租户ID
+ const tenantId = getTenantId();
+ const headers = {
+ "Content-Type": "application/json"
+ };
+ if (tenantId) {
+ headers['X-Tenant-Id'] = tenantId;
+ // 同时在数据中也添加租户ID(如果后端需要)
+ if (!this.editPracticeForm.tenantId) {
+ this.editPracticeForm.tenantId = tenantId;
+ }
+ }
+
+ const res = await uni.request({
+ url: getApiUrl('/api/knowledgeBase/update'),
+ method: 'PUT',
+ data: this.editPracticeForm,
+ header: headers,
+ timeout: 15000
+ });
+
+ uni.hideLoading();
+
+ if (res.statusCode === 200 && res.data && (res.data.success || res.data.code === 200)) {
+ uni.showToast({
+ title: res.data?.message || "保存成功",
+ icon: "success"
+ });
+ // 关闭弹出框并刷新列表
+ this.closeEditPracticePopup();
+ this.practicePage.current = 1;
+ this.fetchPracticeList({ force: true });
+ } else {
+ uni.showToast({
+ title: res.data?.message || "保存失败",
+ icon: "none"
+ });
+ }
+ } catch (error) {
+ uni.hideLoading();
+ console.error("保存陪练失败:", error);
+ uni.showToast({
+ title: error?.message || "保存失败,请重试",
+ icon: "none"
+ });
+ }
+ },
+ handleDeletePractice(item) {
+ this.closePracticeContextMenu();
+ uni.showModal({
+ title: '提示',
+ content: '确认删除该陪练吗?',
+ success: async (res) => {
+ if (res.confirm) {
+ try {
+ uni.showLoading({
+ title: "删除中..."
+ });
+
+ // 获取租户ID
+ const tenantId = getTenantId();
+ const headers = {};
+ if (tenantId) {
+ headers['X-Tenant-Id'] = tenantId;
+ }
+
+ const deleteRes = await uni.request({
+ url: getApiUrl(`/api/knowledgeBase/delete/${item.id}`),
+ method: 'DELETE',
+ header: headers,
+ timeout: 15000
+ });
+
+ uni.hideLoading();
+
+ if (deleteRes.statusCode === 200 && deleteRes.data && (deleteRes.data.success || deleteRes.data.code === 200)) {
+ uni.showToast({
+ title: deleteRes.data?.message || "删除成功",
+ icon: "success"
+ });
+ // 刷新列表
+ this.practicePage.current = 1;
+ this.fetchPracticeList({ force: true });
+ } else {
+ uni.showToast({
+ title: deleteRes.data?.message || "删除失败",
+ icon: "none"
+ });
+ }
+ } catch (error) {
+ uni.hideLoading();
+ console.error("删除陪练失败:", error);
+ uni.showToast({
+ title: error?.message || "删除失败,请重试",
+ icon: "none"
+ });
+ }
+ }
+ }
+ });
+ },
+ // 添加陪练相关方法
+ showAddPractice() {
+ this.showPracticePopup = true;
+ this.practiceForm = {
+ title: '',
+ category: 'AI陪练虚拟人', // 固定值,不可修改
+ industry: '汽车销售', // 默认值
+ file: null
+ };
+ },
+ closePracticePopup() {
+ this.showPracticePopup = false;
+ },
+ choosePracticeFile() {
+ // 限制只能上传一个文件
+ // #ifdef H5
+ // H5平台使用chooseFile
+ uni.chooseFile({
+ count: 1,
+ success: (res) => {
+ const tempFiles = res.tempFiles || [];
+ if (tempFiles.length > 0) {
+ const file = tempFiles[0];
+ // 替换文件,而不是添加
+ this.practiceForm.file = {
+ name: file.name || '文件',
+ path: file.path || file.url,
+ size: file.size
+ };
+ }
+ },
+ fail: (err) => {
+ console.error('选择文件失败:', err);
+ uni.showToast({
+ title: '选择文件失败',
+ icon: 'none'
+ });
+ }
+ });
+ // #endif
+ // #ifndef H5
+ // 非H5平台使用chooseImage(可以选择图片文件)
+ uni.chooseImage({
+ count: 1,
+ success: (res) => {
+ const tempFiles = res.tempFiles || [];
+ if (tempFiles.length > 0) {
+ const file = tempFiles[0];
+ // 替换文件,而不是添加
+ this.practiceForm.file = {
+ name: file.name || '图片',
+ path: file.path,
+ size: file.size
+ };
+ }
+ },
+ fail: (err) => {
+ console.error('选择文件失败:', err);
+ uni.showToast({
+ title: '选择文件失败',
+ icon: 'none'
+ });
+ }
+ });
+ // #endif
+ },
+ removePracticeFile() {
+ // 清空文件
+ this.practiceForm.file = null;
+ },
+ async submitPractice() {
+ // 表单验证
+ if (!this.practiceForm.title || !this.practiceForm.title.trim()) {
+ uni.showToast({
+ title: "请输入知识标题",
+ icon: "none"
+ });
+ return;
+ }
+
+ try {
+ uni.showLoading({
+ title: "提交中..."
+ });
+
+ // 获取租户ID
+ const tenantId = getTenantId();
+
+ let res;
+
+ // 如果有文件,使用 uni.uploadFile 同时上传文件和其他表单数据
+ if (this.practiceForm.file) {
+ // 使用 uni.uploadFile 将文件和其他字段一起提交
+ const formData = {
+ // 其他表单字段
+ 'title': this.practiceForm.title.trim(),
+ 'category': this.practiceForm.category?.trim() || '',
+ 'industry': this.practiceForm.industry?.trim() || '',
+ 'content': '-',
+ 'fileName': this.practiceForm.file.name || 'file' // 文件名
+ };
+
+ // 添加租户ID到formData
+ if (tenantId) {
+ formData['tenantId'] = tenantId;
+ }
+
+ res = await uni.uploadFile({
+ url: getApiUrl('/api/knowledgeBase/add'),
+ filePath: this.practiceForm.file.path,
+ name: 'file', // 文件字段名
+ formData: formData,
+ header: tenantId ? {
+ 'X-Tenant-Id': tenantId
+ } : {},
+ timeout: 15000
+ });
+ } else {
+ // 如果没有文件,使用 uni.request 提交表单数据
+ const payload = {
+ title: this.practiceForm.title.trim(),
+ category: this.practiceForm.category?.trim() || '',
+ industry: this.practiceForm.industry?.trim() || '',
+ content: "-"
+ };
+
+ // 添加租户ID到payload
+ if (tenantId) {
+ payload.tenantId = tenantId;
+ }
+
+ const headers = {
+ "Content-Type": "application/json"
+ };
+
+ // 添加租户ID到header
+ if (tenantId) {
+ headers['X-Tenant-Id'] = tenantId;
+ }
+
+ res = await uni.request({
+ url: getApiUrl('/api/knowledgeBase/add'),
+ method: 'POST',
+ data: payload,
+ header: headers,
+ timeout: 15000
+ });
+ }
+
+ uni.hideLoading();
+
+ // 处理响应(uni.uploadFile 返回的 data 可能是字符串,需要解析)
+ let result;
+ if (this.practiceForm.file) {
+ // uni.uploadFile 返回的数据需要解析
+ try {
+ result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
+ } catch (e) {
+ result = res.data;
+ }
+ } else {
+ result = res.data;
+ }
+
+ if (res.statusCode === 200 && result && (result.success || result.code === 200)) {
+ uni.showToast({
+ title: result?.message || "提交成功",
+ icon: "success"
+ });
+ // 关闭弹出框并刷新列表
+ this.closePracticePopup();
+ this.practicePage.current = 1;
+ this.fetchPracticeList({ force: true });
+ } else {
+ uni.showToast({
+ title: result?.message || "提交失败",
+ icon: "none"
+ });
+ }
+ } catch (error) {
+ uni.hideLoading();
+ console.error("提交陪练失败:", error);
+ uni.showToast({
+ title: error?.message || "提交失败,请重试",
+ icon: "none"
+ });
+ }
}
}
}