本文将介绍如何通过数据模型对社区团购进行管理及 APIs 的实现。
操作步骤
步骤1: 创建数据模型应用
1. 单击左侧菜单数据源按钮 > 单击数据模型列表右侧的 + 号 > 录入数据源名称和标识,单击创建。
在这里我们创建两个数据模型团购商品和团购订单。
![](https://qcloudimg.tencent-cloud.cn/image/document/5b72d0f723e7f0723f5a4dc1bccf842a.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/5b72d0f723e7f0723f5a4dc1bccf842a.png)
2. 进入创建后的数据模型单击编辑,单击添加字段,录入字段信息。
![](https://qcloudimg.tencent-cloud.cn/image/document/4bcc4a65daebcaa2dd023ba10f1ba56b.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/4bcc4a65daebcaa2dd023ba10f1ba56b.png)
按照概述中数据源设计,依次完成数据源创建和字段的添加。
团购订单:
![](https://qcloudimg.tencent-cloud.cn/image/document/1d08a84190dfc245fe839b340ea4b1b5.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/1d08a84190dfc245fe839b340ea4b1b5.png)
团购商品:
![](https://qcloudimg.tencent-cloud.cn/image/document/1f45589692cc73ce23229fb1ebf847f2.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/1f45589692cc73ce23229fb1ebf847f2.png)
步骤2: 创建数据模型应用
1. 进入应用开发 > 应用页面,单击新建应用 > 新建模型应用。
![](https://qcloudimg.tencent-cloud.cn/image/document/b26dd6c918e4feb68f5c53f87a6007b7.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/b26dd6c918e4feb68f5c53f87a6007b7.png)
2. 单击后会自动跳转到快速开始页面,选择对应数据源创建页面。
![](https://qcloudimg.tencent-cloud.cn/image/document/77f19af698c1c6c81973884daa15e17d.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/77f19af698c1c6c81973884daa15e17d.png)
3. 后台用于业务人员使用,这里开发人员可以根据业务诉求,选择相应展示的字段,对页面内容进行相应调整。因为我们的模板功能相对聚焦,完成导航菜单配置、发布数据源等相关操作,即可选择发布体验版进行测试。
![](https://qcloudimg.tencent-cloud.cn/image/document/6318c7ba0cfef65239fb95ac863a4ea7.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/6318c7ba0cfef65239fb95ac863a4ea7.png)
发布成功后,出现二维码和链接。
![](https://qcloudimg.tencent-cloud.cn/image/document/93dfe6f36117de0b7c0e5b88d55a29de.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/93dfe6f36117de0b7c0e5b88d55a29de.png)
我们可以单击访问企业工作台进入后台页面,进行订单与商品的查看与管理。
步骤3:增加 APIs
1. 进入 APIs > 单击新建 APIs。
![](https://qcloudimg.tencent-cloud.cn/image/document/e8e9c02c8b59fca39541bab59f539e52.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/e8e9c02c8b59fca39541bab59f539e52.png)
2. 选择云开发云函数。
![](https://qcloudimg.tencent-cloud.cn/image/document/9a8a1c6e51c38eb70864ab428797938f.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/9a8a1c6e51c38eb70864ab428797938f.png)
3. 填写名称以及标识后进行创建。
![](https://qcloudimg.tencent-cloud.cn/image/document/53da137e48ea78e2c2e0fdd3bdf08781.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/53da137e48ea78e2c2e0fdd3bdf08781.png)
4. 进入 APIs 单击编辑。
![](https://qcloudimg.tencent-cloud.cn/image/document/fc26e9f8343516dae29372aaf0919c1e.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/fc26e9f8343516dae29372aaf0919c1e.png)
5. 单击添加方法。
![](https://qcloudimg.tencent-cloud.cn/image/document/6ffdfc023f010da62bba54ed6b0225d9.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/6ffdfc023f010da62bba54ed6b0225d9.png)
6. 填写名称标识后选择自定义代码进行填写,完成后单击保存。
![](https://qcloudimg.tencent-cloud.cn/image/document/967f4f0583bfb6403986cee5baf64638.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/967f4f0583bfb6403986cee5baf64638.png)
7. 方法列表:
7.1 获取下载地址。
module.exports = async function (params, context) {// 这里是方法入参console.log(params);const orders = await context.callConnector({name: "yqfktg_d6c4wws",methodName: "getOrders",params: {groupId: params.groupId,noOpenId: true}});const csvMap = [{ key: 'address', title: '团购人地址' },{ key: 'contact', title: '团购人姓名' },{ title: '总金额(元)', format: (x) => x.commodityList.reduce((amount, item)=> {amount += item.number * item.pricereturn amount}, 0)},{ key: 'phone', title: '团购人手机号', nested: 'group', format: (x) => `+86 ${x}` },{ key: 'title', title: '团购名称', nested: 'group' },{ key: 'name', nested: 'commodityList', title: '商品名称' },{ key: 'price',nested: 'commodityList', title: '商品价格(元)' },{ key: 'number',nested: 'commodityList', title: '购买数量' },{ nested: 'commodityList', title: '单位', key: 'unit' },{ nested: 'commodityList', title: '总价(元)',format: (item) => (item.price * item.number).toFixed(2) },{ title: '团购时间', nested: 'group', key: 'expireTime',format: (x) => { const d = new Date(x); return `${d.toLocaleDateString()} ${d.toLocaleTimeString()}` } },{ key: 'phone', title: '团长电话', nested: 'group',format: (x) => `+86 ${x}` },]const csvData = orders.records.reduce((csv, order) => {const rows = []order.commodityList.forEach(item => {const row = []csvMap.forEach(x => {// 商品信息let valif(x.nested) {if(x.nested === 'commodityList') {if(!x.key) {val = item}else {val = item[x.key] || '';}} else {if(x.key) {val = order[x.nested][x.key] || '';}else {val = order[x.nested]}}if(x.format) {val = x.format(val)}}else {// 订单相关的信息重复写到单元格中val = order[x.key] || ''if(x.format) {val = x.format(order)}}row.push(val)})rows.push(row);})csv = csv.concat(rows)return csv}, [csvMap.map(x => x.title)])let csv = csvData.map(row => row.join(',')).join('\\n')// console.log('csv:', csv)const fileContent = Buffer.from(csv)const date = new Date()const cloudPath = `groupbuy/${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}/${params.groupId}.csv`console.log(cloudPath)const updateRes = await context.app.uploadFile({cloudPath,fileContent})const result = await updateRes;// 这里返回数据,和出参结构映射return result;};
8. 获取订单列表。
module.exports = async function (params, context) {// 这里是方法入参// 根据团购维度,团长查自己的团下有多少订单,无需传openId,用noOpenId标志位来控制是否以openId作为筛选条件const noOpenId = params.noOpenIdconst p = {where: noOpenId ? [] : [{ key: 'openId', rel: 'eq', val: params.openId }],pageSize: 1000,orderBy: 'updatedAt',orderType: 'desc'}if(params.groupId) {p.where.push({ key: 'groupId', rel: 'eq', val: params.groupId })}if(params.orderId) {p.where.push({ key: '_id', rel: 'eq', val: params.orderId })}if(params.status) {p.where.push({ key: 'status', rel: 'eq', val: params.status })}const orders = await context.callModel({name: "GBuyOrder_igd1rl0",methodName: "wedaGetRecords",params: p})if(!params.isSkipGroupInfo) {// 查询关联的商品信息const groups = await Promise.all(orders.records.map(item => item.groupId).filter((gid, index, self) => self.indexOf(gid) === index).map(groupId => context.callModel({name: "GBuyCommodit_hg68ber",methodName: "wedaGetItem",params: {_id: groupId}})))// 合并商品和订单信息orders.records.forEach(item => {const group = groups.find(x => x._id === item.groupId) || {commodityList: []}item.commodityList.forEach(x => {Object.assign(x, group.commodityList.find(y => x.commodityId === y.commodityId))})item.group = group})}// 这里返回数据,和出参结构映射return orders;};
9. 团购摘要。
module.exports = async function (params, context) {// const response = await context.callConnector({// name: "yqfktg_d6c4wws",// methodName: "getOrders",// params: {// // 这里注释掉openId 是因为这样团长只能查询出来自己下单的数据,不能查询出来其他用户下单的数据// // openId: params.openId,// groupId: params.groupId// }// });// 判断鉴权 如果不是自己的 团购 就直接返回空const res = await context.callModel({name: "GBuyCommodit_hg68ber",methodName: "wedaGetItem",params: {// _id: params.groupId,where: [{key: 'openId',rel: 'eq',val: params.openId},{key: '_id',rel: 'eq',val: params.groupId}]}})// 如果查不到 就说明没权限 res为空对象{}if(!res._id) {return null}const response = await context.callConnector({name: "yqfktg_d6c4wws",methodName: "getOrders",params: {groupId: params.groupId,noOpenId: true}})const result = response.records.reduce((r, item) => {r.orderNumber++if(item.status === 1) {r.pendingNumber++}else if(item.status === 2) {r.receivedNumber++}r.amount = item.commodityList.reduce((amount, c) => {// 计算结果要保留2位有效小数return amount + Math.ceil(c.number * c.price * 100) / 100}, r.amount)return r;}, {amount: 0,orderNumber: 0,receivedNumber: 0,pendingNumber: 0});// 这里返回数据,和出参结构映射result.amount = Math.ceil(result.amount * 100) / 100return result;};
10. 我发起的团购。
module.exports = async function (params, context) {// 这里是方法入参const where = [{ key: "openId", rel: "eq", val: params.openId },];if(params.status) {where.push({ key: 'status', rel: 'eq', val: params.status })}const response = await context.callModel({name: "GBuyCommodit_hg68ber",methodName: "wedaGetRecords",params: {where,orderBy: 'updatedAt',orderType: 'desc'}});await Promise.all(response.records.map(x => context.callConnector({name: "yqfktg_d6c4wws",methodName: "getOrders",params: {// openId: params.openId,noOpenId: true,groupId: x._id,isSkipGroupInfo: true}}).then(ordersRes => {x.orders = ordersRes.records})))// 这里返回数据,和出参结构映射return response;};
11. 团购数据鉴权
module.exports = async function (params, context) {const res = await context.callModel({name: "GBuyCommodit_hg68ber",methodName: "wedaGetItem",params: {// _id: params.groupId,where: [{key: 'openId',rel: 'eq',val: params.openId},{key: '_id',rel: 'eq',val: params.groupId}]}})// 如果查不到 就说明没权限 res为空对象{}// 有权限返回true,没权限返回falsereturn {result: !!res._id}};