index.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. const fs = require('fs')
  2. const path = require('path')
  3. const TE = require('./lib/art-template.js');
  4. // 标准语法的界定符规则
  5. TE.defaults.openTag = '{@'
  6. TE.defaults.closeTag = '@}'
  7. const success = {
  8. success: true
  9. }
  10. const fail = {
  11. success: false
  12. }
  13. async function translateTCB(_fileList = []) {
  14. if (!_fileList.length) return _fileList
  15. // 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回
  16. const {
  17. fileList
  18. } = await uniCloud.getTempFileURL({
  19. fileList: _fileList
  20. });
  21. return fileList.map((item, index) => item.tempFileURL ? item.tempFileURL : _fileList[index])
  22. }
  23. function hasValue(value) {
  24. if (typeof value !== 'object') return !!value
  25. if (value instanceof Array) return !!value.length
  26. return !!(value && Object.keys(value).length)
  27. }
  28. module.exports = async function(id) {
  29. if (!id) {
  30. return {
  31. ...fail,
  32. code: -1,
  33. errMsg: 'id required'
  34. };
  35. }
  36. // 根据sitemap配置加载页面模板,例如列表页,详情页
  37. let templatePage = fs.readFileSync(path.resolve(__dirname, './template.html'), 'utf8');
  38. if (!templatePage) {
  39. return {
  40. ...fail,
  41. code: -2,
  42. errMsg: 'page template no found'
  43. };
  44. }
  45. const db = uniCloud.database()
  46. let dbPublishList
  47. try {
  48. dbPublishList = db.collection('opendb-app-list')
  49. } catch (e) {}
  50. if (!dbPublishList) return fail;
  51. const record = await dbPublishList.where({
  52. _id: id
  53. }).get({
  54. getOne: true
  55. })
  56. if (record && record.data && record.data.length) {
  57. const appInfo = record.data[0]
  58. const defaultOptions = {
  59. hasApp: false,
  60. hasMP: false,
  61. hasH5: false,
  62. hasQuickApp: false
  63. }
  64. defaultOptions.mpNames = {
  65. 'mp_weixin': '微信',
  66. 'mp_alipay': '支付宝',
  67. 'mp_baidu': '百度',
  68. 'mp_toutiao': '字节',
  69. 'mp_qq': 'QQ',
  70. 'mp_dingtalk': '钉钉',
  71. 'mp_kuaishou': '快手',
  72. 'mp_lark': '飞书',
  73. 'mp_jd': '京东'
  74. }
  75. const imageList = [];
  76. ['app_android'].forEach(key => {
  77. if (!hasValue(appInfo[key])) return
  78. imageList.push({
  79. key,
  80. urlKey: 'url',
  81. url: appInfo[key].url
  82. })
  83. })
  84. Object.keys(defaultOptions.mpNames).concat('quickapp').forEach(key => {
  85. if (!hasValue(appInfo[key])) return
  86. imageList.push({
  87. key,
  88. urlKey: 'qrcode_url',
  89. url: appInfo[key].qrcode_url
  90. })
  91. });
  92. ['icon_url'].forEach(key => {
  93. if (!hasValue(appInfo[key])) return
  94. imageList.push({
  95. key,
  96. url: appInfo[key]
  97. })
  98. })
  99. const filelist = await translateTCB(imageList.map(item => item.url))
  100. imageList.forEach((item, index) => {
  101. if (item.urlKey) {
  102. appInfo[item.key][item.urlKey] = filelist[index]
  103. } else {
  104. appInfo[item.key] = filelist[index]
  105. }
  106. })
  107. if (hasValue(appInfo.screenshot)) {
  108. appInfo.screenshot = await translateTCB(appInfo.screenshot)
  109. }
  110. {
  111. const appInfoKeys = Object.keys(appInfo)
  112. if (appInfoKeys.some(key => {
  113. return key.indexOf('app_') !== -1 && hasValue(appInfo[key])
  114. })) {
  115. defaultOptions.hasApp = true
  116. }
  117. if (appInfoKeys.some(key => {
  118. return key.indexOf('mp') !== -1 && hasValue(appInfo[key])
  119. })) {
  120. defaultOptions.hasMP = true
  121. }
  122. if (appInfo.h5 && appInfo.h5.url) {
  123. defaultOptions.hasH5 = true
  124. }
  125. if (appInfo.quickapp && appInfo.quickapp.qrcode_url) {
  126. defaultOptions.hasQuickApp = true
  127. }
  128. // app
  129. if (defaultOptions.hasApp && appInfo.app_android && appInfo.app_android.url) {
  130. defaultOptions.android_url = appInfo.app_android.url
  131. } else {
  132. defaultOptions.android_url = ''
  133. }
  134. if (defaultOptions.hasApp && appInfo.app_ios && appInfo.app_ios.url) {
  135. defaultOptions.ios_url = appInfo.app_ios.url
  136. } else {
  137. defaultOptions.ios_url = ''
  138. }
  139. // mp
  140. defaultOptions.mpKeys = Object.keys(appInfo).filter(key => {
  141. return key.indexOf('mp') !== -1 && hasValue(appInfo[key])
  142. })
  143. }
  144. const html = TE.render(templatePage)(Object.assign({}, appInfo, defaultOptions));
  145. if (!(defaultOptions.hasApp || defaultOptions.hasH5 || defaultOptions.hasMP || defaultOptions
  146. .hasQuickApp)) {
  147. return {
  148. ...fail,
  149. code: -100,
  150. errMsg: '缺少应用信息,App、小程序、H5、快应用请至少填写一项'
  151. }
  152. }
  153. return {
  154. ...success,
  155. mpserverlessComposedResponse: true, // 使用阿里云返回集成响应是需要此字段为true
  156. statusCode: 200,
  157. headers: {
  158. 'content-type': 'text/html'
  159. },
  160. body: html
  161. };
  162. }
  163. return {
  164. ...fail,
  165. code: -3,
  166. errMsg: 'no record'
  167. };
  168. }