文件属性字段如何扩展?

该组件仅适用于私有化WPS365版本

1. 方案概述

区分文件类别的信息就是文件属性,比如:.docx指文档,.xlsx指表格。

这里说的拓展文件属性指的是在文件属性后面打标签,方便后续查找和管理文件。

有哪些标签可以添加

企业可以根据自己的需求自行打标签,常用的标签有三类:

安全管控:比如标记“机密文件”,限制未经授权的人查看或编辑。

流程跟踪:比如标注“待审批”状态,提醒相关负责人处理。

协作管理:比如显示“可/不可分享”状态,避免文件外泄。

针对这种需求,我们可以使用文档中心Web端(PC端)的开放能力,定制文件属性扩展:

实现效果在.docx后,增添文件的更多属性,红色字体可根据企业需要,替换成企业的分类标签。3LAP4PY4AAQAM
支持端文档中心PC端
版本限制版本23-12b(含)以上
操作系统限制支持X86、XC

2. 使用指南

文件属性字段扩展

支持文件列表显示更多信息,如:分享状态.审批状态.安全标记等

👉能力

sdk.kdrive.myDocumentPage.fileList

👉代码示例

sdk.kdrive.myDocumentPage.fileList.onUpdate((data) => {
  const dataList = data.list.items()

  const fileList = sdk.kdrive.myDocumentPage.fileList
  const slotName = 'fileName'

  dataList.length &&
    dataList.forEach((item) => {
      const slot = fileList.fileItem(item['id'])[slotName]

      sdk.append(slot, <div style={{ color: 'red' }}>demo示例</div>, {
        key: 'test-tag',
      })
    })
})

👉效果截图

3LAP4PY4AAQAM

文件属性如何写到元数据

  • 第一步:注册实体扩展信息

post /config/dev/v1/reg_entity_extra

  • 第二步:修改文件元数据

post /v7/dev/drives/{drive_id}/files/{file_id}/update

  • 第三步:获取文件信息

get /v7/drives/{drive_id}/files/{file_id}/meta

👉效果截图

服务端

注册实体扩展信息

type Api struct {
    domain  string
    ak      string
    sk      string
    driveId string
    FileId  string
}

var (
    api        *Api
    apiSrvOnce sync.Once
)

func NewApiSrv() *Api {
    apiSrvOnce.Do(func() {
        api = &Api{
            domain:  "http://encs-pri-cams-engine",
            ak:      config.GlobalConfig.AK,
            sk:      config.GlobalConfig.Sk,
        }
    })
    return api
}

// 使用方自定义命名空间和name
var namespace, name string = "filetransfer", "transferTag"

// 注册实体信息扩展接口
func (a *Api) RegisterEntityExt() error {
    entityExtInfo := &EntityExtReq{
        Copyable:          true,
        EntityType:        "file",
        Movable:           true,
        Name:              name,
        Namespace:         namespace,
        RecycleRestorable: true,
        VersionRestorable: true,
    }

    h, _ := json.Marshal(entityExtInfo)

    uri := "/config/dev/v1/reg_entity_extra"
    // i接口,wps4签名
    wps4Header, err := wps4DocSign.Wps4DocsSign(a.ak, a.sk, uri, "POST", h)
    if err != nil {
        log.Error("wps4DocSign.Wps4DocsSign error: ", err)
        return fmt.Errorf("wps4DocSign.Wps4DocsSign error: %s", err)
    }

    // 发送请求
    url := fmt.Sprintf("%s/i/docmini%s", a.domain, uri)
    request, err := http.NewRequest("POST", url, bytes.NewReader(h))
    if err != nil {
        log.Error("http.NewRequest error: ", err)
        return fmt.Errorf("http.NewRequest error: %s", err)
    }

    request.Header.Set("Content-Type", wps4Header.ContentType)
    request.Header.Set("Wps-Docs-Date", wps4Header.Date)
    request.Header.Set("Wps-Docs-Authorization", wps4Header.Authorization)

    client := &http.Client{}

    resp, err := client.Do(request)
    if err != nil {
        log.Error("client.Do error: ", err)
        return fmt.Errorf("client.Do error: %s", err)
    }
    if resp != nil && resp.Body != nil {
        defer resp.Body.Close()
    }

    var respBody []byte

    if resp.StatusCode != http.StatusOK {
        if resp.Body != nil {
            respBody, _ = io.ReadAll(resp.Body)
            log.Error("RegisterEntityExt error: ", string(respBody), resp.StatusCode)
            return fmt.Errorf("RegisterEntityExt error: %s", string(respBody))
        } else {
            log.Error("RegisterEntityExt error: ", resp.StatusCode)
            return fmt.Errorf("RegisterEntityExt error: %d", resp.StatusCode)
        }
    }

    respBody, _ = io.ReadAll(resp.Body)

    respInfo := &BaseResp{}
    err = json.Unmarshal(respBody, respInfo)
    if err != nil {
        log.Error("json.Unmarshal error: ", err)
        return fmt.Errorf("json.Unmarshal error: %s", err)
    }
    log.Info("RegisterEntityExt success: ", respInfo)
    return nil
}

