素材联调
This commit is contained in:
@@ -117,14 +117,6 @@
|
|||||||
confirm-type="search"
|
confirm-type="search"
|
||||||
@confirm="onMaterialSearch"
|
@confirm="onMaterialSearch"
|
||||||
/>
|
/>
|
||||||
<input
|
|
||||||
class="toolbar-input"
|
|
||||||
v-model="materialQuery.category"
|
|
||||||
placeholder="知识分类"
|
|
||||||
placeholder-style="color: #b0b0b0"
|
|
||||||
confirm-type="search"
|
|
||||||
@confirm="onMaterialSearch"
|
|
||||||
/>
|
|
||||||
<input
|
<input
|
||||||
class="toolbar-input"
|
class="toolbar-input"
|
||||||
v-model="materialQuery.industry"
|
v-model="materialQuery.industry"
|
||||||
@@ -146,8 +138,7 @@
|
|||||||
<view
|
<view
|
||||||
class="service-card material-card-item"
|
class="service-card material-card-item"
|
||||||
v-for="(item, index) in materialList"
|
v-for="(item, index) in materialList"
|
||||||
:key="item.id || index"
|
:key="item.id || index">
|
||||||
@click="viewMaterialDetail(item)">
|
|
||||||
<view class="card-header">
|
<view class="card-header">
|
||||||
<view class="staff-info">
|
<view class="staff-info">
|
||||||
<view class="staff-avatar">
|
<view class="staff-avatar">
|
||||||
@@ -155,24 +146,36 @@
|
|||||||
</view>
|
</view>
|
||||||
<text class="staff-name">{{ item.title || '未命名知识' }}</text>
|
<text class="staff-name">{{ item.title || '未命名知识' }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="card-menu-trigger" @tap.stop="showContextMenu(item, index, $event)">
|
||||||
|
<uni-icons type="more-filled" size="20" color="#999"></uni-icons>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="customer-info">
|
<view class="customer-info">
|
||||||
<text class="customer-name" v-if="item.category">知识分类:{{ item.category }}</text>
|
<text class="customer-name" v-if="item.industry">所属行业: {{ item.industry }}</text>
|
||||||
<text class="customer-name" v-if="item.industry">应用行业:{{ item.industry }}</text>
|
|
||||||
<text class="customer-name" v-if="item.creator">创建人:{{ item.creator }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="customer-tags" v-if="item.status">
|
<view class="customer-tags">
|
||||||
|
<view class="tag-item tag-blue" v-if="item.content">
|
||||||
|
<text>详情: {{ getContentPreview(item.content) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="tag-item tag-orange" v-if="item.remark">
|
||||||
|
<text>备注: {{ item.remark }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 上下文菜单 -->
|
||||||
<view
|
<view
|
||||||
class="tag-item"
|
class="context-menu"
|
||||||
:class="item.status === '启用' || item.status === '已启用' ? 'tag-blue' : 'tag-orange'">
|
v-if="contextMenuVisible && contextMenuIndex === index"
|
||||||
<text>状态:{{ item.status }}</text>
|
:style="{ top: contextMenuTop + 'px', left: contextMenuLeft + 'px' }"
|
||||||
|
@tap.stop>
|
||||||
|
<view class="context-menu-item" @tap.stop="handleEditMaterial(item)">
|
||||||
|
<text>编辑</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="context-menu-item context-menu-item--danger" @tap.stop="handleDeleteMaterial(item)">
|
||||||
|
<text>删除</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="service-duration" v-if="item.createTime || item.updateTime">
|
|
||||||
<text>{{ item.updateTime ? `更新时间:${formatDateTime(item.updateTime)}` : `创建时间:${formatDateTime(item.createTime)}` }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="service-status-empty" v-if="!materialLoading && !materialList.length">
|
<view class="service-status-empty" v-if="!materialLoading && !materialList.length">
|
||||||
@@ -213,6 +216,8 @@
|
|||||||
placeholder="请输入知识分类"
|
placeholder="请输入知识分类"
|
||||||
placeholder-style="color: #9ca3af"
|
placeholder-style="color: #9ca3af"
|
||||||
maxlength="100"
|
maxlength="100"
|
||||||
|
:disabled="true"
|
||||||
|
readonly
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
@@ -228,15 +233,13 @@
|
|||||||
<view class="form-item">
|
<view class="form-item">
|
||||||
<text class="form-item__label">文件上传</text>
|
<text class="form-item__label">文件上传</text>
|
||||||
<view class="file-upload-area">
|
<view class="file-upload-area">
|
||||||
<view class="file-list" v-if="materialForm.files && materialForm.files.length > 0">
|
<view class="file-item" v-if="materialForm.file">
|
||||||
<view class="file-item" v-for="(file, index) in materialForm.files" :key="index">
|
<text class="file-name">{{ materialForm.file.name || '文件' }}</text>
|
||||||
<text class="file-name">{{ file.name || '文件' + (index + 1) }}</text>
|
<view class="file-delete" @click="removeFile">
|
||||||
<view class="file-delete" @click="removeFile(index)">
|
|
||||||
<uni-icons type="close" size="16" color="#999"></uni-icons>
|
<uni-icons type="close" size="16" color="#999"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="file-upload-btn" v-if="!materialForm.file" @click="chooseFile">
|
||||||
<view class="file-upload-btn" @click="chooseFile">
|
|
||||||
<uni-icons type="plus" size="24" color="#2A68FF"></uni-icons>
|
<uni-icons type="plus" size="24" color="#2A68FF"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -254,6 +257,85 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 编辑素材弹出框 -->
|
||||||
|
<view class="material-popup-mask" v-if="showEditMaterialPopup" @click="closeEditMaterialPopup">
|
||||||
|
</view>
|
||||||
|
<view class="material-popup" v-if="showEditMaterialPopup" @click.stop>
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="popup-title">编辑素材</text>
|
||||||
|
<view class="popup-close" @click="closeEditMaterialPopup">
|
||||||
|
<uni-icons type="close" size="20" color="#999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="popup-content" scroll-y>
|
||||||
|
<view class="form-card">
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-item__label">知识标题</text>
|
||||||
|
<input
|
||||||
|
class="form-item__input"
|
||||||
|
v-model="editMaterialForm.title"
|
||||||
|
placeholder="请输入知识标题"
|
||||||
|
placeholder-style="color: #9ca3af"
|
||||||
|
maxlength="512"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-item__label">知识分类</text>
|
||||||
|
<input
|
||||||
|
class="form-item__input"
|
||||||
|
v-model="editMaterialForm.category"
|
||||||
|
placeholder="请输入知识分类"
|
||||||
|
placeholder-style="color: #9ca3af"
|
||||||
|
maxlength="100"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-item__label">应用行业</text>
|
||||||
|
<input
|
||||||
|
class="form-item__input"
|
||||||
|
v-model="editMaterialForm.industry"
|
||||||
|
placeholder="请输入应用行业"
|
||||||
|
placeholder-style="color: #9ca3af"
|
||||||
|
maxlength="100"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-item__label">详情</text>
|
||||||
|
<textarea
|
||||||
|
class="form-item__textarea"
|
||||||
|
v-model="editMaterialForm.content"
|
||||||
|
placeholder="请输入详情内容"
|
||||||
|
placeholder-style="color: #9ca3af"
|
||||||
|
maxlength="2000"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="form-item__label">备注</text>
|
||||||
|
<input
|
||||||
|
class="form-item__input"
|
||||||
|
v-model="editMaterialForm.remark"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
placeholder-style="color: #9ca3af"
|
||||||
|
maxlength="500"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="popup-actions">
|
||||||
|
<view class="popup-btn popup-btn--cancel" @click="closeEditMaterialPopup">
|
||||||
|
<uni-icons class="popup-btn__icon" type="close" size="20" color="#2A68FF"></uni-icons>
|
||||||
|
<text class="popup-btn__text">取消</text>
|
||||||
|
</view>
|
||||||
|
<view class="popup-btn popup-btn--submit" @click="submitEditMaterial">
|
||||||
|
<uni-icons class="popup-btn__icon" type="checkmarkempty" size="20" color="#2A68FF"></uni-icons>
|
||||||
|
<text class="popup-btn__text">保存</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 上下文菜单遮罩层 -->
|
||||||
|
<view class="context-menu-mask" v-if="contextMenuVisible" @tap="closeContextMenu"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -264,6 +346,16 @@
|
|||||||
// #endif
|
// #endif
|
||||||
import { getApiUrl } from "@/common/config.js";
|
import { getApiUrl } from "@/common/config.js";
|
||||||
|
|
||||||
|
// 获取租户ID
|
||||||
|
function getTenantId() {
|
||||||
|
try {
|
||||||
|
return uni.getStorageSync('backend-tenant-id') || '';
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取 tenantId 失败:', e);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// #ifdef APP
|
// #ifdef APP
|
||||||
components: {
|
components: {
|
||||||
@@ -283,7 +375,7 @@
|
|||||||
},
|
},
|
||||||
materialQuery: {
|
materialQuery: {
|
||||||
title: '',
|
title: '',
|
||||||
category: '',
|
category: '基础知识库',
|
||||||
industry: '',
|
industry: '',
|
||||||
creator: '',
|
creator: '',
|
||||||
status: ''
|
status: ''
|
||||||
@@ -295,7 +387,22 @@
|
|||||||
category: '',
|
category: '',
|
||||||
industry: '',
|
industry: '',
|
||||||
files: []
|
files: []
|
||||||
}
|
},
|
||||||
|
// 编辑素材弹出框
|
||||||
|
showEditMaterialPopup: false,
|
||||||
|
editMaterialForm: {
|
||||||
|
id: '',
|
||||||
|
title: '',
|
||||||
|
category: '',
|
||||||
|
industry: '',
|
||||||
|
content: '',
|
||||||
|
remark: ''
|
||||||
|
},
|
||||||
|
// 上下文菜单
|
||||||
|
contextMenuVisible: false,
|
||||||
|
contextMenuIndex: -1,
|
||||||
|
contextMenuTop: 0,
|
||||||
|
contextMenuLeft: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
@@ -338,10 +445,10 @@
|
|||||||
try {
|
try {
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
current: this.materialPage.current,
|
current: this.materialPage.current,
|
||||||
size: this.materialPage.size
|
size: this.materialPage.size,
|
||||||
|
category: '基础知识库' // 默认添加知识分类参数
|
||||||
};
|
};
|
||||||
const trimmedTitle = this.materialQuery?.title?.trim();
|
const trimmedTitle = this.materialQuery?.title?.trim();
|
||||||
const trimmedCategory = this.materialQuery?.category?.trim();
|
|
||||||
const trimmedIndustry = this.materialQuery?.industry?.trim();
|
const trimmedIndustry = this.materialQuery?.industry?.trim();
|
||||||
const trimmedCreator = this.materialQuery?.creator?.trim();
|
const trimmedCreator = this.materialQuery?.creator?.trim();
|
||||||
const trimmedStatus = this.materialQuery?.status?.trim();
|
const trimmedStatus = this.materialQuery?.status?.trim();
|
||||||
@@ -349,9 +456,6 @@
|
|||||||
if (trimmedTitle) {
|
if (trimmedTitle) {
|
||||||
queryParams.title = trimmedTitle;
|
queryParams.title = trimmedTitle;
|
||||||
}
|
}
|
||||||
if (trimmedCategory) {
|
|
||||||
queryParams.category = trimmedCategory;
|
|
||||||
}
|
|
||||||
if (trimmedIndustry) {
|
if (trimmedIndustry) {
|
||||||
queryParams.industry = trimmedIndustry;
|
queryParams.industry = trimmedIndustry;
|
||||||
}
|
}
|
||||||
@@ -366,9 +470,18 @@
|
|||||||
.map(key => `${key}=${encodeURIComponent(queryParams[key])}`)
|
.map(key => `${key}=${encodeURIComponent(queryParams[key])}`)
|
||||||
.join('&');
|
.join('&');
|
||||||
const url = `${getApiUrl('/api/knowledgeBase/list')}?${queryString}`;
|
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({
|
const res = await uni.request({
|
||||||
url,
|
url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
header: headers,
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -419,20 +532,210 @@
|
|||||||
// 查看素材详情
|
// 查看素材详情
|
||||||
console.log('查看素材详情', item);
|
console.log('查看素材详情', item);
|
||||||
},
|
},
|
||||||
|
getContentPreview(content) {
|
||||||
|
if (!content) return '';
|
||||||
|
return content.length > 10 ? content.substring(0, 10) : content;
|
||||||
|
},
|
||||||
|
showContextMenu(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.contextMenuTop = top;
|
||||||
|
this.contextMenuLeft = left;
|
||||||
|
// 显示菜单
|
||||||
|
this.contextMenuIndex = index;
|
||||||
|
this.contextMenuVisible = true;
|
||||||
|
},
|
||||||
|
closeContextMenu() {
|
||||||
|
this.contextMenuVisible = false;
|
||||||
|
this.contextMenuIndex = -1;
|
||||||
|
},
|
||||||
|
handleEditMaterial(item) {
|
||||||
|
this.closeContextMenu();
|
||||||
|
// 填充编辑表单
|
||||||
|
this.editMaterialForm = {
|
||||||
|
id: item.id,
|
||||||
|
title: item.title || '',
|
||||||
|
category: item.category || '',
|
||||||
|
industry: item.industry || '',
|
||||||
|
content: item.content || '',
|
||||||
|
remark: item.remark || ''
|
||||||
|
};
|
||||||
|
this.showEditMaterialPopup = true;
|
||||||
|
},
|
||||||
|
closeEditMaterialPopup() {
|
||||||
|
this.showEditMaterialPopup = false;
|
||||||
|
this.editMaterialForm = {
|
||||||
|
id: '',
|
||||||
|
title: '',
|
||||||
|
category: '',
|
||||||
|
industry: '',
|
||||||
|
content: '',
|
||||||
|
remark: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async submitEditMaterial() {
|
||||||
|
// 表单验证
|
||||||
|
if (!this.editMaterialForm.title || !this.editMaterialForm.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.editMaterialForm.tenantId) {
|
||||||
|
this.editMaterialForm.tenantId = tenantId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await uni.request({
|
||||||
|
url: getApiUrl('/api/knowledgeBase/update'),
|
||||||
|
method: 'PUT',
|
||||||
|
data: this.editMaterialForm,
|
||||||
|
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.closeEditMaterialPopup();
|
||||||
|
this.materialPage.current = 1;
|
||||||
|
this.fetchMaterialList({ 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"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleDeleteMaterial(item) {
|
||||||
|
this.closeContextMenu();
|
||||||
|
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.materialPage.current = 1;
|
||||||
|
this.fetchMaterialList({ 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"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
// 添加素材相关方法
|
// 添加素材相关方法
|
||||||
showAddMaterial() {
|
showAddMaterial() {
|
||||||
this.showMaterialPopup = true;
|
this.showMaterialPopup = true;
|
||||||
this.materialForm = {
|
this.materialForm = {
|
||||||
title: '',
|
title: '',
|
||||||
category: '',
|
category: '基础知识库', // 固定值,不可修改
|
||||||
industry: '',
|
industry: '汽车销售', // 默认值
|
||||||
files: []
|
file: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
closeMaterialPopup() {
|
closeMaterialPopup() {
|
||||||
this.showMaterialPopup = false;
|
this.showMaterialPopup = false;
|
||||||
},
|
},
|
||||||
chooseFile() {
|
chooseFile() {
|
||||||
|
// 限制只能上传一个文件
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
// H5平台使用chooseFile
|
// H5平台使用chooseFile
|
||||||
uni.chooseFile({
|
uni.chooseFile({
|
||||||
@@ -441,11 +744,12 @@
|
|||||||
const tempFiles = res.tempFiles || [];
|
const tempFiles = res.tempFiles || [];
|
||||||
if (tempFiles.length > 0) {
|
if (tempFiles.length > 0) {
|
||||||
const file = tempFiles[0];
|
const file = tempFiles[0];
|
||||||
this.materialForm.files.push({
|
// 替换文件,而不是添加
|
||||||
|
this.materialForm.file = {
|
||||||
name: file.name || '文件',
|
name: file.name || '文件',
|
||||||
path: file.path || file.url,
|
path: file.path || file.url,
|
||||||
size: file.size
|
size: file.size
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
@@ -465,11 +769,12 @@
|
|||||||
const tempFiles = res.tempFiles || [];
|
const tempFiles = res.tempFiles || [];
|
||||||
if (tempFiles.length > 0) {
|
if (tempFiles.length > 0) {
|
||||||
const file = tempFiles[0];
|
const file = tempFiles[0];
|
||||||
this.materialForm.files.push({
|
// 替换文件,而不是添加
|
||||||
|
this.materialForm.file = {
|
||||||
name: file.name || '图片',
|
name: file.name || '图片',
|
||||||
path: file.path,
|
path: file.path,
|
||||||
size: file.size
|
size: file.size
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
@@ -482,8 +787,9 @@
|
|||||||
});
|
});
|
||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
removeFile(index) {
|
removeFile() {
|
||||||
this.materialForm.files.splice(index, 1);
|
// 清空文件
|
||||||
|
this.materialForm.file = null;
|
||||||
},
|
},
|
||||||
async submitMaterial() {
|
async submitMaterial() {
|
||||||
// 表单验证
|
// 表单验证
|
||||||
@@ -500,67 +806,88 @@
|
|||||||
title: "提交中..."
|
title: "提交中..."
|
||||||
});
|
});
|
||||||
|
|
||||||
// 先上传文件(如果有)
|
// 获取租户ID
|
||||||
let fileUrls = [];
|
const tenantId = getTenantId();
|
||||||
if (this.materialForm.files && this.materialForm.files.length > 0) {
|
|
||||||
for (let file of this.materialForm.files) {
|
let res;
|
||||||
try {
|
|
||||||
// 上传文件到后端
|
// 如果有文件,使用 uni.uploadFile 同时上传文件和其他表单数据
|
||||||
const uploadRes = await uni.uploadFile({
|
if (this.materialForm.file) {
|
||||||
url: getApiUrl('/api/knowledgeBase/upload'),
|
// 使用 uni.uploadFile 将文件和其他字段一起提交
|
||||||
filePath: file.path,
|
const formData = {
|
||||||
name: 'file',
|
// 其他表单字段
|
||||||
formData: {
|
'title': this.materialForm.title.trim(),
|
||||||
'name': file.name || 'file'
|
'category': this.materialForm.category?.trim() || '',
|
||||||
|
'industry': this.materialForm.industry?.trim() || '',
|
||||||
|
'content': '-',
|
||||||
|
'fileName': this.materialForm.file.name || 'file' // 文件名
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加租户ID到formData
|
||||||
|
if (tenantId) {
|
||||||
|
formData['tenantId'] = tenantId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = await uni.uploadFile({
|
||||||
|
url: getApiUrl('/api/knowledgeBase/add'),
|
||||||
|
filePath: this.materialForm.file.path,
|
||||||
|
name: 'file', // 文件字段名
|
||||||
|
formData: formData,
|
||||||
|
header: tenantId ? {
|
||||||
|
'X-Tenant-Id': tenantId
|
||||||
|
} : {},
|
||||||
|
timeout: 15000
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
if (uploadRes.statusCode === 200) {
|
// 如果没有文件,使用 uni.request 提交表单数据
|
||||||
let result;
|
|
||||||
try {
|
|
||||||
result = typeof uploadRes.data === 'string' ? JSON.parse(uploadRes.data) : uploadRes.data;
|
|
||||||
} catch (e) {
|
|
||||||
result = uploadRes.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result && (result.success || result.code === 200)) {
|
|
||||||
const url = result.data?.url || result.data || result.url;
|
|
||||||
if (url) {
|
|
||||||
fileUrls.push(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (uploadError) {
|
|
||||||
console.error('文件上传失败:', uploadError);
|
|
||||||
// 继续处理其他文件,不中断整个流程
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建提交数据
|
|
||||||
const payload = {
|
const payload = {
|
||||||
title: this.materialForm.title.trim(),
|
title: this.materialForm.title.trim(),
|
||||||
category: this.materialForm.category?.trim() || '',
|
category: this.materialForm.category?.trim() || '',
|
||||||
industry: this.materialForm.industry?.trim() || '',
|
industry: this.materialForm.industry?.trim() || '',
|
||||||
fileUrls: fileUrls.length > 0 ? fileUrls : undefined
|
content: "-"
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交到后端
|
// 添加租户ID到payload
|
||||||
const res = await uni.request({
|
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'),
|
url: getApiUrl('/api/knowledgeBase/add'),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: payload,
|
data: payload,
|
||||||
header: {
|
header: headers,
|
||||||
"Content-Type": "application/json"
|
|
||||||
},
|
|
||||||
timeout: 15000
|
timeout: 15000
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
|
|
||||||
if (res.statusCode === 200 && res.data && (res.data.success || res.data.code === 200)) {
|
// 处理响应(uni.uploadFile 返回的 data 可能是字符串,需要解析)
|
||||||
|
let result;
|
||||||
|
if (this.materialForm.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({
|
uni.showToast({
|
||||||
title: res.data?.message || "提交成功",
|
title: result?.message || "提交成功",
|
||||||
icon: "success"
|
icon: "success"
|
||||||
});
|
});
|
||||||
// 关闭弹出框并刷新列表
|
// 关闭弹出框并刷新列表
|
||||||
@@ -569,7 +896,7 @@
|
|||||||
this.fetchMaterialList({ force: true });
|
this.fetchMaterialList({ force: true });
|
||||||
} else {
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: res.data?.message || "提交失败",
|
title: result?.message || "提交失败",
|
||||||
icon: "none"
|
icon: "none"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -577,7 +904,7 @@
|
|||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
console.error("提交素材失败:", error);
|
console.error("提交素材失败:", error);
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: "提交失败,请重试",
|
title: error?.message || "提交失败,请重试",
|
||||||
icon: "none"
|
icon: "none"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -713,7 +1040,7 @@
|
|||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
color: #666;
|
color: #666;
|
||||||
margin-right: 16rpx;
|
margin-right: 16rpx;
|
||||||
width: 100%;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-input {
|
.toolbar-input {
|
||||||
@@ -771,6 +1098,53 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-menu-trigger {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu {
|
||||||
|
position: fixed;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 1001;
|
||||||
|
min-width: 160rpx;
|
||||||
|
padding: 8rpx 0;
|
||||||
|
max-width: 200rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item {
|
||||||
|
padding: 24rpx 32rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item:active {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item--danger {
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.staff-info {
|
.staff-info {
|
||||||
@@ -982,6 +1356,26 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 只读输入框样式 */
|
||||||
|
.form-item__input[disabled],
|
||||||
|
.form-item__input[readonly] {
|
||||||
|
background-color: #f3f4f6;
|
||||||
|
color: #6b7280;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item__textarea {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 200rpx;
|
||||||
|
background-color: #f9fafb;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 24rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
.file-upload-area {
|
.file-upload-area {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -989,10 +1383,6 @@
|
|||||||
gap: 12rpx;
|
gap: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-list {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-item {
|
.file-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user