feat: 后端全量更新 - 含所有本次需求

- Contract.php: 返回合约账户余额(balance_contract)
- My.php: 地址管理增加BTC/ETH
- AppContract.php: 一键平仓(closeall)
- AppProxy.php: 代理专属注册链接 + 分级权限(L1/L2)
- site.php: 手续费减半(0.018→0.009)
- agent_permission_setup.sql: 代理权限SQL
- crypto_news_crawler.py: 新闻自动采集脚本
This commit is contained in:
li
2026-03-30 20:16:32 +08:00
commit 1b24994e74
6721 changed files with 1308571 additions and 0 deletions
File diff suppressed because one or more lines are too long
@@ -0,0 +1,173 @@
var findEndOfMath = function(delimiter, text, startIndex) {
// Adapted from
// https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
var index = startIndex;
var braceLevel = 0;
var delimLength = delimiter.length;
while (index < text.length) {
var character = text[index];
if (braceLevel <= 0 &&
text.slice(index, index + delimLength) === delimiter) {
return index;
} else if (character === "\\") {
index++;
} else if (character === "{") {
braceLevel++;
} else if (character === "}") {
braceLevel--;
}
index++;
}
return -1;
};
var splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
var finalData = [];
for (var i = 0; i < startData.length; i++) {
if (startData[i].type === "text") {
var text = startData[i].data;
var lookingForLeft = true;
var currIndex = 0;
var nextIndex;
nextIndex = text.indexOf(leftDelim);
if (nextIndex !== -1) {
currIndex = nextIndex;
finalData.push({
type: "text",
data: text.slice(0, currIndex),
});
lookingForLeft = false;
}
while (true) {
if (lookingForLeft) {
nextIndex = text.indexOf(leftDelim, currIndex);
if (nextIndex === -1) {
break;
}
finalData.push({
type: "text",
data: text.slice(currIndex, nextIndex),
});
currIndex = nextIndex;
} else {
nextIndex = findEndOfMath(
rightDelim,
text,
currIndex + leftDelim.length);
if (nextIndex === -1) {
break;
}
finalData.push({
type: "math",
data: text.slice(
currIndex + leftDelim.length,
nextIndex),
rawData: text.slice(
currIndex,
nextIndex + rightDelim.length),
display: display,
});
currIndex = nextIndex + rightDelim.length;
}
lookingForLeft = !lookingForLeft;
}
finalData.push({
type: "text",
data: text.slice(currIndex),
});
} else {
finalData.push(startData[i]);
}
}
return finalData;
};
//===========================
var splitWithDelimiters = function(text, delimiters) {
var data = [{type: "text", data: text}];
for (var i = 0; i < delimiters.length; i++) {
var delimiter = delimiters[i];
data = splitAtDelimiters(
data, delimiter.left, delimiter.right,
delimiter.display || false);
}
return data;
};
var renderMathInText = function(text, delimiters) {
var data = splitWithDelimiters(text, delimiters);
var fragment = document.createDocumentFragment();
for (var i = 0; i < data.length; i++) {
if (data[i].type === "text") {
fragment.appendChild(document.createTextNode(data[i].data));
} else {
var span = document.createElement("span");
var math = data[i].data;
try {
var domStr = text.replace(/\$\$.*\$\$/g,"");
domStr = trim(domStr);
if(domStr.length>0){
span.setAttribute("class", "latex-inline");
}
katex.render(math, span, {
displayMode: data[i].display,
});
} catch (e) {
if (!(e instanceof katex.ParseError)) {
throw e;
}
fragment.appendChild(document.createTextNode(data[i].rawData));
continue;
}
fragment.appendChild(span);
}
}
return fragment;
};
var renderElem = function(elem, delimiters, ignoredTags) {
for (var i = 0; i < elem.childNodes.length; i++) {
var childNode = elem.childNodes[i];
if (childNode.nodeType === 3) {
// Text node
var frag = renderMathInText(childNode.textContent, delimiters);
i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode);
} else if (childNode.nodeType === 1) {
// Element node
var shouldRender = ignoredTags.indexOf(
childNode.nodeName.toLowerCase()) === -1;
if (shouldRender) {
renderElem(childNode, delimiters, ignoredTags);
}
}
// Otherwise, it's something else, and ignore it.
}
};
var renderMathInElement = function(elem, options) {
if (!elem) {
throw new Error("No element provided to render");
}
var defaultOptions = {
delimiters: [
{left: "$$", right: "$$", display: true},
{left: "\\[", right: "\\]", display: true},
{left: "\\(", right: "\\)", display: false},
// LaTeX uses this, but it ruins the display of normal `$` in text:
// {left: "$", right: "$", display: false},
],
ignoredTags: [
"script", "noscript", "style", "textarea", "pre", "code",
],
};
options = $.extend({}, defaultOptions, options);
renderElem(elem, options.delimiters, options.ignoredTags);
};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
.mermaid .label{color:#333}.node circle,.node ellipse,.node polygon,.node rect{fill:#ececff;stroke:#ccf;stroke-width:1px}.arrowheadPath{fill:#333}.edgePath .path{stroke:#333}.edgeLabel{background-color:#e8e8e8}.cluster rect{fill:#ffffde!important;rx:4!important;stroke:#aa3!important;stroke-width:1px!important}.cluster text{fill:#333}.actor{stroke:#ccf;fill:#ececff}text.actor{fill:#000;stroke:none}.actor-line{stroke:grey}.messageLine0{marker-end:"url(#arrowhead)"}.messageLine0,.messageLine1{stroke-width:1.5;stroke-dasharray:"2 2";stroke:#333}#arrowhead{fill:#333}#crosshead path{fill:#333!important;stroke:#333!important}.messageText{fill:#333;stroke:none}.labelBox{stroke:#ccf;fill:#ececff}.labelText,.loopText{fill:#000;stroke:none}.loopLine{stroke-width:2;stroke-dasharray:"2 2";marker-end:"url(#arrowhead)";stroke:#ccf}.note{stroke:#aa3;fill:#fff5ad}.noteText{fill:#000;stroke:none;font-family:trebuchet ms,verdana,arial;font-size:14px}.section{stroke:none;opacity:.2}.section0{fill:rgba(102,102,255,.49)}.section2{fill:#fff400}.section1,.section3{fill:#fff;opacity:.2}.sectionTitle0,.sectionTitle1,.sectionTitle2,.sectionTitle3{fill:#333}.sectionTitle{text-anchor:start;font-size:11px;text-height:14px}.grid .tick{stroke:#d3d3d3;opacity:.3;shape-rendering:crispEdges}.grid path{stroke-width:0}.today{fill:none;stroke:red;stroke-width:2px}.task{stroke-width:2}.taskText{text-anchor:middle;font-size:11px}.taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px}.taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}.taskText0,.taskText1,.taskText2,.taskText3{fill:#fff}.task0,.task1,.task2,.task3{fill:#8a90dd;stroke:#534fbc}.taskTextOutside0,.taskTextOutside1,.taskTextOutside2,.taskTextOutside3{fill:#000}.active0,.active1,.active2,.active3{fill:#bfc7ff;stroke:#534fbc}.activeText0,.activeText1,.activeText2,.activeText3{fill:#000!important}.done0,.done1,.done2,.done3{stroke:grey;fill:#d3d3d3;stroke-width:2}.doneText0,.doneText1,.doneText2,.doneText3{fill:#000!important}.crit0,.crit1,.crit2,.crit3{stroke:#f88;fill:red;stroke-width:2}.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}.activeCritText0,.activeCritText1,.activeCritText2,.activeCritText3,.doneCritText0,.doneCritText1,.doneCritText2,.doneCritText3{fill:#000!important}.titleText{text-anchor:middle;font-size:18px;fill:#000}g.classGroup text{fill:#9370db;stroke:none;font-family:trebuchet ms,verdana,arial;font-size:10px}g.classGroup rect{fill:#ececff;stroke:#9370db}g.classGroup line{stroke:#9370db;stroke-width:1}svg .classLabel .box{stroke:none;stroke-width:0;fill:#ececff;opacity:.5}svg .classLabel .label{fill:#9370db;font-size:10px}.relation{stroke:#9370db;stroke-width:1;fill:none}#compositionEnd,#compositionStart,.composition{fill:#9370db;stroke:#9370db;stroke-width:1}#aggregationEnd,#aggregationStart,.aggregation{fill:#ececff;stroke:#9370db;stroke-width:1}#dependencyEnd,#dependencyStart,#extensionEnd,#extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}.node text{font-size:14px}.node text,div.mermaidTooltip{font-family:trebuchet ms,verdana,arial}div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}
File diff suppressed because one or more lines are too long