commit c9b01deca22f76736c912a762ccf85ea5501bf6c Author: sichan Date: Wed Feb 21 14:22:45 2024 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d0653a --- /dev/null +++ b/.gitignore @@ -0,0 +1,162 @@ +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + diff --git a/WideRating2024/__init__.py b/WideRating2024/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/WideRating2024/asgi.py b/WideRating2024/asgi.py new file mode 100644 index 0000000..6d4b71e --- /dev/null +++ b/WideRating2024/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for WideRating2024 project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "WideRating2024.settings") + +application = get_asgi_application() diff --git a/WideRating2024/settings.py b/WideRating2024/settings.py new file mode 100644 index 0000000..eb2ab5e --- /dev/null +++ b/WideRating2024/settings.py @@ -0,0 +1,125 @@ +""" +Django settings for WideRating2024 project. + +Generated by 'django-admin startproject' using Django 5.0.2. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.0/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = "django-insecure-3yw3as8#vy_^y$hwijoerwvxk9^etsb2&_eyp$vxwh@6#o2dq2" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "company_data", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] + +ROOT_URLCONF = "WideRating2024.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [BASE_DIR / 'templates'] + , + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + +WSGI_APPLICATION = "WideRating2024.wsgi.application" + + +# Database +# https://docs.djangoproject.com/en/5.0/ref/settings/#databases + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.0/topics/i18n/ + +LANGUAGE_CODE = "zh-hans" # 将语言代码更改为中文简体 + +TIME_ZONE = "Asia/Shanghai" # 将时区更改为中国上海时区 + +USE_I18N = True # 开启国际化支持,以便支持多语言 + +USE_TZ = False # 关闭时区支持,因为中国没有夏令时,所以不需要时区转换 + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.0/howto/static-files/ + +STATIC_URL = "static/" + +# Default primary key field type +# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" diff --git a/WideRating2024/urls.py b/WideRating2024/urls.py new file mode 100644 index 0000000..34c6d57 --- /dev/null +++ b/WideRating2024/urls.py @@ -0,0 +1,22 @@ +""" +URL configuration for WideRating2024 project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path("admin/", admin.site.urls), +] diff --git a/WideRating2024/wsgi.py b/WideRating2024/wsgi.py new file mode 100644 index 0000000..480ca3d --- /dev/null +++ b/WideRating2024/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for WideRating2024 project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "WideRating2024.settings") + +application = get_wsgi_application() diff --git a/company_data/__init__.py b/company_data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/company_data/admin.py b/company_data/admin.py new file mode 100644 index 0000000..fee3f26 --- /dev/null +++ b/company_data/admin.py @@ -0,0 +1,60 @@ +from django.contrib import admin +from django.urls import reverse +from django.utils.html import format_html + +from company_data.models import CompanyResearchInfo + + +class CompanyResearchInfoAdmin(admin.ModelAdmin): + list_display = ['company_name', 'legal_entity_name', 'shareholder_nature', 'action_buttons'] + search_fields = ['company_name'] # 根据问卷名称进行搜索 + list_filter = ['shareholder_nature'] # 添加过滤器 + + def action_buttons(self, obj): + view_name = 'admin:company_data_companyresearchinfo_change' + format_string = '编辑 ''删除' + url = reverse(view_name, args=[obj.pk]) + return format_html(format_string, url, url) + action_buttons.short_description = '操作' + + # 编辑页属性 + fieldsets = ( + ('工商信息', {'fields': ( + ("company_name", "legal_entity_name", "shareholder_nature"), + 'main_business', + )}), + ('股东及董监高', {'fields': ( + ("senior_management_experience", "has_board", "board_members_count"), + ("has_supervisory_board", "supervisory_members_count", "annual_support_funds"), + )}), + ('人员信息', {'fields': ( + ("management_staff_count", "functional_staff_count", "sales_staff_count"), + ("technical_service_staff_count", "bachelors_or_above_count", "below_bachelors_count"), + ("year_end_total_employees", "annual_resignation_count", "training_participation_count"), + ("average_weekly_working_days", "average_daily_working_hours", "work_related_casualties") + )}), + ('经营情况', {'fields': ( + ("sales_amount", "returns_amount", "privacy_breach_incidents"), + ("total_service_times", "valid_customer_complaints", "complaints_resolved", "complaint_response_time"), + )}), + ('经营场所信息', {'fields': ( + ("operating_site_area", "operating_site_location", "operating_site_ownership") + )}), + ('银行账户信息', {'fields': ( + ("rmb_account_bank_name", "rmb_bank_account"), + ("foreign_currency_bank_name", "foreign_currency_bank_account"), + "loan_card_number" + )}), + ('公司制度', {'fields': ( + ("has_quality_management_system", "has_financial_management_system", "has_contract_management_system", + "has_hr_management_system"), + )}), + ('补充信息', {'fields': ( + ("social_responsibility_implementation", "business_credit_record"), + ("customs_credit_record", "bank_credit_record"), + ("court_credit_record", "production_safety_information") + )}), + ) + + +admin.site.register(CompanyResearchInfo, CompanyResearchInfoAdmin) diff --git a/company_data/apps.py b/company_data/apps.py new file mode 100644 index 0000000..2de0a19 --- /dev/null +++ b/company_data/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CompanyDataConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "company_data" diff --git a/company_data/migrations/0001_initial.py b/company_data/migrations/0001_initial.py new file mode 100644 index 0000000..e0617b3 --- /dev/null +++ b/company_data/migrations/0001_initial.py @@ -0,0 +1,396 @@ +# Generated by Django 5.0.2 on 2024-02-21 14:05 + +import django.db.models.deletion +import shortuuid.main +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="CompanyResearchInfo", + fields=[ + ( + "company_id", + models.CharField( + default=shortuuid.main.ShortUUID.uuid, + editable=False, + max_length=22, + primary_key=True, + serialize=False, + verbose_name="企业ID", + ), + ), + ("company_name", models.CharField(max_length=255, verbose_name="企业名称")), + ( + "legal_entity_name", + models.CharField(max_length=255, verbose_name="法人名称"), + ), + ( + "shareholder_nature", + models.CharField( + choices=[ + ("个人", "个人"), + ("私企", "私企"), + ("国企", "国企"), + ("政府", "政府"), + ], + max_length=255, + verbose_name="股东性质", + ), + ), + ( + "main_business", + models.TextField(max_length=255, verbose_name="主营业务"), + ), + ( + "senior_management_experience", + models.FloatField(verbose_name="高管平均从业年限"), + ), + ( + "has_board", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=255, + verbose_name="是否设置董事会", + ), + ), + ("board_members_count", models.IntegerField(verbose_name="董事会人数")), + ( + "has_supervisory_board", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=255, + verbose_name="是否设置监事会", + ), + ), + ("supervisory_members_count", models.IntegerField(verbose_name="监事人数")), + ( + "annual_support_funds", + models.FloatField(verbose_name="年度公司股东或关联方给予公司的资金支持金额"), + ), + ("management_staff_count", models.IntegerField(verbose_name="管理人员人数")), + ("functional_staff_count", models.IntegerField(verbose_name="职能人员人数")), + ("sales_staff_count", models.IntegerField(verbose_name="销售人员人数")), + ( + "technical_service_staff_count", + models.IntegerField(verbose_name="技术服务人员人数"), + ), + ( + "bachelors_or_above_count", + models.IntegerField(verbose_name="本科及以上人员人数"), + ), + ( + "below_bachelors_count", + models.IntegerField(verbose_name="专科及以下人员人数"), + ), + ( + "year_end_total_employees", + models.IntegerField(verbose_name="年末员工总数"), + ), + ( + "annual_resignation_count", + models.IntegerField(verbose_name="年度离职人数"), + ), + ( + "training_participation_count", + models.IntegerField(verbose_name="年度员工培训总次数"), + ), + ( + "average_weekly_working_days", + models.FloatField(verbose_name="员工周均工作天数"), + ), + ( + "average_daily_working_hours", + models.FloatField(verbose_name="员工日均工作时长"), + ), + ( + "work_related_casualties", + models.IntegerField(verbose_name="年度因公伤亡人次"), + ), + ("sales_amount", models.FloatField(verbose_name="销售产品金额")), + ("returns_amount", models.FloatField(verbose_name="退回产品金额")), + ( + "privacy_breach_incidents", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=8, + verbose_name="发生过客户隐私泄露", + ), + ), + ("total_service_times", models.IntegerField(verbose_name="对外服务总次数")), + ( + "valid_customer_complaints", + models.IntegerField(verbose_name="客户有效投诉次数"), + ), + ("complaints_resolved", models.IntegerField(verbose_name="投诉解决次数")), + ("complaint_response_time", models.FloatField(verbose_name="投诉响应时间")), + ( + "rmb_account_bank_name", + models.CharField(max_length=255, verbose_name="人民币开户银行名称"), + ), + ( + "rmb_bank_account", + models.CharField(max_length=255, verbose_name="人民币开户银行账号"), + ), + ( + "foreign_currency_bank_name", + models.CharField(max_length=255, verbose_name="外币开户银行名称"), + ), + ( + "foreign_currency_bank_account", + models.CharField(max_length=255, verbose_name="外币开户银行账号"), + ), + ( + "loan_card_number", + models.CharField(max_length=255, verbose_name="贷款卡编号"), + ), + ( + "operating_site_area", + models.FloatField(max_length=255, verbose_name="经营场所建筑面积"), + ), + ( + "operating_site_location", + models.CharField(max_length=255, verbose_name="经营场所位置"), + ), + ( + "operating_site_ownership", + models.CharField( + choices=[("自有", "自有"), ("租赁", "租赁")], + max_length=255, + verbose_name="经营场所权属关系", + ), + ), + ( + "has_quality_management_system", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=8, + verbose_name="拥有质量管理制度", + ), + ), + ( + "has_financial_management_system", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=8, + verbose_name="拥有财务管理制度", + ), + ), + ( + "has_contract_management_system", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=8, + verbose_name="拥有合同管理制度", + ), + ), + ( + "has_hr_management_system", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=8, + verbose_name="拥有人力资源管理制度", + ), + ), + ( + "business_credit_record", + models.TextField(max_length=255, verbose_name="工商信用记录"), + ), + ( + "customs_credit_record", + models.TextField(max_length=255, verbose_name="海关信用记录"), + ), + ( + "bank_credit_record", + models.TextField(max_length=255, verbose_name="银行信用记录"), + ), + ( + "court_credit_record", + models.TextField(max_length=255, verbose_name="法院信用记录"), + ), + ( + "production_safety_information", + models.TextField(max_length=255, verbose_name="生产安全信息"), + ), + ( + "social_responsibility_implementation", + models.TextField(max_length=255, verbose_name="社会责任实施"), + ), + ], + options={ + "verbose_name": "企业调研信息", + "verbose_name_plural": "企业调研信息", + }, + ), + migrations.CreateModel( + name="CompanyCreditData", + fields=[ + ( + "company_credit_data_id", + models.CharField( + default=shortuuid.main.ShortUUID.uuid, + editable=False, + max_length=22, + primary_key=True, + serialize=False, + verbose_name="企业信用数据ID", + ), + ), + ("company_name", models.CharField(max_length=255, verbose_name="企业名称")), + ("years_in_operation", models.IntegerField(verbose_name="成立年限")), + ( + "shareholder_changes_last_three_years", + models.IntegerField(verbose_name="近三年股东变更次数"), + ), + ( + "negative_public_opinions_ratio", + models.FloatField( + help_text="与企业相关的最近1000条新闻", verbose_name="企业舆情负面占比" + ), + ), + ( + "litigation_announcements", + models.IntegerField( + help_text="被告,类型为合同纠纷或劳动争议", verbose_name="开庭公告" + ), + ), + ( + "tax_credit_rating", + models.CharField( + choices=[("A", "A"), ("B", "B"), ("C", "C"), ("D", "D")], + default="", + max_length=8, + verbose_name="纳税信用等级", + ), + ), + ( + "double_random_check_result", + models.CharField(max_length=100, verbose_name="双随机抽查结果"), + ), + ( + "abnormal_business_operations", + models.IntegerField(verbose_name="经营异常"), + ), + ("tax_notice", models.IntegerField(verbose_name="欠税公告")), + ( + "admin_penalty_warnings", + models.IntegerField( + help_text="最近3年累计的行政处罚的罚款数额", verbose_name="罚款数额" + ), + ), + ( + "admin_penalty_confiscation", + models.IntegerField( + help_text="最近3年行政处罚所没收的违法所得", verbose_name="没收违法所得" + ), + ), + ("judgment_debtor", models.IntegerField(verbose_name="被执行人")), + ( + "dishonest_judgment_debtor", + models.IntegerField(verbose_name="失信被执行人"), + ), + ("tax_violations", models.IntegerField(verbose_name="税收违法")), + ("serious_violations", models.IntegerField(verbose_name="严重违法")), + ( + "company", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="company_credit_data", + to="company_data.companyresearchinfo", + verbose_name="企业ID", + ), + ), + ], + options={ + "verbose_name": "企业信用数据", + "verbose_name_plural": "企业信用数据", + }, + ), + migrations.CreateModel( + name="SimpleFinancialReport", + fields=[ + ( + "financial_report_id", + models.CharField( + default=shortuuid.main.ShortUUID.uuid, + editable=False, + max_length=22, + primary_key=True, + serialize=False, + verbose_name="财务报表ID", + ), + ), + ("company_name", models.CharField(max_length=255, verbose_name="企业名称")), + ("report_date", models.DateField(verbose_name="报告期")), + ("currency_funds", models.FloatField(verbose_name="货币资金")), + ("accounts_receivable", models.FloatField(verbose_name="应收账款")), + ("other_receivables", models.FloatField(verbose_name="其他应收款")), + ("prepayments", models.FloatField(verbose_name="预付款项")), + ("inventory", models.FloatField(verbose_name="存货")), + ("total_current_assets", models.FloatField(verbose_name="流动资产合计")), + ("total_non_current_assets", models.FloatField(verbose_name="非流动资产合计")), + ( + "original_value_fixed_assets", + models.FloatField(verbose_name="固定资产原价"), + ), + ("accumulated_depreciation", models.FloatField(verbose_name="累计折旧")), + ("net_value_fixed_assets", models.FloatField(verbose_name="固定资产净额")), + ("total_fixed_assets", models.FloatField(verbose_name="固定资产总计")), + ( + "total_intangible_and_other_assets", + models.FloatField(verbose_name="无形资产及其他资产合计"), + ), + ("total_assets", models.FloatField(verbose_name="资产总计")), + ("short_term_loans", models.FloatField(verbose_name="短期借款")), + ("notes_payable", models.FloatField(verbose_name="应付票据")), + ("accounts_payable", models.FloatField(verbose_name="应付账款")), + ("advance_payments", models.FloatField(verbose_name="预收账款")), + ("interest_payable", models.FloatField(verbose_name="应付利息")), + ("other_payables", models.FloatField(verbose_name="其他应付款")), + ("total_current_liabilities", models.FloatField(verbose_name="流动负债合计")), + ("long_term_loans", models.FloatField(verbose_name="长期借款")), + ("bonds_payable", models.FloatField(verbose_name="应付债券")), + ( + "total_non_current_liabilities", + models.FloatField(verbose_name="非流动负债合计"), + ), + ("total_liabilities", models.FloatField(verbose_name="负债合计")), + ("undistributed_profit", models.FloatField(verbose_name="未分配利润")), + ("total_equity", models.FloatField(verbose_name="所有者权益合计")), + ("operating_income", models.FloatField(verbose_name="营业收入")), + ("operating_costs", models.FloatField(verbose_name="营业成本")), + ("interest_expense", models.FloatField(verbose_name="利息费用")), + ("net_profit", models.FloatField(verbose_name="净利润")), + ( + "audited", + models.CharField( + choices=[("是", "是"), ("否", "否")], + max_length=8, + verbose_name="是否审计", + ), + ), + ( + "accounting_firm", + models.CharField(max_length=100, verbose_name="会计事务所"), + ), + ( + "company", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="simple_financial_reports", + to="company_data.companyresearchinfo", + verbose_name="企业ID", + ), + ), + ], + options={ + "verbose_name": "简易财务报表", + "verbose_name_plural": "简易财务报表", + }, + ), + ] diff --git a/company_data/migrations/__init__.py b/company_data/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/company_data/models.py b/company_data/models.py new file mode 100644 index 0000000..5a7d4da --- /dev/null +++ b/company_data/models.py @@ -0,0 +1,146 @@ +import shortuuid +from django.db import models + + +# 企业调研信息 +class CompanyResearchInfo(models.Model): + # 选项 + SHAREHOLDER_NATURE_CHOICES = [('个人', '个人'), ('私企', '私企'), ('国企', '国企'), ('政府', '政府'), ] + YES_OR_NO_CHOICES = [('是', '是'), ('否', '否')] + OPERATING_SITE_OWNERSHIP_CHOICES = [('自有', '自有'), ('租赁', '租赁')] + + # 企业ID + company_id = models.CharField(max_length=22, primary_key=True, default=shortuuid.uuid, editable=False, verbose_name='企业ID') + + # 工商信息 + company_name = models.CharField(max_length=255, verbose_name='企业名称') + legal_entity_name = models.CharField(max_length=255, verbose_name='法人名称') + shareholder_nature = models.CharField(max_length=255, choices=SHAREHOLDER_NATURE_CHOICES, verbose_name='股东性质') + main_business = models.TextField(max_length=255, verbose_name='主营业务') + # 股东及董监高 + senior_management_experience = models.FloatField(verbose_name='高管平均从业年限') + has_board = models.CharField(max_length=255, choices=YES_OR_NO_CHOICES, verbose_name='是否设置董事会') + board_members_count = models.IntegerField(verbose_name='董事会人数') + has_supervisory_board = models.CharField(max_length=255, choices=YES_OR_NO_CHOICES, verbose_name='是否设置监事会') + supervisory_members_count = models.IntegerField(verbose_name='监事人数') + annual_support_funds = models.FloatField(verbose_name='年度公司股东或关联方给予公司的资金支持金额') + # 人员信息 + management_staff_count = models.IntegerField(verbose_name='管理人员人数') + functional_staff_count = models.IntegerField(verbose_name='职能人员人数') + sales_staff_count = models.IntegerField(verbose_name='销售人员人数') + technical_service_staff_count = models.IntegerField(verbose_name='技术服务人员人数') + bachelors_or_above_count = models.IntegerField(verbose_name='本科及以上人员人数') + below_bachelors_count = models.IntegerField(verbose_name='专科及以下人员人数') + year_end_total_employees = models.IntegerField(verbose_name='年末员工总数') + annual_resignation_count = models.IntegerField(verbose_name='年度离职人数') + training_participation_count = models.IntegerField(verbose_name='年度员工培训总次数') + average_weekly_working_days = models.FloatField(verbose_name='员工周均工作天数') + average_daily_working_hours = models.FloatField(verbose_name='员工日均工作时长') + work_related_casualties = models.IntegerField(verbose_name='年度因公伤亡人次') + # 经营情况 + sales_amount = models.FloatField(verbose_name='销售产品金额') + returns_amount = models.FloatField(verbose_name='退回产品金额') + privacy_breach_incidents = models.CharField(max_length=8, choices=YES_OR_NO_CHOICES, verbose_name='发生过客户隐私泄露') + total_service_times = models.IntegerField(verbose_name='对外服务总次数') + valid_customer_complaints = models.IntegerField(verbose_name='客户有效投诉次数') + complaints_resolved = models.IntegerField(verbose_name='投诉解决次数') + complaint_response_time = models.FloatField(verbose_name='投诉响应时间') + # 银行账户信息 + rmb_account_bank_name = models.CharField(max_length=255, verbose_name='人民币开户银行名称') + rmb_bank_account = models.CharField(max_length=255, verbose_name='人民币开户银行账号') + foreign_currency_bank_name = models.CharField(max_length=255, verbose_name='外币开户银行名称') + foreign_currency_bank_account = models.CharField(max_length=255, verbose_name='外币开户银行账号') + loan_card_number = models.CharField(max_length=255, verbose_name='贷款卡编号') + # 经营场所信息 + operating_site_area = models.FloatField(max_length=255, verbose_name='经营场所建筑面积') + operating_site_location = models.CharField(max_length=255, verbose_name='经营场所位置') + operating_site_ownership = models.CharField(max_length=255, choices=OPERATING_SITE_OWNERSHIP_CHOICES, verbose_name='经营场所权属关系') + # 公司制度 + has_quality_management_system = models.CharField(max_length=8, choices=YES_OR_NO_CHOICES, verbose_name='拥有质量管理制度') + has_financial_management_system = models.CharField(max_length=8, choices=YES_OR_NO_CHOICES, verbose_name='拥有财务管理制度') + has_contract_management_system = models.CharField(max_length=8, choices=YES_OR_NO_CHOICES, verbose_name='拥有合同管理制度') + has_hr_management_system = models.CharField(max_length=8, choices=YES_OR_NO_CHOICES, verbose_name='拥有人力资源管理制度') + + # 补充信息 + business_credit_record = models.TextField(max_length=255, verbose_name='工商信用记录') + customs_credit_record = models.TextField(max_length=255, verbose_name='海关信用记录') + bank_credit_record = models.TextField(max_length=255, verbose_name='银行信用记录') + court_credit_record = models.TextField(max_length=255, verbose_name='法院信用记录') + production_safety_information = models.TextField(max_length=255, verbose_name='生产安全信息') + social_responsibility_implementation = models.TextField(max_length=255, verbose_name='社会责任实施') + + class Meta: + verbose_name = "企业调研信息" + verbose_name_plural = "企业调研信息" + + +# 简易财务报表 +class SimpleFinancialReport(models.Model): + financial_report_id = models.CharField(max_length=22, primary_key=True, default=shortuuid.uuid, editable=False, verbose_name='财务报表ID') + company = models.ForeignKey(CompanyResearchInfo, on_delete=models.CASCADE, related_name='simple_financial_reports', verbose_name='企业ID') + company_name = models.CharField(max_length=255, verbose_name='企业名称') + report_date = models.DateField(verbose_name="报告期") + currency_funds = models.FloatField(verbose_name="货币资金") + accounts_receivable = models.FloatField(verbose_name="应收账款") + other_receivables = models.FloatField(verbose_name="其他应收款") + prepayments = models.FloatField(verbose_name="预付款项") + inventory = models.FloatField(verbose_name="存货") + total_current_assets = models.FloatField(verbose_name="流动资产合计") + total_non_current_assets = models.FloatField(verbose_name="非流动资产合计") + original_value_fixed_assets = models.FloatField(verbose_name="固定资产原价") + accumulated_depreciation = models.FloatField(verbose_name="累计折旧") + net_value_fixed_assets = models.FloatField(verbose_name="固定资产净额") + total_fixed_assets = models.FloatField(verbose_name="固定资产总计") + total_intangible_and_other_assets = models.FloatField(verbose_name="无形资产及其他资产合计") + total_assets = models.FloatField(verbose_name="资产总计") + short_term_loans = models.FloatField(verbose_name="短期借款") + notes_payable = models.FloatField(verbose_name="应付票据") + accounts_payable = models.FloatField(verbose_name="应付账款") + advance_payments = models.FloatField(verbose_name="预收账款") + interest_payable = models.FloatField(verbose_name="应付利息") + other_payables = models.FloatField(verbose_name="其他应付款") + total_current_liabilities = models.FloatField(verbose_name="流动负债合计") + long_term_loans = models.FloatField(verbose_name="长期借款") + bonds_payable = models.FloatField(verbose_name="应付债券") + total_non_current_liabilities = models.FloatField(verbose_name="非流动负债合计") + total_liabilities = models.FloatField(verbose_name="负债合计") + undistributed_profit = models.FloatField(verbose_name="未分配利润") + total_equity = models.FloatField(verbose_name="所有者权益合计") + operating_income = models.FloatField(verbose_name="营业收入") + operating_costs = models.FloatField(verbose_name="营业成本") + interest_expense = models.FloatField(verbose_name="利息费用") + net_profit = models.FloatField(verbose_name="净利润") + audited = models.CharField(max_length=8, choices=[("是", "是"), ("否", "否")], verbose_name="是否审计") + accounting_firm = models.CharField(max_length=100, verbose_name="会计事务所") + + class Meta: + verbose_name = "简易财务报表" + verbose_name_plural = "简易财务报表" + + +class CompanyCreditData(models.Model): + TAX_CREDIT_RATING_CHOICES = [('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')] + + company_credit_data_id = models.CharField(max_length=22, primary_key=True, default=shortuuid.uuid, editable=False, verbose_name='企业信用数据ID') + company = models.OneToOneField(CompanyResearchInfo, on_delete=models.CASCADE, related_name='company_credit_data', verbose_name='企业ID') + company_name = models.CharField(max_length=255, verbose_name='企业名称') + + # 企业信用数据 + years_in_operation = models.IntegerField(verbose_name="成立年限") + shareholder_changes_last_three_years = models.IntegerField(verbose_name="近三年股东变更次数") + negative_public_opinions_ratio = models.FloatField(verbose_name="企业舆情负面占比", help_text="与企业相关的最近1000条新闻") + litigation_announcements = models.IntegerField(verbose_name="开庭公告", help_text='被告,类型为合同纠纷或劳动争议') + tax_credit_rating = models.CharField(max_length=8, default="", choices=TAX_CREDIT_RATING_CHOICES, verbose_name="纳税信用等级") + double_random_check_result = models.CharField(max_length=100, verbose_name="双随机抽查结果") + abnormal_business_operations = models.IntegerField(verbose_name="经营异常") + tax_notice = models.IntegerField(verbose_name="欠税公告") + admin_penalty_warnings = models.IntegerField(verbose_name="罚款数额", help_text="最近3年累计的行政处罚的罚款数额") + admin_penalty_confiscation = models.IntegerField(verbose_name="没收违法所得", help_text="最近3年行政处罚所没收的违法所得") + judgment_debtor = models.IntegerField(verbose_name="被执行人") + dishonest_judgment_debtor = models.IntegerField(verbose_name="失信被执行人") + tax_violations = models.IntegerField(verbose_name="税收违法") + serious_violations = models.IntegerField(verbose_name="严重违法") + + class Meta: + verbose_name = "企业信用数据" + verbose_name_plural = "企业信用数据" diff --git a/company_data/tests.py b/company_data/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/company_data/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/company_data/views.py b/company_data/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/company_data/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..f901c00 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "WideRating2024.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/mock.py b/mock.py new file mode 100644 index 0000000..fc2bbd3 --- /dev/null +++ b/mock.py @@ -0,0 +1,153 @@ +import os +from datetime import datetime + +import django +import random +import string +import shortuuid +from faker import Faker + +# 设置 DJANGO_SETTINGS_MODULE 环境变量 +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "WideRating2024.settings") + +# 初始化 Django 配置 +django.setup() + +from company_data.models import CompanyResearchInfo, SimpleFinancialReport, CompanyCreditData + +fake = Faker('zh_CN') + + +def generate_company_research_info(): + company_research_info = CompanyResearchInfo( + company_id=shortuuid.uuid(), + company_name=fake.company(), + legal_entity_name=fake.name(), + shareholder_nature=random.choice(['个人', '私企', '国企', '政府']), + main_business=fake.catch_phrase(), + senior_management_experience=round(random.uniform(1, 20), 2), + has_board=random.choice(['是', '否']), + board_members_count=random.randint(1, 10), + has_supervisory_board=random.choice(['是', '否']), + supervisory_members_count=random.randint(1, 10), + annual_support_funds=round(random.uniform(100000, 1000000), 2), + management_staff_count=random.randint(10, 100), + functional_staff_count=random.randint(10, 100), + sales_staff_count=random.randint(10, 100), + technical_service_staff_count=random.randint(10, 100), + bachelors_or_above_count=random.randint(10, 50), + below_bachelors_count=random.randint(10, 50), + year_end_total_employees=random.randint(50, 200), + annual_resignation_count=random.randint(1, 10), + training_participation_count=random.randint(100, 500), + average_weekly_working_days=round(random.uniform(4, 7), 2), + average_daily_working_hours=round(random.uniform(6, 10), 2), + work_related_casualties=random.randint(0, 10), + sales_amount=round(random.uniform(100000, 1000000), 2), + returns_amount=round(random.uniform(10000, 100000), 2), + privacy_breach_incidents=random.choice(['是', '否']), + total_service_times=random.randint(100, 500), + valid_customer_complaints=random.randint(0, 20), + complaints_resolved=random.randint(0, 20), + complaint_response_time=round(random.uniform(0.5, 24), 2), + rmb_account_bank_name=random.choice(['天朝银行', '天朝商业银行', '天朝建设银行', '天朝农业银行', '天朝邮政储蓄银行']), + rmb_bank_account=''.join(random.choices(string.digits, k=16)), + foreign_currency_bank_name=random.choice(['鹰酱银行', '龟谷银行', '棒子银行', '小日子银行', '骆驼银行']), + foreign_currency_bank_account=''.join(random.choices(string.ascii_uppercase + string.digits, k=18)), + loan_card_number=''.join(random.choices(string.ascii_uppercase + string.digits, k=16)), + operating_site_area=round(random.uniform(100, 1000), 2), + operating_site_location=fake.address(), + operating_site_ownership=random.choice(['自有', '租赁']), + has_quality_management_system=random.choice(['是', '否']), + has_financial_management_system=random.choice(['是', '否']), + has_contract_management_system=random.choice(['是', '否']), + has_hr_management_system=random.choice(['是', '否']), + business_credit_record=fake.paragraph(), + customs_credit_record=fake.paragraph(), + bank_credit_record=fake.paragraph(), + court_credit_record=fake.paragraph(), + production_safety_information=fake.paragraph(), + social_responsibility_implementation=fake.paragraph(), + ) + company_research_info.save() + return company_research_info + + +def generate_simple_financial_report(company, year): + + simple_financial_report = SimpleFinancialReport( + financial_report_id=shortuuid.uuid(), + company=company, + company_name=company.company_name, + report_date=datetime(year, 12, 31), + currency_funds=round(random.uniform(10000, 100000), 2), + accounts_receivable=round(random.uniform(10000, 100000), 2), + other_receivables=round(random.uniform(10000, 100000), 2), + prepayments=round(random.uniform(10000, 100000), 2), + inventory=round(random.uniform(10000, 100000), 2), + total_current_assets=round(random.uniform(100000, 1000000), 2), + total_non_current_assets=round(random.uniform(100000, 1000000), 2), + original_value_fixed_assets=round(random.uniform(100000, 1000000), 2), + accumulated_depreciation=round(random.uniform(10000, 100000), 2), + net_value_fixed_assets=round(random.uniform(100000, 1000000), 2), + total_fixed_assets=round(random.uniform(100000, 1000000), 2), + total_intangible_and_other_assets=round(random.uniform(10000, 100000), 2), + total_assets=round(random.uniform(1000000, 10000000), 2), + short_term_loans=round(random.uniform(10000, 100000), 2), + notes_payable=round(random.uniform(10000, 100000), 2), + accounts_payable=round(random.uniform(10000, 100000), 2), + advance_payments=round(random.uniform(10000, 100000), 2), + interest_payable=round(random.uniform(1000, 10000), 2), + other_payables=round(random.uniform(1000, 10000), 2), + total_current_liabilities=round(random.uniform(100000, 1000000), 2), + long_term_loans=round(random.uniform(10000, 100000), 2), + bonds_payable=round(random.uniform(10000, 100000), 2), + total_non_current_liabilities=round(random.uniform(100000, 1000000), 2), + total_liabilities=round(random.uniform(1000000, 10000000), 2), + undistributed_profit=round(random.uniform(10000, 100000), 2), + total_equity=round(random.uniform(100000, 1000000), 2), + operating_income=round(random.uniform(100000, 1000000), 2), + operating_costs=round(random.uniform(10000, 100000), 2), + interest_expense=round(random.uniform(1000, 10000), 2), + net_profit=round(random.uniform(10000, 100000), 2), + audited=random.choice(['是', '否']), + accounting_firm=random.choice(['普华永道中天会计师事务所(特殊普通合伙)', '安永华明会计师事务所(特殊普通合伙)', '毕马威华振会计师事务所(特殊普通合伙)', '德勤华永会计师事务所(特殊普通合伙)']), + ) + simple_financial_report.save() + + +# 创建企业信用数据 +def generate_company_credit_data(company): + company_credit_data = CompanyCreditData( + company_credit_data_id=shortuuid.uuid(), + company=company, + company_name=company.company_name, + years_in_operation=random.randint(1, 30), + shareholder_changes_last_three_years=random.randint(0, 5), + negative_public_opinions_ratio=round(random.uniform(0, 1), 2), + litigation_announcements=random.randint(0, 10), + tax_credit_rating=random.choice(['A', 'B', 'C', 'D']), + double_random_check_result=fake.sentence(), + abnormal_business_operations=random.randint(0, 10), + tax_notice=random.randint(0, 10), + admin_penalty_warnings=random.randint(0, 10), + admin_penalty_confiscation=random.randint(0, 10), + judgment_debtor=random.randint(0, 10), + dishonest_judgment_debtor=random.randint(0, 10), + tax_violations=random.randint(0, 10), + serious_violations=random.randint(0, 10), + ) + company_credit_data.save() + + +def main(): + # 生成30条模拟数据 + for _ in range(30): + company = generate_company_research_info() + generate_company_credit_data(company) + for year in range(2019, 2024): + generate_simple_financial_report(company, year) + + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6c96732 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +Django==5.0.2 +shortuuid==1.0.11 +Faker==23.2.1 \ No newline at end of file