Giter Club home page Giter Club logo

cloudbase-extension-cms's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cloudbase-extension-cms's Issues

集合数据显示顺序

希望新发布的数据显示在第一条,按创建时间倒序。方便再次编辑。(目前是新发布的数据显示到最后一页。如果需要编辑,还得翻到最后一页才能进入编辑。)

希望提供整理内容模型结构的功能

例如:在内容模型管理的时候可以建立目录。可以拖动把内容模型放入不同目录下。这样方便运营的同学查看和管理。

此外内容模型的顺序希望也能通过拖拽进行排序。

注册用户存储在附表tcb-ext-cms-users中的数据不应包含明文密码字段

   // 注册用户
    const { username, password } = body
    const { UUId } = await this.userService.createUser(username, password)

    body.createTime = dateToNumber()

    return this.cloudbaseService.collection(CollectionV2.Users).add({
      ...body, // 包含了password字段
      uuid: UUId,
    })

https://github.com/TencentCloudBase/cloudbase-extension-cms/blob/master/packages/service/src/modules/user/user.controller.ts#L77

collection:
"_id": "_id"
"createTime": 1602291921781
"password": "abab1234"
"roles": ["content:administrator"]
"username": "aa"
"uuid": "uuid"

内容设置中 图标设置的弹窗显示404

packages/tcb-ext-cms-admin/package.json 依赖的 react-material-ui-icon-picker 太久没更新;
导致依赖的iconfont codepoints 路径错误;
https://github.com/DMDc0de/material-ui-icon-picker/blob/master/src/IconsStorage.js#L32

需要在 material-ui-icon-picker 中把 /src/IconsStorage.js
https://raw.githubusercontent.com/google/material-design-icons/master/iconfont/codepoints 改为
https://raw.githubusercontent.com/google/material-design-icons/v2.1.3/iconfont/codepoints

改动参考:
kuamanet/material-ui-icon-picker@master...tza17313:master

建议你们把react-material-ui-icon-picker包的内容,放在项目内单独的组件,毕竟这个包只发布过一个版本,且3年多没更新了;

cms后台管理图片数组在对应文件被删除以后无法编辑

假设某个图片数组在数据库存储如图

[
‘cloudid-1-图片1’,
‘cloudid-2-图片2’
‘cloudid-3-图片3’
]

云存储中,对应有三个文件
/
cloudid-1-图片1
cloudid-2-图片2
cloudid-3-图片3

现在假设我删除了云存储中的任意一张图片,此时数据库不变
[
‘cloudid-1-图片1’,
‘cloudid-2-图片2’
‘cloudid-3-图片3’
]

但是云存储中少了一张图,变成了两个文件
/
cloudid-2-图片2
cloudid-3-图片3

这个时候,需要加入一张新的图片 clouded-4-图片4,通过cms,怎么都编辑不成功,总是失败,只有在数据库中删除所有之前的图片,也就是将数据库中
[
‘cloudid-1-图片1’,
‘cloudid-2-图片2’
‘cloudid-3-图片3’
]
设置为空 [] 然后cms才可以重新编辑图片

提两点操作体验上的小建议

image
1、筛选条件其实大部分情况下都是固定的几个,所以检索定义能否保存下来?下次访问这个集合的时候,可以直接用。
2、「创建时间」、「更新时间」并不需要,能否可以配置它,默认不展示,或者定义模型的时候,可以配置这俩不展示。

建议增加json可视化编辑器

进行数据编辑的一般为非技术人员,有的人对json格式不熟悉,使用可视化工具可以降低学习成本,并且可视化也可以提高编写速度,望支持。推荐json-editor
另外也希望支持定义json schema

【功能建议】字段排序,option可选项,以及关联查询的问题!

一些功能建议,希望采纳~

一:字段排序
enter image description here
新加入了一个字段(前面已有N个字段),
而新加入的字段是需要排在靠前的位置!

