diff --git a/README.md b/README.md index 13a37a2..5878d17 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -### utools-tmpl +### utools-fund -- 使用 uTools 模板插件的模板 +- 自选基金助手 diff --git a/package.json b/package.json index 910e693..d853df4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "utools-tmpl", + "name": "utools-fund", "version": "1.0.0", - "description": "使用 uTools 模板插件的模板", + "description": "自选基金助手", "main": "main.ts", "scripts": { "dev": "set NODE_ENV=development && rollup -c -w", @@ -26,4 +26,4 @@ "axios": "^0.19.2", "encoding": "^0.1.13" } -} +} \ No newline at end of file diff --git a/plugin.config.js b/plugin.config.js index c08afae..4869937 100644 --- a/plugin.config.js +++ b/plugin.config.js @@ -2,11 +2,11 @@ * @type { import ('./src/types/utools').PluginConfig } */ const pluginConfig = { - pluginName: 'utools-tmpl', + pluginName: '自选基金助手', version: 'v1.0.0', - description: '使用模板插件模式', + description: '自选基金助手', author: '罗君', - homepage: 'https://github.com/adams549659584/utools-tmpl', + homepage: 'https://github.com/adams549659584/utools-fund', // main: 'index.html', preload: 'preload.js', logo: 'assets/img/logo.png', @@ -23,20 +23,23 @@ const pluginConfig = { // }, features: [ { - code: 'utools_tmpl_hello_none', - explain: '无 UI 模式', - cmds: ['hello', 'none'], + code: 'utools_fund_add', + explain: '添加自选基金', + icon: 'assets/img/add.png', + cmds: ['添加自选基金', '基金', 'fund'] }, { - code: 'utools_tmpl_hello_list', - explain: '列表模式', - cmds: ['hello', 'list'], + code: 'utools_fund_del', + explain: '删除自选基金', + icon: 'assets/img/del.png', + cmds: ['删除自选基金', '基金', 'fund'] }, { - code: 'utools_tmpl_hello_doc', - explain: '文档模式', - cmds: ['hello', 'doc'], - }, + code: 'utools_fund_my', + explain: '我的自选基金', + icon: 'assets/img/logo.png', + cmds: ['我的自选基金', '基金', 'fund'], + } ], }; export default pluginConfig; diff --git a/rollup.config.js b/rollup.config.js index 5b8a318..3efb160 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -24,7 +24,7 @@ const rollupOptions = { output: { file: './dist/preload.js', format: 'cjs', - sourcemap: NODE_ENV === 'production' ? 'hidden' : 'inline', + sourcemap: NODE_ENV === 'production' ? false : 'inline', }, plugins: [ cleaner({ diff --git a/src/Hello.ts b/src/Hello.ts deleted file mode 100644 index 169f8a9..0000000 --- a/src/Hello.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default class Hello { - static sayHello(message) { - utools.showMessageBox({ - message, - }); - } - - static repeat(message) { - return utools.showMessageBox({ - message, - }); - } -} diff --git a/src/Helper/FundDBHelper.ts b/src/Helper/FundDBHelper.ts new file mode 100644 index 0000000..7e33043 --- /dev/null +++ b/src/Helper/FundDBHelper.ts @@ -0,0 +1,29 @@ +import { IFundEnt } from '@/model/IFundEnt'; +import { DBItem } from '@/types/utools'; + +const FUND_DB_PRE_FIX = 'fund_'; + +export default class FundDBHelper { + static set(fundId: string, data: IFundEnt) { + return utools.db.put({ + _id: `${FUND_DB_PRE_FIX}${fundId}`, + data, + }); + } + + static update(data: DBItem) { + return utools.db.put(data); + } + + static get(fundId: string) { + return utools.db.get(`${FUND_DB_PRE_FIX}${fundId}`); + } + + static getAll() { + return utools.db.allDocs(FUND_DB_PRE_FIX); + } + + static del(fundId: string) { + return utools.db.remove(`${FUND_DB_PRE_FIX}${fundId}`); + } +} diff --git a/src/assets/doc/index.html b/src/assets/doc/index.html deleted file mode 100644 index d10a7c8..0000000 --- a/src/assets/doc/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - 文档模式 - - - 去github - - diff --git a/src/assets/img/add.png b/src/assets/img/add.png new file mode 100644 index 0000000..dc00146 Binary files /dev/null and b/src/assets/img/add.png differ diff --git a/src/assets/img/del.png b/src/assets/img/del.png new file mode 100644 index 0000000..2686935 Binary files /dev/null and b/src/assets/img/del.png differ diff --git a/src/assets/img/down.png b/src/assets/img/down.png new file mode 100644 index 0000000..c0394ee Binary files /dev/null and b/src/assets/img/down.png differ diff --git a/src/assets/img/logo.png b/src/assets/img/logo.png index f42d663..01f074e 100644 Binary files a/src/assets/img/logo.png and b/src/assets/img/logo.png differ diff --git a/src/assets/img/up.png b/src/assets/img/up.png new file mode 100644 index 0000000..7627664 Binary files /dev/null and b/src/assets/img/up.png differ diff --git a/src/main.ts b/src/main.ts index b16b862..cc2a7e0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,69 +1,195 @@ -import { TemplatePlugin } from '@/types/utools'; -import Hello from './Hello'; +import { TemplatePlugin, CallbackListItem, DBItem } from '@/types/utools'; +import { get } from './Helper/HttpHelper'; +import FundDBHelper from './Helper/FundDBHelper'; +import { ISearchFundResult } from './model/ISearchFundResult'; +import { IFundValuationDetailResult } from './model/IFundValuationDetailResult'; +import { IFundEnt } from './model/IFundEnt'; -// utools.onPluginEnter(params => { -// Hello.sayHello(); -// }); +// 缓存基金详情 +let CACHE_FUND_DB_LIST: DBItem[]; +// 当前基金持有数量 +let CURRENT_FUND_HOLD_COUNT = 0; + +const getMyFundDetails = async () => { + const dbList = FundDBHelper.getAll(); + for (const db of dbList) { + const oldData = db.data; + const fundValuationDetail = await get( + `https://fundmobapi.eastmoney.com/FundMApi/FundVarietieValuationDetail.ashx?FCODE=${oldData.id}&deviceid=D03E8A22-9E0A-473F-B045-3745FC7931C4&plat=Iphone&product=EFund&version=6.2.9>OKEN=793EAE9248BC4181A9380C49938D1E31` + ); + if (fundValuationDetail.ErrCode !== 0) { + utools.showMessageBox({ + message: fundValuationDetail.ErrMsg, + }); + continue; + } + let lastTime = fundValuationDetail.Expansion.GZTIME; + let nowJJJZ = Number(fundValuationDetail.Expansion.GZ); + const searchFundResult = await get(`http://fundsuggest.eastmoney.com/FundSearch/api/FundSearchAPI.ashx?m=1&key=${oldData.id}`); + if (searchFundResult.ErrCode !== 0) { + utools.showMessageBox({ + message: searchFundResult.ErrMsg, + }); + continue; + } else { + const searchFundDetail = searchFundResult.Datas[0]; + // 最后单位净值 + if (lastTime.includes(searchFundDetail.FundBaseInfo.FSRQ)) { + lastTime = searchFundDetail.FundBaseInfo.FSRQ; + nowJJJZ = Number(searchFundDetail.FundBaseInfo.DWJZ); + } + } + db.data = { + ...oldData, + yesJJJZ: Number(fundValuationDetail.Expansion.DWJZ), + nowJJJZ: Number(nowJJJZ), + lastTime, + }; + FundDBHelper.update(db); + console.log(db.data); + } + return FundDBHelper.getAll(); +}; + +const fundDetailsToCbList = (dbList: DBItem[]) => { + let sumIncome = 0; + let cbList = dbList.map(db => { + const fund = db.data; + const rate = Math.round((fund.nowJJJZ / fund.yesJJJZ - 1) * 10000) / 10000; + const income = fund.holdCount > 0 ? rate * fund.holdCount * fund.yesJJJZ : 0; + sumIncome += income; + const cb: CallbackListItem = { + fundCode: fund.id, + title: `${fund.id} ${fund.name}`, + description: `${(rate * 100).toFixed(2)}% ¥${income.toFixed(2)}`, + icon: rate >= 0 ? 'assets/img/up.png' : 'assets/img/down.png', + }; + return cb; + }); + cbList = [ + { + title: `今日总收益`, + description: `¥${sumIncome.toFixed(2)}`, + icon: sumIncome >= 0 ? 'assets/img/up.png' : 'assets/img/down.png', + }, + ...cbList, + ]; + return cbList; +}; const preload: TemplatePlugin = { - utools_tmpl_hello_none: { - mode: 'none', + utools_fund_add: { + mode: 'list', args: { - placeholder: '无 UI 模式', - enter: (action, cb) => { - Hello.sayHello('Hello None'); - utools.outPlugin(); + placeholder: '输入基金简称/代码/拼音,回车键确认', + search: async (action, searchWord, callbackSetList) => { + // 获取一些数据 + let cbList: CallbackListItem[] = []; + if (searchWord) { + const searchResult = await get(`http://fundsuggest.eastmoney.com/FundSearch/api/FundSearchAPI.ashx?m=1&key=${searchWord}`); + if (searchResult) { + if (searchResult.ErrCode === 0) { + cbList = searchResult.Datas.map(fund => { + const cb: CallbackListItem = { + title: fund.CODE, + description: fund.NAME, + DWJZ: fund.FundBaseInfo.DWJZ, + FSRQ: fund.FundBaseInfo.FSRQ, + }; + return cb; + }); + } else { + utools.showMessageBox({ + message: searchResult.ErrMsg, + }); + } + } + } + callbackSetList(cbList); + }, // 用户选择列表中某个条目时被调用 + select: (action, itemData, callbackSetList) => { + const existFund = FundDBHelper.get(itemData.title); + if (!existFund) { + FundDBHelper.set(itemData.title, { + id: itemData.title, + name: itemData.description, + holdCount: 0, + yesJJJZ: 0, + nowJJJZ: itemData.DWJZ, + lastTime: itemData.FSRQ, + }); + } + utools.redirect('我的自选基金', ''); }, }, }, - utools_tmpl_hello_list: { + utools_fund_del: { mode: 'list', args: { - placeholder: '列表模式', + placeholder: '选择需删除的基金,回车键确认', enter: (action, callbackSetList) => { - console.log(action); + const dbList = FundDBHelper.getAll(); + const cbList = dbList.map(db => { + const cb: CallbackListItem = { + title: db.data.id, + description: db.data.name, + }; + return cb; + }); // 如果进入插件就要显示列表数据 - callbackSetList([ - { - title: '这是标题', - description: '这是描述(跳去我的github)', - icon: '', // 图标(可选) - url: 'https://github.com/adams549659584/utools-tmpl', - }, - ]); + callbackSetList(cbList); }, search: (action, searchWord, callbackSetList) => { - // 获取一些数据 - // 执行 callbackSetList 显示出来 - callbackSetList([ - { - title: searchWord, - description: '虽然文字变了,但是还是跳去我的github', - icon: '', // 图标, - url: 'https://github.com/adams549659584/utools-tmpl', - other: 'xxx', - }, - ]); + let dbList = FundDBHelper.getAll(); + if (searchWord) { + dbList = dbList.filter(x => x.data.id.includes(searchWord) || x.data.name.includes(searchWord)); + } + const cbList = dbList.map(db => { + const cb: CallbackListItem = { + title: db.data.id, + description: db.data.name, + }; + return cb; + }); + callbackSetList(cbList); }, // 用户选择列表中某个条目时被调用 select: (action, itemData, callbackSetList) => { - utools.hideMainWindow(); - const url = itemData.url; - require('electron').shell.openExternal(url); - utools.outPlugin(); + FundDBHelper.del(itemData.title); + utools.redirect('我的自选基金', ''); }, }, }, - utools_tmpl_hello_doc: { - mode: 'doc', + utools_fund_my: { + mode: 'list', args: { - indexes: [ - { - t: '这是标题', - d: '这是描述', - p: 'assets/doc/index.html', //页面, 只能是相对路径 - }, - ], - placeholder: '文档模式', + placeholder: '输入持有份额,选择对应基金,回车键保存', + enter: async (action, callbackSetList) => { + const dbList = await getMyFundDetails(); + // 缓存 + CACHE_FUND_DB_LIST = dbList; + CURRENT_FUND_HOLD_COUNT = 0; + const cbList = fundDetailsToCbList(dbList); + // 如果进入插件就要显示列表数据 + callbackSetList(cbList); + }, + search: async (action, searchWord, callbackSetList) => { + let dbList = CACHE_FUND_DB_LIST && CACHE_FUND_DB_LIST.length > 0 ? CACHE_FUND_DB_LIST : await getMyFundDetails(); + CURRENT_FUND_HOLD_COUNT = Number(searchWord); + const cbList = fundDetailsToCbList(dbList); + callbackSetList(cbList); + }, // 用户选择列表中某个条目时被调用 + select: (action, itemData, callbackSetList) => { + if (!CACHE_FUND_DB_LIST || CACHE_FUND_DB_LIST.length === 0) { + utools.redirect('添加自选基金', ''); + return; + } + if (action.type === 'text' && itemData.fundCode) { + const fundDb = FundDBHelper.get(itemData.fundCode); + fundDb.data.holdCount = CURRENT_FUND_HOLD_COUNT; + FundDBHelper.update(fundDb); + } + utools.redirect('我的自选基金', ''); + }, }, }, }; diff --git a/src/model/IFundEnt.ts b/src/model/IFundEnt.ts new file mode 100644 index 0000000..43c536b --- /dev/null +++ b/src/model/IFundEnt.ts @@ -0,0 +1,31 @@ +export interface IFundEnt { + /** + * 基金id + */ + id: string; + + /** + * 基金名称 + */ + name: string; + + /** + * 持有数量 + */ + holdCount: number; + + /** + * 昨日基金净值 + */ + yesJJJZ: number; + + /** + * 现在基金净值 + */ + nowJJJZ: number; + + /** + * 当前净值对应时间 + */ + lastTime: string; +} diff --git a/src/model/IFundValuationDetailResult.ts b/src/model/IFundValuationDetailResult.ts new file mode 100644 index 0000000..5e80ce5 --- /dev/null +++ b/src/model/IFundValuationDetailResult.ts @@ -0,0 +1,32 @@ +/** + * 基金估值结果 + */ +export interface IFundValuationDetailResult { + ErrCode: number; + ErrMsg: string; + TotalCount: number; + Datas: string[]; + Expansion: { + FCODE: string; + SHORTNAME: string; + /** + * 估值时间 2020-08-14 15:00 + */ + GZTIME: string; + + /** + * 估值 + */ + GZ: string; + + /** + * 单位净值 + */ + DWJZ: string; + + /** + * 净值日期 2020-08-13 + */ + JZRQ: string; + }; +} diff --git a/src/model/ISearchFundResult.ts b/src/model/ISearchFundResult.ts new file mode 100644 index 0000000..5774af7 --- /dev/null +++ b/src/model/ISearchFundResult.ts @@ -0,0 +1,22 @@ +/** + * 基金搜索结果 + */ +export interface ISearchFundResult { + ErrCode: number; + ErrMsg: string; + Datas: { + CODE: string; + NAME: string; + FundBaseInfo: { + /** + * 单位净值 + */ + DWJZ: number; + + /** + * 净值对应日期 2020-08-14 + */ + FSRQ: string; + }; + }[]; +} diff --git a/src/types/utools.d.ts b/src/types/utools.d.ts index 7e90464..12d60ad 100644 --- a/src/types/utools.d.ts +++ b/src/types/utools.d.ts @@ -100,7 +100,7 @@ export interface UTools { * @param cmd 插件关键词 * @param payload */ - redirect(cmd: string, payload: string | any): Boolean; + redirect(cmd: string, payload: string | FilesPayload | WindowPayload;): Boolean; /** * 弹出文件选择框