index.js 4.5 KB

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