修改文件元数据

// 修改文件元数据接口
func (a *Api) ModifyFileMeta(driveId, fileId string) error {
    fileMetaReq := &ModifyFileMetaReq{
        ExtAttr: ExtAttr{
            Name:  name,
            Value: "test",
        },
    }

    h, _ := json.Marshal(fileMetaReq)
    uri := fmt.Sprintf("/v7/dev/drives/%s/files/%s/update", driveId, fileId)
    // i接口,wps4签名
    wps4Header, err := wps4DocSign.Wps4DocsSign(a.ak, a.sk, uri, "POST", h)
    if err != nil {
        log.Error("wps4DocSign.Wps4DocsSign error: ", err)
        return fmt.Errorf("wps4DocSign.Wps4DocsSign error: %s", err)
    }

    // 发送请求
    url := fmt.Sprintf("%s/i/docmini%s", a.domain, uri)
    request, err := http.NewRequest("POST", url, bytes.NewReader(h))
    if err != nil {
        log.Error("http.NewRequest error: ", err)
        return fmt.Errorf("http.NewRequest error: %s", err)
    }

    request.Header.Set("Content-Type", wps4Header.ContentType)
    request.Header.Set("Wps-Docs-Date", wps4Header.Date)
    request.Header.Set("Wps-Docs-Authorization", wps4Header.Authorization)

    client := &http.Client{}

    resp, err := client.Do(request)
    if err != nil {
        log.Error("client.Do error: ", err)
        return fmt.Errorf("client.Do error: %s", err)
    }

    if resp != nil && resp.Body != nil {
        defer resp.Body.Close()
    }

    var respBody []byte

    if resp.StatusCode != http.StatusOK {
        if resp.Body != nil {
            respBody, _ = io.ReadAll(resp.Body)
            log.Error("ModifyFileMeta error: ", string(respBody), resp.StatusCode)
            return fmt.Errorf("ModifyFileMeta error: %s", string(respBody))
        } else {
            log.Error("ModifyFileMeta error: ", resp.StatusCode)
            return fmt.Errorf("ModifyFileMeta error: %d", resp.StatusCode)
        }
    }

    respBody, _ = io.ReadAll(resp.Body)

    respInfo := &BaseResp{}

    err = json.Unmarshal(respBody, respInfo)
    if err != nil {
        log.Error("json.Unmarshal error: ", err)
        return fmt.Errorf("json.Unmarshal error: %s", err)
    }

    log.Info("ModifyFileMeta success: ", respInfo)
    return nil
}

获取文件信息

