diff --git a/.gitignore b/.gitignore index 8d2c0236..48c3cf9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,10 @@ /.ENV/ /.git/ /secrets.ini -/secrets.ini.example /app.ini /.vscode/ -/FRP/ -/FRP - Copy/ +/.idea/ +/frp/ /logs/ /nginx/ /resource/ @@ -13,6 +12,20 @@ /static/ /staticfiles/ +# 子服务器示例(含 HTTPS 私钥与 SQLite 数据,防入库) +/ATestCServer/ + +# 用户上传目录 +/media/ + +# 运行时日志与状态文件 +/service.log +/service_err.log +/ips.txt +/iptimes.txt +/times.txt +/timer.txt + # GERP 新前端工程(独立 git 仓库) /GERP/ # GERP 的编译文件 @@ -24,9 +37,8 @@ __pycache__/ *.pyc -# GVSite 前端工程构建产物 -/GVSite/dist/ -/GVSite/node_modules/ +# GVSite 前端工程(独立 git 仓库,防 gitlink 误提交) +/GVSite/ # GVSite 生产部署产物(TempLate/GVSite,由 deploy.ps1 同步) /TempLate/GVSite/ diff --git a/ATestCServer/ATestCServer/__init__.py b/ATestCServer/ATestCServer/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ATestCServer/ATestCServer/asgi.py b/ATestCServer/ATestCServer/asgi.py deleted file mode 100644 index bf1f42f4..00000000 --- a/ATestCServer/ATestCServer/asgi.py +++ /dev/null @@ -1,5 +0,0 @@ -import os -from django.core.asgi import get_asgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ATestCServer.settings') -application = get_asgi_application() \ No newline at end of file diff --git a/ATestCServer/ATestCServer/settings.py b/ATestCServer/ATestCServer/settings.py deleted file mode 100644 index eafcfc87..00000000 --- a/ATestCServer/ATestCServer/settings.py +++ /dev/null @@ -1,153 +0,0 @@ -"""ATestCServer — SMANAGE 子服务器 -通过 MSYNC 协议与 SMANAGE 主服务器(www.gvsds.com)桥接。 - -通信拓扑: - 子 → 父: https://www.gvsds.com/api/msync/* (MSYNC 协议) - 父 → 子: http://127.0.0.1:25080/api/sub/* (本地回环)""" - -import os -from pathlib import Path -from django.core.exceptions import ImproperlyConfigured - -BASE_DIR = Path(__file__).resolve().parent.parent - -SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY') -if not SECRET_KEY: - raise ImproperlyConfigured('DJANGO_SECRET_KEY 环境变量未设置,禁止使用默认值启动') - -DEBUG = os.environ.get('DJANGO_DEBUG', 'False').lower() in ('true', '1', 'yes') - -ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost,127.0.0.1').split(',') - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'rest_framework', - 'gvsdsdk', - 'apps.sub_server', -] - -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 = 'ATestCServer.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - '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 = 'ATestCServer.wsgi.application' - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': os.environ.get('DB_NAME', 'atestc'), - 'USER': os.environ.get('DB_USER', 'root'), - 'PASSWORD': os.environ.get('DB_PASSWORD', ''), - 'HOST': os.environ.get('DB_HOST', '127.0.0.1'), - 'PORT': os.environ.get('DB_PORT', '3306'), - 'OPTIONS': { - 'charset': 'utf8mb4', - 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", - }, - }, -} - -DATABASE_ROUTERS = [] - -# gvsdsdk 表由 ATestCServer 自己管理(同源数据库) -GVSDSDK_MANAGE_TABLES = True - -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'}, -] - -LANGUAGE_CODE = 'zh-hans' -TIME_ZONE = 'Asia/Shanghai' -USE_I18N = True -USE_TZ = False - -STATIC_URL = 'static/' - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -REST_FRAMEWORK = { - 'DEFAULT_RENDERER_CLASSES': [ - 'rest_framework.renderers.JSONRenderer', - ], - 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework.authentication.SessionAuthentication', - ], - 'DEFAULT_PERMISSION_CLASSES': [ - 'rest_framework.permissions.IsAuthenticated', - ], - 'UNAUTHENTICATED_USER': None, -} - -MSYNC_MASTER_URL = os.environ.get('MSYNC_MASTER_URL', 'https://www.gvsds.com') - -MSYNC_SERVICE_NAME = os.environ.get('MSYNC_SERVICE_NAME', 'atest-cserver') -MSYNC_SERVICE_DOMAIN = os.environ.get('MSYNC_SERVICE_DOMAIN', 'http://127.0.0.1:25080') -MSYNC_SERVICE_SECRET = os.environ.get('MSYNC_SERVICE_SECRET') -if not MSYNC_SERVICE_SECRET: - raise ImproperlyConfigured('MSYNC_SERVICE_SECRET 环境变量未设置,禁止使用默认值启动') - -MSYNC_SERVICE_SCOPE = [ - 'ogm:read', 'ogm:write', - 'registry:read', - 'tx:participate', -] - -MSYNC_HEARTBEAT_INTERVAL = int(os.environ.get('MSYNC_HEARTBEAT_INTERVAL', '30')) - -HTTP_PORT = int(os.environ.get('HTTP_PORT', '25080')) -HTTPS_PORT = int(os.environ.get('HTTPS_PORT', '25443')) - -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'verbose': { - 'format': '[{levelname}] {asctime} {module} {message}', - 'style': '{', - }, - }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'verbose', - }, - }, - 'loggers': { - '': { - 'handlers': ['console'], - 'level': 'INFO', - }, - }, -} \ No newline at end of file diff --git a/ATestCServer/ATestCServer/urls.py b/ATestCServer/ATestCServer/urls.py deleted file mode 100644 index 79a124b6..00000000 --- a/ATestCServer/ATestCServer/urls.py +++ /dev/null @@ -1,21 +0,0 @@ -"""根 URL 配置""" - -from django.urls import path, include -from django.shortcuts import redirect -from apps.sub_server.views import HealthView -from apps.sub_server import views - - -def root_redirect(request): - return redirect('/api/sub/status/') - - -urlpatterns = [ - path('', root_redirect), - path('health/', HealthView.as_view(), name='health'), - path('api/sub/', include('apps.sub_server.urls')), - # SDK 契约路径:主服务器 Saga 编排引擎按 /api/msync/local/* 回调 - path('api/msync/local/execute/', views.LocalExecuteView.as_view(), name='msync_local_execute'), - path('api/msync/local/compensate/', views.LocalCompensateView.as_view(), name='msync_local_compensate'), - path('api/msync/local/reset/', views.LocalResetView.as_view(), name='msync_local_reset'), -] \ No newline at end of file diff --git a/ATestCServer/ATestCServer/wsgi.py b/ATestCServer/ATestCServer/wsgi.py deleted file mode 100644 index e5aa4e00..00000000 --- a/ATestCServer/ATestCServer/wsgi.py +++ /dev/null @@ -1,5 +0,0 @@ -import os -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ATestCServer.settings') -application = get_wsgi_application() \ No newline at end of file diff --git a/ATestCServer/apps/__init__.py b/ATestCServer/apps/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ATestCServer/apps/sub_server/__init__.py b/ATestCServer/apps/sub_server/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ATestCServer/apps/sub_server/apps.py b/ATestCServer/apps/sub_server/apps.py deleted file mode 100644 index 6e3fdab0..00000000 --- a/ATestCServer/apps/sub_server/apps.py +++ /dev/null @@ -1,72 +0,0 @@ -"""模块:子服务器 AppConfig -Django 启动时自动完成 MSYNC Socket.IO 桥接——连接、注册、认证、心跳。""" - -import logging -import threading -from django.apps import AppConfig -from django.conf import settings - -logger = logging.getLogger(__name__) - -# 与主服务器约定的 SDK 最低版本——版本不一致时启动警告 -REQUIRED_GVSDSDK_VERSION = '1.1.0' - - -class SubServerConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'apps.sub_server' - verbose_name = 'SMANAGE 子服务器' - verbose_name_plural = 'SMANAGE 子服务器' - - def ready(self): - # 1) 校验 gvsdsdk 版本与主服务器一致 - self._check_sdk_version() - # 2) 注册实验本地事务处理器(供主服务器 Saga 编排回调) - self._register_local_handlers() - # 3) 启动 MSYNC 桥接 - self._connect_msync() - - def _register_local_handlers(self): - try: - from .local_handlers import RegisterExperimentHandlers - RegisterExperimentHandlers() - logger.info('实验本地事务处理器已注册: demo_a/demo_b/demo_fail/demo_flaky') - except Exception as e: - logger.error(f'实验本地事务处理器注册失败: {e}') - - def _check_sdk_version(self): - try: - import gvsdsdk - info = gvsdsdk.get_version_info() - logger.info(f'[SDK] 加载: v{info["Version"]} @ {info["Location"]}') - ok, msg = gvsdsdk.check_min_version(REQUIRED_GVSDSDK_VERSION) - if ok: - logger.info(f'[SDK] {msg}') - else: - logger.warning(f'[SDK] 版本不符!{msg}。双端 gvsdsdk 版本必须一致!') - except ImportError as e: - logger.error(f'[SDK] gvsdsdk 未安装: {e}') - except Exception as e: - logger.error(f'[SDK] 版本检查失败: {e}') - - def _connect_msync(self): - try: - from msync_client.sio_client import MSyncSocketClient - - msync_client = MSyncSocketClient( - master_url=settings.MSYNC_MASTER_URL, - service_name=settings.MSYNC_SERVICE_NAME, - service_domain=settings.MSYNC_SERVICE_DOMAIN, - service_secret=settings.MSYNC_SERVICE_SECRET, - scope=settings.MSYNC_SERVICE_SCOPE, - heartbeat_interval=settings.MSYNC_HEARTBEAT_INTERVAL, - metadata={'DBName': settings.DATABASES['default']['NAME']}, - ) - - setattr(settings, 'MSYNC_CLIENT', msync_client) - - t = threading.Thread(target=msync_client.Connect, daemon=True) - t.start() - logger.info('MSYNC Socket.IO 桥接线程已启动') - except Exception as e: - logger.error(f'MSYNC 桥接启动失败: {e}') diff --git a/ATestCServer/apps/sub_server/form_service.py b/ATestCServer/apps/sub_server/form_service.py deleted file mode 100644 index 8d960bc9..00000000 --- a/ATestCServer/apps/sub_server/form_service.py +++ /dev/null @@ -1,22 +0,0 @@ -"""模块:ATestCServer FormService -使用 gvsdsdk 通用 FormService 引擎暴露子服务器 ORM 表。""" - -from gvsdsdk.form_service import FormServiceBase -from .models import BusinessUser, BusinessOrder, SyncLog - - -class ATestCFormService(FormServiceBase): - TABLE_MAP = { - 'BusinessUser': BusinessUser, - 'BusinessOrder': BusinessOrder, - 'SyncLog': SyncLog, - } - - ENTITY_PICKER_MAP = { - 'BusinessUser': { - 'api': '/api/sub/form/action', - 'labelField': 'Username', - 'valueField': 'UserID', - 'placeholder': '输入用户名搜索...', - }, - } diff --git a/ATestCServer/apps/sub_server/local_handlers.py b/ATestCServer/apps/sub_server/local_handlers.py deleted file mode 100644 index a97818fd..00000000 --- a/ATestCServer/apps/sub_server/local_handlers.py +++ /dev/null @@ -1,53 +0,0 @@ -"""实验用本地事务处理器 - -随子服务器进程(runserver)启动即注册,供主服务器 Saga 编排回调。 -msync_experiment 管理命令与 HTTP 服务共用同一进程内处理器。 -""" - -import uuid - -from gvsdsdk.msync.local_tx import local_tx - -# demo_flaky 重试实验状态(进程内计数器,可通过 local/reset 端点清零) -_flaky_state = {'attempts': 0} - - -def _ActionA(payload): - return {'demo_a_uuid': str(uuid.uuid4()), 'received': payload} - - -def _ActionB(payload): - # 返回收到的完整 payload,供主服务器验证步骤间数据流 - return {'received_payload': payload} - - -def _CompensateA(payload, action_result): - return {'compensated': True, 'action_result': action_result} - - -def _ActionFail(payload): - raise RuntimeError('确定性失败(实验)') - - -def _ActionFlaky(payload): - _flaky_state['attempts'] += 1 - if _flaky_state['attempts'] == 1: - raise RuntimeError('首次失败(实验:验证自动重试)') - return {'retried': True, 'attempts': _flaky_state['attempts']} - - -def RegisterExperimentHandlers(): - """注册全部实验处理器(幂等:已存在则跳过)""" - for name, action, compensate in ( - ('demo_a', _ActionA, _CompensateA), - ('demo_b', _ActionB, None), - ('demo_fail', _ActionFail, None), - ('demo_flaky', _ActionFlaky, None), - ): - if not local_tx.HasHandler(name): - local_tx.register(name, action=action, compensate=compensate) - - -def ResetExperimentState(): - """清零重试实验状态(供 local/reset 端点调用)""" - _flaky_state['attempts'] = 0 diff --git a/ATestCServer/apps/sub_server/management/__init__.py b/ATestCServer/apps/sub_server/management/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ATestCServer/apps/sub_server/management/commands/__init__.py b/ATestCServer/apps/sub_server/management/commands/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ATestCServer/apps/sub_server/management/commands/msync_experiment.py b/ATestCServer/apps/sub_server/management/commands/msync_experiment.py deleted file mode 100644 index cc0d80bc..00000000 --- a/ATestCServer/apps/sub_server/management/commands/msync_experiment.py +++ /dev/null @@ -1,202 +0,0 @@ -"""msync_experiment — MSYNC 主从链路自动化实验与验证 - -用法: - python manage.py msync_experiment - -前置条件: - - 主服务器在线(SIO + HTTP),且本服务已通过 MSYNC 桥接注册成功 - - 本服务 local 端点可被主服务器访问(MSYNC_SERVICE_DOMAIN) - -自动执行并输出 PASS/FAIL 汇报表: - 1. 环境状态: SDK 版本 / SIO 连接 / 认证 / 注册 - 2. 正向 Saga: 多步骤成功 → Committed,且验证步骤间数据流 - 3. 失败补偿: 步骤失败 → 逆序补偿 → Compensated - 4. 自动重试: 步骤首次失败 → 主服务器按 CanRetry 自动重试成功 - 5. 幂等去重: local_tx 相同 Idempotency-Key 命中缓存 -""" - -import logging -import time - -from django.conf import settings -from django.core.management.base import BaseCommand - -logger = logging.getLogger(__name__) - - -def _get_msync(): - return getattr(settings, 'MSYNC_CLIENT', None) - - -class Command(BaseCommand): - help = 'MSYNC 主从链路自动化实验与验证' - - def add_arguments(self, parser): - parser.add_argument( - '--wait-seconds', type=int, default=10, - help='等待桥接就绪的秒数(默认 10)', - ) - - def handle(self, *args, **options): - self.results = [] - wait_seconds = options['wait_seconds'] - - self.out('=' * 60) - self.out('MSYNC 主从链路自动化实验') - self.out('=' * 60) - - msync = _get_msync() - if msync is None: - self.fail('MSYNC 未初始化', 'settings.MSYNC_CLIENT 不存在,桥接线程未启动') - return - - # 1. 等待桥接就绪(连接/注册/认证) - self.record('等待桥接就绪', self._wait_ready(msync, wait_seconds)) - self._report_status(msync) - - # 2. 注册本地实验步骤处理器 - self.record('注册本地步骤处理器', self._register_handlers(), 'demo_a/demo_b/demo_fail') - - # 3. 正向 Saga + 步骤数据流 - self.record('正向 Saga(数据流)', self._experiment_forward(msync)) - - # 4. 失败补偿 - self.record('失败补偿', self._experiment_compensate(msync)) - - # 5. 自动重试 - self.record('自动重试', self._experiment_retry(msync)) - - # 6. 幂等去重 - self.record('幂等去重', self._experiment_idempotency()) - - self._summary() - - # ─── 工具 ────────────────────────────────────────────── - - def out(self, msg): - self.stdout.write(msg) - - def record(self, name, ok, detail=''): - self.results.append((name, bool(ok), detail or '')) - mark = 'PASS' if ok else 'FAIL' - self.stdout.write(f' [{mark}] {name}' + (f' ({detail})' if detail else '')) - - def fail(self, name, detail=''): - self.record(name, False, detail) - - def _wait_ready(self, msync, seconds): - for _ in range(seconds * 2): - if msync.IsConnected and msync.IsAuthenticated and msync.IsRegistered: - return True - time.sleep(0.5) - return msync.IsConnected and msync.IsAuthenticated and msync.IsRegistered - - def _report_status(self, msync): - import gvsdsdk - info = gvsdsdk.get_version_info() - self.out(f'\n SDK 版本 : {info["Version"]} @ {info["Location"]}') - self.out(f' SIO 连接 : {msync.IsConnected}') - self.out(f' 密钥认证 : {msync.IsAuthenticated}') - self.out(f' 服务注册 : {msync.IsRegistered}') - self.out(f' 服务名称 : {msync.ServiceName}') - self.out(f' 主服务器 : {msync.MasterURL}') - - # ─── 实验步骤 ────────────────────────────────────────── - - def _register_handlers(self): - from apps.sub_server.local_handlers import RegisterExperimentHandlers - from gvsdsdk.msync.local_tx import local_tx - - RegisterExperimentHandlers() - return all(local_tx.HasHandler(n) for n in ('demo_a', 'demo_b')) - - def _create_and_execute(self, msync, name, steps, timeout_seconds=120): - created = msync.TxCreate(name, steps, timeout_seconds=timeout_seconds) - if not created: - return None, 'TxCreate 失败' - tx_code = created.get('TransactionCode') - detail = msync.TxExecute(tx_code, access_token=msync.AccessToken) - if detail is None: - return tx_code, 'TxExecute 失败' - return tx_code, detail - - def _experiment_forward(self, msync): - tx_code, detail = self._create_and_execute(msync, '实验-正向', [ - {'name': 'demo_a', 'ParticipantService': msync.ServiceName, 'ActionPayload': {'in': 'a'}}, - {'name': 'demo_b', 'ParticipantService': msync.ServiceName, 'ActionPayload': {'in': 'b'}}, - ]) - if not detail: - return False - - self.out(f'\n 正向事务 {tx_code}: Status={detail.get("Status")} / Code={detail.get("StatusCode")}') - committed = detail.get('StatusCode') == 2 - if not committed: - self.out(f' 事务未提交: {detail}') - return False - - steps = {s['Index']: s for s in detail.get('Steps', [])} - step_a, step_b = steps.get(0), steps.get(1) - if not step_a or not step_b: - return False - - result_b = (step_b.get('Result') or {}).get('received_payload') or {} - flow_ok = bool(result_b.get('demo_a_uuid')) # demo_b 收到 demo_a 的输出 → 数据流生效 - self.out(f' 数据流验证: demo_b 收到 demo_a_uuid = {result_b.get("demo_a_uuid")}') - return committed and flow_ok - - def _experiment_compensate(self, msync): - tx_code, detail = self._create_and_execute(msync, '实验-补偿', [ - {'name': 'demo_a', 'ParticipantService': msync.ServiceName}, - {'name': 'demo_fail', 'ParticipantService': msync.ServiceName, 'MaxRetries': 0}, - ]) - if not detail: - return False - self.out(f'\n 补偿事务 {tx_code}: Status={detail.get("Status")} / Code={detail.get("StatusCode")}') - steps = {s['Index']: s for s in detail.get('Steps', [])} - return detail.get('StatusCode') == 4 and steps.get(0, {}).get('Status') in ('已补偿', 'Compensated') - - def _experiment_retry(self, msync): - self._reset_flaky_state() - tx_code, detail = self._create_and_execute(msync, '实验-重试', [ - {'name': 'demo_flaky', 'ParticipantService': msync.ServiceName, 'MaxRetries': 2}, - ]) - if not detail: - return False - self.out(f'\n 重试事务 {tx_code}: Status={detail.get("Status")} / Code={detail.get("StatusCode")}') - steps = {s['Index']: s for s in detail.get('Steps', [])} - step = steps.get(0, {}) - ok = detail.get('StatusCode') == 2 and step.get('RetryCount', 0) >= 1 - self.out(f' 自动重试次数: {step.get("RetryCount")}(要求 >=1)') - return ok - - def _reset_flaky_state(self): - """重置 runserver 进程内的 demo_flaky 计数器(通过 local/reset 端点)""" - import requests - try: - reset_url = f'{settings.MSYNC_SERVICE_DOMAIN}/api/msync/local/reset/' - requests.post(reset_url, timeout=5) - except Exception: - pass - - def _experiment_idempotency(self): - from gvsdsdk.msync.local_tx import local_tx - - r1 = local_tx.ExecuteStep('no_such_demo', {}, 'EXP:1:0') - r2 = local_tx.ExecuteStep('no_such_demo', {}, 'EXP:1:0') - r3 = local_tx.ExecuteStep('no_such_demo', {}, 'EXP:1:1') - return r1 is r2 and r1 is not r3 - - # ─── 汇报 ────────────────────────────────────────────── - - def _summary(self): - self.out('\n' + '=' * 60) - self.out('实验汇报') - self.out('=' * 60) - passed = sum(1 for _, ok, _ in self.results if ok) - for name, ok, detail in self.results: - mark = '✓' if ok else '✗' - self.out(f' {mark} {name}' + (f' ({detail})' if detail else '')) - self.out(f'\n结果: {passed}/{len(self.results)} 通过') - if passed != len(self.results): - self.stdout.write(self.style.ERROR('存在未通过的实验环节,请查看上方明细')) - raise SystemExit(1) diff --git a/ATestCServer/apps/sub_server/migrations/0001_initial.py b/ATestCServer/apps/sub_server/migrations/0001_initial.py deleted file mode 100644 index 39ed3c06..00000000 --- a/ATestCServer/apps/sub_server/migrations/0001_initial.py +++ /dev/null @@ -1,65 +0,0 @@ -# Generated by Django 6.0.5 on 2026-06-11 01:44 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='BusinessUser', - fields=[ - ('UserID', models.AutoField(primary_key=True, serialize=False)), - ('Username', models.CharField(max_length=64, unique=True)), - ('Nickname', models.CharField(default='', max_length=128)), - ('OGMMappingID', models.CharField(db_index=True, default='', max_length=128)), - ('JoinTime', models.DateTimeField(auto_now_add=True)), - ('UserStatus', models.SmallIntegerField(default=1)), - ], - options={ - 'verbose_name': '业务用户', - 'verbose_name_plural': '业务用户', - 'db_table': 'sub_business_user', - }, - ), - migrations.CreateModel( - name='SyncLog', - fields=[ - ('LogID', models.AutoField(primary_key=True, serialize=False)), - ('EventType', models.CharField(max_length=64)), - ('EventDetail', models.JSONField(default=dict)), - ('EventStatus', models.SmallIntegerField(default=1)), - ('CreateTime', models.DateTimeField(auto_now_add=True)), - ], - options={ - 'verbose_name': '同步日志', - 'verbose_name_plural': '同步日志', - 'db_table': 'sub_sync_log', - 'ordering': ['-CreateTime'], - }, - ), - migrations.CreateModel( - name='BusinessOrder', - fields=[ - ('OrderID', models.AutoField(primary_key=True, serialize=False)), - ('OrderCode', models.CharField(db_index=True, max_length=64, unique=True)), - ('Amount', models.DecimalField(decimal_places=4, max_digits=18)), - ('OrderStatus', models.SmallIntegerField(default=0)), - ('OGMMappingID', models.CharField(db_index=True, default='', max_length=128)), - ('CreateTime', models.DateTimeField(auto_now_add=True)), - ('UpdateTime', models.DateTimeField(auto_now=True)), - ('User', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='orders', to='sub_server.businessuser')), - ], - options={ - 'verbose_name': '业务订单', - 'verbose_name_plural': '业务订单', - 'db_table': 'sub_business_order', - }, - ), - ] diff --git a/ATestCServer/apps/sub_server/migrations/__init__.py b/ATestCServer/apps/sub_server/migrations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ATestCServer/apps/sub_server/models.py b/ATestCServer/apps/sub_server/models.py deleted file mode 100644 index 58bd95bd..00000000 --- a/ATestCServer/apps/sub_server/models.py +++ /dev/null @@ -1,66 +0,0 @@ -"""模块:子服务器数据模型 -模拟一个真实子服务器的业务数据结构。""" - -from django.db import models - - -class BusinessUser(models.Model): - """业务用户——模拟子服务器的本地用户数据""" - - UserID = models.AutoField(primary_key=True, verbose_name='用户ID') - Username = models.CharField(max_length=64, unique=True, verbose_name='用户名') - Nickname = models.CharField(max_length=128, default='', verbose_name='昵称') - OGMMappingID = models.CharField(max_length=128, default='', db_index=True, verbose_name='OGM映射ID') - JoinTime = models.DateTimeField(auto_now_add=True, verbose_name='加入时间') - UserStatus = models.SmallIntegerField(default=1, verbose_name='用户状态') - - class Meta: - db_table = 'sub_business_user' - verbose_name = '业务用户' - verbose_name_plural = '业务用户' - - def __str__(self): - return self.Username - - -class BusinessOrder(models.Model): - """业务订单——模拟子服务器的本地订单数据""" - - OrderID = models.AutoField(primary_key=True, verbose_name='订单ID') - OrderCode = models.CharField(max_length=64, unique=True, db_index=True, verbose_name='订单编号') - User = models.ForeignKey( - BusinessUser, on_delete=models.CASCADE, related_name='orders', - verbose_name='用户', - ) - Amount = models.DecimalField(max_digits=18, decimal_places=4, verbose_name='金额') - OrderStatus = models.SmallIntegerField(default=0, verbose_name='订单状态') - OGMMappingID = models.CharField(max_length=128, default='', db_index=True, verbose_name='OGM映射ID') - CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') - UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间') - - class Meta: - db_table = 'sub_business_order' - verbose_name = '业务订单' - verbose_name_plural = '业务订单' - - def __str__(self): - return self.OrderCode - - -class SyncLog(models.Model): - """同步日志——记录与主服务器 MSYNC 通信的事件""" - - LogID = models.AutoField(primary_key=True, verbose_name='日志ID') - EventType = models.CharField(max_length=64, verbose_name='事件类型') - EventDetail = models.JSONField(default=dict, verbose_name='事件详情') - EventStatus = models.SmallIntegerField(default=1, verbose_name='事件状态') - CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') - - class Meta: - db_table = 'sub_sync_log' - verbose_name = '同步日志' - verbose_name_plural = '同步日志' - ordering = ['-CreateTime'] - - def __str__(self): - return f'{self.EventType}@{self.CreateTime}' \ No newline at end of file diff --git a/ATestCServer/apps/sub_server/serializers.py b/ATestCServer/apps/sub_server/serializers.py deleted file mode 100644 index c924cf2a..00000000 --- a/ATestCServer/apps/sub_server/serializers.py +++ /dev/null @@ -1,34 +0,0 @@ -from rest_framework import serializers -from .models import BusinessUser, BusinessOrder, SyncLog - - -class BusinessUserSerializer(serializers.ModelSerializer): - class Meta: - model = BusinessUser - fields = ['UserID', 'Username', 'Nickname', 'OGMMappingID', 'JoinTime', 'UserStatus'] - read_only_fields = ['UserID', 'JoinTime', 'OGMMappingID'] - - -class BusinessOrderSerializer(serializers.ModelSerializer): - class Meta: - model = BusinessOrder - fields = ['OrderID', 'OrderCode', 'Amount', 'OrderStatus', 'OGMMappingID', 'CreateTime', 'UpdateTime', 'User'] - read_only_fields = ['OrderID', 'CreateTime', 'UpdateTime', 'OGMMappingID'] - - -class OrderCreateSerializer(serializers.Serializer): - username = serializers.CharField() - amount = serializers.DecimalField(max_digits=18, decimal_places=4) - - -class OGMRegisterSerializer(serializers.Serializer): - object_type = serializers.CharField() - local_id = serializers.CharField() - metadata = serializers.DictField(required=False, default=dict) - - -class SyncLogSerializer(serializers.ModelSerializer): - class Meta: - model = SyncLog - fields = ['LogID', 'EventType', 'EventDetail', 'EventStatus', 'CreateTime'] - read_only_fields = ['LogID', 'CreateTime'] \ No newline at end of file diff --git a/ATestCServer/apps/sub_server/service_auth.py b/ATestCServer/apps/sub_server/service_auth.py deleted file mode 100644 index c9c7c307..00000000 --- a/ATestCServer/apps/sub_server/service_auth.py +++ /dev/null @@ -1,81 +0,0 @@ -"""子服务器服务认证 - -主服务器调用子服务器 local 端点时携带 `Authorization: Service `。 -子服务器无法本地验证令牌(无主库 ServiceToken 表 / MASTER_SECRET), -因此通过主服务器 `/api/msync/auth/introspect/` 远程自省校验。 -""" - -import json -import logging -import urllib.request -import urllib.error - -from django.conf import settings -from rest_framework.authentication import BaseAuthentication -from rest_framework.exceptions import AuthenticationFailed - -logger = logging.getLogger(__name__) - -SERVICE_AUTH_HEADER = 'Authorization' -SERVICE_AUTH_PREFIX = 'Service' -INTROSPECT_PATH = '/api/msync/auth/introspect/' - - -class ServicePrincipal: - """服务主体——标识调用方服务""" - - def __init__(self, service_name): - self.service_name = service_name - self.service_scope = [] - - @property - def is_authenticated(self): - return True - - def __str__(self): - return f'Service:{self.service_name}' - - -class SubServerServiceAuthentication(BaseAuthentication): - """DRF 认证类——校验主服务器 Service 令牌(远程自省)""" - - def authenticate(self, request): - auth_header = request.headers.get(SERVICE_AUTH_HEADER, '') - if not auth_header.startswith(f'{SERVICE_AUTH_PREFIX} '): - return None - token = auth_header[len(SERVICE_AUTH_PREFIX) + 1:].strip() - if not token: - return None - - payload = self._Introspect(token) - if not payload: - raise AuthenticationFailed('服务令牌验证失败') - - return (ServicePrincipal(payload.get('sub', 'unknown')), token) - - def authenticate_header(self, request): - return 'Service' - - @staticmethod - def _Introspect(access_token): - """调用主服务器令牌自省端点""" - master_url = str(getattr(settings, 'MSYNC_MASTER_URL', '')).rstrip('/') - if not master_url: - return None - body = json.dumps({'AccessToken': access_token}).encode('utf-8') - req = urllib.request.Request( - f'{master_url}{INTROSPECT_PATH}', - data=body, - headers={'Content-Type': 'application/json'}, - method='POST', - ) - try: - with urllib.request.urlopen(req, timeout=10) as resp: - data = json.loads(resp.read().decode('utf-8')) - except (urllib.error.URLError, urllib.error.HTTPError, ValueError, OSError) as e: - logger.error(f'令牌自省失败: {e}') - return None - - if not data.get('Valid'): - return None - return data.get('Payload') or {} diff --git a/ATestCServer/apps/sub_server/templates/status.html b/ATestCServer/apps/sub_server/templates/status.html deleted file mode 100644 index 187cdd7b..00000000 --- a/ATestCServer/apps/sub_server/templates/status.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - -ATestCServer — MSYNC 连接状态 - - - -
-
-

