(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}}
{{?}}
`;
var TPL_STOCKS = `
{{?it.stocksArr && it.stocksArr.length>0}}
{{?}}`;
// 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) {
}
});
})()