// ==UserScript==
// @name ACGN-stock營利統計外掛
// @namespace http://tampermonkey.net/
// @version 4.01.00
// @description Banishment this world!
// @author SoftwareSing
// @match http://acgn-stock.com/*
// @match https://acgn-stock.com/*
// @match https://test.acgn-stock.com/*
// @grant none
// ==/UserScript==
//I love Hatsune Miku.
//版本號為'主要版本號 + "." + 次要版本號 + 錯誤修正版本號,ex 8.31.39
//修復導致功能失效的錯誤或更新重大功能提升主要或次要版本號
//優化UI,優化效能,優化小錯誤更新錯誤版本號
//本腳本修改自 "ACGN股票系統每股營利外掛 2.200 by papago89"
//這邊記一下每個storage的格式
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
//userStcokInfo的格式 session
//{"userID": "CWgfhqxbrJMxsknrb",
// "userCompany": [{"companyID": aaa, "userHold": number}, {}]
// "userManage": [{"companyID": aaa}, {}]
// "userEmployee": {"companyID": aaa} }
/*************************************/
/**************DebugMode**************/
const debugMode = false;
//debugMode == true 的時候,會console更多資訊供debug
function debugConsole(msg)
{
if (debugMode)
console.log(msg);
}
/**************DebugMode**************/
/*************************************/
/*************************************/
/************GlobalVariable***********/
//會跨2區以上使用的全域變數放在這裡
//如從stockSummary跨到accountInfo用的變數
var myID = null; //當前登入的使用者ID
var myHoldStock = []; //當前登入的使用者持有的股票, 在股市總覽可以直接抓到全部
var myOrders = []; //當前登入的使用者未完成交易的買賣單, 在股市總覽可以直接抓到全部
var othersScript = [];
/************GlobalVariable***********/
/*************************************/
/*************************************/
/*********ACGNListenerScript**********/
//本區監測事件搬運自"ACGN股票系統每股營利外掛 ver2.810"
//https://github.com/frozenmouse/acgn-stock-user-script/blob/master/acgn-stock.user.js
(function() {
startEvent();
observeLoadingOverlay();
})();
// 觀察頁面是否進入或離開載入狀態(是否正在轉圈圈)
function observeLoadingOverlay() {
// 頁面處於載入狀態時會出現的蓋版元素(俗稱「轉圈圈」)
const loadingOverlay = $("#loading .loadingOverlay")[0];
// 觀察 loadingOverlay 的 class attribute 是否變動
new MutationObserver(mutations => {
mutations.filter(m => m.attributeName === "class").forEach(m => {
if (m.target.classList.contains("d-none")) {
// 轉圈圈隱藏 => 已脫離載入狀態
onPageLoaded();
} else {
// 顯示轉圈圈 => 正處於載入狀態
onPageLoading();
}
});
}).observe(loadingOverlay, { attributes: true });
}
// 頁面在載入狀態時進行此回呼
function onPageLoading() {
console.log("");
console.log("");
console.log(`Page loading: ${document.location.href}`);
}
// 頁面離開載入狀態時進行此回呼
function onPageLoaded() {
const currentUrl = document.location.href;
console.log(`Page loaded: ${currentUrl}`);
console.log("");
console.log("");
// 頁面 url 樣式的回呼表
const urlPatternCallbackTable = [
{ pattern: /company\/[0-9]+/, callback: onStockSummaryPageLoaded },
{ pattern: /company\/detail/, callback: onCompanyDetailPageLoaded },
{ pattern: /accountInfo/, callback: onAccountInfoPageLoaded },
{ pattern: /foundation\/[0-9]+/, callback: onFoundationPlanPageLoaded },
{ pattern: /arenaInfo/, callback: onArenaInfoPageLoaded },
];
// 匹配當前頁面 url 的樣式並進行對應的回呼
urlPatternCallbackTable.forEach(({ pattern, callback }) => {
if (currentUrl.match(pattern)) {
// loadingOverlay 消失後,需要給點時間讓頁面的載入全部跑完
setTimeout(callback, 100);
}
});
}
// 當「股市總覽」頁面已載入時進行的回呼
function onStockSummaryPageLoaded() {
setTimeout(stockSummaryEvent, 10);
}
// 當「公司資訊」頁面已載入時進行的回呼
function onCompanyDetailPageLoaded() {
setTimeout(companyEvent, 10);
}
// 當「帳號資訊」頁面已載入時進行的回呼
function onAccountInfoPageLoaded() {
setTimeout(checkUserInfo, 10);
//checkUserInfo();
}
// 當「新創計劃」頁面已載入時進行的回呼
function onFoundationPlanPageLoaded() {
}
//當「最萌亂鬥大賽」頁面已載入時進行的回呼
function onArenaInfoPageLoaded() {
setTimeout(arenaInfoEvent, 10);
}
/*********ACGNListenerScript**********/
/*************************************/
/*************************************/
/*************StartScript*************/
//本區StartFunction startEvent()
function startEvent()
{
checkSeriousError();
setTimeout(checkScriptEvent, 1);
//前2項十分重要,需最優先執行
setTimeout(checkCsDatasUpdateTime, 1000);
setTimeout(addAD, 2000);
setTimeout(checkOthersScript, 2500);
setTimeout(checkUserID, 3900);
setTimeout(addPluginDropdownMenuEvent, 5000);
setTimeout(checkOthersScript, 180000);
}
function checkUserID()
{
myID = String(Meteor.connection._userId);
console.log("userID: " + myID);
if (myID === "null")
setTimeout(checkUserID, 15000);
else
setTimeout(checkUserID, 300000);
}
/*************StartScript*************/
/*************************************/
/*************************************/
/**********ResetLocalStorage**********/
//本區StartFunction checkSeriousError()
function checkSeriousError()
{
//這個function將會清空所有由本插件控制的localStorage
//用於如果上一版發生嚴重錯誤導致localStorage錯亂,以致插件無法正常啟動時
//或是用於當插件更新時,需要重設localStorage
var seriousErrorVersion = 3.701;
//seriousErrorVersion會輸入有問題的版本號,當發生問題時我會增加本數字,或是於更新需要時亦會增加
//使用者本地的數字紀錄如果小於這個數字將會清空所有localStorage
var lastErrorVersion = 0 !== window.localStorage.getItem ("lastErrorVersion") ? Number(JSON.parse(window.localStorage.getItem ("lastErrorVersion"))) : 0;
//lastErrorVersion = 0; //你如果覺得現在就有問題 可以把這行的註解取消掉來清空localStorage
if (Number.isNaN(lastErrorVersion))
{
lastErrorVersion = 0;
console.log("reset lastErrorVersion as 0");
}
else
{
console.log("localStorage of lastErrorVersion is work");
}
if (lastErrorVersion < seriousErrorVersion)
{
console.log("last version has serious error, start remove all localStorage");
window.localStorage.removeItem("Dividend_UpdateTime");
window.localStorage.removeItem("Dividend");
window.localStorage.removeItem("local_CsDatas_UpdateTime");
window.localStorage.removeItem("local_CsDatas");
window.localStorage.removeItem("lastErrorVersion");
lastErrorVersion = seriousErrorVersion;
window.localStorage.setItem("lastErrorVersion", JSON.stringify(lastErrorVersion));
}
}
/**********ResetLocalStorage**********/
/*************************************/
/*************************************/
/************UpdateScript*************/
//本區StartFunction checkScriptEvent()
function checkScriptEvent()
{
var myVersion = GM_info.script.version;
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", checkScriptVersion);
oReq.open("GET", "https://gf.qytechs.cn/scripts/33542.json");
oReq.send();
}
function checkScriptVersion()
{
var obj = JSON.parse(this.responseText);
var myVersion = GM_info.script.version;
console.log(obj.version.substr(0, 4) + "," + myVersion.substr(0, 4) + "," + (obj.version.substr(0, 4) > myVersion.substr(0, 4)));
if(obj.version.substr(0, 4) > myVersion.substr(0, 4))
$('<li class="nav-item"><a class="nav-link btn btn-primary" href="https://gf.qytechs.cn/zh-TW/scripts/33542" id="UpdateDividendScript" target="Blank">' + Dict[lan].updateDividendScript + '</a></li>').insertAfter($('.nav-item')[$('.nav-item').length - 1]);
else
setTimeout(checkScriptEvent, 600000);
}
/************UpdateScript*************/
/*************************************/
/*************************************/
/**********CheckOthersScript**********/
//本區StartFunction checkOthersScript()
//檢查是否有安裝其他腳本
function checkOthersScript()
{
console.log("start checkOthersScript()");
const papago89 = check_papago89_Script();
if (papago89)
addToScriptList("papago89");
console.log("complete checkOthersScript()");
}
function addToScriptList(scriptName)
{
const scriptIndex = othersScript.findIndex(n => n == scriptName);
if (scriptIndex === -1)
othersScript.push(scriptName);
}
//檢查是否有安裝papago89的腳本
function check_papago89_Script()
{
const papago89_Script = $('#about-script').length;
if (papago89_Script > 0)
{
console.log("-----found papago89 script");
return true;
}
else
return false;
}
/**********CheckOthersScript**********/
/*************************************/
/*************************************/
/***********GetDataBaseData***********/
//所有外連DB的function都寫在這裡
//所有可以用網頁呈現的DB都用這個去call
function getWebData(url)
{
let webObjCache = null;
const webUrl = String(url);
const request = new XMLHttpRequest();
request.open("GET", webUrl); // 非同步 GET
request.addEventListener("load", () => {
debugConsole("got webData");
try {
webObjCache = JSON.parse(request.responseText);
}
catch(err) {
webObjCache = request.responseText;
}
});
request.send();
return (callback) => {
// 若快取資料存在,則直接回傳快取
if (webObjCache !== null)
{
callback(webObjCache);
return;
}
// 若無快取資料,則加入事件監聽,等載入後再回傳資料
request.addEventListener("load", function() {
callback(webObjCache);
});
};
}
//連上web來取得資料
/**
* 以非同步方式取得另外整理過的公司資料 json
*
* 考慮資料更新週期極長,若是已經取得過資料,就將之前取得的資料快取回傳
*
* 使用方法:
* const getData = getWebData("https://www.google.com"); //這邊請把google換成你要連的網址
* getData(a => {
* // 這裡的 a 即為該 json 物件
* console.log(a);
* });
*
* //有呼叫const的function請務必用setTimeout執行,以防錯誤,即使0秒也行
* setTimeout(fun_a, 0);
* function fun_a() {
* getData(a => {
* console.log(a);
* }
* }
*/
const companies_jsonbin = "https://acgnstock-data.firebaseio.com/ACGNstock-company/companys.json";
const companies_jsonbin_updatetime = "https://acgnstock-data.firebaseio.com/ACGNstock-company/updateTime.json";
const AD_jsonbin = "https://api.jsonbin.io/b/5a2403f32f8952425fe50153";
/***********GetDataBaseData***********/
/*************************************/
/*************************************/
/************updateCsDatas************/
//本區StartFunction checkCsDatasUpdateTime()
function checkCsDatasUpdateTime()
{
console.log("start checkCsDatasUpdateTime()");
var CsDatas_UpdateTime = JSON.parse(window.localStorage.getItem ("local_CsDatas_UpdateTime")) || "null";
const get_companies_jsonbin_updatetime = getWebData(companies_jsonbin_updatetime);
get_companies_jsonbin_updatetime(json_updateTime =>
{
console.log("json_updateTime === CsDatas_UpdateTime : " + (json_updateTime === CsDatas_UpdateTime));
if (json_updateTime === CsDatas_UpdateTime)
{
console.log("dont need update " + CsDatas_UpdateTime);
}
else
{
console.log("server update time: " + json_updateTime);
console.log("local update time: " + CsDatas_UpdateTime);
console.log("start update data");
setTimeout(updateCsDatas, 1, json_updateTime);
}
});
console.log("complete checkCsDatasUpdateTime()");
}
function updateCsDatas(updateTime)
{
console.log("start updateCsDatas()");
var CsDatas = [];
const get_companies_jsonbin = getWebData(companies_jsonbin);
get_companies_jsonbin(jsonData =>
{
for (let n = 0 ; n < jsonData.length ; n++)
{
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
const thisCompany = jsonData[n];
CsDatas.push({
"companyID": String(thisCompany.companyID), "companyName": String(thisCompany.companyName),
"companyPrice": Number(thisCompany.companyPrice), "companyStock": Number(thisCompany.companyStock),
"companyProfit": Number(thisCompany.companyProfit),
"companySalary": Number(thisCompany.companySalary), "companyNextSeasonSalary": Number(thisCompany.companyNextSeasonSalary),
"companyBonus": Number(thisCompany.companyBonus),
"companyEmployeesNumber": Number(thisCompany.companyEmployeesNumber),
"companyNextSeasonEmployeesNumber": Number(thisCompany.companyNextSeasonEmployeesNumber)
});
//debugConsole("push success")
}
window.localStorage.setItem ("local_CsDatas", JSON.stringify(CsDatas));
if (updateTime === null || updateTime === undefined)
{
window.localStorage.setItem ("local_CsDatas_UpdateTime", JSON.stringify("no data"));
}
else
{
window.localStorage.setItem ("local_CsDatas_UpdateTime", JSON.stringify(updateTime));
}
console.log("complete updateCsDatas()");
});
}
/************updateCsDatas************/
/*************************************/
/*************************************/
/**************scriptAD***************/
//本區StartFunction addAD()
function addAD()
{
console.log("start add script AD");
var data, adNumber, link, linkNumber = 0, linkType;
$('<a class="scriptAD float-left" id="scriptAD-0"> </a>').insertAfter($('.text-danger.float-left'));
const get_AD_jsonbin = getWebData(AD_jsonbin);
get_AD_jsonbin(jsonData =>
{
console.log("ADnumber:" + jsonData.adFormat.length);
for (let adF = 0 ; adF < jsonData.adFormat.length ; ++adF)
{
console.log("adding AD");
adNumber = Number($('.scriptAD').length);
data = jsonData.adData[adF];
if (jsonData.adFormat[adF] == "a")
{
$('<a class="scriptAD float-left" id="scriptAD-' + adNumber + '">' + data + '</a>')
.insertAfter($('#scriptAD-' + (adNumber - 1)));
}
else if (jsonData.adFormat[adF] == "aLink")
{
link = jsonData.adLink[linkNumber];
linkType = jsonData.adLinkType[linkNumber];
//console.log(linkType);
//console.log((linkType != "_blank"));
if ((linkType != "_blank") && (linkType != "_parent") && (linkType != "_top"))
linkType = "";
//linkType = "";
$('<a class="scriptAD float-left" id="scriptAD-' + adNumber + '" href="' + link + '" target="' + linkType + '">' + data + '</a>').insertAfter($('#scriptAD-' + (adNumber - 1)));
linkNumber += 1;
}
}
console.log("success add script AD");
});
}
/**************scriptAD***************/
/*************************************/
/*************************************/
/**********pluginDropdownMenu*********/
//本區StartFunction addPluginDropdownMenuEvent()
function addPluginDropdownMenuEvent()
{
setTimeout(addMostStockDropdownMenu, 100);
}
function addMostStockDropdownMenu()
{
console.log("start addMostStockDropdownMenu()");
// 所有按鍵插入在原來的第三個按鍵(主題配置)之後
// 按鍵需要以倒序插入,後加的按鍵會排在左邊
const insertionTarget = $(".note")[2];
const mostStockDropDown = $(`
<div class="note">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">${t("mostStockDropDown")}</a>
<div class="dropdown-menu px-3" aria-labelledby="navbarDropdownMenuLink" style="display: none;" id="stock-menu">
<h6 class="dropdown-header" style="padding: 0.5rem 0rem" id="company-list">${t("mostStockDropDown")}</h6>
</div>
</li>
</div>
`);
mostStockDropDown.insertAfter(insertionTarget);
setTimeout(addMostStockDropdownMenuDetail, 10);
console.log("end addMostStockDropdownMenu()");
}
function addMostStockDropdownMenuDetail()
{
if (myHoldStock.length > 0)
{
console.log("start addMostStockDropdownMenuDetail()");
const top = $('#company-list');
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
var myStockRanked = myHoldStock;
myStockRanked = myStockRanked.sort(function(a, b)
{
debugConsole("-----addMostStockDropdownMenuDetail()-myStockRanked.sort");
//排序
const aIndex = CsDatas.findIndex(x => x.companyID == a.companyId);
const bIndex = CsDatas.findIndex(y => y.companyID == b.companyId);
debugConsole("------myStockRanked.sort a: " + a.companyId);
debugConsole("------myStockRanked.sort b: " + b.companyId);
if ((aIndex !== -1) && (bIndex !== -1))
{
//當2間公司都有資料,可以計算之間的排序
const aPercent = Number(a.stocks) / Number(CsDatas[aIndex].companyStock);
const bPercent = Number(b.stocks) / Number(CsDatas[bIndex].companyStock);
return (bPercent - aPercent);
}
else if (aIndex !== -1)
{
//只有a有資料,a排前面
return -1;
}
else if (bIndex !== -1)
{
//只有b有資料,b排前面
return 1;
}
else
{
//都沒資料,不動排序
return 0;
}
});
debugConsole("-----end addMostStockDropdownMenuDetail()-myStockRanked.sort");
let i = 0, j = 0;
let list = "";
while ((i < 10000) && (myStockRanked.length > i) && (j < 30))
{
debugConsole("-----addMostStockDropdownMenuDetail()-addButton");
const aIndex = CsDatas.findIndex(x => x.companyID == myStockRanked[i].companyId);
if (aIndex !== -1)
{
list += (`<a class="nav-link"
href="/company/detail/${myStockRanked[i].companyId}"
id="company-link">
${CsDatas[aIndex].companyName}</a>`);
j += 1;
}
i += 1;
}
$(list).insertAfter(top);
console.log("end addMostStockDropdownMenuDetail()");
}
else
{
console.log("myHoldStock not ready, restart addMostStockDropdownMenuDetail() after 10s");
setTimeout(addMostStockDropdownMenuDetail, 10000);
}
}
/**********pluginDropdownMenu*********/
/*************************************/
/*************************************/
/************stockSummary*************/
//本區StartFunction stockSummaryEvent()
function stockSummaryEvent()
{
//setTimeout(getBasicUserData, 500, 0);
getBasicUserData(0);
setTimeout(useCompaniesDatasEvent, 600);
}
function getBasicUserData(runNumber)
{
console.log("start getBasicUserData()");
var restart = false;
if (runNumber < 10)
{
runNumber += 1;
if (Meteor.connection._mongo_livedata_collections.directors.find().fetch().length > 0)
myHoldStock = Meteor.connection._mongo_livedata_collections.directors.find().fetch();
else
restart = true;
if (Meteor.connection._mongo_livedata_collections.orders.find().fetch().length > 0)
myOrders = Meteor.connection._mongo_livedata_collections.orders.find().fetch();
else
restart = true;
}
/*if (restart)
setTimeout(getBasicUserData, 1000, runNumber);*/
console.log("complete getBasicUserData()");
console.log("");
}
function useCompaniesDatasEvent()
{
var companiesDatas = Meteor.connection._mongo_livedata_collections.companies.find().fetch();
if (companiesDatas.length > 0)
{
console.log("start useCompaniesDatasEvent()");
var profit, price, ID, release, earnPerShare, manager, hold, name;
var bonus = 5, salary = 0;
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
//如果執行的function需要存值,放在這裡
var value_computeProfit = 0;
var value_BatchAddCsDatasLocalStorage_1 = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
var value_BatchAddCsDatasLocalStorage_2 = false;
var value_BatchAddCsDatasLocalStorage = [value_BatchAddCsDatasLocalStorage_1, value_BatchAddCsDatasLocalStorage_2];
var value_isEnd = false;
for (let i = 0; i < companiesDatas.length; ++i)
{
let thisCompany = companiesDatas[i];
profit = Number(thisCompany.profit);
price = Number(thisCompany.listPrice);
ID = String(thisCompany._id);
release = Number(thisCompany.totalRelease);
earnPerShare = Number((profit * 0.8) / release);
manager = String(thisCompany.manager);
name = String(thisCompany.companyName);
const CDindex = CsDatas.findIndex(c => c.companyID == ID);
if (CDindex !== -1)
{
bonus = Number(CsDatas[CDindex].companyBonus);
salary = Number(CsDatas[CDindex].companySalary);
if (CsDatas[CDindex].companyEmployeesNumber > 0)
earnPerShare = Number((profit * (0.8 - (bonus * 0.01))) / release);
}
const MHSindex = myHoldStock.findIndex(a => a.companyId == ID);
if (MHSindex === -1)
hold = 0;
else
hold = Number(myHoldStock[MHSindex].stocks);
console.log(String(ID + "---" + name + "---" +
price + "---" + release + "---" + profit + "---" + earnPerShare + "---" + hold + "---" +
manager));
//需要執行的function放在這
value_computeProfit = computeProfit(ID, earnPerShare, hold, value_computeProfit);
value_isEnd = (i + 1 >= companiesDatas.length);
value_BatchAddCsDatasLocalStorage = BatchAddCsDatasLocalStorage(ID, name, profit, price, release, value_BatchAddCsDatasLocalStorage, value_isEnd);
const papago89_Script = othersScript.findIndex(n => n == "papago89");
if (papago89_Script === -1)
SSAddSomeInfo(ID, earnPerShare, price, hold, manager, profit);
console.log("");
}
console.log("complete computeProfit()");
console.log("");
}
else
{
console.log("companiesDatas not ready, restart useCompaniesDatasEvent() after 2s");
setTimeout(useCompaniesDatasEvent, 2000);
}
}
//總獲利計算--加入分紅計算
function computeProfit(ID, earnPerShare, hold, sumProfit)
{
console.log("---start computeProfit()");
var classProfit;
sumProfit += earnPerShare * hold;
console.log("-----預計分紅: " + sumProfit);
classProfit = $("#totalProfitNumber");
if (classProfit.length === 0)
{
$('<div class="media company-summary-item border-grid-body" id = "totalProfit"><div class="col-6 text-right border-grid" id = "totalProfitTitle"><h2>' + Dict[lan].totalProfitInThisPage + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "totalProfitNumber"><h2>$ ' + sumProfit.toFixed() + '</h2></div>').insertAfter($('#totalProfitTitle')[0]);
}
else
{
$("#totalProfitNumber")[0].innerHTML = "<h2>$ " + sumProfit.toFixed() + "</h2>";
}
console.log("---complete computeProfit()");
return sumProfit;
}
//批量將公司資料加入localStorage
function BatchAddCsDatasLocalStorage(ID, name, profit, price, release, inputValue, isEnd)
{
console.log("---start BatchAddCsDatasLocalStorage()");
var CsDatas = inputValue[0];
var isChange = inputValue[1];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
let index = CsDatas.findIndex(x => x.companyID == ID);
if (index != -1)
{
if ((CsDatas[index].companyPrice == price) &&
(CsDatas[index].companyStock == release) &&
(CsDatas[index].companyStock == profit))
{
debugConsole("-----dont need update LocalStorage");
}
else
{
isChange = true;
const salary = CsDatas[index].companySalary;
const nextSeasonSalary = CsDatas[index].companyNextSeasonSalary;
const bonus = CsDatas[index].companyBonus;
const employeesNumber = CsDatas[index].companyEmployeesNumber;
const nextSeasonEmployeesNumber = CsDatas[index].companyNextSeasonEmployeesNumber;
CsDatas.splice(index, 1);
debugConsole("-----AddCsDatasLocalStorage---splice");
CsDatas.push({
"companyID": ID, "companyName": name,
"companyPrice": Number(price), "companyStock": Number(release), "companyProfit": Number(profit),
"companySalary": Number(salary), "companyNextSeasonSalary": Number(nextSeasonSalary), "companyBonus": Number(bonus),
"companyEmployeesNumber": Number(employeesNumber),
"companyNextSeasonEmployeesNumber": Number(nextSeasonEmployeesNumber)
});
debugConsole("-----Add local_CsDatas LocalStorage!!");
}
}
else
{
isChange = true;
CsDatas.push({
"companyID": ID, "companyName": name,
"companyPrice": Number(price), "companyStock": Number(release), "companyProfit": Number(profit),
"companySalary": Number(1000), "companyNextSeasonSalary": Number(1000), "companyBonus": Number(5),
"companyEmployeesNumber": Number(0),
"companyNextSeasonEmployeesNumber": Number(0)
});
debugConsole("-----AddCsDatasLocalStorage!!");
}
debugConsole("-----BatchAddCsDatasLocalStorage()---isChange: " + isChange + "---isEnd: " + isEnd + "---");
if (isChange && isEnd)
{
window.localStorage.setItem ("local_CsDatas", JSON.stringify(CsDatas));
debugConsole("-----setItem---local_CsDatas");
}
outputValue = [CsDatas, isChange];
console.log("---complete BatchAddCsDatasLocalStorage()");
return outputValue;
}
function SSAddSomeInfo(ID, earnPerShare, price, hold, manager, profit)
{
if($(".col-12.col-md-6.col-lg-4.col-xl-3").length > 0)
{
//會加入 本益比 股價總值 現金股利 經理薪水
console.log("---start SSAddSomeInfo()");
var classInfo;
var PE, stockWorth, stockProfit, managerSalary;
PE = price / earnPerShare;
PE = PE.toFixed(3);
stockWorth = price * hold;
stockProfit = (earnPerShare * hold).toFixed();
managerSalary = (profit * 0.05).toFixed();
let i = 0;
for (i = 0 ; i < $('.title a').length ; i++)
{
if (ID == String($('.title a')[i].href.match(/\/company\/detail\/([^]+)/)[1]))
break;
}
debugConsole("-----SSAddSomeInfo()---" + ID + "---" + i + "---" + PE + "---" + stockWorth + "---" + stockProfit + "---" + managerSalary + "---");
classInfo = $("#stockPEInfo_" + i);
if (classInfo.length === 0)
{
if (myID == manager)
$('<div name="stockPEInfo" class="row row-info d-flex justify-content-between" id="stockManagerSalaryInfo_' + i + '"><p>' + Dict[lan].stockManagerSalaryInfo + '</p><p>' + managerSalary + '</p></div>').insertAfter($('.company-card')[i].children[6]);
$('<div name="stockPEInfo" class="row row-info d-flex justify-content-between" id="stockProfitInfo_' + i + '"><p>' + Dict[lan].stockProfitInfo + '</p><p>' + stockProfit + '</p></div>').insertAfter($('.company-card')[i].children[6]);
$('<div name="stockPEInfo" class="row row-info d-flex justify-content-between" id="stockWorthInfo_' + i + '"><p>' + Dict[lan].stockWorthInfo + '</p><p>' + stockWorth + '</p></div>').insertAfter($('.company-card')[i].children[6]);
$('<div name="stockPEInfo" class="row row-info d-flex justify-content-between" id="stockPEInfo_' + i + '"><p>' + Dict[lan].stockPEInfo + '</p><p>' + PE + '</p></div>').insertAfter($('.company-card')[i].children[6]);
}
console.log("---complete SSAddSomeInfo()");
}
}
/************stockSummary*************/
/*************************************/
/*************************************/
/**************company****************/
//本區StartFunction companyEvent()
function companyEvent()
{
setTimeout(company_AddCsDatasLocalStorage, 1);
}
function company_AddCsDatasLocalStorage()
{
const companiesDatas = Meteor.connection._mongo_livedata_collections.companies.find().fetch();
const employeesDatas = Meteor.connection._mongo_livedata_collections.employees.find().fetch();
if (companiesDatas.length > 0)
{
console.log("start company_AddCsDatasLocalStorage()");
var profit, price, ID, release, earnPerShare, manager, hold, name;
var salary, nextSeasonSalary, bonus;
var employeesNumber = 0, nextSeasonEmployeesNumber = 0;
let thisCompany = companiesDatas[0];
profit = Number(thisCompany.profit);
price = Number(thisCompany.listPrice);
ID = String(thisCompany._id);
release = Number(thisCompany.totalRelease);
earnPerShare = (Number(thisCompany.profit) * 0.8 / Number(thisCompany.totalRelease));
manager = String(thisCompany.manager);
name = String(thisCompany.companyName);
salary = Number(thisCompany.salary);
nextSeasonSalary = Number(thisCompany.nextSeasonSalary);
bonus = Number(thisCompany.seasonalBonusPercent);
for (let empData of employeesDatas)
{
if ((empData.employed) && (empData.companyId === ID))
employeesNumber += 1;
else if ((empData.employed === false) && (empData.companyId === ID) && (empData.resigned === false))
nextSeasonEmployeesNumber += 1;
}
if (employeesNumber > 0)
earnPerShare = Number((profit * (0.8 - (bonus * 0.01))) / release);
console.log("---" + ID + "---" + name + "---");
//debugConsole(String("---" + ID + "---" + name + "---"));
debugConsole(String("price: " + price + " release: " + release + " profit: " + profit));
debugConsole(String("salary: " + salary + " nextSeasonSalary: " + nextSeasonSalary + " bonus: " + bonus));
debugConsole(String("employeesNumber: " + employeesNumber + " nextSeasonEmployeesNumber: " + nextSeasonEmployeesNumber));
var CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
inputData = {
"companyID": ID, "companyName": name,
"companyPrice": Number(price), "companyStock": Number(release), "companyProfit": Number(profit),
"companySalary": Number(salary), "companyNextSeasonSalary": Number(nextSeasonSalary), "companyBonus": Number(bonus),
"companyEmployeesNumber": Number(employeesNumber),
"companyNextSeasonEmployeesNumber": Number(nextSeasonEmployeesNumber)
};
//如果先前紀錄過該公司,則刪除重記
const index = CsDatas.findIndex(x => x.companyID == ID);
if (index != -1)
{
if (CsDatas[index] === inputData)
{
debugConsole("dont need update cookie");
}
else
{
CsDatas.splice(index, 1);
debugConsole("AddCsDatasCookie---splice");
CsDatas.push(inputData);
window.localStorage.setItem ("local_CsDatas", JSON.stringify(CsDatas));
debugConsole("Add CsDatas localStorage!!");
}
}
else
{
CsDatas.push(inputData);
window.localStorage.setItem ("local_CsDatas", JSON.stringify(CsDatas));
debugConsole("AddCsDatasLocalStorage!!");
}
console.log("complete company_AddCsDatasLocalStorage()");
console.log("");
}
else
{
console.log("companiesDatas not ready, restart company_AddCsDatasLocalStorage() after 2s");
setTimeout(company_AddCsDatasLocalStorage, 2000);
}
}
/**************company****************/
/*************************************/
/*************************************/
/*************accountInfo*************/
//本區StartFunction checkUserInfo()
function checkUserInfo()
{
console.log("start checkUserInfo()");
const userID = String(document.location.href.match(/accountInfo\/([0-z]+)/)[1]);
console.log("-----checkUserInfo() userID = " + userID);
var userStockInfo = JSON.parse(window.sessionStorage.getItem ("userStockInfo")) || [];
//userStcokInfo的格式:
//{"userID": "CWgfhqxbrJMxsknrb",
// "userCompany": [{"companyID": aaa, "userHold": number}, {}]
// "userManage": [{"companyID": aaa}, {}]
// "userEmployee": {"companyID": aaa} }
// userEmployee暫時用不到
var userIndex = userStockInfo.findIndex(a => a.userID == userID);
debugConsole("-----checkUserInfo() userIndex = " + userIndex);
if (userIndex == -1)
{
userStockInfo.push({"userID": userID,
"userCompany": [],
"userManage": [],
"userEmployee": {"companyID": null}
});
userIndex = userStockInfo.findIndex(a => a.userID == userID);
debugConsole("-----checkUserInfo() userIndex = " + userIndex);
}
window.sessionStorage.setItem ("userStockInfo", JSON.stringify(userStockInfo));
if ($('.card-title').length > 0)
{
var managerSalary = Number(computeManagerSalary(userID));
var employeeBonus = Number(computeEmployeeBonus());
debugConsole("-----checkUserInfo() userID = " + userID + " , myID = " + myID + " , userID == myID : " + (userID == myID));
if ((userID == myID) && (myHoldStock.length > 0))
{
checkMyHoldStock();
addUserProfitInfo(userID, managerSalary, employeeBonus);
}
checkUserHoldStock(userID, 0, managerSalary, employeeBonus);
addUserProfitInfo(userID, managerSalary, employeeBonus);
}
else
{
console.log("$('.card-title') is not ready, restart checkUserInfo() after 2s");
setTimeout(checkUserInfo, 2000);
}
console.log("complete checkUserInfo()");
console.log("");
}
function computeManagerSalary(userID)
{
console.log("---start computeManagerSalary()");
var profit, managerSalary = 0;
const companyTitleView = $('.nav-link.active')[0].text;
var userStockInfo = JSON.parse(window.sessionStorage.getItem ("userStockInfo")) || [];
const userIndex = userStockInfo.findIndex(a => a.userID == userID);
//userStcokInfo的格式:
//{"userID": "CWgfhqxbrJMxsknrb",
// "userCompany": [{"companyID": aaa, "userHold": number}, {}]
// "userManage": [{"companyID": aaa}, {}]
// "userEmployee": {"companyID": aaa} }
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
console.log("-----computeManagerSalary()-----companyTitleView === \"經理人\": " + (companyTitleView === "經理人"));
if (companyTitleView === "經理人") //可以獲得經理資訊,更新userStockInfo
{
const companiesDatas = Meteor.connection._mongo_livedata_collections.companies.find().fetch();
debugConsole("-----computeManagerSalary()-----companiesDatas.length: " + companiesDatas.length);
for (let i = 0 ; i < companiesDatas.length ; i++)
{
const ID = companiesDatas[i]._id;
const companyIndex = userStockInfo[userIndex].userManage.findIndex(a => a.companyID == ID);
debugConsole("-----computeManagerSalary()-----manage: " + ID + " index: " + companyIndex);
if (companyIndex === -1)
{
userStockInfo[userIndex].userManage.push({"companyID": ID});
debugConsole("-----computeManagerSalary()-----add into userStockInfo");
}
}
window.sessionStorage.setItem ("userStockInfo", JSON.stringify(userStockInfo));
}
//使用userStockInfo的資訊 計算managerSalary
console.log("-----computeManagerSalary()-----userManage.length: " + userStockInfo[userIndex].userManage.length);
for (let i = 0 ; i < userStockInfo[userIndex].userManage.length ; i++)
{
const ID = userStockInfo[userIndex].userManage[i].companyID;
const companyIndex = CsDatas.findIndex(a => a.companyID == ID);
if (companyIndex === -1)
{
debugConsole("-----computeManagerSalary()-----not found company " + ID);
}
else
{
profit = CsDatas[companyIndex].companyProfit;
debugConsole("-----computeManagerSalary()-----" + ID + "-----" + profit + "-----");
managerSalary += Number(profit * 0.05);
debugConsole("-----computeManagerSalary()-----" + managerSalary);
}
}
//完成後自動開始新增資訊
//但如果沒有經理薪水就不會新增
console.log("-----computeManagerSalary()-----" + managerSalary);
if (managerSalary > 0)
addManagerSalaryInfo(managerSalary);
console.log("---complete computeManagerSalary()");
return managerSalary;
}
function addManagerSalaryInfo(managerSalary)
{
console.log("---start addManagerSalaryInfo()");
managerSalary = Number(managerSalary);
var classManagerSalaryInfo = $("#managerSalaryInfoNumber");
if(classManagerSalaryInfo.length === 0)
{
$('<div class="media account-info-item border-grid-body" id = "managerSalaryInfo"><div class="col-6 text-right border-grid" id = "managerSalaryInfoTitle"><h2>' + Dict[lan].managerTotalSalary + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "managerSalaryInfoNumber"><h2>$ ' + managerSalary.toFixed() + '</h2></div>').insertAfter($('#managerSalaryInfoTitle')[0]);
}
else
{
$("#managerSalaryInfoNumber")[0].innerHTML = "<h2>$ " + managerSalary.toFixed() + "</h2>";
}
console.log("---complete addManagerSalaryInfo()");
}
function computeEmployeeBonus()
{
console.log("---start computeEmployeeBonus()");
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
const employeesDatas = Meteor.connection._mongo_livedata_collections.employees.find().fetch();
var employeeBonus = 0;
for (let emp of employeesDatas)
{
if (emp.employed)
{
const companyIndex = CsDatas.findIndex(c => c.companyID === emp.companyId);
if (companyIndex !== -1)
{
debugConsole("-----computeEmployeeBonus()-----" + emp.companyId + "-----");
debugConsole("-----computeEmployeeBonus()-----" + CsDatas[companyIndex].companyProfit + "-----" +
CsDatas[companyIndex].companyBonus + "-----" + CsDatas[companyIndex].companyEmployeesNumber + "-----");
let bonus = 0;
if (Number(CsDatas[companyIndex].companyEmployeesNumber) > 0)
bonus = Number(CsDatas[companyIndex].companyProfit
* Number(CsDatas[companyIndex].companyBonus * 0.01)
/ Number(CsDatas[companyIndex].companyEmployeesNumber));
employeeBonus += bonus;
debugConsole("-----computeEmployeeBonus()-----" + employeeBonus + "-----");
}
}
}
console.log("-----computeEmployeeBonus()-----" + employeeBonus);
if (employeeBonus > 0)
addEmployeeBonusInfo(employeeBonus);
console.log("---complete computeEmployeeBonus()");
return employeeBonus;
}
function addEmployeeBonusInfo(employeeBonus)
{
console.log("---start addEmployeeBonusInfo()");
employeeBonus = Number(employeeBonus);
var classEmployeeBonusInfo = $("#employeeBonusInfoNumber");
if(classEmployeeBonusInfo.length === 0)
{
$('<div class="media account-info-item border-grid-body" id = "employeeBonusInfo"><div class="col-6 text-right border-grid" id = "employeeBonusInfoTitle"><h2>' + Dict[lan].employeeTotalBonus + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "employeeBonusInfoNumber"><h2>$ ' + employeeBonus.toFixed() + '</h2></div>').insertAfter($('#employeeBonusInfoTitle')[0]);
}
else
{
$("#employeeBonusInfoNumber")[0].innerHTML = "<h2>$ " + employeeBonus.toFixed() + "</h2>";
}
console.log("---complete addEmployeeBonusInfo()");
}
function checkUserHoldStock(userID, CUHS_runNumber, managerSalary, employeeBonus)
{
const directors = Meteor.connection._mongo_livedata_collections.directors.find().fetch();
if (directors.length > 0)
{
console.log("---start checkUserHoldStock()");
/*if ($("[data-toggle-panel=stock]").parent().next().children().last().length > 0)
addNotCompleteMessage();*/
console.log("-----userID: " + userID + " CUHS_runNumber: " + CUHS_runNumber +
" managerSalary: " + managerSalary + " employeeBonus: " + employeeBonus);
var userStockInfo = JSON.parse(window.sessionStorage.getItem ("userStockInfo")) || [];
//userStcokInfo的格式:
//{"userID": "CWgfhqxbrJMxsknrb",
// "userCompany": [{"companyID": aaa, "userHold": number}, {}]
// "userManage": [{"companyID": aaa}, {}]
// "userEmployee": {"companyID": aaa} }
const userIndex = userStockInfo.findIndex(a => a.userID == userID);
var ID, hold;
var isChange = false;
for (let i = 0 ; i < directors.length ; i++)
{
ID = String(directors[i].companyId);
hold = Number(directors[i].stocks);
debugConsole("-----" + ID + "-----" + hold + "-----");
const companyIndex = userStockInfo[userIndex].userCompany.findIndex(b => b.companyID == ID);
if (companyIndex != -1)
{
if (Number(userStockInfo[userIndex].userCompany[companyIndex].userHold) == hold)
{
//debugConsole("dont need update this company");
}
else
{
isChange = true;
userStockInfo[userIndex].userCompany.splice(companyIndex, 1);
userStockInfo[userIndex].userCompany.push({"companyID": ID, "userHold": hold});
}
}
else
{
isChange = true;
userStockInfo[userIndex].userCompany.push({"companyID": ID, "userHold": hold});
}
}
//怕是資料還沒更新完成就開始執行,如果完全沒有變化會再次執行,共確認3次
//目前將確認3次的部分暫時移除,僅做一次更新
if (isChange)
{
window.sessionStorage.setItem ("userStockInfo", JSON.stringify(userStockInfo));
//addCompleteMessage();
//setTimeout(addUserProfitInfo, 10, userID, managerSalary, employeeBonus);
}
else
{
/*if (CUHS_runNumber < 3)
setTimeout(checkUserHoldStock, 100, userID, CUHS_runNumber+1, managerSalary);
else
{
addCompleteMessage();
setTimeout(addUserProfitInfo, 10, userID, managerSalary);
}*/
//addCompleteMessage();
//setTimeout(addUserProfitInfo, 10, userID, managerSalary, employeeBonus);
}
console.log("---complete checkUserHoldStock()");
}
}
function addCompleteMessage()
{
var pageNum = "1";
if (($(".page-item.active")[1] !== undefined) && ($(".page-item.active")[1] !== null))
pageNum = $(".page-item.active")[1].textContent;
if ($("#CompleteMessage").length === 0) {
$(`<button class="btn btn-danger btn-sm" type="button" disabled="disabled" id="CompleteMessage">第${pageNum}頁統計完成</button>`)
.insertAfter($("[data-toggle-panel=stock]").parent().next().children().last());
}
else
{
$("#CompleteMessage")[0].innerHTML = `第${pageNum}頁統計完成`;
}
}
function addNotCompleteMessage()
{
//const pageNum = $(".page-item.active").text();
if ($("#CompleteMessage").length === 0) {
$(`<button class="btn btn-danger btn-sm" type="button" disabled="disabled" id="CompleteMessage">還沒有統計完成</button>`)
.insertAfter($("[data-toggle-panel=stock]").parent().next().children().last());
if ($("#clear-asset-message-btn").length > 0) //為了將訊息移動到正確的位置
{
$("#clear-asset-message-btn").click();
if ($("#compute-btn").length > 0)
$("#compute-btn").click();
}
}
else
{
$("#CompleteMessage")[0].innerHTML = `還沒有統計完成`;
}
}
function checkMyHoldStock()
{
console.log("---start checkMyHoldStock()");
var userStockInfo = JSON.parse(window.sessionStorage.getItem ("userStockInfo")) || [];
//userStcokInfo的格式:
//{"userID": "CWgfhqxbrJMxsknrb",
// "userCompany": [{"companyID": aaa, "userHold": number}, {}]
// "userManage": [{"companyID": aaa}, {}]
// "userEmployee": {"companyID": aaa} }
const userID = myID;
const userIndex = userStockInfo.findIndex(a => a.userID == userID);
var ID, hold;
const directors = myHoldStock;
//避免重複不斷的更新
if (directors.length != userStockInfo[userIndex].userCompany.length)
{
for (let i = 0 ; i < directors.length ; i++)
{
ID = String(directors[i].companyId);
hold = Number(directors[i].stocks);
debugConsole("-----" + ID + "-----" + hold + "-----");
const companyIndex = userStockInfo[userIndex].userCompany.findIndex(b => b.companyID == ID);
if (companyIndex != -1)
{
if (Number(userStockInfo[userIndex].userCompany[companyIndex].userHold) == hold)
{
//console.log("dont need update this company");
}
else
{
userStockInfo[userIndex].userCompany.splice(companyIndex, 1);
userStockInfo[userIndex].userCompany.push({"companyID": ID, "userHold": hold});
}
}
else
{
userStockInfo[userIndex].userCompany.push({"companyID": ID, "userHold": hold});
}
}
window.sessionStorage.setItem ("userStockInfo", JSON.stringify(userStockInfo));
}
console.log("---complete checkMyHoldStock()");
}
function addUserProfitInfo(userID, managerSalary, employeeBonus)
{
console.log("---start addUserProfitInfo()");
const userStockInfo = null !== window.sessionStorage.getItem ("userStockInfo") ? JSON.parse(window.sessionStorage.getItem ("userStockInfo")) : [];
//userStcokInfo的格式:
//{"userID": "CWgfhqxbrJMxsknrb",
// "userCompany": [{"companyID": aaa, "userHold": number}, {}]
// "userManage": [{"companyID": aaa}, {}]
// "userEmployee": {"companyID": aaa} }
const userIndex = userStockInfo.findIndex(a => a.userID == userID);
//理論上到這邊userIndex就不可能是-1了啦.....
const users = Meteor.connection._mongo_livedata_collections.users.find().fetch();
debugConsole("-----userID: " + userID);
const users_i = users.findIndex(u => u._id == String(userID));
debugConsole("-----user_i: " + users_i); //for debug
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
const cash = Number(users[users_i].profile.money);
var classUserProfitInfo, userAssets = 0, userProfit = 0, userCompanyNumber = 0;
var price, earnPerShare;
for (let k = 0 ; k < userStockInfo[userIndex].userCompany.length ; k++)
{
price = 0;
earnPerShare = 0;
const companyIndex = CsDatas.findIndex(b => b.companyID == userStockInfo[userIndex].userCompany[k].companyID);
if (companyIndex != -1)
{
price = Number(CsDatas[companyIndex].companyPrice);
if (CsDatas[companyIndex].employeesNumber > 0)
earnPerShare = Number(CsDatas[companyIndex].companyProfit
* (0.8 - (CsDatas[companyIndex].companyBonus * 0.01))
/ CsDatas[companyIndex].companyStock);
else
earnPerShare = Number(CsDatas[companyIndex].companyProfit * 0.8 / CsDatas[companyIndex].companyStock);
}
userAssets += price * userStockInfo[userIndex].userCompany[k].userHold;
userProfit += earnPerShare * userStockInfo[userIndex].userCompany[k].userHold;
userCompanyNumber += 1;
}
var usingCash = 0; //正在用於買單的錢
var sellingStockWorth = 0; //正在賣的股票價值,以參考價計算
if (userID == myID)
{
const orders = myOrders;
const orderType_buy = "購入";
const orderType_sell = "賣出";
for (let j = 0 ; j < orders.length ; j++)
{
const amount = Number(orders[j].amount);
const done = Number(orders[j].done);
if (orders[j].orderType === orderType_buy)
{
const unitPrice = Number(orders[j].unitPrice);
usingCash += (unitPrice * (amount - done));
}
else if (orders[j].orderType === orderType_sell)
{
const companyIndex = CsDatas.findIndex(b => b.companyID == String(orders[j].companyId));
if (companyIndex === -1)
price = 0;
else
price = Number(CsDatas[companyIndex].companyPrice);
sellingStockWorth += (price * (amount - done));
}
else
{
console.log("-----未完成買賣單發生嚴重錯誤: 不是買單也不是賣單,你怎麼做到的......");
}
}
debugConsole("-----usingCash: " + usingCash);
debugConsole("-----sellingStockWorth: " + sellingStockWorth);
var classUserUsingCashInfo = $("#userUsingCashInfoNumber");
if(classUserUsingCashInfo.length === 0)
{
debugConsole("-----start add using cash info");
$('<div class="media account-info-item border-grid-body" id = "userSellingStockInfo"><div class="col-6 text-right border-grid" id = "userSellingStockInfoTitle"><h2>' + Dict[lan].userTotalSellingStock + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "userSellingStockInfoNumber"><h2>$ ' + sellingStockWorth + '</h2></div>').insertAfter($('#userSellingStockInfoTitle')[0]);
$('<div class="media account-info-item border-grid-body" id = "userUsingCashInfo"><div class="col-6 text-right border-grid" id = "userUsingCashInfoTitle"><h2>' + Dict[lan].userTotalUsingCash + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "userUsingCashInfoNumber"><h2>$ ' + usingCash + '</h2></div>').insertAfter($('#userUsingCashInfoTitle')[0]);
}
else
{
debugConsole("-----start update using cash info");
$("#userSellingStockInfoNumber")[0].innerHTML = "<h2>$ " + sellingStockWorth + "</h2>";
$("#userUsingCashInfoNumber")[0].innerHTML = "<h2>$ " + usingCash + "</h2>";
}
}
debugConsole("-----call compute tax");
const tax = computeTax((userAssets + userProfit + managerSalary + employeeBonus + cash + usingCash + sellingStockWorth));
var classUserTaxInfo = $("#userTaxInfoNumber");
if(classUserTaxInfo.length === 0)
{
debugConsole("-----start add tax info");
$('<div class="media account-info-item border-grid-body" id = "userTaxInfo"><div class="col-6 text-right border-grid" id = "userTaxInfoTitle"><h2>' + Dict[lan].userTotalTax + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "userTaxInfoNumber"><h2>$ ' + tax + '</h2></div>').insertAfter($('#userTaxInfoTitle')[0]);
}
else
{
debugConsole("-----start update tax info");
$("#userTaxInfoNumber")[0].innerHTML = "<h2>$ " + tax + "</h2>";
}
classUserProfitInfo = $("#userProfitInfoNumber");
if(classUserProfitInfo.length === 0)
{
debugConsole("-----start add info");
$('<div class="media account-info-item border-grid-body" id = "userProfitInfo"><div class="col-6 text-right border-grid" id = "userProfitInfoTitle"><h2>' + Dict[lan].userTotalProfit + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "userProfitInfoNumber"><h2>$ ' + userProfit.toFixed() + '</h2></div>').insertAfter($('#userProfitInfoTitle')[0]);
$('<div class="media account-info-item border-grid-body" id = "userAssetsInfo"><div class="col-6 text-right border-grid" id = "userAssetsInfoTitle"><h2>' + Dict[lan].userTotalAssets + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "userAssetsInfoNumber"><h2>$ ' + userAssets + '</h2></div>').insertAfter($('#userAssetsInfoTitle')[0]);
$('<div class="media account-info-item border-grid-body" id = "userCompanyNumberInfo"><div class="col-6 text-right border-grid" id = "userCompanyNumberInfoTitle"><h2>' + Dict[lan].userTotalCompanyNumber + '</h2></div></div>').insertAfter($('.card-title')[0]);
$('<div class="col-6 text-right border-grid" id = "userCompanyNumberInfoNumber"><h2> ' + userCompanyNumber + '</h2></div>').insertAfter($('#userCompanyNumberInfoTitle')[0]);
}
else
{
debugConsole("-----start update info");
$("#userProfitInfoNumber")[0].innerHTML = "<h2>$ " + userProfit.toFixed() + "</h2>";
$("#userAssetsInfoNumber")[0].innerHTML = "<h2>$ " + userAssets + "</h2>";
$("#userCompanyNumberInfoNumber")[0].innerHTML = "<h2> " + userCompanyNumber + "</h2>";
}
console.log("---complete addUserProfitInfo()");
}
// 稅率表:資產上限、稅率、累進差額
function computeTax(input)
{
debugConsole("---start computeTax()");
debugConsole("-----computeTax() input: " + input);
const taxRateTable = [
{ asset: 10000, rate: 0.00, adjustment: 0 },
{ asset: 100000, rate: 0.03, adjustment: 300 },
{ asset: 500000, rate: 0.06, adjustment: 3300 },
{ asset: 1000000, rate: 0.09, adjustment: 18300 },
{ asset: 2000000, rate: 0.12, adjustment: 48300 },
{ asset: 3000000, rate: 0.15, adjustment: 108300 },
{ asset: 4000000, rate: 0.18, adjustment: 198300 },
{ asset: 5000000, rate: 0.21, adjustment: 318300 },
{ asset: 6000000, rate: 0.24, adjustment: 468300 },
{ asset: 7000000, rate: 0.27, adjustment: 648300 },
{ asset: 8000000, rate: 0.30, adjustment: 858300 },
{ asset: 9000000, rate: 0.33, adjustment: 1098300 },
{ asset: 10000000, rate: 0.36, adjustment: 1368300 },
{ asset: 11000000, rate: 0.39, adjustment: 1668300 },
{ asset: 12000000, rate: 0.42, adjustment: 1998300 },
{ asset: 13000000, rate: 0.45, adjustment: 2358300 },
{ asset: 14000000, rate: 0.48, adjustment: 2748300 },
{ asset: 15000000, rate: 0.51, adjustment: 3168300 },
{ asset: 16000000, rate: 0.54, adjustment: 3618300 },
{ asset: 17000000, rate: 0.57, adjustment: 4098300 },
{ asset: Infinity, rate: 0.60, adjustment: 4608300 },
];
const { rate, adjustment } = taxRateTable.find(e => input < e.asset);
const output = Math.ceil(input * rate - adjustment);
debugConsole("-----computeTax() output: " + output);
debugConsole("-----complete computeTax()");
return output;
}
//個人持股表格
//這邊抄了新的方法來實作,做為第一次測試,之後再重構其他的
// 判斷直到 condition 符合之後再執行 action
function waitUntil(condition, action) {
setTimeout(function check() {
if (condition()) {
action();
} else {
setTimeout(check, 0);
}
}, 0);
}
// 控制 持股表格 資料夾是否展開的 ReactiveVar
const userHaveStockInfo_FolderExpandedVar = new ReactiveVar(false);
// 加入持股表格資料夾
Template.accountInfo.onRendered(() => {
console.log("accountInfo.onRendered()");
const instance = Template.instance();
const userHaveStockInfo_FolderHead = $(`
<div class="col-12 border-grid">
<a class="d-block h4" href="" data-toggle-panel="userHaveStockInfo">
${t("userHaveStockInfo")} <i class="fa fa-folder"/>
</a>
</div>
`);
const userHaveStockInfo_FolderIcon = userHaveStockInfo_FolderHead.find("i.fa");
const userHaveStockInfo_FolderBody = $(`
<div class="col-12 text-right border-grid">
<table border="1" id="userHaveStockInfo_Table">
<tr>
<td width="390px"> 公司名稱 </td>
<td> 公司股價 </td>
<td> 每股分紅 </td>
<td> 持有股數 </td>
<td> 持有比例 </td>
<td> 股票總值 </td>
<td> 預估分紅 </td>
<td> 本益比 </td>
</tr>
</table>
</div>
`);
waitUntil(
() => instance.$(".card-block:last() .row").length > 0,
() => instance.$(".card-block:last() .row").append(userHaveStockInfo_FolderHead));
instance.autorun(() => {
const userHaveStockInfo_FolderExpanded = userHaveStockInfo_FolderExpandedVar.get();
if (userHaveStockInfo_FolderExpanded) {
setTimeout(() => {
userHaveStockInfo_FolderIcon.addClass("fa-folder-open").removeClass("fa-folder");
userHaveStockInfo_FolderBody.insertAfter(userHaveStockInfo_FolderHead);
setTimeout(add_userHaveStockInfo_Table, 10);
}, 0);
} else {
setTimeout(() => {
userHaveStockInfo_FolderIcon.addClass("fa-folder").removeClass("fa-folder-open");
userHaveStockInfo_FolderBody.detach();
});
}
});
});
function add_userHaveStockInfo_Table()
{
console.log("---start add_userHaveStockInfo_Table()");
const userID = String(document.location.href.match(/accountInfo\/([0-z]+)/)[1]);
debugConsole("-----userID: " + userID);
const userStockInfo = null !== window.sessionStorage.getItem ("userStockInfo") ? JSON.parse(window.sessionStorage.getItem ("userStockInfo")) : [];
//userStcokInfo的格式:
//{"userID": "CWgfhqxbrJMxsknrb",
// "userCompany": [{"companyID": aaa, "userHold": number}, {}]
// "userManage": [{"companyID": aaa}, {}]
// "userEmployee": {"companyID": aaa} }
const userIndex = userStockInfo.findIndex(a => a.userID == userID);
debugConsole("-----userIndex: " + userIndex);
debugConsole("-----//如果是-1 下一步應該跳出本function");
//到這邊如果是-1那後面的就不用做了,會跳出function
if (userID !== -1)
{
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
for (let k = 0 ; k < userStockInfo[userIndex].userCompany.length ; k++)
{
const companyID = userStockInfo[userIndex].userCompany[k].companyID;
let price = 0;
let earnPerShare = 0;
let name = "error:404 not found";
let release = 0;
const hold = userStockInfo[userIndex].userCompany[k].userHold;
const companyIndex = CsDatas.findIndex(b => b.companyID == companyID);
if (companyIndex != -1)
{
name = String(CsDatas[companyIndex].companyName);
price = Number(CsDatas[companyIndex].companyPrice);
release = Number(CsDatas[companyIndex].companyStock);
if (CsDatas[companyIndex].employeesNumber > 0)
earnPerShare = Number(CsDatas[companyIndex].companyProfit
* (0.8 - (CsDatas[companyIndex].companyBonus * 0.01))
/ CsDatas[companyIndex].companyStock);
else
earnPerShare = Number(CsDatas[companyIndex].companyProfit * 0.8 / CsDatas[companyIndex].companyStock);
}
debugConsole(String(""));
$("#userHaveStockInfo_Table").append(`
<tr>
<td width="390px"> <a href="/company/detail/${companyID}">${name}</a> </td>
<td> ${price} </td>
<td> ${earnPerShare.toFixed(2)} </td>
<td> ${hold} </td>
<td> ${(hold / release * 100).toFixed(2)} % </td>
<td> ${(price * hold)} </td>
<td> ${(earnPerShare * hold).toFixed(0)} </td>
<td> ${(price / earnPerShare).toFixed(3)} </td>
</tr>
`);
}
}
console.log("---end add_userHaveStockInfo_Table()");
}
Template.accountInfo.events({
"click [data-toggle-panel=userHaveStockInfo]"(event) {
event.preventDefault();
console.log("click_userHaveStockInfo");
userHaveStockInfo_FolderExpandedVar.set(!userHaveStockInfo_FolderExpandedVar.get());
},
});
/*************accountInfo*************/
/*************************************/
/*************************************/
/**************arenaInfo**************/
function arenaInfoEvent()
{
checkFighterInfo();
//don't see, don't use, don't ask
myArena();
addRemoveButtton();
}
function Fighter(fID, fManager, fHP, fSP, fATK, fDEF, fAGI)
{
this.ID = fID;
this.manager = fManager;
this.money = {
"total": Number(fHP + fSP + fATK + fDEF + fAGI),
"hp": fHP,
"sp": fSP,
"atk": fATK,
"def": fDEF,
"agi": fAGI
};
this.hp = Number(Math.floor(fHP/200) + 50);
this.sp = Number(Math.floor(fSP/1000) + 5);
this.atk = Number(Math.floor(fATK/1000) + 1);
this.def = Number(Math.floor(fDEF/1000));
this.agi = Number(Math.floor(fAGI/1000));
debugConsole("=====new Fighter ID: " + this.ID);
debugConsole("=====new Fighter total money: " + this.money.total);
}
function checkFighterInfo()
{
console.log("start checkFighterInfo()");
var fighters = [];
const dbFighters = Meteor.connection._mongo_livedata_collections.arenaFighters.find().fetch();
debugConsole("-----for of dbFighters");
for (let f of dbFighters)
{
debugConsole("-----new Fighter input: " + f.companyId + f.manager + f.hp + f.sp + f.atk + f.def + f.agi);
let thisFighter = new Fighter(f.companyId, f.manager, f.hp, f.sp, f.atk, f.def, f.agi);
fighters.push(thisFighter);
}
addFighterMoneyInfo(fighters);
//consoleMoney(fighters);
console.log("end checkFighterInfo()");
}
function addFighterMoneyInfo(fighters)
{
console.log("---start addFighterMoneyInfo()");
const moneyInfoTitle = $(`
<th
class="text-center text-truncate"
style="width: 100px; cursor: pointer;"
title="投資額"
id="moneyInfoTitle"
>
投資額
</th>
`);
debugConsole("-----th[title=投資額].length: " + $('th[title="投資額"]').length);
if ($('th[title="投資額"]').length < 1)
{
moneyInfoTitle.insertAfter($('th[title="名次"]')[0]);
}
debugConsole("-----for of fighters");
for (let thisFighter of fighters)
{
const fID = thisFighter.ID;
debugConsole("-----fID: " + fID);
debugConsole("-----tr[data-id=fID].length: " + $(`tr[data-id=${fID}]`).length);
$(`tr[data-id=${fID}]`).append(`
<td class="text-center px-1 text-truncate">
${thisFighter.money.total}
</td>
`);
}
console.log("---end addFighterMoneyInfo()");
}
function consoleMoney(fighters)
{
fighters.sort(function(a, b) {
return b.money.total - a.money.total;
});
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
for (let f = 0; f < 100; f += 1)
{
const thisFighter = fighters[f];
const cIndex = CsDatas.findIndex(c => c.companyID == thisFighter.ID);
console.log("rank: " + f);
console.log("ID: " + thisFighter.ID);
if (cIndex != -1)
console.log("name: " + CsDatas[cIndex].companyName);
console.log("manager: " + thisFighter.manager);
console.log("money: " + thisFighter.money.total);
console.log("HP: " + thisFighter.hp);
console.log("");
console.log("");
}
}
function removeNotFighter()
{
console.log("start removeNotFighter()");
const dbFighters = Meteor.connection._mongo_livedata_collections.arenaFighters.find().fetch();
for (let f of dbFighters)
{
const money = f.hp + f.sp + f.atk + f.def + f.agi;
if (money < 10000)
{
debugConsole("id: " + f.companyId + " money: " + money);
$(`tr[data-id=${f.companyId}]`).remove();
}
}
console.log("end removeNotFighter()");
}
function addRemoveButtton()
{
const buttonRemove = $(`
<button class="btn btn-primary btn-sm" type="button" id="removeNotFighter">
移除沒資格的參賽者
</button>
`);
buttonRemove.insertAfter($(`h1[class="card-title mb-1"]`)[0]);
$('#removeNotFighter')[0].addEventListener("click", function() {
removeNotFighter();
});
}
//Dark function
//don't see, don't use, don't ask
var my_virtual_fighters = [];
var battleTime = 0;
function myArena()
{
addInputID();
fightSimulatorCreater();
addFindInfoButton();
addStartFightSimulatorButton();
addFindBattleLogButton();
}
function VirtualFighter(fID, fName, fManager, fHP, fSP, fATK, fDEF, fAGI, fspCost, fcreatedAt, fattackSequence)
{
this.ID = fID;
this.name = fName;
this.manager = fManager;
this.money = {
"total": Number(fHP + fSP + fATK + fDEF + fAGI),
"hp": fHP,
"sp": fSP,
"atk": fATK,
"def": fDEF,
"agi": fAGI,
"killBonus": 0
};
this.hp = Number(Math.floor(fHP/200) + 50);
this.sp = Number(Math.floor(fSP/1000) + 5);
this.atk = Number(Math.floor(fATK/1000) + 1);
this.def = Number(Math.floor(fDEF/1000));
this.agi = Number(Math.floor(fAGI/1000));
this.spCost = Number(fspCost);
this.createdAt = Date.parse(fcreatedAt);
this.attackSequence = fattackSequence;
this.attackIndex = -1;
var notFound = 999999;
while (notFound !== -1)
{
this.attackIndex += 1;
notFound = this.attackSequence.findIndex(x => x === this.attackIndex);
}
this.battleLog = [];
debugConsole("=====new Fighter ID: " + this.ID);
debugConsole("=====new Fighter total money: " + this.money.total);
}
function fightSimulatorCreater()
{
battleTime = 0;
const dbFighters = Meteor.connection._mongo_livedata_collections.arenaFighters.find().fetch();
var vFighters = [];
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
debugConsole("-----for of dbFighters");
for (let f of dbFighters)
{
const fName = (CsDatas.find(c => c.companyID === f.companyId)).companyName;
debugConsole("-----new Fighter input: " + f.companyId + fName + f.manager +
f.hp + f.sp + f.atk + f.def + f.agi +
f.spCost + f.createdAt + f.attackSequence.length);
let thisFighter = new VirtualFighter(f.companyId, fName, f.manager,
f.hp, f.sp, f.atk, f.def, f.agi,
f.spCost, f.createdAt, f.attackSequence);
vFighters.push(thisFighter);
}
//刪除不到10000的北七
var deleteList = [];
for (let i=0; i<vFighters.length; i+=1)
{
if (vFighters[i].money.total < 10000)
{
const thisFighterAttackIndex = vFighters[i].attackIndex;
vFighters.splice(i, 1);
deleteList.push(thisFighterAttackIndex);
i -= 1; //因為刪除會導致順序改變,因此i要往回1個
}
}
for (let j=0; j<vFighters.length; j+=1)
{
for (let k of deleteList)
{
const thisI = vFighters[j].attackSequence.findIndex(f => f === k);
vFighters[j].attackSequence.splice(thisI, 1);
}
}
//排攻擊順序
vFighters.sort(function(a, b) {
if ((b.agi - a.agi) === 0)
return a.createdAt - b.createdAt;
else
return b.agi - a.agi;
});
my_virtual_fighters = vFighters;
const moneyInfoTitle = $(`
<th
class="text-center text-truncate"
style="width: 100px; cursor: pointer;"
title="戰鬥獎勵"
id="moneyInfoTitle"
>
戰鬥獎勵
</th>
`);
if ($('th[title="戰鬥獎勵"]').length < 1)
{
moneyInfoTitle.insertAfter($('th[title="投資額"]')[0]);
}
debugConsole("-----for of fighters");
for (let thisFighter of vFighters)
{
const fID = thisFighter.ID;
debugConsole("-----fID: " + fID);
debugConsole("-----tr[data-id=fID].length: " + $(`tr[data-id=${fID}]`).length);
$(`tr[data-id=${fID}]`).append(`
<td class="text-center px-1 text-truncate">
${thisFighter.money.killBonus}
</td>
`);
}
}
function fightSimulator(vFighters)
{
console.log("---start fightSimulator()");
battleTime += 1;
const topSP = 6; // spCost>這個數值 則視為100%發動
const topAGI = 30; // 雙方AGI差距<這個數值 則視為100%命中
var vLog = [];
for (let i=0; i<vFighters.length; i+=1)
{
debugConsole("-----i: " + i);
debugConsole("-----vFighters[i].hp: " + vFighters[i].hp);
if (vFighters[i].hp > 0)
{
const randomSp = Math.floor((Math.random() * 10) + 1);
const randomAgi = Math.floor((Math.random() * 100) + 1);
debugConsole("-----randomSp: " + randomSp);
debugConsole("-----randomAgi: " + randomAgi);
//決定攻擊目標
debugConsole("-----決定攻擊目標");
var targetHP = 0;
var targetIndex = -1;
var t = -1;
debugConsole("-----while()");
while (targetHP < 1)
{
t += 1;
debugConsole("-----t: " + t);
const targetI = vFighters[i].attackSequence[t];
debugConsole("-----targetI: " + targetI);
targetIndex = vFighters.findIndex(f => f.attackIndex === targetI);
debugConsole("-----targetIndex: " + targetIndex);
targetHP = vFighters[targetIndex].hp;
debugConsole("-----targetHP: " + targetHP);
}
debugConsole("-----targetIndex: " + targetIndex);
//開始攻擊
debugConsole("-----開始攻擊");
if (((vFighters[i].spCost > topSP) || (vFighters[i].spCost >= randomSp)) &&
(vFighters[i].sp >= vFighters[i].spCost))
{
vFighters[targetIndex].hp -= vFighters[i].atk;
vFighters[i].sp -= vFighters[i].spCost;
const thisLog = `【第${battleTime}回合】${vFighters[i].name} 使用SP攻擊對 ${vFighters[targetIndex].name} 造成${vFighters[i].atk}傷害,血量變為${vFighters[targetIndex].hp}`;
console.log(thisLog);
vFighters[i].battleLog.push(thisLog);
vFighters[targetIndex].battleLog.push(thisLog);
vLog.push(thisLog);
}
else
{
const agiAGI = vFighters[targetIndex].agi - vFighters[i].agi;
if ((agiAGI < topAGI) || ((agiAGI-randomAgi) <= 0) || (randomAgi > 95))
{
let atkNumber = vFighters[i].atk - vFighters[targetIndex].def;
if (atkNumber < 1)
{
atkNumber = 1;
}
vFighters[targetIndex].hp -= atkNumber;
const thisLog = `【第${battleTime}回合】${vFighters[i].name} 使用普通攻擊對 ${vFighters[targetIndex].name} 造成${atkNumber}傷害,血量變為${vFighters[targetIndex].hp}`;
console.log(thisLog);
vFighters[i].battleLog.push(thisLog);
vFighters[targetIndex].battleLog.push(thisLog);
vLog.push(thisLog);
}
else
{
const thisLog = `【第${battleTime}回合】${vFighters[i].name} 攻擊 ${vFighters[targetIndex].name} ,但AGI差距${agiAGI}點而被閃開了`;
console.log(thisLog);
vFighters[i].battleLog.push(thisLog);
vFighters[targetIndex].battleLog.push(thisLog);
vLog.push(thisLog);
}
}
//計算是否擊倒
debugConsole("-----計算是否擊倒");
if (vFighters[targetIndex].hp <= 0)
{
vFighters[i].money.killBonus += vFighters[targetIndex].money.total;
const thisLog = `【第${battleTime}回合】${vFighters[i].name} 擊倒了 ${vFighters[targetIndex].name} ,獲得了${vFighters[targetIndex].money.total}的獎金`;
console.log(thisLog);
vFighters[i].battleLog.push(thisLog);
vFighters[targetIndex].battleLog.push(thisLog);
vLog.push(thisLog);
}
}
}
//戰鬥結束 回復SP
for (let i=0; i<vFighters.length; i+=1)
{
debugConsole("-----i: " + i);
if (vFighters[i].hp > 0)
{
vFighters[i].sp += 1;
}
}
my_virtual_fighters = vFighters;
addFightSimulatorData(vFighters);
addBattleLogTable(vLog);
console.log("---end fightSimulator()");
}
function addFightSimulatorData(vFighters)
{
console.log("---start addFightSimulatorData()");
for (let thisFighter of vFighters)
{
debugConsole("ID: " + thisFighter.ID + " hp sp killBonus: " + thisFighter.hp + thisFighter.sp + thisFighter.money.killBonus);
$(`tr[data-id=${thisFighter.ID}]`).find('td')[2].innerText = thisFighter.hp;
$(`tr[data-id=${thisFighter.ID}]`).find('td')[3].innerText = thisFighter.sp;
$(`tr[data-id=${thisFighter.ID}]`).find('td')[9].innerText = thisFighter.money.killBonus;
}
console.log("---end addFightSimulatorData()");
}
function addBattleLogTable(vLog)
{
$(`table[id=findArenaOutput_Table]`).remove();
const outListTable = $(`
<table border="1" id="findArenaOutput_Table">
<tr>
<td> 紀錄 </td>
</tr>
</table>
`);
outListTable.insertAfter($(`input[id=inputID]`)[0]);
for (let thisLog of vLog)
{
$("#findArenaOutput_Table").append(`
<tr>
<td> ${thisLog} </td>
</tr>
`);
}
}
function addStartFightSimulatorButton()
{
const buttonFS = $(`
<button class="btn btn-danger btn-sm" type="button" id="startFS">
模擬戰鬥
</button>
`);
buttonFS.insertAfter($(`h1[class="card-title mb-1"]`)[0]);
$('#startFS')[0].addEventListener("click", function() {fightSimulator(my_virtual_fighters); });
}
function findBattleLog(fID)
{
const outListTable = $(`
<table border="1" id="findArenaOutput_Table">
<tr>
<td> 紀錄 </td>
</tr>
</table>
`);
outListTable.insertAfter($(`input[id=inputID]`)[0]);
const thisFighter = my_virtual_fighters.find(f => f.ID === fID);
for (let thisLog of thisFighter.battleLog)
{
$("#findArenaOutput_Table").append(`
<tr>
<td> ${thisLog} </td>
</tr>
`);
}
}
function addFindBattleLogButton()
{
const buttonFindBattleLog = $(`
<button class="btn btn-info btn-sm" type="button" id="findBattleLog">
搜尋模擬戰鬥紀錄
</button>
`);
buttonFindBattleLog.insertAfter($(`h1[class="card-title mb-1"]`)[0]);
$('#findBattleLog')[0].addEventListener("click", function() {
$(`table[id=findArenaOutput_Table]`).remove();
const tID = $(`input[id=inputID]`)[0].value;
findBattleLog(tID);
});
}
function findAttackList(fID)
{
const printNumber = 100;
const thisFighter = my_virtual_fighters.find(x => x.ID === fID);
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
const outListTable = $(`
<table border="1" id="findArenaOutput_Table">
<tr>
<td> 攻擊序 </td>
<td width="390px"> 公司名稱 </td>
</tr>
</table>
`);
outListTable.insertAfter($(`input[id=inputID]`)[0]);
for (let i=0; i<printNumber; i+=1)
{
const a_index = thisFighter.attackSequence[i];
const a_fighter = my_virtual_fighters.find(x => x.attackIndex === a_index);
const a_company = CsDatas.find(c => c.companyID === a_fighter.ID);
console.log("attack: " + i + " " + a_company.companyName);
$("#findArenaOutput_Table").append(`
<tr>
<td> ${(i+1)} </td>
<td width="390px"> <a href="/company/detail/${a_company.companyID}">${a_company.companyName}</a> </td>
</tr>
`);
}
}
function findAttackMe(myID)
{
const fs = my_virtual_fighters;
const myF = fs.find(f => f.ID === myID);
const myIndex = myF.attackIndex;
const findNumberIn = 39;
const CsDatas = JSON.parse(window.localStorage.getItem ("local_CsDatas")) || [];
//local_CsDatas規格 local
//{"companyID": String, "companyName": String,
// "companyPrice": Number, "companyStock": Number, "companyProfit": Number,
// "companySalary": Number, "companyNextSeasonSalary": Number, "companyBonus": Number,
// "companyEmployeesNumber": Number, "companyNextSeasonEmployeesNumber": Number}
const outListTable = $(`
<table border="1" id="findArenaOutput_Table">
<tr>
<td> 攻擊序 </td>
<td width="390px"> 公司名稱 </td>
</tr>
</table>
`);
outListTable.insertAfter($(`input[id=inputID]`)[0]);
for (let f of fs)
{
const xIndex = f.attackSequence.findIndex(x => x === myIndex);
if (xIndex < findNumberIn)
{
const thatcompany = CsDatas.find(c => c.companyID === f.ID);
console.log("ID: " + f.ID);
console.log("name: " + thatcompany.companyName);
console.log("attackIndex: " + xIndex);
//console.log(f);
console.log("");
if (xIndex !== -1)
{
$("#findArenaOutput_Table").append(`
<tr>
<td> ${xIndex + 1} </td>
<td width="390px"> <a href="/company/detail/${f.ID}">${thatcompany.companyName}</a> </td>
</tr>
`);
}
}
}
}
function addInputID()
{
const inputID = $(`
<input
class="form-control"
type="text"
name="inputID"
id="inputID"
maxlength="200"
placeholder="請輸入公司ID,如 初音未來 為 oeQuXvDBoHYTAZ7ei"
>
`);
inputID.insertAfter($(`h1[class="card-title mb-1"]`)[0]);
}
function addFindInfoButton()
{
const buttonAttackList = $(`
<button class="btn btn-warning btn-sm" type="button" id="findAttackList">
搜尋攻擊清單
</button>
`);
buttonAttackList.insertAfter($(`h1[class="card-title mb-1"]`)[0]);
$('#findAttackList')[0].addEventListener("click", function() {
$(`table[id=findArenaOutput_Table]`).remove();
const tID = $(`input[id=inputID]`)[0].value;
findAttackList(tID);
});
const buttonAttackMe = $(`
<button class="btn btn-warning btn-sm" type="button" id="findAttackMe">
搜尋敵人清單
</button>
`);
buttonAttackMe.insertAfter($(`h1[class="card-title mb-1"]`)[0]);
$('#findAttackMe')[0].addEventListener("click", function() {
$(`table[id=findArenaOutput_Table]`).remove();
const tID = $(`input[id=inputID]`)[0].value;
findAttackMe(tID);
});
const buttonRemoveTable = $(`
<button class="btn btn-info btn-sm" type="button" id="removeTable">
移除table
</button>
`);
buttonRemoveTable.insertAfter($(`h1[class="card-title mb-1"]`)[0]);
$('#removeTable')[0].addEventListener("click", function() {
$(`table[id=findArenaOutput_Table]`).remove();
});
}
/**************arenaInfo**************/
/*************************************/
/*************************************/
/**************Language***************/
var lan = "";
lan = null !== window.localStorage.getItem ("PM_language") ? window.localStorage.getItem ("PM_language") : "tw";
// 目前的語言
let currentLanguage = window.localStorage.getItem("PM_language") || "tw";
// 翻譯米糕
function t(key) {
return Dict[currentLanguage][key];
}
/*function ChangeLanguage(l){
if(lan === l)return;
lan = l;
window.localStorage.setItem ("PM_language",l);
window.location.reload();
}*/
const Dict = {
tw:
{
totalProfitInThisPage: "本頁預計分紅:",
updateDividendScript: "更新預估分紅腳本",
userTotalAssets: "使用者股票總值:",
userTotalProfit: "預估股票分紅:",
userTotalCompanyNumber: "持有公司總數:",
managerTotalSalary: "預估經理薪水:",
employeeTotalBonus: "預估員工分紅:",
userTotalTax: "預估本季稅金:",
PEratio: "本益比排行",
stockPEInfo: "本益比",
stockManagerSalaryInfo: "經理薪水",
stockProfitInfo: "現金股利",
stockWorthInfo: "股票總值",
userHaveStockInfo: "持股資訊總表",
userTotalUsingCash: "買單現金總值:",
userTotalSellingStock: "賣單股票總值:",
mostStockDropDown: "最多持股公司",
},
en:
{
totalProfitInThisPage: "Total profit in this page :",
updateDividendScript: "Update Dividend Script",
userTotalAssets: "User stock worth:",
userTotalProfit: "Estimated stock dividends:",
userTotalCompanyNumber: "Hold the total number of companies:",
managerTotalSalary: "Estimated manager salary:",
employeeTotalBonus: "預估員工分紅:",
userTotalTax: "Estimated tax for this season:",
PEratio: "PE ratio",
stockPEInfo: "PE",
stockManagerSalaryInfo: "Manager salary",
stockProfitInfo: "Dividend",
stockWorthInfo: "Stock worth",
userHaveStockInfo: "持股資訊總表",
userTotalUsingCash: "買單現金總值:",
userTotalSellingStock: "賣單股票總值:",
mostStockDropDown: "最多持股公司",
},
jp:
{
totalProfitInThisPage: "本ページ利回り総額:",
updateDividendScript: "更新預估分紅腳本",
userTotalAssets: "使用者股票總值:",
userTotalProfit: "預估股票分紅:",
userTotalCompanyNumber: "持有公司總數:",
managerTotalSalary: "預估經理薪水:",
employeeTotalBonus: "預估員工分紅:",
userTotalTax: "預估本季稅金:",
PEratio: "本益比排行",
stockPEInfo: "本益比",
stockManagerSalaryInfo: "經理薪水",
stockProfitInfo: "現金股利",
stockWorthInfo: "股票總值",
userHaveStockInfo: "持股資訊總表",
userTotalUsingCash: "買單現金總值:",
userTotalSellingStock: "賣單股票總值:",
mostStockDropDown: "最多持股公司",
},
marstw:
{
totalProfitInThisPage: "這ㄘ可yee拿ㄉ$$:",
updateDividendScript: "有★★★版",
userTotalAssets: "股票ㄉ$$:",
userTotalProfit: "這ㄘ會拿ㄉ$$:",
userTotalCompanyNumber: "偶ㄐ間公ㄙ:",
managerTotalSalary: "雞李ㄉ西水:",
employeeTotalBonus: "預估員工分紅:",
userTotalTax: "ㄋ要交ㄉ茄:",
PEratio: "ㄅyee逼排行",
stockPEInfo: "ㄅyee逼",
stockManagerSalaryInfo: "ㄐ李溪水",
stockProfitInfo: "會給ㄉ前",
stockWorthInfo: "股票ㄓˊ",
userHaveStockInfo: "持股資訊總表",
userTotalUsingCash: "買單現金總值:",
userTotalSellingStock: "賣單股票總值:",
mostStockDropDown: "最多持股公司",
}
};
/**************Language***************/
/*************************************/