(function () { const KEY = 'callup_finance_app'; const KXId = PAGE_KX_DATA.kxId; var R = 0; // 计数器,原为全局变量,在 extractStockInfo 中递增 var stockCounter = R; // 建议将 R 改名为 stockCounter 更清晰,但为保持原逻辑未动 R,仅建议 var globalStockList = []; // 1. doT 模板字符串(直接复制你转换好的模板代码) const TPL_COMMENT = ` {{? it.comments && it.comments.length > 0}}
{{~ it.comments :item:index }}
{{= item.nick }}
{{= item.content }}
{{= item.time }} {{= item.agree || 0 }}
{{? it.threadDict && it.threadDict[item.mid] }}
{{~ it.threadDict[item.mid].list :replyItem:replyIndex }}
{{= replyItem.nick }}{{? replyItem.parent_uid !== item.uid && replyItem.thread }} 回复 {{= replyItem.parent_nick }}{{?}}
{{= replyItem.content }}
{{= replyItem.time }}
{{~}}
{{?}}
{{~}}
{{?}} `; var TPL_STOCKS = ` {{?it.stocksArr && it.stocksArr.length>0}}
{{~it.stocksArr:item}}

{{=item.marketTag}}{{=item.key}}

{{~}}
{{?}}`; // 2. 编译模板 const template = doT.template(TPL_COMMENT); const stocks_template = doT.template(TPL_STOCKS); // 3. 模拟你的 fetchComments 函数(使用 jQuery AJAX) function fetchComments() { const comments = []; // 你的评论数组 const threaddict = {}; // 你的回复字典 const parts = PAGE_KX_DATA.commentId ? PAGE_KX_DATA.commentId.split(':') : []; const channel = parts[0]; const news_id = parts[1] || ''; const url = `https://app.cj.sina.com.cn/apps/api/comment/list?page=1&page_size=10&t_size=3&channel=${channel}&newsid=${news_id}` $.ajax({ url: url, method: 'GET', dataType: 'jsonp', success: function (res) { console.log('评论数据:', res); const result = res.result?.data; if (result && result && result.cmntlist) { comments.push(...result.cmntlist); if (result.threaddict) { Object.keys(result.threaddict).forEach(key => { threaddict[key] = result.threaddict[key]; threaddict[key].left = result.threaddict[key].count - result.threaddict[key].list.length; threaddict[key].last_mid = result.threaddict[key].list[result.threaddict[key].list.length - 1]?.mid || null; threaddict[key].showed = false; }); } // 渲染到页面 const html = template({ comments: comments, threadDict: threaddict }); $('#commentList').html(html); $('.icon-comment').on('click',function(){ sfc.tryDirectCall({ position:'724page_hf', newSchemaParams: { client_path: '/news/newsdetails',//不可修改, mid: KXId,//7x24单条mid } }); }); $('.icon-like').on('click',function(){ sfc.tryDirectCall({ position:'724page_dz', newSchemaParams: { client_path: '/news/newsdetails',//不可修改, mid: KXId,//7x24单条mid } }); }); } }, error: function (err) { console.error('获取评论失败', err); } }); } function extractStockInfo(stocks) { var result = []; for (var i = 0; i < stocks.length && !(i > 3); i++) { var marketType = stocks[i]?.market?.replace("foreign", "forgein"); // var marketKey = getMarketKey(stocks[i].symbol.substring(0, 2).toUpperCase()); // var marketClass = getMarketClass(marketType); var marketKey = { cn: stocks[i]?.symbol?.substring(0, 2).toUpperCase(), hk: "HK", us: "US", sb: "TM", forgein: "FE", commodity: "FT",//内盘 CFF: "FT",//内盘 fox: "FT",//外盘 global: "FT",//外盘 worldIndex: "HQ", fund: "基", globalbd: "\u503a" }[marketType]; var marketClass = { cn: "u-hq-" + stocks[i]?.symbol?.substring(0, 2), hk: "u-hq-hk", us: "u-hq-us", sb: "u-hq-tm", forgein: "u-hq-fe", commodity: "u-hq-ft", CFF: "u-hq-ft", fox: "u-hq-ft", global: "u-hq-ft", worldIndex: "u-hq-hq", globalbd: "u-hq-usz", fund: "u-hq-of" }[marketType]; var DataHref = { cn: "//quotes.sina.cn/hs/company/quotes/view/", hk: "//quotes.sina.cn/hk/company/quotes/view/", us: "//gu.sina.cn/us/hq/quotes.php?code=", sb: "//gu.sina.cn/tm/hq/quotes.php?code=", forgein: "//gu.sina.cn/fx/hq/quotes.php?code=", commodity: "//gu.sina.cn/ft/hq/nf.php?symbol=", CFF: "//gu.sina.cn/ft/hq/nf.php?symbol=", fox: "//gu.sina.cn/ft/hq/hf.php?symbol=", global: "//gu.sina.cn/ft/hq/hf.php?symbol=", worldIndex:'https://quotes.sina.cn/index/global/', globalbd: "//quotes.sina.cn/bd/hq/globalbd.php?symbol=", // znb: "//quotes.sina.cn/global/hq/quotes.php?code=", fund: "//stocks.sina.cn/fund/?code=", // lse: "//quotes.sina.cn/lse/hq/quotes.php?symbol=", // usb: "" }[marketType]; var stockKey = stocks[i].key; var uniquePercentId = "percent" + stockCounter + "_" + stocks[i].symbol.replace(".", "usacode"); var normalizedSymbol = normalizeSymbol(stocks[i]).symbol; var callableSymbol = normalizeSymbol(stocks[i]).symbolCall; var link = DataHref+normalizeSymbol(stocks[i]).symbolLink.replace('-',''); if ("sz399001" === stocks[i].symbol) { marketKey = "SZ"; marketClass = "u-hq-sz"; } stockCounter += 1; if(stocks[i].symbol.indexOf('sih')<0){ result.push({ market: marketType, marketTag: marketKey || "", marketClass: marketClass, key: stockKey, percentBox: uniquePercentId, symbol: normalizedSymbol, symbolCall: callableSymbol, link:link }); globalStockList.push({ key: stockKey, percentBox: uniquePercentId, symbol: normalizedSymbol }); } } return result; } function updateStockData(stockElements) { var symbolString = ""; for (var i = 0; i < stockElements.length; i++) { symbolString += stockElements[i].symbol + ","; } symbolString = symbolString.substring(0, symbolString.lastIndexOf(",")); try { KKE.api("datas.hq.get", { symbol: symbolString, cancelEtag: true }, function(response) { var stockDataArray = response.data; if (stockDataArray && stockDataArray.length > 0) { for (var j = 0; j < stockDataArray.length; j++) { var currentStockData = stockDataArray[j]; var specialCase = currentStockData.symbol.split("_")[0] === "globalbd"; if (specialCase) { currentStockData = transformGlobalBdData(currentStockData.hqstr, currentStockData.symbol); } var matchedElement = stockElements[j]; if (matchedElement && currentStockData.symbol === matchedElement.symbol) { var stockInfo = extractStockPercentageInfo(currentStockData); var percentageText = stockInfo.zdf; var colorClass = stockInfo.color; currentStockData.symbol = currentStockData.symbol; var percentElement = $("." + matchedElement.percentBox); if (percentElement) { percentElement.text(percentageText); percentElement.removeClass('u-gray').removeClass('u-red').removeClass('u-green'); percentElement.addClass(colorClass); } if (currentStockData.name !== matchedElement.key) { var nameElement = $("." + matchedElement.percentBox + "_name"); if (nameElement) { nameElement.text(currentStockData.name); } } } } } }); } catch (error) { } } function normalizeSymbol(stock) { var normalized = { symbol: "", symbolCall: "", symbolLink:'' }; switch (stock.market) { case "cn": normalized.symbol = stock.symbol; normalized.symbolCall = stock.symbol; normalized.symbolLink = stock.symbol; break; case "hk": normalized.symbol = (stock.symbol === "hsi") ? "rt_hk" + stock.symbol.toUpperCase() : "rt_hk" + stock.symbol; normalized.symbolCall = stock.symbol; normalized.symbolLink = stock.symbol; break; case "us": normalized.symbol = "gb_" + stock.symbol.replace(".", "$"); normalized.symbolCall = stock.symbol; normalized.symbolLink = stock.symbol; break; case "sb": normalized.symbol = stock.market + stock.symbol; normalized.symbolCall = stock.market + stock.symbol; break; case "foreign": normalized.symbol = stock.symbol; normalized.symbolCall = stock.symbol; normalized.symbolLink = stock.symbol.replace('fx_s',''); break; case "commodity": normalized.symbol = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolCall = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolLink = stock.symbol.split("_")[1]; break; case "CFF": normalized.symbol = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolCall = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolLink = stock.symbol.split("_")[1]; break; case "global": normalized.symbol = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolCall = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolLink = stock.symbol.split("_")[1]; break; case "worldIndex": normalized.symbol = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolCall = stock.symbol.split("_")[0] + "_" + stock.symbol.split("_")[1].toUpperCase(); normalized.symbolLink = stock.symbol.split("_")[1]; break; case "globalbd": normalized.symbol = stock.market + "_" + stock.symbol; normalized.symbolCall = stock.symbol.toUpperCase(); normalized.symbolLink = stock.symbol; break; case "fund": normalized.symbol = "f_" + stock.symbol; normalized.symbolCall = stock.symbol; normalized.symbolLink = stock.symbol; break; default: normalized.symbol = stock.symbol; normalized.symbolCall = stock.symbol; normalized.symbolLink = stock.symbol; } return normalized; } function extractStockPercentageInfo(stockData) { var defaultInfo = { zdf: "--", color: "u-gray" }; if (stockData.state) { if ("-2" === stockData.state) { return { zdf: "未上市", color: defaultInfo.color }; } if ("-3" === stockData.state) { return { zdf: "退市", color: defaultInfo.color }; } if ("01" === stockData.state || "02" === stockData.state || "03" === stockData.state || "04" === stockData.state || "05" === stockData.state) { return { zdf: "- 停牌 -", color: defaultInfo.color }; } } if (!stockData.price || stockData.price === 0) { return defaultInfo; } var changePercent = 100 * (stockData.price - stockData.prevclose) / stockData.prevclose; var color = changePercent === 0 ? "u-gray" : (changePercent > 0 ? "u-red" : "u-green"); var percentText = changePercent > 0 ? "+" + changePercent.toFixed(2) + "%" : changePercent.toFixed(2) + "%"; return { zdf: percentText, color: color }; } function transformGlobalBdData(hqString, symbol) { if (!hqString) { return null; } var fields = hqString.split(","); var stockName = fields[1].replace(/\s*/g, ""); var time = fields[12] + " " + fields[13]; var currentPrice = fields[1] !== "" ? +fields[1] : null; var openPrice = fields[2] !== "" ? +fields[2] : null; var previousClose = fields[3] !== "" ? +fields[3] : null; var changeAmount = fields[8] !== "" ? +fields[8] : null; var changePercent = fields[7] !== "" ? +fields[7] : null; // 若当前价格为 0,则使用 previousClose(或者 open?原逻辑有点模糊,这里保持原行为) if (previousClose === 0) { previousClose = openPrice; changeAmount = 0; changePercent = 0; } var trend = undefined; if (typeof changeAmount !== 'undefined') { trend = changeAmount > 0 ? 1 : (changeAmount < 0 ? -1 : 0); } if (typeof changePercent !== 'undefined') { changePercent = changePercent + "%"; } return { name: stockName, symbol: symbol, price: currentPrice, time: time, open: openPrice, prevclose: previousClose, ca: changeAmount, // Change Amount cp: changePercent, // Change Percent // 如果一定要暴露 trend,也可以加上:trend: trend }; } function f(t) { var e = window.innerHeight , n = t.offsetHeight; return !(t.getBoundingClientRect().bottom - e - n > 0 || t.getBoundingClientRect().top + n < 0) } // 页面加载后执行 S = null; k = null; $(window).scroll(function() { clearTimeout(S), S = setTimeout(function() { if (0 != globalStockList.length) { for (var t = [], e = 0; e < globalStockList.length; e++) { var n = document.querySelector("." + globalStockList[e].percentBox); f(n) && t.push(globalStockList[e]) } clearTimeout(k), t.length > 0 && (updateStockData(t), k = setInterval(function() { updateStockData(t) }, 3e3)) } }, 100) }); function sendSuda(val){ var _self = this; if(navigator.userAgent.indexOf('sinafinance')<0){ try { SUDA.uaTrack(KEY,val); } catch (error) { } } }; function truncateString(str) { let count = 0; let result = ''; for (let i = 0; i < str.length; i++) { const char = str[i]; if (/[\u4e00-\u9fa5]/.test(char)) { count += 2; // 汉字算2个字符 } else { count += 1; // 非汉字算1个字符 } if (count > 130) { return result + '...'; } result += char; } return result; } $(document).ready(function () { //曝光 sendSuda('724page_exp'); if(PAGE_KX_DATA&&PAGE_KX_DATA.stocks&&PAGE_KX_DATA.stocks.length>0){ var stockItems = []; stockItems = extractStockInfo(PAGE_KX_DATA.stocks); // 渲染到页面 const stockHTML = stocks_template({ stocksArr: stockItems }); $('.j-stocks').html(stockHTML); $('.j-stocks').removeClass('hide'); updateStockData(stockItems); console.log(stockItems) } // 获取所有的class="txt03 content"元素 const elements = document.querySelectorAll('.txt03.content'); // 遍历每个元素并处理其内容 elements.forEach(element => { element.textContent = truncateString(element.textContent); }); //统一配置 var __callUpConfig = { eventid:'callup_finance_app', uatrackKey: "callup_finance_app", androidInstallUrl: "http://file.finance.sina.com.cn/finapp/apks/sinaFinance_pcrementuijian.apk", needOpenSource: false } //初始化自动绑定事件 var sfc = new SinaFinanceCallUp.CallUpSinaFinance(__callUpConfig); $('.btn-open-app').on('click',function(event){ event.stopPropagation(); sfc.tryDirectCall({ position:'724page_appopen_btn', newSchemaParams: { client_path: '/app/home',//不可修改, tab: 'news',//不可修改, subTab: 'news_724',//7x24小时, } }); }); //顶部banner $('.j-topbar').on('click',function(){ sfc.tryDirectCall({ position:'724page_topbanner', newSchemaParams: { client_path: '/app/home',//不可修改, tab: 'news',//不可修改, subTab: 'news_724',//7x24小时, } }); }); //绑定评论呼端 $('.j-callup-comment').on('click',function(){ sfc.tryDirectCall({ position:'724page_pl', newSchemaParams: { client_path: '/news/newsdetails',//不可修改, mid: KXId,//7x24单条mid } }); }); //底部添加打开APP按钮 let _isApp = navigator.userAgent.toLocaleLowerCase().indexOf('sinafinance') > -1; function forbiddenCallup(){ var ret = false; var _ua = navigator.userAgent.toLocaleLowerCase(); var _forbidden = /vivo/; ret = _forbidden.test(_ua); return ret; } if(!_isApp&&forbiddenCallup()==false){ var _tempDom = document.createElement('a'); _tempDom.className = 'btn-subpage-bottom-callup animated pluse'; _tempDom.id = 'subPage_bottom_callup_btn'; _tempDom.innerHTML = '打开APP'; document.body.appendChild(_tempDom); let _callupBtn = document.getElementById('subPage_bottom_callup_btn'); _callupBtn.onclick = function(){ sfc.tryDirectCall({ position:'724page_appopen_btn', newSchemaParams: { client_path: '/news/newsdetails',//不可修改, mid: KXId,//7x24单条mid } }); } } try { fetchComments(); } catch (error) { } }); })()