// 获取文件信息接口
func (a *Api) GetFileInfo(driveId, fileId string) (*FileInfoResp, error) {
    uri := fmt.Sprintf("/open/v7/drives/%s/files/%s/meta?with_permission=true&with_ext_attrs=true", driveId, fileId)
    wps4Header, err := wps4DocSign.Wps4DocsSign(a.ak, a.sk, uri, "GET", nil)
    if err != nil {
        log.Error("wps4DocSign.Wps4DocsSign error: ", err)
        return nil, fmt.Errorf("wps4DocSign.Wps4DocsSign error: %s", err)
    }

    // 发送请求
    url := fmt.Sprintf("%s/i/docmini%s", a.domain, uri)
    request, err := http.NewRequest("GET", url, nil)
    if err != nil {
        log.Error("http.NewRequest error: ", err)
        return nil, fmt.Errorf("http.NewRequest error: %s", err)
    }

    request.Header.Set("Content-Type", wps4Header.ContentType)
    request.Header.Set("Wps-Docs-Date", wps4Header.Date)
    request.Header.Set("Wps-Docs-Authorization", wps4Header.Authorization)

    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
    }

    resp, err := client.Do(request)

    if err != nil {
        log.Error("client.Do error: ", err)
        return nil, fmt.Errorf("client.Do error: %s", err)
    }

    if resp != nil && resp.Body != nil {
        defer resp.Body.Close()
    }

    var respBody []byte

    if resp.StatusCode != http.StatusOK {
        if resp.Body != nil {
            respBody, _ = io.ReadAll(resp.Body)
            log.Error("GetFileInfo error: ", string(respBody), resp.StatusCode)
            return nil, fmt.Errorf("GetFileInfo error: %s", string(respBody))
        } else {
            log.Error("GetFileInfo error: ", resp.StatusCode)
            return nil, fmt.Errorf("GetFileInfo error: %d", resp.StatusCode)
        }
    }

    respBody, _ = io.ReadAll(resp.Body)

    log.Info("GetFileInfo success: ", string(respBody))

    fileInfoResp := &FileInfoResp{}

    err = json.Unmarshal(respBody, fileInfoResp)

    if err != nil {
        log.Error("json.Unmarshal error: ", err)
        return nil, fmt.Errorf("json.Unmarshal error: %s", err)
    }

    return fileInfoResp, nil
}

结果

DX5ZWAY5AAAGO

前端

sdk.kdrive.myDocumentPage.fileList.onUpdate(async data => {
  let tag = "transferTag"
  let isRenderTag: boolean = false  // 保证满足条件再进行tag渲染
  let driveId = '4'
  let fileId = '286034168381441'
  try {
    let { data: fileInfo } = await request.get(
      `/cloud/file/u/v1/drives/${driveId}/files/${fileId}`
    )
    console.log('ecis: index start2', fileInfo)

    const extraAttrs = JSON.parse(fileInfo.data.extra)
    if (extraAttrs && extraAttrs[tag]) {
      isRenderTag = true
    }
  } catch (error) {
    console.error('render tag error:', error)
  }

  const dataList = data.list.items()
  const fileList = sdk.kdrive.myDocumentPage.fileList
  const slotName = 'fileName'

  dataList.length && isRenderTag &&
    dataList.forEach(item => {
      const slot = fileList.fileItem(item['id'])[slotName]
      sdk.append(slot, <div style={{ color: 'red' }}>{extraAttrs[tag]}</div>, {
        key: tag
      })
    })
})

结果

HMRGAEQ5ADAE6