二:字段选择项
enter image description here
一个字段内的填的东西是固定的几十个值~
所以可以整个option吗?

一些问题
还有小程序用云开发关联查询总感觉,,,,
我遇到的问题...

如何一次查询N个集合内指定的数据?

如何'优雅'的获取多集合数据?

希望提供云函数的hook

现在提供的webhook用来联动外部系统很方便,但是希望能提供一个functionsHook,可以走私有网络不用鉴权直接调用云函数。

优秀案例征集

大家好,

CloudBase CMS 作为开源项目已经有一段时间了,在开源期间我们积极响应各路开发者的疑问与反馈,持续不断打磨 CloudBase CMS,希望 CloudBase CMS 能更加完善,帮助更多开发者提升开发效率,改善开发体验。

但在庞大的开发工作量下我们深感自身能力的不足,不能很好地满足大家的需求。这时候我们深刻觉得社区力量的重要性,所以我们开启这一篇 isuue,强烈希望各路大佬们能一起为 CloudBase CMS 贡献代码、优秀的案例等,从而让 CloudBase CMS 更加强大,更加好用。

对于各位大佬们的提交,我们会保持跟进与回复,采纳后的项目将在 README 的重要位置展示贡献者的信息!

你还可以主动向 CloudBase CMS 提交 Issue 把你的项目案例放到 README 的案例展示中,提交的案例应包含以下信息:

  • name: 应用名
  • url: 应用官网地址

最后,期待你的贡献~

关于内容模型配置的一些建议

希望能在内容模型配置的时候可以设置这个模型中那些列在列表页面中显示,是否启用排序。默认排序方式,以及展示的优先级(显示在第几列)。

在此对维护者无亦杨的感谢

感谢提供了如此好的开源项目!
可惜我只能贡献一颗星星
如果我有三头六臂
我会给你好多星星 star star 一闪一闪亮晶晶

Webbook推送问题

只有一个Webbook,监听一个集合的创建,但是删除功能也会推送到Webbook上,Webbook链接没有设置删除推送

webhook的使用示例

在cms后台支持了webhook的入口,但并未给出相应的用法示例。

期望,能给出完整示例。

希望支持数据表格顶部固定

当数据一多的时候,顶部的信息就会被刷到最上面,从而无法看到对应的数据字段名,希望加入数据表格顶部固定

[Feature Request] 图片、文件数组支持 请加快呀加快呀

腾讯云热心用户!
CMS重度用户来拉!
在GIT上这么说是不是显得很不专业
不过真的超级喜欢腾讯云
云开发真的是给广大个人开发者解决了大问题!

感谢腾讯云团队

2.0的功能设计已经已经非常非常贴近我们的使用了
有些功能的设计简直已经把我融化了

这个issue主要是催一下进度(我真不要脸)

第一重要的功能

*图片、文件数组支持 🏹 设计中

接下来这个也很重要

*支持复杂的对象,支持复杂数组类型,支持对象嵌套类型,JSON 🏹 设计中

请开发老大尽快将这两个设计中的功能搞定 尽快发布2.0

祝你们工作顺利
谢谢

[feature request]有一个使用体验上不便的地方

首先感谢腾讯云开发,感谢提交了历史性更新,支持文件数组和图片数组的 无亦杨
感谢腾讯云的快速反馈以及辛苦的程序员
CMS已经投入我们的实际生产中,获得了大家的交口称赞

前端开发很快乐,不用写管理界面了;
数据整理小姐姐很开心,因为可以和开发同步修改数据,提前开始,再也不用加班了

在实际使用中,我们遇到一个新的问题,这个是我家整理数据的小姐姐强烈要求的

使用场景如下:

我们要对原始数据做修改 大概1000多条 这个是需要工作人员手工操作的,每一条都要操作

在进入列表页操作的时候, 我们设置的每页50条,从大概第十页开始编辑,假设我们编辑第485条

