├── 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 | 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 | 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 | 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 | 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 | [![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror) 3 | [![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror) 4 | [Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](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 | 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 | 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 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /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 |
2 | 3 |
4 | 6 |
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 |
19 | 21 | 22 |
23 |
24 |
25 | 26 |
27 |
28 | {{ object.name }} 29 |
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 | 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 |
28 | 62 |
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 |
29 | {% csrf_token %} 30 | {{ form.non_field_errors }} 31 | 32 |
33 | {{ form.name.errors }} 34 | 35 | 36 |
37 | 38 |
39 | {{ form.description.errors }} 40 | 41 |
42 | 43 | 44 |
45 |
46 | 47 |
48 | 49 | 50 |
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 ]"); 13 | 14 | MT("nonmatching", 15 | "[tag&bracket <][tag top][tag&bracket >]", 16 | " [tag&bracket <][tag inner][tag&bracket />]", 17 | " [tag&bracket ]"); 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 ]"); 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 ]"); 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 ]"); 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 | --------------------------------------------------------------------------------