├── option
├── __init__.py
├── migrations
│ └── __init__.py
├── tests.py
├── views.py
├── apps.py
├── admin.py
├── models.py
├── context_processors.py
├── management
│ └── commands
│ │ ├── seed_options.py
│ │ └── clean_migrations.py
└── widgets.py
├── wiki
├── __init__.py
├── migrations
│ └── __init__.py
├── templatetags
│ ├── __init__.py
│ └── wiki_tags.py
├── tests.py
├── apps.py
├── forms.py
├── urls.py
├── admin.py
├── models.py
└── widgets.py
├── account
├── __init__.py
├── migrations
│ └── __init__.py
├── tests.py
├── apps.py
├── admin.py
├── urls.py
├── serializers.py
├── api_views.py
├── user_login_backend.py
├── models.py
├── views.py
└── forms.py
├── basedata
├── __init__.py
├── migrations
│ └── __init__.py
├── tests.py
├── apps.py
├── models
│ └── __init__.py
├── urls.py
└── management
│ └── commands
│ ├── update_stocks_pinyin.py
│ ├── seed_report_types.py
│ └── update_last_report_date.py
├── collector
├── __init__.py
├── spiders
│ ├── __init__.py
│ └── stock_report.py
└── fix_items.py
├── tdxStock
├── __init__.py
├── asgi.py
├── wsgi.py
├── api.py
├── fields.py
├── helpers.py
├── abstract_models.py
└── urls.py
├── templates
├── wiki
│ ├── .gitignore
│ ├── concept_detail.html
│ └── concept_form.html
├── widgets
│ ├── attrs.html
│ ├── editor_md.html
│ └── json_editor.html
├── _layout
│ ├── footer.html
│ ├── base_account.html
│ ├── base.html
│ └── nav.html
└── account
│ ├── logged_out.html
│ ├── registration_form.html
│ └── login.html
├── storage
├── cookies
│ └── .gitignore
└── logs
│ └── .gitignore
├── frontend
├── .browserslistrc
├── public
│ ├── favicon.ico
│ └── index.html
├── babel.config.js
├── .env.production
├── src
│ ├── assets
│ │ └── 404_images
│ │ │ ├── 404.png
│ │ │ └── 404_cloud.png
│ ├── store
│ │ ├── getters.js
│ │ ├── index.js
│ │ └── modules
│ │ │ ├── errorLog.js
│ │ │ └── compare.js
│ ├── layout
│ │ ├── components
│ │ │ ├── index.js
│ │ │ ├── AppMain.vue
│ │ │ └── Navbar.vue
│ │ └── index.vue
│ ├── utils
│ │ ├── getPageTitle.js
│ │ ├── errorlog.js
│ │ ├── request.js
│ │ ├── restapi.js
│ │ ├── validate.js
│ │ └── scrollTo.js
│ ├── views
│ │ ├── Home.vue
│ │ └── Industry.vue
│ ├── App.vue
│ ├── main.js
│ ├── vendor
│ │ └── Export2Zip.js
│ ├── defines
│ │ └── consts.js
│ ├── components
│ │ └── IndustryMenu.vue
│ ├── bootstarp.js
│ ├── router
│ │ └── index.js
│ └── api
│ │ └── index.js
├── vue.config.js
├── .editorconfig
├── .gitignore
├── .eslintrc.js
├── README.md
├── .env.development
└── package.json
├── public
└── static
│ ├── img
│ ├── logo.png
│ ├── favicon.ico
│ ├── 404.a57b6f31.png
│ └── 404_cloud.0f4bc32b.png
│ ├── .gitignore
│ ├── editor.md
│ ├── images
│ │ ├── loading.gif
│ │ ├── logos
│ │ │ ├── vi.png
│ │ │ ├── editormd-logo-114x114.png
│ │ │ ├── editormd-logo-120x120.png
│ │ │ ├── editormd-logo-144x144.png
│ │ │ ├── editormd-logo-16x16.png
│ │ │ ├── editormd-logo-180x180.png
│ │ │ ├── editormd-logo-240x240.png
│ │ │ ├── editormd-logo-24x24.png
│ │ │ ├── editormd-logo-320x320.png
│ │ │ ├── editormd-logo-32x32.png
│ │ │ ├── editormd-logo-48x48.png
│ │ │ ├── editormd-logo-57x57.png
│ │ │ ├── editormd-logo-64x64.png
│ │ │ ├── editormd-logo-72x72.png
│ │ │ ├── editormd-logo-96x96.png
│ │ │ ├── editormd-favicon-16x16.ico
│ │ │ ├── editormd-favicon-24x24.ico
│ │ │ ├── editormd-favicon-32x32.ico
│ │ │ ├── editormd-favicon-48x48.ico
│ │ │ └── editormd-favicon-64x64.ico
│ │ ├── loading@2x.gif
│ │ └── loading@3x.gif
│ ├── fonts
│ │ ├── FontAwesome.otf
│ │ ├── editormd-logo.eot
│ │ ├── editormd-logo.ttf
│ │ ├── editormd-logo.woff
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ ├── fontawesome-webfont.woff2
│ │ └── editormd-logo.svg
│ ├── lib
│ │ ├── codemirror
│ │ │ ├── theme
│ │ │ │ ├── ambiance-mobile.css
│ │ │ │ ├── neat.css
│ │ │ │ ├── ssms.css
│ │ │ │ ├── elegant.css
│ │ │ │ ├── neo.css
│ │ │ │ ├── eclipse.css
│ │ │ │ ├── bespin.css
│ │ │ │ ├── isotope.css
│ │ │ │ ├── hopscotch.css
│ │ │ │ ├── railscasts.css
│ │ │ │ ├── colorforth.css
│ │ │ │ ├── cobalt.css
│ │ │ │ ├── idea.css
│ │ │ │ ├── night.css
│ │ │ │ ├── gruvbox-dark.css
│ │ │ │ ├── rubyblue.css
│ │ │ │ └── tomorrow-night-bright.css
│ │ │ ├── addon
│ │ │ │ ├── display
│ │ │ │ │ ├── fullscreen.css
│ │ │ │ │ ├── fullscreen.js
│ │ │ │ │ └── autorefresh.js
│ │ │ │ ├── search
│ │ │ │ │ └── matchesonscrollbar.css
│ │ │ │ ├── fold
│ │ │ │ │ ├── foldgutter.css
│ │ │ │ │ ├── markdown-fold.js
│ │ │ │ │ └── indent-fold.js
│ │ │ │ ├── dialog
│ │ │ │ │ └── dialog.css
│ │ │ │ ├── hint
│ │ │ │ │ ├── show-hint.css
│ │ │ │ │ └── anyword-hint.js
│ │ │ │ ├── mode
│ │ │ │ │ └── multiplex_test.js
│ │ │ │ ├── edit
│ │ │ │ │ └── trailingspace.js
│ │ │ │ ├── tern
│ │ │ │ │ └── worker.js
│ │ │ │ ├── lint
│ │ │ │ │ ├── yaml-lint.js
│ │ │ │ │ ├── css-lint.js
│ │ │ │ │ ├── json-lint.js
│ │ │ │ │ └── coffeescript-lint.js
│ │ │ │ ├── runmode
│ │ │ │ │ └── colorize.js
│ │ │ │ └── scroll
│ │ │ │ │ ├── simplescrollbars.css
│ │ │ │ │ └── scrollpastend.js
│ │ │ ├── mode
│ │ │ │ ├── tiddlywiki
│ │ │ │ │ └── tiddlywiki.css
│ │ │ │ ├── d
│ │ │ │ │ └── test.js
│ │ │ │ ├── css
│ │ │ │ │ └── gss_test.js
│ │ │ │ ├── tiki
│ │ │ │ │ └── tiki.css
│ │ │ │ ├── ruby
│ │ │ │ │ └── test.js
│ │ │ │ ├── rust
│ │ │ │ │ ├── test.js
│ │ │ │ │ └── index.html
│ │ │ │ ├── diff
│ │ │ │ │ └── diff.js
│ │ │ │ ├── mbox
│ │ │ │ │ └── index.html
│ │ │ │ ├── cypher
│ │ │ │ │ └── test.js
│ │ │ │ ├── asciiarmor
│ │ │ │ │ └── index.html
│ │ │ │ ├── twig
│ │ │ │ │ └── index.html
│ │ │ │ ├── spreadsheet
│ │ │ │ │ └── index.html
│ │ │ │ ├── http
│ │ │ │ │ └── index.html
│ │ │ │ ├── haskell-literate
│ │ │ │ │ └── haskell-literate.js
│ │ │ │ ├── oz
│ │ │ │ │ └── index.html
│ │ │ │ ├── solr
│ │ │ │ │ └── index.html
│ │ │ │ ├── z80
│ │ │ │ │ └── index.html
│ │ │ │ ├── ecl
│ │ │ │ │ └── index.html
│ │ │ │ ├── vb
│ │ │ │ │ └── index.html
│ │ │ │ ├── pascal
│ │ │ │ │ └── index.html
│ │ │ │ ├── pig
│ │ │ │ │ └── index.html
│ │ │ │ ├── vbscript
│ │ │ │ │ └── index.html
│ │ │ │ ├── turtle
│ │ │ │ │ └── index.html
│ │ │ │ ├── gherkin
│ │ │ │ │ └── index.html
│ │ │ │ ├── properties
│ │ │ │ │ └── index.html
│ │ │ │ ├── perl
│ │ │ │ │ └── index.html
│ │ │ │ ├── htmlembedded
│ │ │ │ │ └── htmlembedded.js
│ │ │ │ ├── javascript
│ │ │ │ │ └── typescript.html
│ │ │ │ ├── elm
│ │ │ │ │ └── index.html
│ │ │ │ ├── sass
│ │ │ │ │ └── index.html
│ │ │ │ ├── dart
│ │ │ │ │ └── index.html
│ │ │ │ ├── idl
│ │ │ │ │ └── index.html
│ │ │ │ ├── jinja2
│ │ │ │ │ └── index.html
│ │ │ │ └── xml
│ │ │ │ │ └── test.js
│ │ │ ├── bower.json
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ └── LICENSE
│ │ └── jquery.flowchart.min.js
│ ├── css
│ │ └── editormd.logo.min.css
│ └── plugins
│ │ └── test-plugin
│ │ └── test-plugin.js
│ ├── fonts
│ ├── element-icons.535877f5.woff
│ └── element-icons.732389de.ttf
│ ├── js
│ └── app.js
│ └── css
│ └── signin.css
├── docs
└── kline.txt
├── scrapy.cfg
├── notebooks
└── __init__.py
├── requirements.txt
├── .env.sample
├── manage.py
└── .gitignore
/option/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wiki/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/account/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/basedata/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/collector/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tdxStock/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wiki/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/account/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/basedata/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/option/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wiki/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/templates/wiki/.gitignore:
--------------------------------------------------------------------------------
1 | index.html
2 |
--------------------------------------------------------------------------------
/storage/cookies/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/frontend/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/account/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/option/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/wiki/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/basedata/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/option/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | # Create your views here.
4 |
--------------------------------------------------------------------------------
/frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/frontend/public/favicon.ico
--------------------------------------------------------------------------------
/public/static/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/img/logo.png
--------------------------------------------------------------------------------
/public/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/img/favicon.ico
--------------------------------------------------------------------------------
/frontend/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/public/static/.gitignore:
--------------------------------------------------------------------------------
1 | app.*.css
2 | chunk-*.css
3 | app.*.js
4 | app.*.js.map
5 | chunk-*.js
6 | chunk-*.js.map
7 |
--------------------------------------------------------------------------------
/public/static/img/404.a57b6f31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/img/404.a57b6f31.png
--------------------------------------------------------------------------------
/wiki/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class WikiConfig(AppConfig):
5 | name = 'wiki'
6 |
--------------------------------------------------------------------------------
/frontend/.env.production:
--------------------------------------------------------------------------------
1 | # just a flag
2 | ENV = 'production'
3 |
4 | # base api
5 | VUE_APP_BASE_API = '/prod-api'
6 |
--------------------------------------------------------------------------------
/account/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AccountConfig(AppConfig):
5 | name = 'account'
6 |
--------------------------------------------------------------------------------
/frontend/src/assets/404_images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/frontend/src/assets/404_images/404.png
--------------------------------------------------------------------------------
/frontend/vue.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | module.exports = {
4 | assetsDir: 'static',
5 | lintOnSave: false
6 | }
7 |
--------------------------------------------------------------------------------
/public/static/editor.md/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/loading.gif
--------------------------------------------------------------------------------
/public/static/img/404_cloud.0f4bc32b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/img/404_cloud.0f4bc32b.png
--------------------------------------------------------------------------------
/frontend/src/assets/404_images/404_cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/frontend/src/assets/404_images/404_cloud.png
--------------------------------------------------------------------------------
/frontend/src/store/getters.js:
--------------------------------------------------------------------------------
1 | const getters = {
2 | errorLogs: state => state.errorLog.logs
3 | }
4 |
5 | export default getters
6 |
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/vi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/vi.png
--------------------------------------------------------------------------------
/frontend/src/layout/components/index.js:
--------------------------------------------------------------------------------
1 | export { default as Navbar } from './Navbar'
2 | export { default as AppMain } from './AppMain'
3 |
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/editormd-logo.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/editormd-logo.eot
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/editormd-logo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/editormd-logo.ttf
--------------------------------------------------------------------------------
/public/static/editor.md/images/loading@2x.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/loading@2x.gif
--------------------------------------------------------------------------------
/public/static/editor.md/images/loading@3x.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/loading@3x.gif
--------------------------------------------------------------------------------
/public/static/fonts/element-icons.535877f5.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/fonts/element-icons.535877f5.woff
--------------------------------------------------------------------------------
/public/static/fonts/element-icons.732389de.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/fonts/element-icons.732389de.ttf
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/editormd-logo.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/editormd-logo.woff
--------------------------------------------------------------------------------
/option/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class OptionConfig(AppConfig):
5 | name = 'option'
6 | verbose_name = '选项'
7 |
--------------------------------------------------------------------------------
/basedata/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class BasedataConfig(AppConfig):
5 | name = 'basedata'
6 | verbose_name = '基础数据'
7 |
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/frontend/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | trim_trailing_whitespace = true
5 | insert_final_newline = true
6 |
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-114x114.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-120x120.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-144x144.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-16x16.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-180x180.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-240x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-240x240.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-24x24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-24x24.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-320x320.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-320x320.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-32x32.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-48x48.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-57x57.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-64x64.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-72x72.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-logo-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-logo-96x96.png
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-favicon-16x16.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-favicon-16x16.ico
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-favicon-24x24.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-favicon-24x24.ico
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-favicon-32x32.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-favicon-32x32.ico
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-favicon-48x48.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-favicon-48x48.ico
--------------------------------------------------------------------------------
/public/static/editor.md/images/logos/editormd-favicon-64x64.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uees/tdxStock/HEAD/public/static/editor.md/images/logos/editormd-favicon-64x64.ico
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/ambiance-mobile.css:
--------------------------------------------------------------------------------
1 | .cm-s-ambiance.CodeMirror {
2 | -webkit-box-shadow: none;
3 | -moz-box-shadow: none;
4 | box-shadow: none;
5 | }
6 |
--------------------------------------------------------------------------------
/docs/kline.txt:
--------------------------------------------------------------------------------
1 | https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=SH603228&begin=1595164254067&period=day&type=before&count=-284&indicator=kline,pe,pb,ps,pcf,market_capital,agt,ggt,balance
--------------------------------------------------------------------------------
/templates/widgets/attrs.html:
--------------------------------------------------------------------------------
1 | {% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}{% endfor %}
--------------------------------------------------------------------------------
/collector/spiders/__init__.py:
--------------------------------------------------------------------------------
1 | # This package will contain the spiders of your Scrapy project
2 | #
3 | # Please refer to the documentation for information on how to create and manage
4 | # your spiders.
5 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/display/fullscreen.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-fullscreen {
2 | position: fixed;
3 | top: 0; left: 0; right: 0; bottom: 0;
4 | height: auto;
5 | z-index: 9;
6 | }
7 |
--------------------------------------------------------------------------------
/public/static/js/app.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 | 'use strict'
3 |
4 | $('[data-toggle="offcanvas"]').on('click', function () {
5 | $('.offcanvas-collapse').toggleClass('open')
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/frontend/src/utils/getPageTitle.js:
--------------------------------------------------------------------------------
1 |
2 | const title = 'TdxStock'
3 |
4 | export default function getPageTitle (pageTitle) {
5 | if (pageTitle) {
6 | return `${pageTitle} - ${title}`
7 | }
8 | return `${title}`
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

7 |
8 |
9 |
10 |
15 |
--------------------------------------------------------------------------------
/basedata/models/__init__.py:
--------------------------------------------------------------------------------
1 | from .stock import Stock # noqa
2 | from .category import Industry, IndustryStock, Concept, ConceptStock, Territory, Section, SectionStock # noqa
3 | from .report import ReportType, Report, AccountingSubject, ReportItem, XReport, XReportItem # noqa
4 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/search/matchesonscrollbar.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-search-match {
2 | background: gold;
3 | border-top: 1px solid orange;
4 | border-bottom: 1px solid orange;
5 | -moz-box-sizing: border-box;
6 | box-sizing: border-box;
7 | opacity: .5;
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
20 |
--------------------------------------------------------------------------------
/scrapy.cfg:
--------------------------------------------------------------------------------
1 | # Automatically created by: scrapy startproject
2 | #
3 | # For more information about the [deploy] section see:
4 | # https://scrapyd.readthedocs.io/en/latest/deploy.html
5 |
6 | [settings]
7 | default = collector.settings
8 |
9 | [deploy]
10 | #url = http://localhost:6800/
11 | project = collector
12 |
--------------------------------------------------------------------------------
/account/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from .models import User
4 |
5 |
6 | class UserAdmin(admin.ModelAdmin):
7 | list_display = ('id', 'nickname', 'username', 'email', 'last_login', 'date_joined')
8 | list_display_links = ('id', 'username')
9 |
10 |
11 | admin.site.register(User, UserAdmin)
12 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/tiddlywiki/tiddlywiki.css:
--------------------------------------------------------------------------------
1 | span.cm-underlined {
2 | text-decoration: underline;
3 | }
4 | span.cm-strikethrough {
5 | text-decoration: line-through;
6 | }
7 | span.cm-brace {
8 | color: #170;
9 | font-weight: bold;
10 | }
11 | span.cm-table {
12 | color: blue;
13 | font-weight: bold;
14 | }
15 |
--------------------------------------------------------------------------------
/basedata/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = "basedata" # noqa
6 |
7 | urlpatterns = [
8 | path('reports/', views.ReportView.as_view(), name='report'),
9 | path('xreports/', views.XReportView.as_view(), name='xreport'),
10 | path('compare/', views.CompareView.as_view(), name='compare'),
11 | ]
12 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "codemirror",
3 | "version":"5.0.0",
4 | "main": ["lib/codemirror.js", "lib/codemirror.css"],
5 | "ignore": [
6 | "**/.*",
7 | "node_modules",
8 | "components",
9 | "bin",
10 | "demo",
11 | "doc",
12 | "test",
13 | "index.html",
14 | "package.json"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 |
4 | env: {
5 | node: true
6 | },
7 |
8 | parserOptions: {
9 | parser: 'babel-eslint'
10 | },
11 |
12 | rules: {
13 | 'no-console': 'off',
14 | 'no-debugger': 'off',
15 | camelcase: 'off'
16 | },
17 |
18 | extends: [
19 | 'plugin:vue/strongly-recommended',
20 | '@vue/standard'
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/frontend/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import getters from './getters'
4 | import errorLog from './modules/errorLog'
5 | import basedata from './modules/basedata'
6 | import compare from './modules/compare'
7 |
8 | Vue.use(Vuex)
9 |
10 | export default new Vuex.Store({
11 | modules: {
12 | errorLog,
13 | basedata,
14 | compare
15 | },
16 | getters
17 | })
18 |
--------------------------------------------------------------------------------
/templates/_layout/footer.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/account/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 | from .forms import LoginForm
5 |
6 | app_name = "account" # noqa
7 |
8 | urlpatterns = [
9 | path('login/', views.LoginView.as_view(), name='login', kwargs={'authentication_form': LoginForm}),
10 | path('register/', views.RegisterView.as_view(), name='register'),
11 | path('logout/', views.LogoutView.as_view(), name='logout')
12 | ]
13 |
--------------------------------------------------------------------------------
/notebooks/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | > cd notebooks
3 | > python ../manage.py shell_plus --notebook
4 |
5 | >>> from notebooks import setup
6 | >>> setup()
7 | """
8 |
9 | import os
10 | import sys
11 | import django
12 |
13 |
14 | def setup():
15 | sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(__file__))))
16 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tdxStock.settings')
17 | django.setup()
18 |
--------------------------------------------------------------------------------
/templates/account/logged_out.html:
--------------------------------------------------------------------------------
1 | {% extends "_layout/base_account.html" %}
2 | {% load i18n %}
3 |
4 | {% block breadcrumbs %}
5 |
6 | {% endblock %}
7 |
8 | {% block content %}
9 |
10 | {% trans "Thanks for spending some quality time with the Web site today." %}
11 |
12 | {% trans 'Log in again' %}
13 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | # frontend
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/frontend/src/layout/components/AppMain.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
22 |
--------------------------------------------------------------------------------
/tdxStock/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for tdxStock project.
3 |
4 | It exposes the ASGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.asgi import get_asgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tdxStock.settings')
15 |
16 | application = get_asgi_application()
17 |
--------------------------------------------------------------------------------
/tdxStock/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for my_proj project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tdxStock.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/wiki/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from .models import Concept
4 |
5 |
6 | class ConceptForm(forms.ModelForm):
7 | name = forms.CharField(label='名词', required=True, widget=forms.TextInput(
8 | attrs={'value': "", 'size': "30", 'maxlength': "245", 'aria-required': 'true'}))
9 | description = forms.CharField(label='描述', required=True, widget=forms.Textarea())
10 |
11 | class Meta:
12 | model = Concept
13 | fields = ['name', 'description']
14 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==4.0.7
2 | django-debug-toolbar==3.2.4
3 | django-environ==0.8.1
4 | django-extensions==3.1.5
5 | django-filter==21.1
6 | djangorestframework==3.13.1
7 | django-cors-headers==3.11.0
8 | drf-dynamic-fields==0.3.1
9 | psycopg2==2.9.3
10 | redis==4.1.4
11 | jupyter==1.0.0
12 | pandas==1.4.1
13 | matplotlib==3.5.1
14 | scipy==1.8.0
15 | lxml==4.9.1
16 | openpyxl==3.0.9
17 | Scrapy==2.6.2
18 | scrapyd==1.3.0
19 | scrapyd-client==1.2.0
20 | selenium==4.1.0
21 | xpinyin==0.7.6
22 |
--------------------------------------------------------------------------------
/account/serializers.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.models import Group
2 | from rest_framework import serializers
3 |
4 | from .models import User
5 |
6 |
7 | class UserSerializer(serializers.HyperlinkedModelSerializer):
8 | class Meta:
9 | model = User
10 | fields = ('url', 'username', 'nickname', 'email', 'groups')
11 |
12 |
13 | class GroupSerializer(serializers.HyperlinkedModelSerializer):
14 | class Meta:
15 | model = Group
16 | fields = ('url', 'name')
17 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/d/test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function() {
5 | var mode = CodeMirror.getMode({indentUnit: 2}, "d");
6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
7 |
8 | MT("nested_comments",
9 | "[comment /+]","[comment comment]","[comment +/]","[variable void] [variable main](){}");
10 |
11 | })();
12 |
--------------------------------------------------------------------------------
/collector/spiders/stock_report.py:
--------------------------------------------------------------------------------
1 | from basedata.models import Stock
2 | from collector.spiders.report import ReportSpider
3 |
4 |
5 | class StockReportSpider(ReportSpider):
6 | """采用单个股票的报表,主要用于修复数据"""
7 | name = 'stock_report'
8 |
9 | def __init__(self, code, *args, **kwargs):
10 | super().__init__(*args, **kwargs)
11 |
12 | self.code = code
13 | self.crawl_mode = 'all' # 强制全量采集
14 |
15 | def start_requests(self):
16 | stock = Stock.objects.get(code=self.code)
17 | yield self.make_request(stock)
18 |
--------------------------------------------------------------------------------
/frontend/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | import ElementUI from 'element-ui'
4 | import 'element-ui/lib/theme-chalk/index.css'
5 |
6 | import App from './App.vue'
7 | import router from './router'
8 | import store from './store'
9 |
10 | import IndustryMenu from './components/IndustryMenu'
11 |
12 | import './bootstarp'
13 |
14 | Vue.component('industry-menu', IndustryMenu)
15 |
16 | Vue.use(ElementUI)
17 |
18 | Vue.config.productionTip = false
19 |
20 | new Vue({
21 | router,
22 | store,
23 | render: h => h(App)
24 | }).$mount('#app')
25 |
--------------------------------------------------------------------------------
/wiki/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'wiki'
6 | urlpatterns = [
7 | path('', views.ConceptListView.as_view(), name='concept-list'),
8 | path('create/', views.ConceptCreateView.as_view(), name='concept-store'),
9 | path('/', views.ConceptDetailView.as_view(), name='concept-detail'),
10 | path('/edit/', views.ConceptUpdateView.as_view(), name='concept-edit'),
11 | path('/delete/', views.delete, name='concept-delete'),
12 | path('look/', views.look),
13 | ]
14 |
--------------------------------------------------------------------------------
/frontend/src/store/modules/errorLog.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | logs: []
3 | }
4 |
5 | const mutations = {
6 | ADD_ERROR_LOG: (state, log) => {
7 | state.logs.push(log)
8 | },
9 | CLEAR_ERROR_LOG: (state) => {
10 | state.logs.splice(0)
11 | }
12 | }
13 |
14 | const actions = {
15 | addErrorLog ({ commit }, log) {
16 | commit('ADD_ERROR_LOG', log)
17 | },
18 | clearErrorLog ({ commit }) {
19 | commit('CLEAR_ERROR_LOG')
20 | }
21 | }
22 |
23 | export default {
24 | namespaced: true,
25 | state,
26 | mutations,
27 | actions
28 | }
29 |
--------------------------------------------------------------------------------
/basedata/management/commands/update_stocks_pinyin.py:
--------------------------------------------------------------------------------
1 | from django.core.management import BaseCommand
2 | from xpinyin import Pinyin
3 |
4 | from basedata.models import Stock
5 |
6 |
7 | # python manage.py update_stocks_pinyin
8 | class Command(BaseCommand):
9 | help = '更新股票的 PINYIN 字段'
10 |
11 | def handle(self, *args, **options):
12 | p = Pinyin()
13 |
14 | for stock in Stock.objects.all():
15 | stock.pinyin = p.get_initials(stock.name, '')
16 | stock.save()
17 |
18 | self.stdout.write(self.style.SUCCESS('success!'))
19 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/fold/foldgutter.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-foldmarker {
2 | color: blue;
3 | text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
4 | font-family: arial;
5 | line-height: .3;
6 | cursor: pointer;
7 | }
8 | .CodeMirror-foldgutter {
9 | width: .7em;
10 | }
11 | .CodeMirror-foldgutter-open,
12 | .CodeMirror-foldgutter-folded {
13 | cursor: pointer;
14 | }
15 | .CodeMirror-foldgutter-open:after {
16 | content: "\25BE";
17 | }
18 | .CodeMirror-foldgutter-folded:after {
19 | content: "\25B8";
20 | }
21 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/css/gss_test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function() {
5 | "use strict";
6 |
7 | var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss");
8 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); }
9 |
10 | MT("atComponent",
11 | "[def @component] {",
12 | "[tag foo] {",
13 | " [property color]: [keyword black];",
14 | "}",
15 | "}");
16 |
17 | })();
18 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/tiki/tiki.css:
--------------------------------------------------------------------------------
1 | .cm-tw-syntaxerror {
2 | color: #FFF;
3 | background-color: #900;
4 | }
5 |
6 | .cm-tw-deleted {
7 | text-decoration: line-through;
8 | }
9 |
10 | .cm-tw-header5 {
11 | font-weight: bold;
12 | }
13 | .cm-tw-listitem:first-child { /*Added first child to fix duplicate padding when highlighting*/
14 | padding-left: 10px;
15 | }
16 |
17 | .cm-tw-box {
18 | border-top-width: 0px !important;
19 | border-style: solid;
20 | border-width: 1px;
21 | border-color: inherit;
22 | }
23 |
24 | .cm-tw-underline {
25 | text-decoration: underline;
26 | }
--------------------------------------------------------------------------------
/frontend/src/layout/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
31 |
--------------------------------------------------------------------------------
/frontend/.env.development:
--------------------------------------------------------------------------------
1 | # just a flag
2 | ENV = 'development'
3 |
4 | # base api
5 | VUE_APP_BASE_API = '/dev-api'
6 |
7 | # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
8 | # to control whether the babel-plugin-dynamic-import-node plugin is enabled.
9 | # It only does one thing by converting all import() to require().
10 | # This configuration can significantly increase the speed of hot updates,
11 | # when you have a large number of pages.
12 | # Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
13 |
14 | VUE_CLI_BABEL_TRANSPILE_MODULES = true
15 |
--------------------------------------------------------------------------------
/option/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django_extensions.db.fields.json import JSONField
3 |
4 | from .models import Option
5 | from .widgets import JsonEditorWidget
6 |
7 |
8 | class OptionAdmin(admin.ModelAdmin):
9 | list_max_show_all = 20
10 | list_per_page = 20
11 |
12 | fieldsets = [
13 | ('项目', {'fields': ['name']}),
14 | ('值', {'fields': ['value']}),
15 | ('开关', {'fields': ['enable']}),
16 | ]
17 |
18 | formfield_overrides = {
19 | JSONField: {'widget': JsonEditorWidget}
20 | }
21 |
22 |
23 | admin.site.register(Option, OptionAdmin)
24 |
--------------------------------------------------------------------------------
/.env.sample:
--------------------------------------------------------------------------------
1 | SECRET_KEY=some secret_key
2 | DEBUG=true
3 |
4 | #DATABASE_URL=mysql://user:pass@127.0.0.1:3306/database?init_command=SET default_storage_engine=MyISAM&charset=utf8mb4
5 | DATABASE_URL=postgres://user:pass@127.0.0.1:5432/database
6 |
7 | MAIL_HOST=localhost
8 | MAIL_PORT=1025
9 | MAIL_USERNAME=
10 | MAIL_PASSWORD=
11 | MAIL_ENCRYPTION=
12 | MAIL_FROM=webmaster@tdxstock.com
13 | MAIL_NAME=tdxstock
14 |
15 | USER_AGENT="Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0"
16 | ROBOTSTXT_OBEY=0
17 |
18 | REDIS_HOST=127.0.0.1
19 | REDIS_PORT=6379
20 | REDIS_SPIDER_DB=0
21 |
22 | START_YEAR=2015
23 |
--------------------------------------------------------------------------------
/frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/wiki/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.db import models
3 | from django.utils import timezone
4 |
5 | from .models import Concept
6 | from .widgets import MarkdownWidget
7 |
8 |
9 | class ConceptAdmin(admin.ModelAdmin):
10 | formfield_overrides = {
11 | models.TextField: {'widget': MarkdownWidget}
12 | }
13 |
14 | def save_model(self, request, obj, form, change):
15 | obj.description_html = request.POST.get('description_html')
16 | obj.updated_at = timezone.now()
17 | super().save_model(request, obj, form, change)
18 |
19 |
20 | admin.site.register(Concept, ConceptAdmin)
21 |
--------------------------------------------------------------------------------
/templates/widgets/editor_md.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
17 |
--------------------------------------------------------------------------------
/frontend/src/store/modules/compare.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | stocks: [],
3 | index: -1
4 | }
5 |
6 | const mutations = {
7 | SET_STOCKS: (state, stocks) => {
8 | state.stocks = stocks
9 | },
10 | ADD_STOCK: (state, stock) => {
11 | state.stocks.push(stock)
12 | },
13 | UPDATE_STOCK: (state, context) => {
14 | state.stocks.splice(context.index, 1, context.stock)
15 | },
16 | DELETE_STOCK: (state, index) => {
17 | state.stocks.splice(index, 1)
18 | },
19 | SET_INDEX: (state, index) => {
20 | state.index = index
21 | }
22 | }
23 |
24 | const actions = {
25 |
26 | }
27 |
28 | export default {
29 | namespaced: true,
30 | state,
31 | mutations,
32 | actions
33 | }
34 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/dialog/dialog.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-dialog {
2 | position: absolute;
3 | left: 0; right: 0;
4 | background: inherit;
5 | z-index: 15;
6 | padding: .1em .8em;
7 | overflow: hidden;
8 | color: inherit;
9 | }
10 |
11 | .CodeMirror-dialog-top {
12 | border-bottom: 1px solid #eee;
13 | top: 0;
14 | }
15 |
16 | .CodeMirror-dialog-bottom {
17 | border-top: 1px solid #eee;
18 | bottom: 0;
19 | }
20 |
21 | .CodeMirror-dialog input {
22 | border: none;
23 | outline: none;
24 | background: transparent;
25 | width: 20em;
26 | color: inherit;
27 | font-family: monospace;
28 | }
29 |
30 | .CodeMirror-dialog button {
31 | font-size: 70%;
32 | }
33 |
--------------------------------------------------------------------------------
/frontend/src/vendor/Export2Zip.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('script-loader!file-saver')
3 | import JSZip from 'jszip'
4 |
5 | export function export_txt_to_zip(th, jsonData, txtName, zipName) {
6 | const zip = new JSZip()
7 | const txt_name = txtName || 'file'
8 | const zip_name = zipName || 'file'
9 | const data = jsonData
10 | let txtData = `${th}\r\n`
11 | data.forEach((row) => {
12 | let tempStr = ''
13 | tempStr = row.toString()
14 | txtData += `${tempStr}\r\n`
15 | })
16 | zip.file(`${txt_name}.txt`, txtData)
17 | zip.generateAsync({
18 | type: 'blob'
19 | }).then((blob) => {
20 | saveAs(blob, `${zip_name}.zip`)
21 | }, (err) => {
22 | alert('导出失败')
23 | })
24 | }
25 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | """Run administrative tasks."""
9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tdxStock.settings')
10 | try:
11 | from django.core.management import execute_from_command_line
12 | except ImportError as exc:
13 | raise ImportError(
14 | "Couldn't import Django. Are you sure it's installed and "
15 | "available on your PYTHONPATH environment variable? Did you "
16 | "forget to activate a virtual environment?"
17 | ) from exc
18 | execute_from_command_line(sys.argv)
19 |
20 |
21 | if __name__ == '__main__':
22 | main()
23 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/neat.css:
--------------------------------------------------------------------------------
1 | .cm-s-neat span.cm-comment { color: #a86; }
2 | .cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; }
3 | .cm-s-neat span.cm-string { color: #a22; }
4 | .cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; }
5 | .cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; }
6 | .cm-s-neat span.cm-variable { color: black; }
7 | .cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
8 | .cm-s-neat span.cm-meta { color: #555; }
9 | .cm-s-neat span.cm-link { color: #3a3; }
10 |
11 | .cm-s-neat .CodeMirror-activeline-background { background: #e8f2ff; }
12 | .cm-s-neat .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
13 |
--------------------------------------------------------------------------------
/wiki/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.urls import reverse
3 |
4 | from tdxStock.abstract_models import Timestamp
5 |
6 |
7 | class Concept(Timestamp):
8 | """名词解释"""
9 | name = models.CharField("名称", max_length=200, unique=True)
10 | description = models.TextField("描述(Markdown)", null=True, blank=True)
11 | description_html = models.TextField("描述(HTML)", null=True, editable=False)
12 |
13 | class Meta:
14 | ordering = ['-updated_at']
15 | verbose_name = "概念"
16 | verbose_name_plural = verbose_name
17 | get_latest_by = 'created_at'
18 |
19 | def __str__(self):
20 | return self.name
21 |
22 | def get_absolute_url(self):
23 | reverse('wiki:concept-detail', kwargs={'pk': self.pk})
24 |
--------------------------------------------------------------------------------
/tdxStock/api.py:
--------------------------------------------------------------------------------
1 | from rest_framework import routers
2 |
3 | from account import api_views as account_views
4 | from basedata import views as basedata_views
5 |
6 | router = routers.DefaultRouter()
7 | router.register(r'account/users', account_views.UserViewSet)
8 | router.register(r'account/groups', account_views.GroupViewSet)
9 | router.register(r'stocks', basedata_views.StockViewSet)
10 | router.register(r'industries', basedata_views.IndustryViewSet)
11 | router.register(r'concepts', basedata_views.ConceptViewSet)
12 | router.register(r'territories', basedata_views.TerritoryViewSet)
13 | router.register(r'sections', basedata_views.SectionViewSet)
14 | router.register(r'report-types', basedata_views.ReportTypeViewSet)
15 | router.register(r'subjects', basedata_views.AccountingSubjectViewSet)
16 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/hint/show-hint.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-hints {
2 | position: absolute;
3 | z-index: 10;
4 | overflow: hidden;
5 | list-style: none;
6 |
7 | margin: 0;
8 | padding: 2px;
9 |
10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2);
13 | border-radius: 3px;
14 | border: 1px solid silver;
15 |
16 | background: white;
17 | font-size: 90%;
18 | font-family: monospace;
19 |
20 | max-height: 20em;
21 | overflow-y: auto;
22 | }
23 |
24 | .CodeMirror-hint {
25 | margin: 0;
26 | padding: 0 4px;
27 | border-radius: 2px;
28 | white-space: pre;
29 | color: black;
30 | cursor: pointer;
31 | }
32 |
33 | li.CodeMirror-hint-active {
34 | background: #08f;
35 | color: white;
36 | }
37 |
--------------------------------------------------------------------------------
/account/api_views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.models import Group
2 | from rest_framework import viewsets
3 | from rest_framework import permissions # noqa
4 |
5 | from .serializers import UserSerializer, GroupSerializer
6 | from .models import User
7 |
8 |
9 | class UserViewSet(viewsets.ModelViewSet):
10 | """
11 | API endpoint that allows users to be viewed or edited.
12 | """
13 | queryset = User.objects.all().order_by('-date_joined')
14 | serializer_class = UserSerializer
15 | # permission_classes = [permissions.IsAuthenticated]
16 |
17 |
18 | class GroupViewSet(viewsets.ModelViewSet):
19 | """
20 | API endpoint that allows groups to be viewed or edited.
21 | """
22 | queryset = Group.objects.all()
23 | serializer_class = GroupSerializer
24 | # permission_classes = [permissions.IsAuthenticated]
25 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/ssms.css:
--------------------------------------------------------------------------------
1 | .cm-s-ssms span.cm-keyword { color: blue; }
2 | .cm-s-ssms span.cm-comment { color: darkgreen; }
3 | .cm-s-ssms span.cm-string { color: red; }
4 | .cm-s-ssms span.cm-def { color: black; }
5 | .cm-s-ssms span.cm-variable { color: black; }
6 | .cm-s-ssms span.cm-variable-2 { color: black; }
7 | .cm-s-ssms span.cm-atom { color: darkgray; }
8 | .cm-s-ssms .CodeMirror-linenumber { color: teal; }
9 | .cm-s-ssms .CodeMirror-activeline-background { background: #ffffff; }
10 | .cm-s-ssms span.cm-string-2 { color: #FF00FF; }
11 | .cm-s-ssms span.cm-operator,
12 | .cm-s-ssms span.cm-bracket,
13 | .cm-s-ssms span.cm-punctuation { color: darkgray; }
14 | .cm-s-ssms .CodeMirror-gutters { border-right: 3px solid #ffee62; background-color: #ffffff; }
15 | .cm-s-ssms div.CodeMirror-selected { background: #ADD6FF; }
16 |
17 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/README.md:
--------------------------------------------------------------------------------
1 | # CodeMirror
2 | [](https://travis-ci.org/codemirror/CodeMirror)
3 | [](https://www.npmjs.org/package/codemirror)
4 | [Funding status: ](https://marijnhaverbeke.nl/fund/)
5 |
6 | CodeMirror is a JavaScript component that provides a code editor in
7 | the browser. When a mode is available for the language you are coding
8 | in, it will color your code, and optionally help with indentation.
9 |
10 | The project page is http://codemirror.net
11 | The manual is at http://codemirror.net/doc/manual.html
12 | The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 | # C extensions
6 | *.so
7 |
8 | # Distribution / packaging
9 | .Python
10 | venv/
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | /lib/
18 | /lib64/
19 | /parts/
20 | /sdist/
21 | /var/
22 | *.egg-info/
23 | .installed.cfg
24 | *.egg
25 |
26 | # Unit test / coverage reports
27 | htmlcov/
28 | .tox/
29 | .coverage
30 | .coverage.*
31 | .cache
32 | nosetests.xml
33 | coverage.xml
34 | *,cover
35 |
36 | # Windows:
37 | Thumbs.db
38 | ehthumbs.db
39 | Desktop.ini
40 |
41 | # Translations
42 | *.mo
43 | *.pot
44 |
45 | # Django stuff:
46 | *.log
47 | local_settings.py
48 | migrations/
49 | !migrations/__init__.py
50 |
51 | # My configurations:
52 | .idea/
53 | *.sqlite3
54 | *.db
55 | .env
56 | .vscode
57 | .ipynb_checkpoints/
58 | fixtures/
59 |
--------------------------------------------------------------------------------
/option/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 |
4 | class Option(models.Model):
5 | name = models.CharField('项目', max_length=200, unique=True)
6 | value = models.JSONField('值', null=True, blank=True)
7 | enable = models.BooleanField(default=True)
8 |
9 | class Meta:
10 | db_table = "options"
11 | verbose_name = '选项'
12 | verbose_name_plural = verbose_name
13 |
14 | def __str__(self):
15 | return self.name
16 |
17 | _options = {} # cache
18 |
19 | @classmethod
20 | def get_option(cls, name, default=None):
21 | if name in cls._options:
22 | return cls._options[name]
23 |
24 | o = cls.objects.filter(enable=True).filter(name=name).first()
25 |
26 | if o:
27 | cls._options[name] = o.value
28 | return o.value
29 |
30 | return default
31 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/elegant.css:
--------------------------------------------------------------------------------
1 | .cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom { color: #762; }
2 | .cm-s-elegant span.cm-comment { color: #262; font-style: italic; line-height: 1em; }
3 | .cm-s-elegant span.cm-meta { color: #555; font-style: italic; line-height: 1em; }
4 | .cm-s-elegant span.cm-variable { color: black; }
5 | .cm-s-elegant span.cm-variable-2 { color: #b11; }
6 | .cm-s-elegant span.cm-qualifier { color: #555; }
7 | .cm-s-elegant span.cm-keyword { color: #730; }
8 | .cm-s-elegant span.cm-builtin { color: #30a; }
9 | .cm-s-elegant span.cm-link { color: #762; }
10 | .cm-s-elegant span.cm-error { background-color: #fdd; }
11 |
12 | .cm-s-elegant .CodeMirror-activeline-background { background: #e8f2ff; }
13 | .cm-s-elegant .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
14 |
--------------------------------------------------------------------------------
/templates/_layout/base_account.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{ SITE_NAME }} | {{ SITE_DESCRIPTION }}
13 |
14 |
15 |
16 |
17 |
18 | {% block breadcrumbs %}{% endblock %}
19 | {% block content %}{% endblock %}
20 |
21 |
--------------------------------------------------------------------------------
/account/user_login_backend.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth import get_user_model
2 | from django.contrib.auth.backends import ModelBackend
3 |
4 | User = get_user_model()
5 |
6 |
7 | class EmailOrUsernameModelBackend(ModelBackend):
8 | """
9 | 允许使用用户名或邮箱登录
10 | """
11 |
12 | def authenticate(self, request, username=None, password=None, **kwargs):
13 | if '@' in username:
14 | kwargs = {'email': username}
15 | else:
16 | kwargs = {'username': username}
17 | try:
18 | user = User.objects.get(**kwargs)
19 | if user.check_password(password):
20 | return user
21 | except User.DoesNotExist:
22 | return None
23 |
24 | def get_user(self, username):
25 | try:
26 | return User.objects.get(pk=username)
27 | except User.DoesNotExist:
28 | return None
29 |
--------------------------------------------------------------------------------
/frontend/src/views/Industry.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 | {{ stock.name }}
8 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
42 |
--------------------------------------------------------------------------------
/frontend/src/defines/consts.js:
--------------------------------------------------------------------------------
1 | export const NUMBER_TYPE = 1
2 | export const STRING_TYPE = 2
3 |
4 | export const DATA_TYPES = [
5 | { value: NUMBER_TYPE, label: '数值' },
6 | { value: STRING_TYPE, label: '字符串' }
7 | ]
8 |
9 | const YUAN = 1
10 | const WAN_YUAN = 2
11 | const YI = 3
12 | const GE = 4
13 | const REN = 5
14 | const CI = 6
15 | const RATE = 7
16 |
17 | export const UNIT_TYPES = [
18 | { value: YUAN, label: '元' },
19 | { value: WAN_YUAN, label: '万元' },
20 | { value: YI, label: '亿' },
21 | { value: GE, label: '个' },
22 | { value: REN, label: '人' },
23 | { value: CI, label: '次' },
24 | { value: RATE, label: '%' }
25 | ]
26 |
27 | export const REPORT_TYPES = [
28 | { value: 'primary_indicator_sheet', label: '主要指标' },
29 | { value: 'consolidated_income_sheet', label: '利润表' },
30 | { value: 'consolidated_balance_sheet', label: '资产负债表' },
31 | { value: 'cash_flow_sheet', label: '现金流量表' }
32 | ]
33 |
--------------------------------------------------------------------------------
/option/context_processors.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from django.core.cache import cache
4 |
5 | from .models import Option
6 |
7 | logger = logging.getLogger(__name__)
8 |
9 |
10 | def options_processor(requests):
11 | key = 'options_cache'
12 | value = cache.get(key)
13 | if value:
14 | return value
15 |
16 | logger.info('set options cache.')
17 | options = Option.objects.filter(name__in=['site_name',
18 | 'site_seo_description',
19 | 'site_description',
20 | 'site_keywords',
21 | 'site_host',
22 | 'site_comment_status']).all()
23 | value = {}
24 | for option in options:
25 | value[option.name.upper()] = option.value
26 |
27 | cache.set(key, value, 60 * 60 * 10)
28 |
29 | return value
30 |
--------------------------------------------------------------------------------
/account/models.py:
--------------------------------------------------------------------------------
1 | import base64
2 |
3 | from django.conf import settings
4 | from django.contrib.auth.models import AbstractUser
5 | from django.db import models
6 | from django.utils import timezone
7 |
8 | from .identicon import Generator
9 |
10 |
11 | class User(AbstractUser):
12 | nickname = models.CharField('昵称', max_length=100, blank=True)
13 | avatar = models.TextField('头像', null=True)
14 | updated_at = models.DateTimeField('更新时间', default=timezone.now)
15 |
16 | def __str__(self):
17 | return f"{self.nickname}({self.email})"
18 |
19 | def save(self, *args, **kwargs):
20 | if not self.avatar:
21 | self.change_avatar()
22 | super().save(*args, **kwargs)
23 |
24 | def change_avatar(self):
25 | g = Generator(9, 9, foreground=settings.IDENTICON_FOREGROUND)
26 | data = base64.b64encode(g.generate(self.email, 256, 256, output_format='gif'))
27 | self.avatar = f'data:image/gif;base64,{data}'
28 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/ruby/test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function() {
5 | var mode = CodeMirror.getMode({indentUnit: 2}, "ruby");
6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
7 |
8 | MT("divide_equal_operator",
9 | "[variable bar] [operator /=] [variable foo]");
10 |
11 | MT("divide_equal_operator_no_spacing",
12 | "[variable foo][operator /=][number 42]");
13 |
14 | MT("complex_regexp",
15 | "[keyword if] [variable cr] [operator =~] [string-2 /(?: \\( #{][tag RE_NOT][string-2 }\\( | #{][tag RE_NOT_PAR_OR][string-2 }* #{][tag RE_OPA_OR][string-2 } )/][variable x]")
16 |
17 | MT("indented_heredoc",
18 | "[keyword def] [def x]",
19 | " [variable y] [operator =] [string <<-FOO]",
20 | "[string bar]",
21 | "[string FOO]",
22 | "[keyword end]")
23 | })();
24 |
--------------------------------------------------------------------------------
/option/management/commands/seed_options.py:
--------------------------------------------------------------------------------
1 | from django.core.management import BaseCommand, CommandError
2 |
3 | from option.models import Option
4 |
5 |
6 | class Command(BaseCommand):
7 | help = '填充 options 表'
8 |
9 | def handle(self, *args, **options):
10 | if not Option.objects.exists():
11 | Option.objects.create(name="site_name", value="TdxStock")
12 | Option.objects.create(name="site_host", value="localhost")
13 | Option.objects.create(name="site_description", value="沪深股票分析")
14 | options = [Option(name=name, value="") for name in ['site_seo_description',
15 | 'site_keywords',
16 | 'site_comment_status']]
17 | Option.objects.bulk_create(options)
18 | self.stdout.write(self.style.SUCCESS('填充 options 表成功'))
19 |
20 | else:
21 | raise CommandError('options 表中已经有数据')
22 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "codemirror",
3 | "version":"5.0.0",
4 | "main": "lib/codemirror.js",
5 | "description": "In-browser code editing made bearable",
6 | "licenses": [{"type": "MIT",
7 | "url": "http://codemirror.net/LICENSE"}],
8 | "directories": {"lib": "./lib"},
9 | "scripts": {"test": "node ./test/run.js"},
10 | "devDependencies": {"node-static": "0.6.0",
11 | "phantomjs": "1.9.2-5",
12 | "blint": ">=0.1.1"},
13 | "bugs": "http://github.com/codemirror/CodeMirror/issues",
14 | "keywords": ["JavaScript", "CodeMirror", "Editor"],
15 | "homepage": "http://codemirror.net",
16 | "maintainers":[{"name": "Marijn Haverbeke",
17 | "email": "marijnh@gmail.com",
18 | "web": "http://marijnhaverbeke.nl"}],
19 | "repository": {"type": "git",
20 | "url": "https://github.com/codemirror/CodeMirror.git"}
21 | }
22 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/mode/multiplex_test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function() {
5 | CodeMirror.defineMode("markdown_with_stex", function(){
6 | var inner = CodeMirror.getMode({}, "stex");
7 | var outer = CodeMirror.getMode({}, "markdown");
8 |
9 | var innerOptions = {
10 | open: '$',
11 | close: '$',
12 | mode: inner,
13 | delimStyle: 'delim',
14 | innerStyle: 'inner'
15 | };
16 |
17 | return CodeMirror.multiplexingMode(outer, innerOptions);
18 | });
19 |
20 | var mode = CodeMirror.getMode({}, "markdown_with_stex");
21 |
22 | function MT(name) {
23 | test.mode(
24 | name,
25 | mode,
26 | Array.prototype.slice.call(arguments, 1),
27 | 'multiplexing');
28 | }
29 |
30 | MT(
31 | "stexInsideMarkdown",
32 | "[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]");
33 | })();
34 |
--------------------------------------------------------------------------------
/frontend/src/components/IndustryMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
14 |
15 | {{ industry.name }}
16 |
17 |
18 |
19 |
20 |
21 | {{ industry.name }}
22 |
23 |
24 |
25 |
26 |
37 |
--------------------------------------------------------------------------------
/templates/account/registration_form.html:
--------------------------------------------------------------------------------
1 | {% extends '_layout/base_account.html' %}
2 | {% load static %}
3 | {% block content %}
4 |
5 |
6 |
注册一个账号
7 |
8 |

10 |
21 |
22 |
23 | 登录
24 |
25 |
26 |
© 2019 {{ SITE_NAME }}
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/public/static/css/signin.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-top: 40px;
3 | padding-bottom: 40px;
4 | background-color: #fff;
5 | }
6 |
7 | .form-signin {
8 | max-width: 330px;
9 | padding: 15px;
10 | margin: 0 auto;
11 | }
12 |
13 | .form-signin-heading {
14 | margin: 0 0 15px;
15 | font-size: 18px;
16 | font-weight: 400;
17 | color: #555;
18 | }
19 |
20 | .form-signin .form-control {
21 | position: relative;
22 | height: auto;
23 | -webkit-box-sizing: border-box;
24 | -moz-box-sizing: border-box;
25 | box-sizing: border-box;
26 | padding: 10px;
27 | font-size: 16px;
28 | }
29 |
30 | .form-signin .form-control:focus {
31 | z-index: 2;
32 | }
33 |
34 | .form-signin input[name="username"] {
35 | margin-bottom: 10px;
36 | }
37 |
38 | .form-signin input[type="email"] {
39 | margin-bottom: 10px;
40 | }
41 |
42 | .form-signin input[type="password"] {
43 | margin-bottom: 10px;
44 | }
45 |
46 | .form-signin .checkbox {
47 | margin-bottom: 10px;
48 | font-weight: normal;
49 | text-align: left;
50 | }
51 |
--------------------------------------------------------------------------------
/frontend/src/utils/errorlog.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import store from '@/store'
3 | import { isString, isArray } from './validate'
4 | import settings from '@/settings'
5 |
6 | // you can set in settings.js
7 | // errorLog:'production' | ['production', 'development']
8 | const { errorLog: needErrorLog } = settings
9 |
10 | function checkNeed () {
11 | const env = process.env.NODE_ENV
12 | if (isString(needErrorLog)) {
13 | return env === needErrorLog
14 | }
15 | if (isArray(needErrorLog)) {
16 | return needErrorLog.includes(env)
17 | }
18 | return false
19 | }
20 |
21 | if (checkNeed()) {
22 | Vue.config.errorHandler = function (err, vm, info, a) {
23 | // Don't ask me why I use Vue.nextTick, it just a hack.
24 | // detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500
25 | Vue.nextTick(() => {
26 | store.dispatch('errorLog/addErrorLog', {
27 | err,
28 | vm,
29 | info,
30 | url: window.location.href
31 | })
32 | console.error(err, info)
33 | })
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/public/static/editor.md/fonts/editormd-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/edit/trailingspace.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
13 | if (prev == CodeMirror.Init) prev = false;
14 | if (prev && !val)
15 | cm.removeOverlay("trailingspace");
16 | else if (!prev && val)
17 | cm.addOverlay({
18 | token: function(stream) {
19 | for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
20 | if (i > stream.pos) { stream.pos = i; return null; }
21 | stream.pos = l;
22 | return "trailingspace";
23 | },
24 | name: "trailingspace"
25 | });
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/option/widgets.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.template import loader
3 |
4 |
5 | class JsonEditorWidget(forms.Textarea):
6 |
7 | def __init__(self, *args, **kwargs):
8 | self.template = kwargs.pop('template', 'widgets/json_editor.html')
9 | super().__init__(*args, **kwargs)
10 |
11 | def render(self, name, value, attrs=None, renderer=None):
12 | template = loader.get_template(self.template)
13 | context = self.get_context(name, value, attrs)
14 | return template.render(context)
15 |
16 | class Media:
17 | css = {
18 | "all": (
19 | "editor.md/lib/codemirror/lib/codemirror.css",
20 | "editor.md/lib/codemirror/addon/lint/lint.css",
21 | "editor.md/lib/codemirror/theme/rubyblue.css",
22 | )
23 | }
24 | js = (
25 | 'js/jsonlint.js',
26 | 'editor.md/lib/codemirror/lib/codemirror.js',
27 | 'editor.md/lib/codemirror/mode/javascript/javascript.js',
28 | "editor.md/lib/codemirror/addon/lint/lint.js",
29 | "editor.md/lib/codemirror/addon/lint/json-lint.js"
30 | )
31 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/neo.css:
--------------------------------------------------------------------------------
1 | /* neo theme for codemirror */
2 |
3 | /* Color scheme */
4 |
5 | .cm-s-neo.CodeMirror {
6 | background-color:#ffffff;
7 | color:#2e383c;
8 | line-height:1.4375;
9 | }
10 | .cm-s-neo .cm-comment { color:#75787b; }
11 | .cm-s-neo .cm-keyword, .cm-s-neo .cm-property { color:#1d75b3; }
12 | .cm-s-neo .cm-atom,.cm-s-neo .cm-number { color:#75438a; }
13 | .cm-s-neo .cm-node,.cm-s-neo .cm-tag { color:#9c3328; }
14 | .cm-s-neo .cm-string { color:#b35e14; }
15 | .cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier { color:#047d65; }
16 |
17 |
18 | /* Editor styling */
19 |
20 | .cm-s-neo pre {
21 | padding:0;
22 | }
23 |
24 | .cm-s-neo .CodeMirror-gutters {
25 | border:none;
26 | border-right:10px solid transparent;
27 | background-color:transparent;
28 | }
29 |
30 | .cm-s-neo .CodeMirror-linenumber {
31 | padding:0;
32 | color:#e0e2e5;
33 | }
34 |
35 | .cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; }
36 | .cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; }
37 |
38 | .cm-s-neo .CodeMirror-cursor {
39 | width: auto;
40 | border: 0;
41 | background: rgba(155,157,162,0.37);
42 | z-index: 1;
43 | }
44 |
--------------------------------------------------------------------------------
/account/views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth import views
2 | from django.http import HttpResponseRedirect
3 | from django.shortcuts import redirect
4 | from django.urls import reverse
5 | from django.views.generic import FormView
6 |
7 | from .forms import LoginForm, RegisterForm
8 |
9 |
10 | class RegisterView(FormView):
11 | form_class = RegisterForm
12 | template_name = 'account/registration_form.html'
13 | success_url = '/'
14 |
15 | def get(self, request, *args, **kwargs):
16 | if request.user.is_authenticated:
17 | return redirect(self.success_url)
18 |
19 | return super().get(request, *args, **kwargs)
20 |
21 | def form_valid(self, form):
22 | user = form.save(False)
23 | user.avatar = ''
24 | user.save(True)
25 | url = reverse('account:login')
26 | return HttpResponseRedirect(url)
27 |
28 |
29 | class LogoutView(views.LogoutView):
30 | next_page = '/'
31 | template_name = 'account/logged_out.html'
32 |
33 |
34 | class LoginView(views.LoginView):
35 | form_class = LoginForm
36 | template_name = 'account/login.html'
37 | redirect_authenticated_user = True
38 | success_url = '/'
39 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2014 by Marijn Haverbeke and others
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/collector/fix_items.py:
--------------------------------------------------------------------------------
1 | from django.db.models import Q
2 | from twisted.internet import defer
3 |
4 | from basedata.models import ReportItem
5 |
6 |
7 | async def _fix_item(item):
8 | try:
9 | item.value_number = float(item.value)
10 | except ValueError:
11 | print('字符串%s' % item.id)
12 | item.value_type = 2 # 字符串
13 | else:
14 | item.value_type = 1
15 | item.value = None
16 |
17 | item.save()
18 |
19 |
20 | async def fix_report_items(start, limit):
21 | items = ReportItem.objects.filter(
22 | Q(value__isnull=False) & Q(value_number__isnull=True) & Q(pk__gt=start)
23 | ).all()[:limit]
24 | count = 0
25 | next_start = -1
26 | for item in items:
27 | print('fixing... %s' % item.id)
28 | count += 1
29 | next_start = item.id
30 | if item.value_number is None:
31 | await _fix_item(item)
32 |
33 | if count < limit:
34 | print('最后一页')
35 | return
36 |
37 | await fix_report_items(next_start, limit)
38 |
39 |
40 | def run():
41 | from twisted.internet import reactor
42 |
43 | defer.ensureDeferred(fix_report_items(0, 1000))
44 | reactor.run()
45 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/rust/test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function() {
5 | var mode = CodeMirror.getMode({indentUnit: 4}, "rust");
6 | function MT(name) {test.mode(name, mode, Array.prototype.slice.call(arguments, 1));}
7 |
8 | MT('integer_test',
9 | '[number 123i32]',
10 | '[number 123u32]',
11 | '[number 123_u32]',
12 | '[number 0xff_u8]',
13 | '[number 0o70_i16]',
14 | '[number 0b1111_1111_1001_0000_i32]',
15 | '[number 0usize]');
16 |
17 | MT('float_test',
18 | '[number 123.0f64]',
19 | '[number 0.1f64]',
20 | '[number 0.1f32]',
21 | '[number 12E+99_f64]');
22 |
23 | MT('string-literals-test',
24 | '[string "foo"]',
25 | '[string r"foo"]',
26 | '[string "\\"foo\\""]',
27 | '[string r#""foo""#]',
28 | '[string "foo #\\"# bar"]',
29 |
30 | '[string b"foo"]',
31 | '[string br"foo"]',
32 | '[string b"\\"foo\\""]',
33 | '[string br#""foo""#]',
34 | '[string br##"foo #" bar"##]',
35 |
36 | "[string-2 'h']",
37 | "[string-2 b'h']");
38 |
39 | })();
40 |
--------------------------------------------------------------------------------
/templates/account/login.html:
--------------------------------------------------------------------------------
1 | {% extends '_layout/base_account.html' %}
2 | {% load static %}
3 | {% block content %}
4 |
5 |

7 |
24 |
25 | 创建账号
26 | |
27 | 主页
28 |
29 |
© 2019 {{ SITE_NAME }}
30 |
31 | {% endblock %}
32 |
--------------------------------------------------------------------------------
/option/management/commands/clean_migrations.py:
--------------------------------------------------------------------------------
1 | import os
2 | import shutil
3 |
4 | from django.conf import settings
5 | from django.core.management import BaseCommand
6 |
7 |
8 | class Command(BaseCommand):
9 | help = '清除 migrations 数据'
10 |
11 | def handle(self, *args, **options):
12 | clean_migrations()
13 | self.stdout.write(self.style.SUCCESS('清除成功'))
14 |
15 |
16 | def clean_migrations():
17 | for migrations_path in get_migrations_dirs():
18 | for item in os.listdir(migrations_path):
19 | if item != '__init__.py':
20 | item_path = os.path.join(migrations_path, item)
21 | if os.path.isfile(item_path):
22 | os.remove(item_path)
23 | else:
24 | shutil.rmtree(item_path)
25 |
26 |
27 | def get_migrations_dirs():
28 | migrations_dirs = []
29 | for item in os.listdir(settings.BASE_DIR):
30 | item_path = os.path.join(settings.BASE_DIR, item)
31 | if os.path.isdir(item_path):
32 | app_migrations_path = os.path.join(item_path, 'migrations')
33 | if os.path.exists(app_migrations_path):
34 | migrations_dirs.append(app_migrations_path)
35 | return migrations_dirs
36 |
--------------------------------------------------------------------------------
/wiki/templatetags/wiki_tags.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from django import template
4 | from django.conf import settings
5 | from django.template.defaultfilters import stringfilter
6 |
7 | # Get an instance of a logger
8 | logger = logging.getLogger(__name__)
9 |
10 | register = template.Library()
11 |
12 |
13 | @register.simple_tag
14 | def timeformat(time_data):
15 | try:
16 | return time_data.strftime(settings.TIME_FORMAT)
17 | except Exception as e:
18 | logger.error(e)
19 | return ""
20 |
21 |
22 | @register.simple_tag
23 | def datetimeformat(datetime_data):
24 | try:
25 | return datetime_data.strftime(settings.DATE_TIME_FORMAT)
26 | except Exception as e:
27 | logger.error(e)
28 | return ""
29 |
30 |
31 | @register.filter(is_safe=True)
32 | @stringfilter
33 | def truncate(content: str):
34 | from django.utils.html import strip_tags
35 |
36 | return strip_tags(content)[:150]
37 |
38 |
39 | @register.simple_tag
40 | def query(qs, **kwargs):
41 | """ template tag which allows queryset filtering. Usage:
42 | {% query books author=author as mybooks %}
43 | {% for book in mybooks %}
44 | ...
45 | {% endfor %}
46 | """
47 | return qs.filter(**kwargs)
48 |
--------------------------------------------------------------------------------
/templates/_layout/base.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {% block title %}{% endblock %} | {{ SITE_NAME }}
11 |
12 |
13 |
14 | {% block header_css %}{% endblock %}
15 | {% block header_js %}{% endblock %}
16 |
17 |
18 |
19 | {% include '_layout/nav.html' %}
20 |
21 |
22 | {% block content %}{% endblock %}
23 |
24 |
25 | {% include '_layout/footer.html' %}
26 |
27 |
28 |
29 |
30 |
31 |
32 | {% block scripts %}{% endblock %}
33 |
34 |
35 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/eclipse.css:
--------------------------------------------------------------------------------
1 | .cm-s-eclipse span.cm-meta { color: #FF1717; }
2 | .cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; }
3 | .cm-s-eclipse span.cm-atom { color: #219; }
4 | .cm-s-eclipse span.cm-number { color: #164; }
5 | .cm-s-eclipse span.cm-def { color: #00f; }
6 | .cm-s-eclipse span.cm-variable { color: black; }
7 | .cm-s-eclipse span.cm-variable-2 { color: #0000C0; }
8 | .cm-s-eclipse span.cm-variable-3, .cm-s-eclipse span.cm-type { color: #0000C0; }
9 | .cm-s-eclipse span.cm-property { color: black; }
10 | .cm-s-eclipse span.cm-operator { color: black; }
11 | .cm-s-eclipse span.cm-comment { color: #3F7F5F; }
12 | .cm-s-eclipse span.cm-string { color: #2A00FF; }
13 | .cm-s-eclipse span.cm-string-2 { color: #f50; }
14 | .cm-s-eclipse span.cm-qualifier { color: #555; }
15 | .cm-s-eclipse span.cm-builtin { color: #30a; }
16 | .cm-s-eclipse span.cm-bracket { color: #cc7; }
17 | .cm-s-eclipse span.cm-tag { color: #170; }
18 | .cm-s-eclipse span.cm-attribute { color: #00c; }
19 | .cm-s-eclipse span.cm-link { color: #219; }
20 | .cm-s-eclipse span.cm-error { color: #f00; }
21 |
22 | .cm-s-eclipse .CodeMirror-activeline-background { background: #e8f2ff; }
23 | .cm-s-eclipse .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
24 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "@antv/g2": "^4.0.0",
12 | "axios": "^0.21.2",
13 | "core-js": "^3.6.4",
14 | "element-ui": "^2.13.0",
15 | "file-saver": "^2.0.2",
16 | "nprogress": "^0.2.0",
17 | "vue": "^2.6.11",
18 | "vue-fragment": "^1.5.1",
19 | "vue-router": "^3.1.5",
20 | "vuex": "^3.1.2",
21 | "xlsx": "^0.17.0"
22 | },
23 | "devDependencies": {
24 | "@vue/cli-plugin-babel": "~4.2.0",
25 | "@vue/cli-plugin-eslint": "~4.2.0",
26 | "@vue/cli-plugin-router": "~4.2.0",
27 | "@vue/cli-plugin-vuex": "~4.2.0",
28 | "@vue/cli-service": "~4.2.0",
29 | "@vue/eslint-config-standard": "^5.1.0",
30 | "babel-eslint": "^10.0.3",
31 | "eslint": "^6.7.2",
32 | "eslint-plugin-import": "^2.20.1",
33 | "eslint-plugin-node": "^11.0.0",
34 | "eslint-plugin-promise": "^4.2.1",
35 | "eslint-plugin-standard": "^4.0.0",
36 | "eslint-plugin-vue": "^6.1.2",
37 | "node-sass": "^7.0.0",
38 | "sass-loader": "^8.0.2",
39 | "script-loader": "^0.7.2",
40 | "vue-template-compiler": "^2.6.11"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/diff/diff.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineMode("diff", function() {
15 |
16 | var TOKEN_NAMES = {
17 | '+': 'positive',
18 | '-': 'negative',
19 | '@': 'meta'
20 | };
21 |
22 | return {
23 | token: function(stream) {
24 | var tw_pos = stream.string.search(/[\t ]+?$/);
25 |
26 | if (!stream.sol() || tw_pos === 0) {
27 | stream.skipToEnd();
28 | return ("error " + (
29 | TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
30 | }
31 |
32 | var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
33 |
34 | if (tw_pos === -1) {
35 | stream.skipToEnd();
36 | } else {
37 | stream.pos = tw_pos;
38 | }
39 |
40 | return token_name;
41 | }
42 | };
43 | });
44 |
45 | CodeMirror.defineMIME("text/x-diff", "diff");
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/jquery.flowchart.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery.flowchart.js v1.1.0 | jquery.flowchart.min.js | jQuery plugin for flowchart.js. | MIT License | By: Pandao | https://github.com/pandao/jquery.flowchart.js | 2015-03-09 */
2 | (function(factory){if(typeof require==="function"&&typeof exports==="object"&&typeof module==="object"){module.exports=factory}else{if(typeof define==="function"){factory(jQuery,flowchart)}else{factory($,flowchart)}}}(function(jQuery,flowchart){(function($){$.fn.flowChart=function(options){options=options||{};var defaults={"x":0,"y":0,"line-width":2,"line-length":50,"text-margin":10,"font-size":14,"font-color":"black","line-color":"black","element-color":"black","fill":"white","yes-text":"yes","no-text":"no","arrow-end":"block","symbols":{"start":{"font-color":"black","element-color":"black","fill":"white"},"end":{"class":"end-element"}},"flowstate":{"past":{"fill":"#CCCCCC","font-size":12},"current":{"fill":"black","font-color":"white","font-weight":"bold"},"future":{"fill":"white"},"request":{"fill":"blue"},"invalid":{"fill":"#444444"},"approved":{"fill":"#58C4A3","font-size":12,"yes-text":"APPROVED","no-text":"n/a"},"rejected":{"fill":"#C45879","font-size":12,"yes-text":"n/a","no-text":"REJECTED"}}};return this.each(function(){var $this=$(this);var diagram=flowchart.parse($this.text());var settings=$.extend(true,defaults,options);$this.html("");diagram.drawSVG(this,settings)})}})(jQuery)}));
--------------------------------------------------------------------------------
/tdxStock/fields.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | from django.db import models
4 | from django_extensions.db.fields.json import JSONField as JField
5 |
6 | from tdxStock.helpers import is_json_stringify
7 |
8 |
9 | class JSONField(JField):
10 | """支持纯字符串的JSONField"""
11 |
12 | def to_python(self, value):
13 | """Convert our string value to JSON after we load it from the DB"""
14 | try:
15 | res = super().to_python(value)
16 | except json.decoder.JSONDecodeError:
17 | res = value
18 |
19 | return res
20 |
21 | def get_db_prep_save(self, value, connection, **kwargs):
22 | """Convert our JSON object to a string before we save"""
23 |
24 | if isinstance(value, str) and not is_json_stringify(value):
25 | value = json.dumps(value)
26 |
27 | return super().get_db_prep_save(value, connection, **kwargs)
28 |
29 |
30 | # MySQL unsigned integer (range 0 to 4294967295).
31 | class UnsignedAutoField(models.AutoField):
32 | def db_type(self, connection):
33 | return 'integer UNSIGNED AUTO_INCREMENT'
34 |
35 | def rel_db_type(self, connection):
36 | return 'integer UNSIGNED'
37 |
38 |
39 | class UnsignedBigAutoField(models.AutoField):
40 | def db_type(self, connection):
41 | return 'BIGINT UNSIGNED AUTO_INCREMENT'
42 |
43 | def rel_db_type(self, connection):
44 | return 'BIGINT UNSIGNED'
45 |
--------------------------------------------------------------------------------
/wiki/widgets.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.conf import settings
3 | from django.template import loader
4 |
5 |
6 | class MarkdownWidget(forms.Textarea):
7 |
8 | def __init__(self, *args, **kwargs):
9 | self.template = kwargs.pop('template', 'widgets/editor_md.html')
10 | self.lib = settings.STATIC_URL + "editor.md/lib/"
11 | self.width = kwargs.pop("width", "100%")
12 | self.height = kwargs.pop("height", "640")
13 | super().__init__(*args, **kwargs)
14 |
15 | def render(self, name, value, attrs=None, renderer=None):
16 | final_attrs = self.build_attrs(attrs, {'name': name})
17 |
18 | if "class" not in final_attrs:
19 | final_attrs["class"] = ""
20 | final_attrs["class"] += " wmd-input"
21 | template = loader.get_template(self.template)
22 | markdown_conf = {
23 | 'width': self.width,
24 | 'height': self.height,
25 | 'path': self.lib,
26 | 'id': final_attrs["id"],
27 | }
28 | context = self.get_context(name, value, attrs)
29 | context.update(markdown_conf)
30 | return template.render(context)
31 |
32 | class Media:
33 | css = {
34 | "all": ("editor.md/css/editormd.min.css",)
35 | }
36 | js = (
37 | 'js/jquery-3.2.1.min.js',
38 | 'editor.md/editormd.min.js',
39 | )
40 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/tern/worker.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | // declare global: tern, server
5 |
6 | var server;
7 |
8 | this.onmessage = function(e) {
9 | var data = e.data;
10 | switch (data.type) {
11 | case "init": return startServer(data.defs, data.plugins, data.scripts);
12 | case "add": return server.addFile(data.name, data.text);
13 | case "del": return server.delFile(data.name);
14 | case "req": return server.request(data.body, function(err, reqData) {
15 | postMessage({id: data.id, body: reqData, err: err && String(err)});
16 | });
17 | case "getFile":
18 | var c = pending[data.id];
19 | delete pending[data.id];
20 | return c(data.err, data.text);
21 | default: throw new Error("Unknown message type: " + data.type);
22 | }
23 | };
24 |
25 | var nextId = 0, pending = {};
26 | function getFile(file, c) {
27 | postMessage({type: "getFile", name: file, id: ++nextId});
28 | pending[nextId] = c;
29 | }
30 |
31 | function startServer(defs, plugins, scripts) {
32 | if (scripts) importScripts.apply(null, scripts);
33 |
34 | server = new tern.Server({
35 | getFile: getFile,
36 | async: true,
37 | defs: defs,
38 | plugins: plugins
39 | });
40 | }
41 |
42 | this.console = {
43 | log: function(v) { postMessage({type: "debug", message: v}); }
44 | };
45 |
--------------------------------------------------------------------------------
/basedata/management/commands/seed_report_types.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from django.core.management import BaseCommand, CommandError
4 | from django.conf import settings
5 | from openpyxl import load_workbook
6 |
7 | from basedata.models import ReportType, AccountingSubject
8 |
9 |
10 | class Command(BaseCommand):
11 | help = '填充数据'
12 |
13 | def handle(self, *args, **options):
14 | wb = load_workbook(os.path.join(
15 | os.path.join(settings.BASE_DIR, 'fixtures'),
16 | 'report_types.xlsx'))
17 | ws = wb['report_types']
18 |
19 | current_type = None
20 | parent_subjects = [None for i in range(ws.max_column)]
21 | for row in ws.iter_rows(min_row=1, max_col=ws.max_column, max_row=ws.max_row, values_only=True):
22 | for i in range(ws.max_column):
23 | if isinstance(row[i], str) and row[i].strip():
24 | if i == 0:
25 | current_type, created = ReportType.objects.get_or_create(name=row[i].strip())
26 |
27 | else:
28 | subject, created = AccountingSubject.objects.get_or_create(
29 | name=row[i].strip(),
30 | report_type=current_type,
31 | parent=parent_subjects[i - 1]
32 | )
33 |
34 | parent_subjects[i] = subject
35 |
36 | continue # 一行只处理一个
37 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/lint/yaml-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | // Depends on js-yaml.js from https://github.com/nodeca/js-yaml
15 |
16 | // declare global: jsyaml
17 |
18 | CodeMirror.registerHelper("lint", "yaml", function(text) {
19 | var found = [];
20 | if (!window.jsyaml) {
21 | if (window.console) {
22 | window.console.error("Error: window.jsyaml not defined, CodeMirror YAML linting cannot run.");
23 | }
24 | return found;
25 | }
26 | try { jsyaml.loadAll(text); }
27 | catch(e) {
28 | var loc = e.mark,
29 | // js-yaml YAMLException doesn't always provide an accurate lineno
30 | // e.g., when there are multiple yaml docs
31 | // ---
32 | // ---
33 | // foo:bar
34 | from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0),
35 | to = from;
36 | found.push({ from: from, to: to, message: e.message });
37 | }
38 | return found;
39 | });
40 |
41 | });
42 |
--------------------------------------------------------------------------------
/templates/widgets/json_editor.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
--------------------------------------------------------------------------------
/account/forms.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth import get_user_model
2 | from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
3 | from django.forms import widgets
4 | from django.utils.translation import gettext as _
5 |
6 |
7 | class LoginForm(AuthenticationForm):
8 | def __init__(self, *args, **kwargs):
9 | super().__init__(*args, **kwargs)
10 | self.fields['username'].widget = widgets.TextInput(
11 | attrs={'placeholder': _("username"), "class": "form-control"})
12 | self.fields['password'].widget = widgets.PasswordInput(
13 | attrs={'placeholder': _("password"), "class": "form-control"})
14 |
15 |
16 | class RegisterForm(UserCreationForm):
17 | def __init__(self, *args, **kwargs):
18 | super().__init__(*args, **kwargs)
19 |
20 | self.fields['username'].widget = widgets.TextInput(
21 | attrs={'placeholder': _("username"), "class": "form-control"})
22 | self.fields['email'].widget = widgets.EmailInput(
23 | attrs={'placeholder': _("Email"), "class": "form-control"})
24 | self.fields['password1'].widget = widgets.PasswordInput(
25 | attrs={'placeholder': _("Password"), "class": "form-control"})
26 | self.fields['password2'].widget = widgets.PasswordInput(
27 | attrs={'placeholder': _("Password confirmation"), "class": "form-control"})
28 |
29 | class Meta:
30 | model = get_user_model()
31 | fields = ("username", "email")
32 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/lint/css-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | // Depends on csslint.js from https://github.com/stubbornella/csslint
5 |
6 | // declare global: CSSLint
7 |
8 | (function(mod) {
9 | if (typeof exports == "object" && typeof module == "object") // CommonJS
10 | mod(require("../../lib/codemirror"));
11 | else if (typeof define == "function" && define.amd) // AMD
12 | define(["../../lib/codemirror"], mod);
13 | else // Plain browser env
14 | mod(CodeMirror);
15 | })(function(CodeMirror) {
16 | "use strict";
17 |
18 | CodeMirror.registerHelper("lint", "css", function(text, options) {
19 | var found = [];
20 | if (!window.CSSLint) {
21 | if (window.console) {
22 | window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run.");
23 | }
24 | return found;
25 | }
26 | var results = CSSLint.verify(text, options), messages = results.messages, message = null;
27 | for ( var i = 0; i < messages.length; i++) {
28 | message = messages[i];
29 | var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;
30 | found.push({
31 | from: CodeMirror.Pos(startLine, startCol),
32 | to: CodeMirror.Pos(endLine, endCol),
33 | message: message.message,
34 | severity : message.type
35 | });
36 | }
37 | return found;
38 | });
39 |
40 | });
41 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/runmode/colorize.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"), require("./runmode"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror", "./runmode"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;
15 |
16 | function textContent(node, out) {
17 | if (node.nodeType == 3) return out.push(node.nodeValue);
18 | for (var ch = node.firstChild; ch; ch = ch.nextSibling) {
19 | textContent(ch, out);
20 | if (isBlock.test(node.nodeType)) out.push("\n");
21 | }
22 | }
23 |
24 | CodeMirror.colorize = function(collection, defaultMode) {
25 | if (!collection) collection = document.body.getElementsByTagName("pre");
26 |
27 | for (var i = 0; i < collection.length; ++i) {
28 | var node = collection[i];
29 | var mode = node.getAttribute("data-lang") || defaultMode;
30 | if (!mode) continue;
31 |
32 | var text = [];
33 | textContent(node, text);
34 | node.innerHTML = "";
35 | CodeMirror.runMode(text.join(""), mode, node);
36 |
37 | node.className += " cm-s-default";
38 | }
39 | };
40 | });
41 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/mbox/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: mbox mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | mbox mode
27 |
38 |
41 |
42 | MIME types defined: application/mbox.
43 |
44 |
45 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/cypher/test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function() {
5 | var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "cypher");
6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
7 |
8 | MT("unbalancedDoubledQuotedString",
9 | "[string \"a'b\"][variable c]");
10 |
11 | MT("unbalancedSingleQuotedString",
12 | "[string 'a\"b'][variable c]");
13 |
14 | MT("doubleQuotedString",
15 | "[string \"a\"][variable b]");
16 |
17 | MT("singleQuotedString",
18 | "[string 'a'][variable b]");
19 |
20 | MT("single attribute (with content)",
21 | "[node {][atom a:][string 'a'][node }]");
22 |
23 | MT("multiple attribute, singleQuotedString (with content)",
24 | "[node {][atom a:][string 'a'][node ,][atom b:][string 'b'][node }]");
25 |
26 | MT("multiple attribute, doubleQuotedString (with content)",
27 | "[node {][atom a:][string \"a\"][node ,][atom b:][string \"b\"][node }]");
28 |
29 | MT("single attribute (without content)",
30 | "[node {][atom a:][string 'a'][node }]");
31 |
32 | MT("multiple attribute, singleQuotedString (without content)",
33 | "[node {][atom a:][string ''][node ,][atom b:][string ''][node }]");
34 |
35 | MT("multiple attribute, doubleQuotedString (without content)",
36 | "[node {][atom a:][string \"\"][node ,][atom b:][string \"\"][node }]");
37 | })();
38 |
--------------------------------------------------------------------------------
/tdxStock/helpers.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 |
4 | from .settings import BASE_DIR
5 |
6 |
7 | def is_json_stringify(v):
8 | try:
9 | json.loads(v)
10 | except ValueError:
11 | return False
12 | return True
13 |
14 |
15 | def is_number(value):
16 | try:
17 | value + 1
18 | except TypeError:
19 | return False
20 | else:
21 | return True
22 |
23 |
24 | def is_number_like(value):
25 | try:
26 | int(value)
27 | except ValueError:
28 | return False
29 | else:
30 | return True
31 |
32 |
33 | def str_fix_null(value):
34 | if value is None:
35 | value = ''
36 | return value
37 |
38 |
39 | def dict_merge(target: dict, origin: dict):
40 | """ 嵌套字典合并 """
41 | for key in origin.keys():
42 | if isinstance(target.get(key), dict) and isinstance(origin[key], dict):
43 | dict_merge(target[key], origin[key])
44 | else:
45 | target[key] = origin[key]
46 |
47 |
48 | def read_cookie(name):
49 | path = os.path.join(os.path.join(BASE_DIR, 'storage/cookies'), name)
50 | with open(path, 'r', encoding="utf-8") as f:
51 | cookie_str = f.readline()
52 |
53 | return string2dict(cookie_str)
54 |
55 |
56 | def string2dict(string, eq='=', split=';'):
57 | result = {}
58 | for item in string.split(split):
59 | pos = item.find(eq)
60 | key = item[:pos].strip()
61 | value = item[pos + len(eq):]
62 | result[key] = value
63 |
64 | return result
65 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/lint/json-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | // Depends on jsonlint.js from https://github.com/zaach/jsonlint
5 |
6 | // declare global: jsonlint
7 |
8 | (function(mod) {
9 | if (typeof exports == "object" && typeof module == "object") // CommonJS
10 | mod(require("../../lib/codemirror"));
11 | else if (typeof define == "function" && define.amd) // AMD
12 | define(["../../lib/codemirror"], mod);
13 | else // Plain browser env
14 | mod(CodeMirror);
15 | })(function(CodeMirror) {
16 | "use strict";
17 |
18 | CodeMirror.registerHelper("lint", "json", function(text) {
19 | var found = [];
20 | if (!window.jsonlint) {
21 | if (window.console) {
22 | window.console.error("Error: window.jsonlint not defined, CodeMirror JSON linting cannot run.");
23 | }
24 | return found;
25 | }
26 | // for jsonlint's web dist jsonlint is exported as an object with a single property parser, of which parseError
27 | // is a subproperty
28 | var jsonlint = window.jsonlint.parser || window.jsonlint
29 | jsonlint.parseError = function(str, hash) {
30 | var loc = hash.loc;
31 | found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
32 | to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
33 | message: str});
34 | };
35 | try { jsonlint.parse(text); }
36 | catch(e) {}
37 | return found;
38 | });
39 |
40 | });
41 |
--------------------------------------------------------------------------------
/templates/wiki/concept_detail.html:
--------------------------------------------------------------------------------
1 | {% extends '_layout/base.html' %}
2 | {% load static %}
3 | {% block title %}{{ object.name }}{% endblock %}
4 |
5 | {% block header_css %}
6 |
7 | {% endblock %}
8 |
9 | {% block content %}
10 |
11 |

12 |
13 |
{{ SITE_NAME }}
14 | Since 2019
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
30 |
31 | {{ object.description_html|safe }}
32 |
33 |
36 |
37 | {% endblock %}
38 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/asciiarmor/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: ASCII Armor (PGP) mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | ASCII Armor (PGP) mode
27 |
36 |
37 |
42 |
43 | MIME types
44 | defined: application/pgp, application/pgp-encrypted, application/pgp-keys, application/pgp-signature
45 |
46 |
47 |
--------------------------------------------------------------------------------
/frontend/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Message } from 'element-ui'
3 |
4 | // create an axios instance
5 | const service = axios.create({
6 | baseURL: process.env.VUE_APP_BASE_API,
7 | withCredentials: true, // send cookies when cross-domain requests
8 | timeout: 30000
9 | })
10 |
11 | // request interceptor
12 | service.interceptors.request.use(
13 | config => {
14 | // do something before request is sent
15 | config.headers['X-Requested-With'] = 'XMLHttpRequest'
16 | return config
17 | },
18 | error => {
19 | // do something with request error
20 | if (process.env.NODE_ENV === 'development') {
21 | console.log(error) // for debug
22 | }
23 | return Promise.reject(error)
24 | }
25 | )
26 |
27 | // response interceptor
28 | service.interceptors.response.use(
29 | /**
30 | * If you want to get http information such as headers or status
31 | * Please return response => response
32 | */
33 | response => response.data,
34 | error => {
35 | if (process.env.NODE_ENV === 'development') {
36 | console.log('err' + error) // for debug
37 | }
38 | let $message
39 |
40 | if (error.response) {
41 | const data = error.response.data
42 | $message = data.message || (data.data && data.data.message) || error.message
43 | } else {
44 | $message = error.message
45 | }
46 |
47 | Message({
48 | message: $message,
49 | type: 'error',
50 | duration: 5 * 1000
51 | })
52 | return Promise.reject(error)
53 | }
54 | )
55 |
56 | export default service
57 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/twig/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Twig mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Twig mode
27 |
40 |
45 |
46 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/bespin.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Name: Bespin
4 | Author: Mozilla / Jan T. Sott
5 |
6 | CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
7 | Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
8 |
9 | */
10 |
11 | .cm-s-bespin.CodeMirror {background: #28211c; color: #9d9b97;}
12 | .cm-s-bespin div.CodeMirror-selected {background: #36312e !important;}
13 | .cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;}
14 | .cm-s-bespin .CodeMirror-linenumber {color: #666666;}
15 | .cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;}
16 |
17 | .cm-s-bespin span.cm-comment {color: #937121;}
18 | .cm-s-bespin span.cm-atom {color: #9b859d;}
19 | .cm-s-bespin span.cm-number {color: #9b859d;}
20 |
21 | .cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;}
22 | .cm-s-bespin span.cm-keyword {color: #cf6a4c;}
23 | .cm-s-bespin span.cm-string {color: #f9ee98;}
24 |
25 | .cm-s-bespin span.cm-variable {color: #54be0d;}
26 | .cm-s-bespin span.cm-variable-2 {color: #5ea6ea;}
27 | .cm-s-bespin span.cm-def {color: #cf7d34;}
28 | .cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;}
29 | .cm-s-bespin span.cm-bracket {color: #9d9b97;}
30 | .cm-s-bespin span.cm-tag {color: #cf6a4c;}
31 | .cm-s-bespin span.cm-link {color: #9b859d;}
32 |
33 | .cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
34 | .cm-s-bespin .CodeMirror-activeline-background { background: #404040; }
35 |
--------------------------------------------------------------------------------
/frontend/src/bootstarp.js:
--------------------------------------------------------------------------------
1 | import NProgress from 'nprogress' // progress bar
2 | import 'nprogress/nprogress.css' // progress bar style
3 | import router from './router'
4 | import store from './store'
5 | import getPageTitle from './utils/getPageTitle'
6 |
7 | NProgress.configure({ showSpinner: false }) // NProgress Configuration
8 |
9 | router.beforeEach(async (to, from, next) => {
10 | // start progress bar
11 | NProgress.start()
12 |
13 | // set page title
14 | document.title = getPageTitle(to.meta.title)
15 |
16 | try {
17 | // init store data
18 | if (store.state.basedata.reportTypes.data.length === 0) {
19 | await store.dispatch('basedata/loadReportTypes')
20 | await store.dispatch('basedata/loadAccountingSubjects')
21 | }
22 |
23 | if (store.state.basedata.territories.data.length === 0) {
24 | await store.dispatch('basedata/loadTerritories', { omit: 'stocks' })
25 | }
26 |
27 | if (store.state.basedata.sections.data.length === 0) {
28 | await store.dispatch('basedata/loadSections', { omit: 'stocks' })
29 | }
30 |
31 | if (store.state.basedata.concepts.data.length === 0) {
32 | await store.dispatch('basedata/loadConcepts', { omit: 'stocks' })
33 | }
34 |
35 | if (store.state.basedata.industries.data.length === 0) {
36 | await store.dispatch('basedata/loadIndustries', { omit: 'stocks' })
37 | }
38 | } catch (error) {
39 | console.log(error)
40 | NProgress.done()
41 | }
42 |
43 | next()
44 | })
45 |
46 | router.afterEach(() => {
47 | // finish progress bar
48 | NProgress.done()
49 | })
50 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/spreadsheet/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Spreadsheet mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 | Spreadsheet mode
28 |
29 |
30 |
37 |
38 | MIME types defined: text/x-spreadsheet.
39 |
40 | The Spreadsheet Mode
41 | Created by Robert Plummer
42 |
43 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/http/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: HTTP mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | HTTP mode
27 |
28 |
29 |
39 |
40 |
43 |
44 | MIME types defined: message/http.
45 |
46 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/isotope.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Name: Isotope
4 | Author: David Desandro / Jan T. Sott
5 |
6 | CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
7 | Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
8 |
9 | */
10 |
11 | .cm-s-isotope.CodeMirror {background: #000000; color: #e0e0e0;}
12 | .cm-s-isotope div.CodeMirror-selected {background: #404040 !important;}
13 | .cm-s-isotope .CodeMirror-gutters {background: #000000; border-right: 0px;}
14 | .cm-s-isotope .CodeMirror-linenumber {color: #808080;}
15 | .cm-s-isotope .CodeMirror-cursor {border-left: 1px solid #c0c0c0 !important;}
16 |
17 | .cm-s-isotope span.cm-comment {color: #3300ff;}
18 | .cm-s-isotope span.cm-atom {color: #cc00ff;}
19 | .cm-s-isotope span.cm-number {color: #cc00ff;}
20 |
21 | .cm-s-isotope span.cm-property, .cm-s-isotope span.cm-attribute {color: #33ff00;}
22 | .cm-s-isotope span.cm-keyword {color: #ff0000;}
23 | .cm-s-isotope span.cm-string {color: #ff0099;}
24 |
25 | .cm-s-isotope span.cm-variable {color: #33ff00;}
26 | .cm-s-isotope span.cm-variable-2 {color: #0066ff;}
27 | .cm-s-isotope span.cm-def {color: #ff9900;}
28 | .cm-s-isotope span.cm-error {background: #ff0000; color: #c0c0c0;}
29 | .cm-s-isotope span.cm-bracket {color: #e0e0e0;}
30 | .cm-s-isotope span.cm-tag {color: #ff0000;}
31 | .cm-s-isotope span.cm-link {color: #cc00ff;}
32 |
33 | .cm-s-isotope .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
34 | .cm-s-isotope .CodeMirror-activeline-background { background: #202020; }
35 |
--------------------------------------------------------------------------------
/frontend/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import Layout from '../layout/index.vue'
4 |
5 | Vue.use(VueRouter)
6 |
7 | const routes = [
8 | {
9 | path: '/',
10 | component: Layout,
11 | redirect: '/industries',
12 | children: [
13 | {
14 | path: 'industries',
15 | name: 'IndustryList',
16 | component: () => import('../views/IndustryList'),
17 | meta: { title: '行业列表' }
18 | },
19 | {
20 | path: 'industries/:id',
21 | name: 'Industry',
22 | props: true,
23 | component: () => import('../views/Industry'),
24 | meta: { title: '行业' }
25 | },
26 | {
27 | path: 'reports/:id',
28 | name: 'Report',
29 | props: true,
30 | component: () => import('../views/Report'),
31 | meta: { title: '报表' }
32 | },
33 | {
34 | path: 'compare',
35 | name: 'Compare',
36 | component: () => import('../views/Compare'),
37 | meta: { title: '对比' }
38 | }
39 | ]
40 | },
41 | // {
42 | // path: '/about',
43 | // name: 'About',
44 | // route level code-splitting
45 | // this generates a separate chunk (about.[hash].js) for this route
46 | // which is lazy-loaded when the route is visited.
47 | // component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
48 | // }
49 |
50 | // 404 page must be placed at the end !!!
51 | { path: '*', component: () => import('../views/404') }
52 | ]
53 |
54 | const router = new VueRouter({
55 | routes
56 | })
57 |
58 | export default router
59 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/haskell-literate/haskell-literate.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function (mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"), require("../haskell/haskell"))
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror", "../haskell/haskell"], mod)
9 | else // Plain browser env
10 | mod(CodeMirror)
11 | })(function (CodeMirror) {
12 | "use strict"
13 |
14 | CodeMirror.defineMode("haskell-literate", function (config, parserConfig) {
15 | var baseMode = CodeMirror.getMode(config, (parserConfig && parserConfig.base) || "haskell")
16 |
17 | return {
18 | startState: function () {
19 | return {
20 | inCode: false,
21 | baseState: CodeMirror.startState(baseMode)
22 | }
23 | },
24 | token: function (stream, state) {
25 | if (stream.sol()) {
26 | if (state.inCode = stream.eat(">"))
27 | return "meta"
28 | }
29 | if (state.inCode) {
30 | return baseMode.token(stream, state.baseState)
31 | } else {
32 | stream.skipToEnd()
33 | return "comment"
34 | }
35 | },
36 | innerMode: function (state) {
37 | return state.inCode ? {state: state.baseState, mode: baseMode} : null
38 | }
39 | }
40 | }, "haskell")
41 |
42 | CodeMirror.defineMIME("text/x-literate-haskell", "haskell-literate")
43 | });
44 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/oz/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Oz mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
26 |
27 |
28 | Oz mode
29 |
50 | MIME type defined: text/x-oz.
51 |
52 |
59 |
60 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/solr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Solr mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
20 |
33 |
34 |
35 | Solr mode
36 |
37 |
38 |
47 |
48 |
49 |
55 |
56 | MIME types defined: text/x-solr.
57 |
58 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/hopscotch.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Name: Hopscotch
4 | Author: Jan T. Sott
5 |
6 | CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
7 | Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
8 |
9 | */
10 |
11 | .cm-s-hopscotch.CodeMirror {background: #322931; color: #d5d3d5;}
12 | .cm-s-hopscotch div.CodeMirror-selected {background: #433b42 !important;}
13 | .cm-s-hopscotch .CodeMirror-gutters {background: #322931; border-right: 0px;}
14 | .cm-s-hopscotch .CodeMirror-linenumber {color: #797379;}
15 | .cm-s-hopscotch .CodeMirror-cursor {border-left: 1px solid #989498 !important;}
16 |
17 | .cm-s-hopscotch span.cm-comment {color: #b33508;}
18 | .cm-s-hopscotch span.cm-atom {color: #c85e7c;}
19 | .cm-s-hopscotch span.cm-number {color: #c85e7c;}
20 |
21 | .cm-s-hopscotch span.cm-property, .cm-s-hopscotch span.cm-attribute {color: #8fc13e;}
22 | .cm-s-hopscotch span.cm-keyword {color: #dd464c;}
23 | .cm-s-hopscotch span.cm-string {color: #fdcc59;}
24 |
25 | .cm-s-hopscotch span.cm-variable {color: #8fc13e;}
26 | .cm-s-hopscotch span.cm-variable-2 {color: #1290bf;}
27 | .cm-s-hopscotch span.cm-def {color: #fd8b19;}
28 | .cm-s-hopscotch span.cm-error {background: #dd464c; color: #989498;}
29 | .cm-s-hopscotch span.cm-bracket {color: #d5d3d5;}
30 | .cm-s-hopscotch span.cm-tag {color: #dd464c;}
31 | .cm-s-hopscotch span.cm-link {color: #c85e7c;}
32 |
33 | .cm-s-hopscotch .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
34 | .cm-s-hopscotch .CodeMirror-activeline-background { background: #302020; }
35 |
--------------------------------------------------------------------------------
/basedata/management/commands/update_last_report_date.py:
--------------------------------------------------------------------------------
1 | from django.core.management import BaseCommand # , CommandError
2 | from django.db.models import Max
3 |
4 | from basedata.models import Report, ReportType, Stock, XReport
5 | from tdxStock.helpers import dict_merge
6 |
7 |
8 | # 在一个 app 的 management/commands 目录下
9 | # 内部需要定义一个 Command 类并继承 BaseCommand 类或其子类
10 | # python manage.py update_last_report_date --single
11 | class Command(BaseCommand):
12 | help = '更新股票的后报表期字段'
13 |
14 | # add_arguments 函数是用来接收可选参数的
15 | def add_arguments(self, parser):
16 | parser.add_argument('--single',
17 | action='store_true',
18 | dest='single',
19 | default=False,
20 | help='是否单季度报告')
21 |
22 | def handle(self, *args, **options):
23 | if options['single']:
24 | report_model = Report
25 | key = "last_report_date"
26 | else:
27 | report_model = XReport
28 | key = "last_all_report_date"
29 |
30 | reports = report_model.objects.values('stock_id', 'report_type_id').annotate(last_date=Max('report_date'))
31 | for report in reports:
32 | stock = Stock.objects.get(pk=report['stock_id'])
33 | report_type = ReportType.objects.get(pk=report['report_type_id'])
34 |
35 | metas = stock.metas if stock.metas else {}
36 | dict_merge(metas, {report_type.slug: {key: report['last_date']}})
37 | stock.metas = metas
38 |
39 | stock.save()
40 |
41 | self.stdout.write(self.style.SUCCESS('success!'))
42 |
--------------------------------------------------------------------------------
/public/static/editor.md/css/editormd.logo.min.css:
--------------------------------------------------------------------------------
1 | /*! Editor.md v1.5.0 | editormd.logo.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */
2 | /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(.../fonts/editormd-logo.eot?#iefix-5y8q6h)format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h)format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h)format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon)format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"\e1987"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196F3}
--------------------------------------------------------------------------------
/frontend/src/api/index.js:
--------------------------------------------------------------------------------
1 | import RestApi from '../utils/restapi'
2 | import request from '../utils/request'
3 |
4 | /**
5 | * 获取股票列表和查看单个股票
6 | */
7 | export const stocksApi = new RestApi({
8 | url: '/stocks/',
9 | methods: ['list', 'show']
10 | })
11 |
12 | /**
13 | * 行业信息接口
14 | */
15 | export const industriesApi = new RestApi({
16 | url: '/industries/',
17 | methods: ['list', 'show']
18 | })
19 |
20 | /**
21 | * 概念接口
22 | */
23 | export const conceptsApi = new RestApi({
24 | url: '/concepts/',
25 | methods: ['list', 'show']
26 | })
27 |
28 | /**
29 | * 板块接口
30 | */
31 | export const sectionsApi = new RestApi({
32 | url: '/sections/',
33 | methods: ['list', 'show']
34 | })
35 |
36 | /**
37 | * 地域接口
38 | */
39 | export const territoriesApi = new RestApi({
40 | url: '/territories/',
41 | methods: ['list', 'show']
42 | })
43 |
44 | /**
45 | * 报告类型接口
46 | */
47 | export const reportTypesApi = new RestApi({
48 | url: '/report-types/',
49 | methods: ['list', 'show']
50 | })
51 |
52 | /**
53 | * 会计科目接口
54 | */
55 | export const subjectsApi = new RestApi({
56 | url: '/subjects/',
57 | methods: ['list', 'show']
58 | })
59 |
60 | /**
61 | * 单季报接口
62 | * @param {object} params
63 | */
64 | export function get_report (params) {
65 | return request.get('/reports/', { params })
66 | }
67 |
68 | /**
69 | * 报告期季报接口
70 | * @param {object} params
71 | */
72 | export function get_xreport (params) {
73 | return request.get('/xreports/', { params })
74 | }
75 |
76 | /**
77 | * 比较信息接口
78 | * @param {object} params
79 | */
80 | export function compare_stock (params) {
81 | return request.get('/compare/', { params })
82 | }
83 |
--------------------------------------------------------------------------------
/tdxStock/abstract_models.py:
--------------------------------------------------------------------------------
1 | from django.db import connection, models
2 | from django.utils import timezone
3 |
4 |
5 | class Timestamp(models.Model):
6 | created_at = models.DateTimeField("创建时间", null=True, editable=False, default=timezone.now)
7 | updated_at = models.DateTimeField("更新时间", null=True, editable=False,
8 | auto_now=True) # 调用 save() 会自动更新, 调用 objects.update 不会更新
9 |
10 | class Meta:
11 | abstract = True
12 |
13 |
14 | class DynamicModel(object):
15 | _instance = dict()
16 | _tables = [table_info.name for table_info in connection.introspection.get_table_list(connection.cursor())]
17 |
18 | def __new__(cls, base_cls, db_table_suffix):
19 | """
20 | 创建类
21 | :param base_cls: 模型基类, 要在基类 Meta 中定义 abstract = True
22 | :param db_table_suffix: 表后缀
23 | :return new_model_cls: 类
24 | """
25 | new_cls_name = f"{base_cls.__name__}_{db_table_suffix}"
26 | if new_cls_name not in cls._instance:
27 | new_db_table = "{}_{}".format(base_cls._meta.db_table, db_table_suffix) # noqa
28 | model_cls = type(new_cls_name, (base_cls,), {'__module__': base_cls.__module__})
29 | model_cls._meta.db_table = new_db_table # noqa
30 | cls._instance[new_cls_name] = model_cls
31 |
32 | # 不存在表则创建表
33 | if new_db_table not in cls._tables:
34 | with connection.schema_editor() as schema_editor:
35 | schema_editor.create_model(model_cls)
36 | cls._tables.append(new_db_table)
37 |
38 | return cls._instance[new_cls_name]
39 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/z80/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Z80 assembly mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Z80 assembly mode
27 |
28 |
29 |
45 |
46 |
51 |
52 | MIME types defined: text/x-z80, text/x-ez80.
53 |
54 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/ecl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: ECL mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | ECL mode
27 |
45 |
48 |
49 | Based on CodeMirror's clike mode. For more information see HPCC Systems web site.
50 | MIME types defined: text/x-ecl.
51 |
52 |
53 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/railscasts.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Name: Railscasts
4 | Author: Ryan Bates (http://railscasts.com)
5 |
6 | CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
7 | Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
8 |
9 | */
10 |
11 | .cm-s-railscasts.CodeMirror {background: #2b2b2b; color: #f4f1ed;}
12 | .cm-s-railscasts div.CodeMirror-selected {background: #272935 !important;}
13 | .cm-s-railscasts .CodeMirror-gutters {background: #2b2b2b; border-right: 0px;}
14 | .cm-s-railscasts .CodeMirror-linenumber {color: #5a647e;}
15 | .cm-s-railscasts .CodeMirror-cursor {border-left: 1px solid #d4cfc9 !important;}
16 |
17 | .cm-s-railscasts span.cm-comment {color: #bc9458;}
18 | .cm-s-railscasts span.cm-atom {color: #b6b3eb;}
19 | .cm-s-railscasts span.cm-number {color: #b6b3eb;}
20 |
21 | .cm-s-railscasts span.cm-property, .cm-s-railscasts span.cm-attribute {color: #a5c261;}
22 | .cm-s-railscasts span.cm-keyword {color: #da4939;}
23 | .cm-s-railscasts span.cm-string {color: #ffc66d;}
24 |
25 | .cm-s-railscasts span.cm-variable {color: #a5c261;}
26 | .cm-s-railscasts span.cm-variable-2 {color: #6d9cbe;}
27 | .cm-s-railscasts span.cm-def {color: #cc7833;}
28 | .cm-s-railscasts span.cm-error {background: #da4939; color: #d4cfc9;}
29 | .cm-s-railscasts span.cm-bracket {color: #f4f1ed;}
30 | .cm-s-railscasts span.cm-tag {color: #da4939;}
31 | .cm-s-railscasts span.cm-link {color: #b6b3eb;}
32 |
33 | .cm-s-railscasts .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
34 | .cm-s-railscasts .CodeMirror-activeline-background { background: #303040; }
35 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/scroll/simplescrollbars.css:
--------------------------------------------------------------------------------
1 | .CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {
2 | position: absolute;
3 | background: #ccc;
4 | -moz-box-sizing: border-box;
5 | box-sizing: border-box;
6 | border: 1px solid #bbb;
7 | border-radius: 2px;
8 | }
9 |
10 | .CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical {
11 | position: absolute;
12 | z-index: 6;
13 | background: #eee;
14 | }
15 |
16 | .CodeMirror-simplescroll-horizontal {
17 | bottom: 0; left: 0;
18 | height: 8px;
19 | }
20 | .CodeMirror-simplescroll-horizontal div {
21 | bottom: 0;
22 | height: 100%;
23 | }
24 |
25 | .CodeMirror-simplescroll-vertical {
26 | right: 0; top: 0;
27 | width: 8px;
28 | }
29 | .CodeMirror-simplescroll-vertical div {
30 | right: 0;
31 | width: 100%;
32 | }
33 |
34 |
35 | .CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler {
36 | display: none;
37 | }
38 |
39 | .CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
40 | position: absolute;
41 | background: #bcd;
42 | border-radius: 3px;
43 | }
44 |
45 | .CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical {
46 | position: absolute;
47 | z-index: 6;
48 | }
49 |
50 | .CodeMirror-overlayscroll-horizontal {
51 | bottom: 0; left: 0;
52 | height: 6px;
53 | }
54 | .CodeMirror-overlayscroll-horizontal div {
55 | bottom: 0;
56 | height: 100%;
57 | }
58 |
59 | .CodeMirror-overlayscroll-vertical {
60 | right: 0; top: 0;
61 | width: 6px;
62 | }
63 | .CodeMirror-overlayscroll-vertical div {
64 | right: 0;
65 | width: 100%;
66 | }
67 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/display/fullscreen.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
15 | if (old == CodeMirror.Init) old = false;
16 | if (!old == !val) return;
17 | if (val) setFullscreen(cm);
18 | else setNormal(cm);
19 | });
20 |
21 | function setFullscreen(cm) {
22 | var wrap = cm.getWrapperElement();
23 | cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
24 | width: wrap.style.width, height: wrap.style.height};
25 | wrap.style.width = "";
26 | wrap.style.height = "auto";
27 | wrap.className += " CodeMirror-fullscreen";
28 | document.documentElement.style.overflow = "hidden";
29 | cm.refresh();
30 | }
31 |
32 | function setNormal(cm) {
33 | var wrap = cm.getWrapperElement();
34 | wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
35 | document.documentElement.style.overflow = "";
36 | var info = cm.state.fullScreenRestore;
37 | wrap.style.width = info.width; wrap.style.height = info.height;
38 | window.scrollTo(info.scrollLeft, info.scrollTop);
39 | cm.refresh();
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/vb/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: VB.NET mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
30 |
31 |
32 | VB.NET mode
33 |
34 |
46 |
47 | MIME type defined: text/x-vb.
48 |
49 |
50 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/lint/coffeescript-lint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | // Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js
5 |
6 | // declare global: coffeelint
7 |
8 | (function(mod) {
9 | if (typeof exports == "object" && typeof module == "object") // CommonJS
10 | mod(require("../../lib/codemirror"));
11 | else if (typeof define == "function" && define.amd) // AMD
12 | define(["../../lib/codemirror"], mod);
13 | else // Plain browser env
14 | mod(CodeMirror);
15 | })(function(CodeMirror) {
16 | "use strict";
17 |
18 | CodeMirror.registerHelper("lint", "coffeescript", function(text) {
19 | var found = [];
20 | if (!window.coffeelint) {
21 | if (window.console) {
22 | window.console.error("Error: window.coffeelint not defined, CodeMirror CoffeeScript linting cannot run.");
23 | }
24 | return found;
25 | }
26 | var parseError = function(err) {
27 | var loc = err.lineNumber;
28 | found.push({from: CodeMirror.Pos(loc-1, 0),
29 | to: CodeMirror.Pos(loc, 0),
30 | severity: err.level,
31 | message: err.message});
32 | };
33 | try {
34 | var res = coffeelint.lint(text);
35 | for(var i = 0; i < res.length; i++) {
36 | parseError(res[i]);
37 | }
38 | } catch(e) {
39 | found.push({from: CodeMirror.Pos(e.location.first_line, 0),
40 | to: CodeMirror.Pos(e.location.last_line, e.location.last_column),
41 | severity: 'error',
42 | message: e.message});
43 | }
44 | return found;
45 | });
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/pascal/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Pascal mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Pascal mode
27 |
28 |
29 |
52 |
53 |
59 |
60 | MIME types defined: text/x-pascal.
61 |
62 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/pig/index.html:
--------------------------------------------------------------------------------
1 |
2 | CodeMirror: Pig Latin mode
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
23 |
24 |
25 | Pig Latin mode
26 |
38 |
39 |
46 |
47 |
48 | Simple mode that handles Pig Latin language.
49 |
50 |
51 | MIME type defined: text/x-pig
52 | (PIG code)
53 |
54 |
--------------------------------------------------------------------------------
/tdxStock/urls.py:
--------------------------------------------------------------------------------
1 | """tdxStock URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/3.1/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.urls import include, path
14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 | """
16 | from django.conf import settings
17 | from django.contrib import admin
18 | from django.conf.urls.static import static
19 | from django.urls import path, include, re_path
20 | from django.views.generic.base import RedirectView
21 |
22 | from tdxStock.api import router
23 |
24 | admin.AdminSite.site_title = settings.SITE_NAME
25 | admin.AdminSite.site_header = f"{settings.SITE_NAME} 管理"
26 |
27 | urlpatterns = [
28 | path('', RedirectView.as_view(url='/wiki/'), name='index'),
29 | path('wiki/', include('wiki.urls')),
30 | path('account/', include('account.urls')),
31 | path('admin/', admin.site.urls),
32 | path('api/', include(router.urls)),
33 | path('api/', include('basedata.urls')),
34 | ]
35 |
36 | if settings.DEBUG:
37 | import debug_toolbar
38 |
39 | # Server statics and uploaded media
40 | urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))
41 |
42 | # debug_toolbar
43 | urlpatterns.extend([
44 | re_path(r'^__debug__/', include(debug_toolbar.urls)),
45 | ])
46 |
--------------------------------------------------------------------------------
/templates/_layout/nav.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/static/editor.md/plugins/test-plugin/test-plugin.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Test plugin for Editor.md
3 | *
4 | * @file test-plugin.js
5 | * @author pandao
6 | * @version 1.2.0
7 | * @updateTime 2015-03-07
8 | * {@link https://github.com/pandao/editor.md}
9 | * @license MIT
10 | */
11 |
12 | (function() {
13 |
14 | var factory = function (exports) {
15 |
16 | var $ = jQuery; // if using module loader(Require.js/Sea.js).
17 |
18 | exports.testPlugin = function(){
19 | alert("testPlugin");
20 | };
21 |
22 | exports.fn.testPluginMethodA = function() {
23 | /*
24 | var _this = this; // this == the current instance object of Editor.md
25 | var lang = _this.lang;
26 | var settings = _this.settings;
27 | var editor = this.editor;
28 | var cursor = cm.getCursor();
29 | var selection = cm.getSelection();
30 | var classPrefix = this.classPrefix;
31 |
32 | cm.focus();
33 | */
34 | //....
35 |
36 | alert("testPluginMethodA");
37 | };
38 |
39 | };
40 |
41 | // CommonJS/Node.js
42 | if (typeof require === "function" && typeof exports === "object" && typeof module === "object")
43 | {
44 | module.exports = factory;
45 | }
46 | else if (typeof define === "function") // AMD/CMD/Sea.js
47 | {
48 | if (define.amd) { // for Require.js
49 |
50 | define(["editormd"], function(editormd) {
51 | factory(editormd);
52 | });
53 |
54 | } else { // for Sea.js
55 | define(function(require) {
56 | var editormd = require("./../../editormd");
57 | factory(editormd);
58 | });
59 | }
60 | }
61 | else
62 | {
63 | factory(window.editormd);
64 | }
65 |
66 | })();
67 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/vbscript/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: VBScript mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | VBScript mode
27 |
28 |
29 |
46 |
47 |
53 |
54 | MIME types defined: text/vbscript.
55 |
56 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/display/autorefresh.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"))
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod)
9 | else // Plain browser env
10 | mod(CodeMirror)
11 | })(function(CodeMirror) {
12 | "use strict"
13 |
14 | CodeMirror.defineOption("autoRefresh", false, function(cm, val) {
15 | if (cm.state.autoRefresh) {
16 | stopListening(cm, cm.state.autoRefresh)
17 | cm.state.autoRefresh = null
18 | }
19 | if (val && cm.display.wrapper.offsetHeight == 0)
20 | startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250})
21 | })
22 |
23 | function startListening(cm, state) {
24 | function check() {
25 | if (cm.display.wrapper.offsetHeight) {
26 | stopListening(cm, state)
27 | if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight)
28 | cm.refresh()
29 | } else {
30 | state.timeout = setTimeout(check, state.delay)
31 | }
32 | }
33 | state.timeout = setTimeout(check, state.delay)
34 | state.hurry = function() {
35 | clearTimeout(state.timeout)
36 | state.timeout = setTimeout(check, 50)
37 | }
38 | CodeMirror.on(window, "mouseup", state.hurry)
39 | CodeMirror.on(window, "keyup", state.hurry)
40 | }
41 |
42 | function stopListening(_cm, state) {
43 | clearTimeout(state.timeout)
44 | CodeMirror.off(window, "mouseup", state.hurry)
45 | CodeMirror.off(window, "keyup", state.hurry)
46 | }
47 | });
48 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/turtle/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Turtle mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 | Turtle mode
28 |
42 |
48 |
49 | MIME types defined: text/turtle.
50 |
51 |
52 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/gherkin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Gherkin mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Gherkin mode
27 |
42 |
45 |
46 | MIME types defined: text/x-feature.
47 |
48 |
49 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/properties/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Properties files mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Properties files mode
27 |
46 |
49 |
50 | MIME types defined: text/x-properties,
51 | text/x-ini.
52 |
53 |
54 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/scroll/scrollpastend.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) {
15 | if (old && old != CodeMirror.Init) {
16 | cm.off("change", onChange);
17 | cm.off("refresh", updateBottomMargin);
18 | cm.display.lineSpace.parentNode.style.paddingBottom = "";
19 | cm.state.scrollPastEndPadding = null;
20 | }
21 | if (val) {
22 | cm.on("change", onChange);
23 | cm.on("refresh", updateBottomMargin);
24 | updateBottomMargin(cm);
25 | }
26 | });
27 |
28 | function onChange(cm, change) {
29 | if (CodeMirror.changeEnd(change).line == cm.lastLine())
30 | updateBottomMargin(cm);
31 | }
32 |
33 | function updateBottomMargin(cm) {
34 | var padding = "";
35 | if (cm.lineCount() > 1) {
36 | var totalH = cm.display.scroller.clientHeight - 30,
37 | lastLineH = cm.getLineHandle(cm.lastLine()).height;
38 | padding = (totalH - lastLineH) + "px";
39 | }
40 | if (cm.state.scrollPastEndPadding != padding) {
41 | cm.state.scrollPastEndPadding = padding;
42 | cm.display.lineSpace.parentNode.style.paddingBottom = padding;
43 | cm.off("refresh", updateBottomMargin);
44 | cm.setSize();
45 | cm.on("refresh", updateBottomMargin);
46 | }
47 | }
48 | });
49 |
--------------------------------------------------------------------------------
/frontend/src/utils/restapi.js:
--------------------------------------------------------------------------------
1 | import request from './request'
2 |
3 | export default class RestApi {
4 | constructor (config) {
5 | const options = {
6 | url: '',
7 | subPath: '',
8 | methods: ['list', 'store', 'update', 'destroy', 'show']
9 | }
10 | this.config = Object.assign({}, options, config)
11 | this.url = this.config.url
12 | if (this.config.subPath) {
13 | if (!this.url.endsWith('/')) {
14 | this.url = `${this.url}/`
15 | }
16 | this.url = `${this.url}${this.config.subPath}`
17 | }
18 | this.methods = this.config.methods
19 | this.applyApi()
20 | }
21 |
22 | applyApi () {
23 | if (this.methods.includes('list')) {
24 | this.list = (config) => {
25 | return request.get(this.url, config)
26 | }
27 | }
28 |
29 | if (this.methods.includes('store')) {
30 | this.store = (obj, config) => {
31 | return request.post(this.url, obj, config)
32 | }
33 | }
34 |
35 | if (this.methods.includes('update')) {
36 | this.update = (id, obj, config) => {
37 | if (!this.url.endsWith('/')) {
38 | this.url = `${this.url}/`
39 | }
40 | return request.patch(`${this.url}${id}/`, obj, config)
41 | }
42 | }
43 |
44 | if (this.methods.includes('destroy')) {
45 | this.destroy = (id, config) => {
46 | if (!this.url.endsWith('/')) {
47 | this.url = `${this.url}/`
48 | }
49 | return request.delete(`${this.url}${id}/`, config)
50 | }
51 | }
52 |
53 | if (this.methods.includes('show')) {
54 | this.show = (id, config) => {
55 | if (!this.url.endsWith('/')) {
56 | this.url = `${this.url}/`
57 | }
58 | return request.get(`${this.url}${id}/`, config)
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/rust/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Rust mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 | Rust mode
28 |
29 |
30 |
53 |
54 |
62 |
63 | MIME types defined: text/x-rustsrc.
64 |
65 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/colorforth.css:
--------------------------------------------------------------------------------
1 | .cm-s-colorforth.CodeMirror { background: #000000; color: #f8f8f8; }
2 | .cm-s-colorforth .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
3 | .cm-s-colorforth .CodeMirror-guttermarker { color: #FFBD40; }
4 | .cm-s-colorforth .CodeMirror-guttermarker-subtle { color: #78846f; }
5 | .cm-s-colorforth .CodeMirror-linenumber { color: #bababa; }
6 | .cm-s-colorforth .CodeMirror-cursor { border-left: 1px solid white; }
7 |
8 | .cm-s-colorforth span.cm-comment { color: #ededed; }
9 | .cm-s-colorforth span.cm-def { color: #ff1c1c; font-weight:bold; }
10 | .cm-s-colorforth span.cm-keyword { color: #ffd900; }
11 | .cm-s-colorforth span.cm-builtin { color: #00d95a; }
12 | .cm-s-colorforth span.cm-variable { color: #73ff00; }
13 | .cm-s-colorforth span.cm-string { color: #007bff; }
14 | .cm-s-colorforth span.cm-number { color: #00c4ff; }
15 | .cm-s-colorforth span.cm-atom { color: #606060; }
16 |
17 | .cm-s-colorforth span.cm-variable-2 { color: #EEE; }
18 | .cm-s-colorforth span.cm-variable-3, .cm-s-colorforth span.cm-type { color: #DDD; }
19 | .cm-s-colorforth span.cm-property {}
20 | .cm-s-colorforth span.cm-operator {}
21 |
22 | .cm-s-colorforth span.cm-meta { color: yellow; }
23 | .cm-s-colorforth span.cm-qualifier { color: #FFF700; }
24 | .cm-s-colorforth span.cm-bracket { color: #cc7; }
25 | .cm-s-colorforth span.cm-tag { color: #FFBD40; }
26 | .cm-s-colorforth span.cm-attribute { color: #FFF700; }
27 | .cm-s-colorforth span.cm-error { color: #f00; }
28 |
29 | .cm-s-colorforth div.CodeMirror-selected { background: #333d53; }
30 |
31 | .cm-s-colorforth span.cm-compilation { background: rgba(255, 255, 255, 0.12); }
32 |
33 | .cm-s-colorforth .CodeMirror-activeline-background { background: #253540; }
34 |
--------------------------------------------------------------------------------
/frontend/src/utils/validate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} path
3 | * @returns {Boolean}
4 | */
5 | export function isExternal (path) {
6 | return /^(https?:|mailto:|tel:)/.test(path)
7 | }
8 |
9 | /* 合法uri */
10 | export function isURL (textval) {
11 | const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
12 | return urlregex.test(textval)
13 | }
14 |
15 | /* 小写字母 */
16 | export function isLowerCase (str) {
17 | const reg = /^[a-z]+$/
18 | return reg.test(str)
19 | }
20 |
21 | /* 大写字母 */
22 | export function isUpperCase (str) {
23 | const reg = /^[A-Z]+$/
24 | return reg.test(str)
25 | }
26 |
27 | /* 大小写字母 */
28 | export function isAlphabets (str) {
29 | const reg = /^[A-Za-z]+$/
30 | return reg.test(str)
31 | }
32 |
33 | /**
34 | * validate email
35 | * @param email
36 | * @returns {boolean}
37 | */
38 | export function isEmail (email) {
39 | const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
40 | return re.test(email)
41 | }
42 |
43 | /**
44 | * @param {string} str
45 | * @returns {Boolean}
46 | */
47 | export function isString (str) {
48 | if (typeof str === 'string' || str instanceof String) {
49 | return true
50 | }
51 | return false
52 | }
53 |
54 | /**
55 | * @param {Array} arg
56 | * @returns {Boolean}
57 | */
58 | export function isArray (arg) {
59 | if (typeof Array.isArray === 'undefined') {
60 | return Object.prototype.toString.call(arg) === '[object Array]'
61 | }
62 | return Array.isArray(arg)
63 | }
64 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/cobalt.css:
--------------------------------------------------------------------------------
1 | .cm-s-cobalt.CodeMirror { background: #002240; color: white; }
2 | .cm-s-cobalt div.CodeMirror-selected { background: #b36539; }
3 | .cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); }
4 | .cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); }
5 | .cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
6 | .cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; }
7 | .cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
8 | .cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; }
9 | .cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; }
10 |
11 | .cm-s-cobalt span.cm-comment { color: #08f; }
12 | .cm-s-cobalt span.cm-atom { color: #845dc4; }
13 | .cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
14 | .cm-s-cobalt span.cm-keyword { color: #ffee80; }
15 | .cm-s-cobalt span.cm-string { color: #3ad900; }
16 | .cm-s-cobalt span.cm-meta { color: #ff9d00; }
17 | .cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
18 | .cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def, .cm-s-cobalt .cm-type { color: white; }
19 | .cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
20 | .cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
21 | .cm-s-cobalt span.cm-link { color: #845dc4; }
22 | .cm-s-cobalt span.cm-error { color: #9d1e15; }
23 |
24 | .cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; }
25 | .cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }
26 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/fold/markdown-fold.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.registerHelper("fold", "markdown", function(cm, start) {
15 | var maxDepth = 100;
16 |
17 | function isHeader(lineNo) {
18 | var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0));
19 | return tokentype && /\bheader\b/.test(tokentype);
20 | }
21 |
22 | function headerLevel(lineNo, line, nextLine) {
23 | var match = line && line.match(/^#+/);
24 | if (match && isHeader(lineNo)) return match[0].length;
25 | match = nextLine && nextLine.match(/^[=\-]+\s*$/);
26 | if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2;
27 | return maxDepth;
28 | }
29 |
30 | var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1);
31 | var level = headerLevel(start.line, firstLine, nextLine);
32 | if (level === maxDepth) return undefined;
33 |
34 | var lastLineNo = cm.lastLine();
35 | var end = start.line, nextNextLine = cm.getLine(end + 2);
36 | while (end < lastLineNo) {
37 | if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break;
38 | ++end;
39 | nextLine = nextNextLine;
40 | nextNextLine = cm.getLine(end + 2);
41 | }
42 |
43 | return {
44 | from: CodeMirror.Pos(start.line, firstLine.length),
45 | to: CodeMirror.Pos(end, cm.getLine(end).length)
46 | };
47 | });
48 |
49 | });
50 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/idea.css:
--------------------------------------------------------------------------------
1 | /**
2 | Name: IDEA default theme
3 | From IntelliJ IDEA by JetBrains
4 | */
5 |
6 | .cm-s-idea span.cm-meta { color: #808000; }
7 | .cm-s-idea span.cm-number { color: #0000FF; }
8 | .cm-s-idea span.cm-keyword { line-height: 1em; font-weight: bold; color: #000080; }
9 | .cm-s-idea span.cm-atom { font-weight: bold; color: #000080; }
10 | .cm-s-idea span.cm-def { color: #000000; }
11 | .cm-s-idea span.cm-variable { color: black; }
12 | .cm-s-idea span.cm-variable-2 { color: black; }
13 | .cm-s-idea span.cm-variable-3, .cm-s-idea span.cm-type { color: black; }
14 | .cm-s-idea span.cm-property { color: black; }
15 | .cm-s-idea span.cm-operator { color: black; }
16 | .cm-s-idea span.cm-comment { color: #808080; }
17 | .cm-s-idea span.cm-string { color: #008000; }
18 | .cm-s-idea span.cm-string-2 { color: #008000; }
19 | .cm-s-idea span.cm-qualifier { color: #555; }
20 | .cm-s-idea span.cm-error { color: #FF0000; }
21 | .cm-s-idea span.cm-attribute { color: #0000FF; }
22 | .cm-s-idea span.cm-tag { color: #000080; }
23 | .cm-s-idea span.cm-link { color: #0000FF; }
24 | .cm-s-idea .CodeMirror-activeline-background { background: #FFFAE3; }
25 |
26 | .cm-s-idea span.cm-builtin { color: #30a; }
27 | .cm-s-idea span.cm-bracket { color: #cc7; }
28 | .cm-s-idea { font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;}
29 |
30 |
31 | .cm-s-idea .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
32 |
33 | .CodeMirror-hints.idea {
34 | font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
35 | color: #616569;
36 | background-color: #ebf3fd !important;
37 | }
38 |
39 | .CodeMirror-hints.idea .CodeMirror-hint-active {
40 | background-color: #a2b8c9 !important;
41 | color: #5c6065 !important;
42 | }
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/night.css:
--------------------------------------------------------------------------------
1 | /* Loosely based on the Midnight Textmate theme */
2 |
3 | .cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; }
4 | .cm-s-night div.CodeMirror-selected { background: #447; }
5 | .cm-s-night .CodeMirror-line::selection, .cm-s-night .CodeMirror-line > span::selection, .cm-s-night .CodeMirror-line > span > span::selection { background: rgba(68, 68, 119, .99); }
6 | .cm-s-night .CodeMirror-line::-moz-selection, .cm-s-night .CodeMirror-line > span::-moz-selection, .cm-s-night .CodeMirror-line > span > span::-moz-selection { background: rgba(68, 68, 119, .99); }
7 | .cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
8 | .cm-s-night .CodeMirror-guttermarker { color: white; }
9 | .cm-s-night .CodeMirror-guttermarker-subtle { color: #bbb; }
10 | .cm-s-night .CodeMirror-linenumber { color: #f8f8f8; }
11 | .cm-s-night .CodeMirror-cursor { border-left: 1px solid white; }
12 |
13 | .cm-s-night span.cm-comment { color: #8900d1; }
14 | .cm-s-night span.cm-atom { color: #845dc4; }
15 | .cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; }
16 | .cm-s-night span.cm-keyword { color: #599eff; }
17 | .cm-s-night span.cm-string { color: #37f14a; }
18 | .cm-s-night span.cm-meta { color: #7678e2; }
19 | .cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
20 | .cm-s-night span.cm-variable-3, .cm-s-night span.cm-def, .cm-s-night span.cm-type { color: white; }
21 | .cm-s-night span.cm-bracket { color: #8da6ce; }
22 | .cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
23 | .cm-s-night span.cm-link { color: #845dc4; }
24 | .cm-s-night span.cm-error { color: #9d1e15; }
25 |
26 | .cm-s-night .CodeMirror-activeline-background { background: #1C005A; }
27 | .cm-s-night .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
28 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/hint/anyword-hint.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | var WORD = /[\w$]+/, RANGE = 500;
15 |
16 | CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
17 | var word = options && options.word || WORD;
18 | var range = options && options.range || RANGE;
19 | var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
20 | var end = cur.ch, start = end;
21 | while (start && word.test(curLine.charAt(start - 1))) --start;
22 | var curWord = start != end && curLine.slice(start, end);
23 |
24 | var list = options && options.list || [], seen = {};
25 | var re = new RegExp(word.source, "g");
26 | for (var dir = -1; dir <= 1; dir += 2) {
27 | var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
28 | for (; line != endLine; line += dir) {
29 | var text = editor.getLine(line), m;
30 | while (m = re.exec(text)) {
31 | if (line == cur.line && m[0] === curWord) continue;
32 | if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
33 | seen[m[0]] = true;
34 | list.push(m[0]);
35 | }
36 | }
37 | }
38 | }
39 | return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/perl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Perl mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Perl mode
27 |
28 |
29 |
67 |
68 |
73 |
74 | MIME types defined: text/x-perl.
75 |
76 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/addon/fold/indent-fold.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | function lineIndent(cm, lineNo) {
15 | var text = cm.getLine(lineNo)
16 | var spaceTo = text.search(/\S/)
17 | if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1))))
18 | return -1
19 | return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
20 | }
21 |
22 | CodeMirror.registerHelper("fold", "indent", function(cm, start) {
23 | var myIndent = lineIndent(cm, start.line)
24 | if (myIndent < 0) return
25 | var lastLineInFold = null
26 |
27 | // Go through lines until we find a line that definitely doesn't belong in
28 | // the block we're folding, or to the end.
29 | for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
30 | var indent = lineIndent(cm, i)
31 | if (indent == -1) {
32 | } else if (indent > myIndent) {
33 | // Lines with a greater indent are considered part of the block.
34 | lastLineInFold = i;
35 | } else {
36 | // If this line has non-space, non-comment content, and is
37 | // indented less or equal to the start line, it is the start of
38 | // another block.
39 | break;
40 | }
41 | }
42 | if (lastLineInFold) return {
43 | from: CodeMirror.Pos(start.line, cm.getLine(start.line).length),
44 | to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
45 | };
46 | });
47 |
48 | });
49 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/htmlembedded/htmlembedded.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
7 | require("../../addon/mode/multiplex"));
8 | else if (typeof define == "function" && define.amd) // AMD
9 | define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
10 | "../../addon/mode/multiplex"], mod);
11 | else // Plain browser env
12 | mod(CodeMirror);
13 | })(function(CodeMirror) {
14 | "use strict";
15 |
16 | CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
17 | var closeComment = parserConfig.closeComment || "--%>"
18 | return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
19 | open: parserConfig.openComment || "<%--",
20 | close: closeComment,
21 | delimStyle: "comment",
22 | mode: {token: function(stream) {
23 | stream.skipTo(closeComment) || stream.skipToEnd()
24 | return "comment"
25 | }}
26 | }, {
27 | open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
28 | close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
29 | mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
30 | });
31 | }, "htmlmixed");
32 |
33 | CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"});
34 | CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
35 | CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"});
36 | CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"});
37 | });
38 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/javascript/typescript.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: TypeScript mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 | TypeScript mode
28 |
29 |
30 |
52 |
53 |
60 |
61 | This is a specialization of the JavaScript mode.
62 |
63 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/gruvbox-dark.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Name: gruvbox-dark
4 | Author: kRkk (https://github.com/krkk)
5 |
6 | Original gruvbox color scheme by Pavel Pertsev (https://github.com/morhetz/gruvbox)
7 |
8 | */
9 |
10 | .cm-s-gruvbox-dark.CodeMirror, .cm-s-gruvbox-dark .CodeMirror-gutters { background-color: #282828; color: #bdae93; }
11 | .cm-s-gruvbox-dark .CodeMirror-gutters {background: #282828; border-right: 0px;}
12 | .cm-s-gruvbox-dark .CodeMirror-linenumber {color: #7c6f64;}
13 | .cm-s-gruvbox-dark .CodeMirror-cursor { border-left: 1px solid #ebdbb2; }
14 | .cm-s-gruvbox-dark div.CodeMirror-selected { background: #928374; }
15 | .cm-s-gruvbox-dark span.cm-meta { color: #83a598; }
16 |
17 | .cm-s-gruvbox-dark span.cm-comment { color: #928374; }
18 | .cm-s-gruvbox-dark span.cm-number, span.cm-atom { color: #d3869b; }
19 | .cm-s-gruvbox-dark span.cm-keyword { color: #f84934; }
20 |
21 | .cm-s-gruvbox-dark span.cm-variable { color: #ebdbb2; }
22 | .cm-s-gruvbox-dark span.cm-variable-2 { color: #ebdbb2; }
23 | .cm-s-gruvbox-dark span.cm-variable-3, .cm-s-gruvbox-dark span.cm-type { color: #fabd2f; }
24 | .cm-s-gruvbox-dark span.cm-operator { color: #ebdbb2; }
25 | .cm-s-gruvbox-dark span.cm-callee { color: #ebdbb2; }
26 | .cm-s-gruvbox-dark span.cm-def { color: #ebdbb2; }
27 | .cm-s-gruvbox-dark span.cm-property { color: #ebdbb2; }
28 | .cm-s-gruvbox-dark span.cm-string { color: #b8bb26; }
29 | .cm-s-gruvbox-dark span.cm-string-2 { color: #8ec07c; }
30 | .cm-s-gruvbox-dark span.cm-qualifier { color: #8ec07c; }
31 | .cm-s-gruvbox-dark span.cm-attribute { color: #8ec07c; }
32 |
33 | .cm-s-gruvbox-dark .CodeMirror-activeline-background { background: #3c3836; }
34 | .cm-s-gruvbox-dark .CodeMirror-matchingbracket { background: #928374; color:#282828 !important; }
35 |
36 | .cm-s-gruvbox-dark span.cm-builtin { color: #fe8019; }
37 | .cm-s-gruvbox-dark span.cm-tag { color: #fe8019; }
38 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/rubyblue.css:
--------------------------------------------------------------------------------
1 | .cm-s-rubyblue.CodeMirror { background: #112435; color: white; }
2 | .cm-s-rubyblue div.CodeMirror-selected { background: #38566F; }
3 | .cm-s-rubyblue .CodeMirror-line::selection, .cm-s-rubyblue .CodeMirror-line > span::selection, .cm-s-rubyblue .CodeMirror-line > span > span::selection { background: rgba(56, 86, 111, 0.99); }
4 | .cm-s-rubyblue .CodeMirror-line::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 86, 111, 0.99); }
5 | .cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; }
6 | .cm-s-rubyblue .CodeMirror-guttermarker { color: white; }
7 | .cm-s-rubyblue .CodeMirror-guttermarker-subtle { color: #3E7087; }
8 | .cm-s-rubyblue .CodeMirror-linenumber { color: white; }
9 | .cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white; }
10 |
11 | .cm-s-rubyblue span.cm-comment { color: #999; font-style:italic; line-height: 1em; }
12 | .cm-s-rubyblue span.cm-atom { color: #F4C20B; }
13 | .cm-s-rubyblue span.cm-number, .cm-s-rubyblue span.cm-attribute { color: #82C6E0; }
14 | .cm-s-rubyblue span.cm-keyword { color: #F0F; }
15 | .cm-s-rubyblue span.cm-string { color: #F08047; }
16 | .cm-s-rubyblue span.cm-meta { color: #F0F; }
17 | .cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; }
18 | .cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def, .cm-s-rubyblue span.cm-type { color: white; }
19 | .cm-s-rubyblue span.cm-bracket { color: #F0F; }
20 | .cm-s-rubyblue span.cm-link { color: #F4C20B; }
21 | .cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; }
22 | .cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; }
23 | .cm-s-rubyblue span.cm-error { color: #AF2018; }
24 |
25 | .cm-s-rubyblue .CodeMirror-activeline-background { background: #173047; }
26 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/elm/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Elm mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Elm mode
27 |
28 |
52 |
53 |
59 |
60 | MIME types defined: text/x-elm.
61 |
62 |
--------------------------------------------------------------------------------
/frontend/src/layout/components/Navbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 | 行业
10 |
11 |
12 |
13 | 概念
14 |
15 |
16 |
20 | 板块
21 |
22 |
23 |
24 | 地域
25 |
26 |
27 |
28 | 比较
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
62 |
63 |
87 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/theme/tomorrow-night-bright.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Name: Tomorrow Night - Bright
4 | Author: Chris Kempson
5 |
6 | Port done by Gerard Braad
7 |
8 | */
9 |
10 | .cm-s-tomorrow-night-bright.CodeMirror { background: #000000; color: #eaeaea; }
11 | .cm-s-tomorrow-night-bright div.CodeMirror-selected { background: #424242; }
12 | .cm-s-tomorrow-night-bright .CodeMirror-gutters { background: #000000; border-right: 0px; }
13 | .cm-s-tomorrow-night-bright .CodeMirror-guttermarker { color: #e78c45; }
14 | .cm-s-tomorrow-night-bright .CodeMirror-guttermarker-subtle { color: #777; }
15 | .cm-s-tomorrow-night-bright .CodeMirror-linenumber { color: #424242; }
16 | .cm-s-tomorrow-night-bright .CodeMirror-cursor { border-left: 1px solid #6A6A6A; }
17 |
18 | .cm-s-tomorrow-night-bright span.cm-comment { color: #d27b53; }
19 | .cm-s-tomorrow-night-bright span.cm-atom { color: #a16a94; }
20 | .cm-s-tomorrow-night-bright span.cm-number { color: #a16a94; }
21 |
22 | .cm-s-tomorrow-night-bright span.cm-property, .cm-s-tomorrow-night-bright span.cm-attribute { color: #99cc99; }
23 | .cm-s-tomorrow-night-bright span.cm-keyword { color: #d54e53; }
24 | .cm-s-tomorrow-night-bright span.cm-string { color: #e7c547; }
25 |
26 | .cm-s-tomorrow-night-bright span.cm-variable { color: #b9ca4a; }
27 | .cm-s-tomorrow-night-bright span.cm-variable-2 { color: #7aa6da; }
28 | .cm-s-tomorrow-night-bright span.cm-def { color: #e78c45; }
29 | .cm-s-tomorrow-night-bright span.cm-bracket { color: #eaeaea; }
30 | .cm-s-tomorrow-night-bright span.cm-tag { color: #d54e53; }
31 | .cm-s-tomorrow-night-bright span.cm-link { color: #a16a94; }
32 | .cm-s-tomorrow-night-bright span.cm-error { background: #d54e53; color: #6A6A6A; }
33 |
34 | .cm-s-tomorrow-night-bright .CodeMirror-activeline-background { background: #2a2a2a; }
35 | .cm-s-tomorrow-night-bright .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
36 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/sass/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Sass mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
26 |
27 |
28 | Sass mode
29 |
59 |
66 |
67 | MIME types defined: text/x-sass.
68 |
69 |
--------------------------------------------------------------------------------
/frontend/src/utils/scrollTo.js:
--------------------------------------------------------------------------------
1 | Math.easeInOutQuad = function (t, b, c, d) {
2 | t /= d / 2
3 | if (t < 1) {
4 | return c / 2 * t * t + b
5 | }
6 | t--
7 | return -c / 2 * (t * (t - 2) - 1) + b
8 | }
9 |
10 | // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
11 | var requestAnimFrame = (function () {
12 | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60) }
13 | })()
14 |
15 | /**
16 | * Because it's so fucking difficult to detect the scrolling element, just move them all
17 | * @param {number} amount
18 | */
19 | function move (amount) {
20 | document.documentElement.scrollTop = amount
21 | document.body.parentNode.scrollTop = amount
22 | document.body.scrollTop = amount
23 | }
24 |
25 | function position () {
26 | return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
27 | }
28 |
29 | /**
30 | * @param {number} to
31 | * @param {number} duration
32 | * @param {Function} callback
33 | */
34 | export function scrollTo (to, duration, callback) {
35 | const start = position()
36 | const change = to - start
37 | const increment = 20
38 | let currentTime = 0
39 | duration = (typeof (duration) === 'undefined') ? 500 : duration
40 | var animateScroll = function () {
41 | // increment the time
42 | currentTime += increment
43 | // find the value with the quadratic in-out easing function
44 | var val = Math.easeInOutQuad(currentTime, start, change, duration)
45 | // move the document.body
46 | move(val)
47 | // do the animation unless its over
48 | if (currentTime < duration) {
49 | requestAnimFrame(animateScroll)
50 | } else {
51 | if (callback && typeof (callback) === 'function') {
52 | // the animation is done so lets callback
53 | callback()
54 | }
55 | }
56 | }
57 | animateScroll()
58 | }
59 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/dart/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Dart mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Dart mode
27 |
63 |
64 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/templates/wiki/concept_form.html:
--------------------------------------------------------------------------------
1 | {% extends '_layout/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}{% if object %}编辑 - {{ object.name }}{% else %}创建概念{% endif %}{% endblock %}
5 |
6 | {% block header_css %}
7 |
8 | {% endblock %}
9 |
10 | {% block scripts %}
11 |
12 |
21 | {% endblock %}
22 |
23 | {% block content %}
24 |
25 |
{% if object %}编辑{% else %}创建{% endif %}概念
26 |
27 |
28 |
51 |
52 | {% endblock %}
53 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/idl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: IDL mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 | IDL mode
28 |
29 |
53 |
63 |
64 | MIME types defined: text/x-idl.
65 |
66 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/jinja2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CodeMirror: Jinja2 mode
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | Jinja2 mode
27 |
49 |
54 |
55 |
--------------------------------------------------------------------------------
/public/static/editor.md/lib/codemirror/mode/xml/test.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: https://codemirror.net/LICENSE
3 |
4 | (function() {
5 | var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml";
6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), mname); }
7 |
8 | MT("matching",
9 | "[tag&bracket <][tag top][tag&bracket >]",
10 | " text",
11 | " [tag&bracket <][tag inner][tag&bracket />]",
12 | "[tag&bracket ][tag top][tag&bracket >]");
13 |
14 | MT("nonmatching",
15 | "[tag&bracket <][tag top][tag&bracket >]",
16 | " [tag&bracket <][tag inner][tag&bracket />]",
17 | " [tag&bracket ][tag&error tip][tag&bracket&error >]");
18 |
19 | MT("doctype",
20 | "[meta ]",
21 | "[tag&bracket <][tag top][tag&bracket />]");
22 |
23 | MT("cdata",
24 | "[tag&bracket <][tag top][tag&bracket >]",
25 | " [atom ]",
27 | "[tag&bracket ][tag top][tag&bracket >]");
28 |
29 | // HTML tests
30 | mode = CodeMirror.getMode({indentUnit: 2}, "text/html");
31 |
32 | MT("selfclose",
33 | "[tag&bracket <][tag html][tag&bracket >]",
34 | " [tag&bracket <][tag link] [attribute rel]=[string stylesheet] [attribute href]=[string \"/foobar\"][tag&bracket >]",
35 | "[tag&bracket ][tag html][tag&bracket >]");
36 |
37 | MT("list",
38 | "[tag&bracket <][tag ol][tag&bracket >]",
39 | " [tag&bracket <][tag li][tag&bracket >]one",
40 | " [tag&bracket <][tag li][tag&bracket >]two",
41 | "[tag&bracket ][tag ol][tag&bracket >]");
42 |
43 | MT("valueless",
44 | "[tag&bracket <][tag input] [attribute type]=[string checkbox] [attribute checked][tag&bracket />]");
45 |
46 | MT("pThenArticle",
47 | "[tag&bracket <][tag p][tag&bracket >]",
48 | " foo",
49 | "[tag&bracket <][tag article][tag&bracket >]bar");
50 |
51 | })();
52 |
--------------------------------------------------------------------------------