@@ -21,7 +21,8 @@ const CryptoJS = require('crypto-js') // 编解码
2121const tencentcloud = require ( 'tencentcloud-sdk-nodejs' ) // 腾讯云 API NODEJS SDK
2222const fs = require ( 'fs' )
2323const FormData = require ( 'form-data' ) // 图片上传
24- const pushoo = require ( 'pushoo' ) . default
24+ const pushoo = require ( 'pushoo' ) . default // 即时消息通知
25+ const ipToRegion = require ( 'dy-node-ip2region' ) // IP 属地查询
2526
2627// 云函数 SDK / tencent cloudbase sdk
2728const app = tcb . init ( { env : tcb . SYMBOL_CURRENT_ENV } )
@@ -33,6 +34,9 @@ const _ = db.command
3334const window = new JSDOM ( '' ) . window
3435const DOMPurify = createDOMPurify ( window )
3536
37+ // 初始化 IP 属地
38+ const ipRegionSearcher = ipToRegion . create ( )
39+
3640// 常量 / constants
3741const RES_CODE = {
3842 SUCCESS : 0 ,
@@ -343,13 +347,15 @@ function parseComment (comments, uid) {
343347function toCommentDto ( comment , uid , replies = [ ] , comments = [ ] ) {
344348 let displayOs = ''
345349 let displayBrowser = ''
346- try {
347- const ua = bowser . getParser ( comment . ua )
348- const os = ua . getOS ( )
349- displayOs = [ os . name , os . versionName ? os . versionName : os . version ] . join ( ' ' )
350- displayBrowser = [ ua . getBrowserName ( ) , ua . getBrowserVersion ( ) ] . join ( ' ' )
351- } catch ( e ) {
352- console . log ( 'bowser 错误:' , e )
350+ if ( config . SHOW_UA !== 'false' ) {
351+ try {
352+ const ua = bowser . getParser ( comment . ua )
353+ const os = ua . getOS ( )
354+ displayOs = [ os . name , os . versionName ? os . versionName : os . version ] . join ( ' ' )
355+ displayBrowser = [ ua . getBrowserName ( ) , ua . getBrowserVersion ( ) ] . join ( ' ' )
356+ } catch ( e ) {
357+ console . log ( 'bowser 错误:' , e )
358+ }
353359 }
354360 return {
355361 id : comment . _id ,
@@ -360,6 +366,7 @@ function toCommentDto (comment, uid, replies = [], comments = []) {
360366 comment : comment . comment ,
361367 os : displayOs ,
362368 browser : displayBrowser ,
369+ ipRegion : config . SHOW_REGION ? getIpRegion ( { ip : comment . ip } ) : '' ,
363370 master : comment . master ,
364371 like : comment . like ? comment . like . length : 0 ,
365372 liked : comment . like ? comment . like . findIndex ( ( item ) => item === uid ) > - 1 : false ,
@@ -440,7 +447,7 @@ function getCommentSearchCondition (event) {
440447
441448function parseCommentForAdmin ( comments ) {
442449 for ( const comment of comments ) {
443- comment . commentText = $ ( comment . comment ) . text ( )
450+ comment . ipRegion = getIpRegion ( { ip : comment . ip , detail : true } )
444451 }
445452 return comments
446453}
@@ -1652,6 +1659,27 @@ async function isAdmin () {
16521659 return ADMIN_USER_ID === userInfo . userInfo . customUserId
16531660}
16541661
1662+ /**
1663+ * 获取 IP 属地
1664+ * @param detail true 返回省市运营商,false 只返回省
1665+ * @returns {String }
1666+ */
1667+ function getIpRegion ( { ip, detail = false } ) {
1668+ if ( ! ip ) return ''
1669+ try {
1670+ const { region } = ipRegionSearcher . btreeSearchSync ( ip )
1671+ const [ , , province , city , isp ] = region . split ( '|' )
1672+ if ( detail ) {
1673+ return province === city ? [ city , isp ] . join ( ' ' ) : [ province , city , isp ] . join ( ' ' )
1674+ } else {
1675+ return province
1676+ }
1677+ } catch ( e ) {
1678+ console . error ( 'IP 属地查询失败:' , e )
1679+ return ''
1680+ }
1681+ }
1682+
16551683// 判断是否为递归调用(即云函数调用自身)
16561684function isRecursion ( context ) {
16571685 const envObj = tcb . getCloudbaseContext ( context )
0 commit comments