您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
try to take over the world!
当前为
// ==UserScript== // @name ACGN-stock營利統計外掛 // @namespace http://tampermonkey.net/ // @version 3.100 // @description try to take over the world! // @author SoftwareSing // @match http://acgn-stock.com/* // @match https://acgn-stock.com/* // @grant none // ==/UserScript== //版本號為'主要版本號 + "." + 次要版本號 + 錯誤修正版本號(兩位),ex 1.801 //修復導致功能失效的錯誤或更新重大功能提升主要或次要版本號 //優化UI,優化效能,優化小錯誤更新錯誤版本號 //兩個錯誤修正版本號防止迫不得已進位到次要版本號 //本腳本修改自 "ACGN股票系統每股營利外掛 2.200 by papago89" /*************************************/ /************GlobalVariable***********/ //會跨2區以上使用的全域變數放在這裡 //如從stockSummary跨到accountInfo用的變數 var myID = null; //當前登入的使用者ID var myHoldStock = []; //當前登入的使用者持有的股票, 在股市總覽可以直接抓到全部 var myOrders = []; //當前登入的使用者未完成交易的買賣單, 在股市總覽可以直接抓到全部 /************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(`Page loading: ${document.location.href}`); } // 頁面離開載入狀態時進行此回呼 function onPageLoaded() { const currentUrl = document.location.href; console.log(`Page loaded: ${currentUrl}`); // 頁面 url 樣式的回呼表 const urlPatternCallbackTable = [ { pattern: /company\/[0-9]+/, callback: onStockSummaryPageLoaded }, { pattern: /company\/detail/, callback: onCompanyDetailPageLoaded }, { pattern: /accountInfo/, callback: onAccountInfoPageLoaded }, { pattern: /foundation\/[0-9]+/, callback: onFoundationPlanPageLoaded }, ]; // 匹配當前頁面 url 的樣式並進行對應的回呼 urlPatternCallbackTable.forEach(({ pattern, callback }) => { if (currentUrl.match(pattern)) { // loadingOverlay 消失後,需要給點時間讓頁面的載入全部跑完 setTimeout(callback, 100); } }); } // 當「股市總覽」頁面已載入時進行的回呼 function onStockSummaryPageLoaded() { setTimeout(stockSummaryEvent, 500); } // 當「公司資訊」頁面已載入時進行的回呼 function onCompanyDetailPageLoaded() { setTimeout(companyEvent, 500); } // 當「帳號資訊」頁面已載入時進行的回呼 function onAccountInfoPageLoaded() { setTimeout(checkUserInfo, 10); //checkUserInfo(); } // 當「新創計劃」頁面已載入時進行的回呼 function onFoundationPlanPageLoaded() { } /*********ACGNListenerScript**********/ /*************************************/ /*************************************/ /*************StartScript*************/ //本區StartFunction startEvent() function startEvent() { checkSeriousError(); setTimeout(checkScriptEvent, 390); //前2項十分重要,需最優先執行 setTimeout(checkDividendUpdateTime, 1000); setTimeout(addAD, 2000); setTimeout(checkUserID, 3900); } function checkUserID() { myID = String(Meteor.connection._userId); console.log("userID: " + myID); if (myID === null) setTimeout(checkUserID, 30000); else setTimeout(checkUserID, 1200000); } /*************StartScript*************/ /*************************************/ /*************************************/ /**********ResetLocalStorage**********/ //本區StartFunction checkSeriousError() function checkSeriousError() { //這個function將會清空所有由本插件控制的localStorage //用於如果上一版發生嚴重錯誤導致localStorage錯亂,以致插件無法正常啟動時 //或是用於當插件更新時,需要重設localStorage var seriousErrorVersion = 3.000; //seriousErrorVersion會輸入有問題的版本號,當發生問題時我會增加本數字,或是於更新需要時亦會增加 //使用者本地的數字紀錄如果小於這個數字將會清空所有localStorage var lastErrorVersion = 0 !== window.localStorage.getItem ("lastErrorVersion") ? Number(JSON.parse(window.localStorage.getItem ("lastErrorVersion"))) : 0; //lastErrorVersion = 0; //你如果覺得現在就有問題 可以把這行的註解取消掉來清空localStorage //console.log(Number.isInteger(lastErrorVersion)); //console.log(lastErrorVersion); 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 ("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, 3) + "," + myVersion.substr(0, 3) + "," + (obj.version.substr(0, 3) > myVersion.substr(0, 3))); if(obj.version.substr(0, 3) > myVersion.substr(0, 3)) $('<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*************/ /*************************************/ /*************************************/ /***********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", () => { console.log("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 get_companies_jsonbin = getWebData("https://jsonbin.org/abcd1357/ACGNstock-company"); const get_companies_jsonbin_updatetime = getWebData("https://jsonbin.org/abcd1357/ACGNstock-company/updateTime"); const get_companies_firebase = getWebData("https://acgnstock-data.firebaseio.com/ACGNstock-company.json"); const get_AD_jsonbin = getWebData("https://jsonbin.org/abcd1357/ACGNstock-AD"); /***********GetDataBaseData***********/ /*************************************/ /*************************************/ /**********UpdateDividendData*********/ //本區StartFunction checkDividendUpdateTime() function checkDividendUpdateTime() { console.log("start check Dividend update time"); //window.localStorage.removeItem ("Dividend_UpdateTime"); var Dividend_UpdateTime = null !== window.localStorage.getItem ("Dividend_UpdateTime") ? JSON.parse(window.localStorage.getItem ("Dividend_UpdateTime")) : "null"; get_companies_jsonbin_updatetime(json_updateTime => { console.log("json_updateTime === Dividend_UpdateTime : " + (json_updateTime === Dividend_UpdateTime)); if (json_updateTime === Dividend_UpdateTime) { console.log("dont need update " + Dividend_UpdateTime); } else { console.log("server update time: " + json_updateTime); console.log("local update time: " + Dividend_UpdateTime); console.log("start update data"); setTimeout(updateDividendData, 1); } }); console.log("complete check Dividend update time"); } function updateDividendData() { console.log("start update Dividend data"); var Dividends = []; get_companies_jsonbin(jsonData => { for (let n in jsonData.companys) { Dividends.push({"companyID": String(jsonData.companys[n].companyID), "companyDividend": String(jsonData.companys[n].companyDividend), "companyPrice": String(jsonData.companys[n].companyPrice), "companyStock": String(jsonData.companys[n].companyStock) }); //console.log("push success"); } window.localStorage.setItem ("Dividend", JSON.stringify(Dividends)); if (jsonData.updateTime === null || jsonData.updateTime === undefined) { window.localStorage.setItem ("Dividend_UpdateTime", JSON.stringify("no data")); } else { window.localStorage.setItem ("Dividend_UpdateTime", JSON.stringify(jsonData.updateTime)); } }); console.log("complete update Dividend data"); } /**********UpdateDividendData*********/ /*************************************/ /*************************************/ /**************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')); 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***************/ /*************************************/ /*************************************/ /************stockSummary*************/ //本區StartFunction stockSummaryEvent() function stockSummaryEvent() { setTimeout(getBasicUserData, 500, 0); setTimeout(useCompaniesDatasEvent, 600); } function getBasicUserData(runNumber) { 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() > 0) myOrders = Meteor.connection._mongo_livedata_collections.orders.find().fetch(); else restart = true; } if (restart) setTimeout(getBasicUserData, 1000, runNumber); } 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; //如果執行的function需要存值,放在這裡 var value_computeProfit = 0; var value_BatchAddDividendLocalStorage_1 = null !== window.localStorage.getItem ("Dividend") ? JSON.parse(window.localStorage.getItem ("Dividend")) : []; var value_BatchAddDividendLocalStorage_2 = false; var value_BatchAddDividendLocalStorage = [value_BatchAddDividendLocalStorage_1, value_BatchAddDividendLocalStorage_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(thisCompany.profit) * 0.8075 / Number(thisCompany.totalRelease)); manager = String(thisCompany.manager); const MHSindex = myHoldStock.findIndex(a => a.companyId == ID); if (MHSindex === -1) hold = 0; else hold = Number(myHoldStock[MHSindex].stocks); console.log(ID + "---" + price + "---" + release + "---" + profit + "---" + earnPerShare + "---" + manager + "---" + hold); //需要執行的function放在這 value_computeProfit = computeProfit(ID, earnPerShare, hold, value_computeProfit); value_isEnd = (i + 1 >= companiesDatas.length); value_BatchAddDividendLocalStorage = BatchAddDividendLocalStorage(ID, earnPerShare, price, release, value_BatchAddDividendLocalStorage, value_isEnd); SSAddSomeInfo(ID, earnPerShare, price, hold, manager, profit); console.log(""); } console.log("complete computeProfit()"); } 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.mb-1')[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 BatchAddDividendLocalStorage(ID, earnPerShare, price, release, inputValue, isEnd) { console.log("-----start BatchAddDividendLocalStorage()"); var Dividends = inputValue[0]; var isChange = inputValue[1]; //Dividends規格 //{"companyID": A, "companyDividend": B, "companyPrice": C, "companyStock": D} let index = Dividends.findIndex(x => x.companyID == ID); if (index != -1) { if ((Dividends[index].companyDividend == earnPerShare) && (Dividends[index].companyPrice == price) && (Dividends[index].companyStock == release)) { console.log("dont need update LocalStorage"); } else { isChange = true; Dividends.splice(index, 1); console.log("AddDividendLocalStorage---splice"); Dividends.push({"companyID": ID, "companyDividend": earnPerShare, "companyPrice": price, "companyStock": release}); console.log("Add Dividend LocalStorage!!"); } } else { isChange = true; Dividends.push({"companyID": ID, "companyDividend": earnPerShare, "companyPrice": price, "companyStock": release}); console.log("AddDividendLocalStorage!!"); } //console.log("-----BatchAddDividendLocalStorage()---isChange: " + isChange + "---isEnd: " + isEnd + "---"); if (isChange && isEnd) { window.localStorage.setItem ("Dividend", JSON.stringify(Dividends)); console.log("setItem---Dividend"); } outputValue = [Dividends, isChange]; console.log("-----complete BatchAddDividendLocalStorage()"); 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 in $('.title a')) { if (ID == String($('.title a')[i].href.match(/\/company\/detail\/([^]+)/)[1])) break; } console.log("-----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_AddDividendLocalStorage, 1000); } function company_AddDividendLocalStorage() { var companiesDatas = Meteor.connection._mongo_livedata_collections.companies.find().fetch(); if (companiesDatas.length > 0) { console.log("start company_AddDividendLocalStorage()"); var profit, price, ID, release, earnPerShare, manager, hold; 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.8075 / Number(thisCompany.totalRelease)); manager = String(thisCompany.manager); console.log(ID + "---" + price + "---" + release + "---" + profit + "---" + earnPerShare + "---" + manager + "---"); var Dividends = null !== window.localStorage.getItem ("Dividend") ? JSON.parse(window.localStorage.getItem ("Dividend")) : []; //如果先前紀錄過該公司,則刪除重記 const index = Dividends.findIndex(x => x.companyID == ID); if (index != -1) { if ((Dividends[index].companyDividend == earnPerShare) && (Dividends[index].companyPrice == price) && (Dividends[index].companyStock == release)) { console.log("dont need update cookie"); } else { Dividends.splice(index, 1); console.log("AddDividendCookie---splice"); Dividends.push({"companyID": ID, "companyDividend": earnPerShare, "companyPrice": price, "companyStock": release}); window.localStorage.setItem ("Dividend", JSON.stringify(Dividends)); console.log("Add Dividend localStorage!!"); } } else { Dividends.push({"companyID": ID, "companyDividend": earnPerShare, "companyPrice": price, "companyStock": release}); window.localStorage.setItem ("Dividend", JSON.stringify(Dividends)); console.log("AddDividendlocalStorage!!"); } console.log("complete company_AddDividendLocalStorage()"); } else { console.log("companiesDatas not ready, restart company_AddDividendLocalStorage() after 2s"); setTimeout(company_AddDividendLocalStorage, 2000); } } /**************company****************/ /*************************************/ /*************************************/ /*************accountInfo*************/ //本區StartFunction checkUserInfo() function checkUserInfo() { const userID = String(document.location.href.match(/accountInfo\/([0-z]+)/)[1]); var userStockInfo = null !== window.sessionStorage.getItem ("userStockInfo") ? JSON.parse(window.sessionStorage.getItem ("userStockInfo")) : []; //userStcokInfo的格式: //{"userID": CWgfhqxbrJMxsknrb, "userCompany": [{"companyID": aaa, "userHold": number}, {}]} var userIndex = userStockInfo.findIndex(a => a.userID == userID); if (userIndex == -1) { userStockInfo.push({"userID": userID, "userCompany": []}); userIndex = userStockInfo.findIndex(a => a.userID == userID); } window.sessionStorage.setItem ("userStockInfo", JSON.stringify(userStockInfo)); if ($('.card-title.mb-1').length > 0) { var managerSalary = Number(computeManagerSalary()); if ((userID == myID) && (myHoldStock.length > 0)) { checkMyHoldStock(); addUserProfitInfo(userID, managerSalary); } checkUserHoldStock(userID, 0, managerSalary); setTimeout(addUserProfitInfo, 10, userID, managerSalary); //addUserProfitInfo(userID, managerSalary); } else { console.log("users not ready, restart checkUserInfo() after 2s"); setTimeout(checkUserInfo, 2000); } } function computeManagerSalary() { console.log("---start company_AddDividendLocalStorage()"); var Dividends = null !== window.localStorage.getItem ("Dividend") ? JSON.parse(window.localStorage.getItem ("Dividend")) : []; //Dividends規格 //{"companyID": A, "companyDividend": B, "companyPrice": C, "companyStock": D} var companiesDatas = Meteor.connection._mongo_livedata_collections.companies.find().fetch(); var earnPerShare, release, managerSalary = 0; for (let i in companiesDatas) { const ID = companiesDatas[i]._id; const companyIndex = Dividends.findIndex(a => a.companyID == ID); if (companyIndex === -1) { console.log("not found company " + ID); } else { earnPerShare = Number(Dividends[companyIndex].companyDividend); release = Number(Dividends[companyIndex].companyStock); console.log("---computeManagerSalary()-----" + ID + "-----" + earnPerShare + "-----" + release + "-----"); managerSalary += ((earnPerShare * release / 0.8075) * 0.05); console.log("---computeManagerSalary()-----" + managerSalary); } } //完成後自動開始新增資訊 //但如果沒有經理薪水就不會新增 if (managerSalary > 0) addManagerSalaryInfo(managerSalary); console.log("---complete company_AddDividendLocalStorage()"); 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.mb-1')[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 checkUserHoldStock(userID, CUHS_runNumber, managerSalary) { 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); var userStockInfo = null !== window.sessionStorage.getItem ("userStockInfo") ? JSON.parse(window.sessionStorage.getItem ("userStockInfo")) : []; //userStcokInfo的格式: //{"userID": CWgfhqxbrJMxsknrb, "userCompany": [{"companyID": aaa, "userHold": number}, {}]} var userIndex = userStockInfo.findIndex(a => a.userID == userID); if (userIndex == -1) { userStockInfo.push({"userID": userID, "userCompany": []}); userIndex = userStockInfo.findIndex(a => a.userID == userID); } var ID, hold; var isChange = false; for (let i in directors) { ID = String(directors[i].companyId); hold = Number(directors[i].stocks); console.log("-----" + 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 { 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次 if (isChange) { window.sessionStorage.setItem ("userStockInfo", JSON.stringify(userStockInfo)); addCompleteMessage(); setTimeout(addUserProfitInfo, 10, userID, managerSalary); } else { if (CUHS_runNumber < 3) setTimeout(checkUserHoldStock, 100, userID, CUHS_runNumber+1, managerSalary); else { addCompleteMessage(); setTimeout(addUserProfitInfo, 10, userID, managerSalary); } } } } function addCompleteMessage() { var pageNum = "1"; if (($(".page-item.active")[0] !== undefined) && ($(".page-item.active")[0] !== null)) pageNum = $(".page-item.active")[0].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() { var userStockInfo = null !== window.sessionStorage.getItem ("userStockInfo") ? JSON.parse(window.sessionStorage.getItem ("userStockInfo")) : []; //userStcokInfo的格式: //{"userID": CWgfhqxbrJMxsknrb, "userCompany": [{"companyID": aaa, "userHold": number}, {}]} const userID = myID; var userIndex = userStockInfo.findIndex(a => a.userID == userID); if (userIndex == -1) { userStockInfo.push({"userID": userID, "userCompany": []}); userIndex = userStockInfo.findIndex(a => a.userID == userID); } var ID, hold; const directors = myHoldStock; //避免重複不斷的更新 if (directors.length != userStockInfo[userIndex].userCompany.length) { for (let i in directors) { ID = String(directors[i].companyId); hold = Number(directors[i].stocks); console.log("-----" + 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)); } } function addUserProfitInfo(userID, managerSalary) { const userStockInfo = null !== window.sessionStorage.getItem ("userStockInfo") ? JSON.parse(window.sessionStorage.getItem ("userStockInfo")) : []; //userStcokInfo的格式: //{"userID": CWgfhqxbrJMxsknrb, "userCompany": [{"companyID": aaa, "userHold": number}, {}]} const userIndex = userStockInfo.findIndex(a => a.userID == userID); //理論上到這邊userIndex就不可能是-1了啦..... const users = Meteor.connection._mongo_livedata_collections.users.find().fetch(); //console.log("for debug"); //console.log("userID: " + userID); //console.log(users); const users_i = users.findIndex(u => u._id == String(userID)); console.log("user_i: " + users_i); //for debug const Dividends = null !== window.localStorage.getItem ("Dividend") ? JSON.parse(window.localStorage.getItem ("Dividend")) : []; //Dividends規格 //{"companyID": A, "companyDividend": B, "companyPrice": C, "companyStock": D} const cash = Number(users[users_i].profile.money); var classUserProfitInfo, userAssets = 0, userProfit = 0, userCompanyNumber = 0; var price, earnPerShare; for (let k in userStockInfo[userIndex].userCompany) { price = 0; earnPerShare = 0; const dividendIndex = Dividends.findIndex(b => b.companyID == userStockInfo[userIndex].userCompany[k].companyID); if (dividendIndex != -1) { price = Number(Dividends[dividendIndex].companyPrice); earnPerShare = Number(Dividends[dividendIndex].companyDividend); } userAssets += price * userStockInfo[userIndex].userCompany[k].userHold; userProfit += earnPerShare * userStockInfo[userIndex].userCompany[k].userHold; userCompanyNumber += 1; } //console.log("compute complete"); var usingCash = 0; //正在用於買單的錢 var sellingStockWorth = 0; //正在賣的股票價值,以參考價計算 if (userID == myID) { const orders = myOrders; const orderType_buy = "購入"; const orderType_sell = "賣出"; for (let j in orders) { 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 dividendIndex = Dividends.findIndex(b => b.companyID == String(orders[j].companyId)); if (dividendIndex === -1) price = 0; else price = Number(Dividends[dividendIndex].companyPrice); sellingStockWorth += (price * (amount - done)); } else { console.log("不是買單也不是賣單,你怎麼做到的......"); } } console.log("usingCash: " + usingCash); console.log("sellingStockWorth" + sellingStockWorth); } console.log("start compute tax"); const tax = computeTax((userAssets + userProfit + managerSalary + cash + usingCash + sellingStockWorth)); console.log("compute complete"); var classUserTaxInfo = $("#userTaxInfoNumber"); if(classUserTaxInfo.length === 0) { $('<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.mb-1')[0]); $('<div class="col-6 text-right border-grid" id = "userTaxInfoNumber"><h2>$ ' + tax + '</h2></div>').insertAfter($('#userTaxInfoTitle')[0]); } else { console.log("start update info"); $("#userTaxInfoNumber")[0].innerHTML = "<h2>$ " + tax + "</h2>"; } classUserProfitInfo = $("#userProfitInfoNumber"); if(classUserProfitInfo.length === 0) { console.log("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.mb-1')[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.mb-1')[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.mb-1')[0]); $('<div class="col-6 text-right border-grid" id = "userCompanyNumberInfoNumber"><h2> ' + userCompanyNumber + '</h2></div>').insertAfter($('#userCompanyNumberInfoTitle')[0]); } else { console.log("start update info"); $("#userProfitInfoNumber")[0].innerHTML = "<h2>$ " + userProfit.toFixed() + "</h2>"; $("#userAssetsInfoNumber")[0].innerHTML = "<h2>$ " + userAssets + "</h2>"; $("#userCompanyNumberInfoNumber")[0].innerHTML = "<h2> " + userCompanyNumber + "</h2>"; } } // 稅率表:資產上限、稅率、累進差額 function computeTax(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); return output; } /*************accountInfo*************/ /*************************************/ /*************************************/ /**************Language***************/ var lan = ""; lan = null !== window.localStorage.getItem ("PM_language") ? window.localStorage.getItem ("PM_language") : "tw"; /*function ChangeLanguage(l){ if(lan === l)return; lan = l; window.localStorage.setItem ("PM_language",l); window.location.reload(); }*/ var Dict = { tw: { totalProfitInThisPage: "本頁預計分紅:", updateDividendScript: "更新預估分紅腳本", userTotalAssets: "使用者股票總值:", userTotalProfit: "預估股票分紅:", userTotalCompanyNumber: "持有公司總數:", managerTotalSalary: "預估經理薪水:", userTotalTax: "預估本季稅金:", PEratio: "本益比排行", stockPEInfo: "本益比", stockManagerSalaryInfo: "經理薪水", stockProfitInfo: "現金股利", stockWorthInfo: "股票總值", }, 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:", userTotalTax: "Estimated tax for this season:", PEratio: "PE ratio", stockPEInfo: "PE", stockManagerSalaryInfo: "Manager salary", stockProfitInfo: "Dividend", stockWorthInfo: "Stock worth", }, jp: { totalProfitInThisPage: "本ページ利回り総額:", updateDividendScript: "更新預估分紅腳本", userTotalAssets: "使用者股票總值:", userTotalProfit: "預估股票分紅:", userTotalCompanyNumber: "持有公司總數:", managerTotalSalary: "預估經理薪水:", userTotalTax: "預估本季稅金:", PEratio: "本益比排行", stockPEInfo: "本益比", stockManagerSalaryInfo: "經理薪水", stockProfitInfo: "現金股利", stockWorthInfo: "股票總值", }, marstw: { totalProfitInThisPage: "這ㄘ可yee拿ㄉ$$:", updateDividendScript: "有★★★版", userTotalAssets: "股票ㄉ$$:", userTotalProfit: "這ㄘ會拿ㄉ$$:", userTotalCompanyNumber: "偶ㄐ間公ㄙ:", managerTotalSalary: "雞李ㄉ西水:", userTotalTax: "ㄋ要交ㄉ茄:", PEratio: "ㄅyee逼排行", stockPEInfo: "ㄅyee逼", stockManagerSalaryInfo: "ㄐ李溪水", stockProfitInfo: "會給ㄉ前", stockWorthInfo: "股票ㄓˊ", } }; /**************Language***************/ /*************************************/
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址