├── public
└── favicon.ico
├── src
├── assets
│ ├── logo.png
│ ├── js
│ │ ├── storage.js
│ │ ├── cart.js
│ │ └── api.js
│ └── css
│ │ └── cart.css
├── shims-vue.d.ts
├── request.ts
├── main.ts
├── components
│ ├── details
│ │ ├── Manager.vue
│ │ ├── allocate
│ │ │ ├── Bond.vue
│ │ │ ├── Industry.vue
│ │ │ ├── Stock.vue
│ │ │ ├── Concentrate.vue
│ │ │ ├── IndustrySw.vue
│ │ │ ├── Asset.vue
│ │ │ └── AllocateHis.vue
│ │ ├── charts
│ │ │ ├── CyclePerformance.vue
│ │ │ ├── ScaleChange.vue
│ │ │ ├── RiskTraceShort.vue
│ │ │ ├── Turnover.vue
│ │ │ ├── HistoryStyle.vue
│ │ │ ├── Performance.vue
│ │ │ ├── HolderInfo.vue
│ │ │ ├── Statistic.vue
│ │ │ ├── Style.vue
│ │ │ └── Brinson.vue
│ │ ├── DetailLayout.vue
│ │ ├── Allocate.vue
│ │ ├── manager
│ │ │ ├── Managed.vue
│ │ │ └── TopHolding.vue
│ │ ├── Fact.vue
│ │ ├── KeyPortfolio.vue
│ │ └── Attribution.vue
│ ├── etf
│ │ ├── ETFLayout.vue
│ │ ├── ETFRecent.vue
│ │ ├── ETFCategory.vue
│ │ └── ETFHome.vue
│ ├── Cart.vue
│ ├── layout
│ │ ├── Layout.vue
│ │ └── Header.vue
│ ├── dashboard
│ │ ├── Simple.vue
│ │ ├── Detail.vue.jsx.map
│ │ ├── Detail.vue
│ │ └── Detail.vue.jsx
│ ├── Home.vue
│ ├── Dashboard.vue
│ ├── portfolio
│ │ ├── Portfolio.vue.jsx.map
│ │ ├── Portfolio.vue.jsx
│ │ └── Portfolio.vue
│ ├── screen
│ │ ├── AddToPool.vue
│ │ └── ScreenResult.vue
│ ├── News.vue
│ └── cart
│ │ ├── Basic.vue
│ │ ├── General.vue
│ │ └── CartTable.vue.jsx.map
├── App.vue
└── router
│ └── index.ts
├── .gitignore
├── vite.config.ts
├── index.html
├── tsconfig.json
├── package.json
└── README.md
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PengchuanC/fund_vue3/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PengchuanC/fund_vue3/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | dist-ssr
5 | *.local
6 | .idea
7 | dist.tar.gz
8 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import { DefineComponent } from 'vue'
3 | const component: DefineComponent<{}, {}, any>
4 | export default component
5 | }
6 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import vue from '@vitejs/plugin-vue'
3 | import vueJsx from '@vitejs/plugin-vue-jsx'
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [vue(), vueJsx()]
8 | })
9 |
--------------------------------------------------------------------------------
/src/request.ts:
--------------------------------------------------------------------------------
1 | import {extend} from "umi-request";
2 |
3 |
4 | const baseURL = "https://product.nomuraoi-sec.com/api/v1"
5 | // const baseURL = "http://localhost:8000/api/v1"
6 | const request = extend({
7 | prefix: baseURL,
8 | timeout: 50000,
9 | useCache: true
10 | })
11 |
12 | export default request;
13 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import element from 'element-plus'
3 | import 'element-plus/lib/theme-chalk/index.css'
4 | import vxe from 'vxe-table'
5 | import 'vxe-table/lib/style.css'
6 | import locale from 'element-plus/lib/locale/lang/zh-cn'
7 |
8 | import App from './App.vue'
9 | import router from './router'
10 |
11 | const app = createApp(App)
12 | app.use(router)
13 | app.use(element, { locale })
14 | app.use(vxe)
15 |
16 | app.mount('#app')
17 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 基金筛选系统
8 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "strict": true,
7 | "jsx": "preserve",
8 | "sourceMap": true,
9 | "resolveJsonModule": true,
10 | "esModuleInterop": true,
11 | "lib": ["esnext", "dom"],
12 | "types": ["vite/client"],
13 | "skipLibCheck": true,
14 | "noImplicitAny": false
15 | },
16 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/details/Manager.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
25 |
26 |
39 |
--------------------------------------------------------------------------------
/src/assets/js/storage.js:
--------------------------------------------------------------------------------
1 |
2 | export default class Storage {
3 | static saveSearchHistory(search){
4 | let history = Storage.loadSearchHistory()
5 | for (const v in Object.keys(history)) {
6 | if (history[v].label === search.label){
7 | return
8 | }
9 | }
10 | history.unshift(search)
11 | history = Array.from(new Set(history))
12 | history = history.slice(0, 15)
13 | localStorage.setItem('searchHistory', JSON.stringify(history))
14 | }
15 |
16 | static loadSearchHistory(){
17 | let historyStr = localStorage.getItem('searchHistory')
18 | let history = JSON.parse(historyStr)
19 | return history || []
20 | }
21 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fund",
3 | "version": "2.0.0",
4 | "scripts": {
5 | "dev": "vite --host",
6 | "build": "vue-tsc --noEmit && vite build",
7 | "serve": "vite preview"
8 | },
9 | "dependencies": {
10 | "@vitejs/plugin-vue-jsx": "^1.1.7",
11 | "dayjs": "^1.10.6",
12 | "echarts": "^5.1.2",
13 | "element-plus": "^1.0.2-beta.71",
14 | "numeral": "^2.0.6",
15 | "umi-request": "^1.3.9",
16 | "vue": "^3.2.4",
17 | "vue-router": "4.0.11",
18 | "vxe-table": "^4.0.26",
19 | "xe-utils": "^3.3.1"
20 | },
21 | "devDependencies": {
22 | "@types/numeral": "^2.0.1",
23 | "@vitejs/plugin-vue": "^1.4.0",
24 | "@vue/compiler-sfc": "^3.2.4",
25 | "typescript": "^4.2.4",
26 | "vite": "^2.5.0",
27 | "vue-tsc": "^0.2.3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/components/etf/ETFLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
34 |
35 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
49 |
--------------------------------------------------------------------------------
/src/assets/css/cart.css:
--------------------------------------------------------------------------------
1 | .overview {
2 | width: 100%;
3 | }
4 |
5 | .head-wrapper {
6 | width: 100%;
7 | background-color: #f0f0f0;
8 | text-align: left;
9 | }
10 |
11 | h4 {
12 | margin: 10px;
13 | }
14 |
15 | .selection-area {
16 | text-align: left;
17 | width: 100%;
18 | padding: 0 20px;
19 | margin: 5px 0;
20 | }
21 |
22 | .items-wrapper {
23 | display: inline-flex;
24 | width: 100%;
25 | }
26 |
27 | .target {
28 | font-weight: normal;
29 | width: 200px;
30 | }
31 |
32 | .selection-items {
33 | display: flex;
34 | flex-wrap: wrap;
35 | justify-content: flex-start;
36 | width: 100%;
37 | margin-bottom: 10px;
38 | border-bottom: #cccccc dashed 1px;
39 | }
40 |
41 | .selection-items > .checkbox {
42 | margin-right: 20px;
43 | }
44 |
45 | .risk-selector {
46 | width: 600px;
47 | min-width: 400px;
48 | }
49 |
50 | .selector-items {
51 | display: flex;
52 | flex-wrap: wrap;
53 | justify-content: flex-start;
54 | width: 100%;
55 | margin-bottom: 10px;
56 | }
57 |
58 | .data-present {
59 | width: 100%;
60 | margin: 0 0 10px;
61 | }
62 |
63 | .submit-button {
64 | margin-left: 20px;
65 | }
--------------------------------------------------------------------------------
/src/components/Cart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
基金筛选
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
40 |
41 |
--------------------------------------------------------------------------------
/src/components/details/allocate/Bond.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
更新日期: {{data.date}}
15 |
16 |
17 |
18 |
49 |
50 |
61 |
--------------------------------------------------------------------------------
/src/components/details/allocate/Industry.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
更新日期: {{data.date}}
14 |
15 |
16 |
17 |
51 |
52 |
63 |
--------------------------------------------------------------------------------
/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import {createRouter, createWebHistory} from "vue-router";
2 |
3 | const routes = [
4 | {
5 | name: 'home',
6 | path: '/home',
7 | component: () => import('../components/Home.vue'),
8 | meta: {keepAlive: true}
9 | },
10 | {
11 | name: 'cart',
12 | path: '/cart',
13 | component: () => import('../components/Cart.vue'),
14 | meta: {keepAlive: true}
15 | },
16 | {
17 | name: 'etf',
18 | path: '/etf',
19 | component: () => import('../components/etf/ETFLayout.vue'),
20 | meta: {keepAlive: true}
21 | },
22 | {
23 | name: 'screen',
24 | path: '/screen',
25 | component: () => import('../components/Screen.vue')
26 | },
27 | {
28 | name: 'dashboard',
29 | path: '/dashboard',
30 | component: () => import('../components/Dashboard.vue'),
31 | meta: {keepAlive: true}
32 | },
33 | {
34 | name: 'news',
35 | path: '/news',
36 | component: () => import('../components/News.vue'),
37 | meta: {keepAlive: true}
38 | },
39 | {
40 | name: 'portfolio',
41 | path: '/portfolio',
42 | component: () => import('../components/portfolio/Portfolio.vue'),
43 | meta: {keepAlive: true}
44 | },
45 | {
46 | name: 'info',
47 | path: '/info/:secucode(\\d+)',
48 | component: () => import('../components/details/DetailLayout.vue'),
49 | meta: {keepAlive: true}
50 | },
51 | {
52 | path: '/',
53 | redirect: () => {
54 | return {name: 'home'}
55 | }
56 | },
57 | ]
58 |
59 | export default createRouter({
60 | end: false,
61 | history: createWebHistory(),
62 | sensitive: false,
63 | strict: false,
64 | routes
65 | })
66 |
--------------------------------------------------------------------------------
/src/components/details/allocate/Stock.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
更新日期: {{data.date}}
17 |
18 |
19 |
20 |
54 |
55 |
66 |
--------------------------------------------------------------------------------
/src/components/etf/ETFRecent.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
82 |
83 |
--------------------------------------------------------------------------------
/src/components/details/charts/CyclePerformance.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
收益特征
4 |
5 |
当前基金暂无此类数据
6 |
7 |
8 |
9 |
81 |
82 |
93 |
--------------------------------------------------------------------------------
/src/components/details/DetailLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 基金详情
5 | {{ state.currentTab }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
68 |
69 |
--------------------------------------------------------------------------------
/src/components/layout/Layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 | UP
27 |
28 |
29 |
30 |
31 |
32 |
50 |
51 |
--------------------------------------------------------------------------------
/src/components/details/charts/ScaleChange.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 规模变化
4 |
5 |
6 |
7 |
92 |
93 |
99 |
--------------------------------------------------------------------------------
/src/components/details/Allocate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 资产配置
7 |
8 |
9 |
10 | 行业配置
11 |
12 |
13 |
14 | 资产配置-多期
15 |
16 |
17 |
18 | 前十大集中度
19 |
20 |
21 |
22 |
23 |
24 | 重仓债券
25 |
26 |
27 |
28 | 重仓股票
29 |
30 |
31 |
32 | 行业配置
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
62 |
63 |
89 |
--------------------------------------------------------------------------------
/src/components/dashboard/Simple.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ year }}
5 | {{ style }}
6 | {{ industry }}
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
67 |
68 |
--------------------------------------------------------------------------------
/src/components/details/allocate/Concentrate.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
91 |
92 |
102 |
--------------------------------------------------------------------------------
/src/components/details/charts/RiskTraceShort.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
92 |
93 |
99 |
--------------------------------------------------------------------------------
/src/components/details/charts/Turnover.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
96 |
97 |
103 |
--------------------------------------------------------------------------------
/src/components/details/charts/HistoryStyle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
风格分类
4 |
5 |
当前基金暂无此类数据
6 |
7 |
8 |
9 |
95 |
96 |
107 |
--------------------------------------------------------------------------------
/src/components/details/charts/Performance.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
100 |
101 |
104 |
--------------------------------------------------------------------------------
/src/components/details/allocate/IndustrySw.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
101 |
102 |
112 |
--------------------------------------------------------------------------------
/src/components/details/manager/Managed.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ state.manager.manager }}
6 |
7 |
8 | {{ state.manager.start }}
9 |
10 |
11 | {{ formatter(state.manager.managed_scale).format('0,000.0') }}亿元
12 |
13 |
14 |
20 |
21 |
22 |
23 |
116 |
117 |
129 |
--------------------------------------------------------------------------------
/src/components/details/Fact.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 区间表现
9 |
10 |
11 |
12 | 基金风格
13 |
14 |
15 |
16 | 业绩归因
17 |
18 |
19 |
20 | 换手率
21 |
22 |
23 |
24 | 业绩评价
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 业绩曲线
37 |
38 |
39 |
40 | 规模变化
41 |
42 |
43 |
44 | 持有人结构
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
83 |
84 |
106 |
--------------------------------------------------------------------------------
/src/components/details/allocate/Asset.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 更新日期: {{data.date}}
19 |
20 |
21 |
109 |
110 |
131 |
--------------------------------------------------------------------------------
/src/components/details/charts/HolderInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
130 |
131 |
137 |
--------------------------------------------------------------------------------
/src/components/Home.vue:
--------------------------------------------------------------------------------
1 |
2 | 基金分类汇总
3 |
4 |
7 |
8 |
17 |
18 |
19 |
20 |
21 |
22 |
137 |
138 |
--------------------------------------------------------------------------------
/src/components/details/charts/Statistic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{numeral(state.info.nav).format('1.0000')}} ({{state.info.update_date}})
6 |
7 |
8 | {{numeral(state.info.nav_acc).format('1.0000')}} ({{state.info.update_date}})
9 |
10 |
11 |
12 |
13 |
14 | {{numeral(state.info.return_1w/100).format('0.00%')}}
15 |
16 |
17 | {{numeral(state.info.return_1m/100).format('0.00%')}}
18 |
19 |
20 | {{numeral(state.info.return_3m/100).format('0.00%')}}
21 |
22 |
23 | {{numeral(state.info.return_6m/100).format('0.00%')}}
24 |
25 |
26 | {{numeral(state.info.return_1y/100).format('0.00%')}}
27 |
28 |
29 | {{numeral(state.info.return_3y/100).format('0.00%')}}
30 |
31 |
32 |
33 |
34 |
35 | {{state.manager.classify}}
36 |
37 |
38 | {{numeral(state.manager.scale).format('0,000.0')}}(亿元)
39 |
40 |
41 | {{state.manager.manager}}
42 |
43 |
44 | {{state.manager.setup}}
45 |
46 |
47 | {{state.manager.start}}
48 |
49 |
50 | {{numeral(state.manager.managed_scale).format('0,000.0')}}(亿元)
51 |
52 |
53 |
54 |
55 |
56 | {{numeral(state.manager.stock).format('0.00%')}}
57 |
58 |
59 | {{state.manager.style}}
60 |
61 |
62 | {{state.manager.scale_type}}
63 |
64 |
65 | {{state.manager.industry_style}}
66 |
67 |
68 | {{state.manager.industry}}
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
114 |
115 |
118 |
--------------------------------------------------------------------------------
/src/components/layout/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
37 |
38 |
39 |
96 |
97 |
127 |
--------------------------------------------------------------------------------
/src/components/details/allocate/AllocateHis.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
139 |
140 |
150 |
--------------------------------------------------------------------------------
/src/components/details/manager/TopHolding.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
任职以来持仓前20位
4 |
12 |
13 |
14 |
15 |
157 |
158 |
176 |
--------------------------------------------------------------------------------
/src/components/Dashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 时间段:
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | 风格:
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | 行业:
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
110 |
111 |
144 |
--------------------------------------------------------------------------------
/src/assets/js/cart.js:
--------------------------------------------------------------------------------
1 | import {defineComponent, onMounted, reactive} from "vue";
2 | import request from '../../request'
3 | import CartTable from "../../components/cart/CartTable.vue";
4 |
5 | const checkbox = {
6 | indeterminate: false,
7 | checkAll: true,
8 | checkAllGroup: []
9 | }
10 |
11 | const props = {
12 | multiple: true,
13 | expandTrigger: 'hover'
14 | }
15 |
16 | const createCart = (propName, url)=>{
17 | return defineComponent({
18 | name: propName,
19 | components: { CartTable },
20 | setup(){
21 | const state = reactive({
22 | init: false,
23 | selections: {checkbox: {}, selectors: {}},
24 | selected: {checkbox: {}, selectors: {}},
25 | data: [],
26 | loading: true
27 | })
28 |
29 | const basicUrl = url
30 |
31 | // 初始化选项布置
32 | const fetchSelections = ()=>{
33 | request.get(basicUrl + '/selections').then(r=>{
34 | state.selections = r.data
35 | const data = r.data.checkbox
36 | for (const attr in data) {
37 | if (data.hasOwnProperty(attr)){
38 | const groups = Object.keys(data[attr].value)
39 | state.selected.checkbox[attr] = {...checkbox, checkAllGroup: groups}
40 | }
41 | }
42 |
43 | const { selectors } = r.data
44 | for (const name in selectors) {
45 | if (selectors.hasOwnProperty(name)){
46 | state.selected.selectors[name] = []
47 | }
48 | }
49 |
50 | state.init = true
51 | })
52 | }
53 |
54 | onMounted(()=>{
55 | fetchSelections()
56 | })
57 |
58 | const handleCheckAll = (group) => {
59 | if (state.selected.checkbox[group].indeterminate) {
60 | state.selected.checkbox[group].checkAll = false;
61 | } else {
62 | state.selected.checkbox[group].checkAll = !state.selected.checkbox[group].checkAll;
63 | }
64 | state.selected.checkbox[group].indeterminate = false;
65 |
66 | if (state.selected.checkbox[group].checkAll) {
67 | state.selected.checkbox[group].checkAllGroup = Object.keys(state.selections.checkbox[group].value);
68 | } else {
69 | state.selected.checkbox[group].checkAllGroup = [];
70 | }
71 | }
72 |
73 |
74 | const checkAllGroupChange = (data, group) => {
75 | if (data.length === Object.keys(state.selections.checkbox[group].value).length) {
76 | state.selected.checkbox[group].indeterminate = false;
77 | state.selected.checkbox[group].checkAll = true;
78 | } else if (data.length > 0) {
79 | state.selected.checkbox[group].indeterminate = true;
80 | state.selected.checkbox[group].checkAll = false;
81 | } else {
82 | state.selected.checkbox[group].indeterminate = false;
83 | state.selected.checkbox[group].checkAll = false;
84 | }
85 | }
86 |
87 | const submit = ()=>{
88 | const checkbox = Object.keys(state.selected.checkbox).map(name=>{
89 | return {name: name, value: state.selected.checkbox[name].checkAllGroup }
90 | })
91 |
92 | state.loading = true
93 | const params = {checkbox:checkbox, selectors: state.selected.selectors}
94 | request.post(basicUrl, {data: params}).then(r => {
95 | state.data = r.data
96 | state.loading = false
97 | })
98 | }
99 |
100 | return { state, props, handleCheckAll, checkAllGroupChange, submit }
101 | }
102 | })
103 | }
104 |
105 | export default createCart
--------------------------------------------------------------------------------
/src/components/details/charts/Style.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
163 |
164 |
170 |
--------------------------------------------------------------------------------
/src/assets/js/api.js:
--------------------------------------------------------------------------------
1 | import {extend} from "umi-request";
2 |
3 |
4 | const baseURL = "https://product.nomuraoi-sec.com/api/v2"
5 | // const baseURL = "http://localhost:8005/api/v2"
6 | const request = extend({
7 | prefix: baseURL,
8 | timeout: 50000,
9 | useCache: true
10 | })
11 |
12 | // 基金周期内业绩表现
13 | export function cycle(secucode){
14 | return request(
15 | "/fundinfo/cycle",
16 | {params: {secucode}}
17 | )
18 | }
19 |
20 | // 基金最新业绩表现
21 | export function latestPerformance(secucode){
22 | return request(
23 | "/fundinfo",
24 | {params: {secucode}}
25 | )
26 | }
27 |
28 | // 基金风控指标表格
29 | export function riskPerformance(secucode){
30 | return request(
31 | "/fundinfo/performance",
32 | {params: {secucode}}
33 | )
34 | }
35 |
36 | // 基金持有人结构
37 | export function holder(secucode){
38 | return request(
39 | "/fundinfo/holder",
40 | {
41 | params: {secucode}
42 | }
43 | )
44 | }
45 |
46 | // 基金换手率
47 | export function turnover(secucode){
48 | return request(
49 | "/fundinfo/turnover",
50 | {params: {secucode}}
51 | )
52 | }
53 |
54 | // 基金规模变化
55 | export function scaleChange(secucode){
56 | return request(
57 | "/fundinfo/scale",
58 | {params: {secucode}}
59 | )
60 | }
61 |
62 | // 基金与指数相似度
63 | export function historyStyle(secucode){
64 | return request(
65 | "/fundinfo/his_style",
66 | {params: {secucode}}
67 | )
68 | }
69 |
70 |
71 | // 基金风险评价雷达图
72 | export function shortRisk(secucode) {
73 | return request(
74 | "/fundinfo/risk/short",
75 | {params: {secucode}}
76 | )
77 | }
78 |
79 | export function longRisk(secucode) {
80 | return request(
81 | "/fundinfo/risk/long",
82 | {params: {secucode}}
83 | )
84 | }
85 |
86 | // 基金经理在管基金信息
87 | export function managedFund(secucode) {
88 | return request(
89 | "/manager/managed",
90 | {params: {secucode}}
91 | )
92 | }
93 |
94 | // 基金经理任职以来持仓前20位股票
95 | export function holdingTop20(secucode) {
96 | return request(
97 | "/manager/topHolding",
98 | {params: {secucode}}
99 | )
100 | }
101 |
102 | // 基金搜索
103 | export function searchFund(search) {
104 | return request(
105 | "/search/fundList",
106 | {params: {search}}
107 | )
108 | }
109 |
110 | // 基金风格
111 | export function rbsaStyle(secucode) {
112 | return request(
113 | '/fundinfo/style',
114 | {params:{secucode}}
115 | )
116 | }
117 |
118 |
119 | // 基金风格指数与宽基指数
120 | export function styleAndBenchmarkIndices(){
121 | return request(
122 | "/fundinfo/style&benchmark"
123 | )
124 | }
125 |
126 | // 基金与基准指数净值对比
127 | export function netValueSeries(secucode, style, benchmark) {
128 | return request(
129 | "/fundinfo/nav",
130 | {params:{secucode, style, benchmark}}
131 | )
132 | }
133 |
134 | // 基金分年度业绩表现
135 | export function yearlyPerformance(secucode, style, benchmark){
136 | return request(
137 | "/fundinfo/nav/yearly",
138 | {params:{secucode, style, benchmark}}
139 | )
140 | }
141 |
142 | // 基金与指数近期表现
143 | export function recentPerformance(secucode, style, benchmark){
144 | return request(
145 | "/fundinfo/nav/recent",
146 | {params:{secucode, style, benchmark}}
147 | )
148 | }
149 |
150 | // 基金风格信息
151 | export function fundStyle(secucode) {
152 | return request(
153 | '/manager',
154 | { params: {secucode}}
155 | )
156 | }
157 |
158 | // 基金资产配置
159 | export function fundAllocate(secucode) {
160 | return request(
161 | '/asset',
162 | { params: {secucode}}
163 | )
164 | }
165 |
166 | // 基金历史资产配置
167 | export function fundHistoricalAllocate(secucode) {
168 | return request(
169 | '/asset/history',
170 | { params: {secucode}}
171 | )
172 | }
173 |
174 | // 基金重仓持股
175 | export function fundKeyStock(secucode) {
176 | return request(
177 | '/asset/keyStock',
178 | { params: {secucode}}
179 | )
180 | }
181 |
182 | // 基金重仓持债
183 | export function fundKeyBond(secucode) {
184 | return request(
185 | '/asset/keyBond',
186 | { params: {secucode}}
187 | )
188 | }
189 |
190 | // 基金持股集中度
191 | export function fundConcentrate(secucode) {
192 | return request(
193 | '/asset/concentrate',
194 | { params: {secucode}}
195 | )
196 | }
197 |
198 | // 基金行业分布
199 | export function fundIndustryCSI(secucode) {
200 | return request(
201 | '/asset/industryCsi',
202 | { params: {secucode}}
203 | )
204 | }
205 |
206 | // 基金行业风格
207 | export function fundIndustryStyle(secucode) {
208 | return request(
209 | '/asset/style',
210 | { params: {secucode}}
211 | )
212 | }
213 |
--------------------------------------------------------------------------------
/src/components/portfolio/Portfolio.vue.jsx.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"Portfolio.vue.jsx","sourceRoot":"","sources":["Portfolio.vue"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/src/components/details/KeyPortfolio.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
任职以来重仓股票概览
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
{{date}}
17 |
22 | {{row.stockname}}
23 |
24 |
{{sum(rows)}}
25 |
26 |
27 |
28 |
29 |
总结:
30 |
{{state.msg}}
31 |
32 |
33 |
34 |
35 |
36 |
{{idx}}
37 |
41 |
42 |
{{s.stockname}}
43 |
{{numeral(s.ratio).format('0.00%')}}
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
103 |
104 |
210 |
--------------------------------------------------------------------------------
/src/components/dashboard/Detail.vue.jsx.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"Detail.vue.jsx","sourceRoot":"","sources":["Detail.vue"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # 【FOF】基金筛选系统介绍
3 |
4 | [点击这里](https://pengchuanc.github.io/posts/introduction-fundscreen/) 前往我的主页查看更多项目, 此项目仅为**基金筛选系统前端部分**。
5 |
6 | # 一、系统介绍
7 |
8 | 为了方便基金投资,开发了基金投资相关系统,基金筛选系统为最初开发系统,目前已经过三次迭代。当前基金筛选系统主要包含8个模块,分别为
9 |
10 | 1. 基金市场整体统计
11 | 2. 基金挑选
12 | 3. 基金看板
13 | 4. ETF每日跟踪
14 | 5. 基金分类筛选入池
15 | 6. 入池基金管理
16 | 7. 市场热点资讯
17 | 8. 基金详细信息
18 |
19 |
20 |
21 | # 二、功能展示
22 |
23 | ## 1.基金市场统计
24 |
25 | 该模块为整个系统首页,统计截止上个月底的基金市场规模和数量,基金分类为野村东方国际FOF组根据基金发行公告中的投资范围自定义的分类方式。
26 |
27 | 
28 |
29 | 
30 |
31 | 
32 |
33 |
34 |
35 | ## 2.基金挑选
36 |
37 | 基金挑选模块可以从全市场的公募基金中按一些预设的条件,挑选出符合条件的基金,针对常用的主动权益基金、被动指数基金和债券型基金会有一些更符合基金特点的筛选条件。
38 |
39 |
40 |
41 | ### 2.1 筛选界面预览
42 |
43 | 界面上方为基金筛选条件,下方为展示表格。
44 |
45 | 
46 |
47 | 执行筛选条件后:
48 |
49 | 
50 |
51 | 数据预览表格可全屏,方便查看数据。
52 |
53 | 
54 |
55 |
56 |
57 | ## 3.基金看板
58 |
59 | 根据基金年报和半年报持仓股票,对基金持有股票总市值占比大于60%的基金(多为股票型和偏股混合型基金),可以按市值风格将基金分为成长型、均衡性和价值型,根据股票行业占比,可以确定基金的行业风格。
60 |
61 | 基金看板模块即是对这些基金的跟踪,基金看板首页将这些基金类型按小卡片形式展示,单个卡片最多不超过5条记录,点击全屏按钮可以查看全部该类型基金。
62 |
63 | 
64 |
65 | 展开后如下:
66 |
67 | 
68 |
69 |
70 |
71 | ## 4.ETF每日跟踪
72 |
73 | ### 4.1 资金概览
74 |
75 | 本页可以按日频、周频、月频查看各类ETF净资金流向,通过图表两种方式展现。
76 |
77 | 
78 |
79 |
80 |
81 | ### 4.2 分类统计
82 |
83 | 本页可以查看具体某一类ETF的资金流向情况和场内、场外业绩表现情况。
84 |
85 | 
86 |
87 |
88 |
89 | ### 4.3 近期情况
90 |
91 | 本页展示分周度、分类型ETF资金流入热力图。
92 |
93 | 
94 |
95 |
96 |
97 | ## 5.基金分类筛选入池
98 |
99 | 此模块本身用于NOI FOF团队每月筛选合适的基金进入**观察池**和**核心池**,便于持续跟踪,对于合适的基金可以放入**精选层**。
100 |
101 | ### 5.1 基础筛选
102 |
103 | 基金经过基础筛选,可放入观察池。
104 |
105 | 
106 |
107 | ### 5.2 进阶筛选
108 |
109 | 进阶筛选结果,可放入核心池。
110 |
111 | 
112 |
113 | 入池保存页面:
114 |
115 | 
116 |
117 | ## 6.组合管理
118 |
119 | 组合管理模块主要用于跟踪入池的基金,主要功能如下(涉及具体基金数据,仅展示部分数据):
120 |
121 | 观察池:
122 |
123 | 
124 |
125 | 核心池:
126 |
127 | 
128 |
129 | 精选层:
130 |
131 | 
132 |
133 | ## 7.市场热点资讯
134 |
135 | 此模块最初用于收集市场热门新闻整理发布给公司各部门,此后改造进入客户服务系统,目前此模块处于半废弃状态。
136 |
137 | 
138 |
139 | ## 8.基金详细信息
140 |
141 | 在系统其他模块,点击基金代码,即可进入单只基金详细信息页面。
142 |
143 | ### 8.1 基金概览
144 |
145 | 概览页面包括如下信息:
146 |
147 | - 基金摘要
148 | - 近期业绩表现
149 | - 基金与基准净值曲线
150 | - 规模变化
151 | - 风格指标
152 | - 基金风格
153 | - 换手情况
154 | - 规模变化
155 |
156 | 预览图如下:
157 |
158 | 
159 |
160 | ### 8.2 业绩表现
161 |
162 | 业绩表现对基金区间业绩从多个维度做一个详细的诊断,预览图如下:
163 |
164 | 
165 |
166 | ### 8.3 基金经理
167 |
168 | 本页主要展示该基金的基金经理同时在管基金的简单信息汇总,预览图如下:
169 |
170 | 
171 |
172 | ### 8.4 资产配置
173 |
174 | 基金资产配置情况,预览图如下:
175 |
176 | 
177 |
178 | ### 8.5 业绩归因
179 |
180 | 基金Brinson归因情况,可选区间,预览图如下:
181 |
182 | 
183 |
184 | ### 8.6 重仓持股
185 |
186 | 本页主要展示至当前基金经理任职以来,多个报告期的持股情况统计,分析其持股偏好。预览图如下:
187 | 
188 |
189 | ## 三、程序设计
190 |
191 | 项目采用前后端分离设计,前端负责渲染和处理交互,后端以restful api方式提高数据。
192 |
193 | 整个项目前前后后经过3次迭代,前端完整重构了一次。本系统需要大量的基金数据和常用的股票数据,项目开发早期由于没有数据支持,只能从Wind终端的api接口提取数据,数据库接口也只能按照适合处理wind api的方式来构建,为整个程序的开发带来了巨大的工程量。
194 |
195 | 第一次版本更新正是考虑到数据维护的复杂性,开始将数据库迁移至恒生聚源数据,主要重构的部分在后端。
196 |
197 | 第二次版本更新主要是前端的改造,初版基金筛选系统主要功能集中在**基金筛选**这个功能上,所有功能都围绕基金筛选展开,此后产品提出了相当多的基于单个基金展示和基金挑选的需求,前后端进行大改造。
198 |
199 | 第三次版本更新主要是对后端单只基金信息展示的改造,后端由于Python的性能瓶颈限制,将部分功能的实现通过Golang来扩展了,以保证延迟和并发需求。
200 |
201 | 目前系统仍有一些小修小改,但整体呈现的效果如前所述。
202 |
203 | ## 四、技术栈
204 |
205 | 总体来说,项目基于MySQL+Python+Golang+Typescript,使用到的框架包括Django、Gin和Vue。
206 |
207 | ### 1.数据库
208 |
209 | 数据库使用关系型数据库MySQL,采用读写分离模式,部署到了两台服务器上。
210 |
211 | ### 2.后端程序
212 |
213 | 后端经过改造和性能提升,目前用到的工具包括:
214 |
215 | - Python: Django grpc
216 | - Golang: Gin Gorm grpc
217 |
218 | 后端部分功能使用到了grpc,这功能块通常是与其他系统关联的,如基金分类、Brinson归因、基金风格等功能,会在多个系统中使用到,采用grpc可以降低其他系统的工作量。
219 |
220 | Python后端项目可[点击这里](https://github.com/PengchuanC/fund_back_django)查看;
221 |
222 | Golang后端项目可[点击这里](https://github.com/PengchuanC/fund_screen)查看。
223 |
224 | ### 3.前端程序
225 |
226 | 前端程序基于Vue3.x开发,UI框架基于Element Plus,开发语言为Typescript,图表插件主要使用到了`vxe-table`和`echarts`。
227 |
228 | 前端项目地址已开源,可[点击查看](https://github.com/PengchuanC/fund_vue3)。
229 |
230 | ### 4.前置机配置
231 |
232 | 前置机采用常用的`Nginx`做反向代理,主要使用到了`httpv2`、`stream`和`grpc`代理等功能。
233 |
234 | 后端Python网关选用`asgi`框架`uvicorn`,充分利用异步能力。
235 |
236 | 项目托管软件采用`supervisor`,监控后端程序并赋予多进程能力。
237 |
--------------------------------------------------------------------------------
/src/components/screen/AddToPool.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | 选择基金池
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 基金池类型
21 |
22 |
23 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | 内容提示
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | 执行操作
50 |
51 |
52 | 提交
53 |
54 |
55 | 重置
56 |
57 |
58 |
59 |
60 |
61 |
62 |
156 |
157 |
--------------------------------------------------------------------------------
/src/components/News.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
{{n.title}}
25 |
{{n.abstract}}
26 |
27 |
{{formatDate(n.savedate)}}
28 |
{{n.source}}
29 |
30 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
147 |
148 |
--------------------------------------------------------------------------------
/src/components/screen/ScreenResult.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
246 |
247 |
--------------------------------------------------------------------------------
/src/components/cart/Basic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ selection.label }}
5 |
11 | 不限
12 |
13 |
checkAllGroupChange(data, abbr)"
16 | >
17 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
{{item.label}}
26 |
27 |
32 |
33 |
34 |
35 |
36 |
执行筛选
37 |
刷新缓存(耗时操作)
38 |
39 |
40 |
41 |
42 |
43 |
44 |
165 |
166 |
--------------------------------------------------------------------------------
/src/components/portfolio/Portfolio.vue.jsx:
--------------------------------------------------------------------------------
1 | import { defineComponent, nextTick, onMounted, reactive } from "vue";
2 | import { useRouter } from "vue-router";
3 | import request from "../../request";
4 | import numeral from "numeral";
5 | import { ElLoading } from "element-plus";
6 | export default defineComponent({
7 | name: "Portfolio",
8 | setup() {
9 | const state = reactive({
10 | portfolio: 1,
11 | portType: 1,
12 | portfolioOptions: [],
13 | date: null,
14 | dateOptions: [],
15 | data: []
16 | });
17 | const fetchPortfolio = () => {
18 | request.get('/portfolio/new').then((r) => {
19 | state.portfolioOptions = r;
20 | });
21 | };
22 | const fetchDateOptions = () => {
23 | request.get('/portfolio/new/date', { params: {
24 | port_id: state.portfolio, port_type: state.portType
25 | } }).then((r) => {
26 | state.dateOptions = r.data;
27 | });
28 | };
29 | onMounted(() => {
30 | fetchPortfolio();
31 | fetchDateOptions();
32 | onChange();
33 | });
34 | const onChange = () => {
35 | const instance = ElLoading.service({ fullscreen: true });
36 | state.data = [];
37 | fetchDateOptions();
38 | request.post('/portfolio/new', { data: {
39 | port_id: state.portfolio, port_type: state.portType, date: state.date
40 | } }).then((r) => {
41 | state.data = r;
42 | nextTick(() => { });
43 | instance.close();
44 | });
45 | };
46 | const router = useRouter();
47 | const columns = [
48 | {
49 | type: "checkbox",
50 | align: "center",
51 | width: 40
52 | },
53 | {
54 | type: "seq",
55 | title: '#',
56 | align: "center",
57 | width: 60
58 | },
59 | {
60 | title: "基金代码",
61 | field: "secucode",
62 | align: "left",
63 | sortable: true,
64 | slots: {
65 | default: ({ row }) => {
66 | const { secucode } = row;
67 | return router.push({ name: 'info', params: { secucode } })}>{secucode}
;
68 | }
69 | }
70 | },
71 | {
72 | title: "基金简称",
73 | field: "secuabbr",
74 | align: "left",
75 | sortable: true
76 | },
77 | {
78 | title: "成立日期",
79 | field: "launch_date",
80 | align: "center",
81 | sortable: true
82 | },
83 | {
84 | title: "基金经理",
85 | field: "manager",
86 | align: "left",
87 | showOverflow: true
88 | },
89 | {
90 | title: "规模(亿元)",
91 | field: "scale",
92 | align: "right",
93 | sortable: true,
94 | formatter: ({ row }) => numeral(row.scale).format('0,00.0')
95 | },
96 | {
97 | title: "净值日期",
98 | field: "date",
99 | align: "center",
100 | sortable: true
101 | },
102 | {
103 | title: "净值",
104 | field: "unitnv",
105 | align: "right",
106 | formatter: ({ row }) => numeral(row.unitnv).format('0.0000')
107 | },
108 | {
109 | title: "日涨跌",
110 | field: "daily",
111 | align: "right",
112 | sortable: true,
113 | formatter: ({ row }) => numeral(row.daily).format('0.00')
114 | },
115 | {
116 | title: "近1周",
117 | field: "week",
118 | align: "right",
119 | sortable: true,
120 | formatter: ({ row }) => numeral(row.week).format('0.00')
121 | },
122 | {
123 | title: "近1月",
124 | field: "month",
125 | align: "right",
126 | sortable: true,
127 | formatter: ({ row }) => numeral(row.month).format('0.00')
128 | },
129 | {
130 | title: "近3月",
131 | field: "month3",
132 | align: "right",
133 | sortable: true,
134 | formatter: ({ row }) => numeral(row.month3).format('0.00')
135 | },
136 | {
137 | title: "近6月",
138 | field: "month6",
139 | align: "right",
140 | sortable: true,
141 | formatter: ({ row }) => numeral(row.month6).format('0.00')
142 | },
143 | {
144 | title: "近1年",
145 | field: "year",
146 | align: "right",
147 | sortable: true,
148 | formatter: ({ row }) => numeral(row.year).format('0.00')
149 | },
150 | {
151 | title: "近3年",
152 | field: "year3",
153 | align: "right",
154 | sortable: true,
155 | formatter: ({ row }) => numeral(row.year3).format('0.00')
156 | },
157 | {
158 | title: "成立年化",
159 | field: "ftd_annual",
160 | align: "right",
161 | sortable: true,
162 | formatter: ({ row }) => numeral(row.ftd_annual).format('0.00')
163 | },
164 | {
165 | title: "状态",
166 | field: "status",
167 | align: "center",
168 | sortable: true,
169 | filters: [{ label: '新增', value: '新增' }, { label: '保持', value: '保持' }, { label: '回归', value: '回归' }, { label: '删除', value: '删除' }],
170 | filterMultiple: true,
171 | }
172 | ];
173 | return { state, onChange, columns };
174 | }
175 | });
176 | //# sourceMappingURL=Portfolio.vue.jsx.map
--------------------------------------------------------------------------------
/src/components/dashboard/Detail.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
245 |
246 |
--------------------------------------------------------------------------------
/src/components/portfolio/Portfolio.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 观察池
8 | 核心池
9 | 精选层
10 |
11 |
12 |
13 |
14 |
20 |
21 |
22 |
23 |
209 |
210 |
--------------------------------------------------------------------------------
/src/components/cart/General.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ abbr.name }}
5 |
9 | 不限
10 |
11 |
{checkAllGroupChange(d, abbr.key)}">
13 |
15 |
16 |
17 |
18 |
19 |
20 |
{{item.label}}
21 |
22 |
27 |
28 |
29 |
30 |
31 |
执行筛选
32 |
刷新缓存(耗时操作)
33 |
34 |
35 |
36 |
37 |
38 |
39 |
194 |
195 |
--------------------------------------------------------------------------------
/src/components/details/charts/Brinson.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
230 |
231 |
237 |
--------------------------------------------------------------------------------
/src/components/details/Attribution.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
219 |
220 |
240 |
--------------------------------------------------------------------------------
/src/components/cart/CartTable.vue.jsx.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"CartTable.vue.jsx","sourceRoot":"","sources":["CartTable.vue"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/src/components/dashboard/Detail.vue.jsx:
--------------------------------------------------------------------------------
1 | import request from "../../request";
2 | import { onMounted, ref, defineComponent } from "vue";
3 | import numeral from "numeral";
4 | import { useRouter } from "vue-router";
5 | export default defineComponent({
6 | name: "Detail",
7 | props: {
8 | params: Object
9 | },
10 | setup(props) {
11 | const { params } = props;
12 | const state = ref([]);
13 | const loading = ref(true);
14 | const router = useRouter();
15 | onMounted(() => {
16 | request.get('/dashboard/detail', { params: params }).then(r => {
17 | const { data } = r;
18 | state.value = data;
19 | loading.value = false;
20 | });
21 | });
22 | const columns = [
23 | {
24 | type: 'seq',
25 | width: 50,
26 | align: 'center'
27 | },
28 | {
29 | field: 'secucode',
30 | title: '证券代码',
31 | width: 90,
32 | slots: {
33 | default: (table) => {
34 | const { secucode } = table.row;
35 | return router.push({ name: 'info', params: { secucode } })}>{secucode};
36 | }
37 | },
38 | sortable: true,
39 | align: 'center'
40 | },
41 | {
42 | field: 'secuabbr',
43 | title: '证券简称',
44 | width: 120,
45 | overflow: true
46 | },
47 | {
48 | field: 'manager',
49 | title: '基金经理',
50 | width: 80
51 | },
52 | {
53 | field: 'nvi',
54 | title: '规模(亿元)',
55 | width: 100,
56 | align: 'right',
57 | formatter: (table) => {
58 | return numeral(table.cellValue).format('0.0');
59 | },
60 | sortable: true
61 | },
62 | {
63 | field: 'start',
64 | title: '任职日期',
65 | width: 90,
66 | sortable: true
67 | },
68 | {
69 | field: 'nav_date',
70 | title: '净值日期',
71 | width: 80
72 | },
73 | {
74 | field: 'ftd',
75 | title: '成立至今',
76 | width: 80,
77 | align: 'right',
78 | formatter: (table) => {
79 | return numeral(table.cellValue).format('0.00');
80 | }
81 | },
82 | {
83 | field: 'manager_yield',
84 | title: '任职至今',
85 | width: 80,
86 | align: 'right',
87 | formatter: (table) => {
88 | return numeral(table.cellValue).format('0.00');
89 | },
90 | visible: true
91 | },
92 | {
93 | field: 'daily',
94 | title: '单日收益',
95 | width: 90,
96 | align: 'right',
97 | slots: {
98 | default: (table) => {
99 | const { row } = table;
100 | const { daily } = row;
101 | return ( 0 ? 'red' : 'green' }}>{numeral(daily).format('0.00')});
102 | }
103 | },
104 | sortable: true
105 | },
106 | {
107 | field: 'ytd',
108 | title: 'YTD收益',
109 | width: 90,
110 | align: 'right',
111 | slots: {
112 | default: (table) => {
113 | const { row } = table;
114 | const { ytd } = row;
115 | return ( 0 ? 'red' : 'green' }}>{numeral(ytd).format('0.00')});
116 | }
117 | },
118 | sortable: true
119 | },
120 | {
121 | field: 'year',
122 | title: '1年收益',
123 | width: 90,
124 | align: 'right',
125 | slots: {
126 | default: (table) => {
127 | const { row } = table;
128 | const { year } = row;
129 | return ( 0 ? 'red' : 'green' }}>{numeral(year).format('0.00')});
130 | }
131 | },
132 | sortable: true
133 | },
134 | {
135 | field: 'year3',
136 | title: '3年收益',
137 | width: 90,
138 | align: 'right',
139 | slots: {
140 | default: (table) => {
141 | const { row } = table;
142 | const { year3 } = row;
143 | return ( 0 ? 'red' : 'green' }}>{numeral(year3).format('0.00')});
144 | }
145 | },
146 | sortable: true
147 | },
148 | {
149 | field: 'year5',
150 | title: '5年收益',
151 | width: 90,
152 | align: 'right',
153 | slots: {
154 | default: (table) => {
155 | const { row } = table;
156 | const { year5 } = row;
157 | return ( 0 ? 'red' : 'green' }}>{numeral(year5).format('0.00')});
158 | }
159 | },
160 | sortable: true
161 | },
162 | {
163 | field: 'stock',
164 | title: '股票仓位',
165 | width: 90,
166 | align: 'right',
167 | formatter: (row) => numeral(row.cellValue).format('00.0')
168 | },
169 | {
170 | field: 'scale_nature',
171 | title: '规模属性',
172 | width: 100,
173 | align: 'right',
174 | sortable: true
175 | },
176 | {
177 | field: 'style_nature',
178 | title: '风格属性',
179 | width: 100,
180 | align: 'right',
181 | sortable: true
182 | },
183 | {
184 | field: 'classify_industry',
185 | title: '行业风格',
186 | width: 100,
187 | align: 'right',
188 | sortable: true
189 | },
190 | {
191 | field: 'apply',
192 | title: '申购状态',
193 | width: 100,
194 | align: 'right',
195 | sortable: true
196 | },
197 | {
198 | field: 'redeem',
199 | title: '赎回状态',
200 | width: 100,
201 | align: 'right',
202 | sortable: true
203 | },
204 | {
205 | field: 'limit',
206 | title: '大额限制',
207 | width: 100,
208 | align: 'right',
209 | sortable: true
210 | }
211 | ];
212 | return { state, columns, loading };
213 | }
214 | });
215 | //# sourceMappingURL=Detail.vue.jsx.map
--------------------------------------------------------------------------------
/src/components/etf/ETFCategory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
17 |
18 |
19 |
32 |
33 |
34 |
35 |
36 |
284 |
285 |
--------------------------------------------------------------------------------
/src/components/etf/ETFHome.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 | 日频
17 | 周频
18 | 月频
19 |
20 |
21 |
22 |
23 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
298 |
299 |
--------------------------------------------------------------------------------