index.js 5.0 KB

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