tencentcloudbase / cloudbase-extension-cms Goto Github PK
View Code? Open in Web Editor NEW🚀 一站式云端内容管理系统 - An open source Node.js headless cms based on CloudBase
License: Other
🚀 一站式云端内容管理系统 - An open source Node.js headless cms based on CloudBase
License: Other
希望新发布的数据显示在第一条,按创建时间倒序。方便再次编辑。(目前是新发布的数据显示到最后一页。如果需要编辑,还得翻到最后一页才能进入编辑。)
例如:在内容模型管理的时候可以建立目录。可以拖动把内容模型放入不同目录下。这样方便运营的同学查看和管理。
此外内容模型的顺序希望也能通过拖拽进行排序。
// 注册用户
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,
})
"_id": "_id"
"createTime": 1602291921781
"password": "abab1234"
"roles": ["content:administrator"]
"username": "aa"
"uuid": "uuid"
有没有vue.js版?
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才可以重新编辑图片
内容设置新建或编辑栏目时,”图标设置“不好用的,没反应,即使输入了关键词,什么图标也没有,选择不了图标。
现在的数据结构是跟mysql类似的,并木有发挥出nosql的优势。
期望,数据类型支持更全面一些
枚举字段内想在已有数据中插入或排序已有数据
手动操作容易出现问题,
希望可以拖动排序。
进行数据编辑的一般为非技术人员,有的人对json格式不熟悉,使用可视化工具可以降低学习成本,并且可视化也可以提高编写速度,望支持。推荐json-editor
另外也希望支持定义json schema
现在提供的webhook用来联动外部系统很方便,但是希望能提供一个functionsHook,可以走私有网络不用鉴权直接调用云函数。
例如我们在开发环境把各种数据都准备好后想上生产环境,现在只能一个个集合自己导出,图片也是。如果能一起dump出来一个压缩包就好了。
大家好,
CloudBase CMS 作为开源项目已经有一段时间了,在开源期间我们积极响应各路开发者的疑问与反馈,持续不断打磨 CloudBase CMS,希望 CloudBase CMS 能更加完善,帮助更多开发者提升开发效率,改善开发体验。
但在庞大的开发工作量下我们深感自身能力的不足,不能很好地满足大家的需求。这时候我们深刻觉得社区力量的重要性,所以我们开启这一篇 isuue,强烈希望各路大佬们能一起为 CloudBase CMS 贡献代码、优秀的案例等,从而让 CloudBase CMS 更加强大,更加好用。
对于各位大佬们的提交,我们会保持跟进与回复,采纳后的项目将在 README 的重要位置展示贡献者的信息!
你还可以主动向 CloudBase CMS 提交 Issue 把你的项目案例放到 README 的案例展示中,提交的案例应包含以下信息:
最后,期待你的贡献~
比如有一个专门存商品分类的表,只需要管理员一次性把商品的分类录入好了,之后其他表直接关联就行了。并不需要其他用户去curd。
这样的话,可以在开始的时候由管理员录入好了数据,然后把这个商品分类表设置成隐藏,即不需要出现在左侧的菜单里面。
希望能在内容模型配置的时候可以设置这个模型中那些列在列表页面中显示,是否启用排序。默认排序方式,以及展示的优先级(显示在第几列)。
感谢提供了如此好的开源项目!
可惜我只能贡献一颗星星
如果我有三头六臂
我会给你好多星星 star star 一闪一闪亮晶晶
只有一个Webbook,监听一个集合的创建,但是删除功能也会推送到Webbook上,Webbook链接没有设置删除推送
在cms后台支持了webhook的入口,但并未给出相应的用法示例。
期望,能给出完整示例。
云存储中设置为"仅创建者及管理员可读写",在CMS中无法显示,地址用的是fileID.会提示"获取图片链接失败 STORAGE_EXCEED_AUTHORITY".请问有什么办法解决吗?
一般来说搜日期时间型都是搜范围需求来的多啊。
当数据一多的时候,顶部的信息就会被刷到最上面,从而无法看到对应的数据字段名,希望加入数据表格顶部固定
根据接口规范
后台模版 template 自定义
插件自定义,适应灵活的需求,以便达到无缝嵌入已有系统
腾讯云热心用户!
CMS重度用户来拉!
在GIT上这么说是不是显得很不专业
不过真的超级喜欢腾讯云
云开发真的是给广大个人开发者解决了大问题!
感谢腾讯云团队
2.0的功能设计已经已经非常非常贴近我们的使用了
有些功能的设计简直已经把我融化了
这个issue主要是催一下进度(我真不要脸)
第一重要的功能
*图片、文件数组支持 🏹 设计中
接下来这个也很重要
*支持复杂的对象,支持复杂数组类型,支持对象嵌套类型,JSON 🏹 设计中
请开发老大尽快将这两个设计中的功能搞定 尽快发布2.0
祝你们工作顺利
谢谢
首先感谢腾讯云开发,感谢提交了历史性更新,支持文件数组和图片数组的 无亦杨
感谢腾讯云的快速反馈以及辛苦的程序员
CMS已经投入我们的实际生产中,获得了大家的交口称赞
前端开发很快乐,不用写管理界面了;
数据整理小姐姐很开心,因为可以和开发同步修改数据,提前开始,再也不用加班了
在实际使用中,我们遇到一个新的问题,这个是我家整理数据的小姐姐强烈要求的
使用场景如下:
我们要对原始数据做修改 大概1000多条 这个是需要工作人员手工操作的,每一条都要操作
在进入列表页操作的时候, 我们设置的每页50条,从大概第十页开始编辑,假设我们编辑第485条
核对完数据以后,修改提交,会跳转到列表页第一页,这时候每页显示10条,这样很难快速找到第486条继续编辑
希望变成:
在提交以后,保留每页50条,还是留在第十页,这样在编辑完485条以后,可以紧接着编辑486条
诚恳请求大佬考虑下.感谢!
群二维码过期了,怎么入群呢
示例的体验账号和密码说多少啊
请问通过云控制台安装后能否再通过本地部署的方式更新升级呢?
不会存在重写之前已运营数据的风险吧?
参考腾讯云开发的文档,小程序云开发和腾讯云开发的环境不是互通的
现在只有管理员和运营两种权限,但完整的权限应当还包含角色权限、菜单权限。
新增图片内容时候上传完自动跳转回列表页,还没有按新建按钮确定,会是因为Webbook原因吗,没见新建成功
云函数代码
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;
};
目前我遇到一个bug,就是在2.30导出的模型文件导入到2.40后那个模型就管理不了。后来经过分析是发现2.30到2.40的模型文件发生了变化。
所以在导入模型文件的时候应该检测一下导出的模型文件版本是否兼容,不兼容则不允许导入。
有些时候字符串枚举可以胜任,
但是有时候还是希望数据库里躺着的就是数字!
Webbook新建内容后,再次点击新建内容还是记录上次的内容,点击编辑旧的Webbook没有同步显示对应的Webbook的内容
数组可不可以使用对象,或者关联其他集合
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.