koishi-plugin-monetary-bourse 2.0.3-Alpha.12 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +36 -27
- package/lib/templates/holding-card.html +556 -379
- package/lib/templates/stock-chart.html +478 -468
- package/lib/templates/trade-result.html +624 -559
- package/package.json +1 -1
- package/readme.md +13 -2
package/lib/index.js
CHANGED
|
@@ -138,7 +138,7 @@ function apply(ctx, config) {
|
|
|
138
138
|
}
|
|
139
139
|
__name(isMarketOpen, "isMarketOpen");
|
|
140
140
|
async function getCashBalance(uid, currency) {
|
|
141
|
-
if (
|
|
141
|
+
if (uid === void 0 || uid === null || typeof uid !== "number" || Number.isNaN(uid)) {
|
|
142
142
|
logger.warn(`getCashBalance: 无效的uid: ${uid}`);
|
|
143
143
|
return 0;
|
|
144
144
|
}
|
|
@@ -157,7 +157,7 @@ function apply(ctx, config) {
|
|
|
157
157
|
}
|
|
158
158
|
__name(getCashBalance, "getCashBalance");
|
|
159
159
|
async function changeCashBalance(uid, currency, delta) {
|
|
160
|
-
if (
|
|
160
|
+
if (uid === void 0 || uid === null || typeof uid !== "number" || Number.isNaN(uid)) {
|
|
161
161
|
logger.warn(`changeCashBalance: 无效的uid: ${uid}`);
|
|
162
162
|
return false;
|
|
163
163
|
}
|
|
@@ -190,7 +190,7 @@ function apply(ctx, config) {
|
|
|
190
190
|
}
|
|
191
191
|
__name(changeCashBalance, "changeCashBalance");
|
|
192
192
|
async function getBankDemandBalance(uid, currency) {
|
|
193
|
-
if (
|
|
193
|
+
if (uid === void 0 || uid === null || typeof uid !== "number" || Number.isNaN(uid)) return 0;
|
|
194
194
|
try {
|
|
195
195
|
const tables = ctx.database.tables;
|
|
196
196
|
if (!tables || !("monetary_bank_int" in tables)) {
|
|
@@ -211,7 +211,7 @@ function apply(ctx, config) {
|
|
|
211
211
|
}
|
|
212
212
|
__name(getBankDemandBalance, "getBankDemandBalance");
|
|
213
213
|
async function deductBankDemand(uid, currency, amount) {
|
|
214
|
-
if (
|
|
214
|
+
if (uid === void 0 || uid === null || typeof uid !== "number" || Number.isNaN(uid) || amount <= 0) return false;
|
|
215
215
|
try {
|
|
216
216
|
const tables = ctx.database.tables;
|
|
217
217
|
if (!tables || !("monetary_bank_int" in tables)) return false;
|
|
@@ -727,7 +727,7 @@ function apply(ctx, config) {
|
|
|
727
727
|
});
|
|
728
728
|
}
|
|
729
729
|
} else if (txn.type === "sell") {
|
|
730
|
-
if (txn.uid && typeof txn.uid === "number") {
|
|
730
|
+
if (txn.uid !== void 0 && txn.uid !== null && typeof txn.uid === "number" && !Number.isNaN(txn.uid)) {
|
|
731
731
|
const amount = Number(txn.cost.toFixed(2));
|
|
732
732
|
const success = await changeCashBalance(txn.uid, config.currency, amount);
|
|
733
733
|
if (!success) {
|
|
@@ -803,10 +803,23 @@ function apply(ctx, config) {
|
|
|
803
803
|
timestamp: h2.time.getTime()
|
|
804
804
|
};
|
|
805
805
|
});
|
|
806
|
-
const
|
|
807
|
-
|
|
806
|
+
const lastHistoryPrice = formattedData[formattedData.length - 1]?.price;
|
|
807
|
+
if (lastHistoryPrice !== currentPrice) {
|
|
808
|
+
const nowTime = /* @__PURE__ */ new Date();
|
|
809
|
+
let nowTimeStr = nowTime.toLocaleTimeString();
|
|
810
|
+
if (interval === "week" || interval === "day") {
|
|
811
|
+
nowTimeStr = `${nowTime.getMonth() + 1}-${nowTime.getDate()} ${nowTime.getHours()}:${nowTime.getMinutes().toString().padStart(2, "0")}`;
|
|
812
|
+
}
|
|
813
|
+
formattedData.push({
|
|
814
|
+
time: nowTimeStr,
|
|
815
|
+
price: currentPrice,
|
|
816
|
+
timestamp: nowTime.getTime()
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
const high = Math.max(...formattedData.map((d) => d.price), currentPrice);
|
|
820
|
+
const low = Math.min(...formattedData.map((d) => d.price), currentPrice);
|
|
808
821
|
const viewLabel = interval === "week" ? "周走势" : interval === "day" ? "日走势" : "实时走势";
|
|
809
|
-
const img = await renderStockImage(ctx, formattedData, config.stockName, viewLabel,
|
|
822
|
+
const img = await renderStockImage(ctx, formattedData, config.stockName, viewLabel, currentPrice, high, low);
|
|
810
823
|
return img;
|
|
811
824
|
});
|
|
812
825
|
ctx.command("stock.buy <amount:number>", "买入股票").userFields(["id"]).action(async ({ session }, amount) => {
|
|
@@ -816,18 +829,14 @@ function apply(ctx, config) {
|
|
|
816
829
|
}
|
|
817
830
|
if (!await isMarketOpen()) return "休市中,无法交易。";
|
|
818
831
|
const visibleUserId = session.userId;
|
|
819
|
-
if (!session.user || session.user.id
|
|
832
|
+
if (!session.user || session.user.id === void 0 || session.user.id === null) {
|
|
820
833
|
logger.error(`stock.buy: session.user 不存在或 id 为空 user=${session.userId}`);
|
|
821
834
|
return "无法获取用户ID,请稍后重试。";
|
|
822
835
|
}
|
|
823
|
-
|
|
836
|
+
const uid = session.user.id;
|
|
824
837
|
if (typeof uid !== "number") {
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
logger.error(`stock.buy: 无法获取数字UID user=${session.userId}, rawId=${uid}`);
|
|
828
|
-
return "无法获取用户ID,请稍后重试。";
|
|
829
|
-
}
|
|
830
|
-
uid = parsedUid;
|
|
838
|
+
logger.error(`stock.buy: 无法获取数字UID user=${session.userId}, rawId=${uid}`);
|
|
839
|
+
return "无法获取用户ID,请稍后重试。";
|
|
831
840
|
}
|
|
832
841
|
const cost = Number((currentPrice * amount).toFixed(2));
|
|
833
842
|
const payResult = await pay(uid, cost, config.currency);
|
|
@@ -842,7 +851,7 @@ function apply(ctx, config) {
|
|
|
842
851
|
if (freezeMinutes < config.minFreezeTime) freezeMinutes = config.minFreezeTime;
|
|
843
852
|
}
|
|
844
853
|
const freezeMs = freezeMinutes * 60 * 1e3;
|
|
845
|
-
const userPendingOrders = await ctx.database.get("bourse_pending", { userId: visibleUserId }, { sort: { endTime: "desc" }, limit: 1 });
|
|
854
|
+
const userPendingOrders = await ctx.database.get("bourse_pending", { userId: visibleUserId, type: "buy" }, { sort: { endTime: "desc" }, limit: 1 });
|
|
846
855
|
let startTime = /* @__PURE__ */ new Date();
|
|
847
856
|
if (userPendingOrders.length > 0) {
|
|
848
857
|
const lastOrderEndTime = userPendingOrders[0].endTime;
|
|
@@ -906,18 +915,14 @@ function apply(ctx, config) {
|
|
|
906
915
|
}
|
|
907
916
|
if (!await isMarketOpen()) return "休市中,无法交易。";
|
|
908
917
|
const visibleUserId = session.userId;
|
|
909
|
-
if (!session.user || session.user.id
|
|
918
|
+
if (!session.user || session.user.id === void 0 || session.user.id === null) {
|
|
910
919
|
logger.error(`stock.sell: session.user 不存在或 id 为空 user=${session.userId}`);
|
|
911
920
|
return "无法获取用户ID,请稍后重试。";
|
|
912
921
|
}
|
|
913
|
-
|
|
922
|
+
const uid = session.user.id;
|
|
914
923
|
if (typeof uid !== "number") {
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
logger.error(`stock.sell: 无法获取数字UID user=${session.userId}, rawId=${uid}`);
|
|
918
|
-
return "无法获取用户ID,请稍后重试。";
|
|
919
|
-
}
|
|
920
|
-
uid = parsedUid;
|
|
924
|
+
logger.error(`stock.buy: 无法获取数字UID user=${session.userId}, rawId=${uid}`);
|
|
925
|
+
return "无法获取用户ID,请稍后重试。";
|
|
921
926
|
}
|
|
922
927
|
const holding = await ctx.database.get("bourse_holding", { userId: visibleUserId, stockId });
|
|
923
928
|
if (holding.length === 0 || holding[0].amount < amount) {
|
|
@@ -952,7 +957,7 @@ function apply(ctx, config) {
|
|
|
952
957
|
if (freezeMinutes < config.minFreezeTime) freezeMinutes = config.minFreezeTime;
|
|
953
958
|
}
|
|
954
959
|
const freezeMs = freezeMinutes * 60 * 1e3;
|
|
955
|
-
const userPendingOrders = await ctx.database.get("bourse_pending", { userId: visibleUserId }, { sort: { endTime: "desc" }, limit: 1 });
|
|
960
|
+
const userPendingOrders = await ctx.database.get("bourse_pending", { userId: visibleUserId, type: "sell" }, { sort: { endTime: "desc" }, limit: 1 });
|
|
956
961
|
let startTime = /* @__PURE__ */ new Date();
|
|
957
962
|
if (userPendingOrders.length > 0) {
|
|
958
963
|
const lastOrderEndTime = userPendingOrders[0].endTime;
|
|
@@ -1018,7 +1023,11 @@ function apply(ctx, config) {
|
|
|
1018
1023
|
tradeMeta
|
|
1019
1024
|
);
|
|
1020
1025
|
});
|
|
1021
|
-
ctx.command("stock.my", "我的持仓").action(async ({ session }) => {
|
|
1026
|
+
ctx.command("stock.my", "我的持仓").userFields(["id"]).action(async ({ session }) => {
|
|
1027
|
+
if (!session.user || session.user.id === void 0 || session.user.id === null) {
|
|
1028
|
+
logger.error(`stock.my: session.user 不存在或 id 为空 user=${session.userId}`);
|
|
1029
|
+
return "无法获取用户ID,请稍后重试。";
|
|
1030
|
+
}
|
|
1022
1031
|
const userId = session.userId;
|
|
1023
1032
|
const holdings = await ctx.database.get("bourse_holding", { userId });
|
|
1024
1033
|
const pending = await ctx.database.get("bourse_pending", { userId });
|