效果图
filechatbot.js
accessToken: '你的Coze token'
Page({
data: {
selectedFile: null,
uploading: false,
fileId: '',
fileInfo: null,
fileInfoStr: '',
errorMsg: '',
accessToken: '你的Coze token' // 请替换为实际的访问令牌
},
// 选择文件
chooseFile() {
wx.chooseMessageFile({
count: 1,
type: 'file',
extension: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'numbers', 'csv', 'jpg', 'jpeg', 'png', 'gif', 'webp', 'heic', 'heif', 'bmp', 'pcd', 'tiff'],
success: (res) => {
const file = res.tempFiles[0];
this.setData({
selectedFile: file,
errorMsg: ''
});
console.log('选择的文件:', file);
},
fail: (error) => {
this.setData({
errorMsg: '选择文件失败:' + error.errMsg
});
}
});
},
// 上传文件
async uploadFile() {
if (!this.data.selectedFile) {
this.setData({
errorMsg: '请先选择文件'
});
return;
}
this.setData({
uploading: true,
errorMsg: ''
});
wx.showLoading({
title: '上传中...',
mask: true
});
wx.uploadFile({
url: 'https://api.coze.cn/v1/files/upload',
header: {
'Authorization': `Bearer ${this.data.accessToken}`,
'content-type': 'multipart/form-data'
},
filePath: this.data.selectedFile.path,
name: 'file',
formData: { 'file': this.data.selectedFile.path },
success: (res) => {
wx.hideLoading();
this.setData({ uploading: false });
try {
const data = JSON.parse(res.data);
if (data.code === 0) {
this.setData({
fileId: data.data.id
});
console.log('文件上传成功,文件ID:', this.data.fileId);
wx.showToast({
title: '上传成功',
icon: 'success'
});
} else {
throw new Error(data.msg || '上传失败');
}
} catch (error) {
this.handleError(error, '解析响应数据失败');
}
},
fail: (err) => {
wx.hideLoading();
this.setData({
uploading: false,
errorMsg: '上传失败:' + err.errMsg
});
console.log('上传失败:', err.errMsg);
}
});
},
// 复制文件信息到剪贴板
copyFileInfo() {
if (!this.data.fileInfoStr) {
this.handleError(new Error('没有可复制的文件信息'));
return;
}
wx.setClipboardData({
data: this.data.fileInfoStr,
success: () => {
wx.showToast({
title: '已复制',
icon: 'success',
duration: 2000
});
},
fail: (error) => {
this.handleError(error, '复制失败');
}
});
},
// 查询文件信息
async retrieveFile() {
if (!this.data.fileId) {
this.setData({
errorMsg: '请先输入文件ID'
});
return;
}
wx.showLoading({
title: '查询中...',
mask: true
});
wx.request({
url: `https://api.coze.cn/v1/files/retrieve?file_id=${this.data.fileId}`,
method: 'GET',
header: {
'Authorization': `Bearer ${this.data.accessToken}`,
'Content-Type': 'application/json'
},
success: (res) => {
wx.hideLoading();
const data = res.data;
if (data.code === 0) {
const fileInfo = {
...data.data,
created_at_formatted: this.formatTimestamp(data.data.created_at),
size_formatted: this.formatFileSize(data.data.bytes)
};
this.setData({
fileInfo,
fileInfoStr: JSON.stringify(fileInfo, null, 2)
});
console.log('文件信息查询成功:', fileInfo);
} else {
this.handleError(new Error(data.msg || '查询失败'));
}
},
fail: (err) => {
wx.hideLoading();
this.setData({
errorMsg: '查询失败:' + err.errMsg
});
console.log('查询失败:', err.errMsg);
}
});
},
// 格式化时间戳
formatTimestamp(timestamp) {
const date = new Date(timestamp * 1000);
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
},
// 格式化文件大小
formatFileSize(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
},
// 统一错误处理
handleError(error, customMessage = '') {
console.error(customMessage || '操作失败', error);
const errorMessage = error.errMsg || error.message || customMessage || '操作失败';
this.setData({
errorMsg: errorMessage
});
wx.showToast({
title: errorMessage,
icon: 'none',
duration: 2000
});
}
});
filechatbot.wxml
<navigation-bar title="文件管理" back="{{false}}" color="black" background="#FFF"></navigation-bar>
<!-- 上传区域 -->
<view class="weui-panel">
<view class="weui-panel__hd">
<text class="weui-media-box__title">文件上传</text>
<text class="weui-media-box__desc">支持文档和图片格式,最大 512MB</text>
</view>
<view class="weui-panel__bd">
<view class="weui-uploader__input-box" wx:if="{{!selectedFile}}" bindtap="chooseFile">
<view class="upload-placeholder">
<image class="upload-icon" src="/images/upload.png" mode="aspectFit"></image>
<text class="upload-text">点击选择文件</text>
<text class="upload-hint">支持文档和图片格式</text>
</view>
</view>
<view class="file-info" wx:else>
<view class="weui-media-box weui-media-box_appmsg">
<view class="weui-media-box__hd">
<image class="file-icon" src="/images/file.png" mode="aspectFit"></image>
</view>
<view class="weui-media-box__bd">
<text class="weui-media-box__title">{{selectedFile.name}}</text>
<text class="weui-media-box__desc">{{formatFileSize(selectedFile.size)}}</text>
</view>
<view class="weui-media-box__ft">
<button class="weui-btn weui-btn_mini weui-btn_primary"
bindtap="uploadFile"
disabled="{{uploading}}">
{{uploading ? '上传中...' : '上传'}}
</button>
</view>
</view>
</view>
</view>
</view>
<!-- 文件查询区域 -->
<view class="weui-panel" style="margin-top: 20px;">
<view class="weui-panel__hd">
<text class="weui-media-box__title">文件查询</text>
</view>
<view class="weui-panel__bd">
<view class="weui-cell">
<view class="weui-cell__bd">
<input class="weui-input"
placeholder="请输入文件ID"
bindinput="onFileIdInput"
value="{{fileId}}" />
</view>
<view class="weui-cell__ft">
<button class="weui-btn weui-btn_mini weui-btn_primary"
bindtap="retrieveFile"
disabled="{{!fileId}}">
查询
</button>
</view>
</view>
</view>
</view>
<!-- 文件信息展示 -->
<view class="weui-panel" wx:if="{{fileInfo}}">
<view class="weui-panel__hd">
<text class="weui-media-box__title">查询结果</text>
<button class="weui-btn weui-btn_mini weui-btn_default" bindtap="copyFileInfo">
复制信息
</button>
</view>
<view class="weui-panel__bd">
<view class="weui-media-box weui-media-box_text">
<view class="result-item">
<text class="weui-media-box__title">文件ID</text>
<text class="weui-media-box__desc" user-select>{{fileInfo.id}}</text>
</view>
<view class="result-item">
<text class="weui-media-box__title">文件名称</text>
<text class="weui-media-box__desc">{{fileInfo.file_name}}</text>
</view>
<view class="result-item">
<text class="weui-media-box__title">文件大小</text>
<text class="weui-media-box__desc">{{fileInfo.size_formatted}}</text>
</view>
<view class="result-item">
<text class="weui-media-box__title">上传时间</text>
<text class="weui-media-box__desc">{{fileInfo.created_at_formatted}}</text>
</view>
</view>
<view class="json-view">
<text user-select class="json-content">{{fileInfoStr}}</text>
</view>
</view>
</view>
<!-- 错误提示 -->
<view wx:if="{{errorMsg}}" class="weui-toptips weui-toptips_warn">
<text>{{errorMsg}}</text>
</view>
filechatbot.wxss
.upload-icon {
width: 48px;
height: 48px;
}
.file-icon {
width: 24px;
height: 24px;
margin-right: 8px;
}
.error-toast {
position: fixed;
top: 88px;
left: 50%;
transform: translateX(-50%);
background: rgba(0,0,0,0.8);
color: #fff;
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
z-index: 1000;
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
border: 2px dashed #d9d9d9;
border-radius: 4px;
background-color: #f8f8f8;
}
.upload-text {
margin-top: 10px;
font-size: 16px;
color: #666;
}
.upload-hint {
margin-top: 5px;
font-size: 12px;
color: #999;
}
.json-view {
background-color: #f8f9fa;
padding: 10px;
border-radius: 4px;
font-family: monospace;
white-space: pre-wrap;
word-break: break-all;
font-size: 12px;
width: 100%;
box-sizing: border-box;
}
使用微信 Weui
filechatbot.json
{
"usingComponents": {
"mp-dialog": "weui-miniprogram/dialog/dialog",
"navigation-bar": "/components/navigation-bar/navigation-bar",
"mp-loading": "weui-miniprogram/loading/loading",
"mp-icon": "weui-miniprogram/icon/icon"
}
}