相关新闻

  • WPS协作产品消息审计能力助力客户应对信息安全、合规及消息追溯的挑战

    WPS协作产品消息审计能力助力客户应对信息安全、合规及消息追溯的挑战

    为了满足数字化办公时代组织对于企业内风险消息监控的需求,WPS提供了审计授权、消息搜索、审计操作、审计设置及审计日志等几大能力,助力企业提升内部消息的安全性和合规性。 能力简介 在数字化办公时代,即时通讯(IM)工具在组织的作用越发重要,随之要面对的就是风险消息监控、敏感词过滤、日志全量留存及多维分析等诸多问题来确保企业通讯的合规性。WPS协作产品为客户提供了消息审计的相关接口和基础能力,基于相关接口和能力,客户可以通过开发实现内容识别拦截违规信息、完整记录消息内容、时间、参与方等元数据,支持分…

    最佳实践 2025年12月11日
  • 文档中心与第三方IM集成,促进高效协同办公

    文档中心与第三方IM集成,促进高效协同办公

    随着企业数字化转型的深入,企业在自研IM基础上需要补齐文档协作能力。文档中心通过集成第三方IM,为企业提供高效、安全的文档协作体验。 一、方案简介 金山办公文档中心V7集成第三方IM旨在为企业自研IM(即时通讯)系统提供文档能力的集成支持,通过文档中心V7与第三方IM的深度整合。 金山办公文档中心V7通过标准化接口与定制化开发相结合,实现IM与文档中心的无缝衔接,帮助企业构建”沟通-协作-管理”一体化平台。金山文档中心V7通过提供在线编辑、多人协同、版本管理,帮助客户减少…

    最佳实践 2025年12月11日
  • PDF转Word全流程解决方案

    PDF转Word全流程解决方案

    方案简介 基于WPS WebOffice开放平台的格式转换能力,构建企业级文档中台,实现标书协议、合同管理、档案等PDF文件的自动化转换、结构化处理与业务系统无缝集成。 WPS WebOffice格式转换服务:提供PDF→Word的精准转换能力。支持保留原PDF的字体、段落、表格、图片等元素,针对扫描件PDF,支持OCR识别,支持单次上传100+文件批量转换。 企业文档中台:作为转换服务的调度中心和数据枢纽,实现转换流程与现有业务系统的无缝对接。拥有操作日志审计,完整记录转换操作的人员、时间、文…

    最佳实践 2025年12月11日
  • 告别Excel乱崩+电话催办!WPS 365,一键搭建任务预警平台,进度可视化、协作不内耗

    告别Excel乱崩+电话催办!WPS 365,一键搭建任务预警平台,进度可视化、协作不内耗

    🚨 任务太多没人交?3张表搞定进度监控!多维表格“动态预警平台”来了! “这个月的PPT谁还没交?”“预算表收齐了吗?我得一个个打电话问……”“又要手动统计,Excel一乱全崩了!” 你是不是也经历过这些? 作为管理者,最怕的就是: ✅ 任务安排下去,杳无音信 ✅ 每次催进度,都像“打地鼠” ✅ 手动汇总数据,一不小心就出错 别急!今天教你用 多维表格 搭建一个—— 👉 任务提交进度动态监管预警平台 无需代码、零成本,三张表打通闭环,实时看谁交了、谁没交、完成率多少! 🎯 为什么你需要这个系统?…

    企业数智化转型 2026年3月1日
  • 登录密码页和访问到期页定制

    登录密码页和访问到期页定制

    针对设有密码的文件夹,企业可以定制密码登录页及访问到期页

    最佳实践 2025年12月11日
  • 应用中心增加常用应用

    应用中心增加常用应用

    出于使用便捷的考虑,企业需要将常用应用放在统一入口 如何在应用中心添加常用应用入口? 该组件仅适用于私有化WPS365版本 1. 插件概述 出于使用便捷的考虑,企业需要将常用应用放在统一入口里。 比如,企业会将自己的OA、ERP等常用应用地址放到应用中心里,变成一个能找到所需应用的快捷入口。 包含三类应用:WPS自带应用、第三方应用和企业自研应用。 针对这种需求,我们可以使用文档中心PC端的开放能力,定制应用中心入口 实现效果 企业可以将第三方应用或自研应用加入应用中心。比如:将WPS Offi…

    最佳实践 2025年12月11日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

立即咨询 立即试用 上门服务

请您留言

感谢您的关注,你可留下联系方式,我们将第一时间与您联系。