ATestCServer

- SMANAGE 子服务器 · HTTP :25080 · HTTPS :25443 -
-
- - 断开 -
-
- -
- -
-

连接状态

-
加载中...
-
加载中...
-
加载中...
-
加载中...
-
自动刷新中...
-
- - -
-

服务标识

-
-
服务名—
-
域名—
-
主服务器—
-
Token—
-
-
- - -
-

对等服务

-
  • 加载中...
-
- - -
-

最近同步事件

-
  • 暂无事件
-
- - -
-

原始响应

-
{}
-
-
- - - - - - \ No newline at end of file diff --git a/ATestCServer/apps/sub_server/urls.py b/ATestCServer/apps/sub_server/urls.py deleted file mode 100644 index d3a8bb62..00000000 --- a/ATestCServer/apps/sub_server/urls.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.urls import path -from . import views - -app_name = 'sub_server' - -urlpatterns = [ - path('health/', views.HealthView.as_view(), name='health'), - path('status/', views.StatusPageView, name='status_page'), - path('msync/status/', views.MSyncStatusView.as_view(), name='msync_status'), - path('users/', views.UserListView.as_view(), name='user_list'), - path('users//', views.UserDetailView.as_view(), name='user_detail'), - path('orders/', views.OrderListView.as_view(), name='order_list'), - path('orders//', views.OrderDetailView.as_view(), name='order_detail'), - path('ogm/register/', views.OGMRegisterView.as_view(), name='ogm_register'), - path('ogm/resolve//', views.OGMResolveView.as_view(), name='ogm_resolve'), - path('remote/call/', views.RemoteCallDemoView.as_view(), name='remote_call'), - path('sync/logs/', views.SyncLogView.as_view(), name='sync_logs'), - path('local/execute/', views.LocalExecuteView.as_view(), name='local_execute'), - path('local/compensate/', views.LocalCompensateView.as_view(), name='local_compensate'), - path('local/handlers/', views.LocalHandlersView.as_view(), name='local_handlers'), -] \ No newline at end of file diff --git a/ATestCServer/apps/sub_server/views.py b/ATestCServer/apps/sub_server/views.py deleted file mode 100644 index 9b6389ca..00000000 --- a/ATestCServer/apps/sub_server/views.py +++ /dev/null @@ -1,420 +0,0 @@ -"""模块:子服务器 REST API 视图 -提供业务 CRUD 端点 + MSYNC 状态查询 + 服务间调用演示 + FormService ORM 管理。""" - -import logging -from django.conf import settings -from django.shortcuts import render -from rest_framework.views import APIView -from rest_framework.response import Response -from rest_framework.permissions import AllowAny, IsAuthenticated -from .service_auth import SubServerServiceAuthentication -from .models import BusinessUser, BusinessOrder, SyncLog -from .serializers import ( - BusinessUserSerializer, - BusinessOrderSerializer, - OrderCreateSerializer, - OGMRegisterSerializer, - SyncLogSerializer, -) - -logger = logging.getLogger(__name__) - - -def _ok(data=None, msg='success'): - return {'code': 200, 'msg': msg, 'data': data} - - -def _err(msg, code=400): - return {'code': code, 'msg': msg, 'data': None} - - -def _get_msync(): - """获取 MSYNC 客户端实例""" - return getattr(settings, 'MSYNC_CLIENT', None) - - -def _log_sync(event_type, detail, status=1): - """记录同步日志""" - try: - SyncLog.objects.create( - EventType=event_type, - EventDetail=detail, - EventStatus=status, - ) - except Exception: - pass - - -class HealthView(APIView): - authentication_classes = [] - permission_classes = [AllowAny] - - def get(self, request): - msync = _get_msync() - token = msync.AccessToken if msync else None - msync_status = { - 'Connected': msync.IsConnected if msync else False, - 'Authenticated': msync.IsAuthenticated if msync else False, - 'Registered': msync.IsRegistered if msync else False, - 'ServiceName': msync.ServiceName if msync else None, - 'ServiceDomain': msync.ServiceDomain if msync else None, - 'MasterURL': msync.MasterURL if msync else None, - 'AccessToken': 'exists' if token else 'none', - } - - # SDK 版本信息 - sdk_info = {'Name': 'gvsdsdk'} - try: - import gvsdsdk - sdk_info.update(gvsdsdk.get_version_info()) - except ImportError as e: - sdk_info['Error'] = str(e) - - # SAAS 数据库连接状态 - saas_db_status = {'Configured': 'saas' in settings.DATABASES} - try: - from django.db import connections - conn = connections['saas'] - conn.ensure_connection() - saas_db_status['Connected'] = True - # 尝试统计用户数验证连接可用 - from gvsdsdk.models import User - saas_db_status['UserCount'] = User.objects.using('saas').count() - except Exception as e: - saas_db_status['Connected'] = False - saas_db_status['Error'] = str(e) - - return Response(_ok({ - 'Server': 'ATestCServer', - 'Status': 'running', - 'MSync': msync_status, - 'SDK': sdk_info, - 'SAASDB': saas_db_status, - })) - - -class MSyncStatusView(APIView): - authentication_classes = [] - permission_classes = [AllowAny] - - def get(self, request): - msync = _get_msync() - if not msync: - return Response(_err('MSYNC 未初始化', 500), status=500) - - services = msync.DiscoverAll() - token = msync.AccessToken - return Response(_ok({ - 'ServiceName': msync.ServiceName, - 'ServiceDomain': msync.ServiceDomain, - 'MasterURL': msync.MasterURL, - 'Authenticated': msync.IsAuthenticated, - 'Registered': msync.IsRegistered, - 'Connected': msync.IsConnected, - 'AccessToken': 'exists' if token else 'none', - 'PeerServices': services, - })) - - -class UserListView(APIView): - - def get(self, request): - users = BusinessUser.objects.filter(UserStatus=1).order_by('-JoinTime') - return Response(_ok(BusinessUserSerializer(users, many=True).data)) - - def post(self, request): - username = request.data.get('username', '').strip() - nickname = request.data.get('nickname', '') - - if not username: - return Response(_err('用户名不能为空', 400), status=400) - - user, created = BusinessUser.objects.get_or_create( - Username=username, - defaults={'Nickname': nickname or username}, - ) - - if created: - msync = _get_msync() - if msync: - try: - ogm_result = msync.OGMRegister( - object_type='user', - local_id=str(user.UserID), - service_name=msync.ServiceName, - metadata={'username': username, 'nickname': nickname or username}, - ) - if ogm_result: - user.OGMMappingID = ogm_result.get('ObjectGlobalID', '') - user.save(update_fields=['OGMMappingID']) - _log_sync('ogm_register', { - 'object_type': 'user', - 'local_id': str(user.UserID), - 'global_id': user.OGMMappingID, - }) - except Exception as e: - logger.warning(f'OGM注册失败: {e}') - - status_code = 201 if created else 200 - return Response(_ok(BusinessUserSerializer(user).data), status=status_code) - - -class UserDetailView(APIView): - - def get(self, request, user_id): - try: - user = BusinessUser.objects.get(UserID=user_id) - except BusinessUser.DoesNotExist: - return Response(_err('用户不存在', 404), status=404) - return Response(_ok(BusinessUserSerializer(user).data)) - - -class OrderListView(APIView): - - def get(self, request): - orders = BusinessOrder.objects.all().order_by('-CreateTime')[:50] - return Response(_ok(BusinessOrderSerializer(orders, many=True).data)) - - def post(self, request): - ser = OrderCreateSerializer(data=request.data) - if not ser.is_valid(): - return Response(_err(ser.errors, 400), status=400) - - username = ser.validated_data['username'] - amount = ser.validated_data['amount'] - - try: - user = BusinessUser.objects.get(Username=username) - except BusinessUser.DoesNotExist: - return Response(_err('用户不存在', 404), status=404) - - import uuid - order = BusinessOrder.objects.create( - OrderCode=f'SUB-{uuid.uuid4().hex[:12].upper()}', - User=user, - Amount=amount, - OrderStatus=0, - ) - - msync = _get_msync() - if msync: - try: - ogm_result = msync.OGMRegister( - object_type='order', - local_id=str(order.OrderID), - service_name=msync.ServiceName, - metadata={ - 'order_code': order.OrderCode, - 'amount': str(amount), - 'user_id': str(user.UserID), - }, - ) - if ogm_result: - order.OGMMappingID = ogm_result.get('ObjectGlobalID', '') - order.save(update_fields=['OGMMappingID']) - _log_sync('ogm_register', { - 'object_type': 'order', - 'local_id': str(order.OrderID), - 'global_id': order.OGMMappingID, - }) - except Exception as e: - logger.warning(f'订单OGM注册失败: {e}') - - return Response(_ok(BusinessOrderSerializer(order).data), status=201) - - -class OrderDetailView(APIView): - - def get(self, request, order_id): - try: - order = BusinessOrder.objects.get(OrderID=order_id) - except BusinessOrder.DoesNotExist: - return Response(_err('订单不存在', 404), status=404) - return Response(_ok(BusinessOrderSerializer(order).data)) - - -class OGMRegisterView(APIView): - - def post(self, request): - ser = OGMRegisterSerializer(data=request.data) - if not ser.is_valid(): - return Response(_err(ser.errors, 400), status=400) - - msync = _get_msync() - if not msync: - return Response(_err('MSYNC 未初始化', 500), status=500) - - result = msync.OGMRegister( - object_type=ser.validated_data['object_type'], - local_id=ser.validated_data['local_id'], - service_name=msync.ServiceName, - metadata=ser.validated_data.get('metadata', {}), - ) - - if result: - _log_sync('ogm_register_manual', { - 'object_type': ser.validated_data['object_type'], - 'local_id': ser.validated_data['local_id'], - 'global_id': result.get('ObjectGlobalID', ''), - }) - return Response(_ok(result), status=201) - - return Response(_err('OGM注册失败', 500), status=500) - - -class OGMResolveView(APIView): - - def get(self, request, global_id): - msync = _get_msync() - if not msync: - return Response(_err('MSYNC 未初始化', 500), status=500) - - result = msync.OGMResolve(global_id) - if result: - return Response(_ok(result)) - return Response(_err('映射不存在', 404), status=404) - - -class RemoteCallDemoView(APIView): - - def get(self, request): - msync = _get_msync() - if not msync: - return Response(_err('MSYNC 未初始化', 500), status=500) - - services = msync.DiscoverAll() - results = [] - - for svc in services: - svc_name = svc.get('ServiceName', '') - if svc_name == msync.ServiceName: - continue - - target_domain = svc.get('ServiceDomain', '') - resp = msync.CallRemote( - service_name=svc_name, - method='GET', - path='/health/', - ) - - if resp is None: - results.append({ - 'service': svc_name, - 'domain': target_domain, - 'error': '远端调用失败', - }) - else: - # CallRemote 返回 requests.Response(或 dict 时兼容) - if isinstance(resp, dict): - body = resp - else: - try: - body = resp.json() - except ValueError: - body = {'code': resp.status_code, 'msg': resp.text[:200], 'data': None} - results.append({ - 'service': svc_name, - 'domain': target_domain, - 'code': body.get('code'), - 'msg': body.get('msg'), - 'data': body.get('data'), - }) - - return Response(_ok(results)) - - -class SyncLogView(APIView): - authentication_classes = [] - permission_classes = [AllowAny] - - def get(self, request): - logs = SyncLog.objects.all()[:50] - return Response(_ok(SyncLogSerializer(logs, many=True).data)) - - -def StatusPageView(request): - """连接状态仪表盘页面""" - return render(request, 'status.html', { - 'service_name': settings.MSYNC_SERVICE_NAME, - 'service_domain': settings.MSYNC_SERVICE_DOMAIN, - 'master_url': settings.MSYNC_MASTER_URL, - }) - - -class LocalExecuteView(APIView): - """本地事务执行端点——由主服务器 Saga 编排引擎调用(需主服务器 Service 令牌)""" - - authentication_classes = [SubServerServiceAuthentication] - permission_classes = [IsAuthenticated] - - def post(self, request): - from gvsdsdk.msync.local_tx import local_tx - - step_name = request.data.get('StepName', '') - payload = request.data.get('payload') or {} - idempotency_key = request.headers.get('Idempotency-Key') - - if not step_name: - return Response(_err('StepName 不能为空', 400), status=400) - - result = local_tx.ExecuteStep( - name=step_name, - payload=payload, - idempotency_key=idempotency_key, - ) - - if result['success']: - return Response(_ok(result['result'])) - return Response(_err(result['error'], 500), status=500) - - -class LocalCompensateView(APIView): - """本地事务补偿端点——由主服务器 Saga 编排引擎调用(需主服务器 Service 令牌)""" - - authentication_classes = [SubServerServiceAuthentication] - permission_classes = [IsAuthenticated] - - def post(self, request): - from gvsdsdk.msync.local_tx import local_tx - - step_name = request.data.get('StepName', '') - payload = request.data.get('payload') or {} - action_result = request.data.get('ActionResult') or {} - idempotency_key = request.headers.get('Idempotency-Key') - - if not step_name: - return Response(_err('StepName 不能为空', 400), status=400) - - result = local_tx.CompensateStep( - name=step_name, - payload=payload, - action_result=action_result, - idempotency_key=idempotency_key, - ) - - if result['success']: - return Response(_ok(result['result'])) - return Response(_err(result['error'], 500), status=500) - - -class LocalHandlersView(APIView): - """列出已注册的本地事务步骤处理器""" - - authentication_classes = [SubServerServiceAuthentication] - permission_classes = [IsAuthenticated] - - def get(self, request): - from gvsdsdk.msync.local_tx import local_tx - return Response(_ok(local_tx.ListHandlers())) - - -class LocalResetView(APIView): - """重置实验处理器状态(demo_flaky 重试计数清零),仅限本地回环使用""" - - authentication_classes = [] - permission_classes = [AllowAny] - - def post(self, request): - from .local_handlers import ResetExperimentState - ResetExperimentState() - return Response(_ok({'reset': True})) \ No newline at end of file diff --git a/ATestCServer/certs/cert.pem b/ATestCServer/certs/cert.pem deleted file mode 100644 index 1bbc20b3..00000000 --- a/ATestCServer/certs/cert.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDDzCCAfegAwIBAgIUHtoO8DpIL/M32xypjXvfWJ4DBncwDQYJKoZIhvcNAQEL -BQAwFzEVMBMGA1UEAwwMQVRlc3RDU2VydmVyMB4XDTI2MDYxMDE3NDQwMloXDTI3 -MDYxMDE3NDQwMlowFzEVMBMGA1UEAwwMQVRlc3RDU2VydmVyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAudYM0z+CR/wmG1b26549CJg7OU0xWONDExZM -AVLByEoIj7r/GxiS/FFxA3Fu6a9T98ddd+j80Qmimkjlp6kLl6wHASkvcpyiDQiw -Glp7xwE7hLVbyHw8Sd8z/cLidPaSft4qCh6GZW5yE/XqnGgmlFXpS+458QMmoQck -enROeBnYQvu0DA34pHiPNiICn8S3luc+qQ1XFcDLBE8LERCypdJsO21n6J/94lRG -AJXuEyOzbjcIShRUZpy7KRmQaeo7NLjbanvpKajhLITWKd9fdATkut3hcPjsPdtt -f0icu3ScJaQKGMWuIcfHFK9rC9ACj67XwsZ7bR79D2viEDK9NQIDAQABo1MwUTAd -BgNVHQ4EFgQUCdTC/KUqxAEVGXmuoPP8hh+7ZpowHwYDVR0jBBgwFoAUCdTC/KUq -xAEVGXmuoPP8hh+7ZpowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC -AQEAfk1BH3jURvnBby2ViIq1hohnzAQvpkpedmiDmtkQXilbAF2Wwc1Fb386L8Ba -eOgEYlglsPIvYoMtW3Jjd+2Xw6ZlRObYK+yBr+SUSJ3/DVOislYStBoq5Z2dTedV -N+C8xVRg3fTYsZbk4zzZrQ0p9EdEFVkNAwxh/Q+lipZhv4IW5OXMnYYI2nfq1lJ3 -sx/wQT6X/t9aHAX3ain2OifquuE+NPs98D6e2Ge0PeLTgJBdvVO1cguuQTfhz71c -Jk/nSZCcxBraoIVnDQbsThv2TUaCFt+7H6lqTyoFCd+dzMjoG75Ndhg/QUKLkAyr -RQ8FTNs63xPctOKSFGUwA0JY/Q== ------END CERTIFICATE----- diff --git a/ATestCServer/certs/key.pem b/ATestCServer/certs/key.pem deleted file mode 100644 index 6e5659b8..00000000 --- a/ATestCServer/certs/key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC51gzTP4JH/CYb -Vvbrnj0ImDs5TTFY40MTFkwBUsHISgiPuv8bGJL8UXEDcW7pr1P3x1136PzRCaKa -SOWnqQuXrAcBKS9ynKINCLAaWnvHATuEtVvIfDxJ3zP9wuJ09pJ+3ioKHoZlbnIT -9eqcaCaUVelL7jnxAyahByR6dE54GdhC+7QMDfikeI82IgKfxLeW5z6pDVcVwMsE -TwsRELKl0mw7bWfon/3iVEYAle4TI7NuNwhKFFRmnLspGZBp6js0uNtqe+kpqOEs -hNYp3190BOS63eFw+Ow9221/SJy7dJwlpAoYxa4hx8cUr2sL0AKPrtfCxnttHv0P -a+IQMr01AgMBAAECggEAAxbtxEG7Au2y0FryeeitEp+bbLkoUYDmBHqWDYA+9LcQ -x7TSEr2M8zzhHsCzZkHsueLREbIuwqKHaCkuTEINHnRQrm4o03vPGTuCPoovkaAe -ljsz60VFOVMvBVSmnxwwEHLEYDmPOfrxyh5MbneWi0b9cC5/gT20q2dq9kWNNZ9T -fDe1PAGuPoNujW+NqSs83SXtFpP52JX7T5TjzBtXDB3JYw10j/fdeMfGct/cxvp/ -MK+jeXuXJbRtsyzVk2Ji9gJQo1RQdKuMoHAMjRglWnbNFeB06jKUXxAC+NlsligD -kLWrn/YZSsX7LRSeMzh7SThu69E3B+T0Ht+SY0niIQKBgQDxuQmHU3en3sziRNkf -jAZ+q6A1AxJ07tGfsCWDXNPM4Y0NzfkUw+SkKrn0WE9LXJzwCdwCTSCD4qhJw+/Z -JmV3VegomE52uBMp5JlegNPH5wT6tfi+BpMN8RsQjsT+NXpbfI/XyIAOkkiVEReH -pBHY/pAs+/JZcWjOG7VFzcpJkQKBgQDEz/rnH6yl298pkhhMiSSZvWSaLTCYsr36 -ZWZlfMmRiZYxYJemmiH+RQD64GF4l2qhd+msnx6Jv3WM0Et1kNPzQxGVDq6ZEPZE -khve9dBZMvGoBnWZVcMlMRXg+mocOrKWA61jL0tV+JlPkpi9GzDRuWkBUpBkOxM2 -7SToYvTHZQKBgDr+uTehBHQhKYoT2ZYce71Qr/IgRNHrM5gwyocMEdlQNzfmTGNo -CBaVIvtizj+LY/Ylwd+B6Wym1gHi41fxShRdECNQQN4ywOKZm2D4Ojfwx0NVRFdE -jYF6lettnOCaNrm7ZfP5SF/GDhbrq/176qs2PgPsndJ8nmKnWo+l0TgxAoGBAIac -3jahAnw7A8syIq6OitsgoCOXzwpSDwCpxDyb+l4x5emF8JPCDogUeFQfjmtl3Uft -dYVdHA0JSAR1H3edBGr5L5hs/1ywLlC+QpPgO44W+xR6voqPDzdr+FP10wfV2foj -L7+MRJHbxDiZwyBs7Zo0n66I4zu68Cx8TOcpb9TFAoGBAJIlo7Ajm5Wc8vomkQOD -CCqxKbpPKUnoqvhKGs2UsP4j4LhuAWScOMkI429Jm7e035IdV/7Mnc40YsoOfYKi -ePga4nL9ce9Ie/ay8iOuT8Dp/QpXMtJO1CUwMFSdOOLx/CWMB92XV+6YEAc9f6oR -B3KS6OnbIZhWoEceLLiwZAlb ------END PRIVATE KEY----- diff --git a/ATestCServer/db.sqlite3 b/ATestCServer/db.sqlite3 deleted file mode 100644 index 716f7019..00000000 Binary files a/ATestCServer/db.sqlite3 and /dev/null differ diff --git a/ATestCServer/manage.py b/ATestCServer/manage.py deleted file mode 100644 index 6ef1a1d9..00000000 --- a/ATestCServer/manage.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -def main(): - sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) - os.environ['DJANGO_SETTINGS_MODULE'] = 'ATestCServer.settings' - os.environ['DB_NAME'] = 'atestc' - # 安全:禁止硬编码默认密钥/口令,缺失时显式报错(settings.py 亦有 - # ImproperlyConfigured 兜底)。MSYNC_SERVICE_SECRET 与 DB_PASSWORD - # 由部署环境(环境变量)提供。 - required_envs = ['DJANGO_SECRET_KEY', 'MSYNC_SERVICE_SECRET', 'DB_PASSWORD'] - missing = [name for name in required_envs if not os.environ.get(name)] - if missing: - raise SystemExit( - '缺少必需的环境变量: ' + ', '.join(missing) - + '(禁止使用默认值,请通过环境变量注入)' - ) - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Make sure it's installed and available." - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/ATestCServer/msync_client/__init__.py b/ATestCServer/msync_client/__init__.py deleted file mode 100644 index 89220d60..00000000 --- a/ATestCServer/msync_client/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -"""MSYNC 客户端 - -模块入口,导出: - - MSyncSocketClient: Socket.IO 客户端(实时通道) -""" - -from .sio_client import MSyncSocketClient - -__all__ = ['MSyncSocketClient'] \ No newline at end of file diff --git a/ATestCServer/msync_client/sio_client.py b/ATestCServer/msync_client/sio_client.py deleted file mode 100644 index 409a7308..00000000 --- a/ATestCServer/msync_client/sio_client.py +++ /dev/null @@ -1,513 +0,0 @@ -"""模块:MSYNC Socket.IO 客户端 - -替代 HTTP REST,通过 Socket.IO 与 SMANAGE 主服务器实时通信。 -所有方法名、事件字段全部使用 PascalCase。 - -优势: - - 连接复用,无需每次请求建立 TCP/TLS - - 内置心跳保活,替代应用层心跳线程 - - 服务端可主动推送事件(服务上下线通知) - - 断线自动重连 -""" - -import hashlib -import logging -import threading -import time -import socketio - -from gvsdsdk.msync.auth import GenerateChallenge, BuildAuthPayload, SignPayload - -logger = logging.getLogger(__name__) - - -class MSyncSocketClient: - """MSYNC Socket.IO 客户端——子服务器接入 SMANAGE 的实时通道""" - - def __init__(self, master_url, service_name, service_domain, - service_secret, scope=None, heartbeat_interval=30, - service_type=0, metadata=None): - self.MasterURL = master_url.rstrip('/') - self.ServiceName = service_name - self.ServiceDomain = service_domain - self.ServiceSecret = service_secret - self.Scope = scope or ['ogm:read', 'ogm:write', 'registry:read'] - self.HeartbeatInterval = heartbeat_interval - self.ServiceType = service_type - self.Metadata = metadata or {} - - self._sio = socketio.Client( - reconnection=True, - reconnection_attempts=0, - reconnection_delay=2, - reconnection_delay_max=30, - logger=True, - engineio_logger=True, - ) - - self._token_data = None - self._registered = False - self._running = False - self._heartbeat_thread = None - self._initial_connected = False - self._reconnect_lock = threading.Lock() - - self._SetupEvents() - - def _SetupEvents(self): - @self._sio.on('connect', namespace='/msync') - def on_connect(): - logger.info(f'[SIO] ← connect ns=/msync') - if self._initial_connected: - logger.info(f'[SIO] 重连 detected, 重新注册/认证') - t = threading.Thread(target=self._DoReconnect, daemon=True) - t.start() - - @self._sio.on('disconnect', namespace='/msync') - def on_disconnect(): - logger.warning(f'[SIO] ← disconnect ns=/msync') - self._registered = False - self._token_data = None - logger.info(f'[SIO] 状态已清理: registered=False, token_data=None') - - @self._sio.on('msync:service:online', namespace='/msync') - def on_service_online(data): - logger.info(f'[SIO] ← msync:service:online data={data}') - - @self._sio.on('msync:service:offline', namespace='/msync') - def on_service_offline(data): - logger.info(f'[SIO] ← msync:service:offline data={data}') - - @self._sio.on('msync:force:deregister', namespace='/msync') - def on_force_deregister(data): - logger.warning(f'[SIO] ← msync:force:deregister data={data}') - self._registered = False - self._token_data = None - # 延迟后自动重新注册 - t = threading.Thread(target=self._DoReconnect, daemon=True) - t.start() - - @self._sio.on('*') - def catch_all(event, data): - logger.info(f'[SIO] ← unhandled event="{event}" data={data}') - - # ---------- 连接管理 ---------- - - def Connect(self): - self._running = True - url = self.MasterURL - try: - logger.info(f'[SIO] → connect url={url} ns=/msync') - self._sio.connect(url, namespaces=['/msync'], wait=True, wait_timeout=15) - except Exception as e: - logger.warning(f'Socket.IO 连接失败: {e},启动兜底重连线程') - self._StartBootstrap() - return - - self._OnReady() - - def _StartBootstrap(self): - """初次连接失败的兜底:循环重连,成功后走完整注册/认证流程 - - python-socketio 的 reconnection 仅在"已连接后断开"时生效, - 初次 connect 失败不会自动重连,需自行兜底。 - """ - - def bootstrap(): - while self._running and not self._sio.connected: - try: - logger.info(f'[SIO] 兜底重连尝试: {self.MasterURL}') - self._sio.connect( - self.MasterURL, - namespaces=['/msync'], - wait=True, - wait_timeout=10, - ) - break - except Exception as e: - logger.warning(f'[SIO] 兜底重连失败: {e}') - time.sleep(3) - if self._sio.connected: - self._OnReady() - - threading.Thread(target=bootstrap, daemon=True, name='msync-bootstrap').start() - - def _OnReady(self): - """连接建立后的统一就绪流程:注册/认证/心跳/ORM 中转""" - logger.info(f'[SIO] Socket 已连接, 开始注册/认证...') - for attempt in range(1, 4): - reg_ok = self._DoRegister() - auth_ok = self._DoAuth() - if reg_ok and auth_ok: - break - logger.warning(f'[SIO] 首次注册/认证失败 第 {attempt}/3 次 (reg={reg_ok}, auth={auth_ok})') - if attempt < 3: - time.sleep(2) - self._DoHeartbeat() - self._initial_connected = True - - self._StartHeartbeat() - - # 注册 ORM 中转处理器 - try: - from gvsdsdk.msync.orm_handler import ORMRelayHandler - self._orm_handler = ORMRelayHandler() - self._orm_handler.Register(self) - except Exception as e: - logger.warning(f'[ORM] ORM 中转处理器注册失败: {e}') - - logger.info(f'MSYNC Socket.IO 客户端已启动: {self.ServiceName}') - - def Disconnect(self): - self._running = False - try: - self._DoDeregister() - except Exception: - pass - try: - self._sio.disconnect() - except Exception: - pass - logger.info(f'MSYNC Socket.IO 客户端已断开: {self.ServiceName}') - - def _DoReconnect(self, max_retries=3): - """重连后重新注册/认证,失败时自动重试(内部持有互斥锁)""" - if not self._reconnect_lock.acquire(blocking=False): - logger.warning('[SIO] 重连已在进行中,跳过本次重连') - return - try: - for attempt in range(1, max_retries + 1): - logger.info(f'[SIO] 重连注册/认证 第 {attempt}/{max_retries} 次') - reg_ok = self._DoRegister() - auth_ok = self._DoAuth() - if reg_ok and auth_ok: - logger.info(f'[SIO] 重连注册/认证成功') - return - logger.warning(f'[SIO] 重连注册/认证失败 (reg={reg_ok}, auth={auth_ok}),{2}s 后重试') - if attempt < max_retries: - time.sleep(2) - logger.error(f'[SIO] 重连注册/认证 {max_retries} 次均失败,等待 Socket.IO 下次重连触发') - finally: - self._reconnect_lock.release() - - def _StartHeartbeat(self): - if self._heartbeat_thread and self._heartbeat_thread.is_alive(): - return - self._heartbeat_thread = threading.Thread( - target=self._HeartbeatLoop, - daemon=True, - name=f'msync-heartbeat-{self.ServiceName}', - ) - self._heartbeat_thread.start() - logger.info(f'心跳线程已启动, 间隔={self.HeartbeatInterval}s') - - def _HeartbeatLoop(self): - consecutive_failures = 0 - while self._running: - time.sleep(self.HeartbeatInterval) - try: - if not self._sio.connected: - continue - # 检查令牌是否即将过期,主动续期 - if not self.IsAuthenticated: - logger.info('[SIO] 令牌已过期或即将过期,主动续期') - try: - self.EnsureAuthenticated() - except Exception as e: - logger.warning(f'[SIO] 令牌续期失败: {e},触发重连') - consecutive_failures += 1 - if consecutive_failures >= 3: - logger.warning('[SIO] 连续失败次数过多,强制重连') - self._ForceReconnect() - consecutive_failures = 0 - continue - # 发送心跳 - result = self._Call('msync:heartbeat', {}) - if result and result.get('code') not in (200, 0): - code = result.get('code') - msg = result.get('msg', '') - logger.warning(f'[SIO] 心跳异常: code={code} msg={msg}') - # 404 = 服务不存在/已禁用,需要立即重新注册 - if code == 404: - logger.warning('[SIO] 服务已被注销,立即重新注册') - try: - reg_ok = self._DoRegister() - auth_ok = self._DoAuth() - if reg_ok and auth_ok: - logger.info('[SIO] 重新注册/认证成功') - consecutive_failures = 0 - continue - except Exception as e: - logger.error(f'[SIO] 重新注册失败: {e}') - # 注册也失败,强制重连 - self._ForceReconnect() - consecutive_failures = 0 - continue - consecutive_failures += 1 - if consecutive_failures >= 3: - logger.warning('[SIO] 心跳连续失败次数过多,强制重连') - self._ForceReconnect() - consecutive_failures = 0 - elif result: - consecutive_failures = 0 - except Exception as e: - logger.warning(f'[SIO] 心跳异常: {e}') - consecutive_failures += 1 - if consecutive_failures >= 3: - self._ForceReconnect() - consecutive_failures = 0 - - def _Call(self, event, data, timeout=15): - if not self._sio.connected: - logger.warning(f'[SIO] ✗ 未连接,无法发送 event={event}') - return None - try: - logger.info(f'[SIO] → event="{event}" ns=/msync data_keys={list(data.keys()) if isinstance(data, dict) else type(data).__name__}') - result = self._sio.call(event, data, namespace='/msync', timeout=timeout) - logger.info(f'[SIO] ← ack event="{event}" result={result}') - return result - except socketio.exceptions.TimeoutError: - logger.error(f'[SIO] ✗ timeout event="{event}" ({timeout}s)') - return None - except Exception as e: - logger.error(f'[SIO] ✗ call failed event="{event}": {type(e).__name__}: {e}') - return None - - # ---------- 注册与认证 ---------- - - def _DoRegister(self): - payload = { - 'ServiceName': self.ServiceName, - 'ServiceDomain': self.ServiceDomain, - 'ServiceSecretHash': hashlib.sha256(self.ServiceSecret.encode()).hexdigest(), - 'ServiceSecret': self.ServiceSecret, - 'ServiceScope': self.Scope, - 'ServiceType': self.ServiceType, - 'ServiceMetadata': self.Metadata, - } - result = self._Call('msync:register', payload) - if result and result.get('code') == 200: - self._registered = True - logger.info(f'服务注册成功: {self.ServiceName}') - return True - if result and result.get('code') == 409: - logger.warning(f'服务已存在(409冲突),可能已用不同密钥注册: {self.ServiceName},尝试认证') - return True - logger.warning(f'服务注册失败: result={result}') - return False - - def _DoAuth(self): - challenge = GenerateChallenge() - payload = BuildAuthPayload(self.ServiceName, challenge) - signature = SignPayload(payload, self.ServiceSecret) - - # 调试:打印签名详情 - import json - canonical = json.dumps(payload, sort_keys=True, separators=(',', ':')) - logger.info(f'[AUTH] 客户端签名: service={self.ServiceName}, canonical={canonical}, sig={signature}') - - result = self._Call('msync:auth', { - 'ServiceName': self.ServiceName, - 'Payload': payload, - 'Signature': signature, - }) - if result and result.get('code') == 200 and result.get('data'): - token_data = result['data'] - self._token_data = { - 'AccessToken': token_data.get('AccessToken'), - 'RefreshToken': token_data.get('RefreshToken'), - 'Scope': token_data.get('Scope', []), - 'ExpiresAt': token_data.get('ExpiresAt'), - } - logger.info(f'服务认证成功: {self.ServiceName}') - return True - logger.warning(f'服务认证失败: result={result}') - return False - - def _DoDeregister(self): - self._Call('msync:deregister', {'ServiceName': self.ServiceName}) - self._registered = False - - def _DoHeartbeat(self): - result = self._Call('msync:heartbeat', {}) - if result and result.get('code') == 200: - logger.info(f'初始心跳成功: {self.ServiceName}') - else: - logger.warning(f'初始心跳失败: {result}') - - # ---------- 状态 ---------- - - @property - def AccessToken(self): - return self._token_data.get('AccessToken') if self._token_data else None - - @property - def RefreshToken(self): - return self._token_data.get('RefreshToken') if self._token_data else None - - @property - def IsAuthenticated(self): - if not self._token_data: - return False - expires = self._token_data.get('ExpiresAt', 0) - if expires and time.time() > expires - 60: - return False - return True - - @property - def IsRegistered(self): - return self._registered - - @property - def IsConnected(self): - return self._sio.connected - - def EnsureAuthenticated(self): - """确保认证有效,过期则续期,续期失败则断开重连""" - if not self.IsAuthenticated: - if self._token_data and self._token_data.get('RefreshToken'): - result = self._RefreshToken() - if result: - return result - logger.warning('[SIO] 令牌刷新失败,尝试完整认证') - auth_ok = self._DoAuth() - if auth_ok: - return self._token_data - # 认证彻底失败,断开连接触发 Socket.IO 自动重连 - logger.error('[SIO] 完整认证也失败,断开连接触发自动重连') - self._ForceReconnect() - return None - return self._token_data - - def _RefreshToken(self): - result = self._Call('msync:auth:refresh', { - 'RefreshToken': self._token_data.get('RefreshToken', ''), - }) - if result and result.get('code') == 200 and result.get('data'): - token_data = result['data'] - self._token_data = { - 'AccessToken': token_data.get('AccessToken'), - 'RefreshToken': token_data.get('RefreshToken'), - 'Scope': token_data.get('Scope', []), - 'ExpiresAt': token_data.get('ExpiresAt'), - } - logger.info(f'令牌刷新成功: {self.ServiceName}') - return self._token_data - logger.info('令牌刷新失败,回退到完整认证') - return None - - def _ForceReconnect(self): - """强制断开连接,让 Socket.IO 自动重连""" - try: - self._registered = False - self._token_data = None - self._sio.disconnect() - except Exception as e: - logger.warning(f'[SIO] 强制断开失败: {e}') - - def _Headers(self): - token = self.AccessToken - if not token: - self.EnsureAuthenticated() - token = self.AccessToken - return {'Authorization': f'Bearer {token}'} if token else {} - - # ---------- 服务发现 ---------- - - def DiscoverAll(self, active_only=True): - result = self._Call('msync:discover', {'ActiveOnly': active_only}) - if result and result.get('code') == 200: - return result.get('data', []) - return [] - - def Discover(self, service_name): - result = self._Call('msync:discover:one', {'ServiceName': service_name}) - if result and result.get('code') == 200: - return result.get('data') - return None - - # ---------- OGM ---------- - - def OGMRegister(self, object_type, local_id, service_name, - global_id=None, metadata=None): - body = { - 'ObjectType': object_type, - 'ObjectLocalID': str(local_id), - 'ServiceName': service_name, - } - if global_id: - body['ObjectGlobalID'] = global_id - if metadata: - body['Metadata'] = metadata - result = self._Call('msync:ogm:register', body) - if result and result.get('code') == 200: - return result.get('data') - return None - - def OGMResolve(self, global_id): - result = self._Call('msync:ogm:resolve', {'ObjectGlobalID': global_id}) - if result and result.get('code') == 200: - return result.get('data') - return None - - def OGMQuery(self, object_type=None, service_name=None, local_id=None): - body = {} - if object_type: - body['ObjectType'] = object_type - if service_name: - body['ServiceName'] = service_name - if local_id: - body['ObjectLocalID'] = local_id - result = self._Call('msync:ogm:query', body) - if result and result.get('code') == 200: - return result.get('data') - return None - - def OGMDeregister(self, global_id): - result = self._Call('msync:ogm:deregister', {'ObjectGlobalID': global_id}) - return result is not None and result.get('code') == 200 - - # ---------- 事务 ---------- - - def TxCreate(self, name, steps, **kwargs): - body = {'TransactionName': name, 'Steps': steps} - for key in ('TransactionDescription', 'TransactionType', 'InitiatorServiceName', - 'ReferenceOGMUUID', 'Payload', 'TimeoutSeconds'): - kwarg_key = key[0].lower() + key[1:] - if kwarg_key in kwargs: - body[key] = kwargs.pop(kwarg_key) - body.update(kwargs) - result = self._Call('msync:tx:create', body, timeout=30) - if result and result.get('code') == 200: - return result.get('data') - return None - - def TxExecute(self, transaction_code, access_token=None): - result = self._Call('msync:tx:execute', { - 'TransactionCode': transaction_code, - 'AccessToken': access_token, - }, timeout=60) - if result and result.get('code') == 200: - return result.get('data') - return None - - def TxDetail(self, transaction_code): - result = self._Call('msync:tx:detail', {'TransactionCode': transaction_code}) - if result and result.get('code') == 200: - return result.get('data') - return None - - # ---------- 远程调用 ---------- - - def CallRemote(self, service_name, method, path, data=None, json=None, **kwargs): - import requests - service_info = self.Discover(service_name) - if not service_info: - logger.error(f'目标服务未发现: {service_name}') - return None - domain = service_info.get('ServiceDomain', '') - url = f'{domain.rstrip("/")}{path}' - kwargs.setdefault('headers', {}).update(self._Headers()) - kwargs.setdefault('timeout', 30) - method_func = getattr(requests, method.lower(), requests.get) - return method_func(url, data=data, json=json, **kwargs) \ No newline at end of file diff --git a/ATestCServer/requirements.txt b/ATestCServer/requirements.txt deleted file mode 100644 index 2d631089..00000000 --- a/ATestCServer/requirements.txt +++ /dev/null @@ -1,23 +0,0 @@ -# ATestCServer 子服务器依赖 -# 安装顺序:先装 SDK,再装项目依赖 -# 1) pip install -e ../gvsdsdk -# 2) pip install -r requirements.txt - -# === GVS-DSDK(双端共享,必须装,**版本与主服务器严格一致**) === -gvsdsdk==1.0.0 - -# === Django 核心 === -django>=4.2,<5.0 -djangorestframework>=3.14,<4.0 - -# === 数据库(连接 SAAS 主库 MySQL) === -mysqlclient>=2.2 - -# === MSYNC Socket.IO 客户端(子服务器需要) === -python-socketio[client]>=5.0,<6.0 -websocket-client>=1.5 -requests>=2.28 - -# === 加密(与主服务器同版本) === -pyOpenSSL>=23.0 -pycryptodome>=3.18 \ No newline at end of file diff --git a/ATestCServer/start.ps1 b/ATestCServer/start.ps1 deleted file mode 100644 index 2807c470..00000000 --- a/ATestCServer/start.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -# ATestCServer 启动脚本 -# HTTP 端口 25080,HTTPS 端口 25443 -# -# 用法: -# .\start.ps1 # 普通启动 -# .\start.ps1 -Migrate # 带数据库迁移 - -param( - [switch]$Migrate = $false -) - -$ErrorActionPreference = "Stop" -$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path -Set-Location $ScriptDir - -Write-Host "============================" -ForegroundColor Cyan -Write-Host " ATestCServer 子服务器启动" -ForegroundColor Cyan -Write-Host " HTTP : http://127.0.0.1:25080" -ForegroundColor Green -Write-Host " HTTPS : https://127.0.0.1:25443" -ForegroundColor Green -Write-Host " MSYNC → https://www.gvsds.com" -ForegroundColor Yellow -Write-Host " (父) → http://127.0.0.1:25080 (本地回环)" -ForegroundColor Yellow -Write-Host "============================" -ForegroundColor Cyan - -$env:PYTHONPATH = "$ScriptDir;$ScriptDir\..\gvsdsdk" - -if ($Migrate) { - Write-Host "[*] 执行数据库迁移..." -ForegroundColor Magenta - python manage.py makemigrations sub_server - python manage.py migrate - Write-Host "[√] 迁移完成" -ForegroundColor Green -} - -Write-Host "[*] 启动 Django 开发服务器..." -ForegroundColor Magenta - -python manage.py runserver 0.0.0.0:25080 \ No newline at end of file diff --git a/GVSite b/GVSite deleted file mode 160000 index f86622d4..00000000 --- a/GVSite +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f86622d4137d96b94a9b497b1764094954b4f4be diff --git a/docs/architecture_debt_governance.md b/docs/architecture_debt_governance.md new file mode 100644 index 00000000..6357b159 --- /dev/null +++ b/docs/architecture_debt_governance.md @@ -0,0 +1,90 @@ +# ERP 架构债治理清单 + +> 生成日期:2026-08-13 +> 来源:对 d:\SMANAGE 后端(gvsds+gvsdsdk)、前端(GERP Vue)、仓库卫生的三路并行架构审查结论 +> 状态:按阶段依次执行,每阶段完成后提交,直到收敛 + +--- + +## Phase 0 — 止血(低风险,立即执行) + +| # | 问题 | 动作 | 状态 | +|---|---|---|---| +| 0.1 | ATestCServer 私钥/SQLite 可入库 | .gitignore 加 `/ATestCServer/`,git rm --cached 清理,目录移入 backup\ | | +| 0.2 | media/ 未忽略 | .gitignore 加 `/media/` + git rm --cached | | +| 0.3 | 根目录日志/状态文件未忽略 | .gitignore 加 service.log、service_err.log、ips.txt、iptimes.txt、times.txt、timer.txt | | +| 0.4 | GVSite/deploy.ps1 必然失败 Bug | L195-196 `$ProdAssets/$DistAssets` 改为 `$ProdGvsite/$DistGvsite` 或删除冗余校验 | | +| 0.5 | GVSite 嵌套仓库 gitlink 风险 | .gitignore 加 `/GVSite/` + git rm --cached 检查 | | +| 0.6 | frp token 明文 + `/FRP/` 大小写错 | token 移环境变量;gitignore 改小写 `frp/` | | +| 0.7 | 前端死依赖(FormKit/tinymce-i18n/@vxe-ui/plugin-render-element/vite-plugin-static-copy) | 从 package.json 移除 + main.ts 去掉 FormKit 注册 | | + +## Phase 1 — 架构债收敛(核心) + +| # | 问题 | 动作 | 状态 | +|---|---|---|---| +| 1.1 | 模型双轨制(最大负债) | 定唯一模型源:gvsds 侧改 `from gvsdsdk.models import *`(Meta 别名)或建字段一致性校验脚本;stats/payment/commission 三处副本同步 | | +| 1.2 | 数据权限硬编码 | `ApplyScopeToQueryset`/form_service 30+ 处 `if table_name` 改策略注册表 | | +| 1.3 | 角色解析双实现 | auth.py `ResolveRoleContext` 与 SDK `CurrentRoleMiddleware` 合并为唯一实现 | | +| 1.4 | AUTH_USER_MODEL 未设置 | 设 `AUTH_USER_MODEL='core.User'`,删除 auth.py 硬编码覆盖 | | +| 1.5 | 部分表无 TenantUUID | Dept/Workgroup/Shop/User 补列+回填迁移,替换 form_service 反射补偿 | | + +## Phase 2 — 安全与运维加固 + +| # | 问题 | 动作 | 状态 | +|---|---|---|---| +| 2.1 | Access Token 168h + refresh 不黑名单 | 缩至 2-4h + `BLACKLIST_AFTER_ROTATION=True` | | +| 2.2 | core UserPassword 硬编码默认哈希 | 移除默认值,首登强制改密 | | +| 2.3 | IP 过滤默认 disabled + 顺序靠后 | 改显式配置(漏配即 fail-fast),移到认证中间件前 | | +| 2.4 | Celery 任务无重试/日志/周期清理 | 套 `RetryOnFailure`;PurgeOldStats 支持全周期类型;补 FileHandler | | +| 2.5 | 攻击日志同步写库放大 DoS | 异步化/限频合并 AbnormalUserLog 写入 | | +| 2.6 | 异常 print 到 stdout | 改 logging,日志落盘可审计 | | +| 2.7 | USE_TZ=False | 评估改 True 并迁移存量时间戳 | | + +## Phase 3 — 前端质量 + +| # | 问题 | 动作 | 状态 | +|---|---|---|---| +| 3.1 | Sku.vue 1870 行全 Mock 已上生产路由 | 移出路由或删除 | | +| 3.2 | CrudTable 1201 行职责混乱 | 草稿/卡片树/批量创建抽独立 composable;补 el-form rules;批量删除改并发限流 | | +| 3.3 | tab 关闭不销毁组件 | removeTab 时 v-if 卸载 + onDeactivated 清理,或 KeepAlive max 上限 | | +| 3.4 | api 层不统一 | 提供 `requestRaw()`;Menu/Editor/Manager 迁 api 层 | | +| 3.5 | 双表格栈 + Element Plus 全量引入 | 统一 vxe-table;明确全量或按需二选一 | | +| 3.6 | 动态路由空壳 / 死状态 / 43 处 any | 实现真 addRoute 或删空壳;清死状态;类型收口 | | +| 3.7 | tinymce 整包 40MB 入 dist | 只拷 min.js + 插件 + zh_CN + oxide 皮肤 | | + +## Phase 4 — 清理归档 + +| # | 问题 | 动作 | 状态 | +|---|---|---|---| +| 4.1 | TempLate 死目录仍公网可达 | 先删 SUBDOMAIN_CONFIG 配置项,再移 backup\ 归档 | | +| 4.2 | 子域配置名大小写不一致 | 对齐目录或删配置 | | +| 4.3 | 部署脚本三套不统一 | 抽公共 deploy 模板参数化 | | +| 4.4 | 根目录散落工具/Version 死代码/双生产入口 | 归 tools\ + docs\;Version 归档;生产入口二选一 | | +| 4.5 | 巨型文件拆分 | crb/views.py、auth/managers.py、form_service.py 按领域拆包 | | + +--- + +## 详细分析依据 + +### 后端(gvsds + gvsdsdk) +- H1 模型双轨制:gerp/models.py(929 行)与 gvsdsdk/models.py(1418 行)对同一批表定义两套 ORM,字段类型不一致(FK vs UUIDField);stats/payment/commission 有显式副本。migrations 冻结后 gvsds 模型层仅服务 admin/serializer +- H2 数据权限硬编码:role_scope.py L176-195 仅认识 User/UserRole/Order 三张表;form_service.py 30+ 处表级特判 +- H3 无 TenantUUID:User/Dept/Workgroup/Shop 仅 CompanyUUID,form_service 用 `CompanyUUID__TenantUUID` 反射补偿 +- H4 角色解析双实现:auth.py `ResolveRoleContext`(JWT 链路)与 gvsdsdk/auth/middleware.py `CurrentRoleMiddleware`(Session 链路)逐行相似 +- H5 未设 AUTH_USER_MODEL:admin/sessions 用 auth.User,业务用 core.User,靠 auth.py L101 硬编码覆盖 +- 中优先级:7 库路由粗糙(AbnormalUserLog 显式 .using 例外);根 urls.py 287 行巨型化 + 视图双入口 + 生产自托管静态/catch-all;巨型文件(crb/views.py 2637、auth/managers.py 2290、form_service.py 1726、gvsdsdk/models.py 1418);安全弱点(168h token、默认密码哈希、print 堆栈);Celery 无重试/无日志落盘/beat 任务名不一致 + +### 前端(GERP) +- H1 FormKit 死注册(main.ts L10,35),构建含独立 formkit chunk +- H2 大文件:Sku.vue 1870(全 Mock + 12 TODO)、Mailbox.vue 1650、Editor.vue 1431、Manager.vue 1392(15 TODO + 直接 XHR)、CrudTable.vue 1201、Menu.vue 1129、EntityPicker.vue 1024 +- H3 CrudTable 职责混乱:表格+表单+卡片树+草稿+批量创建;form 无 rules;批量删除串行 N 请求 +- H4 v-show 常驻内存泄漏:removeTab 不销毁组件实例 +- 中优先级:Element Plus 全量引入名不副实;vxe/el-table 双栈;api 层不统一(responseType hack ×2、直接 XHR);动态路由空壳 + meta 无类型;stores 死状态 + AdminCheckResult 双份定义;43 处 any;tinymce 整包 40MB;4 个未使用依赖 + +### 仓库卫生 +- H1 ATestCServer 私钥/SQLite 可入库(半成品骨架) +- H2 media/ 未忽略 +- H3 根目录运行时文件未忽略(service.log 含堆栈、ips.txt 1743 行) +- H4 GVSite/deploy.ps1 L195-196 未定义变量必然失败 +- H5 GVSite 未整目录忽略(gitlink 风险);TempLate 子域配置名大小写不一致 +- 中优先级:TempLate 死目录仍公网服务;三套部署脚本不统一;gvsdsdk 版本矩阵不一致(主 1.1.0/子 1.0.0);frp token 明文 + gitignore 大小写错 diff --git a/ips.txt b/ips.txt deleted file mode 100644 index c0671c1d..00000000 --- a/ips.txt +++ /dev/null @@ -1,1743 +0,0 @@ -82.221.131.71 -160.250.186.220 -130.193.15.79 -72.195.114.169 -199.116.112.6 -190.211.254.185 -23.191.200.25 -185.45.95.115 -67.201.35.145 -45.135.194.111 -185.220.101.182 -185.220.101.110 -85.254.59.20 -171.25.193.39 -45.66.35.34 -192.42.116.53 -185.220.101.11 -185.220.101.18 -185.45.95.240 -216.158.207.190 -23.128.248.163 -85.254.30.167 -185.220.100.250 -217.154.191.103 -85.254.137.205 -47.82.152.247 -109.70.100.1 -123.136.31.130 -130.193.10.21 -216.158.207.18 -185.220.101.30 -209.141.34.15 -184.181.217.210 -216.158.207.152 -192.42.116.96 -87.118.116.103 -185.45.95.173 -45.66.35.30 -81.181.104.22 -216.158.207.34 -64.190.76.4 -93.95.231.14 -147.90.235.17 -216.158.207.83 -107.189.31.187 -103.95.119.103 -216.158.207.64 -195.47.238.44 -168.144.112.115 -85.254.59.43 -50.6.169.131 -23.191.200.124 -85.254.59.148 -93.99.104.40 -192.42.116.57 -185.220.101.187 -179.43.159.78 -85.254.59.134 -185.246.190.137 -192.42.116.45 -185.220.101.60 -64.190.76.10 -192.121.44.26 -85.254.137.170 -171.25.193.131 -149.102.153.38 -185.220.101.22 -85.254.103.132 -38.95.35.74 -85.254.59.160 -98.188.47.132 -23.191.200.115 -185.220.101.143 -192.42.116.65 -23.191.200.48 -192.42.116.20 -141.239.158.222 -162.241.152.21 -85.254.103.30 -103.253.24.18 -45.128.133.242 -85.254.103.221 -198.46.168.17 -85.254.103.227 -95.135.112.212 -23.191.200.97 -185.220.101.14 -23.128.248.164 -185.45.95.156 -185.154.110.16 -216.158.207.167 -85.254.59.152 -45.13.237.121 -82.193.116.160 -85.254.59.208 -85.254.137.173 -216.158.207.171 -184.181.217.201 -185.220.101.49 -171.25.193.40 -185.220.101.25 -23.191.200.84 -171.25.193.46 -109.70.100.11 -23.129.64.99 -157.180.95.108 -23.191.200.37 -193.105.134.155 -192.42.116.48 -50.6.231.19 -192.111.130.5 -185.45.95.200 -147.90.235.40 -85.254.59.253 -45.66.35.20 -104.244.73.43 -185.45.95.81 -104.37.135.145 -23.191.200.27 -184.178.172.25 -23.191.200.44 -23.191.200.86 -185.220.101.181 -85.254.103.18 -185.45.95.63 -93.95.227.37 -147.90.235.20 -204.8.156.142 -23.129.64.172 -141.105.68.238 -23.129.64.130 -23.128.248.168 -194.156.89.134 -185.45.95.123 -5.255.104.202 -178.17.174.14 -45.91.250.107 -37.221.208.71 -85.254.137.154 -185.45.95.223 -203.202.232.160 -184.178.172.11 -5.255.101.10 -94.142.241.194 -185.45.95.70 -193.189.100.203 -93.127.139.122 -94.156.152.8 -85.254.137.211 -85.254.103.81 -147.90.234.63 -109.70.100.15 -107.189.3.148 -185.45.95.110 -188.68.36.28 -38.242.211.132 -185.45.95.181 -142.54.235.9 -185.220.101.174 -134.122.64.174 -85.254.30.104 -77.90.185.51 -89.147.111.87 -45.84.107.33 -45.66.35.31 -5.104.84.183 -185.45.95.111 -192.42.116.145 -185.220.101.170 -216.158.207.186 -51.38.225.46 -193.189.100.201 -104.244.73.193 -185.45.95.66 -162.240.96.211 -85.254.59.67 -216.158.207.159 -85.254.137.100 -185.220.101.144 -121.127.33.253 -184.178.172.28 -101.0.17.73 -192.42.116.63 -185.220.101.171 -23.129.64.212 -2.56.10.36 -84.16.224.227 -154.209.4.204 -104.244.79.50 -23.137.105.248 -210.211.99.176 -65.109.124.253 -104.167.242.118 -216.158.207.44 -185.220.101.97 -185.82.219.109 -149.202.79.129 -109.70.100.8 -155.254.126.141 -98.170.57.249 -147.90.235.21 -23.191.200.11 -192.42.116.94 -185.45.95.127 -185.45.95.199 -185.220.101.27 -23.191.200.109 -107.189.5.121 -23.191.200.104 -192.42.116.66 -85.254.59.162 -23.191.200.8 -85.254.30.171 -185.121.170.61 -185.45.95.49 -23.129.64.134 -185.220.101.53 -95.169.191.186 -98.181.137.80 -87.118.122.51 -121.200.216.56 -85.254.103.70 -45.84.107.17 -85.254.59.220 -85.254.137.175 -5.255.123.164 -192.42.116.62 -178.20.55.16 -185.220.101.167 -205.185.113.112 -23.129.64.165 -85.254.30.175 -216.158.207.14 -185.45.95.0 -85.254.137.192 -23.129.64.222 -209.42.18.223 -91.208.75.178 -23.191.200.75 -23.129.64.214 -185.45.95.95 -185.45.95.73 -23.129.64.156 -23.129.64.164 -216.158.207.179 -23.191.200.122 -38.134.41.34 -23.129.64.167 -85.254.103.148 -192.252.209.158 -85.254.30.212 -23.191.200.7 -185.220.101.1 -23.129.64.180 -85.215.36.85 -85.254.59.14 -185.129.61.3 -188.191.164.55 -171.25.193.82 -85.254.30.223 -165.232.137.226 -85.254.59.72 -198.54.126.140 -216.158.207.204 -85.254.137.97 -190.120.229.98 -85.254.30.246 -185.220.101.21 -216.158.207.225 -85.254.103.105 -216.158.207.59 -23.191.200.120 -23.129.64.131 -62.182.84.146 -171.25.158.95 -194.53.137.42 -205.185.121.170 -85.254.103.211 -185.243.218.232 -192.42.116.56 -23.129.64.194 -104.244.73.14 -107.189.8.226 -216.158.207.141 -85.90.207.185 -185.100.87.41 -199.102.105.242 -142.54.237.34 -193.233.137.130 -192.42.116.42 -185.45.95.254 -192.210.214.5 -23.191.200.34 -185.220.101.191 -64.190.76.12 -185.220.101.15 -216.158.207.246 -87.118.116.12 -185.220.101.46 -85.254.59.150 -216.158.207.250 -190.120.229.2 -216.158.207.107 -184.178.172.3 -64.69.40.75 -185.220.101.178 -192.42.116.21 -154.26.132.116 -94.230.208.147 -172.81.132.94 -85.254.103.249 -185.247.184.105 -45.66.35.35 -107.189.29.8 -185.67.82.114 -185.220.101.39 -193.36.132.21 -185.170.114.25 -5.255.123.162 -185.45.95.4 -185.220.101.130 -67.215.236.114 -185.220.101.3 -103.197.48.210 -167.172.108.109 -103.91.65.44 -85.254.103.54 -212.69.84.196 -185.220.101.16 -37.114.50.142 -216.158.207.108 -23.129.64.186 -5.255.127.222 -216.158.207.131 -23.191.200.31 -147.90.235.16 -185.45.95.33 -85.254.30.15 -51.91.18.151 -45.137.69.5 -185.220.100.245 -107.189.31.52 -185.45.95.34 -185.220.100.241 -212.73.134.204 -85.254.137.243 -205.185.121.177 -152.53.210.165 -185.45.95.149 -65.254.225.234 -185.45.95.25 -150.40.126.172 -119.148.11.141 -107.189.11.111 -190.103.179.98 -85.254.30.199 -216.158.207.205 -85.254.59.172 -93.99.104.194 -185.45.95.168 -216.158.207.243 -23.129.64.188 -152.53.144.223 -85.254.59.92 -185.129.61.10 -185.220.101.185 -193.239.232.235 -192.252.215.5 -185.220.101.7 -85.254.137.120 -147.90.234.115 -51.79.177.162 -23.128.248.172 -192.42.116.16 -172.104.243.155 -37.77.56.238 -23.191.200.61 -185.220.101.169 -204.137.14.105 -185.220.100.251 -185.220.101.9 -23.129.64.140 -195.80.151.242 -5.255.111.52 -103.109.101.105 -41.111.171.131 -216.158.207.174 -104.192.3.74 -45.9.168.95 -185.45.95.212 -185.220.101.33 -85.254.59.2 -185.220.101.177 -185.220.101.100 -198.96.155.3 -216.158.207.54 -171.25.193.45 -163.182.170.162 -184.170.248.5 -216.158.207.192 -209.141.51.30 -216.158.207.164 -27.112.79.157 -192.42.116.14 -185.220.101.34 -57.129.91.235 -185.11.139.198 -142.249.174.12 -91.212.45.214 -185.243.218.231 -23.129.64.193 -54.36.102.244 -5.196.95.34 -84.21.166.105 -85.254.103.56 -85.254.103.62 -85.254.137.27 -5.2.67.226 -68.71.242.118 -192.42.116.43 -5.45.104.176 -194.26.192.22 -96.44.159.148 -85.254.137.139 -185.235.146.29 -85.254.137.138 -23.137.255.85 -216.158.207.217 -87.106.76.226 -85.254.137.123 -185.220.101.59 -23.129.64.137 -23.129.64.197 -94.23.70.39 -185.45.95.174 -192.42.116.46 -107.189.8.56 -23.129.64.200 -23.129.64.171 -185.45.95.242 -185.45.95.162 -45.84.107.97 -178.20.55.182 -23.191.200.98 -102.211.56.112 -85.254.59.76 -185.220.101.180 -119.189.6.23 -37.228.129.168 -68.1.210.163 -185.45.95.191 -37.228.129.241 -92.119.164.208 -107.189.29.184 -23.129.64.218 -154.44.99.224 -185.220.101.0 -107.189.6.232 -185.220.101.163 -85.254.30.2 -23.191.200.69 -185.220.101.47 -185.220.101.12 -85.254.137.161 -216.158.207.13 -213.171.208.62 -85.254.59.135 -23.191.200.89 -209.141.58.254 -185.45.95.82 -199.58.184.97 -185.220.100.242 -203.159.90.15 -23.151.8.88 -185.220.100.246 -185.129.62.64 -107.189.13.253 -45.84.107.128 -185.45.95.35 -185.220.101.38 -85.254.103.144 -85.254.103.0 -194.53.137.102 -147.90.235.22 -85.254.30.114 -107.189.12.3 -103.20.241.102 -185.220.101.51 -192.42.116.68 -85.254.59.99 -185.220.101.13 -185.45.95.217 -23.129.64.141 -85.254.137.209 -23.129.64.168 -23.137.253.113 -85.254.30.230 -185.220.101.172 -45.61.188.15 -185.45.95.198 -45.137.69.89 -85.254.137.73 -5.182.209.54 -85.254.30.137 -185.129.61.4 -138.59.18.110 -85.254.30.150 -109.70.100.5 -23.191.200.15 -23.129.64.219 -31.220.96.135 -85.254.59.97 -216.158.207.66 -216.158.207.214 -85.254.103.118 -109.71.252.97 -185.45.95.72 -23.190.216.25 -23.191.200.114 -185.246.188.74 -185.45.95.114 -185.45.95.128 -45.197.6.246 -23.129.64.211 -185.243.218.230 -23.191.200.12 -185.45.95.134 -192.42.116.115 -192.42.116.100 -185.165.169.239 -65.254.225.222 -185.220.101.179 -216.158.207.239 -216.158.207.158 -85.254.103.21 -85.254.137.166 -178.79.154.219 -85.254.103.127 -185.45.95.220 -185.220.101.62 -107.189.1.160 -85.254.137.43 -23.129.64.206 -179.43.182.58 -172.81.131.156 -185.130.47.58 -216.158.207.129 -64.188.93.178 -95.135.112.152 -85.254.103.25 -192.252.211.193 -185.220.101.150 -185.129.62.62 -85.254.59.136 -85.254.103.212 -104.244.78.232 -98.190.239.3 -184.178.172.26 -216.158.207.46 -212.38.189.186 -216.158.207.29 -147.90.235.226 -192.42.116.104 -23.129.64.199 -85.254.30.120 -109.71.252.88 -185.220.101.52 -195.47.238.50 -35.0.127.52 -184.178.172.23 -23.191.200.78 -192.42.116.102 -64.190.76.14 -204.137.14.53 -102.211.56.20 -85.254.30.18 -5.255.119.76 -85.254.59.249 -23.129.64.189 -85.254.137.189 -5.255.115.48 -64.190.113.106 -23.191.200.85 -85.254.103.58 -94.16.116.81 -85.254.103.93 -193.189.100.204 -23.191.200.117 -185.45.95.62 -91.92.109.126 -104.223.84.84 -186.26.95.249 -85.254.59.157 -23.191.200.19 -5.255.123.158 -185.220.101.102 -184.170.249.65 -171.25.193.80 -85.254.30.166 -85.254.137.57 -23.191.200.92 -85.254.103.209 -50.6.192.190 -172.232.209.254 -216.158.207.121 -185.181.61.203 -77.48.28.193 -185.220.101.154 -107.189.8.70 -85.254.103.180 -128.31.0.13 -45.9.156.106 -64.190.76.2 -23.191.200.40 -216.158.207.172 -185.220.101.98 -162.220.14.54 -36.138.252.97 -23.129.64.203 -85.254.103.149 -82.221.131.86 -147.90.234.118 -85.254.30.135 -200.122.181.2 -216.158.207.142 -64.190.113.221 -185.220.101.160 -206.166.251.193 -198.98.50.199 -85.254.137.99 -185.45.95.92 -45.66.35.29 -185.45.95.160 -85.254.59.167 -185.220.101.50 -216.158.207.157 -85.254.59.205 -216.158.207.151 -45.84.107.174 -192.42.116.113 -208.102.51.6 -192.42.116.109 -31.220.75.237 -162.0.229.130 -45.61.184.51 -82.197.182.161 -185.220.100.255 -121.127.34.40 -192.111.135.18 -185.129.61.6 -216.158.207.227 -216.158.207.185 -85.254.137.78 -185.45.95.61 -88.80.26.4 -51.15.15.81 -185.220.101.26 -167.71.132.111 -5.255.117.56 -107.189.4.12 -185.244.192.184 -85.254.59.188 -85.254.59.124 -104.167.241.4 -104.244.79.61 -185.220.101.157 -102.130.127.117 -23.191.200.110 -85.254.59.164 -185.132.53.11 -216.158.207.37 -216.158.207.60 -216.158.207.125 -192.42.116.15 -62.210.185.4 -65.38.109.3 -85.254.137.226 -185.243.218.226 -47.85.51.197 -185.247.226.95 -216.158.207.69 -85.254.103.205 -201.76.149.85 -216.158.207.219 -216.158.207.85 -162.240.101.155 -23.129.64.139 -85.254.59.100 -185.220.101.152 -72.195.114.184 -45.90.98.8 -139.99.8.57 -23.191.200.59 -65.254.225.233 -23.191.200.82 -185.45.95.187 -107.189.4.209 -85.254.30.244 -147.90.234.159 -94.102.51.15 -89.234.157.254 -185.45.95.74 -94.75.225.81 -216.158.207.76 -194.32.107.172 -85.254.30.96 -185.220.101.35 -185.220.101.176 -216.158.207.86 -185.220.101.24 -45.12.3.80 -107.189.10.175 -85.254.103.153 -23.191.200.64 -185.45.95.196 -46.224.234.158 -184.178.172.14 -92.119.165.108 -93.113.25.90 -85.254.137.31 -85.254.59.46 -107.189.14.4 -85.254.103.128 -185.45.95.19 -85.93.218.204 -185.129.61.9 -45.142.141.134 -185.220.101.107 -185.45.95.142 -45.84.107.200 -85.254.137.219 -171.25.193.37 -216.239.90.19 -185.45.95.91 -185.181.61.201 -192.252.209.155 -129.121.76.191 -199.195.248.168 -193.105.134.150 -157.173.125.157 -43.230.201.87 -216.158.207.57 -23.191.200.77 -93.99.104.18 -216.158.207.191 -107.189.8.181 -185.220.101.132 -216.158.207.103 -23.191.200.18 -204.8.96.120 -185.45.95.243 -23.191.200.16 -82.223.101.158 -68.71.249.158 -45.9.156.22 -193.189.100.200 -84.239.46.144 -47.237.120.182 -185.220.101.28 -192.108.48.150 -23.191.200.10 -95.128.43.164 -185.45.95.40 -192.252.208.67 -185.45.95.98 -85.254.103.85 -107.189.3.94 -147.90.235.227 -185.220.101.141 -185.132.53.46 -174.77.111.197 -107.189.31.33 -23.191.200.46 -185.220.101.184 -82.221.128.191 -85.254.137.45 -198.98.61.60 -23.128.248.162 -185.45.95.47 -85.254.103.139 -31.24.44.107 -89.147.108.90 -185.56.171.94 -23.137.253.125 -23.129.64.190 -185.220.101.40 -192.111.129.145 -216.158.207.130 -85.254.59.70 -85.254.30.193 -205.185.113.8 -152.53.111.131 -45.66.35.28 -185.243.218.225 -107.189.13.180 -23.129.64.183 -115.79.143.180 -92.246.84.133 -23.134.88.61 -85.254.103.99 -85.254.59.211 -45.66.35.23 -64.190.76.13 -23.129.64.135 -185.45.95.55 -208.109.191.140 -45.154.98.33 -192.42.116.49 -85.254.30.72 -185.45.95.218 -23.191.200.60 -192.42.116.111 -185.220.101.156 -192.42.116.108 -185.246.190.136 -23.137.254.244 -216.158.207.106 -23.129.64.145 -216.158.207.251 -85.254.30.221 -23.191.200.9 -216.158.207.200 -216.158.207.146 -203.55.81.1 -216.158.207.114 -185.220.101.164 -185.220.101.147 -178.17.174.164 -51.158.151.177 -45.84.107.55 -85.254.59.68 -185.129.61.2 -192.252.216.86 -185.45.95.175 -178.162.175.5 -96.44.154.224 -153.127.19.115 -109.70.100.2 -185.45.95.94 -185.45.95.232 -185.45.95.15 -185.220.101.159 -70.166.167.45 -72.205.0.93 -185.220.101.189 -185.220.101.103 -23.129.64.159 -151.242.242.45 -185.220.101.8 -171.25.158.50 -85.254.137.42 -147.90.235.249 -172.232.219.78 -192.42.116.93 -185.45.95.10 -192.42.116.61 -192.42.116.105 -122.166.223.194 -185.150.28.13 -185.220.101.149 -185.45.95.105 -23.191.200.68 -185.45.95.207 -23.129.64.216 -85.254.103.80 -185.220.100.254 -185.220.101.42 -144.126.147.123 -85.254.59.224 -85.254.59.63 -178.93.57.114 -45.95.169.104 -192.42.116.118 -216.158.207.154 -216.158.207.222 -23.191.200.72 -193.189.100.205 -185.45.95.11 -31.40.204.151 -23.129.64.158 -216.158.207.242 -171.25.193.132 -185.220.100.253 -216.158.207.80 -216.158.207.105 -85.254.137.178 -185.220.101.105 -198.98.57.151 -216.158.207.98 -109.70.100.9 -149.56.44.47 -185.45.95.103 -185.45.95.178 -103.197.48.208 -185.220.101.43 -104.244.72.132 -185.220.101.145 -216.158.207.177 -194.15.115.212 -216.158.207.104 -216.158.207.228 -95.135.112.154 -68.71.243.14 -107.189.30.69 -109.70.100.6 -85.254.137.15 -95.135.112.222 -209.141.61.225 -47.82.145.247 -216.158.207.229 -216.158.207.195 -185.45.95.37 -185.45.95.161 -72.5.43.62 -85.254.137.68 -185.45.95.21 -103.146.203.11 -216.158.207.95 -23.191.200.50 -5.255.99.75 -185.45.95.13 -185.243.218.229 -185.220.101.161 -64.23.165.122 -23.129.64.224 -85.254.103.137 -41.76.213.235 -185.45.95.165 -216.158.207.7 -216.158.207.170 -45.95.169.119 -85.254.137.127 -23.129.64.213 -85.254.30.139 -85.254.30.29 -23.129.64.217 -171.25.158.113 -23.191.200.87 -185.220.101.44 -43.129.80.138 -192.42.116.51 -95.135.112.167 -185.45.95.20 -23.129.64.210 -85.254.137.50 -178.17.170.225 -23.191.200.23 -37.228.129.162 -107.189.6.124 -192.42.116.19 -13.49.28.182 -192.42.116.52 -216.158.207.143 -31.133.0.235 -37.114.50.124 -192.121.44.27 -87.118.122.30 -85.254.103.103 -70.166.167.55 -192.42.116.95 -23.191.200.107 -152.53.32.167 -83.217.9.73 -23.128.248.169 -23.129.64.204 -93.95.231.88 -23.191.200.105 -185.183.157.214 -85.254.59.123 -85.254.103.242 -178.93.57.145 -203.55.81.2 -185.246.84.179 -62.133.45.2 -23.191.200.113 -216.158.207.96 -65.254.225.220 -65.254.225.221 -45.84.107.182 -107.174.146.5 -45.133.74.53 -198.98.57.74 -23.191.200.56 -192.42.116.44 -23.129.64.198 -185.45.95.211 -147.90.234.213 -45.84.107.172 -193.189.100.194 -185.129.61.5 -37.114.50.18 -80.67.172.162 -85.254.103.213 -68.178.160.25 -23.191.200.39 -69.49.112.73 -185.129.61.8 -85.254.103.244 -85.254.30.36 -23.129.64.163 -185.220.101.139 -23.129.64.175 -107.189.7.168 -212.95.50.77 -23.191.200.118 -85.254.103.197 -108.59.12.41 -46.165.243.36 -85.254.30.224 -45.137.201.5 -185.220.101.168 -23.191.200.70 -185.181.60.204 -192.42.116.101 -23.129.64.155 -178.17.171.102 -85.254.137.80 -185.93.89.96 -95.211.239.220 -216.158.207.2 -171.25.193.35 -147.90.234.214 -85.254.103.176 -45.66.35.33 -91.98.140.41 -185.220.101.158 -216.158.207.215 -185.220.101.155 -185.39.207.83 -162.251.5.152 -185.220.100.248 -185.45.95.214 -65.254.225.232 -107.189.30.236 -185.45.95.201 -184.181.217.206 -172.105.20.12 -216.158.207.124 -89.147.110.82 -209.141.32.198 -23.129.64.192 -202.181.177.206 -185.45.95.215 -185.45.95.163 -86.54.28.49 -23.191.200.73 -185.42.170.203 -185.225.69.222 -45.84.107.47 -85.254.59.192 -93.99.104.128 -148.113.1.196 -205.185.116.34 -23.129.64.151 -185.246.188.149 -185.244.192.175 -85.254.103.83 -23.191.200.35 -185.45.95.26 -23.129.64.153 -85.254.103.92 -91.92.109.43 -185.45.95.216 -192.42.116.142 -85.254.30.202 -216.158.207.181 -85.254.30.54 -78.141.219.102 -85.254.59.64 -171.25.193.235 -23.129.64.191 -107.189.1.175 -85.254.137.149 -207.246.110.27 -216.158.207.27 -185.207.107.216 -23.129.64.215 -185.220.101.17 -85.254.59.154 -185.220.101.138 -185.246.190.83 -185.45.95.124 -198.98.62.158 -185.220.101.190 -189.15.232.200 -23.191.200.41 -185.45.95.144 -91.203.145.116 -23.95.117.249 -51.15.116.168 -192.111.139.163 -85.254.137.163 -192.42.116.114 -107.189.12.157 -64.31.31.90 -185.220.101.146 -85.254.103.14 -23.129.64.179 -185.220.101.131 -85.254.30.151 -185.45.95.132 -23.191.200.108 -185.45.95.227 -23.191.200.33 -166.70.207.2 -107.189.27.145 -194.26.192.186 -147.90.235.228 -188.68.52.231 -178.218.144.96 -107.148.225.242 -88.80.26.3 -103.193.179.233 -94.16.115.121 -193.189.100.202 -185.45.95.209 -185.193.52.180 -109.70.100.3 -185.106.102.102 -216.158.207.101 -23.128.248.161 -103.50.205.131 -23.191.200.96 -107.189.30.86 -23.191.200.3 -185.220.101.63 -82.118.248.205 -67.219.109.141 -115.245.68.130 -23.129.64.209 -50.62.183.144 -103.197.48.209 -185.45.95.137 -185.45.95.67 -185.129.61.1 -45.38.20.213 -23.129.64.166 -54.36.108.162 -85.254.137.60 -85.254.59.27 -216.158.207.53 -185.220.101.142 -185.45.95.112 -195.246.231.197 -45.137.201.100 -5.255.125.196 -23.129.64.157 -45.9.168.102 -98.178.72.30 -216.158.207.203 -85.254.59.10 -23.129.64.150 -185.220.101.183 -23.129.64.143 -185.45.95.85 -185.100.87.166 -179.43.133.50 -107.189.30.49 -85.254.59.110 -23.129.64.207 -185.220.101.134 -216.158.207.78 -185.220.101.166 -194.163.157.49 -85.254.103.196 -74.91.224.220 -205.185.124.176 -85.254.103.248 -194.53.137.156 -185.220.101.96 -95.211.244.28 -193.189.100.198 -185.45.95.231 -209.141.40.68 -216.158.207.63 -23.129.64.201 -23.191.200.24 -185.100.87.174 -65.254.225.219 -23.191.200.28 -192.42.116.106 -185.207.107.130 -185.225.69.232 -85.254.137.228 -192.42.116.13 -185.220.101.99 -216.158.207.26 -109.70.100.12 -85.254.103.142 -185.243.218.233 -199.116.114.11 -85.254.30.76 -216.158.207.188 -147.90.234.34 -147.90.234.116 -43.98.255.162 -66.78.40.91 -152.53.150.12 -147.90.234.117 -192.121.44.33 -176.65.142.198 -37.114.50.27 -185.35.202.222 -185.220.101.6 -23.191.200.36 -89.58.41.156 -45.66.35.27 -85.254.59.8 -209.141.55.88 -23.129.64.161 -188.239.191.25 -72.49.49.11 -192.42.116.143 -185.220.101.137 -23.191.200.90 -185.231.33.38 -45.84.107.222 -85.254.30.105 -45.66.35.26 -85.254.103.216 -199.116.112.3 -85.254.137.231 -45.154.98.42 -185.45.95.102 -23.129.64.225 -85.254.137.104 -5.79.66.19 -93.95.228.125 -45.194.33.12 -59.90.128.5 -185.121.170.60 -178.218.144.18 -185.220.100.240 -192.42.116.117 -195.250.23.247 -45.84.107.54 -23.191.200.63 -23.137.255.45 -185.220.101.173 -23.129.64.205 -216.158.207.113 -23.191.200.93 -23.129.64.162 -216.158.207.234 -185.220.101.129 -91.208.75.3 -85.254.137.222 -102.0.14.42 -23.129.64.185 -185.45.95.117 -195.176.3.23 -216.158.207.218 -85.254.137.83 -45.84.107.74 -147.90.235.15 -185.225.69.225 -5.255.110.120 -85.254.30.28 -204.137.14.106 -103.119.139.118 -192.121.44.34 -85.254.59.38 -104.219.236.100 -23.191.200.58 -23.129.64.178 -85.254.103.234 -85.254.59.82 -188.68.41.191 -91.206.26.26 -31.44.238.25 -85.254.137.101 -23.191.200.91 -82.221.100.222 -85.137.57.19 -185.247.224.89 -185.45.95.151 -23.191.200.88 -185.45.95.225 -185.45.95.203 -5.255.118.151 -85.254.103.28 -171.25.193.20 -85.254.59.126 -185.220.101.148 -185.45.95.8 -85.254.103.135 -85.254.30.60 -185.220.101.55 -85.254.103.241 -66.42.224.229 -85.254.30.206 -178.218.144.99 -45.137.70.158 -192.42.116.107 -85.254.59.234 -162.240.168.158 -162.19.7.11 -171.25.193.234 -23.134.88.60 -81.16.33.42 -85.254.59.227 -85.254.30.88 -45.138.16.125 -185.220.100.249 -192.42.116.99 -163.172.84.90 -185.220.101.2 -185.45.95.252 -194.15.115.204 -45.84.107.76 -216.158.207.5 -5.45.102.93 -45.66.35.32 -109.70.100.14 -51.15.59.15 -23.129.64.146 -185.220.101.31 -104.244.76.121 -193.200.229.243 -185.220.101.108 -107.189.13.254 -179.60.149.108 -185.220.101.20 -107.189.8.16 -91.208.75.4 -193.189.100.199 -185.254.196.141 -216.158.207.220 -206.206.192.178 -85.254.59.228 -185.220.101.4 -85.254.59.168 -45.84.107.198 -51.15.16.14 -185.220.101.58 -185.45.95.5 -199.58.185.9 -160.187.148.71 -85.254.59.176 -185.220.101.135 -85.254.30.148 -176.65.134.8 -85.254.59.48 -104.244.79.44 -45.137.69.13 -23.129.64.133 -201.170.74.221 -45.66.35.22 -216.158.207.89 -185.45.95.87 -185.45.95.52 -185.45.95.48 -85.254.137.186 -23.129.64.174 -185.220.101.5 -85.254.103.195 -67.23.237.2 -45.13.225.69 -185.45.95.71 -85.254.137.181 -23.129.64.176 -185.252.232.218 -47.147.19.149 -150.40.127.65 -185.220.101.106 -23.129.64.154 -91.132.144.59 -85.254.103.107 -185.45.95.93 -85.254.137.114 -85.254.30.189 -23.191.200.45 -69.163.77.166 -23.129.64.170 -85.254.103.52 -171.25.193.81 -85.254.59.137 -216.158.207.232 -192.42.116.64 -23.191.200.55 -93.113.25.160 -198.54.121.186 -149.202.79.101 -178.218.144.51 -85.254.30.82 -64.190.76.3 -85.254.30.185 -185.220.101.153 -85.254.137.144 -45.9.168.96 -23.129.64.136 -23.191.200.14 -77.48.28.204 -185.220.101.109 -85.254.59.163 -193.189.100.196 -83.212.240.55 -146.59.231.4 -216.158.207.231 -85.254.30.67 -88.80.26.2 -216.158.207.212 -85.254.59.248 -5.255.102.26 -85.254.103.22 -23.191.200.103 -98.188.47.150 -173.237.206.68 -85.254.59.201 -192.42.116.50 -213.171.208.232 -172.194.139.254 -23.191.200.83 -185.129.61.7 -192.42.116.112 -45.66.35.24 -192.42.116.18 -192.42.116.92 -204.137.14.92 -216.158.207.6 -85.254.137.232 -5.255.118.218 -216.158.207.20 -109.70.100.10 -185.129.61.129 -185.45.95.77 -23.191.200.112 -103.109.187.71 -216.158.207.73 -192.42.116.12 -85.254.103.112 -85.254.59.6 -107.189.5.7 -85.254.30.68 -216.158.207.194 -23.191.200.26 -85.254.137.249 -185.220.101.188 -216.158.207.245 -194.32.107.231 -109.69.67.17 -66.116.199.98 -216.158.207.206 -103.197.48.211 -23.129.64.138 -171.25.193.36 -185.45.95.177 -192.42.116.110 -85.254.137.198 -185.45.95.193 -107.189.8.65 -85.254.137.131 -194.15.113.118 -185.220.101.140 -64.188.77.26 -89.248.193.158 -185.132.53.150 -185.220.101.175 -154.16.116.61 -144.31.192.13 -107.189.7.141 -185.45.95.150 -47.82.151.247 -84.19.182.20 -185.45.95.59 -143.20.166.14 -37.228.129.128 -185.220.101.32 -85.254.137.252 -72.195.34.35 -147.90.234.88 -204.137.14.104 -89.147.110.118 -85.254.137.233 -155.94.163.175 -185.45.95.83 -171.25.193.38 -185.246.188.73 -77.48.28.239 -23.129.64.184 -23.129.64.208 -82.221.100.12 -104.244.73.190 -78.142.18.172 -23.191.200.29 -5.45.98.162 -203.12.31.87 -185.45.95.164 -85.254.30.183 -45.66.35.25 -85.254.59.175 -23.129.64.142 -107.189.1.9 -216.158.207.32 -109.228.160.190 -89.58.26.216 -85.254.103.133 -85.254.103.63 -47.79.79.35 -104.244.76.237 -216.158.207.52 -23.129.64.160 -23.129.64.152 -87.121.79.14 -192.42.116.59 -185.220.101.41 -85.254.30.181 -95.135.113.248 -185.45.95.90 -192.42.116.116 -64.94.85.248 -185.220.101.23 -216.158.207.137 -43.161.217.219 -23.129.64.220 -192.42.116.97 -72.207.109.5 -209.141.45.141 -185.132.53.121 -85.254.137.63 -72.37.217.3 -179.43.182.232 -192.42.116.55 -23.129.64.181 -23.191.200.13 -104.244.78.233 -50.6.196.179 -23.191.200.121 -171.25.193.25 -185.45.95.241 -192.42.116.98 -72.214.108.67 -85.254.59.166 -67.215.234.141 -23.129.64.148 -216.158.207.25 -185.220.101.151 -216.158.207.33 -171.25.193.77 -193.189.100.195 -23.129.64.195 -216.158.207.161 -185.31.121.107 -185.220.101.61 -85.254.59.219 -104.244.73.136 -23.129.64.182 -158.174.210.97 -23.191.200.80 -185.45.95.43 -185.45.95.226 -82.221.131.5 -216.158.207.1 -109.70.100.7 -23.94.148.16 -85.254.59.106 -185.227.68.78 -185.132.53.45 -23.129.64.132 -185.165.171.84 -23.191.200.76 -216.73.159.101 -23.191.200.38 -45.131.64.118 -104.37.188.34 -85.254.103.163 -23.129.64.187 -147.90.234.30 -168.253.92.93 -185.45.95.157 -185.225.69.187 -85.254.59.9 -91.208.75.156 -85.254.30.112 -209.127.122.140 -208.109.188.137 -5.255.115.58 -107.189.3.11 -194.32.107.14 -185.220.100.243 -45.38.20.153 -91.208.75.153 -85.254.103.170 -185.45.95.182 -185.220.101.101 -85.254.103.120 -27.75.98.73 -185.45.95.54 -198.54.114.113 -101.99.79.250 -78.29.40.227 -171.25.193.79 -192.42.116.103 -185.45.95.192 -23.129.64.173 -192.42.116.54 -109.237.27.11 -185.220.101.19 -216.158.207.202 -23.191.200.32 -24.203.156.90 -185.45.95.121 -185.220.101.186 -185.220.101.56 -192.42.116.58 -45.9.168.93 -185.132.53.37 -185.45.95.120 -94.230.208.148 -85.254.30.184 -45.13.225.78 -46.232.251.191 -185.150.189.131 -204.85.191.8 -185.220.101.29 -85.254.59.15 -65.254.225.231 -45.9.168.106 -184.178.172.17 -65.87.7.53 -205.185.113.180 -171.25.193.78 -185.220.100.247 -104.244.74.51 -185.45.95.155 -64.190.76.11 -85.254.137.106 -85.254.103.204 -23.129.64.177 -85.254.103.45 -45.84.107.101 -192.42.116.144 -87.118.116.90 -85.254.103.68 -176.65.148.3 -85.254.59.40 -85.254.59.120 -212.21.66.6 -185.45.95.125 -85.254.137.190 -199.195.251.119 -185.220.101.136 -72.207.33.64 -216.158.207.81 -109.70.100.4 -81.17.28.95 -85.254.30.190 -87.118.110.27 -23.129.64.169 -185.220.101.48 -94.142.244.16 -85.254.137.84 -38.49.217.60 -216.158.207.168 -5.253.247.27 -216.9.225.157 -85.254.30.191 -107.189.8.133 -37.48.70.156 -185.45.95.236 -194.15.112.133 -185.45.95.166 -192.76.153.253 -37.114.63.5 -91.203.144.194 -23.129.64.202 -185.220.100.244 -216.158.207.176 -45.141.119.80 -185.45.95.221 -192.42.116.67 -109.71.252.182 -168.63.79.147 -23.128.248.160 -85.254.59.116 -23.129.64.223 -23.129.64.147 -85.254.30.1 -185.220.101.37 -184.178.172.5 -85.254.59.233 -192.42.116.47 -74.82.47.194 -85.254.103.231 -185.220.101.54 -185.45.95.143 -23.129.64.221 -23.129.64.196 -198.8.84.3 -192.42.116.17 -185.45.95.188 -85.254.30.81 -95.135.112.147 -188.68.49.235 -23.191.200.123 -185.220.100.252 -164.52.218.210 -216.158.207.120 -184.178.172.18 -185.45.95.89 -85.254.59.1 -185.129.62.63 -185.45.95.1 -45.66.35.21 -192.42.116.60 -195.176.3.24 -85.254.103.253 -185.220.101.10 -185.220.101.165 -185.45.95.53 -85.254.30.50 -23.129.64.144 -80.67.167.81 -185.220.101.57 -216.158.207.72 -185.220.101.104 -216.158.207.189 -194.15.36.117 -185.220.101.45 -51.15.18.73 -23.191.200.57 -193.189.100.197 -85.254.103.186 -172.81.131.139 -107.189.12.7 -199.229.254.129 -5.83.143.18 -193.189.100.206 -185.45.95.86 -85.254.137.110 -185.220.101.36 -85.254.103.240 -23.129.64.149 -185.220.101.133 -107.189.7.144 -178.175.148.155 -109.70.100.13 -85.254.59.151 -85.254.59.17 -41.76.213.108 -185.220.101.162 -85.254.30.247 -185.45.95.189 diff --git a/iptimes.txt b/iptimes.txt deleted file mode 100644 index ca26976b..00000000 --- a/iptimes.txt +++ /dev/null @@ -1,1304 +0,0 @@ -162.240.96.211:1277909 -216.158.207.177:287 -31.24.44.107:14819 -184.178.172.23:234234 -66.42.224.229:1190039 -72.195.114.169:202139 -192.252.215.5:204364 -98.170.57.249:88341 -72.49.49.11:1221484 -216.158.207.251:345 -171.25.158.95:808940 -98.181.137.80:207325 -199.102.105.242:40754 -5.255.99.75:2237476 -51.79.177.162:1267868 -82.193.116.160:67013 -45.194.33.12:1942379 -192.252.216.86:43469 -43.161.217.219:1303081 -184.178.172.11:28507 -142.54.235.9:77099 -109.70.100.8:308 -199.116.112.6:38715 -104.37.135.145:189534 -185.45.95.103:978 -67.201.35.145:2216 -43.129.80.138:21554 -103.197.48.210:12145 -98.188.47.150:87369 -72.195.114.184:201281 -72.214.108.67:503996 -199.229.254.129:4392 -68.71.249.158:53214 -98.178.72.30:93465 -85.254.137.120:465 -199.58.184.97:44909 -184.178.172.25:126524 -192.42.116.56:1132 -5.255.123.162:908808 -192.111.130.5:38802 -142.54.237.34:175305 -72.207.109.5:87193 -216.158.207.186:659 -23.129.64.169:1818 -85.254.103.58:523 -192.252.209.155:76237 -199.116.114.11:2491 -192.252.208.67:47932 -85.254.30.223:640 -23.129.64.137:1944 -70.166.167.55:179663 -23.129.64.183:2906 -85.254.59.1:543 -185.45.95.93:942 -23.129.64.195:2599 -168.253.92.93:41052 -184.178.172.26:165610 -216.158.207.159:665 -85.254.30.105:529 -185.220.101.106:1140 -192.111.139.163:95999 -198.8.84.3:50986 -64.94.85.248:11476 -152.53.144.223:1217977 -184.178.172.5:144105 -184.170.249.65:56047 -85.254.103.118:509 -185.45.95.73:904 -208.102.51.6:774762 -23.129.64.133:2593 -85.254.137.104:517 -85.254.137.127:641 -104.244.73.14:1105 -192.111.135.18:105810 -23.129.64.147:2548 -85.254.137.181:546 -72.207.33.64:2884 -174.77.111.197:82695 -85.254.103.56:521 -68.71.242.118:2430 -192.252.209.158:51724 -98.188.47.132:68817 -192.42.116.65:217 -192.111.129.145:43892 -70.166.167.45:3022 -185.129.61.9:41 -23.129.64.170:1993 -23.129.64.189:1519 -192.42.116.62:352 -216.158.207.26:720 -184.181.217.206:132135 -192.42.116.105:467 -185.45.95.174:398 -185.45.95.123:734 -23.129.64.224:2634 -184.181.217.210:118663 -216.158.207.190:406 -216.158.207.25:684 -23.129.64.191:1991 -85.254.30.151:429 -199.116.112.3:28742 -216.158.207.105:487 -23.129.64.210:4184 -216.158.207.232:408 -23.129.64.151:2627 -185.45.95.43:684 -185.45.95.193:540 -216.158.207.106:896 -72.5.43.62:8168 -85.254.59.14:388 -85.254.59.6:579 -206.166.251.193:7544 -216.158.207.172:476 -185.45.95.182:541 -23.129.64.203:3182 -85.254.59.110:838 -185.45.95.242:521 -185.45.95.156:353 -185.45.95.120:398 -185.45.95.215:656 -47.147.19.149:83110 -85.254.30.206:485 -85.254.59.228:327 -85.254.59.20:726 -85.254.137.43:420 -185.45.95.188:374 -23.129.64.148:3895 -85.254.30.189:839 -185.45.95.71:386 -23.129.64.223:2179 -85.254.30.224:748 -192.42.116.46:766 -185.45.95.124:712 -85.254.30.212:638 -23.129.64.164:3712 -85.254.30.193:648 -216.158.207.215:623 -192.42.116.43:994 -185.220.101.169:23 -85.254.137.106:720 -85.254.137.249:498 -85.254.59.220:405 -85.254.137.73:790 -85.254.103.227:547 -185.220.101.36:467 -216.158.207.78:644 -85.254.59.10:513 -192.42.116.60:608 -85.254.30.29:515 -185.45.95.125:668 -185.45.95.132:881 -185.129.61.2:266 -47.79.79.35:1358 -85.254.137.138:549 -216.158.207.195:466 -185.45.95.218:503 -85.254.59.134:572 -23.129.64.190:2531 -85.254.137.123:730 -216.158.207.204:371 -23.129.64.175:2982 -216.158.207.95:741 -85.254.30.191:719 -23.129.64.219:3339 -192.42.116.110:110 -192.42.116.15:181 -85.254.30.2:397 -85.254.103.112:705 -85.254.30.150:680 -85.254.103.70:363 -85.254.137.114:679 -179.60.149.108:14541 -85.254.30.15:495 -85.254.103.139:392 -216.158.207.228:588 -23.129.64.166:3062 -216.158.207.124:613 -85.254.137.219:607 -216.158.207.158:496 -85.254.103.240:490 -85.254.103.205:511 -216.158.207.229:500 -185.45.95.13:722 -107.189.30.86:862 -216.158.207.96:395 -64.69.40.75:1526 -216.158.207.101:443 -85.254.103.241:693 -64.190.113.221:9750 -185.45.95.149:771 -51.38.225.46:599 -216.158.207.76:759 -78.29.40.227:8260 -23.129.64.135:2702 -85.254.137.80:522 -85.254.103.62:686 -185.45.95.10:581 -185.45.95.221:587 -123.136.31.130:38338 -45.84.107.182:2594 -85.254.59.253:706 -23.129.64.199:3241 -185.45.95.82:636 -216.158.207.89:625 -23.129.64.140:1975 -85.254.137.57:469 -23.129.64.208:2272 -216.158.207.185:741 -216.158.207.18:493 -107.189.12.3:19 -216.158.207.152:756 -83.212.240.55:25489 -23.129.64.200:3130 -85.254.137.189:247 -91.92.109.126:682 -85.254.137.226:319 -85.254.59.172:611 -192.42.116.67:194 -185.45.95.231:295 -85.254.103.163:496 -185.220.101.96:651 -23.129.64.173:2059 -216.158.207.179:517 -23.129.64.130:2138 -23.129.64.204:3448 -185.45.95.191:564 -107.189.13.254:45009 -109.70.100.5:48 -216.158.207.66:469 -85.254.59.116:743 -85.254.30.137:575 -185.220.101.133:314 -23.129.64.142:2225 -23.129.64.180:2062 -88.80.26.3:1295 -23.129.64.213:2703 -185.45.95.47:376 -5.255.117.56:96 -216.158.207.53:768 -23.129.64.209:3605 -85.254.103.92:443 -85.254.103.103:698 -85.254.59.123:663 -185.220.101.109:949 -216.158.207.157:493 -216.158.207.98:561 -85.254.103.153:939 -23.129.64.156:2402 -85.254.30.184:394 -185.220.100.240:1777 -185.45.95.134:706 -85.254.59.234:519 -85.254.103.22:489 -64.190.113.106:6538 -85.254.137.205:759 -85.254.137.190:638 -85.254.137.78:594 -216.158.207.121:550 -185.129.62.62:1191 -216.158.207.191:283 -85.254.103.28:543 -85.254.30.82:654 -23.129.64.211:2441 -216.158.207.69:908 -23.129.64.184:2755 -23.129.64.159:2070 -185.220.101.166:261 -23.129.64.225:2550 -23.129.64.212:1637 -85.254.137.209:408 -23.129.64.178:2893 -85.254.30.185:475 -23.129.64.181:2757 -45.84.107.97:2920 -192.42.116.93:48 -23.129.64.207:2870 -45.84.107.54:4084 -185.220.101.146:360 -23.129.64.99:2299 -109.70.100.9:235 -192.42.116.47:467 -109.70.100.11:284 -45.84.107.74:4095 -85.254.59.163:551 -147.90.234.115:1038 -23.129.64.160:2596 -216.158.207.54:582 -54.36.108.162:335 -45.84.107.128:3140 -23.129.64.171:2022 -185.220.101.57:386 -45.84.107.174:3556 -37.114.50.124:179 -107.189.13.180:267 -185.220.101.97:361 -85.254.137.252:613 -216.158.207.7:654 -85.254.59.224:467 -185.45.95.5:1025 -193.189.100.199:617 -23.129.64.165:3905 -185.45.95.94:590 -185.220.101.47:414 -23.129.64.141:3514 -216.158.207.63:723 -23.129.64.179:2469 -23.129.64.143:2161 -185.45.95.225:816 -85.254.59.233:657 -192.42.116.42:368 -216.158.207.2:576 -185.220.101.61:128 -185.45.95.173:504 -216.158.207.29:284 -85.254.103.128:287 -23.129.64.174:2746 -85.254.59.205:573 -85.254.103.133:693 -185.231.33.38:1962 -85.254.103.197:648 -176.65.134.8:839 -85.254.59.166:752 -216.158.207.85:500 -23.129.64.138:4013 -216.158.207.250:410 -216.158.207.1:635 -216.158.207.174:1049 -185.220.101.174:260 -45.66.35.27:371 -185.45.95.203:587 -185.220.100.243:1998 -23.129.64.177:2524 -85.254.59.135:495 -216.158.207.189:872 -85.254.59.137:495 -23.129.64.185:1778 -85.254.59.151:1110 -185.45.95.254:489 -192.42.116.44:334 -142.249.174.12:16 -185.220.101.189:819 -103.197.48.211:481 -216.158.207.218:521 -109.70.100.15:424 -185.220.101.105:231 -85.254.103.170:433 -192.42.116.58:725 -185.45.95.157:476 -23.129.64.187:3116 -185.45.95.21:566 -192.42.116.112:1333 -185.220.101.101:530 -185.45.95.155:485 -23.129.64.149:1888 -185.220.101.132:496 -23.129.64.167:3400 -185.220.101.143:114 -216.158.207.131:628 -85.254.103.253:399 -85.254.59.227:641 -216.158.207.170:559 -23.129.64.202:2381 -23.129.64.155:2496 -109.70.100.2:51 -23.129.64.194:3595 -23.129.64.206:2830 -23.191.200.18:211 -23.129.64.146:1894 -94.142.241.194:21 -23.129.64.215:1798 -85.254.59.63:270 -185.220.101.181:470 -85.254.59.15:719 -192.42.116.54:536 -85.254.30.175:523 -216.158.207.242:648 -185.45.95.226:503 -185.45.95.105:414 -45.66.35.35:458 -216.158.207.181:523 -185.45.95.66:559 -85.254.30.68:533 -147.90.234.88:162 -216.158.207.37:614 -185.243.218.225:898 -192.42.116.68:37 -185.45.95.72:940 -45.66.35.26:483 -216.158.207.168:718 -216.158.207.151:842 -85.254.103.209:565 -23.129.64.158:2581 -85.254.59.82:587 -193.189.100.200:1009 -85.254.103.80:636 -216.158.207.143:934 -102.211.56.20:35 -185.45.95.90:534 -23.129.64.154:2247 -216.158.207.27:1215 -185.220.101.107:1167 -23.129.64.176:3045 -185.220.100.252:903 -185.45.95.163:962 -85.254.30.114:457 -45.84.107.172:2339 -85.254.103.204:603 -45.84.107.198:2421 -185.45.95.165:381 -85.254.30.247:705 -23.129.64.182:2268 -216.158.207.80:345 -85.254.137.99:616 -107.189.1.175:603 -85.254.59.208:758 -185.45.95.177:344 -185.45.95.33:692 -185.45.95.4:818 -23.129.64.161:2526 -185.45.95.20:520 -216.158.207.154:575 -207.246.110.27:179 -216.158.207.103:752 -23.129.64.217:2715 -216.158.207.219:218 -185.45.95.209:695 -23.129.64.196:3002 -185.45.95.70:470 -23.129.64.192:2286 -216.158.207.141:644 -185.45.95.117:501 -85.254.137.50:351 -216.158.207.46:523 -216.158.207.200:521 -192.42.116.116:326 -216.158.207.234:454 -85.254.137.211:606 -85.254.103.186:493 -85.254.103.132:436 -185.45.95.198:720 -185.45.95.181:791 -85.254.103.234:338 -185.45.95.161:575 -85.254.30.135:470 -85.254.59.192:481 -185.220.101.103:715 -85.254.59.150:398 -91.206.26.26:501 -185.246.188.74:3593 -85.254.30.28:709 -185.45.95.137:580 -85.254.103.248:405 -85.254.103.196:642 -85.254.59.17:642 -23.129.64.144:3429 -107.189.8.181:759 -216.158.207.217:574 -5.255.111.52:315 -85.254.103.30:608 -185.45.95.111:571 -185.246.188.73:2401 -185.45.95.92:247 -85.254.137.42:345 -85.254.137.139:633 -185.45.95.89:748 -23.129.64.216:2674 -23.129.64.139:2056 -216.158.207.214:250 -185.45.95.223:486 -45.84.107.222:2426 -185.45.95.227:800 -85.254.30.183:559 -216.158.207.14:476 -85.254.103.211:382 -77.48.28.204:214 -185.45.95.212:486 -216.158.207.13:396 -185.45.95.77:496 -85.254.59.126:717 -216.158.207.32:539 -185.45.95.143:802 -216.158.207.83:792 -85.254.137.149:507 -23.129.64.188:2543 -185.45.95.115:797 -216.158.207.125:571 -185.45.95.35:633 -85.254.103.142:382 -85.254.59.76:237 -85.254.137.173:545 -185.45.95.53:578 -95.169.191.186:80 -185.45.95.25:608 -185.220.101.139:153 -45.66.35.32:563 -85.254.30.76:656 -185.150.28.13:280 -185.45.95.59:426 -85.254.59.154:572 -85.254.30.50:603 -203.55.81.2:3133 -85.254.59.99:624 -185.45.95.55:575 -85.254.59.38:657 -107.189.3.11:321 -185.45.95.54:499 -185.129.62.63:704 -128.31.0.13:126 -216.158.207.59:894 -185.45.95.207:596 -85.254.137.232:397 -85.254.59.176:410 -193.189.100.205:388 -185.45.95.127:650 -45.66.35.23:257 -85.254.103.25:911 -85.254.59.46:593 -85.254.30.139:449 -216.158.207.142:457 -185.45.95.40:345 -23.129.64.163:2470 -185.45.95.200:494 -107.189.7.141:337 -185.45.95.232:1118 -216.158.207.146:981 -85.254.30.1:395 -185.45.95.37:611 -85.254.137.27:512 -185.220.100.253:1646 -185.100.87.41:118 -185.220.101.137:277 -85.254.103.63:675 -85.254.103.221:579 -85.254.30.18:614 -185.45.95.192:719 -85.254.137.233:613 -185.45.95.11:652 -185.45.95.8:567 -185.243.218.226:758 -185.45.95.83:1213 -204.137.14.106:385 -185.45.95.52:671 -85.254.103.54:491 -23.129.64.220:2020 -216.158.207.64:689 -45.13.237.121:266 -216.158.207.33:625 -85.254.103.107:426 -85.254.30.120:557 -171.25.193.132:770 -85.254.30.81:489 -185.45.95.102:752 -80.67.172.162:910 -85.254.103.212:275 -185.45.95.201:694 -45.84.107.17:2632 -85.254.59.167:393 -109.71.252.88:306 -85.254.30.88:649 -85.254.30.246:588 -85.254.103.81:573 -85.254.59.164:268 -185.45.95.151:512 -23.129.64.172:2519 -216.158.207.5:509 -185.45.95.187:437 -216.158.207.81:781 -85.254.137.231:510 -185.45.95.34:771 -85.254.137.131:575 -85.254.103.180:352 -85.254.103.120:527 -64.190.76.4:296 -85.254.59.148:558 -85.254.103.144:671 -85.254.103.244:378 -85.254.103.148:710 -185.45.95.114:617 -216.158.207.20:374 -216.158.207.205:214 -85.254.59.211:450 -85.254.59.201:655 -216.158.207.192:669 -216.158.207.57:481 -93.99.104.128:95 -216.158.207.104:414 -85.254.30.148:462 -185.45.95.61:584 -185.45.95.220:701 -185.45.95.49:594 -45.135.194.111:474 -35.0.127.52:198 -185.45.95.166:702 -216.158.207.113:660 -85.254.137.83:541 -216.158.207.220:558 -85.254.30.171:402 -216.158.207.73:715 -23.129.64.162:2120 -85.254.103.52:435 -216.158.207.222:449 -23.129.64.132:2099 -185.45.95.211:551 -85.254.103.242:343 -185.220.101.99:1121 -85.254.59.168:340 -85.254.30.221:548 -85.254.59.249:780 -85.254.137.163:503 -185.45.95.168:556 -85.254.59.9:443 -185.45.95.162:901 -147.90.235.15:363 -216.158.207.239:617 -85.254.103.213:324 -85.254.30.67:350 -193.189.100.197:643 -85.254.103.83:555 -85.254.30.202:582 -185.45.95.160:697 -23.129.64.214:1988 -216.158.207.86:439 -85.254.59.136:582 -185.220.101.34:132 -85.254.59.157:613 -85.254.137.31:461 -85.254.103.14:552 -85.254.59.152:382 -216.158.207.72:566 -192.42.116.18:174 -192.42.116.92:1008 -85.254.59.162:563 -192.42.116.64:918 -85.254.59.106:724 -193.105.134.155:42 -85.254.103.127:573 -185.45.95.85:716 -85.254.30.54:311 -85.254.59.92:684 -216.158.207.164:527 -85.254.103.137:453 -171.25.193.80:966 -185.220.101.33:756 -45.9.156.106:46 -192.42.116.114:494 -185.45.95.216:978 -85.254.137.243:707 -185.45.95.95:751 -23.129.64.222:2712 -203.55.81.1:2977 -23.129.64.205:3140 -185.220.100.242:1737 -216.158.207.243:790 -185.129.62.64:1145 -85.254.59.48:373 -85.254.103.85:512 -85.254.103.93:686 -185.45.95.189:735 -85.254.103.0:588 -107.189.3.148:267 -185.45.95.110:741 -216.158.207.44:650 -216.158.207.225:534 -185.45.95.217:727 -85.254.103.99:416 -185.220.100.247:637 -216.158.207.206:688 -85.254.30.96:485 -185.220.101.52:454 -216.158.207.188:521 -85.254.59.64:440 -85.254.137.110:580 -85.254.59.70:734 -216.158.207.245:533 -23.129.64.221:2538 -85.254.30.36:252 -85.254.137.60:696 -216.158.207.137:790 -23.129.64.157:1603 -185.181.61.203:1011 -85.254.137.84:649 -85.254.59.68:271 -23.129.64.150:2163 -216.158.207.107:554 -185.45.95.19:488 -185.129.61.3:341 -216.158.207.231:695 -85.254.137.166:655 -5.255.123.158:255 -185.45.95.1:580 -85.254.103.68:543 -85.254.59.67:515 -85.254.137.144:894 -85.254.30.181:632 -85.254.137.154:618 -85.254.30.112:444 -85.254.59.124:590 -185.45.95.241:581 -185.45.95.240:562 -85.254.59.27:613 -216.158.207.108:424 -216.158.207.202:649 -185.220.101.151:217 -85.254.137.100:429 -85.254.30.244:426 -185.45.95.74:691 -85.254.59.248:457 -192.42.116.118:121 -45.66.35.21:146 -85.254.103.135:639 -85.254.137.161:608 -171.25.193.81:1408 -85.254.103.18:716 -85.254.59.97:551 -85.254.30.190:561 -45.13.225.78:988 -185.45.95.144:441 -85.254.137.178:495 -85.254.59.188:384 -185.45.95.67:608 -185.45.95.98:536 -146.59.231.4:20 -216.158.207.176:625 -85.254.137.228:404 -185.220.101.144:717 -45.84.107.101:2248 -185.45.95.91:973 -185.45.95.0:399 -212.95.50.77:51 -23.129.64.218:2288 -85.254.137.101:747 -23.129.64.198:1901 -185.45.95.175:677 -185.45.95.178:624 -85.254.137.15:366 -185.45.95.81:462 -5.255.125.196:494 -185.45.95.86:860 -85.254.59.100:558 -216.158.207.171:576 -85.254.103.105:293 -185.45.95.128:447 -85.254.59.160:411 -85.254.137.198:334 -171.25.193.37:381 -185.45.95.196:438 -23.129.64.153:2612 -85.254.137.45:429 -107.189.6.124:724 -150.40.126.172:129 -23.191.200.7:89 -216.158.207.130:440 -23.129.64.168:1943 -185.220.101.1:425 -171.25.193.131:862 -104.244.73.190:125 -185.45.95.26:438 -185.220.101.29:529 -85.254.137.170:481 -171.25.193.45:678 -45.66.35.34:841 -192.42.116.51:337 -185.243.218.232:305 -185.45.95.62:584 -216.158.207.120:860 -23.129.64.152:3700 -45.84.107.47:2175 -109.70.100.3:530 -192.42.116.108:690 -185.220.101.14:565 -192.42.116.20:271 -45.91.250.107:539 -185.45.95.252:454 -85.254.59.43:486 -185.220.101.98:937 -185.220.101.136:501 -85.254.30.166:452 -216.158.207.194:807 -85.254.137.175:421 -194.32.107.231:416 -23.129.64.136:3284 -23.129.64.197:2955 -185.130.47.58:269 -45.9.168.93:117 -185.220.101.30:149 -85.254.30.60:817 -88.80.26.2:446 -23.129.64.134:2839 -185.220.100.241:2061 -85.254.30.104:653 -193.189.100.206:442 -192.42.116.95:208 -85.254.137.192:508 -185.45.95.236:520 -185.220.100.255:1295 -147.90.234.118:62 -216.158.207.6:409 -185.220.101.20:298 -185.170.114.25:259 -45.66.35.30:535 -192.42.116.103:1224 -216.158.207.161:429 -192.42.116.45:425 -216.158.207.246:708 -216.158.207.212:497 -185.45.95.150:627 -107.189.31.52:68 -171.25.193.82:1003 -109.70.100.10:198 -85.254.103.249:685 -185.220.101.53:395 -185.45.95.112:484 -45.84.107.76:2183 -45.84.107.33:3489 -85.254.103.195:426 -192.42.116.16:84 -5.255.119.76:293 -185.45.95.199:725 -91.208.75.156:135 -85.254.59.72:466 -185.220.101.2:175 -216.158.207.114:520 -185.45.95.87:410 -85.254.103.21:506 -185.220.101.6:311 -85.254.59.175:509 -185.220.100.249:844 -185.165.169.239:87 -192.42.116.101:213 -85.254.59.8:533 -85.254.137.97:473 -192.42.116.66:968 -45.84.107.55:3396 -107.189.29.8:266 -86.54.28.49:409 -185.220.101.182:447 -193.189.100.201:242 -192.42.116.100:350 -192.42.116.109:332 -85.254.30.230:415 -185.220.101.16:119 -23.129.64.201:2918 -85.254.103.149:641 -185.45.95.164:634 -45.66.35.24:140 -185.220.101.108:975 -216.158.207.167:529 -192.42.116.115:878 -185.220.100.254:2071 -216.158.207.52:256 -80.67.167.81:759 -185.45.95.63:604 -171.25.193.40:424 -185.220.101.186:108 -198.98.62.158:220 -171.25.193.235:631 -185.220.101.180:276 -185.45.95.15:466 -192.42.116.99:1777 -185.45.95.214:428 -107.189.8.70:102 -85.254.59.219:488 -192.42.116.53:186 -85.254.103.216:379 -193.189.100.195:401 -185.220.100.244:927 -104.244.76.121:198 -95.211.239.220:86 -5.255.118.151:24 -192.42.116.111:286 -45.38.20.153:5070 -64.190.76.12:370 -107.189.8.16:110 -95.128.43.164:69 -85.93.218.204:48 -85.254.30.167:572 -185.220.101.142:479 -193.189.100.204:372 -185.45.95.243:560 -185.220.101.7:759 -192.42.116.55:725 -85.254.137.186:572 -185.45.95.142:464 -192.42.116.52:199 -109.71.252.182:326 -89.147.110.82:14 -171.25.193.39:487 -64.190.76.14:184 -147.90.234.63:200 -185.220.101.140:248 -23.151.8.88:634 -185.220.101.31:220 -192.42.116.102:151 -85.254.137.63:417 -23.129.64.131:2452 -185.220.101.164:233 -51.15.116.168:332 -185.220.101.135:290 -185.220.101.177:545 -109.70.100.12:722 -185.246.188.149:788 -45.95.169.119:70 -147.90.235.20:109 -185.243.218.233:384 -82.221.131.86:278 -185.132.53.150:8 -192.108.48.150:137 -85.254.137.68:494 -85.254.103.45:443 -85.254.30.199:343 -185.220.101.147:39 -185.220.101.11:350 -185.220.101.21:121 -85.254.30.72:300 -147.90.235.249:442 -23.129.64.145:2577 -185.220.101.162:433 -185.45.95.48:579 -85.254.103.231:373 -185.220.101.25:140 -23.129.64.193:1839 -149.56.44.47:52 -185.220.101.102:665 -85.254.59.40:179 -205.185.113.112:11 -216.158.207.203:657 -193.189.100.198:790 -185.45.95.121:552 -185.220.101.62:424 -193.36.132.21:190 -185.220.100.245:92 -185.220.101.188:605 -45.66.35.31:569 -147.90.234.117:721 -185.225.69.225:185 -84.21.166.105:1552 -45.133.74.53:239 -85.254.137.222:333 -85.254.59.120:268 -192.42.116.107:460 -193.189.100.203:915 -185.220.101.145:200 -185.220.101.104:289 -185.220.101.161:484 -91.208.75.153:197 -216.158.207.34:543 -152.53.210.165:190 -85.254.59.2:325 -152.53.32.167:222 -192.42.116.98:529 -147.90.234.116:32 -85.137.57.19:487 -37.114.50.142:168 -178.162.175.5:211 -192.42.116.50:561 -103.91.65.44:99 -185.220.101.26:328 -37.114.50.27:107 -64.190.76.2:685 -93.113.25.160:28 -185.246.190.83:179 -216.158.207.129:419 -185.220.101.138:799 -109.70.100.13:465 -178.20.55.16:187 -216.158.207.227:385 -185.220.101.32:740 -31.133.0.235:800 -201.170.74.221:3714 -51.91.18.151:121 -147.90.235.21:402 -78.142.18.172:32255 -185.225.69.187:21 -185.220.101.19:61 -193.189.100.194:412 -46.232.251.191:107 -185.220.101.35:223 -45.84.107.200:220 -216.158.207.60:664 -23.129.64.186:1338 -51.15.18.73:399 -192.42.116.113:149 -204.8.96.120:99 -185.129.61.8:378 -185.220.101.159:289 -104.244.74.51:18 -185.220.101.154:416 -185.220.101.5:622 -185.100.87.174:348 -171.25.193.77:423 -23.128.248.161:114 -185.220.101.141:417 -85.254.103.176:302 -192.121.44.26:123 -185.220.101.28:183 -168.144.112.115:161 -150.40.127.65:36 -185.220.101.167:536 -185.220.101.9:488 -171.25.193.79:516 -185.220.100.251:479 -107.189.31.187:268 -192.76.153.253:477 -192.42.116.63:13 -193.200.229.243:487 -37.114.63.5:525 -171.25.193.38:346 -147.90.234.214:359 -65.254.225.231:5876 -45.66.35.20:593 -65.254.225.232:5439 -65.254.225.234:5952 -65.254.225.233:6266 -171.25.193.46:1254 -192.42.116.117:327 -185.220.101.187:255 -185.220.101.0:402 -185.220.101.38:269 -185.220.101.42:59 -185.220.101.10:252 -192.42.116.97:350 -23.191.200.88:48 -185.220.101.51:222 -192.42.116.19:126 -5.255.101.10:423 -185.220.101.13:216 -171.25.193.35:738 -185.220.101.15:105 -185.220.101.110:674 -23.191.200.24:246 -185.220.101.4:409 -171.25.193.78:1114 -185.129.61.129:158 -185.220.101.56:440 -185.220.101.3:422 -23.137.255.45:206 -179.43.133.50:155 -45.66.35.25:407 -77.90.185.51:121 -178.218.144.99:274 -45.12.3.80:148 -64.190.76.10:542 -88.80.26.4:774 -89.147.108.90:46 -185.220.100.248:811 -185.220.101.43:192 -31.220.75.237:301 -185.100.87.166:397 -109.71.252.97:290 -107.189.30.69:505 -192.42.116.49:152 -185.129.61.1:270 -216.9.225.157:226 -87.118.122.51:133 -5.255.123.164:29 -91.208.75.3:206 -185.220.101.134:235 -192.42.116.21:166 -185.220.101.176:299 -45.66.35.33:366 -185.220.101.184:215 -171.25.193.20:697 -185.220.101.24:315 -192.42.116.48:644 -212.21.66.6:91 -109.70.100.1:292 -185.220.101.41:68 -192.42.116.144:35 -185.220.101.60:263 -45.137.69.13:264 -185.220.101.55:122 -185.129.61.7:64 -84.16.224.227:54 -23.137.105.248:216 -176.65.142.198:1073 -185.220.101.183:403 -185.220.101.100:906 -23.191.200.92:116 -96.44.154.224:81 -185.220.101.185:650 -217.154.191.103:101 -37.114.50.18:279 -46.165.243.36:59 -185.220.101.156:154 -93.113.25.90:345 -198.98.61.60:22 -185.244.192.184:236 -185.220.101.59:354 -64.190.76.3:368 -107.189.3.94:41 -209.141.45.141:35 -185.220.101.175:495 -23.128.248.162:36 -130.193.15.79:23 -185.220.100.246:853 -178.17.171.102:129 -185.220.101.50:374 -185.220.101.129:340 -185.243.218.231:368 -185.220.101.155:59 -204.137.14.104:466 -178.20.55.182:350 -185.220.101.163:179 -185.220.101.54:94 -2.56.10.36:162 -185.129.61.6:336 -23.128.248.169:221 -107.189.8.56:45 -185.181.61.201:218 -185.220.101.27:458 -185.220.101.157:360 -93.95.231.14:114 -45.66.35.22:601 -37.221.208.71:160 -23.191.200.58:35 -185.220.101.158:124 -193.189.100.202:495 -195.47.238.50:57 -194.15.36.117:174 -185.235.146.29:133 -185.220.101.39:691 -109.70.100.7:474 -185.220.101.17:48 -185.220.101.165:40 -5.83.143.18:122 -185.220.101.191:206 -45.9.168.95:73 -91.92.109.43:217 -185.220.101.8:455 -185.220.101.58:409 -198.98.57.151:136 -185.220.101.160:218 -188.68.36.28:294 -31.44.238.25:581 -185.220.101.46:170 -82.221.128.191:196 -158.174.210.97:117 -185.220.101.173:344 -45.66.35.29:353 -185.220.101.131:93 -185.220.101.171:70 -205.185.121.177:57 -23.191.200.120:32 -212.38.189.186:351 -82.197.182.161:40 -109.70.100.6:244 -178.218.144.96:255 -185.220.101.172:196 -185.220.101.45:564 -23.128.248.164:42 -45.9.168.96:88 -155.254.126.141:33001 -185.220.101.178:159 -147.90.235.40:134 -104.223.84.84:31 -121.127.34.40:158 -185.220.101.152:212 -185.243.218.230:21 -23.191.200.13:36 -147.90.234.30:295 -171.25.193.25:100 -81.17.28.95:16 -162.220.14.54:189 -104.244.72.132:20 -147.90.235.16:133 -104.244.79.50:39 -185.220.101.22:123 -185.39.207.83:205 -193.189.100.196:909 -23.191.200.98:66 -147.90.234.213:120 -109.228.160.190:211 -147.90.234.34:48 -185.129.61.5:185 -198.96.155.3:150 -202.181.177.206:73 -64.190.76.11:184 -91.203.144.194:67 -185.220.101.23:19 -195.176.3.23:292 -107.189.4.209:295 -185.220.101.153:192 -5.253.247.27:15 -109.70.100.4:267 -45.137.201.100:588 -192.121.44.34:81 -107.189.27.145:31 -23.191.200.27:146 -107.189.12.157:446 -87.118.110.27:198 -204.137.14.105:185 -203.12.31.87:111 -107.189.5.7:80 -185.246.190.136:148 -87.121.79.14:57 -121.127.33.253:45 -107.189.11.111:186 -23.191.200.89:47 -139.99.8.57:65 -147.90.235.17:168 -45.61.188.15:170 -23.191.200.57:75 -185.220.101.149:285 -188.239.191.25:27 -23.191.200.28:46 -93.95.227.37:92 -176.65.148.3:122 -5.255.118.218:77 -185.247.226.95:48 -23.191.200.104:144 -179.43.182.58:57 -107.189.14.4:128 -37.48.70.156:264 -107.189.30.49:75 -45.13.225.69:287 -199.195.248.168:377 -185.220.101.48:379 -185.227.68.78:91 -94.16.115.121:391 -171.25.193.36:243 -192.210.214.5:74 -185.207.107.130:51 -23.191.200.121:40 -185.220.101.37:560 -5.255.102.26:198 -23.191.200.25:73 -23.128.248.160:300 -185.129.61.10:99 -23.191.200.63:128 -185.243.218.229:86 -45.138.16.125:192 -172.105.20.12:236 -185.220.101.12:88 -149.202.79.101:103 -179.43.182.232:67 -155.94.163.175:88 -188.68.49.235:199 -185.181.60.204:117 -23.95.117.249:122 -194.15.115.204:190 -45.137.70.158:169 -23.191.200.41:135 -185.132.53.121:94 -91.208.75.4:60 -109.70.100.14:170 -204.8.156.142:76 -185.132.53.37:181 -23.191.200.45:79 -185.129.61.4:205 -107.148.225.242:110 -107.189.8.133:89 -178.175.148.155:42 -107.189.7.144:67 -23.128.248.168:68 -194.32.107.14:294 -45.137.201.5:243 -45.141.119.80:219 -185.220.101.170:98 -185.220.101.40:501 -147.90.235.226:135 -171.25.193.234:183 -185.67.82.114:281 -64.190.76.13:77 -185.244.192.175:61 -23.128.248.172:110 -23.128.248.163:151 -87.118.116.103:63 -96.44.159.148:179 -23.134.88.60:80 -185.220.101.130:71 -23.191.200.59:127 -185.220.100.250:159 -51.15.16.14:184 -185.183.157.214:235 -195.176.3.24:60 -152.53.150.12:99 -77.48.28.193:76 -37.228.129.241:92 -204.137.14.92:318 -107.189.5.121:170 -185.220.101.190:312 -24.203.156.90:78 -23.191.200.68:180 -85.215.36.85:604 -104.244.79.44:324 -185.154.110.16:40 -203.202.232.160:44 -84.19.182.20:79 -185.220.101.168:60 -94.75.225.81:41 -37.228.129.128:99 -107.174.146.5:39 -147.90.235.22:148 -185.225.69.232:47 -185.220.101.179:195 -23.191.200.11:140 -185.220.101.63:207 -23.191.200.60:50 -103.109.187.71:97 -5.45.98.162:46 -93.95.228.125:47 -185.220.101.150:32 -205.185.121.170:42 -45.66.35.28:35 diff --git a/media/company-icons/2328c005-151f-4c05-a6ea-eecffd234063.png b/media/company-icons/2328c005-151f-4c05-a6ea-eecffd234063.png deleted file mode 100644 index 0934ad1d..00000000 Binary files a/media/company-icons/2328c005-151f-4c05-a6ea-eecffd234063.png and /dev/null differ diff --git a/service.log b/service.log deleted file mode 100644 index 7d2e9cad..00000000 --- a/service.log +++ /dev/null @@ -1,42 +0,0 @@ -[EXCEPTION] CmeBalancesViewSet: 身份认证信息未提供。 -[EXCEPTION] MenuListCompatView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserRolesView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] DashboardStatsView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] GetUserAvatarView: 身份认证信息未提供。 -[EXCEPTION] FormAPICompatView: 身份认证信息未提供。 -[EXCEPTION] FormAPICompatView: 身份认证信息未提供。 -[EXCEPTION] GetUserRolesView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 -[EXCEPTION] GetUserInfoView: 身份认证信息未提供。 diff --git a/timer.txt b/timer.txt deleted file mode 100644 index 2760ff61..00000000 --- a/timer.txt +++ /dev/null @@ -1 +0,0 @@ -81167348 \ No newline at end of file diff --git a/times.txt b/times.txt deleted file mode 100644 index d28f6c6d..00000000 --- a/times.txt +++ /dev/null @@ -1 +0,0 @@ -19692665 \ No newline at end of file