核对完数据以后,修改提交,会跳转到列表页第一页,这时候每页显示10条,这样很难快速找到第486条继续编辑

希望变成:

在提交以后,保留每页50条,还是留在第十页,这样在编辑完485条以后,可以紧接着编辑486条

诚恳请求大佬考虑下.感谢!

新建角色权限问题

Screen Shot 2020-12-26 at 3 56 36 PM

如图,我只希望能对《菜单》和《温馨提示》有编辑权限,结果这些编辑权限对第一栏的所有项目都会生效

内容集合新增图片

新增图片内容时候上传完自动跳转回列表页,还没有按新建按钮确定,会是因为Webbook原因吗,没见新建成功

导出数据,支持导出xlsx表格,显示关联数据,枚举数据,时间戳等对应显示数据,对隐藏字段不导出

导出数据为{collectionName}.xlsx,全量导出,支持导出xlsx表格,显示关联数据,枚举数据,时间戳等对应显示数据,对隐藏字段不导出,可以将页面params传入支持一定条件下全量导出

云函数代码

const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})
var xlsx = require('node-xlsx');

const db = cloud.database();
const MAX_LIMIT = 100;
const _ = db.command;
exports.main = async (event, context) => {
  console.log(event)
  event.queryStringParameters = event.queryStringParameters||{};
  const collection = event.collection || event.queryStringParameters.collection;

  const params = event.params || event.queryStringParameters.params || {};
  // const acceptType = ["String", "Tel", "Array", "Number", "Connect", "Boolean", "Enum", "Date", "DateTime"]; //"File","Image"
  const unacceptType = ["File", "Image"];
  const schemasRes = await db.collection("tcb-ext-cms-schemas").where({
    collectionName: collection
  }).get();
  const schemas = schemasRes.data[0];

  let connectList = [];


  const title = event.title || event.queryStringParameters.title || schemas.displayName || "数据";


  // 先取出集合记录总数


  const countRes = await db.collection(collection).where(params).count();
  const fields = schemas.fields.filter(function (schemas) {
    return unacceptType.indexOf(schemas.type) == -1 && (!schemas.isHidden);
  });
  const connectResourcenList = [];
  fields.forEach(field => {
    if (field.type == "Connect") {
      connectList.push(field);
      connectResourcenList.push(field.connectResource)
    }
  });

  const schemasListRes = await db.collection("tcb-ext-cms-schemas").where({
    _id: _.in(connectResourcenList)
  }).limit(MAX_LIMIT).get();
  const schemasList = schemasListRes.data || [];

  // console.log("fields==============================")
  console.log(schemasList)
  const total = countRes.total
  // 计算需分几次取
  const batchTimes = Math.ceil(total / MAX_LIMIT)
  // 承载所有读操作的 promise 的数组
  const tasks = []
  for (let i = 0; i < batchTimes; i++) {
    //console.log(connectList.length)
    if (connectList.length > 0) {
      let lookupList = [];
      connectList.forEach(connect => {
        const connectschemas = schemasList.filter(function (schemas) {
          return schemas._id == connect.connectResource;
        })[0];
        lookupList.push({
          from: connectschemas.collectionName,
          localField: connect.name,
          foreignField: '_id',
          as: "connect" + connect.name
        })

      });

      let aggregate = db.collection(collection).aggregate().match(params).skip(i * MAX_LIMIT).limit(MAX_LIMIT);

      for (let index = 0; index < connectList.length; index++) {
        aggregate = aggregate.lookup(lookupList[index]);

      }

      aggregate = aggregate.end();



      tasks.push(aggregate)
    } else {

      const promise = db.collection(collection).where(params).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get();
      tasks.push(promise)
    }

  }
  console.log(tasks)
  // 等待所有
  let recordRes = (await Promise.all(tasks)).reduce((acc, cur) => {

    return {
      list: (acc.list || []).concat(cur.list || []),
      data: (acc.data || []).concat(cur.data || []),
    }
  })

  let records = (recordRes.list || []).concat(recordRes.data || []) || [];
  //1.定义表格名
  let dataCVS = title + '.xlsx';
  let excelData = [];
  let row = [];
  fields.forEach(field => {
    row.push(field.displayName)
  });

  excelData.push(row);

  records.forEach(record => {
    let arr = [];
    fields.forEach(field => {
      if (!record.hasOwnProperty(field.name)) {
        arr.push("")
      } else {
        switch (field.type) {
          case "Connect":
            arr.push(join2Str(record["connect" + field.name], field.connectField))
            break;
          case "DateTime":
            arr.push(formatDateTime(record[field.name]))
            break;
          case "Date":
            arr.push(formatDate(record[field.name]))
            break;
          case "Boolean":
            arr.push(record[field.name] ? "是" : "否")
            break;
            case "Enum":
              let enumElements = field.enumElements;
              let enumElement= enumElements.find(function(item){
                return item.value = record[field.name];
              })
              
              arr.push(enumElement.label)
              break;
          default:
            arr.push(record[field.name])
            break;
        }
      }

    });
    excelData.push(arr);
  });






  //3,把数据保存到excel里
  var buffer = await xlsx.build([{
    name: title,
    data: excelData
  }]);
  //4,把excel文件保存到云存储里
  const excelFileIdRes = await cloud.uploadFile({
    cloudPath: dataCVS,
    fileContent: buffer, //excel二进制文件
  });

  return await cloud.getTempFileURL({
    fileList: [excelFileIdRes.fileID]
  }).then(function (res) {
    return res.fileList[0].tempFileURL
  })



}

