[6][Coze API][小程序] 上传 + 查询 文件
评论区

[6][Coze API][小程序] 上传 + 查询 文件

茉卷
茉卷
2025-03-16
扣子专业版扣子
大数据研发治理套件 DataLeap
了解详情 
一站式数据中台套件

效果图

picture.image

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"
      }
  }
0
0
0
0
关于作者
相关资源
CV 技术在视频创作中的应用
本次演讲将介绍在拍摄、编辑等场景,我们如何利用 AI 技术赋能创作者;以及基于这些场景,字节跳动积累的领先技术能力。
相关产品
大数据研发治理套件 DataLeap
一站式数据中台套件
了解详情 
推荐
云数据库 MySQL 版
基于云平台的即开即用、稳定可靠、灵活弹性、易于使用的关系型数据库服务
了解详情 
文档数据库 MongoDB 版
开箱即用、稳定可靠、灵活弹性的云数据库服务,完全兼容原生 MongoDB
了解详情 
评论
未登录
看完啦,登录分享一下感受吧~
正在加载中...