文件属性字段如何扩展?

该组件仅适用于私有化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文档共享权限管控方案,既能精准的配置文档访问、编辑、共享等权限,又能实现动态调整与全程留痕,有效保障企业文档信息安全与协作效率。 方案简介 WPS文档共享权限管控方案是针对企业文档协作中权限管理难题,提供精准授权与全程可控的解决方案。通过构建多层级权限管控体系,支持按角色/岗位细分权限、动态权限调整、协作行为留痕、权限到期自动回收功能,确保文档协作数据安全,提升内部协作效率。 该方案可与企业现有组织架构无缝对接,在企业私有环境内运行,最大程度保障文档协作数据不被泄露,为企业文档管理提供全方…

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

    PDF转Word全流程解决方案

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

    最佳实践 2025年12月11日
  • 文档中心主题皮肤定制

    文档中心主题皮肤定制

    将企业主题色融入WPS365产品界面,使之与企业风格更为统一 如何为文档中心定制主题皮肤? 本定制方案仅适用于私有化WPS365版本 1. 方案概述 主题皮肤就是文档中心提供的界面颜色,下图为文档中心标准产品的主题皮肤: 出于以下需求的考虑,客户可能会需要定制个性化的主题皮肤: 实现效果 深色模式浅色模式护眼模式跟随系统模式注:以上展示的【深色】【浅色】【护眼】模式的具体颜色效果由客户自己定义,上图仅作参考示例 依赖端 文档中心PC端 依赖版本 23.0907(含)以上 依赖操作系统 支持X86…

    最佳实践 2025年12月11日
  • WPS协作产品消息审计能力助力客户应对信息安全、合规及消息追溯的挑战

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

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

    最佳实践 2025年12月11日
  • 新增自定义侧边栏菜单

    新增自定义侧边栏菜单

    企业想把文档中心上定制的新功能放在文档中心上,可以将入口放在文档中心左侧Tab栏

    最佳实践 2025年12月11日
  • AI在组织级“水土不服”?轻舟AI解法来了

    AI在组织级“水土不服”?轻舟AI解法来了

    WPS 365 轻舟AI,专为组织级打造的私有化轻量AI办公方案。

    最佳实践 2026年5月8日

发表回复

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

立即咨询 企业版试用 上门服务

请您留言

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