function join2Str(obj, fieldName) {
  if (Object.prototype.toString.call(obj) == "[object Array]") {
    let resultArr = [];
    obj.forEach(item => {
      if (item.hasOwnProperty(fieldName))
        resultArr.push(item[fieldName])
    });
    return resultArr.join(",")
  } else {
    if (obj.hasOwnProperty(fieldName))
      return obj[fieldName]
  }
}

function formatDateTime(inputTime) {
  var date = new Date(inputTime);
  var y = date.getFullYear();
  var m = date.getMonth() + 1;
  m = m < 10 ? ('0' + m) : m;
  var d = date.getDate();
  d = d < 10 ? ('0' + d) : d;
  var h = date.getHours();
  h = h < 10 ? ('0' + h) : h;
  var minute = date.getMinutes();
  var second = date.getSeconds();
  minute = minute < 10 ? ('0' + minute) : minute;
  second = second < 10 ? ('0' + second) : second;
  return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
};

function formatDate(inputTime) {
  var date = new Date(inputTime);
  var y = date.getFullYear();
  var m = date.getMonth() + 1;
  m = m < 10 ? ('0' + m) : m;
  var d = date.getDate();
  d = d < 10 ? ('0' + d) : d;
  return y + '-' + m + '-' + d;
};

在导出的模型json文件中应该带有版本信息

目前我遇到一个bug,就是在2.30导出的模型文件导入到2.40后那个模型就管理不了。后来经过分析是发现2.30到2.40的模型文件发生了变化。

所以在导入模型文件的时候应该检测一下导出的模型文件版本是否兼容,不兼容则不允许导入。

导入多个模型文件的时候异常

目前导入模型文件的时候是可以一个个文件拖到文件上传区域(这时候下方列表会显示多个文件)
image

这样用户会误以为导入模型文件的时候支持多个文件同时导入。但是实际上只导入了一个文件。

建议要么修改为只能导入一个文件(拖第二个文件进去的时候替换掉第一个文件)

要么修改为支持拖动多个文件到文件上传列表,支持一次性导入多个文件。

Webbook编辑问题

Webbook新建内容后,再次点击新建内容还是记录上次的内容,点击编辑旧的Webbook没有同步显示对应的Webbook的内容

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.