feat(data-process): 完善后台生成与失败重试

This commit is contained in:
caoxiaozhu
2026-07-28 10:56:05 +08:00
parent 8a6a6574bb
commit 01d2e6c76a
178 changed files with 4472 additions and 595 deletions

View File

@@ -7,12 +7,16 @@ import logging
import os
import re
import socket
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from contextlib import contextmanager
from dataclasses import asdict
from pathlib import Path
from threading import BoundedSemaphore, Lock
from typing import Any, Iterator, Literal
from urllib.parse import quote, urlsplit
import httpx
import psycopg
from fastapi import (
APIRouter,
@@ -77,6 +81,7 @@ from app.schemas.data_process import (
DataProcessStatus,
DataProcessTaskCreate,
DataProcessTaskUpdate,
DataProcessWorkflowStepUpdate,
ExternalPullRequest,
ExternalSourceRequest,
GenerateRequest,
@@ -85,6 +90,8 @@ from app.schemas.data_process import (
PreviewItemUpdate,
ProcessType,
PublishRequest,
ResultBatchRegenerateRequest,
ResultRegenerateRequest,
ResultUpdate,
)
@@ -122,6 +129,12 @@ RAW_INLINE_PREVIEW_MEDIA_TYPES = {
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
}
RESULT_REGENERATION_CONCURRENCY = 4
RESULT_REGENERATION_RETRIES = 0
RESULT_REGENERATION_TIMEOUT_SECONDS = 60.0
_result_regeneration_slots = BoundedSemaphore(RESULT_REGENERATION_CONCURRENCY)
_result_regeneration_claims_lock = Lock()
_active_result_regenerations: set[tuple[str, str]] = set()
def ok(data: Any = None, message: str = "ok") -> dict[str, Any]:
@@ -147,8 +160,11 @@ def api_errors() -> Iterator[None]:
raise fail(409, str(exc)) from exc
except (DataProcessStoreError, ValueError) as exc:
raise fail(400, str(exc)) from exc
except psycopg.errors.UndefinedTable as exc:
raise fail(503, "data process schema is not installed; run schema_cli --check") from exc
except (psycopg.errors.UndefinedTable, psycopg.errors.UndefinedColumn) as exc:
raise fail(
503,
"data process schema is missing or out of date; run schema_cli --check",
) from exc
except psycopg.OperationalError as exc:
raise fail(503, "data process database is unavailable") from exc
@@ -205,7 +221,10 @@ def _commit_source_batch(
storage.delete(item.reference)
except Exception:
# 文件系统回滚失败不能覆盖数据库抛出的根因,并继续清理其余对象。
pass
logger.exception(
"failed to roll back data process source object task_id=%s",
task_id,
)
raise
@@ -533,9 +552,21 @@ def _all_preview_items(store: DataProcessStore, task_id: str) -> list[dict[str,
def _run_generation(
store: DataProcessStore, task_id: str, generation_run_id: str
) -> None:
started_at = time.perf_counter()
logger.info(
"data process generation worker started task_id=%s generation_run_id=%s",
task_id,
generation_run_id,
)
try:
task = store.get_task(task_id)
if not store.generation_is_running(task_id, generation_run_id):
logger.info(
"data process generation worker skipped inactive run task_id=%s "
"generation_run_id=%s",
task_id,
generation_run_id,
)
return
all_preview_items = _all_preview_items(store, task_id)
preview_items = [
@@ -619,6 +650,12 @@ def _run_generation(
len(preview_items),
len(preview_items),
):
logger.info(
"data process generation stopped before completion task_id=%s "
"generation_run_id=%s",
task_id,
generation_run_id,
)
return
known_fingerprints: set[str] = set()
@@ -678,7 +715,7 @@ def _run_generation(
# stop 请求可能在纯函数计算期间到达,最终写入前再次检查状态。
if store.generation_is_running(task_id, generation_run_id):
store.complete_generation(
completed = store.complete_generation(
task_id,
accepted,
generation_run_id=generation_run_id,
@@ -686,7 +723,32 @@ def _run_generation(
duplicate_count=duplicate_count,
error_count=error_count,
)
except Exception as exc: # noqa: BLE001 - background failures must be persisted
logger.info(
"data process generation completed task_id=%s generation_run_id=%s "
"output_count=%s filtered_count=%s duplicate_count=%s error_count=%s "
"duration_ms=%.2f",
task_id,
generation_run_id,
completed.get("output_count", len(accepted)),
completed.get("filtered_count", filtered_count),
completed.get("duplicate_count", duplicate_count),
completed.get("error_count", error_count),
(time.perf_counter() - started_at) * 1000,
)
else:
logger.info(
"data process generation stopped before result persistence task_id=%s "
"generation_run_id=%s",
task_id,
generation_run_id,
)
except Exception as exc:
logger.exception(
"data process generation failed task_id=%s generation_run_id=%s duration_ms=%.2f",
task_id,
generation_run_id,
(time.perf_counter() - started_at) * 1000,
)
try:
if store.generation_is_running(task_id, generation_run_id):
store.mark_failed(
@@ -695,7 +757,12 @@ def _run_generation(
generation_run_id=generation_run_id,
)
except Exception:
return
logger.exception(
"failed to persist data process generation failure task_id=%s "
"generation_run_id=%s",
task_id,
generation_run_id,
)
@router.get("")
@@ -757,6 +824,19 @@ def update_task(
)
@router.put("/{task_id}/workflow-step")
def update_workflow_step(
task_id: str,
payload: DataProcessWorkflowStepUpdate,
store: DataProcessStore = Depends(get_data_process_store),
) -> dict[str, Any]:
with api_errors():
return ok(
store.update_workflow_step(task_id, payload.workflow_step.value),
"data process workflow step updated",
)
@router.post("/{task_id}/regenerate")
def prepare_regeneration(
task_id: str,
@@ -1338,6 +1418,150 @@ def _prepare_preview_items(
return items
def _run_preview(
store: DataProcessStore,
storage: LocalDataProcessStorage,
task_id: str,
preview_run_id: str,
source_file_ids: list[str],
) -> None:
"""后台逐文件切分;所有写入均由 preview_run_id 保护。"""
started_at = time.perf_counter()
logger.info(
"data process preview started task_id=%s preview_run_id=%s total_files=%s",
task_id,
preview_run_id,
len(source_file_ids),
)
try:
if not store.mark_preview_running(task_id, preview_run_id):
logger.info(
"data process preview skipped inactive run task_id=%s preview_run_id=%s",
task_id,
preview_run_id,
)
return
total_files = len(source_file_ids)
total_items = 0
for completed_files, source_file_id in enumerate(source_file_ids, start=1):
if not store.preview_is_running(task_id, preview_run_id):
logger.info(
"data process preview cancelled task_id=%s preview_run_id=%s "
"completed_files=%s total_files=%s",
task_id,
preview_run_id,
completed_files - 1,
total_files,
)
return
items = _prepare_preview_items(
task_id,
store,
storage,
[source_file_id],
)
if not items:
raise InvalidStateError(
f"source file did not produce preview items: {source_file_id}"
)
created = store.replace_preview_items(
task_id,
items,
source_file_ids=[source_file_id],
preview_run_id=preview_run_id,
)
total_items += len(created)
if not store.update_preview_progress(
task_id,
preview_run_id,
completed_files,
total_files,
):
logger.info(
"data process preview stopped before progress update task_id=%s "
"preview_run_id=%s completed_files=%s total_files=%s",
task_id,
preview_run_id,
completed_files,
total_files,
)
return
if store.complete_preview(task_id, preview_run_id):
logger.info(
"data process preview completed task_id=%s preview_run_id=%s "
"total_files=%s total_items=%s duration_ms=%.2f",
task_id,
preview_run_id,
total_files,
total_items,
(time.perf_counter() - started_at) * 1000,
)
else:
logger.info(
"data process preview completion ignored for inactive run task_id=%s "
"preview_run_id=%s",
task_id,
preview_run_id,
)
except Exception as exc:
logger.exception(
"data process preview failed task_id=%s preview_run_id=%s duration_ms=%.2f",
task_id,
preview_run_id,
(time.perf_counter() - started_at) * 1000,
)
try:
if store.preview_is_running(task_id, preview_run_id):
store.mark_preview_failed(
task_id,
str(exc),
preview_run_id=preview_run_id,
)
except Exception:
logger.exception(
"failed to persist data process preview failure task_id=%s "
"preview_run_id=%s",
task_id,
preview_run_id,
)
@router.post("/{task_id}/preview/start", status_code=202)
def start_preview(
task_id: str,
background_tasks: BackgroundTasks,
payload: PreviewBuildRequest = Body(default_factory=PreviewBuildRequest),
store: DataProcessStore = Depends(get_data_process_store),
storage: LocalDataProcessStorage = Depends(get_data_process_storage),
) -> dict[str, Any]:
with api_errors():
task, selected_ids = store.start_preview(
task_id,
source_file_ids=payload.source_file_ids,
)
preview_run_id = str(task["preview_run_id"])
progress = store.preview_progress(task_id)
background_tasks.add_task(
_run_preview,
store,
storage,
task_id,
preview_run_id,
selected_ids,
)
return ok(progress, "data process preview started")
@router.get("/{task_id}/preview/progress")
def preview_progress(
task_id: str,
store: DataProcessStore = Depends(get_data_process_store),
) -> dict[str, Any]:
with api_errors():
return ok(store.preview_progress(task_id))
@router.post("/{task_id}/preview/build")
def build_preview(
task_id: str,
@@ -1537,6 +1761,15 @@ def results(
)
@router.post("/{task_id}/confirm-results")
def confirm_results(
task_id: str,
store: DataProcessStore = Depends(get_data_process_store),
) -> dict[str, Any]:
with api_errors():
return ok(store.confirm_results(task_id), "data process results confirmed")
@router.put("/{task_id}/results/{result_id}")
def update_result(
task_id: str,
@@ -1635,6 +1868,387 @@ def restore_result(
return ok(restored, "data process result restored")
class _ResultRegenerationFailed(InvalidStateError):
"""模型返回或质量校验失败,原失败结果必须保持不变。"""
def _assert_result_regeneration_allowed(task: dict[str, Any]) -> None:
if task.get("status") != "completed" or task.get("workflow_step") != "results":
raise InvalidStateError("task is not editing generation results")
if task.get("results_confirmed"):
raise InvalidStateError("confirmed results cannot be regenerated")
if task.get("output_dataset_id"):
raise InvalidStateError("published results cannot be regenerated")
def _result_regeneration_model(
task: dict[str, Any],
store: DataProcessStore,
) -> tuple[dict[str, Any], dict[str, Any]]:
config = task.get("config") or {}
model_id = _value(config, "generation_model_id", "generationModelId", None)
if not model_id:
raise InvalidStateError("task does not have a generation model")
return config, store.get_generation_model(str(model_id))
def _result_regeneration_timeout(config: dict[str, Any]) -> float:
configured = float(
_value(config, "request_timeout_seconds", "requestTimeoutSeconds", 60)
)
return max(1.0, min(RESULT_REGENERATION_TIMEOUT_SECONDS, configured))
@contextmanager
def _claim_result_regeneration(task_id: str, result_id: str) -> Iterator[None]:
key = (task_id, result_id)
with _result_regeneration_claims_lock:
if key in _active_result_regenerations:
raise ConflictError("data process result regeneration is already running")
_active_result_regenerations.add(key)
try:
yield
finally:
with _result_regeneration_claims_lock:
_active_result_regenerations.discard(key)
def _generate_result_replacement(
task_id: str,
current: dict[str, Any],
preview: dict[str, Any],
config: dict[str, Any],
generation_model: dict[str, Any],
model_client: httpx.Client | None = None,
) -> dict[str, Any]:
source_content = str(
preview.get("edited_content") or preview.get("original_content") or ""
).strip()
if not source_content or preview.get("status") == "invalid":
raise InvalidStateError("result source preview item is invalid or empty")
output_type = str(
_value(config, "output_type", "outputType", "standard")
).strip().lower()
previous_instruction = str(current.get("instruction") or "")[:1000]
previous_output = str(current.get("output") or "")[:1000]
base_prompt = str(
_value(config, "generation_prompt", "generationPrompt", "") or ""
)
regeneration_instruction = (
"这是一次失败结果的重新生成。请使用新的提问角度和表达,"
"不要复述旧结果。旧问题:"
f"{previous_instruction or ''};旧答案:{previous_output or ''}"
)
runtime_config = {
**config,
"generation_prompt": f"{base_prompt}\n{regeneration_instruction}".strip(),
"output_type": output_type,
"reasoning_detail": _value(
config, "reasoning_detail", "reasoningDetail", "normal"
),
"max_tokens": _value(config, "max_tokens", "maxTokens", 1024),
"json_mode": _value(config, "json_mode", "jsonMode", False),
# 交互式重新生成只做一次新尝试,避免继承整任务的重试配置后长时间等待。
"generation_retries": RESULT_REGENERATION_RETRIES,
"request_timeout_seconds": _result_regeneration_timeout(config),
}
with _result_regeneration_slots:
generated = generate_model_records(
[preview],
model=generation_model,
config=runtime_config,
task_id=task_id,
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=model_client,
)
if not generated or generated[0].get("status") == "invalid":
reason = str(
(generated[0] if generated else {}).get("error")
or "model generation failed"
)
raise _ResultRegenerationFailed(f"重新生成结果仍无效:{reason}")
minimum = max(
1,
int(_value(config, "min_output_length", "minOutputLength", 20) or 20),
)
replacement = generated[0]
quality = score_quality(
replacement,
min_output_length=minimum,
source_content=source_content,
)
if not quality.is_valid:
reason = ", ".join(quality.flags) or "quality validation failed"
raise _ResultRegenerationFailed(f"重新生成结果未通过质量校验:{reason}")
replacement["quality_score"] = asdict(quality)
replacement["status"] = "valid"
replacement["error"] = None
return replacement
def _regenerate_result_in_place(
task_id: str,
current: dict[str, Any],
preview: dict[str, Any],
config: dict[str, Any],
generation_model: dict[str, Any],
store: DataProcessStore,
*,
expected_updated_at: str,
model_client: httpx.Client | None = None,
) -> dict[str, Any]:
result_id = str(current["id"])
with _claim_result_regeneration(task_id, result_id):
replacement = _generate_result_replacement(
task_id,
current,
preview,
config,
generation_model,
model_client,
)
return store.replace_generated_result(
task_id,
result_id,
replacement,
expected_updated_at=expected_updated_at,
)
def _safe_regeneration_error(exc: Exception) -> str:
return re.sub(r"\s+", " ", str(exc)).strip()[:500] or "result regeneration failed"
@router.post("/{task_id}/results/regenerate-batch")
def regenerate_results_batch(
task_id: str,
payload: ResultBatchRegenerateRequest,
store: DataProcessStore = Depends(get_data_process_store),
) -> dict[str, Any]:
"""并发重新生成一批失败结果;每条独立提交并允许部分成功。"""
started_at = time.perf_counter()
batch_id = new_id("dprb")
with api_errors():
task = store.get_task(task_id)
_assert_result_regeneration_allowed(task)
config, generation_model = _result_regeneration_model(task, store)
prepared: list[tuple[int, dict[str, Any], dict[str, Any], str]] = []
failures: list[tuple[int, dict[str, str]]] = []
for index, requested in enumerate(payload.items):
try:
current = store.get_result(task_id, requested.result_id)
if current.get("status") != "invalid":
raise InvalidStateError("only an invalid result can be regenerated")
if requested.expected_updated_at != str(current.get("updated_at") or ""):
raise ConflictError("data process result was modified by another request")
preview_id = current.get("preview_item_id")
if not preview_id:
raise InvalidStateError(
"result is not associated with a source preview item"
)
preview = store.get_preview_item(task_id, str(preview_id))
prepared.append(
(index, current, preview, requested.expected_updated_at)
)
except ConflictError as exc:
failures.append((index, {
"result_id": requested.result_id,
"code": "conflict",
"message": _safe_regeneration_error(exc),
}))
except (NotFoundError, InvalidStateError) as exc:
failures.append((index, {
"result_id": requested.result_id,
"code": "skipped",
"message": _safe_regeneration_error(exc),
}))
logger.info(
"data process result batch regeneration started batch_id=%s task_id=%s "
"requested=%s prepared=%s concurrency=%s",
batch_id,
task_id,
len(payload.items),
len(prepared),
min(RESULT_REGENERATION_CONCURRENCY, len(prepared)),
)
successes: list[tuple[int, dict[str, Any]]] = []
if prepared:
request_timeout = _result_regeneration_timeout(config)
model_timeout = httpx.Timeout(
request_timeout,
connect=min(10.0, request_timeout),
)
model_limits = httpx.Limits(
max_connections=RESULT_REGENERATION_CONCURRENCY,
max_keepalive_connections=RESULT_REGENERATION_CONCURRENCY,
)
# httpx.Client 支持跨线程复用,批次内共享连接池可减少重复建连开销。
with (
httpx.Client(timeout=model_timeout, limits=model_limits) as model_client,
ThreadPoolExecutor(
max_workers=min(RESULT_REGENERATION_CONCURRENCY, len(prepared)),
thread_name_prefix="data-result-regeneration",
) as executor,
):
futures = {
executor.submit(
_regenerate_result_in_place,
task_id,
current,
preview,
config,
generation_model,
store,
expected_updated_at=expected_updated_at,
model_client=model_client,
): (index, str(current["id"]), time.perf_counter())
for index, current, preview, expected_updated_at in prepared
}
for future in as_completed(futures):
index, result_id, item_started_at = futures[future]
try:
regenerated = future.result()
successes.append((index, regenerated))
outcome = "succeeded"
except ConflictError as exc:
outcome = "conflict"
failures.append((index, {
"result_id": result_id,
"code": outcome,
"message": _safe_regeneration_error(exc),
}))
except _ResultRegenerationFailed as exc:
outcome = "generation_failed"
failures.append((index, {
"result_id": result_id,
"code": outcome,
"message": _safe_regeneration_error(exc),
}))
except (NotFoundError, InvalidStateError) as exc:
outcome = "skipped"
failures.append((index, {
"result_id": result_id,
"code": outcome,
"message": _safe_regeneration_error(exc),
}))
except Exception as exc: # pragma: no cover - defensive boundary
outcome = "internal_error"
logger.exception(
"data process result batch regeneration crashed "
"batch_id=%s task_id=%s result_id=%s",
batch_id,
task_id,
result_id,
)
failures.append((index, {
"result_id": result_id,
"code": outcome,
"message": _safe_regeneration_error(exc),
}))
logger.info(
"data process result batch item finished batch_id=%s task_id=%s "
"result_id=%s outcome=%s duration_ms=%.2f",
batch_id,
task_id,
result_id,
outcome,
(time.perf_counter() - item_started_at) * 1000,
)
success_items = [item for _, item in sorted(successes, key=lambda pair: pair[0])]
failure_items = [item for _, item in sorted(failures, key=lambda pair: pair[0])]
remaining_invalid_count = int(
store.list_results(
task_id,
page=1,
page_size=1,
status="invalid",
)["total"]
)
duration_ms = (time.perf_counter() - started_at) * 1000
logger.info(
"data process result batch regeneration completed batch_id=%s task_id=%s "
"succeeded=%s failed=%s remaining_invalid=%s duration_ms=%.2f",
batch_id,
task_id,
len(success_items),
len(failure_items),
remaining_invalid_count,
duration_ms,
)
return ok(
{
"batch_id": batch_id,
"total": len(payload.items),
"succeeded": len(success_items),
"failed": len(failure_items),
"remaining_invalid_count": remaining_invalid_count,
"duration_ms": round(duration_ms, 2),
"items": success_items,
"failures": failure_items,
},
"data process results regenerated",
)
@router.post("/{task_id}/results/{result_id}/regenerate")
def regenerate_result(
task_id: str,
result_id: str,
payload: ResultRegenerateRequest,
store: DataProcessStore = Depends(get_data_process_store),
) -> dict[str, Any]:
"""只重新生成一个失败结果,成功后原位替换且不影响其他结果。"""
started_at = time.perf_counter()
with api_errors():
task = store.get_task(task_id)
_assert_result_regeneration_allowed(task)
current = store.get_result(task_id, result_id)
if current.get("status") != "invalid":
raise InvalidStateError("only an invalid result can be regenerated")
if payload.expected_updated_at != str(current.get("updated_at") or ""):
raise ConflictError("data process result was modified by another request")
preview_id = current.get("preview_item_id")
if not preview_id:
raise InvalidStateError("result is not associated with a source preview item")
preview = store.get_preview_item(task_id, str(preview_id))
config, generation_model = _result_regeneration_model(task, store)
try:
result = _regenerate_result_in_place(
task_id,
current,
preview,
config,
generation_model,
store,
expected_updated_at=payload.expected_updated_at,
)
except _ResultRegenerationFailed as exc:
logger.warning(
"data process result regeneration failed task_id=%s result_id=%s "
"duration_ms=%.2f reason=%s",
task_id,
result_id,
(time.perf_counter() - started_at) * 1000,
_safe_regeneration_error(exc),
)
raise
logger.info(
"data process result regenerated task_id=%s result_id=%s duration_ms=%.2f",
task_id,
result_id,
(time.perf_counter() - started_at) * 1000,
)
return ok(result, "data process result regenerated")
@router.post("/{task_id}/publish")
def publish(
task_id: str,

View File

@@ -80,6 +80,17 @@ CREATE TABLE IF NOT EXISTS data_process_tasks (
error_count BIGINT NOT NULL DEFAULT 0 CHECK (error_count >= 0),
failure_reason TEXT,
generation_run_id TEXT,
results_confirmed BOOLEAN NOT NULL DEFAULT TRUE,
workflow_step VARCHAR(20) NOT NULL DEFAULT 'create'
CHECK (workflow_step IN ('create', 'model', 'upload', 'preview', 'generate', 'results')),
preview_status VARCHAR(20) NOT NULL DEFAULT 'idle'
CHECK (preview_status IN ('idle', 'queued', 'running', 'completed', 'failed', 'cancelled')),
preview_progress NUMERIC(5,2) NOT NULL DEFAULT 0
CHECK (preview_progress >= 0 AND preview_progress <= 100),
preview_run_id TEXT,
preview_failure_reason TEXT,
preview_total_files INTEGER NOT NULL DEFAULT 0 CHECK (preview_total_files >= 0),
preview_completed_files INTEGER NOT NULL DEFAULT 0 CHECK (preview_completed_files >= 0),
tenant_id TEXT,
project_id TEXT,
owner_id TEXT,
@@ -95,6 +106,87 @@ CREATE TABLE IF NOT EXISTS data_process_tasks (
);
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS generation_run_id TEXT;
-- 历史任务在引入六步确认流程前已经完成审核,默认保留为已确认;
-- 新任务由创建接口显式写入 FALSE并在第六步确认后转为 TRUE。
ALTER TABLE data_process_tasks
ADD COLUMN IF NOT EXISTS results_confirmed BOOLEAN NOT NULL DEFAULT TRUE;
UPDATE data_process_tasks
SET results_confirmed=FALSE
WHERE status <> 'completed' AND results_confirmed=TRUE;
-- 先以可空列接入旧库,才能只回填历史行;随后再收紧默认值与约束。
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS workflow_step VARCHAR(20);
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS preview_status VARCHAR(20);
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS preview_progress NUMERIC(5,2);
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS preview_run_id TEXT;
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS preview_failure_reason TEXT;
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS preview_total_files INTEGER;
ALTER TABLE data_process_tasks ADD COLUMN IF NOT EXISTS preview_completed_files INTEGER;
CREATE TEMP TABLE data_process_workflow_backfill_ids ON COMMIT DROP AS
SELECT id FROM data_process_tasks WHERE workflow_step IS NULL;
UPDATE data_process_tasks task
SET workflow_step = CASE
WHEN task.status IN ('running', 'failed', 'stopped') THEN 'generate'
WHEN task.status = 'completed' AND task.results_confirmed=FALSE THEN 'generate'
WHEN task.status = 'completed' THEN 'results'
ELSE 'create'
END
WHERE task.workflow_step IS NULL;
UPDATE data_process_tasks
SET preview_status='idle', preview_progress=0,
preview_total_files=0, preview_completed_files=0
WHERE preview_status IS NULL OR preview_progress IS NULL
OR preview_total_files IS NULL OR preview_completed_files IS NULL;
ALTER TABLE data_process_tasks ALTER COLUMN workflow_step SET DEFAULT 'create';
ALTER TABLE data_process_tasks ALTER COLUMN workflow_step SET NOT NULL;
ALTER TABLE data_process_tasks ALTER COLUMN preview_status SET DEFAULT 'idle';
ALTER TABLE data_process_tasks ALTER COLUMN preview_status SET NOT NULL;
ALTER TABLE data_process_tasks ALTER COLUMN preview_progress SET DEFAULT 0;
ALTER TABLE data_process_tasks ALTER COLUMN preview_progress SET NOT NULL;
ALTER TABLE data_process_tasks ALTER COLUMN preview_total_files SET DEFAULT 0;
ALTER TABLE data_process_tasks ALTER COLUMN preview_total_files SET NOT NULL;
ALTER TABLE data_process_tasks ALTER COLUMN preview_completed_files SET DEFAULT 0;
ALTER TABLE data_process_tasks ALTER COLUMN preview_completed_files SET NOT NULL;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conrelid='data_process_tasks'::regclass
AND conname='ck_data_process_tasks_workflow_step'
) THEN
ALTER TABLE data_process_tasks ADD CONSTRAINT ck_data_process_tasks_workflow_step
CHECK (workflow_step IN ('create', 'model', 'upload', 'preview', 'generate', 'results'));
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conrelid='data_process_tasks'::regclass
AND conname='ck_data_process_tasks_preview_status'
) THEN
ALTER TABLE data_process_tasks ADD CONSTRAINT ck_data_process_tasks_preview_status
CHECK (preview_status IN ('idle', 'queued', 'running', 'completed', 'failed', 'cancelled'));
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conrelid='data_process_tasks'::regclass
AND conname='ck_data_process_tasks_preview_progress'
) THEN
ALTER TABLE data_process_tasks ADD CONSTRAINT ck_data_process_tasks_preview_progress
CHECK (preview_progress >= 0 AND preview_progress <= 100);
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conrelid='data_process_tasks'::regclass
AND conname='ck_data_process_tasks_preview_file_counts'
) THEN
ALTER TABLE data_process_tasks ADD CONSTRAINT ck_data_process_tasks_preview_file_counts
CHECK (preview_total_files >= 0 AND preview_completed_files >= 0
AND preview_completed_files <= preview_total_files);
END IF;
END $$;
CREATE UNIQUE INDEX IF NOT EXISTS uq_data_process_tasks_name_alive
ON data_process_tasks(name) WHERE deleted_at IS NULL;
@@ -153,6 +245,22 @@ CREATE TABLE IF NOT EXISTS data_process_preview_items (
CREATE INDEX IF NOT EXISTS idx_data_process_preview_task_file
ON data_process_preview_items(task_id, source_file_id, created_at);
-- 子表在新库中到这里才存在;只修复本次新增 workflow_step 前的历史任务。
UPDATE data_process_tasks task
SET workflow_step = CASE
WHEN EXISTS (
SELECT 1 FROM data_process_preview_items preview
WHERE preview.task_id=task.id
) THEN 'preview'
WHEN EXISTS (
SELECT 1 FROM data_process_source_files source_file
WHERE source_file.task_id=task.id AND source_file.deleted_at IS NULL
) THEN 'upload'
ELSE task.workflow_step
END
WHERE task.id IN (SELECT id FROM data_process_workflow_backfill_ids)
AND task.status='pending';
CREATE TABLE IF NOT EXISTS data_process_results (
id TEXT PRIMARY KEY,
task_id TEXT NOT NULL REFERENCES data_process_tasks(id) ON DELETE CASCADE,

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
import hashlib
import json
import logging
import re
from collections.abc import Callable, Iterable, Mapping
from typing import Any
@@ -22,6 +23,10 @@ class ModelGenerationError(ValueError):
"""模型配置、响应或调用失败。"""
class _TerminalModelGenerationError(ModelGenerationError):
"""使用相同参数重试也无法恢复的模型响应错误。"""
OUTPUT_TYPE_STANDARD = "standard"
OUTPUT_TYPE_REASONING = "reasoning"
SUPPORTED_OUTPUT_TYPES = {OUTPUT_TYPE_STANDARD, OUTPUT_TYPE_REASONING}
@@ -31,6 +36,25 @@ SUPPORTED_REASONING_DETAILS = {
REASONING_DETAIL_NORMAL,
REASONING_DETAIL_DETAILED,
}
MINIMAX_M3_API_HOSTS = {"api.minimax.io", "api.minimaxi.com"}
MINIMAX_M3_MIN_COMPLETION_TOKENS = 4096
logger = logging.getLogger(__name__)
def _is_retryable_generation_error(exc: Exception) -> bool:
if isinstance(exc, _TerminalModelGenerationError):
return False
if isinstance(exc, httpx.HTTPStatusError):
status_code = exc.response.status_code
return status_code in {408, 425, 429} or status_code >= 500
if isinstance(exc, httpx.RequestError):
return True
return isinstance(exc, (json.JSONDecodeError, ModelGenerationError))
def _is_official_minimax_m3(endpoint: str, model_name: str) -> bool:
host = (urlsplit(endpoint).hostname or "").casefold()
return host in MINIMAX_M3_API_HOSTS and model_name.casefold() == "minimax-m3"
def chat_completions_url(value: str) -> str:
@@ -59,32 +83,139 @@ def chat_completions_url(value: str) -> str:
return urlunsplit((parsed.scheme, parsed.netloc, target_path, "", ""))
def _message_content(payload: Mapping[str, Any]) -> str:
def _response_choice(payload: Mapping[str, Any]) -> Mapping[str, Any]:
try:
content = payload["choices"][0]["message"]["content"]
choice = payload["choices"][0]
except (KeyError, IndexError, TypeError) as exc:
raise ModelGenerationError(
"model response does not contain choices[0].message.content"
) from exc
raise ModelGenerationError("模型响应缺少 choices[0]") from exc
if not isinstance(choice, Mapping):
raise ModelGenerationError("模型响应 choices[0] 不是对象")
return choice
def _response_finish_reason(payload: Mapping[str, Any]) -> str:
try:
return str(_response_choice(payload).get("finish_reason") or "").strip().lower()
except ModelGenerationError:
return ""
def _response_content_length(payload: Mapping[str, Any]) -> int:
try:
message = _response_choice(payload).get("message")
if not isinstance(message, Mapping):
return 0
content = message.get("content")
if isinstance(content, str):
return len(content)
if isinstance(content, list):
return sum(
len(str(item.get("text") or ""))
for item in content
if isinstance(item, Mapping)
)
except ModelGenerationError:
pass
return 0
def _raise_for_terminal_response(payload: Mapping[str, Any]) -> Mapping[str, Any]:
choice = _response_choice(payload)
base_response = payload.get("base_resp")
status_code: Any = None
status_message = ""
if isinstance(base_response, Mapping):
status_code = base_response.get("status_code")
status_message = re.sub(
r"\s+", " ", str(base_response.get("status_msg") or "")
).strip()[:200]
if bool(payload.get("input_sensitive")) or status_code in {1026, "1026"}:
raise _TerminalModelGenerationError(
f"模型输入触发内容安全拦截code={status_code or 1026}"
)
if bool(payload.get("output_sensitive")) or status_code in {1027, "1027"}:
raise _TerminalModelGenerationError(
f"模型输出触发内容安全拦截code={status_code or 1027}"
)
finish_reason = str(choice.get("finish_reason") or "").strip().lower()
if finish_reason == "length":
raise _TerminalModelGenerationError(
"模型输出因达到 Token 上限被截断finish_reason=length"
"请提高最大输出长度后重试"
)
if finish_reason == "content_filter":
raise _TerminalModelGenerationError(
"模型输出被内容安全策略拦截finish_reason=content_filter"
)
if finish_reason in {"tool_calls", "function_call"}:
raise _TerminalModelGenerationError(
f"模型返回了当前生成任务不支持的工具调用finish_reason={finish_reason}"
)
if status_code not in {None, "", 0, "0"}:
detail = f"{status_message}" if status_message else ""
raise _TerminalModelGenerationError(
f"模型服务返回业务错误code={status_code}{detail}"
)
return choice
def _message_content(payload: Mapping[str, Any]) -> str:
choice = _raise_for_terminal_response(payload)
message = choice.get("message")
if not isinstance(message, Mapping):
raise ModelGenerationError("模型响应缺少 choices[0].message")
content = message.get("content")
if isinstance(content, str):
return content
if isinstance(content, list):
result = content
elif isinstance(content, list):
parts = [
str(item.get("text") or "")
for item in content
if isinstance(item, Mapping) and item.get("type") in {None, "text", "output_text"}
]
if parts:
return "".join(parts)
raise ModelGenerationError("model response content must be text")
result = "".join(parts)
elif content is None:
result = ""
else:
raise ModelGenerationError("模型响应 content 必须是文本")
if not result.strip():
raise ModelGenerationError("模型返回的最终内容为空,未生成可解析的 JSON")
return result
def _json_documents(content: str) -> list[Any]:
decoder = json.JSONDecoder()
documents: list[Any] = []
cursor = 0
while cursor < len(content):
match = re.search(r"[\[{]", content[cursor:])
if not match:
break
start = cursor + match.start()
try:
value, end = decoder.raw_decode(content[start:])
except json.JSONDecodeError:
cursor = start + 1
continue
if isinstance(value, (Mapping, list)):
documents.append(value)
cursor = start + max(end, 1)
return documents
def _json_payload(content: str) -> Any:
# 只移除模型在 JSON 之前自行输出的思考过程,不能破坏 JSON 字段中的训练内容。
cleaned = content.strip()
if re.match(r"^\s*<think>", cleaned, flags=re.IGNORECASE) and not re.match(
r"^\s*<think>[\s\S]*?</think>", cleaned, flags=re.IGNORECASE
):
raise ModelGenerationError("模型思考内容未闭合,响应可能已被截断")
cleaned = re.sub(
r"^\s*<think>[\s\S]*?</think>\s*",
r"^\s*(?:<think>[\s\S]*?</think>\s*)+",
"",
content,
cleaned,
count=1,
flags=re.IGNORECASE,
).strip()
@@ -93,10 +224,16 @@ def _json_payload(content: str) -> Any:
cleaned = fenced.group(1).strip()
try:
return json.loads(cleaned)
except json.JSONDecodeError as exc:
except json.JSONDecodeError as direct_error:
documents = _json_documents(cleaned)
if len(documents) == 1:
return documents[0]
if len(documents) > 1:
raise ModelGenerationError("模型响应包含多个 JSON 对象,无法确定应使用哪一个")
raise ModelGenerationError(
f"model response is not valid JSON at line {exc.lineno}, column {exc.colno}"
) from exc
"模型响应中没有找到唯一且完整的 JSON 对象"
f"(第 {direct_error.lineno} 行,第 {direct_error.colno} 列)"
) from direct_error
def _result_items(payload: Any) -> list[Mapping[str, Any]]:
@@ -206,6 +343,7 @@ def generate_model_records(
model_name = str(model.get("online_model_name") or model.get("name") or "").strip()
if not model_name:
raise ModelGenerationError("generation model name is required")
is_minimax_m3 = _is_official_minimax_m3(endpoint, model_name)
temperature = float(config.get("temperature", 0.7))
max_tokens = int(config.get("max_tokens", 1024))
@@ -246,9 +384,18 @@ def generate_model_records(
reasoning_detail=reasoning_detail,
),
"temperature": temperature,
"max_tokens": max_tokens,
}
if bool(config.get("json_mode", False)):
if is_minimax_m3:
request_payload.update(
reasoning_split=True,
max_completion_tokens=max(
max_tokens,
MINIMAX_M3_MIN_COMPLETION_TOKENS,
),
)
else:
request_payload["max_tokens"] = max_tokens
if bool(config.get("json_mode", False)) and not is_minimax_m3:
request_payload["response_format"] = {"type": "json_object"}
last_error: Exception | None = None
@@ -264,7 +411,24 @@ def generate_model_records(
body = response.json()
if not isinstance(body, Mapping):
raise ModelGenerationError("model response body must be a JSON object")
candidate_items = _result_items(_json_payload(_message_content(body)))
try:
candidate_items = _result_items(
_json_payload(_message_content(body))
)
except ModelGenerationError as exc:
logger.warning(
"data process model response rejected task_id=%s model=%s "
"finish_reason=%s response_chars=%s input_sensitive=%s "
"output_sensitive=%s reason=%s",
task_id,
model_name,
_response_finish_reason(body) or "missing",
_response_content_length(body),
bool(body.get("input_sensitive")),
bool(body.get("output_sensitive")),
str(exc),
)
raise
if len(candidate_items) < batch_count:
raise ModelGenerationError(
"model response contains fewer result objects than requested: "
@@ -278,6 +442,8 @@ def generate_model_records(
ModelGenerationError,
) as exc:
last_error = exc
if not _is_retryable_generation_error(exc):
break
if generated_items is None:
error_message = str(last_error or "model generation failed")[:2000]

View File

@@ -7,6 +7,18 @@ from urllib.parse import urlsplit
from app.modules.data_process.store import DataProcessStore
REQUIRED_TASK_COLUMNS = (
"generation_run_id",
"results_confirmed",
"workflow_step",
"preview_status",
"preview_progress",
"preview_run_id",
"preview_failure_reason",
"preview_total_files",
"preview_completed_files",
)
def _target_label(database_url: str) -> str:
parsed = urlsplit(database_url)
@@ -18,14 +30,13 @@ def _schema_ready(store: DataProcessStore) -> bool:
with store.connect() as conn:
row = conn.execute(
"""
SELECT EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema=current_schema()
AND table_name='data_process_tasks'
AND column_name='generation_run_id'
) AS ready
"""
SELECT COUNT(*) = %s AS ready
FROM information_schema.columns
WHERE table_schema=current_schema()
AND table_name='data_process_tasks'
AND column_name = ANY(%s)
""",
(len(REQUIRED_TASK_COLUMNS), list(REQUIRED_TASK_COLUMNS)),
).fetchone()
return bool(row and row["ready"])

View File

@@ -20,6 +20,8 @@ from app.modules.data_process.algorithms import estimate_token_count, stable_spl
TASK_STATUSES = {"pending", "running", "completed", "failed", "stopped"}
EDITABLE_STATUSES = {"pending", "failed", "stopped", "completed"}
ACTIVE_PREVIEW_STATUSES = {"queued", "running"}
WORKFLOW_STEPS = {"create", "model", "upload", "preview", "generate", "results"}
_PREVIEW_CONFIG_ALIASES = {
"preprocess_options": "preprocessOptions",
@@ -339,9 +341,10 @@ class DataProcessStore:
"""
INSERT INTO data_process_tasks
(id, name, description, status, process_type, source_dataset_id, config,
progress, tenant_id, project_id, owner_id, created_by, updated_by,
progress, results_confirmed, tenant_id, project_id, owner_id, created_by, updated_by,
created_at, updated_at)
VALUES (%s, %s, %s, 'pending', %s, %s, %s, 0, %s, %s, %s, %s, %s, %s, %s)
VALUES (%s, %s, %s, 'pending', %s, %s, %s, 0, FALSE,
%s, %s, %s, %s, %s, %s, %s)
RETURNING *
""",
(
@@ -442,9 +445,30 @@ class DataProcessStore:
def _ensure_editable(task: dict[str, Any]) -> None:
if task["status"] not in EDITABLE_STATUSES:
raise InvalidStateError(f"task cannot be edited while status is {task['status']}")
if task.get("preview_status") in ACTIVE_PREVIEW_STATUSES:
raise InvalidStateError("task cannot be edited while preview is running")
if task.get("output_dataset_id") and not _is_regeneration_prepared(task):
raise InvalidStateError("published task cannot be edited")
def update_workflow_step(self, task_id: str, workflow_step: str) -> dict[str, Any]:
"""独立保存向导位置,不触发配置或结果失效逻辑。"""
if workflow_step not in WORKFLOW_STEPS:
raise ValueError("invalid data process workflow step")
with self.connect() as conn:
row = conn.execute(
"""
UPDATE data_process_tasks
SET workflow_step=%s, updated_at=%s
WHERE id=%s AND deleted_at IS NULL
RETURNING *
""",
(workflow_step, utcnow(), task_id),
).fetchone()
if not row:
raise NotFoundError("data process task not found")
return _public_task(_decode_row(row)) or {}
def recover_legacy_aborted_regeneration(self, task_id: str) -> dict[str, Any]:
"""恢复旧版在真正开始生成前误删的上一轮结果。
@@ -593,7 +617,8 @@ class DataProcessStore:
output_count=%s, filtered_count=0, duplicate_count=0,
error_count=(SELECT COUNT(*) FROM data_process_results
WHERE task_id=%s AND status='invalid'),
failure_reason=NULL, updated_at=%s
failure_reason=NULL, results_confirmed=TRUE,
workflow_step='results', updated_at=%s
WHERE id=%s
""",
(
@@ -660,6 +685,13 @@ class DataProcessStore:
"error_count": 0,
"failure_reason": None,
"generation_run_id": None,
"results_confirmed": False,
"preview_status": "idle",
"preview_progress": 0,
"preview_run_id": None,
"preview_failure_reason": None,
"preview_total_files": 0,
"preview_completed_files": 0,
"started_at": None,
"completed_at": None,
}
@@ -709,6 +741,8 @@ class DataProcessStore:
task = self._task_in_connection(conn, task_id, for_update=True)
if task["status"] == "running":
raise ConflictError("running task cannot be prepared for regeneration")
if task.get("preview_status") in ACTIVE_PREVIEW_STATUSES:
raise ConflictError("running preview cannot be prepared for regeneration")
current_updated_at = _serialize_value(task.get("updated_at"))
if payload["expected_updated_at"] != current_updated_at:
@@ -785,14 +819,19 @@ class DataProcessStore:
def delete_task(self, task_id: str, *, deleted_by: str | None = None) -> None:
with self.connect() as conn:
task = self._task_in_connection(conn, task_id, for_update=True)
if task["status"] == "running":
raise InvalidStateError("running task must be stopped before deletion")
self._task_in_connection(conn, task_id, for_update=True)
now = utcnow()
conn.execute(
"""
UPDATE data_process_tasks
SET deleted_at=%s, deleted_by=%s, updated_at=%s
SET status=CASE WHEN status='running' THEN 'stopped' ELSE status END,
generation_run_id=NULL,
preview_status=CASE
WHEN preview_status IN ('queued', 'running') THEN 'cancelled'
ELSE preview_status
END,
preview_run_id=NULL,
deleted_at=%s, deleted_by=%s, updated_at=%s
WHERE id=%s
""",
(now, deleted_by, now, task_id),
@@ -918,7 +957,10 @@ class DataProcessStore:
SELECT COALESCE(SUM(record_count), 0)
FROM data_process_source_files
WHERE task_id=%s AND deleted_at IS NULL
), updated_at=%s
), workflow_step='upload', preview_status='idle',
preview_progress=0, preview_run_id=NULL,
preview_failure_reason=NULL, preview_total_files=0,
preview_completed_files=0, updated_at=%s
WHERE id=%s
""",
(task_id, now, task_id),
@@ -934,7 +976,12 @@ class DataProcessStore:
UPDATE data_process_tasks
SET status='pending', progress=%s, output_count=0, filtered_count=0,
duplicate_count=0, error_count=0, failure_reason=NULL,
generation_run_id=NULL, started_at=NULL, completed_at=NULL,
generation_run_id=NULL, results_confirmed=FALSE,
workflow_step='upload', preview_status='idle',
preview_progress=0, preview_run_id=NULL,
preview_failure_reason=NULL, preview_total_files=0,
preview_completed_files=0,
started_at=NULL, completed_at=NULL,
input_count=(
SELECT COALESCE(SUM(record_count), 0)
FROM data_process_source_files
@@ -1035,7 +1082,10 @@ class DataProcessStore:
SET input_count=(SELECT COALESCE(SUM(record_count), 0)
FROM data_process_source_files
WHERE task_id=%s AND deleted_at IS NULL),
updated_at=%s
workflow_step='upload', preview_status='idle',
preview_progress=0, preview_run_id=NULL,
preview_failure_reason=NULL, preview_total_files=0,
preview_completed_files=0, updated_at=%s
WHERE id=%s
""",
(task_id, now, task_id),
@@ -1049,6 +1099,11 @@ class DataProcessStore:
UPDATE data_process_tasks
SET status='pending', progress=0, output_count=0, filtered_count=0,
duplicate_count=0, error_count=0, failure_reason=NULL,
results_confirmed=FALSE,
workflow_step='upload', preview_status='idle',
preview_progress=0, preview_run_id=NULL,
preview_failure_reason=NULL, preview_total_files=0,
preview_completed_files=0,
input_count=(SELECT COALESCE(SUM(record_count), 0)
FROM data_process_source_files
WHERE task_id=%s AND deleted_at IS NULL),
@@ -1064,6 +1119,7 @@ class DataProcessStore:
items: Sequence[dict[str, Any]],
*,
source_file_ids: Sequence[str] | None = None,
preview_run_id: str | None = None,
) -> list[dict[str, Any]]:
selected_ids = (
list(dict.fromkeys(str(file_id) for file_id in source_file_ids))
@@ -1081,11 +1137,21 @@ class DataProcessStore:
}
if unexpected:
raise ValueError("preview items contain an unselected source file")
preview_file_count = len(selected_ids) if selected_ids is not None else len(
{str(item.get("source_file_id") or "") for item in items}
)
is_direct_build = preview_run_id is None
now = utcnow()
with self.connect() as conn:
task = self._task_in_connection(conn, task_id, for_update=True)
self._ensure_editable(task)
if is_direct_build:
self._ensure_editable(task)
elif (
task.get("preview_run_id") != preview_run_id
or task.get("preview_status") != "running"
):
raise InvalidStateError("preview run is no longer active")
regeneration_prepared = _is_regeneration_prepared(task)
if not regeneration_prepared:
conn.execute("DELETE FROM data_process_results WHERE task_id=%s", (task_id,))
@@ -1144,22 +1210,249 @@ class DataProcessStore:
).fetchone()
created.append(_decode_row(row) or {})
if regeneration_prepared:
conn.execute(
"UPDATE data_process_tasks SET updated_at=%s WHERE id=%s",
(now, task_id),
)
if is_direct_build:
conn.execute(
"""
UPDATE data_process_tasks
SET workflow_step='preview', preview_status='completed',
preview_progress=100, preview_run_id=NULL,
preview_failure_reason=NULL, preview_total_files=%s,
preview_completed_files=%s, updated_at=%s
WHERE id=%s
""",
(preview_file_count, preview_file_count, now, task_id),
)
else:
conn.execute(
"UPDATE data_process_tasks SET updated_at=%s WHERE id=%s",
(now, task_id),
)
else:
conn.execute(
"""
UPDATE data_process_tasks
SET status='pending', progress=20, output_count=0, filtered_count=0,
duplicate_count=0, error_count=0, failure_reason=NULL, updated_at=%s
duplicate_count=0, error_count=0, failure_reason=NULL,
results_confirmed=FALSE,
workflow_step=CASE WHEN %s THEN 'preview' ELSE workflow_step END,
preview_status=CASE WHEN %s THEN 'completed' ELSE preview_status END,
preview_progress=CASE WHEN %s THEN 100 ELSE preview_progress END,
preview_run_id=CASE WHEN %s THEN NULL ELSE preview_run_id END,
preview_failure_reason=CASE WHEN %s THEN NULL ELSE preview_failure_reason END,
preview_total_files=CASE WHEN %s THEN %s ELSE preview_total_files END,
preview_completed_files=CASE WHEN %s THEN %s ELSE preview_completed_files END,
updated_at=%s
WHERE id=%s
""",
(now, task_id),
(
is_direct_build,
is_direct_build,
is_direct_build,
is_direct_build,
is_direct_build,
is_direct_build,
preview_file_count,
is_direct_build,
preview_file_count,
now,
task_id,
),
)
return created
def start_preview(
self,
task_id: str,
*,
source_file_ids: Sequence[str] | None = None,
) -> tuple[dict[str, Any], list[str]]:
"""创建一轮持久化切分任务,并返回本轮固定的源文件集合。"""
requested_ids = (
list(dict.fromkeys(str(file_id) for file_id in source_file_ids))
if source_file_ids is not None
else None
)
if requested_ids is not None and (
not requested_ids or any(not file_id for file_id in requested_ids)
):
raise ValueError("source_file_ids must contain non-empty ids")
with self.connect() as conn:
task = self._task_in_connection(conn, task_id, for_update=True)
self._ensure_editable(task)
if requested_ids is None:
rows = conn.execute(
"""
SELECT id FROM data_process_source_files
WHERE task_id=%s AND deleted_at IS NULL
ORDER BY created_at, id
""",
(task_id,),
).fetchall()
else:
rows = conn.execute(
"""
SELECT id FROM data_process_source_files
WHERE task_id=%s AND deleted_at IS NULL AND id=ANY(%s)
ORDER BY created_at, id
""",
(task_id, requested_ids),
).fetchall()
selected_ids = [str(row["id"]) for row in rows]
if not selected_ids:
raise InvalidStateError("at least one source file is required")
if requested_ids is not None:
missing = set(requested_ids) - set(selected_ids)
if missing:
raise NotFoundError(
f"source files not found: {', '.join(sorted(missing))}"
)
regeneration_prepared = _is_regeneration_prepared(task)
if not regeneration_prepared:
conn.execute("DELETE FROM data_process_results WHERE task_id=%s", (task_id,))
preview_run_id = new_id("dpprun")
now = utcnow()
row = conn.execute(
"""
UPDATE data_process_tasks
SET status=CASE WHEN %s THEN status ELSE 'pending' END,
progress=CASE WHEN %s THEN progress ELSE 0 END,
output_count=CASE WHEN %s THEN output_count ELSE 0 END,
filtered_count=CASE WHEN %s THEN filtered_count ELSE 0 END,
duplicate_count=CASE WHEN %s THEN duplicate_count ELSE 0 END,
error_count=CASE WHEN %s THEN error_count ELSE 0 END,
failure_reason=CASE WHEN %s THEN failure_reason ELSE NULL END,
results_confirmed=CASE WHEN %s THEN results_confirmed ELSE FALSE END,
workflow_step='upload', preview_status='queued', preview_progress=0,
preview_run_id=%s, preview_failure_reason=NULL,
preview_total_files=%s, preview_completed_files=0,
updated_at=%s
WHERE id=%s AND deleted_at IS NULL
RETURNING *
""",
(
regeneration_prepared,
regeneration_prepared,
regeneration_prepared,
regeneration_prepared,
regeneration_prepared,
regeneration_prepared,
regeneration_prepared,
regeneration_prepared,
preview_run_id,
len(selected_ids),
now,
task_id,
),
).fetchone()
return _public_task(_decode_row(row)) or {}, selected_ids
def mark_preview_running(self, task_id: str, preview_run_id: str) -> bool:
with self.connect() as conn:
row = conn.execute(
"""
UPDATE data_process_tasks
SET preview_status='running', updated_at=%s
WHERE id=%s AND deleted_at IS NULL
AND preview_status='queued' AND preview_run_id=%s
RETURNING id
""",
(utcnow(), task_id, preview_run_id),
).fetchone()
return row is not None
def preview_is_running(self, task_id: str, preview_run_id: str) -> bool:
with self.connect() as conn:
row = conn.execute(
"""
SELECT preview_status, preview_run_id
FROM data_process_tasks
WHERE id=%s AND deleted_at IS NULL
""",
(task_id,),
).fetchone()
return bool(
row
and row.get("preview_status") in ACTIVE_PREVIEW_STATUSES
and row.get("preview_run_id") == preview_run_id
)
def update_preview_progress(
self,
task_id: str,
preview_run_id: str,
completed_files: int,
total_files: int,
) -> bool:
total = max(1, total_files)
completed = min(max(0, completed_files), total)
progress = completed / total * 100
with self.connect() as conn:
row = conn.execute(
"""
UPDATE data_process_tasks
SET preview_progress=%s, preview_completed_files=%s, updated_at=%s
WHERE id=%s AND deleted_at IS NULL
AND preview_status='running' AND preview_run_id=%s
RETURNING id
""",
(progress, completed, utcnow(), task_id, preview_run_id),
).fetchone()
return row is not None
def complete_preview(self, task_id: str, preview_run_id: str) -> bool:
with self.connect() as conn:
row = conn.execute(
"""
UPDATE data_process_tasks
SET workflow_step='preview', preview_status='completed',
preview_progress=100, preview_run_id=NULL,
preview_failure_reason=NULL,
preview_completed_files=preview_total_files, updated_at=%s
WHERE id=%s AND deleted_at IS NULL
AND preview_status='running' AND preview_run_id=%s
RETURNING id
""",
(utcnow(), task_id, preview_run_id),
).fetchone()
return row is not None
def mark_preview_failed(
self,
task_id: str,
reason: str,
*,
preview_run_id: str,
) -> bool:
with self.connect() as conn:
row = conn.execute(
"""
UPDATE data_process_tasks
SET preview_status='failed', preview_run_id=NULL,
preview_failure_reason=%s, updated_at=%s
WHERE id=%s AND deleted_at IS NULL
AND preview_status IN ('queued', 'running') AND preview_run_id=%s
RETURNING id
""",
(reason[:4000], utcnow(), task_id, preview_run_id),
).fetchone()
return row is not None
def preview_progress(self, task_id: str) -> dict[str, Any]:
task = self.get_task(task_id)
return {
"task_id": task["id"],
"workflow_step": task.get("workflow_step") or "create",
"preview_status": task.get("preview_status") or "idle",
"preview_progress": float(task.get("preview_progress") or 0),
"preview_run_id": task.get("preview_run_id"),
"preview_failure_reason": task.get("preview_failure_reason"),
"preview_total_files": int(task.get("preview_total_files") or 0),
"preview_completed_files": int(task.get("preview_completed_files") or 0),
}
def list_preview_items(
self,
task_id: str,
@@ -1332,7 +1625,7 @@ class DataProcessStore:
UPDATE data_process_tasks
SET status='pending', progress=20, output_count=0, filtered_count=0,
duplicate_count=0, error_count=0, failure_reason=NULL,
generation_run_id=NULL, updated_at=%s
generation_run_id=NULL, results_confirmed=FALSE, updated_at=%s
WHERE id=%s
""",
(now, task_id),
@@ -1348,6 +1641,8 @@ class DataProcessStore:
raise InvalidStateError("published task cannot be regenerated")
if task["status"] == "running":
raise ConflictError("data process task is already running")
if task.get("preview_status") in ACTIVE_PREVIEW_STATUSES:
raise ConflictError("preview is still running")
preview_count = conn.execute(
"SELECT COUNT(*) AS count FROM data_process_preview_items WHERE task_id=%s",
(task_id,),
@@ -1365,7 +1660,8 @@ class DataProcessStore:
SET config=%s, status='running', progress=30, failure_reason=NULL,
started_at=%s, completed_at=NULL, output_dataset_id=NULL,
output_count=0, filtered_count=0, duplicate_count=0, error_count=0,
generation_run_id=%s, updated_at=%s
generation_run_id=%s, results_confirmed=FALSE,
workflow_step='generate', updated_at=%s
WHERE id=%s
RETURNING *
""",
@@ -1391,10 +1687,19 @@ class DataProcessStore:
return _decode_row(row) or {}
def generation_is_running(self, task_id: str, generation_run_id: str) -> bool:
task = self.get_task(task_id)
return (
task["status"] == "running"
and task.get("generation_run_id") == generation_run_id
with self.connect() as conn:
row = conn.execute(
"""
SELECT status, generation_run_id
FROM data_process_tasks
WHERE id=%s AND deleted_at IS NULL
""",
(task_id,),
).fetchone()
return bool(
row
and row.get("status") == "running"
and row.get("generation_run_id") == generation_run_id
)
def update_generation_progress(
@@ -1469,7 +1774,8 @@ class DataProcessStore:
UPDATE data_process_tasks
SET status='completed', progress=100, output_count=%s, filtered_count=%s,
duplicate_count=%s, error_count=%s, failure_reason=NULL,
completed_at=%s, generation_run_id=NULL, updated_at=%s
completed_at=%s, generation_run_id=NULL, results_confirmed=FALSE,
updated_at=%s
WHERE id=%s AND generation_run_id=%s RETURNING *
""",
(
@@ -1519,10 +1825,59 @@ class DataProcessStore:
"duplicate_count": int(task.get("duplicate_count") or 0),
"error_count": int(task.get("error_count") or 0),
"failure_reason": task.get("failure_reason"),
"results_confirmed": bool(task.get("results_confirmed")),
"started_at": task.get("started_at"),
"completed_at": task.get("completed_at"),
}
def confirm_results(self, task_id: str) -> dict[str, Any]:
"""确认第六步结果,确认前再次校验所有生成记录。"""
with self.connect() as conn:
task = self._task_in_connection(conn, task_id, for_update=True)
if task["status"] != "completed":
raise InvalidStateError("only a completed task can confirm results")
if task.get("workflow_step") != "results":
raise InvalidStateError("workflow must be on results before confirmation")
if task.get("results_confirmed"):
return task
rows = conn.execute(
"""
SELECT status, instruction, output
FROM data_process_results
WHERE task_id=%s
""",
(task_id,),
).fetchall()
if not rows:
raise InvalidStateError("task has no results to confirm")
invalid_count = sum(
1
for row in rows
if row["status"] == "invalid"
or not str(row.get("instruction") or "").strip()
or not str(row.get("output") or "").strip()
or (
_task_output_type(task) == "reasoning"
and not _reasoning_output_is_valid(row.get("output"))
)
)
if invalid_count:
raise InvalidStateError(
f"task contains {invalid_count} invalid results"
)
row = conn.execute(
"""
UPDATE data_process_tasks
SET results_confirmed=TRUE, updated_at=%s
WHERE id=%s RETURNING *
""",
(utcnow(), task_id),
).fetchone()
return _decode_row(row) or {}
def list_results(
self,
task_id: str,
@@ -1651,6 +2006,83 @@ class DataProcessStore:
)
return _decode_row(row) or {}
def replace_generated_result(
self,
task_id: str,
result_id: str,
replacement: dict[str, Any],
*,
expected_updated_at: str,
) -> dict[str, Any]:
"""用新模型结果原位替换失败项,并将新内容设为恢复基线。"""
with self.connect() as conn:
task = self._task_in_connection(conn, task_id, for_update=True)
if task["status"] != "completed" or task.get("workflow_step") != "results":
raise InvalidStateError("task is not editing generation results")
if task.get("results_confirmed"):
raise InvalidStateError("confirmed results cannot be regenerated")
if task.get("output_dataset_id"):
raise InvalidStateError("published results cannot be regenerated")
current = conn.execute(
"""SELECT * FROM data_process_results
WHERE id=%s AND task_id=%s FOR UPDATE""",
(result_id, task_id),
).fetchone()
if not current:
raise NotFoundError("data process result not found")
if current.get("status") != "invalid":
raise InvalidStateError("only an invalid result can be regenerated")
current_updated_at = _serialize_value(current.get("updated_at"))
if expected_updated_at != current_updated_at:
raise ConflictError("data process result was modified by another request")
instruction = str(replacement.get("instruction") or "").strip()
input_text = str(replacement.get("input") or "").strip()
output = str(replacement.get("output") or "").strip()
quality_score = replacement.get("quality_score") or {}
if not instruction or not output or not bool(quality_score.get("is_valid")):
raise InvalidStateError("regenerated result did not pass quality validation")
if _task_output_type(task) == "reasoning" and not _reasoning_output_is_valid(output):
raise InvalidStateError("regenerated reasoning result has an invalid output format")
now = utcnow()
row = conn.execute(
"""
UPDATE data_process_results
SET instruction=%s, input=%s, output=%s,
original_instruction=%s, original_input=%s, original_output=%s,
status='valid', error=NULL, quality_score=%s, updated_at=%s
WHERE id=%s AND task_id=%s
RETURNING *
""",
(
instruction,
input_text,
output,
instruction,
input_text,
output,
json_dumps(quality_score),
now,
result_id,
task_id,
),
).fetchone()
conn.execute(
"""
UPDATE data_process_tasks
SET error_count=(
SELECT COUNT(*) FROM data_process_results
WHERE task_id=%s AND status='invalid'
), updated_at=%s
WHERE id=%s
""",
(task_id, now, task_id),
)
return _decode_row(row) or {}
def get_generation_model(self, model_id: str) -> dict[str, Any]:
with self.connect() as conn:
row = conn.execute(
@@ -1704,6 +2136,8 @@ class DataProcessStore:
)
if task["status"] != "completed":
raise InvalidStateError("only a completed task can be published")
if not task.get("results_confirmed"):
raise InvalidStateError("results must be confirmed before publishing")
rows = conn.execute(
"""
SELECT * FROM data_process_results

View File

@@ -109,6 +109,24 @@ class DataProcessStatus(StrEnum):
stopped = "stopped"
class DataProcessWorkflowStep(StrEnum):
create = "create"
model = "model"
upload = "upload"
preview = "preview"
generate = "generate"
results = "results"
class DataProcessPreviewStatus(StrEnum):
idle = "idle"
queued = "queued"
running = "running"
completed = "completed"
failed = "failed"
cancelled = "cancelled"
class ProcessType(StrEnum):
structured = "structured"
unstructured = "unstructured"
@@ -164,6 +182,14 @@ class DataProcessTaskUpdate(BaseModel):
return self
class DataProcessWorkflowStepUpdate(BaseModel):
"""仅保存创建向导位置,不修改配置或使下游产物失效。"""
model_config = ConfigDict(extra="forbid")
workflow_step: DataProcessWorkflowStep
class DataProcessRegenerateRequest(BaseModel):
"""以一份完整配置准备任务重新生成。
@@ -288,6 +314,32 @@ class ResultUpdate(BaseModel):
expected_updated_at: str | None = None
class ResultRegenerateRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
expected_updated_at: str = Field(min_length=1, max_length=100)
class ResultBatchRegenerateItem(BaseModel):
model_config = ConfigDict(extra="forbid")
result_id: str = Field(min_length=1, max_length=100)
expected_updated_at: str = Field(min_length=1, max_length=100)
class ResultBatchRegenerateRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
items: list[ResultBatchRegenerateItem] = Field(min_length=1, max_length=100)
@model_validator(mode="after")
def validate_unique_results(self) -> "ResultBatchRegenerateRequest":
result_ids = [item.result_id for item in self.items]
if len(result_ids) != len(set(result_ids)):
raise ValueError("result_id values must be unique")
return self
class DatasetSplit(BaseModel):
model_config = ConfigDict(extra="forbid")

View File

@@ -3,11 +3,13 @@ from __future__ import annotations
from copy import deepcopy
from io import BytesIO
from pathlib import Path
from threading import Barrier, Lock
from typing import Any
import psycopg
import pytest
from docx import Document as WordDocument
from fastapi import FastAPI
from fastapi import FastAPI, HTTPException
from fastapi.testclient import TestClient
from openpyxl import Workbook
@@ -31,6 +33,7 @@ class FakeDataProcessStore:
self.previews: dict[str, list[dict[str, Any]]] = {}
self.results: dict[str, list[dict[str, Any]]] = {}
self.datasets: dict[str, dict[str, Any]] = {}
self.models: dict[str, dict[str, Any]] = {}
self.regeneration_prepared: set[str] = set()
self.sequence = 0
@@ -73,6 +76,14 @@ class FakeDataProcessStore:
"error_count": 0,
"failure_reason": None,
"output_dataset_id": None,
"results_confirmed": False,
"workflow_step": "create",
"preview_status": "idle",
"preview_progress": 0,
"preview_run_id": None,
"preview_failure_reason": None,
"preview_total_files": 0,
"preview_completed_files": 0,
}
self.tasks[task_id] = task
self.sources[task_id] = []
@@ -105,6 +116,11 @@ class FakeDataProcessStore:
self.tasks[task_id].update(deepcopy(payload))
return self.get_task(task_id)
def update_workflow_step(self, task_id: str, workflow_step: str) -> dict[str, Any]:
self.get_task(task_id)
self.tasks[task_id]["workflow_step"] = workflow_step
return self.get_task(task_id)
def prepare_regeneration(self, task_id: str, payload: dict[str, Any]) -> dict[str, Any]:
task = self.tasks.get(task_id)
if task is None:
@@ -136,8 +152,6 @@ class FakeDataProcessStore:
def delete_task(self, task_id: str, **_: Any) -> None:
self.get_task(task_id)
if self.tasks[task_id]["status"] == "running":
raise InvalidStateError("running task must be stopped before deletion")
del self.tasks[task_id]
def list_source_files(self, task_id: str) -> list[dict[str, Any]]:
@@ -197,6 +211,13 @@ class FakeDataProcessStore:
"error_count": 0,
"failure_reason": None,
"generation_run_id": None,
"workflow_step": "upload",
"preview_status": "idle",
"preview_progress": 0,
"preview_run_id": None,
"preview_failure_reason": None,
"preview_total_files": 0,
"preview_completed_files": 0,
"started_at": None,
"completed_at": None,
}
@@ -254,6 +275,15 @@ class FakeDataProcessStore:
item for item in self.previews[task_id] if item["source_file_id"] != file_id
]
self.results[task_id] = []
self.tasks[task_id].update(
workflow_step="upload",
preview_status="idle",
preview_progress=0,
preview_run_id=None,
preview_failure_reason=None,
preview_total_files=0,
preview_completed_files=0,
)
def replace_preview_items(
self,
@@ -261,7 +291,10 @@ class FakeDataProcessStore:
items: list[dict[str, Any]],
*,
source_file_ids: list[str] | None = None,
preview_run_id: str | None = None,
) -> list[dict[str, Any]]:
if preview_run_id is not None and not self.preview_is_running(task_id, preview_run_id):
raise InvalidStateError("preview run is no longer active")
created = [
{"id": self._id("dpp"), "task_id": task_id, **deepcopy(item)} for item in items
]
@@ -276,8 +309,121 @@ class FakeDataProcessStore:
] + created
self.results[task_id] = []
self.tasks[task_id]["progress"] = 20
if preview_run_id is None:
file_count = len(source_file_ids or {item["source_file_id"] for item in created})
self.tasks[task_id].update(
workflow_step="preview",
preview_status="completed",
preview_progress=100,
preview_run_id=None,
preview_failure_reason=None,
preview_total_files=file_count,
preview_completed_files=file_count,
)
return deepcopy(created)
def start_preview(
self,
task_id: str,
*,
source_file_ids: list[str] | None = None,
) -> tuple[dict[str, Any], list[str]]:
task = self.tasks[task_id]
if task.get("preview_status") in {"queued", "running"}:
raise InvalidStateError("task cannot be edited while preview is running")
selected_ids = source_file_ids or [str(item["id"]) for item in self.sources[task_id]]
found = {str(item["id"]) for item in self.sources[task_id]}
missing = set(selected_ids) - found
if missing:
raise NotFoundError(f"source files not found: {', '.join(sorted(missing))}")
if not selected_ids:
raise InvalidStateError("at least one source file is required")
run_id = self._id("dpprun")
self.results[task_id] = []
task.update(
status="pending",
workflow_step="upload",
preview_status="queued",
preview_progress=0,
preview_run_id=run_id,
preview_failure_reason=None,
preview_total_files=len(selected_ids),
preview_completed_files=0,
results_confirmed=False,
)
return self.get_task(task_id), list(selected_ids)
def mark_preview_running(self, task_id: str, preview_run_id: str) -> bool:
task = self.tasks.get(task_id)
if not task or task.get("preview_status") != "queued" or task.get("preview_run_id") != preview_run_id:
return False
task["preview_status"] = "running"
return True
def preview_is_running(self, task_id: str, preview_run_id: str) -> bool:
task = self.tasks.get(task_id)
return bool(
task
and task.get("preview_status") in {"queued", "running"}
and task.get("preview_run_id") == preview_run_id
)
def update_preview_progress(
self,
task_id: str,
preview_run_id: str,
completed_files: int,
total_files: int,
) -> bool:
if not self.preview_is_running(task_id, preview_run_id):
return False
self.tasks[task_id]["preview_completed_files"] = completed_files
self.tasks[task_id]["preview_progress"] = completed_files / max(1, total_files) * 100
return True
def complete_preview(self, task_id: str, preview_run_id: str) -> bool:
if not self.preview_is_running(task_id, preview_run_id):
return False
task = self.tasks[task_id]
task.update(
workflow_step="preview",
preview_status="completed",
preview_progress=100,
preview_run_id=None,
preview_failure_reason=None,
preview_completed_files=task["preview_total_files"],
)
return True
def mark_preview_failed(
self,
task_id: str,
reason: str,
*,
preview_run_id: str,
) -> bool:
if not self.preview_is_running(task_id, preview_run_id):
return False
self.tasks[task_id].update(
preview_status="failed",
preview_run_id=None,
preview_failure_reason=reason,
)
return True
def preview_progress(self, task_id: str) -> dict[str, Any]:
task = self.get_task(task_id)
return {
"task_id": task_id,
"workflow_step": task["workflow_step"],
"preview_status": task["preview_status"],
"preview_progress": task["preview_progress"],
"preview_run_id": task["preview_run_id"],
"preview_failure_reason": task["preview_failure_reason"],
"preview_total_files": task["preview_total_files"],
"preview_completed_files": task["preview_completed_files"],
}
def list_preview_items(
self,
task_id: str,
@@ -348,15 +494,19 @@ class FakeDataProcessStore:
progress=30,
output_dataset_id=None,
output_count=0,
results_confirmed=False,
workflow_step="generate",
generation_run_id=self._id("dprun"),
)
self.regeneration_prepared.discard(task_id)
return self.get_task(task_id)
def generation_is_running(self, task_id: str, generation_run_id: str) -> bool:
task = self.tasks.get(task_id)
return (
self.tasks[task_id]["status"] == "running"
and self.tasks[task_id].get("generation_run_id") == generation_run_id
bool(task)
and task["status"] == "running"
and task.get("generation_run_id") == generation_run_id
)
def update_generation_progress(
@@ -389,6 +539,7 @@ class FakeDataProcessStore:
status="completed",
progress=100,
output_count=len(results),
results_confirmed=False,
generation_run_id=None,
**counts,
)
@@ -416,6 +567,7 @@ class FakeDataProcessStore:
result = {key: task.get(key) for key in (
"status", "progress", "input_count", "output_count",
"filtered_count", "duplicate_count", "error_count", "failure_reason",
"results_confirmed",
)}
result["task_id"] = task["id"]
return result
@@ -488,6 +640,66 @@ class FakeDataProcessStore:
item["status"] = "valid"
return deepcopy(item)
def get_generation_model(self, model_id: str) -> dict[str, Any]:
model = self.models.get(model_id)
if not model:
raise NotFoundError("generation model not found")
return deepcopy(model)
def replace_generated_result(
self,
task_id: str,
result_id: str,
replacement: dict[str, Any],
*,
expected_updated_at: str,
) -> dict[str, Any]:
task = self.tasks[task_id]
if task["status"] != "completed" or task.get("workflow_step") != "results":
raise InvalidStateError("task is not editing generation results")
if task.get("results_confirmed") or task.get("output_dataset_id"):
raise InvalidStateError("confirmed or published results cannot be regenerated")
item = next((item for item in self.results[task_id] if item["id"] == result_id), None)
if not item:
raise NotFoundError("data process result not found")
if item["status"] != "invalid":
raise InvalidStateError("only an invalid result can be regenerated")
if expected_updated_at != item.get("updated_at"):
raise InvalidStateError("data process result was modified by another request")
for field in ("instruction", "input", "output"):
item[field] = replacement[field]
item[f"original_{field}"] = replacement[field]
item.update(
status=replacement["status"],
error=replacement.get("error"),
quality_score=deepcopy(replacement["quality_score"]),
updated_at="2026-07-27T22:00:00Z",
)
task["error_count"] = sum(
result["status"] == "invalid" for result in self.results[task_id]
)
return deepcopy(item)
def confirm_results(self, task_id: str) -> dict[str, Any]:
task = self.tasks[task_id]
if task["status"] != "completed":
raise InvalidStateError("only a completed task can confirm results")
if task.get("workflow_step") != "results":
raise InvalidStateError("workflow must be on results before confirmation")
invalid_count = sum(
1
for item in self.results[task_id]
if item["status"] == "invalid"
or not item["instruction"].strip()
or not item["output"].strip()
)
if invalid_count:
raise InvalidStateError(f"task contains {invalid_count} invalid results")
if not self.results[task_id]:
raise InvalidStateError("task has no results to confirm")
task["results_confirmed"] = True
return self.get_task(task_id)
def publish(self, task_id: str, payload: dict[str, Any]) -> dict[str, Any]:
task = self.tasks[task_id]
if task_id in self.regeneration_prepared:
@@ -508,6 +720,8 @@ class FakeDataProcessStore:
}
if task["status"] != "completed":
raise InvalidStateError("only a completed task can be published")
if not task.get("results_confirmed"):
raise InvalidStateError("results must be confirmed before publishing")
split_specs = (
("train", "训练集"),
("val", "验证集"),
@@ -625,6 +839,14 @@ def _minimal_pdf(text: str = "Hello PDF") -> bytes:
return _minimal_pdf_pages(text)
def test_outdated_data_process_schema_returns_actionable_503() -> None:
with pytest.raises(HTTPException) as captured, data_process_endpoint.api_errors():
raise psycopg.errors.UndefinedColumn("missing runtime column")
assert captured.value.status_code == 503
assert "schema is missing or out of date" in captured.value.detail["message"]
def test_data_process_full_contract_without_database(tmp_path: Path) -> None:
client, store, _ = make_client(tmp_path)
created = client.post(
@@ -636,6 +858,7 @@ def test_data_process_full_contract_without_database(tmp_path: Path) -> None:
},
)
assert created.status_code == 200
assert created.json()["data"]["results_confirmed"] is False
task_id = created.json()["data"]["id"]
source_content = (
@@ -687,8 +910,10 @@ def test_data_process_full_contract_without_database(tmp_path: Path) -> None:
generated = client.post(f"/modelTF/data-process/{task_id}/generate")
assert generated.status_code == 200
assert generated.json()["data"]["results_confirmed"] is False
progress = client.get(f"/modelTF/data-process/{task_id}/progress")
assert progress.json()["data"]["status"] == "completed"
assert progress.json()["data"]["results_confirmed"] is False
result_page = client.get(f"/modelTF/data-process/{task_id}/results").json()["data"]
assert result_page["total"] == 2
keyword_page = client.get(
@@ -719,6 +944,17 @@ def test_data_process_full_contract_without_database(tmp_path: Path) -> None:
assert restored.json()["data"]["status"] == "valid"
assert store.tasks[task_id]["error_count"] == 0
workflow = client.put(
f"/modelTF/data-process/{task_id}/workflow-step",
json={"workflow_step": "results"},
)
assert workflow.status_code == 200
confirmed = client.post(
f"/modelTF/data-process/{task_id}/confirm-results"
)
assert confirmed.status_code == 200
assert confirmed.json()["data"]["results_confirmed"] is True
publish_payload = {"dataset_name": "客服问答清洗集"}
first_publish = client.post(
f"/modelTF/data-process/{task_id}/publish", json=publish_payload
@@ -761,6 +997,120 @@ def test_task_list_exposes_document_and_generation_counts(
assert item["output_dataset_id"] is None
def test_workflow_step_update_is_independent_and_validated(tmp_path: Path) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={"name": "步骤持久化", "process_type": "structured", "config": {}},
).json()["data"]["id"]
store.previews[task_id] = [{"id": "preview-1"}]
store.results[task_id] = [{"id": "result-1"}]
store.tasks[task_id].update(status="running", generation_run_id="run-1")
updated = client.put(
f"/modelTF/data-process/{task_id}/workflow-step",
json={"workflow_step": "generate"},
)
assert updated.status_code == 200
assert updated.json()["data"]["workflow_step"] == "generate"
assert store.previews[task_id] == [{"id": "preview-1"}]
assert store.results[task_id] == [{"id": "result-1"}]
assert store.tasks[task_id]["status"] == "running"
assert client.put(
f"/modelTF/data-process/{task_id}/workflow-step",
json={"workflow_step": "unknown"},
).status_code == 422
def test_background_preview_persists_progress_and_items(tmp_path: Path) -> None:
client, _, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={"name": "后台切分", "process_type": "structured", "config": {}},
).json()["data"]["id"]
source = client.post(
f"/modelTF/data-process/{task_id}/source-files",
files={
"files": (
"one.jsonl",
b'{"question":"What is one?","answer":"One."}\n',
"application/jsonl",
)
},
).json()["data"]["files"][0]
started = client.post(
f"/modelTF/data-process/{task_id}/preview/start",
json={"source_file_ids": [source["id"]]},
)
assert started.status_code == 202
assert started.json()["data"]["preview_status"] == "queued"
assert started.json()["data"]["preview_run_id"]
progress = client.get(
f"/modelTF/data-process/{task_id}/preview/progress"
).json()["data"]
assert progress == {
"task_id": task_id,
"workflow_step": "preview",
"preview_status": "completed",
"preview_progress": 100.0,
"preview_run_id": None,
"preview_failure_reason": None,
"preview_total_files": 1,
"preview_completed_files": 1,
}
assert client.get(
f"/modelTF/data-process/{task_id}/preview"
).json()["data"]["total"] == 1
def test_stale_preview_worker_cannot_replace_new_run(tmp_path: Path) -> None:
_, store, storage = make_client(tmp_path)
task = store.create_task(
{"name": "切分代次", "process_type": "structured", "config": {}}
)
task_id = str(task["id"])
store.sources[task_id] = [{"id": "source-1"}]
first, source_ids = store.start_preview(task_id, source_file_ids=["source-1"])
first_run_id = str(first["preview_run_id"])
store.tasks[task_id].update(preview_status="cancelled", preview_run_id=None)
second, _ = store.start_preview(task_id, source_file_ids=["source-1"])
data_process_endpoint._run_preview(
store,
storage,
task_id,
first_run_id,
source_ids,
)
assert store.tasks[task_id]["preview_status"] == "queued"
assert store.tasks[task_id]["preview_run_id"] == second["preview_run_id"]
assert store.previews[task_id] == []
def test_delete_invalidates_active_generation_and_preview(tmp_path: Path) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={"name": "删除运行任务", "process_type": "structured", "config": {}},
).json()["data"]["id"]
store.tasks[task_id].update(
status="running",
generation_run_id="generation-1",
preview_status="running",
preview_run_id="preview-1",
)
deleted = client.delete(f"/modelTF/data-process/{task_id}")
assert deleted.status_code == 200
assert store.generation_is_running(task_id, "generation-1") is False
assert store.preview_is_running(task_id, "preview-1") is False
def test_task_detail_uses_returned_source_files_as_document_count(tmp_path: Path) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
@@ -811,6 +1161,404 @@ def test_generation_start_response_clears_previous_output_count(
assert store.tasks[task_id]["output_count"] == 0
def test_results_must_be_generated_and_valid_before_confirmation(
tmp_path: Path,
) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={"name": "结果确认门禁", "process_type": "structured", "config": {}},
).json()["data"]["id"]
pending = client.post(f"/modelTF/data-process/{task_id}/confirm-results")
assert pending.status_code == 409
store.tasks[task_id].update(status="completed", progress=100, workflow_step="generate")
store.results[task_id] = [
{
"id": "result_valid",
"status": "valid",
"instruction": "问题",
"input": "",
"output": "答案",
}
]
wrong_step = client.post(f"/modelTF/data-process/{task_id}/confirm-results")
assert wrong_step.status_code == 409
store.tasks[task_id]["workflow_step"] = "results"
store.results[task_id] = [
{
"id": "result_invalid",
"status": "invalid",
"instruction": "问题",
"input": "",
"output": "",
}
]
invalid = client.post(f"/modelTF/data-process/{task_id}/confirm-results")
assert invalid.status_code == 409
store.results[task_id][0].update(status="valid", output="答案")
confirmed = client.post(f"/modelTF/data-process/{task_id}/confirm-results")
assert confirmed.status_code == 200
assert confirmed.json()["data"]["results_confirmed"] is True
assert client.post(
f"/modelTF/data-process/{task_id}/confirm-results"
).status_code == 200
def test_invalid_result_can_be_regenerated_in_place(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={
"name": "单条重生成",
"process_type": "structured",
"config": {
"generation_model_id": "model-1",
"output_type": "standard",
"min_output_length": 5,
"generation_retries": 5,
"request_timeout_seconds": 120,
},
},
).json()["data"]["id"]
store.tasks[task_id].update(
status="completed",
progress=100,
workflow_step="results",
results_confirmed=False,
error_count=1,
)
store.models["model-1"] = {
"id": "model-1",
"name": "测试模型",
"online_model_name": "test-model",
"api_url": "https://model.example/v1",
"api_key": "secret",
}
store.previews[task_id] = [{
"id": "preview-1",
"status": "original",
"original_content": "申请编号字段用于标识报销申请。",
"edited_content": "申请编号字段用于标识报销申请。",
}]
store.results[task_id] = [{
"id": "result-1",
"preview_item_id": "preview-1",
"instruction": "模型生成失败,请人工补充",
"input": "申请编号字段用于标识报销申请。",
"output": "",
"original_instruction": "模型生成失败,请人工补充",
"original_input": "申请编号字段用于标识报销申请。",
"original_output": "",
"status": "invalid",
"error": "model response is not valid JSON",
"split": "train",
"quality_score": {},
"updated_at": "2026-07-27T21:00:00Z",
}]
captured: dict[str, Any] = {}
def fake_generate(preview_items: Any, **kwargs: Any) -> list[dict[str, Any]]:
captured["preview_items"] = list(preview_items)
captured["qa_pairs_per_item"] = kwargs["qa_pairs_per_item"]
captured["config"] = kwargs["config"]
return [{
"id": "temporary-result",
"preview_item_id": "preview-1",
"instruction": "申请编号字段有什么作用?",
"input": "申请编号字段用于标识报销申请。",
"output": "申请编号字段用于唯一标识一笔报销申请。",
"original_instruction": "申请编号字段有什么作用?",
"original_input": "申请编号字段用于标识报销申请。",
"original_output": "申请编号字段用于唯一标识一笔报销申请。",
"status": "valid",
"error": None,
"split": "train",
}]
monkeypatch.setattr(data_process_endpoint, "generate_model_records", fake_generate)
response = client.post(
f"/modelTF/data-process/{task_id}/results/result-1/regenerate",
json={"expected_updated_at": "2026-07-27T21:00:00Z"},
)
assert response.status_code == 200
regenerated = response.json()["data"]
assert regenerated["id"] == "result-1"
assert regenerated["status"] == "valid"
assert regenerated["instruction"] == regenerated["original_instruction"]
assert regenerated["output"] == regenerated["original_output"]
assert store.tasks[task_id]["error_count"] == 0
assert captured["qa_pairs_per_item"] == 1
assert [item["id"] for item in captured["preview_items"]] == ["preview-1"]
assert captured["config"]["generation_retries"] == 0
assert captured["config"]["request_timeout_seconds"] == 60
def test_failed_result_regeneration_keeps_the_original_error(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={
"name": "失败结果保留",
"process_type": "structured",
"config": {
"generation_model_id": "model-1",
"output_type": "standard",
},
},
).json()["data"]["id"]
store.tasks[task_id].update(
status="completed",
progress=100,
workflow_step="results",
results_confirmed=False,
error_count=1,
)
store.models["model-1"] = {
"id": "model-1",
"online_model_name": "test-model",
"api_url": "https://model.example/v1",
"api_key": "secret",
}
store.previews[task_id] = [{
"id": "preview-1",
"status": "original",
"original_content": "原始内容",
"edited_content": "原始内容",
}]
original_result = {
"id": "result-1",
"preview_item_id": "preview-1",
"instruction": "模型生成失败,请人工补充",
"input": "原始内容",
"output": "",
"status": "invalid",
"error": "first failure",
"updated_at": "2026-07-27T21:30:00Z",
}
store.results[task_id] = [original_result.copy()]
monkeypatch.setattr(
data_process_endpoint,
"generate_model_records",
lambda *args, **kwargs: [{
"status": "invalid",
"error": "second failure",
}],
)
response = client.post(
f"/modelTF/data-process/{task_id}/results/result-1/regenerate",
json={"expected_updated_at": "2026-07-27T21:30:00Z"},
)
assert response.status_code == 409
assert store.results[task_id] == [original_result]
assert store.tasks[task_id]["error_count"] == 1
def test_failed_results_can_be_regenerated_in_parallel_with_partial_success(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={
"name": "批量重生成",
"process_type": "structured",
"config": {
"generation_model_id": "model-1",
"output_type": "standard",
"min_output_length": 5,
},
},
).json()["data"]["id"]
store.tasks[task_id].update(
status="completed",
progress=100,
workflow_step="results",
results_confirmed=False,
error_count=2,
)
store.models["model-1"] = {
"id": "model-1",
"online_model_name": "test-model",
"api_url": "https://model.example/v1",
"api_key": "secret",
}
store.previews[task_id] = [
{
"id": "preview-1",
"status": "original",
"original_content": "申请编号用于唯一标识一笔报销申请。",
"edited_content": "申请编号用于唯一标识一笔报销申请。",
},
{
"id": "preview-2",
"status": "original",
"original_content": "联系电话用于联系申请人。",
"edited_content": "联系电话用于联系申请人。",
},
]
original_results = [
{
"id": "result-1",
"preview_item_id": "preview-1",
"instruction": "模型生成失败,请人工补充",
"input": "申请编号用于唯一标识一笔报销申请。",
"output": "",
"original_instruction": "模型生成失败,请人工补充",
"original_input": "申请编号用于唯一标识一笔报销申请。",
"original_output": "",
"status": "invalid",
"error": "first failure",
"split": "train",
"quality_score": {},
"updated_at": "2026-07-28T09:00:00Z",
},
{
"id": "result-2",
"preview_item_id": "preview-2",
"instruction": "模型生成失败,请人工补充",
"input": "联系电话用于联系申请人。",
"output": "",
"original_instruction": "模型生成失败,请人工补充",
"original_input": "联系电话用于联系申请人。",
"original_output": "",
"status": "invalid",
"error": "first failure",
"split": "train",
"quality_score": {},
"updated_at": "2026-07-28T09:00:01Z",
},
]
store.results[task_id] = deepcopy(original_results)
barrier = Barrier(2, timeout=2)
activity_lock = Lock()
active_calls = 0
max_active_calls = 0
model_clients: list[Any] = []
def fake_generate(preview_items: Any, **kwargs: Any) -> list[dict[str, Any]]:
nonlocal active_calls, max_active_calls
preview = next(iter(preview_items))
with activity_lock:
active_calls += 1
max_active_calls = max(max_active_calls, active_calls)
model_clients.append(kwargs.get("client"))
try:
barrier.wait()
if preview["id"] == "preview-2":
return [{"status": "invalid", "error": "second failure"}]
return [{
"id": "temporary-result",
"preview_item_id": preview["id"],
"instruction": "申请编号有什么作用?",
"input": preview["edited_content"],
"output": "申请编号用于唯一标识一笔报销申请。",
"status": "valid",
"error": None,
"split": "train",
}]
finally:
with activity_lock:
active_calls -= 1
monkeypatch.setattr(data_process_endpoint, "generate_model_records", fake_generate)
response = client.post(
f"/modelTF/data-process/{task_id}/results/regenerate-batch",
json={
"items": [
{
"result_id": "result-1",
"expected_updated_at": "2026-07-28T09:00:00Z",
},
{
"result_id": "result-2",
"expected_updated_at": "2026-07-28T09:00:01Z",
},
],
},
)
assert response.status_code == 200
data = response.json()["data"]
assert data["total"] == 2
assert data["succeeded"] == 1
assert data["failed"] == 1
assert data["remaining_invalid_count"] == 1
assert [item["id"] for item in data["items"]] == ["result-1"]
assert data["failures"][0]["result_id"] == "result-2"
assert store.results[task_id][0]["status"] == "valid"
assert store.results[task_id][0]["id"] == "result-1"
assert store.results[task_id][1] == original_results[1]
assert store.tasks[task_id]["error_count"] == 1
assert max_active_calls == 2
assert all(client is not None for client in model_clients)
assert len({id(client) for client in model_clients}) == 1
@pytest.mark.parametrize(
"locked_state",
[
{"results_confirmed": True},
{"output_dataset_id": "dataset-published"},
],
ids=["confirmed", "published"],
)
def test_batch_result_regeneration_rejects_locked_tasks_before_model_call(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
locked_state: dict[str, Any],
) -> None:
client, store, _ = make_client(tmp_path)
task_id = client.post(
"/modelTF/data-process",
json={
"name": "批量重生成门禁",
"process_type": "structured",
"config": {"generation_model_id": "model-1"},
},
).json()["data"]["id"]
store.tasks[task_id].update(
status="completed",
workflow_step="results",
results_confirmed=False,
)
store.tasks[task_id].update(locked_state)
model_calls = 0
def fake_generate(*args: Any, **kwargs: Any) -> list[dict[str, Any]]:
nonlocal model_calls
model_calls += 1
return []
monkeypatch.setattr(data_process_endpoint, "generate_model_records", fake_generate)
response = client.post(
f"/modelTF/data-process/{task_id}/results/regenerate-batch",
json={
"items": [{
"result_id": "result-1",
"expected_updated_at": "2026-07-28T09:00:00Z",
}],
},
)
assert response.status_code == 409
assert model_calls == 0
def test_preview_build_replaces_only_selected_files_and_reports_file_counts(
tmp_path: Path,
) -> None:
@@ -1026,6 +1774,7 @@ def test_published_split_datasets_remain_in_detail_after_regeneration(
"status": "completed",
"updated_at": "2026-07-27T09:00:00Z",
"output_count": 1,
"results_confirmed": True,
}
)
store.results[task_id] = [
@@ -1440,6 +2189,41 @@ def test_reasoning_output_requires_generation_model() -> None:
assert failed["failure_reason"] == "思维链输出必须配置可用的数据生成模型"
def test_generation_failure_is_written_to_structured_log(caplog: pytest.LogCaptureFixture) -> None:
store = FakeDataProcessStore()
task = store.create_task(
{
"name": "生成失败日志",
"process_type": "structured",
"config": {"output_type": "reasoning"},
}
)
task_id = task["id"]
store.replace_preview_items(
task_id,
[
{
"source_file_id": None,
"original_content": "需要推理的来源内容",
"edited_content": "需要推理的来源内容",
"status": "manual",
}
],
)
started = store.start_generation(task_id, replace_existing=True)
with caplog.at_level("INFO", logger=data_process_endpoint.__name__):
data_process_endpoint._run_generation(
store,
task_id,
started["generation_run_id"],
)
messages = [record.getMessage() for record in caplog.records]
assert any("generation worker started" in message for message in messages)
assert any("generation failed" in message for message in messages)
def test_result_status_cannot_be_forged_by_client(tmp_path: Path) -> None:
client, _, _ = make_client(tmp_path)
task_id = client.post(

View File

@@ -88,6 +88,344 @@ def test_generate_model_records_uses_prompt_auth_and_stable_split() -> None:
assert progress_updates == [(1, 1)]
def test_minimax_m3_uses_split_reasoning_and_completion_token_budget() -> None:
requests: list[dict[str, object]] = []
def handler(request: httpx.Request) -> httpx.Response:
payload = json.loads(request.content)
requests.append(payload)
return httpx.Response(
200,
json={
"choices": [{
"finish_reason": "stop",
"message": {
"reasoning_content": "模型内部思考不应混入业务 JSON",
"content": json.dumps({
"items": [{
"instruction": "申请编号有什么作用?",
"reasoning": "来源说明它用于标识报销申请。",
"answer": "它用于唯一标识一笔报销申请。",
}],
}, ensure_ascii=False),
},
}],
"output_sensitive": False,
"base_resp": {"status_code": 0, "status_msg": ""},
},
)
records = generate_model_records(
[{"id": "preview-minimax", "edited_content": "申请编号用于标识报销申请。"}],
model={
"name": "MiniMax",
"online_model_name": "MiniMax-M3",
"api_url": "https://api.minimaxi.com/v1",
},
config={
"output_type": "reasoning",
"json_mode": True,
"max_tokens": 1024,
"generation_retries": 0,
},
task_id="task-minimax",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert records[0]["status"] == "valid"
assert len(requests) == 1
assert requests[0]["reasoning_split"] is True
assert requests[0]["max_completion_tokens"] >= 4096
assert "max_tokens" not in requests[0]
assert "response_format" not in requests[0]
def test_minimax_m3_keeps_larger_configured_completion_budget() -> None:
requests: list[dict[str, object]] = []
def handler(request: httpx.Request) -> httpx.Response:
requests.append(json.loads(request.content))
return httpx.Response(
200,
json={
"choices": [{
"message": {
"content": json.dumps({
"items": [{
"instruction": "问题",
"output": "这是满足测试要求的完整答案。",
}],
}, ensure_ascii=False),
},
}],
},
)
generate_model_records(
[{"id": "preview-minimax-budget", "edited_content": "来源正文"}],
model={
"online_model_name": "MiniMax-M3",
"api_url": "https://api.minimax.io/v1",
},
config={"max_tokens": 8192, "generation_retries": 0},
task_id="task-minimax-budget",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert requests[0]["max_completion_tokens"] == 8192
def test_minimax_m3_name_on_custom_proxy_keeps_generic_openai_parameters() -> None:
requests: list[dict[str, object]] = []
def handler(request: httpx.Request) -> httpx.Response:
requests.append(json.loads(request.content))
return httpx.Response(
200,
json={
"choices": [{
"message": {
"content": json.dumps({
"items": [{
"instruction": "问题",
"output": "这是代理服务返回的完整答案。",
}],
}, ensure_ascii=False),
},
}],
},
)
generate_model_records(
[{"id": "preview-minimax-proxy", "edited_content": "来源正文"}],
model={
"online_model_name": "MiniMax-M3",
"api_url": "https://model-proxy.example/v1",
},
config={"max_tokens": 1024, "json_mode": True, "generation_retries": 0},
task_id="task-minimax-proxy",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert requests[0]["max_tokens"] == 1024
assert requests[0]["response_format"] == {"type": "json_object"}
assert "reasoning_split" not in requests[0]
assert "max_completion_tokens" not in requests[0]
def test_generate_model_records_extracts_json_surrounded_by_model_explanation() -> None:
content = "模型结果如下:\n```json\n" + json.dumps(
{
"items": [{
"instruction": "字段有什么作用?",
"output": "该字段用于唯一标识记录。",
}],
},
ensure_ascii=False,
) + "\n```\n生成完毕。"
client = httpx.Client(
transport=httpx.MockTransport(
lambda _: httpx.Response(
200,
json={"choices": [{"message": {"content": content}}]},
)
)
)
records = generate_model_records(
[{"id": "preview-explanation", "edited_content": "字段用于唯一标识记录。"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 0},
task_id="task-explanation",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=client,
)
assert records[0]["status"] == "valid"
assert records[0]["output"] == "该字段用于唯一标识记录。"
def test_generate_model_records_reports_token_truncation_instead_of_json_error() -> None:
client = httpx.Client(
transport=httpx.MockTransport(
lambda _: httpx.Response(
200,
json={
"choices": [{
"finish_reason": "length",
"message": {"content": ""},
}],
"output_sensitive": False,
},
)
)
)
records = generate_model_records(
[{"id": "preview-truncated", "edited_content": "来源正文"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 0},
task_id="task-truncated",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=client,
)
assert records[0]["status"] == "invalid"
assert "Token" in records[0]["error"]
assert "截断" in records[0]["error"]
def test_token_truncation_is_not_retried_even_when_json_looks_complete() -> None:
request_count = 0
content = json.dumps({
"items": [{
"instruction": "问题",
"output": "表面完整但服务端已声明截断。",
}],
}, ensure_ascii=False)
def handler(_: httpx.Request) -> httpx.Response:
nonlocal request_count
request_count += 1
return httpx.Response(
200,
json={
"choices": [{
"finish_reason": "length",
"message": {"content": content},
}],
},
)
records = generate_model_records(
[{"id": "preview-length", "edited_content": "来源正文"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 5},
task_id="task-length",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert request_count == 1
assert records[0]["status"] == "invalid"
assert "finish_reason=length" in records[0]["error"]
def test_sensitive_model_response_is_not_retried_or_saved() -> None:
request_count = 0
def handler(_: httpx.Request) -> httpx.Response:
nonlocal request_count
request_count += 1
return httpx.Response(
200,
json={
"choices": [{
"finish_reason": "stop",
"message": {"content": "{}"},
}],
"output_sensitive": True,
"base_resp": {"status_code": 1027, "status_msg": "output sensitive"},
},
)
records = generate_model_records(
[{"id": "preview-sensitive", "edited_content": "来源正文"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 5},
task_id="task-sensitive",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert request_count == 1
assert records[0]["status"] == "invalid"
assert "安全拦截" in records[0]["error"]
assert "1027" in records[0]["error"]
def test_empty_model_content_can_retry_then_succeed() -> None:
request_count = 0
def handler(_: httpx.Request) -> httpx.Response:
nonlocal request_count
request_count += 1
if request_count == 1:
return httpx.Response(
200,
json={"choices": [{"finish_reason": "stop", "message": {"content": ""}}]},
)
return httpx.Response(
200,
json={
"choices": [{
"finish_reason": "stop",
"message": {
"content": json.dumps({
"items": [{
"instruction": "问题",
"output": "第二次请求返回了完整答案。",
}],
}, ensure_ascii=False),
},
}],
},
)
records = generate_model_records(
[{"id": "preview-empty-retry", "edited_content": "来源正文"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 1},
task_id="task-empty-retry",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert request_count == 2
assert records[0]["status"] == "valid"
def test_multiple_top_level_json_documents_are_rejected_as_ambiguous() -> None:
first = json.dumps({
"items": [{"instruction": "问题一", "output": "答案一"}],
}, ensure_ascii=False)
second = json.dumps({
"items": [{"instruction": "问题二", "output": "答案二"}],
}, ensure_ascii=False)
client = httpx.Client(
transport=httpx.MockTransport(
lambda _: httpx.Response(
200,
json={"choices": [{"message": {"content": f"{first}\n{second}"}}]},
)
)
)
records = generate_model_records(
[{"id": "preview-ambiguous", "edited_content": "来源正文"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 0},
task_id="task-ambiguous",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=client,
)
assert records[0]["status"] == "invalid"
assert "多个 JSON" in records[0]["error"]
def test_generate_model_records_builds_reasoning_output_with_think_tags() -> None:
def handler(request: httpx.Request) -> httpx.Response:
payload = json.loads(request.content)
@@ -414,6 +752,112 @@ def test_generate_model_records_retries_short_batch_then_marks_it_invalid() -> N
assert "expected 10, got 1" in records[0]["error"]
def test_generate_model_records_does_not_retry_non_retryable_http_errors() -> None:
request_count = 0
def handler(_: httpx.Request) -> httpx.Response:
nonlocal request_count
request_count += 1
return httpx.Response(401, json={"error": {"message": "unauthorized"}})
records = generate_model_records(
[{"id": "preview-auth", "edited_content": "来源内容"}],
model={
"api_url": "https://model.example/v1",
"online_model_name": "test-model",
"api_key": "invalid",
},
config={"generation_retries": 5},
task_id="task-auth",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert request_count == 1
assert records[0]["status"] == "invalid"
assert "401" in records[0]["error"]
@pytest.mark.parametrize("status_code", [408, 425, 429, 500])
def test_generate_model_records_retries_retryable_http_statuses(
status_code: int,
) -> None:
request_count = 0
def handler(_: httpx.Request) -> httpx.Response:
nonlocal request_count
request_count += 1
if request_count == 1:
return httpx.Response(status_code)
return httpx.Response(
200,
json={
"choices": [{
"message": {
"content": json.dumps({
"items": [{
"instruction": "来源内容是什么?",
"output": "这是用于验证可重试错误的来源内容。",
}],
}, ensure_ascii=False),
},
}],
},
)
records = generate_model_records(
[{"id": "preview-retryable", "edited_content": "来源内容"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 1},
task_id="task-retryable",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert request_count == 2
assert records[0]["status"] == "valid"
def test_generate_model_records_retries_transient_network_errors() -> None:
request_count = 0
def handler(request: httpx.Request) -> httpx.Response:
nonlocal request_count
request_count += 1
if request_count == 1:
raise httpx.ConnectError("temporary connection failure", request=request)
return httpx.Response(
200,
json={
"choices": [{
"message": {
"content": json.dumps({
"items": [{
"instruction": "网络恢复了吗?",
"output": "临时连接错误后,第二次模型请求已经成功。",
}],
}, ensure_ascii=False),
},
}],
},
)
records = generate_model_records(
[{"id": "preview-network", "edited_content": "网络重试来源"}],
model={"name": "model", "api_url": "https://model.example/v1"},
config={"generation_retries": 1},
task_id="task-network",
split={"train": 100, "validation": 0, "test": 0},
qa_pairs_per_item=1,
client=httpx.Client(transport=httpx.MockTransport(handler)),
)
assert request_count == 2
assert records[0]["status"] == "valid"
@pytest.mark.parametrize("qa_pairs_per_item", [0, 51])
def test_generate_model_records_rejects_out_of_range_count(
qa_pairs_per_item: int,

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
from pathlib import Path
from app.modules.data_process.schema_cli import _target_label
from app.modules.data_process.schema_cli import REQUIRED_TASK_COLUMNS, _target_label
def test_runtime_migration_fails_fast_on_incompatible_schema() -> None:
@@ -18,6 +18,24 @@ def test_runtime_migration_fails_fast_on_incompatible_schema() -> None:
assert "requires 001_platform_runtime.sql first" in sql
assert "supports only the current TEXT runtime schema" in sql
assert "generation_run_id" in sql
assert "results_confirmed BOOLEAN NOT NULL DEFAULT TRUE" in sql
assert "WHERE status <> 'completed' AND results_confirmed=TRUE" in sql
assert "ADD COLUMN IF NOT EXISTS workflow_step VARCHAR(20)" in sql
assert "ADD COLUMN IF NOT EXISTS preview_status VARCHAR(20)" in sql
assert "ADD COLUMN IF NOT EXISTS preview_progress NUMERIC(5,2)" in sql
assert "ADD COLUMN IF NOT EXISTS preview_run_id TEXT" in sql
assert "ADD COLUMN IF NOT EXISTS preview_failure_reason TEXT" in sql
assert "ADD COLUMN IF NOT EXISTS preview_total_files INTEGER" in sql
assert "ADD COLUMN IF NOT EXISTS preview_completed_files INTEGER" in sql
assert "data_process_workflow_backfill_ids" in sql
assert "ck_data_process_tasks_workflow_step" in sql
assert "ck_data_process_tasks_preview_status" in sql
assert "ck_data_process_tasks_preview_progress" in sql
assert "ck_data_process_tasks_preview_file_counts" in sql
for value in ("create", "model", "upload", "preview", "generate", "results"):
assert f"'{value}'" in sql
for value in ("idle", "queued", "running", "completed", "failed", "cancelled"):
assert f"'{value}'" in sql
assert "CREATE TABLE IF NOT EXISTS data_process_results" in sql
assert sql.count("BEGIN;") == 1
assert sql.rstrip().endswith("COMMIT;")
@@ -27,3 +45,17 @@ def test_schema_cli_target_label_never_contains_credentials() -> None:
label = _target_label("postgresql://secret-user:secret-password@db.example:5433/yg_ft")
assert label == "db.example:5433/yg_ft"
assert "secret" not in label
def test_schema_check_requires_current_runtime_columns() -> None:
assert REQUIRED_TASK_COLUMNS == (
"generation_run_id",
"results_confirmed",
"workflow_step",
"preview_status",
"preview_progress",
"preview_run_id",
"preview_failure_reason",
"preview_total_files",
"preview_completed_files",
)

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
import inspect
import json
from collections.abc import Iterator
from contextlib import contextmanager
@@ -20,6 +21,14 @@ from app.modules.data_process.store import (
)
def test_preview_replace_sql_never_uses_untyped_null_placeholders() -> None:
source = inspect.getsource(DataProcessStore.replace_preview_items)
assert "%s IS NULL" not in source
assert "is_direct_build = preview_run_id is None" in source
assert "workflow_step=CASE WHEN %s THEN 'preview'" in source
class _Result:
def __init__(self, *, row: dict[str, Any] | None = None, rows: list[dict[str, Any]] | None = None):
self.row = row
@@ -146,6 +155,7 @@ class _PublishStore(DataProcessStore):
return {
"id": task_id,
"status": "completed",
"results_confirmed": True,
"description": "",
"config": self._task_config,
"output_dataset_id": train_dataset and train_dataset["id"],
@@ -454,12 +464,14 @@ class _LegacyRecoveryConnection:
record["preview_item_id"] = params[1]
return _Result()
if normalized.startswith("UPDATE data_process_tasks SET status='completed'"):
assert "workflow_step='results'" in normalized
self.task.update(
{
"status": "completed",
"progress": 100,
"output_dataset_id": params[0],
"output_count": params[1],
"workflow_step": "results",
}
)
return _Result()
@@ -496,6 +508,7 @@ class _StartGenerationConnection:
config=config,
output_dataset_id="dataset_train" if published_prepared else None,
output_count=28,
results_confirmed=published_prepared,
),
"generation_run_id": None,
}
@@ -512,6 +525,7 @@ class _StartGenerationConnection:
assert normalized.startswith("UPDATE data_process_tasks SET config=%s, status='running'")
assert "output_dataset_id=NULL" in normalized
assert "output_count=0" in normalized
assert "results_confirmed=FALSE" in normalized
self.task.update(
{
"config": params[0],
@@ -526,6 +540,7 @@ class _StartGenerationConnection:
"duplicate_count": 0,
"error_count": 0,
"generation_run_id": params[2],
"results_confirmed": False,
"updated_at": params[3],
}
)
@@ -713,6 +728,7 @@ def test_start_generation_clears_previous_output_count() -> None:
assert task["status"] == "running"
assert task["output_count"] == 0
assert task["results_confirmed"] is False
assert conn.results == []
@@ -737,6 +753,7 @@ def test_prepared_published_task_survives_generation_preflight_failure() -> None
assert conn.task["status"] == "completed"
assert conn.task["output_dataset_id"] == "dataset_train"
assert conn.task["output_count"] == 28
assert conn.task["results_confirmed"] is True
assert "_regeneration_prepared" in conn.task["config"]
assert conn.results == [{"id": "old-result"}]
@@ -752,6 +769,7 @@ def test_legacy_aborted_regeneration_recovers_results_and_published_state() -> N
assert conn.task["progress"] == 100
assert conn.task["output_dataset_id"] == "dataset_train"
assert conn.task["output_count"] == 2
assert conn.task["workflow_step"] == "results"
assert conn.task["started_at"] is None
assert conn.task["completed_at"] is None
assert [item["id"] for item in conn.results] == ["result_train", "result_test"]
@@ -1185,3 +1203,96 @@ def test_source_storage_descriptor_rejects_unowned_or_unsupported_references(
"dpt_task",
"dpsf_source",
)
class _LifecycleConnection:
def __init__(self) -> None:
self.task: dict[str, Any] = {
"id": "task-lifecycle",
"status": "running",
"generation_run_id": "generation-active",
"workflow_step": "generate",
"preview_status": "running",
"preview_progress": Decimal("40.00"),
"preview_run_id": "preview-active",
"preview_failure_reason": None,
"preview_total_files": 5,
"preview_completed_files": 2,
"deleted_at": None,
"deleted_by": None,
}
self.last_update_sql = ""
def execute(self, sql: str, params: Any = None) -> _Result:
normalized = " ".join(sql.split())
if params is not None:
assert normalized.count("%s") == len(params)
if normalized.startswith("SELECT * FROM data_process_tasks"):
row = None if self.task["deleted_at"] is not None else dict(self.task)
return _Result(row=row)
if normalized.startswith("UPDATE data_process_tasks SET workflow_step="):
self.last_update_sql = normalized
workflow_step, updated_at, task_id = params
assert task_id == self.task["id"]
self.task.update(workflow_step=workflow_step, updated_at=updated_at)
return _Result(row=dict(self.task))
if normalized.startswith("UPDATE data_process_tasks SET status=CASE"):
self.last_update_sql = normalized
deleted_at, deleted_by, updated_at, task_id = params
assert task_id == self.task["id"]
self.task.update(
status="stopped",
generation_run_id=None,
preview_status="cancelled",
preview_run_id=None,
deleted_at=deleted_at,
deleted_by=deleted_by,
updated_at=updated_at,
)
return _Result()
if normalized.startswith("SELECT status, generation_run_id"):
row = None if self.task["deleted_at"] is not None else dict(self.task)
return _Result(row=row)
if normalized.startswith("SELECT preview_status, preview_run_id"):
row = None if self.task["deleted_at"] is not None else dict(self.task)
return _Result(row=row)
raise AssertionError(f"unexpected SQL: {normalized}")
class _LifecycleStore(DataProcessStore):
def __init__(self, conn: _LifecycleConnection) -> None:
self._conn = conn
@contextmanager
def connect(self) -> Iterator[_LifecycleConnection]:
yield self._conn
def test_workflow_step_update_does_not_invalidate_active_runs() -> None:
conn = _LifecycleConnection()
task = _LifecycleStore(conn).update_workflow_step("task-lifecycle", "results")
assert task["workflow_step"] == "results"
assert task["status"] == "running"
assert task["generation_run_id"] == "generation-active"
assert task["preview_status"] == "running"
assert task["preview_run_id"] == "preview-active"
assert "generation_run_id" not in conn.last_update_sql
assert "preview_run_id" not in conn.last_update_sql
def test_delete_atomically_invalidates_generation_and_preview_runs() -> None:
conn = _LifecycleConnection()
store = _LifecycleStore(conn)
store.delete_task("task-lifecycle", deleted_by="user-1")
assert conn.task["status"] == "stopped"
assert conn.task["generation_run_id"] is None
assert conn.task["preview_status"] == "cancelled"
assert conn.task["preview_run_id"] is None
assert conn.task["deleted_by"] == "user-1"
assert conn.task["deleted_at"] is not None
assert store.generation_is_running("task-lifecycle", "generation-active") is False
assert store.preview_is_running("task-lifecycle", "preview-active") is False

View File

@@ -328,6 +328,57 @@ final result: blocked
---
# Failed Result Regeneration Design QA
## Evidence
- Source visual truth: `/var/folders/nk/yks07zp14wb4rv3jqq0pt_4h0000gn/T/codex-clipboard-0c2e6f90-aaac-4817-9084-bc31496aed0a.png`.
- Implementation route: `http://localhost:16801/data-process/:id/workflow`, step 6.
- Browser evidence: `/Users/caoxiaozhu/.codex/visualizations/2026/07/27/019fa277-626b-76a1-af02-48948d66c7ec/data-process-empty-list.png`.
- Viewport: 1280 × 720.
- Target state: a completed task on step 6 with a selected invalid result.
- Available browser state: authenticated data-process list with zero tasks; no representative invalid result could be opened without creating or mutating local business data.
## Static and automated evidence
- Invalid results render a primary plain `重新生成` button in the right side of the result header.
- Valid results keep the existing `恢复生成结果` action.
- While regeneration is running, the selected row shows a spinner, the button shows loading, editors are disabled, and the footer confirmation action is disabled.
- A successful response replaces only the selected row in place; a failed second generation leaves the original invalid row untouched.
- `regression-data-process-wizard.mjs`: passed.
- `regression-data-process-detail.mjs`: passed.
- `regression-data-process-list.mjs`: passed.
- `vue-tsc -b --noEmit`: passed.
- Relevant backend tests: 97 passed, with one third-party deprecation warning.
## Required fidelity surfaces
- Typography and hierarchy: the action uses the existing Element Plus small-button hierarchy and remains secondary to result content.
- Spacing and layout rhythm: the action is placed in the existing flex header's right action slot, matching the source location.
- Colors and tokens: the action uses the existing product primary color and existing Font Awesome refresh icon.
- Copy and content: the visible label is exactly `重新生成`; only server-saved invalid results expose it.
- Interaction: optimistic concurrency protects against overwriting a newer edit, and persistence happens only after the replacement passes generation and quality validation.
## Findings
- [P2] Representative rendered comparison unavailable
Location: step 6 result header with an invalid result selected.
Evidence: the authenticated local database currently contains zero data-processing tasks, so the target state cannot be reached without creating test business data or invoking the configured model.
Impact: automated and static checks prove the contract and placement, but cannot prove pixel-level spacing against the supplied screenshot.
Fix: open any existing failed result after one is available, capture the same 1280 × 720 state, and compare it side by side with the source screenshot.
## Comparison history
### Iteration 1 — blocked
- Source screenshot was inspected and the implementation was aligned to its existing right-header action slot.
- Local login and list navigation succeeded.
- The target result state was unavailable because the local task list was empty.
final result: blocked
---
# Dataset Version Actions Design QA
## Evidence

View File

@@ -1 +1 @@
import{d as C,bf as g,D as E,H as O,o as _,e as B,s as D,Z as $,w as A,c as I,aL as K,q as t,n as v,aa as r,g as q,bg as M,y as u,z as N,P as k}from"./index-CGB0A5x_.js";import{_ as R}from"./_plugin-vue_export-helper-DlAUqK2U.js";const V={class:"app-confirm-header"},z={class:"app-confirm-heading"},H={class:"app-confirm-icon","aria-hidden":"true"},L={class:"app-confirm-body"},P={class:"app-confirm-actions"},S=C({__name:"AppConfirmDialog",setup(j,{expose:x}){const c=u(!1),m=u(),p=u(),d=`app-confirm-title-${g()}`,y=`app-confirm-message-${g()}`,n=N({title:"请确认操作",message:"",confirmText:"确定",cancelText:"取消",tone:"warning",closeOnOverlay:!1});let o=null,i=null;function s(a){c.value=!1;const e=o;o=null,e==null||e(a)}function h(a){return o&&s(!1),Object.assign(n,{confirmText:"确定",cancelText:"取消",tone:"warning",closeOnOverlay:!1,...a}),c.value=!0,new Promise(e=>{o=e})}function w(){n.closeOnOverlay&&s(!1)}function T(a){var b;if(a.key==="Escape"){a.preventDefault(),s(!1);return}if(a.key!=="Tab")return;const e=Array.from(((b=m.value)==null?void 0:b.querySelectorAll("button:not([disabled])"))??[]),l=e[0],f=e[e.length-1];!l||!f||(a.shiftKey&&document.activeElement===l?(a.preventDefault(),f.focus()):!a.shiftKey&&document.activeElement===f&&(a.preventDefault(),l.focus()))}return E(c,async a=>{var e;if(a){i=document.activeElement instanceof HTMLElement?document.activeElement:null,await k(),(e=p.value)==null||e.focus();return}await k(),i==null||i.focus(),i=null}),O(()=>{o==null||o(!1),o=null}),x({open:h}),(a,e)=>(_(),B(M,{to:"body"},[D($,{name:"app-confirm"},{default:A(()=>[c.value?(_(),I("div",{key:0,class:"app-confirm-overlay",onMousedown:K(w,["self"])},[t("section",{ref_key:"dialogRef",ref:m,class:v(["app-confirm-dialog",`is-${n.tone}`]),role:"alertdialog","aria-modal":!0,"aria-labelledby":d,"aria-describedby":y,onKeydown:T},[t("header",V,[t("div",z,[t("span",H,[t("i",{class:v(n.tone==="primary"?"fa fa-question-circle":"fa fa-exclamation-triangle")},null,2)]),t("h2",{id:d},r(n.title),1)]),t("button",{class:"app-confirm-close",type:"button","aria-label":"关闭确认弹窗",onClick:e[0]||(e[0]=l=>s(!1))},[...e[3]||(e[3]=[t("i",{class:"fa fa-times","aria-hidden":"true"},null,-1)])])]),t("div",L,[t("p",{id:y},r(n.message),1)]),t("footer",P,[t("button",{ref_key:"cancelButtonRef",ref:p,class:"app-confirm-button is-cancel",type:"button",onClick:e[1]||(e[1]=l=>s(!1))},r(n.cancelText),513),t("button",{class:"app-confirm-button is-confirm",type:"button",onClick:e[2]||(e[2]=l=>s(!0))},r(n.confirmText),1)])],34)],32)):q("",!0)]),_:1})]))}}),G=R(S,[["__scopeId","data-v-8d3bf6ad"]]);export{G as A};
import{d as C,bf as g,D as E,H as O,o as _,e as B,s as D,Z as $,w as A,c as I,aL as K,q as t,n as v,aa as r,g as q,bg as M,y as u,z as N,P as k}from"./index-Dd84m4NL.js";import{_ as R}from"./_plugin-vue_export-helper-DlAUqK2U.js";const V={class:"app-confirm-header"},z={class:"app-confirm-heading"},H={class:"app-confirm-icon","aria-hidden":"true"},L={class:"app-confirm-body"},P={class:"app-confirm-actions"},S=C({__name:"AppConfirmDialog",setup(j,{expose:x}){const c=u(!1),m=u(),p=u(),d=`app-confirm-title-${g()}`,y=`app-confirm-message-${g()}`,n=N({title:"请确认操作",message:"",confirmText:"确定",cancelText:"取消",tone:"warning",closeOnOverlay:!1});let o=null,i=null;function s(a){c.value=!1;const e=o;o=null,e==null||e(a)}function h(a){return o&&s(!1),Object.assign(n,{confirmText:"确定",cancelText:"取消",tone:"warning",closeOnOverlay:!1,...a}),c.value=!0,new Promise(e=>{o=e})}function w(){n.closeOnOverlay&&s(!1)}function T(a){var b;if(a.key==="Escape"){a.preventDefault(),s(!1);return}if(a.key!=="Tab")return;const e=Array.from(((b=m.value)==null?void 0:b.querySelectorAll("button:not([disabled])"))??[]),l=e[0],f=e[e.length-1];!l||!f||(a.shiftKey&&document.activeElement===l?(a.preventDefault(),f.focus()):!a.shiftKey&&document.activeElement===f&&(a.preventDefault(),l.focus()))}return E(c,async a=>{var e;if(a){i=document.activeElement instanceof HTMLElement?document.activeElement:null,await k(),(e=p.value)==null||e.focus();return}await k(),i==null||i.focus(),i=null}),O(()=>{o==null||o(!1),o=null}),x({open:h}),(a,e)=>(_(),B(M,{to:"body"},[D($,{name:"app-confirm"},{default:A(()=>[c.value?(_(),I("div",{key:0,class:"app-confirm-overlay",onMousedown:K(w,["self"])},[t("section",{ref_key:"dialogRef",ref:m,class:v(["app-confirm-dialog",`is-${n.tone}`]),role:"alertdialog","aria-modal":!0,"aria-labelledby":d,"aria-describedby":y,onKeydown:T},[t("header",V,[t("div",z,[t("span",H,[t("i",{class:v(n.tone==="primary"?"fa fa-question-circle":"fa fa-exclamation-triangle")},null,2)]),t("h2",{id:d},r(n.title),1)]),t("button",{class:"app-confirm-close",type:"button","aria-label":"关闭确认弹窗",onClick:e[0]||(e[0]=l=>s(!1))},[...e[3]||(e[3]=[t("i",{class:"fa fa-times","aria-hidden":"true"},null,-1)])])]),t("div",L,[t("p",{id:y},r(n.message),1)]),t("footer",P,[t("button",{ref_key:"cancelButtonRef",ref:p,class:"app-confirm-button is-cancel",type:"button",onClick:e[1]||(e[1]=l=>s(!1))},r(n.cancelText),513),t("button",{class:"app-confirm-button is-confirm",type:"button",onClick:e[2]||(e[2]=l=>s(!0))},r(n.confirmText),1)])],34)],32)):q("",!0)]),_:1})]))}}),G=R(S,[["__scopeId","data-v-8d3bf6ad"]]);export{G as A};

View File

@@ -1 +1 @@
import{a as B,E as K}from"./el-form-item-Ct_zBuY0.js";import{E as M}from"./index-CbmPSBt0.js";import{E as h}from"./index-CCavIuTY.js";import{E as I}from"./el-tag-C_D80BPW.js";import{E as R}from"./el-divider-DF2VMDw-.js";import{E as F}from"./el-slider-CM3VEvCM.js";import{d as L,G as z,e as V,w as s,ac as D,y as $,o as f,s as a,x as p,q as j,c as k,ad as A,aa as b,f as E,M as G,g as J,v as O,z as H,j as _,A as P}from"./index-CGB0A5x_.js";import"./el-popper-DvBtRO32.js";import"./el-tooltip-l0sNRNKZ.js";import"./el-input-number-VAjRO6-I.js";import{P as Q}from"./PageCard-D1lOaeEG.js";import{u as W}from"./usePolling-B4Zfd6BY.js";import{a as X}from"./compare-ClXsFp7Q.js";import{a as Y}from"./status-Dl1fykxa.js";import{_ as Z}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./index-DMVRI44M.js";import"./debounce-Bqww2DS8.js";import"./toNumber-IRhFg6gN.js";import"./clamp-BqqU4KQ-.js";import"./index-BPwPlcbL.js";import"./index-CL2S8yHq.js";import"./el-card-BWcR1iD2.js";const tt={class:"model-list"},et={key:0,class:"empty-hint"},ot=L({__name:"CompareChatView",setup(at){const T=D(),y=O(),x=T.params.id,n=$(null),e=H({systemPrompt:"",question:"",temperature:.7,topP:.9,topK:40,maxTokens:2048}),m=_(()=>{var l;if(!((l=n.value)!=null&&l.load_status))return[];try{return(typeof n.value.load_status=="string"?JSON.parse(n.value.load_status):n.value.load_status).loaded_models||[]}catch{return[]}}),C=_(()=>m.value.length>0&&m.value.every(l=>l.status==="ready"||l.status==="running")),g=_(()=>m.value.some(l=>l.status==="starting"));async function c(){try{n.value=await X(x)}catch{}}function S(){var u,i;if(!e.question.trim()){P.warning("请输入问题");return}if(g.value){P.warning("模型仍在启动中,请稍候");return}const l=new URLSearchParams({taskId:x,taskName:((u=n.value)==null?void 0:u.model_name)||((i=n.value)==null?void 0:i.name)||"",question:e.question,systemPrompt:e.systemPrompt,temperature:String(e.temperature),topP:String(e.topP),topK:String(e.topK),maxTokens:String(e.maxTokens)}),t=y.resolve(`/model-compare/result?${l.toString()}`).href;window.open(t,"_blank")}const{start:q}=W(c,5e3,{immediate:!1});return z(async()=>{await c(),q()}),(l,t)=>{const u=R,i=I,v=M,r=B,d=F,w=h,U=K;return f(),V(Q,{title:"模型对比配置"},{default:s(()=>[a(u,{"content-position":"left"},{default:s(()=>[...t[7]||(t[7]=[p("已启动模型",-1)])]),_:1}),j("div",tt,[(f(!0),k(G,null,A(m.value,(o,N)=>(f(),V(i,{key:N,type:o.status==="ready"||o.status==="running"?"success":o.status==="starting"?"warning":"danger",size:"large"},{default:s(()=>[p(b(o.model_name)+" ("+b(E(Y)(o.status))+") ",1)]),_:2},1032,["type"]))),128)),m.value.length?J("",!0):(f(),k("span",et,"暂无已启动模型"))]),a(u,{"content-position":"left"},{default:s(()=>[...t[8]||(t[8]=[p("对话配置",-1)])]),_:1}),a(U,{"label-width":"120px",style:{"max-width":"700px"}},{default:s(()=>[a(r,{label:"系统提示词"},{default:s(()=>[a(v,{modelValue:e.systemPrompt,"onUpdate:modelValue":t[0]||(t[0]=o=>e.systemPrompt=o),type:"textarea",rows:3,placeholder:"可选"},null,8,["modelValue"])]),_:1}),a(r,{label:"问题"},{default:s(()=>[a(v,{modelValue:e.question,"onUpdate:modelValue":t[1]||(t[1]=o=>e.question=o),type:"textarea",rows:4,placeholder:"请输入要对比的问题"},null,8,["modelValue"])]),_:1}),a(r,{label:"Temperature"},{default:s(()=>[a(d,{modelValue:e.temperature,"onUpdate:modelValue":t[2]||(t[2]=o=>e.temperature=o),min:0,max:2,step:.1,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,{label:"Top-p"},{default:s(()=>[a(d,{modelValue:e.topP,"onUpdate:modelValue":t[3]||(t[3]=o=>e.topP=o),min:0,max:1,step:.05,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,{label:"Top-k"},{default:s(()=>[a(d,{modelValue:e.topK,"onUpdate:modelValue":t[4]||(t[4]=o=>e.topK=o),min:1,max:100,step:1,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,{label:"Max Tokens"},{default:s(()=>[a(d,{modelValue:e.maxTokens,"onUpdate:modelValue":t[5]||(t[5]=o=>e.maxTokens=o),min:256,max:4096,step:128,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,null,{default:s(()=>[a(w,{type:"primary",disabled:!C.value||g.value,onClick:S},{default:s(()=>[...t[9]||(t[9]=[p(" 开始对比 ",-1)])]),_:1},8,["disabled"]),a(w,{onClick:t[6]||(t[6]=o=>E(y).back())},{default:s(()=>[...t[10]||(t[10]=[p("返回",-1)])]),_:1})]),_:1})]),_:1})]),_:1})}}}),Ut=Z(ot,[["__scopeId","data-v-fbe74cb0"]]);export{Ut as default};
import{a as B,E as K}from"./el-form-item-BMccCMQS.js";import{E as M}from"./index-CxrDRhwR.js";import{E as h}from"./index-9zpOHVFd.js";import{E as I}from"./el-tag-DPsbND_Z.js";import{E as R}from"./el-divider-Y9JqUYBG.js";import{E as F}from"./el-slider-zfFAQg0d.js";import{d as L,G as z,e as V,w as s,ac as D,y as $,o as f,s as a,x as p,q as j,c as k,ad as A,aa as b,f as E,M as G,g as J,v as O,z as H,j as _,A as P}from"./index-Dd84m4NL.js";import"./el-popper-CXiDZrHI.js";import"./el-tooltip-l0sNRNKZ.js";import"./el-input-number-CLGVcD2n.js";import{P as Q}from"./PageCard-Bj5UBPkt.js";import{u as W}from"./usePolling-DY3PpJx-.js";import{a as X}from"./compare-xeHnYdLV.js";import{a as Y}from"./status-Dl1fykxa.js";import{_ as Z}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./index-DEuQ2B0Z.js";import"./debounce-CqM0EiuE.js";import"./toNumber-Dzu6kJGs.js";import"./clamp-MxoDdpzk.js";import"./index-KnEmF0FL.js";import"./index-CrQUvw33.js";import"./el-card-WMAJU1WK.js";const tt={class:"model-list"},et={key:0,class:"empty-hint"},ot=L({__name:"CompareChatView",setup(at){const T=D(),y=O(),x=T.params.id,n=$(null),e=H({systemPrompt:"",question:"",temperature:.7,topP:.9,topK:40,maxTokens:2048}),m=_(()=>{var l;if(!((l=n.value)!=null&&l.load_status))return[];try{return(typeof n.value.load_status=="string"?JSON.parse(n.value.load_status):n.value.load_status).loaded_models||[]}catch{return[]}}),C=_(()=>m.value.length>0&&m.value.every(l=>l.status==="ready"||l.status==="running")),g=_(()=>m.value.some(l=>l.status==="starting"));async function c(){try{n.value=await X(x)}catch{}}function S(){var u,i;if(!e.question.trim()){P.warning("请输入问题");return}if(g.value){P.warning("模型仍在启动中,请稍候");return}const l=new URLSearchParams({taskId:x,taskName:((u=n.value)==null?void 0:u.model_name)||((i=n.value)==null?void 0:i.name)||"",question:e.question,systemPrompt:e.systemPrompt,temperature:String(e.temperature),topP:String(e.topP),topK:String(e.topK),maxTokens:String(e.maxTokens)}),t=y.resolve(`/model-compare/result?${l.toString()}`).href;window.open(t,"_blank")}const{start:q}=W(c,5e3,{immediate:!1});return z(async()=>{await c(),q()}),(l,t)=>{const u=R,i=I,v=M,r=B,d=F,w=h,U=K;return f(),V(Q,{title:"模型对比配置"},{default:s(()=>[a(u,{"content-position":"left"},{default:s(()=>[...t[7]||(t[7]=[p("已启动模型",-1)])]),_:1}),j("div",tt,[(f(!0),k(G,null,A(m.value,(o,N)=>(f(),V(i,{key:N,type:o.status==="ready"||o.status==="running"?"success":o.status==="starting"?"warning":"danger",size:"large"},{default:s(()=>[p(b(o.model_name)+" ("+b(E(Y)(o.status))+") ",1)]),_:2},1032,["type"]))),128)),m.value.length?J("",!0):(f(),k("span",et,"暂无已启动模型"))]),a(u,{"content-position":"left"},{default:s(()=>[...t[8]||(t[8]=[p("对话配置",-1)])]),_:1}),a(U,{"label-width":"120px",style:{"max-width":"700px"}},{default:s(()=>[a(r,{label:"系统提示词"},{default:s(()=>[a(v,{modelValue:e.systemPrompt,"onUpdate:modelValue":t[0]||(t[0]=o=>e.systemPrompt=o),type:"textarea",rows:3,placeholder:"可选"},null,8,["modelValue"])]),_:1}),a(r,{label:"问题"},{default:s(()=>[a(v,{modelValue:e.question,"onUpdate:modelValue":t[1]||(t[1]=o=>e.question=o),type:"textarea",rows:4,placeholder:"请输入要对比的问题"},null,8,["modelValue"])]),_:1}),a(r,{label:"Temperature"},{default:s(()=>[a(d,{modelValue:e.temperature,"onUpdate:modelValue":t[2]||(t[2]=o=>e.temperature=o),min:0,max:2,step:.1,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,{label:"Top-p"},{default:s(()=>[a(d,{modelValue:e.topP,"onUpdate:modelValue":t[3]||(t[3]=o=>e.topP=o),min:0,max:1,step:.05,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,{label:"Top-k"},{default:s(()=>[a(d,{modelValue:e.topK,"onUpdate:modelValue":t[4]||(t[4]=o=>e.topK=o),min:1,max:100,step:1,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,{label:"Max Tokens"},{default:s(()=>[a(d,{modelValue:e.maxTokens,"onUpdate:modelValue":t[5]||(t[5]=o=>e.maxTokens=o),min:256,max:4096,step:128,"show-input":"",style:{"max-width":"500px"}},null,8,["modelValue"])]),_:1}),a(r,null,{default:s(()=>[a(w,{type:"primary",disabled:!C.value||g.value,onClick:S},{default:s(()=>[...t[9]||(t[9]=[p(" 开始对比 ",-1)])]),_:1},8,["disabled"]),a(w,{onClick:t[6]||(t[6]=o=>E(y).back())},{default:s(()=>[...t[10]||(t[10]=[p("返回",-1)])]),_:1})]),_:1})]),_:1})]),_:1})}}}),Ut=Z(ot,[["__scopeId","data-v-fbe74cb0"]]);export{Ut as default};

View File

@@ -1 +1 @@
import{E as D}from"./el-alert-DBfM1mZE.js";import{E as $}from"./index-CCavIuTY.js";import{E as z}from"./el-tag-C_D80BPW.js";import{E as F}from"./el-card-BWcR1iD2.js";import{d as O,G as U,H as J,c as d,q as i,aa as c,f as v,s as N,w as m,M as K,ad as A,ac as G,y as g,o as r,x as p,e as y,g as H}from"./index-CGB0A5x_.js";import{_ as L}from"./MarkdownView.vue_vue_type_style_index_0_lang-DqO2Wm8-.js";import{a as W,c as j}from"./compare-ClXsFp7Q.js";import{_ as Q}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./vnode-DFpZw5lG.js";const X={class:"compare-result"},Y={class:"result-header"},Z={class:"header-actions"},tt={class:"result-grid"},et={class:"card-header"},st={class:"model-name"},ot={key:0,class:"error-text"},at={key:1,class:"streaming-text"},nt={key:3,class:"loading-text"},lt={key:4,class:"result-stats"},rt=O({__name:"CompareResultView",setup(it){const u=G(),q=u.query.taskId,k=decodeURIComponent(u.query.question||""),h=decodeURIComponent(u.query.systemPrompt||""),E=Number(u.query.temperature||.7),P=Number(u.query.topP||.9),I=Number(u.query.topK||40),b=Number(u.query.maxTokens||2048),w=u.query.taskName,l=g([]),C=g(!1),x=g([]),f=new Set;async function B(){if(!C.value){C.value=!0;try{const s=await W(q);let t=[];s.load_status&&(t=(typeof s.load_status=="string"?JSON.parse(s.load_status):s.load_status).loaded_models||[]),x.value=t,l.value=t.map(o=>({name:o.model_name||"模型",content:"",displayContent:"",isTyping:!1,status:"loading"})),await Promise.all(t.map((o,e)=>S(o,e)))}catch{}}}async function S(s,t){const o=Date.now();try{const e=await V(j({port:s.port,model_name:s.model_name,messages:[...h?[{role:"system",content:h}]:[],{role:"user",content:k}],temperature:E,top_p:P,top_k:I,max_tokens:b}),3e5),a=(e==null?void 0:e.response)||(e==null?void 0:e.content)||(e==null?void 0:e.data)||JSON.stringify(e),_=(Date.now()-o)/1e3;l.value[t].content=a,l.value[t].status="done",l.value[t].stats={totalTime:_,charsPerSec:_>0?Number((a.length/_).toFixed(1)):0},M(t,a)}catch(e){l.value[t].content="推理失败: "+(e.message||""),l.value[t].status="error"}}async function V(s,t){let o=null;try{return await Promise.race([s,new Promise((e,a)=>{o=setTimeout(()=>a(new Error("推理超时")),t)})])}finally{o&&clearTimeout(o)}}function M(s,t){let o=0;l.value[s].isTyping=!0;const e=Math.max(2,Math.ceil(t.length/30)),a=setInterval(()=>{o+=e,l.value[s].displayContent=t.slice(0,o),o>=t.length&&(clearInterval(a),f.delete(a),l.value[s].displayContent=t,l.value[s].isTyping=!1)},50);f.add(a)}return U(B),J(()=>{f.forEach(clearInterval),f.clear()}),(s,t)=>{const o=$,e=D,a=z,_=F;return r(),d("div",X,[i("div",Y,[i("h2",null,"对比结果"+c(v(w)?` - ${v(w)}`:""),1),i("div",Z,[N(o,{onClick:t[0]||(t[0]=n=>s.$router.push("/model-inference"))},{default:m(()=>[...t[1]||(t[1]=[p("返回列表",-1)])]),_:1})])]),N(e,{type:"info",closable:!1,"show-icon":"",class:"question-box"},{title:m(()=>[t[2]||(t[2]=i("strong",null,"问题:",-1)),p(c(v(k)),1)]),_:1}),i("div",tt,[(r(!0),d(K,null,A(l.value,(n,R)=>(r(),y(_,{key:R,shadow:"hover",class:"result-card"},{header:m(()=>[i("div",et,[i("span",st,c(n.name),1),n.status==="loading"?(r(),y(a,{key:0,type:"warning",size:"small"},{default:m(()=>[...t[3]||(t[3]=[p("生成中...",-1)])]),_:1})):n.status==="done"?(r(),y(a,{key:1,type:"success",size:"small"},{default:m(()=>[...t[4]||(t[4]=[p("完成",-1)])]),_:1})):(r(),y(a,{key:2,type:"danger",size:"small"},{default:m(()=>[...t[5]||(t[5]=[p("失败",-1)])]),_:1}))])]),default:m(()=>{var T;return[n.status==="error"?(r(),d("div",ot,c(n.content),1)):n.isTyping?(r(),d("div",at,c(n.displayContent),1)):n.displayContent?(r(),y(L,{key:2,content:n.displayContent},null,8,["content"])):(r(),d("div",nt,[...t[6]||(t[6]=[i("i",{class:"fa fa-spinner fa-spin"},null,-1),p(" 正在生成回答... ",-1)])])),n.stats?(r(),d("div",lt,[i("span",null,"耗时 "+c((T=n.stats.totalTime)==null?void 0:T.toFixed(1))+"s",1),i("span",null,"速度 "+c(n.stats.charsPerSec)+" 字/秒",1)])):H("",!0)]}),_:2},1024))),128))])])}}}),gt=Q(rt,[["__scopeId","data-v-8391f389"]]);export{gt as default};
import{E as D}from"./el-alert-B_M4eVTG.js";import{E as $}from"./index-9zpOHVFd.js";import{E as z}from"./el-tag-DPsbND_Z.js";import{E as F}from"./el-card-WMAJU1WK.js";import{d as O,G as U,H as J,c as d,q as i,aa as c,f as v,s as N,w as m,M as K,ad as A,ac as G,y as g,o as r,x as p,e as y,g as H}from"./index-Dd84m4NL.js";import{_ as L}from"./MarkdownView.vue_vue_type_style_index_0_lang-AsgI6XQ4.js";import{a as W,c as j}from"./compare-xeHnYdLV.js";import{_ as Q}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./vnode-CasYkit1.js";const X={class:"compare-result"},Y={class:"result-header"},Z={class:"header-actions"},tt={class:"result-grid"},et={class:"card-header"},st={class:"model-name"},ot={key:0,class:"error-text"},at={key:1,class:"streaming-text"},nt={key:3,class:"loading-text"},lt={key:4,class:"result-stats"},rt=O({__name:"CompareResultView",setup(it){const u=G(),q=u.query.taskId,k=decodeURIComponent(u.query.question||""),h=decodeURIComponent(u.query.systemPrompt||""),E=Number(u.query.temperature||.7),P=Number(u.query.topP||.9),I=Number(u.query.topK||40),b=Number(u.query.maxTokens||2048),w=u.query.taskName,l=g([]),C=g(!1),x=g([]),f=new Set;async function B(){if(!C.value){C.value=!0;try{const s=await W(q);let t=[];s.load_status&&(t=(typeof s.load_status=="string"?JSON.parse(s.load_status):s.load_status).loaded_models||[]),x.value=t,l.value=t.map(o=>({name:o.model_name||"模型",content:"",displayContent:"",isTyping:!1,status:"loading"})),await Promise.all(t.map((o,e)=>S(o,e)))}catch{}}}async function S(s,t){const o=Date.now();try{const e=await V(j({port:s.port,model_name:s.model_name,messages:[...h?[{role:"system",content:h}]:[],{role:"user",content:k}],temperature:E,top_p:P,top_k:I,max_tokens:b}),3e5),a=(e==null?void 0:e.response)||(e==null?void 0:e.content)||(e==null?void 0:e.data)||JSON.stringify(e),_=(Date.now()-o)/1e3;l.value[t].content=a,l.value[t].status="done",l.value[t].stats={totalTime:_,charsPerSec:_>0?Number((a.length/_).toFixed(1)):0},M(t,a)}catch(e){l.value[t].content="推理失败: "+(e.message||""),l.value[t].status="error"}}async function V(s,t){let o=null;try{return await Promise.race([s,new Promise((e,a)=>{o=setTimeout(()=>a(new Error("推理超时")),t)})])}finally{o&&clearTimeout(o)}}function M(s,t){let o=0;l.value[s].isTyping=!0;const e=Math.max(2,Math.ceil(t.length/30)),a=setInterval(()=>{o+=e,l.value[s].displayContent=t.slice(0,o),o>=t.length&&(clearInterval(a),f.delete(a),l.value[s].displayContent=t,l.value[s].isTyping=!1)},50);f.add(a)}return U(B),J(()=>{f.forEach(clearInterval),f.clear()}),(s,t)=>{const o=$,e=D,a=z,_=F;return r(),d("div",X,[i("div",Y,[i("h2",null,"对比结果"+c(v(w)?` - ${v(w)}`:""),1),i("div",Z,[N(o,{onClick:t[0]||(t[0]=n=>s.$router.push("/model-inference"))},{default:m(()=>[...t[1]||(t[1]=[p("返回列表",-1)])]),_:1})])]),N(e,{type:"info",closable:!1,"show-icon":"",class:"question-box"},{title:m(()=>[t[2]||(t[2]=i("strong",null,"问题:",-1)),p(c(v(k)),1)]),_:1}),i("div",tt,[(r(!0),d(K,null,A(l.value,(n,R)=>(r(),y(_,{key:R,shadow:"hover",class:"result-card"},{header:m(()=>[i("div",et,[i("span",st,c(n.name),1),n.status==="loading"?(r(),y(a,{key:0,type:"warning",size:"small"},{default:m(()=>[...t[3]||(t[3]=[p("生成中...",-1)])]),_:1})):n.status==="done"?(r(),y(a,{key:1,type:"success",size:"small"},{default:m(()=>[...t[4]||(t[4]=[p("完成",-1)])]),_:1})):(r(),y(a,{key:2,type:"danger",size:"small"},{default:m(()=>[...t[5]||(t[5]=[p("失败",-1)])]),_:1}))])]),default:m(()=>{var T;return[n.status==="error"?(r(),d("div",ot,c(n.content),1)):n.isTyping?(r(),d("div",at,c(n.displayContent),1)):n.displayContent?(r(),y(L,{key:2,content:n.displayContent},null,8,["content"])):(r(),d("div",nt,[...t[6]||(t[6]=[i("i",{class:"fa fa-spinner fa-spin"},null,-1),p(" 正在生成回答... ",-1)])])),n.stats?(r(),d("div",lt,[i("span",null,"耗时 "+c((T=n.stats.totalTime)==null?void 0:T.toFixed(1))+"s",1),i("span",null,"速度 "+c(n.stats.charsPerSec)+" 字/秒",1)])):H("",!0)]}),_:2},1024))),128))])])}}}),gt=Q(rt,[["__scopeId","data-v-8391f389"]]);export{gt as default};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{a as N,E as v}from"./el-form-item-Ct_zBuY0.js";import{E as b}from"./el-popper-DvBtRO32.js";import{E as O}from"./index-CbmPSBt0.js";import{E as S}from"./index-CCavIuTY.js";import{E as g,a as E}from"./el-select-C59URVI0.js";import{d as J,e as V,w as e,o as w,q as t,s as l,x as i,z as x,A as C}from"./index-CGB0A5x_.js";import"./el-tooltip-l0sNRNKZ.js";import"./el-scrollbar-p6_f_LH2.js";import"./el-tag-C_D80BPW.js";import{P as U}from"./PageCard-D1lOaeEG.js";import{_ as y}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./index-DMVRI44M.js";import"./index-BPwPlcbL.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./vnode-DFpZw5lG.js";import"./index-khuXz7sd.js";import"./scroll-C0BSy_Rk.js";import"./clamp-BqqU4KQ-.js";import"./toNumber-IRhFg6gN.js";import"./_baseIteratee-uVh0OyD5.js";import"./el-card-BWcR1iD2.js";const F={class:"converter-panel"},L={class:"form-row"},T={class:"panel-footer"},B={class:"actions"},k=J({__name:"DataConvertView",setup(I){const a=x({outputName:"converted-data",encoding:"UTF-8"});function p(){C.info("当前仅完成界面设计,转换功能将在后续接入")}function d(){Object.assign(a,{outputName:"converted-data",encoding:"UTF-8"})}return(j,o)=>{const n=N,m=O,u=E,f=g,c=v,r=S,_=b;return w(),V(U,{class:"data-convert-page",title:"数据类型转换",subtitle:"将 JSON 文件转换为便于训练和评测使用的 JSONL 格式"},{default:e(()=>[t("div",F,[o[9]||(o[9]=t("div",{class:"panel-header"},[t("div",{class:"tool-icon","aria-hidden":"true"},[t("i",{class:"fa fa-exchange"})]),t("div",null,[t("h3",null,"JSON 转 JSONL"),t("p",null,"每条 JSON 数据将输出为 JSONL 文件中的一行记录")])],-1)),l(c,{class:"converter-form","label-position":"top"},{default:e(()=>[l(n,{label:"转换类型"},{default:e(()=>[...o[2]||(o[2]=[t("div",{class:"format-field","aria-label":"JSON 转 JSONL"},[t("span",null,"JSON"),t("i",{class:"fa fa-long-arrow-right","aria-hidden":"true"}),t("span",null,"JSONL")],-1)])]),_:1}),l(n,{label:"源文件",required:""},{default:e(()=>[t("button",{class:"upload-zone",type:"button",onClick:p},[...o[3]||(o[3]=[t("i",{class:"fa fa-cloud-upload","aria-hidden":"true"},null,-1),t("span",{class:"upload-content"},[t("strong",null,"点击选择或拖拽 JSON 文件到此处"),t("small",null,"仅支持 .json 格式,单文件不超过 200 MB")],-1),t("span",{class:"select-button"},"选择文件",-1)])])]),_:1}),t("div",L,[l(n,{label:"输出文件名"},{default:e(()=>[l(m,{modelValue:a.outputName,"onUpdate:modelValue":o[0]||(o[0]=s=>a.outputName=s)},{append:e(()=>[...o[4]||(o[4]=[i(".jsonl",-1)])]),_:1},8,["modelValue"])]),_:1}),l(n,{label:"字符编码"},{default:e(()=>[l(f,{modelValue:a.encoding,"onUpdate:modelValue":o[1]||(o[1]=s=>a.encoding=s),style:{width:"100%"}},{default:e(()=>[l(u,{label:"UTF-8",value:"UTF-8"})]),_:1},8,["modelValue"])]),_:1})]),o[5]||(o[5]=t("div",{class:"format-tip"},[t("i",{class:"fa fa-info-circle","aria-hidden":"true"}),t("span",null,"支持由 JSON 数组转换为 JSONL每个数组元素输出为一行。")],-1))]),_:1}),t("div",T,[o[8]||(o[8]=t("span",{class:"prototype-label"},"当前为 UI 原型,暂不执行实际转换",-1)),t("div",B,[l(r,{onClick:d},{default:e(()=>[...o[6]||(o[6]=[i("重置",-1)])]),_:1}),l(_,{content:"转换功能将在后续开发中接入",placement:"top"},{default:e(()=>[t("span",null,[l(r,{type:"primary",disabled:""},{default:e(()=>[...o[7]||(o[7]=[i("开始转换",-1)])]),_:1})])]),_:1})])])])]),_:1})}}}),it=y(k,[["__scopeId","data-v-89a8493f"]]);export{it as default};
import{a as N,E as v}from"./el-form-item-BMccCMQS.js";import{E as b}from"./el-popper-CXiDZrHI.js";import{E as O}from"./index-CxrDRhwR.js";import{E as S}from"./index-9zpOHVFd.js";import{E as g,a as E}from"./el-select-DinjeS4W.js";import{d as J,e as V,w as e,o as w,q as t,s as l,x as i,z as x,A as C}from"./index-Dd84m4NL.js";import"./el-tooltip-l0sNRNKZ.js";import"./el-scrollbar-CnqWU4CY.js";import"./el-tag-DPsbND_Z.js";import{P as U}from"./PageCard-Bj5UBPkt.js";import{_ as y}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./index-DEuQ2B0Z.js";import"./index-KnEmF0FL.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./vnode-CasYkit1.js";import"./index-C5oiM9Uu.js";import"./scroll-CJw98M_S.js";import"./clamp-MxoDdpzk.js";import"./toNumber-Dzu6kJGs.js";import"./_baseIteratee-CfOSjoYo.js";import"./el-card-WMAJU1WK.js";const F={class:"converter-panel"},L={class:"form-row"},T={class:"panel-footer"},B={class:"actions"},k=J({__name:"DataConvertView",setup(I){const a=x({outputName:"converted-data",encoding:"UTF-8"});function p(){C.info("当前仅完成界面设计,转换功能将在后续接入")}function d(){Object.assign(a,{outputName:"converted-data",encoding:"UTF-8"})}return(j,o)=>{const n=N,m=O,u=E,f=g,c=v,r=S,_=b;return w(),V(U,{class:"data-convert-page",title:"数据类型转换",subtitle:"将 JSON 文件转换为便于训练和评测使用的 JSONL 格式"},{default:e(()=>[t("div",F,[o[9]||(o[9]=t("div",{class:"panel-header"},[t("div",{class:"tool-icon","aria-hidden":"true"},[t("i",{class:"fa fa-exchange"})]),t("div",null,[t("h3",null,"JSON 转 JSONL"),t("p",null,"每条 JSON 数据将输出为 JSONL 文件中的一行记录")])],-1)),l(c,{class:"converter-form","label-position":"top"},{default:e(()=>[l(n,{label:"转换类型"},{default:e(()=>[...o[2]||(o[2]=[t("div",{class:"format-field","aria-label":"JSON 转 JSONL"},[t("span",null,"JSON"),t("i",{class:"fa fa-long-arrow-right","aria-hidden":"true"}),t("span",null,"JSONL")],-1)])]),_:1}),l(n,{label:"源文件",required:""},{default:e(()=>[t("button",{class:"upload-zone",type:"button",onClick:p},[...o[3]||(o[3]=[t("i",{class:"fa fa-cloud-upload","aria-hidden":"true"},null,-1),t("span",{class:"upload-content"},[t("strong",null,"点击选择或拖拽 JSON 文件到此处"),t("small",null,"仅支持 .json 格式,单文件不超过 200 MB")],-1),t("span",{class:"select-button"},"选择文件",-1)])])]),_:1}),t("div",L,[l(n,{label:"输出文件名"},{default:e(()=>[l(m,{modelValue:a.outputName,"onUpdate:modelValue":o[0]||(o[0]=s=>a.outputName=s)},{append:e(()=>[...o[4]||(o[4]=[i(".jsonl",-1)])]),_:1},8,["modelValue"])]),_:1}),l(n,{label:"字符编码"},{default:e(()=>[l(f,{modelValue:a.encoding,"onUpdate:modelValue":o[1]||(o[1]=s=>a.encoding=s),style:{width:"100%"}},{default:e(()=>[l(u,{label:"UTF-8",value:"UTF-8"})]),_:1},8,["modelValue"])]),_:1})]),o[5]||(o[5]=t("div",{class:"format-tip"},[t("i",{class:"fa fa-info-circle","aria-hidden":"true"}),t("span",null,"支持由 JSON 数组转换为 JSONL每个数组元素输出为一行。")],-1))]),_:1}),t("div",T,[o[8]||(o[8]=t("span",{class:"prototype-label"},"当前为 UI 原型,暂不执行实际转换",-1)),t("div",B,[l(r,{onClick:d},{default:e(()=>[...o[6]||(o[6]=[i("重置",-1)])]),_:1}),l(_,{content:"转换功能将在后续开发中接入",placement:"top"},{default:e(()=>[t("span",null,[l(r,{type:"primary",disabled:""},{default:e(()=>[...o[7]||(o[7]=[i("开始转换",-1)])]),_:1})])]),_:1})])])])]),_:1})}}}),it=y(k,[["__scopeId","data-v-89a8493f"]]);export{it as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{E as z}from"./index-CCavIuTY.js";import{E as L}from"./el-tag-C_D80BPW.js";import{E as M}from"./el-table-DkdQ6gPU.js";import{d as P,G as V,c as h,s as o,w as s,y as c,o as d,q as f,x as n,f as b,aa as r,e as $,A as I,v as S}from"./index-CGB0A5x_.js";import{E as q}from"./index-BMrs0kLP.js";import"./el-checkbox-Ci1DH0Aj.js";import{D as A}from"./DataTablePage-CURtmoAI.js";import{g as F,d as G}from"./dataProcess-D7vRt2n_.js";import{d as v}from"./dataProcessStatus-BNY61_45.js";import{_ as R}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./el-scrollbar-p6_f_LH2.js";import"./index-DMVRI44M.js";import"./el-popper-DvBtRO32.js";import"./index-BPwPlcbL.js";import"./_baseClone-CX1E8HTZ.js";import"./_baseIteratee-uVh0OyD5.js";import"./castArray-Cgg396Sr.js";import"./debounce-Bqww2DS8.js";import"./toNumber-IRhFg6gN.js";import"./raf-CCivjDro.js";import"./validator-D7tSoy2w.js";import"./index-Coa9QRND.js";import"./clamp-BqqU4KQ-.js";import"./index-C5EKbiob.js";import"./scroll-C0BSy_Rk.js";import"./index-CbmPSBt0.js";import"./index-D2-3cnGo.js";import"./omit-DaFv1hTo.js";import"./el-card-BWcR1iD2.js";import"./el-pagination-DGQ0vO_O.js";import"./el-select-C59URVI0.js";import"./vnode-DFpZw5lG.js";import"./index-khuXz7sd.js";import"./directive-vzjADwzS.js";import"./el-tooltip-l0sNRNKZ.js";const j={class:"data-process-page",style:{height:"100%"}},H={key:1},J={class:"action-buttons"},K=P({__name:"DataProcessListView",setup(O){const x={structured:"结构化数据",unstructured:"非结构化数据",external:"外来数据源拉取"},k=S(),l=c([]),p=c(!1),m=c(null),u=c("");async function D(t=!1){t||(p.value=!0),u.value="";try{const a=await F({page:1,page_size:200});l.value=a.items}catch{u.value="数据处理任务加载失败,请稍后重试。"}finally{t||(p.value=!1)}}function C(t){const a=t.id;k.push({name:"data-process-detail",params:{id:a}})}async function E(t){try{await q.confirm(`确定删除数据处理任务“${t.name}”吗?删除后无法恢复。`,"确认删除",{type:"warning",confirmButtonText:"删除",cancelButtonText:"取消",confirmButtonClass:"el-button--danger"})}catch{return}m.value=t.id;try{await G(t.id),l.value=l.value.filter(a=>a.id!==t.id),I.success("数据处理任务已删除")}catch{}finally{m.value=null}}function T(t){if(!t)return"-";const a=new Date(t);return Number.isNaN(a.getTime())?t:a.toLocaleString("zh-CN",{hour12:!1})}function _(t){const a=Number(t);return Number.isFinite(a)?Math.max(0,Math.trunc(a)):0}function w(t){return`${_(t.source_file_count)}`}function B(t){return`${_(t.output_count)}`}return V(D),(t,a)=>{const i=M,g=L,y=z;return d(),h("div",j,[o(A,{title:"",data:l.value,loading:p.value,searchable:"","search-fields":["name"],"create-text":"新建数据处理","create-to":"/data-process/create","row-key":"id","page-size":10,"empty-text":u.value||"暂无数据处理任务"},{columns:s(()=>[o(i,{label:"任务ID",prop:"id",align:"center",width:"100"}),o(i,{label:"任务名称",prop:"name",align:"center","show-overflow-tooltip":""}),o(i,{label:"任务状态",align:"center",width:"110"},{default:s(({row:e})=>[o(g,{type:b(v)(e).type,size:"small",effect:"light"},{default:s(()=>[n(r(b(v)(e).label),1)]),_:2},1032,["type"])]),_:1}),o(i,{label:"处理类型",align:"center",width:"140"},{default:s(({row:e})=>[e.process_type?(d(),$(g,{key:0,size:"small",type:"info",effect:"plain"},{default:s(()=>[n(r(x[e.process_type]||e.process_type),1)]),_:2},1024)):(d(),h("span",H,"-"))]),_:1}),o(i,{label:"文档数量",align:"center",width:"120"},{default:s(({row:e})=>[n(r(w(e)),1)]),_:1}),o(i,{label:"生成个数",align:"center",width:"120"},{default:s(({row:e})=>[n(r(B(e)),1)]),_:1}),o(i,{label:"创建时间",align:"center",width:"190"},{default:s(({row:e})=>[n(r(T(e.create_time||e.created_at)),1)]),_:1})]),actions:s(({row:e})=>[f("div",J,[o(y,{type:"primary",link:"",size:"small",onClick:N=>C(e)},{default:s(()=>[...a[0]||(a[0]=[f("i",{class:"fa fa-file-text-o",style:{"margin-right":"4px"}},null,-1),n("详情 ",-1)])]),_:1},8,["onClick"]),o(y,{type:"danger",link:"",size:"small",loading:m.value===e.id,onClick:N=>E(e)},{default:s(()=>[...a[1]||(a[1]=[f("i",{class:"fa fa-trash-o",style:{"margin-right":"4px"}},null,-1),n("删除 ",-1)])]),_:1},8,["loading","onClick"])])]),_:1},8,["data","loading","empty-text"])])}}}),Nt=R(K,[["__scopeId","data-v-c2486738"]]);export{Nt as default};

View File

@@ -1 +0,0 @@
.action-buttons[data-v-c2486738]{display:flex;justify-content:center;gap:8px}

View File

@@ -0,0 +1 @@
.action-buttons[data-v-89c68dd6]{display:flex;justify-content:center;gap:8px}

View File

@@ -0,0 +1 @@
import{E as L}from"./index-9zpOHVFd.js";import{E as M}from"./el-tag-DPsbND_Z.js";import{E as V}from"./el-table-CknU6KUt.js";import{d as $,G as I,c as v,s,w as i,y as c,o as d,q as f,x as n,f as b,aa as l,e as S,A as q,v as A}from"./index-Dd84m4NL.js";import{E as F}from"./index-Czb9Dcel.js";import"./el-checkbox-DmCZOH3C.js";import{D as G}from"./DataTablePage-_dKtm0HL.js";import{g as R,d as j}from"./dataProcess-PWnIk5S8.js";import{u as H}from"./usePolling-DY3PpJx-.js";import{d as x}from"./dataProcessStatus-D3lSxyuc.js";import{_ as J}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./el-scrollbar-CnqWU4CY.js";import"./index-DEuQ2B0Z.js";import"./el-popper-CXiDZrHI.js";import"./index-KnEmF0FL.js";import"./_baseClone-C6YdWYHR.js";import"./_baseIteratee-CfOSjoYo.js";import"./castArray-Cc7cuNko.js";import"./debounce-CqM0EiuE.js";import"./toNumber-Dzu6kJGs.js";import"./raf-CGf5YZRu.js";import"./validator-BEv3fs9p.js";import"./index-BsIWQhw5.js";import"./clamp-MxoDdpzk.js";import"./index-B6n2yrjP.js";import"./scroll-CJw98M_S.js";import"./index-CxrDRhwR.js";import"./index-BkMrw1Qg.js";import"./omit-njl9pMBF.js";import"./el-card-WMAJU1WK.js";import"./el-pagination-CZfi7rql.js";import"./el-select-DinjeS4W.js";import"./vnode-CasYkit1.js";import"./index-C5oiM9Uu.js";import"./directive-CGqZKDhv.js";import"./el-tooltip-l0sNRNKZ.js";const K={class:"data-process-page",style:{height:"100%"}},O={key:1},Q={class:"action-buttons"},U=$({__name:"DataProcessListView",setup(W){const k={structured:"结构化数据",unstructured:"非结构化数据",external:"外来数据源拉取"},w=A(),r=c([]),p=c(!1),u=c(null),m=c("");async function _(t=!1){t||(p.value=!0),m.value="";try{const e=await R({page:1,page_size:200});r.value=e.items,r.value.some(o=>o.status==="running"||o.preview_status==="running"||o.preview_status==="queued")?B():P()}catch{m.value="数据处理任务加载失败,请稍后重试。"}finally{t||(p.value=!1)}}function D(t){const e=t,o=e.status==="completed"&&e.results_confirmed!==!1?"data-process-detail":"data-process-workflow";w.push({name:o,params:{id:e.id}})}async function C(t){try{await F.confirm(`确定删除数据处理任务“${t.name}”吗?删除后无法恢复。`,"确认删除",{type:"warning",confirmButtonText:"删除",cancelButtonText:"取消",confirmButtonClass:"el-button--danger"})}catch{return}u.value=t.id;try{await j(t.id),r.value=r.value.filter(e=>e.id!==t.id),q.success("数据处理任务已删除")}catch{}finally{u.value=null}}function E(t){if(!t)return"-";const e=new Date(t);return Number.isNaN(e.getTime())?t:e.toLocaleString("zh-CN",{hour12:!1})}function g(t){const e=Number(t);return Number.isFinite(e)?Math.max(0,Math.trunc(e)):0}function T(t){return`${g(t.source_file_count)}`}function N(t){return`${g(t.output_count)}`}const{start:B,stop:P}=H(()=>_(!0),3e3,{immediate:!1});return I(()=>void _()),(t,e)=>{const o=V,y=M,h=L;return d(),v("div",K,[s(G,{title:"",data:r.value,loading:p.value,searchable:"","search-fields":["name"],"create-text":"新建数据处理","create-to":"/data-process/create","row-key":"id","page-size":10,"empty-text":m.value||"暂无数据处理任务"},{columns:i(()=>[s(o,{label:"任务ID",prop:"id",align:"center",width:"100"}),s(o,{label:"任务名称",prop:"name",align:"center","show-overflow-tooltip":""}),s(o,{label:"任务状态",align:"center",width:"110"},{default:i(({row:a})=>[s(y,{type:b(x)(a).type,size:"small",effect:"light"},{default:i(()=>[n(l(b(x)(a).label),1)]),_:2},1032,["type"])]),_:1}),s(o,{label:"处理类型",align:"center",width:"140"},{default:i(({row:a})=>[a.process_type?(d(),S(y,{key:0,size:"small",type:"info",effect:"plain"},{default:i(()=>[n(l(k[a.process_type]||a.process_type),1)]),_:2},1024)):(d(),v("span",O,"-"))]),_:1}),s(o,{label:"文档数量",align:"center",width:"120"},{default:i(({row:a})=>[n(l(T(a)),1)]),_:1}),s(o,{label:"生成个数",align:"center",width:"120"},{default:i(({row:a})=>[n(l(N(a)),1)]),_:1}),s(o,{label:"创建时间",align:"center",width:"190"},{default:i(({row:a})=>[n(l(E(a.create_time||a.created_at)),1)]),_:1})]),actions:i(({row:a})=>[f("div",Q,[s(h,{type:"primary",link:"",size:"small",onClick:z=>D(a)},{default:i(()=>[...e[0]||(e[0]=[f("i",{class:"fa fa-file-text-o",style:{"margin-right":"4px"}},null,-1),n("详情 ",-1)])]),_:1},8,["onClick"]),s(h,{type:"danger",link:"",size:"small",loading:u.value===a.id,onClick:z=>C(a)},{default:i(()=>[...e[1]||(e[1]=[f("i",{class:"fa fa-trash-o",style:{"margin-right":"4px"}},null,-1),n("删除 ",-1)])]),_:1},8,["loading","onClick"])])]),_:1},8,["data","loading","empty-text"])])}}}),Mt=J(U,[["__scopeId","data-v-89c68dd6"]]);export{Mt as default};

View File

@@ -1 +0,0 @@
@charset "UTF-8";.data-table-page[data-v-19a2982f]{width:100%;height:100%;box-sizing:border-box;display:flex;flex-direction:column;min-height:0}.data-table-page .table-card[data-v-19a2982f]{margin-bottom:0;width:100%;flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.data-table-page .table-toolbar[data-v-19a2982f]{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;padding:0 12px;flex-wrap:wrap;gap:12px}.data-table-page .table-title[data-v-19a2982f]{font-size:18px;font-weight:600;color:#1e293b;margin:0;letter-spacing:-.3px}.data-table-page .toolbar-actions[data-v-19a2982f]{display:flex;align-items:center;gap:12px}.data-table-page .search-input[data-v-19a2982f]{width:280px}.data-table-page .search-input[data-v-19a2982f] .el-input__wrapper{border-radius:8px;box-shadow:0 0 0 1px #e2e8f0 inset;transition:all .2s}.data-table-page .search-input[data-v-19a2982f] .el-input__wrapper.is-focus{box-shadow:0 0 0 1px var(--primary-color) inset}.data-table-page .batch-bar[data-v-19a2982f]{display:flex;align-items:center;justify-content:space-between;background:#4f46e50d;border:1px solid rgba(79,70,229,.1);border-radius:8px;padding:10px 16px;margin:0 24px 16px}.data-table-page .batch-bar .batch-info[data-v-19a2982f]{font-size:13px;color:var(--primary-color)}.data-table-page .batch-bar .batch-info strong[data-v-19a2982f]{font-weight:600;margin:0 4px}.data-table-page .table-body[data-v-19a2982f]{flex:1;min-height:0}.data-table-page .table-pagination[data-v-19a2982f]{display:flex;justify-content:flex-end;align-items:center;padding:16px 24px;border-top:1px solid #f1f5f9}.data-table-page .table-pagination[data-v-19a2982f] .el-pagination{margin-top:0}.data-table-page[data-v-19a2982f] .el-card__body{display:flex;flex-direction:column;padding:12px 0 0;flex:1;min-height:0}.data-table-page[data-v-19a2982f] .el-table__inner-wrapper:before{display:none}.data-table-page[data-v-19a2982f] .el-table td.el-table__cell{padding:18px 0!important}.data-table-page[data-v-19a2982f] .el-table__cell .cell{line-height:22px;white-space:nowrap}.data-table-page[data-v-19a2982f] .el-table .action-buttons{display:flex;align-items:center;justify-content:center;flex-wrap:nowrap;gap:8px}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
@charset "UTF-8";.data-table-page[data-v-bda71432]{width:100%;height:100%;box-sizing:border-box;display:flex;flex-direction:column;min-height:0}.data-table-page .table-card[data-v-bda71432]{margin-bottom:0;width:100%;flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.data-table-page .table-toolbar[data-v-bda71432]{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;padding:0 12px;flex-wrap:wrap;gap:12px}.data-table-page .table-title[data-v-bda71432]{font-size:18px;font-weight:600;color:#1e293b;margin:0;letter-spacing:-.3px}.data-table-page .toolbar-actions[data-v-bda71432]{display:flex;align-items:center;gap:12px}.data-table-page .search-input[data-v-bda71432]{width:280px}.data-table-page .search-input[data-v-bda71432] .el-input__wrapper{border-radius:8px;box-shadow:0 0 0 1px #e2e8f0 inset;transition:all .2s}.data-table-page .search-input[data-v-bda71432] .el-input__wrapper.is-focus{box-shadow:0 0 0 1px var(--primary-color) inset}.data-table-page .batch-bar[data-v-bda71432]{display:flex;align-items:center;justify-content:space-between;background:#4f46e50d;border:1px solid rgba(79,70,229,.1);border-radius:8px;padding:10px 16px;margin:0 24px 16px}.data-table-page .batch-bar .batch-info[data-v-bda71432]{font-size:13px;color:var(--primary-color)}.data-table-page .batch-bar .batch-info strong[data-v-bda71432]{font-weight:600;margin:0 4px}.data-table-page .table-body[data-v-bda71432]{flex:1;min-height:0}.data-table-page .table-pagination[data-v-bda71432]{display:flex;justify-content:flex-end;align-items:center;padding:16px 24px;border-top:1px solid #f1f5f9}.data-table-page .table-pagination[data-v-bda71432] .el-pagination{margin-top:0}.data-table-page[data-v-bda71432] .el-card__body{display:flex;flex-direction:column;padding:12px 0 0;flex:1;min-height:0}.data-table-page[data-v-bda71432] .el-table__inner-wrapper:before{display:none}.data-table-page[data-v-bda71432] .el-table td.el-table__cell{padding:18px 0!important}.data-table-page[data-v-bda71432] .el-table__cell .cell{line-height:22px;white-space:nowrap}.data-table-page[data-v-bda71432] .el-table .action-buttons{display:flex;align-items:center;justify-content:center;flex-wrap:nowrap;gap:8px}

View File

@@ -0,0 +1 @@
@charset "UTF-8";.capsule-tabs[data-v-ccb2fce8]{display:flex;background:#f1f5f9;padding:3px;border-radius:8px;gap:2px;border:1px solid #e2e8f0}.capsule-tab-item[data-v-ccb2fce8]{border:0;background:transparent;padding:6px 20px;font-size:13px;font-weight:500;color:#64748b;cursor:pointer;border-radius:6px;transition:all .2s ease;outline:none}.capsule-tab-item[data-v-ccb2fce8]:hover{color:#1e293b}.capsule-tab-item.active[data-v-ccb2fce8]{background:#fff;color:#4f46e5;box-shadow:0 1px 3px #0000000f,0 1px 2px #0000000a;font-weight:600}.numeric-cell[data-v-ccb2fce8]{font-variant-numeric:tabular-nums;white-space:nowrap}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
@charset "UTF-8";.capsule-tabs[data-v-75b95d11]{display:flex;background:#f1f5f9;padding:3px;border-radius:8px;gap:2px;border:1px solid #e2e8f0}.capsule-tab-item[data-v-75b95d11]{border:0;background:transparent;padding:6px 20px;font-size:13px;font-weight:500;color:#64748b;cursor:pointer;border-radius:6px;transition:all .2s ease;outline:none}.capsule-tab-item[data-v-75b95d11]:hover{color:#1e293b}.capsule-tab-item.active[data-v-75b95d11]{background:#fff;color:#4f46e5;box-shadow:0 1px 3px #0000000f,0 1px 2px #0000000a;font-weight:600}

View File

@@ -1 +0,0 @@
import{E}from"./index-CCavIuTY.js";import{E as T}from"./el-tag-C_D80BPW.js";import{E as L}from"./el-table-DkdQ6gPU.js";import{d as A,y as f,G as V,e as k,w as e,ac as $,j as B,o as y,q as r,s as l,x as i,g as N,aa as p,f as b,aY as P,aZ as S,n as w,v as M,A as R}from"./index-CGB0A5x_.js";import"./el-checkbox-Ci1DH0Aj.js";import{D as q}from"./DataTablePage-CURtmoAI.js";import{g as G,d as I,a as Y}from"./dataset-C_hkNkI5.js";import{_ as j}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./el-scrollbar-p6_f_LH2.js";import"./index-DMVRI44M.js";import"./el-popper-DvBtRO32.js";import"./index-BPwPlcbL.js";import"./_baseClone-CX1E8HTZ.js";import"./_baseIteratee-uVh0OyD5.js";import"./castArray-Cgg396Sr.js";import"./debounce-Bqww2DS8.js";import"./toNumber-IRhFg6gN.js";import"./raf-CCivjDro.js";import"./omit-DaFv1hTo.js";import"./index-CbmPSBt0.js";import"./index-D2-3cnGo.js";import"./el-card-BWcR1iD2.js";import"./el-pagination-DGQ0vO_O.js";import"./el-select-C59URVI0.js";import"./vnode-DFpZw5lG.js";import"./index-khuXz7sd.js";import"./scroll-C0BSy_Rk.js";import"./clamp-BqqU4KQ-.js";import"./directive-vzjADwzS.js";import"./index-BMrs0kLP.js";import"./validator-D7tSoy2w.js";import"./index-Coa9QRND.js";import"./index-C5EKbiob.js";import"./el-tooltip-l0sNRNKZ.js";const O={class:"capsule-tabs"},U={class:"action-buttons"},Z=A({__name:"DatasetListView",setup(F){const C=M(),D=$(),c=f(!1),u=f([]),n=f(D.query.tab==="task"?"task":"upload"),h=B(()=>n.value==="task"?u.value.filter(s=>s.source==="task"):u.value.filter(s=>s.source!=="task"));async function d(){c.value=!0;try{u.value=await G()||[]}catch{}finally{c.value=!1}}async function _(s){await I(s.id),u.value=u.value.filter(a=>a.id!==s.id),await d(),R.success("删除成功")}function x(s){C.push(`/dataset/${s.id}/preview`)}function z(s){window.open(Y(s.id),"_blank")}return V(d),(s,a)=>{const o=L,v=T,m=E;return y(),k(q,{title:"数据集管理",data:h.value,loading:c.value,searchable:"","search-fields":["name","description"],"create-text":n.value==="upload"?"上传数据集":"","create-to":"/dataset/create","delete-fn":_,"row-key":"id",onRefresh:d},{title:e(()=>[r("div",O,[r("button",{class:w(["capsule-tab-item",{active:n.value==="upload"}]),onClick:a[0]||(a[0]=t=>n.value="upload")}," 上传任务 ",2),r("button",{class:w(["capsule-tab-item",{active:n.value==="task"}]),onClick:a[1]||(a[1]=t=>n.value="task")}," 数据任务 ",2)])]),columns:e(()=>[n.value==="task"?(y(),k(o,{key:0,label:"任务ID",prop:"task_id",align:"center",width:"100"})):N("",!0),l(o,{label:"数据集名称",prop:"name",align:"center"}),l(o,{label:"数据类型",align:"center",width:"110"},{default:e(({row:t})=>[l(v,{type:"primary",size:"small"},{default:e(()=>[i(p(b(P)[String(t.type).toLowerCase()]||t.type||"-"),1)]),_:2},1024)]),_:1}),l(o,{label:"存储位置",align:"center",width:"110"},{default:e(({row:t})=>[l(v,{type:"success",size:"small"},{default:e(()=>[i(p(b(S)[t.storage_type]||t.storage_type||"-"),1)]),_:2},1024)]),_:1}),l(o,{label:"大小",align:"center",width:"100"},{default:e(({row:t})=>[i(p(t.size&&t.size!=="0 B"&&t.size!=="0"?t.size:"-"),1)]),_:1}),l(o,{label:"数据条数",align:"center",width:"100"},{default:e(({row:t})=>[i(p(t.count||0),1)]),_:1}),l(o,{label:"描述",align:"center","show-overflow-tooltip":""},{default:e(({row:t})=>[i(p(t.description||"-"),1)]),_:1}),l(o,{label:"创建时间",align:"center",width:"180"},{default:e(({row:t})=>[i(p(t.create_time?new Date(t.create_time).toLocaleString("zh-CN"):"-"),1)]),_:1})]),actions:e(({row:t})=>[r("div",U,[l(m,{type:"primary",link:"",size:"small",onClick:g=>x(t)},{default:e(()=>[...a[2]||(a[2]=[r("i",{class:"fa fa-eye",style:{"margin-right":"4px"}},null,-1),i("详情 ",-1)])]),_:1},8,["onClick"]),l(m,{type:"success",link:"",size:"small",onClick:g=>z(t)},{default:e(()=>[...a[3]||(a[3]=[r("i",{class:"fa fa-download",style:{"margin-right":"4px"}},null,-1),i("下载 ",-1)])]),_:1},8,["onClick"]),l(m,{type:"danger",link:"",size:"small",onClick:g=>_(t)},{default:e(()=>[...a[4]||(a[4]=[r("i",{class:"fa fa-trash-o",style:{"margin-right":"4px"}},null,-1),i("删除 ",-1)])]),_:1},8,["onClick"])])]),_:1},8,["data","loading","create-text"])}}}),Tt=j(Z,[["__scopeId","data-v-75b95d11"]]);export{Tt as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{a as k,E as M}from"./el-form-item-Ct_zBuY0.js";import{E as q}from"./index-CbmPSBt0.js";import{E as R}from"./index-CCavIuTY.js";import{d as S,G as B,e as F,w as i,j as y,y as _,z as I,o as O,s as r,f as m,aB as P,x as h,aa as j,A as x,v as A,ac as L}from"./index-CGB0A5x_.js";import{P as N}from"./PageCard-D1lOaeEG.js";import{E as T,D as U}from"./DimensionFormFields-Dz4OI87j.js";import{b as z,u as G,c as H}from"./eval-CNlv4GHr.js";import{g as J}from"./model-xlHsHa68.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./index-DMVRI44M.js";import"./el-card-BWcR1iD2.js";import"./_plugin-vue_export-helper-DlAUqK2U.js";import"./el-select-C59URVI0.js";import"./index-BPwPlcbL.js";import"./vnode-DFpZw5lG.js";import"./el-popper-DvBtRO32.js";import"./el-scrollbar-p6_f_LH2.js";import"./index-khuXz7sd.js";import"./el-tag-C_D80BPW.js";import"./scroll-C0BSy_Rk.js";import"./clamp-BqqU4KQ-.js";import"./toNumber-IRhFg6gN.js";import"./_baseIteratee-uVh0OyD5.js";import"./el-checkbox-Ci1DH0Aj.js";import"./omit-DaFv1hTo.js";import"./el-radio-group-B7nPUe8-.js";import"./el-input-number-VAjRO6-I.js";import"./index-CL2S8yHq.js";import"./el-slider-CM3VEvCM.js";import"./debounce-Bqww2DS8.js";import"./el-switch-ZjdGiO6T.js";import"./validator-D7tSoy2w.js";import"./el-tooltip-l0sNRNKZ.js";/* empty css */const Se=S({__name:"DimensionCreateView",setup(K){const c=L(),f=A(),n=_(),p=_(!1),u=y(()=>!!c.params.id),s=y(()=>c.params.id),d=_([]);let e=I({name:"",type:"",description:"",eval_model:"",eval_method:"",eval_prompt:"",is_active:!0,is_default:!1,bleu_n:1,output_precision:3,score_min:0,score_max:5,pass_threshold:3});const b={name:[{required:!0,message:"请输入维度名称",trigger:"blur"},{max:50,message:"不超过 50 字符",trigger:"blur"}],type:[{required:!0,message:"请选择指标类型",trigger:"change"}],eval_model:[{required:!0,message:"请选择大模型",trigger:"change"}],eval_method:[{required:!0,message:"请选择评估方式",trigger:"change"}],eval_prompt:[{required:!0,message:"请填写评估 Prompt",trigger:"blur"}]};async function w(){var o,t;if(s.value)try{const a=await z(s.value);Object.assign(e,{name:a.name||"",type:a.type||"",description:a.description||"",eval_model:a.eval_model||"",eval_method:a.eval_method||(a.type?(t=(o=T[a.type])==null?void 0:o[0])==null?void 0:t.value:""),eval_prompt:a.eval_prompt||"",is_active:a.is_active!==!1,is_default:!!a.is_default,bleu_n:a.bleu_n??1,output_precision:a.output_precision??3,score_min:a.score_min??0,score_max:a.score_max??5,pass_threshold:a.pass_threshold??3})}catch{}}async function E(){try{const o=await J()||[];d.value=o.filter(t=>t.purpose==="evaluation")}catch{d.value=[]}}async function D(){n.value&&await n.value.validate(async o=>{if(o){p.value=!0;try{const t={name:e.name,type:e.type,description:e.description,eval_model:e.type==="text_similarity"?null:e.eval_model,eval_method:e.eval_method,eval_prompt:e.type==="text_similarity"?null:e.eval_prompt,is_active:e.is_active,is_default:e.is_default,create_time:new Date().toISOString()};e.type==="text_similarity"&&(t.bleu_n=e.bleu_n,t.output_precision=e.output_precision),e.type==="metric"&&(t.score_min=e.score_min,t.score_max=e.score_max,t.pass_threshold=e.pass_threshold),u.value&&s.value?(await G(s.value,t),x.success("更新成功")):(await H(t),x.success("创建成功")),f.push("/model-eval")}catch{}finally{p.value=!1}}})}function V(){f.back()}return B(()=>{E(),w()}),(o,t)=>{const a=q,v=k,g=R,C=M;return O(),F(N,{title:u.value?"编辑评测维度":"添加评测维度"},{default:i(()=>[r(C,{ref_key:"formRef",ref:n,model:m(e),rules:b,"label-width":"130px",style:{"max-width":"760px"}},{default:i(()=>[r(v,{label:"维度名称",prop:"name"},{default:i(()=>[r(a,{modelValue:m(e).name,"onUpdate:modelValue":t[0]||(t[0]=l=>m(e).name=l),placeholder:"请输入维度名称",maxlength:"50","show-word-limit":""},null,8,["modelValue"])]),_:1}),r(U,{modelValue:m(e),"onUpdate:modelValue":t[1]||(t[1]=l=>P(e)?e.value=l:e=l),"eval-models":d.value},null,8,["modelValue","eval-models"]),r(v,null,{default:i(()=>[r(g,{type:"primary",loading:p.value,onClick:D},{default:i(()=>[h(j(u.value?"保存":"创建"),1)]),_:1},8,["loading"]),r(g,{onClick:V},{default:i(()=>[...t[2]||(t[2]=[h("取消",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1},8,["title"])}}});export{Se as default};
import{a as k,E as M}from"./el-form-item-BMccCMQS.js";import{E as q}from"./index-CxrDRhwR.js";import{E as R}from"./index-9zpOHVFd.js";import{d as S,G as B,e as F,w as i,j as y,y as _,z as I,o as O,s as r,f as m,aB as P,x as h,aa as j,A as x,v as A,ac as L}from"./index-Dd84m4NL.js";import{P as N}from"./PageCard-Bj5UBPkt.js";import{E as T,D as U}from"./DimensionFormFields-lGjE6lQb.js";import{b as z,u as G,c as H}from"./eval-CGFUI2sL.js";import{g as J}from"./model-SG-pVLXE.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./index-DEuQ2B0Z.js";import"./el-card-WMAJU1WK.js";import"./_plugin-vue_export-helper-DlAUqK2U.js";import"./el-select-DinjeS4W.js";import"./index-KnEmF0FL.js";import"./vnode-CasYkit1.js";import"./el-popper-CXiDZrHI.js";import"./el-scrollbar-CnqWU4CY.js";import"./index-C5oiM9Uu.js";import"./el-tag-DPsbND_Z.js";import"./scroll-CJw98M_S.js";import"./clamp-MxoDdpzk.js";import"./toNumber-Dzu6kJGs.js";import"./_baseIteratee-CfOSjoYo.js";import"./el-checkbox-DmCZOH3C.js";import"./omit-njl9pMBF.js";import"./el-radio-group-WtTCRL8H.js";import"./el-input-number-CLGVcD2n.js";import"./index-CrQUvw33.js";import"./el-slider-zfFAQg0d.js";import"./debounce-CqM0EiuE.js";import"./el-switch-DeGokrBx.js";import"./validator-BEv3fs9p.js";import"./el-tooltip-l0sNRNKZ.js";/* empty css */const Se=S({__name:"DimensionCreateView",setup(K){const c=L(),f=A(),n=_(),p=_(!1),u=y(()=>!!c.params.id),s=y(()=>c.params.id),d=_([]);let e=I({name:"",type:"",description:"",eval_model:"",eval_method:"",eval_prompt:"",is_active:!0,is_default:!1,bleu_n:1,output_precision:3,score_min:0,score_max:5,pass_threshold:3});const b={name:[{required:!0,message:"请输入维度名称",trigger:"blur"},{max:50,message:"不超过 50 字符",trigger:"blur"}],type:[{required:!0,message:"请选择指标类型",trigger:"change"}],eval_model:[{required:!0,message:"请选择大模型",trigger:"change"}],eval_method:[{required:!0,message:"请选择评估方式",trigger:"change"}],eval_prompt:[{required:!0,message:"请填写评估 Prompt",trigger:"blur"}]};async function w(){var o,t;if(s.value)try{const a=await z(s.value);Object.assign(e,{name:a.name||"",type:a.type||"",description:a.description||"",eval_model:a.eval_model||"",eval_method:a.eval_method||(a.type?(t=(o=T[a.type])==null?void 0:o[0])==null?void 0:t.value:""),eval_prompt:a.eval_prompt||"",is_active:a.is_active!==!1,is_default:!!a.is_default,bleu_n:a.bleu_n??1,output_precision:a.output_precision??3,score_min:a.score_min??0,score_max:a.score_max??5,pass_threshold:a.pass_threshold??3})}catch{}}async function E(){try{const o=await J()||[];d.value=o.filter(t=>t.purpose==="evaluation")}catch{d.value=[]}}async function D(){n.value&&await n.value.validate(async o=>{if(o){p.value=!0;try{const t={name:e.name,type:e.type,description:e.description,eval_model:e.type==="text_similarity"?null:e.eval_model,eval_method:e.eval_method,eval_prompt:e.type==="text_similarity"?null:e.eval_prompt,is_active:e.is_active,is_default:e.is_default,create_time:new Date().toISOString()};e.type==="text_similarity"&&(t.bleu_n=e.bleu_n,t.output_precision=e.output_precision),e.type==="metric"&&(t.score_min=e.score_min,t.score_max=e.score_max,t.pass_threshold=e.pass_threshold),u.value&&s.value?(await G(s.value,t),x.success("更新成功")):(await H(t),x.success("创建成功")),f.push("/model-eval")}catch{}finally{p.value=!1}}})}function V(){f.back()}return B(()=>{E(),w()}),(o,t)=>{const a=q,v=k,g=R,C=M;return O(),F(N,{title:u.value?"编辑评测维度":"添加评测维度"},{default:i(()=>[r(C,{ref_key:"formRef",ref:n,model:m(e),rules:b,"label-width":"130px",style:{"max-width":"760px"}},{default:i(()=>[r(v,{label:"维度名称",prop:"name"},{default:i(()=>[r(a,{modelValue:m(e).name,"onUpdate:modelValue":t[0]||(t[0]=l=>m(e).name=l),placeholder:"请输入维度名称",maxlength:"50","show-word-limit":""},null,8,["modelValue"])]),_:1}),r(U,{modelValue:m(e),"onUpdate:modelValue":t[1]||(t[1]=l=>P(e)?e.value=l:e=l),"eval-models":d.value},null,8,["modelValue","eval-models"]),r(v,null,{default:i(()=>[r(g,{type:"primary",loading:p.value,onClick:D},{default:i(()=>[h(j(u.value?"保存":"创建"),1)]),_:1},8,["loading"]),r(g,{onClick:V},{default:i(()=>[...t[2]||(t[2]=[h("取消",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1},8,["title"])}}});export{Se as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{E as V}from"./index-CCavIuTY.js";import{E as $}from"./el-table-DkdQ6gPU.js";import{d as B,G as D,c as T,e as _,w as o,g as C,y as p,o as v,s as a,q as i,x as b,aa as L,n as c,v as N,A as z}from"./index-CGB0A5x_.js";import{E as M}from"./index-BMrs0kLP.js";import"./el-tag-C_D80BPW.js";import"./el-checkbox-Ci1DH0Aj.js";import{D as y}from"./DataTablePage-CURtmoAI.js";import{_ as A}from"./ModelStatusTag.vue_vue_type_script_setup_true_lang-NhrqSCT2.js";import{g as G,d as P}from"./eval-CNlv4GHr.js";import{_ as R}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./el-scrollbar-p6_f_LH2.js";import"./index-DMVRI44M.js";import"./el-popper-DvBtRO32.js";import"./index-BPwPlcbL.js";import"./_baseClone-CX1E8HTZ.js";import"./_baseIteratee-uVh0OyD5.js";import"./castArray-Cgg396Sr.js";import"./debounce-Bqww2DS8.js";import"./toNumber-IRhFg6gN.js";import"./raf-CCivjDro.js";import"./validator-D7tSoy2w.js";import"./index-Coa9QRND.js";import"./clamp-BqqU4KQ-.js";import"./index-C5EKbiob.js";import"./scroll-C0BSy_Rk.js";import"./index-CbmPSBt0.js";import"./index-D2-3cnGo.js";import"./omit-DaFv1hTo.js";import"./el-card-BWcR1iD2.js";import"./el-pagination-DGQ0vO_O.js";import"./el-select-C59URVI0.js";import"./vnode-DFpZw5lG.js";import"./index-khuXz7sd.js";import"./directive-vzjADwzS.js";import"./el-tooltip-l0sNRNKZ.js";import"./status-Dl1fykxa.js";const S={class:"eval-page"},q={class:"capsule-tabs"},I={class:"capsule-tabs"},Q=B({__name:"EvalView",setup(j){const f=N(),s=p("tasks"),d=p(!1),n=p([]),w=p([{rank:1,name:"GPT-4",score:92.5},{rank:2,name:"Claude-3",score:90.1},{rank:3,name:"Qwen-Max",score:85.3}]);async function u(){d.value=!0;try{n.value=await G()||[]}catch{n.value=[]}finally{d.value=!1}}async function k(r){await M.confirm("确定要删除这个评测任务吗?","确认删除",{type:"warning"}),await P(r.id),n.value=n.value.filter(e=>e.id!==r.id),z.success("删除成功"),await u()}function E(){f.push("/model-eval/create")}function m(r){return s.value===r}function x(r){f.push({name:"model-eval-detail",params:{id:r.id}})}return D(()=>{u()}),(r,e)=>{const l=$,g=V;return v(),T("div",S,[s.value==="tasks"?(v(),_(y,{key:0,title:"",data:n.value,loading:d.value,"delete-fn":k,"create-text":"创建评测任务",onCreate:E,"row-key":"id",onRefresh:u},{title:o(()=>[i("div",q,[i("button",{class:c(["capsule-tab-item",{active:m("tasks")}]),onClick:e[0]||(e[0]=t=>s.value="tasks")},"评测任务",2),i("button",{class:c(["capsule-tab-item",{active:m("leaderboard")}]),onClick:e[1]||(e[1]=t=>s.value="leaderboard")},"排行榜",2)])]),columns:o(()=>[a(l,{label:"任务名称",prop:"eval_task_name",align:"center"}),a(l,{label:"评测模型",prop:"model_name",align:"center"}),a(l,{label:"数据集",prop:"dataset",align:"center"}),a(l,{label:"指标",prop:"metric",align:"center"}),a(l,{label:"评分",prop:"score",width:"100",align:"center"}),a(l,{label:"状态",width:"100",align:"center"},{default:o(({row:t})=>[a(A,{status:t.status},null,8,["status"])]),_:1}),a(l,{label:"创建时间",align:"center",width:"180"},{default:o(({row:t})=>[b(L(t.create_time?new Date(t.create_time).toLocaleString("zh-CN"):"-"),1)]),_:1})]),actions:o(({row:t})=>[a(g,{link:"",type:"primary",size:"small",onClick:h=>x(t)},{default:o(()=>[...e[4]||(e[4]=[i("i",{class:"fa fa-file-text-o",style:{"margin-right":"4px"}},null,-1),b("详情 ",-1)])]),_:1},8,["onClick"]),a(g,{link:"",type:"danger",size:"small",onClick:h=>k(t)},{default:o(()=>[...e[5]||(e[5]=[i("i",{class:"fa fa-trash-o",style:{"margin-right":"4px"}},null,-1),b("删除 ",-1)])]),_:1},8,["onClick"])]),_:1},8,["data","loading"])):C("",!0),s.value==="leaderboard"?(v(),_(y,{key:1,title:"",data:w.value,"row-key":"rank"},{title:o(()=>[i("div",I,[i("button",{class:c(["capsule-tab-item",{active:m("tasks")}]),onClick:e[2]||(e[2]=t=>s.value="tasks")},"评测任务",2),i("button",{class:c(["capsule-tab-item",{active:m("leaderboard")}]),onClick:e[3]||(e[3]=t=>s.value="leaderboard")},"排行榜",2)])]),columns:o(()=>[a(l,{label:"排名",prop:"rank",width:"80",align:"center"}),a(l,{label:"模型名称",prop:"name",align:"center"}),a(l,{label:"综合评分",prop:"score",align:"center"})]),_:1},8,["data"])):C("",!0)])}}}),Ve=R(Q,[["__scopeId","data-v-894b0bb7"]]);export{Ve as default};
import{E as V}from"./index-9zpOHVFd.js";import{E as $}from"./el-table-CknU6KUt.js";import{d as B,G as D,c as T,e as _,w as o,g as C,y as p,o as v,s as a,q as i,x as b,aa as L,n as c,v as N,A as z}from"./index-Dd84m4NL.js";import{E as M}from"./index-Czb9Dcel.js";import"./el-tag-DPsbND_Z.js";import"./el-checkbox-DmCZOH3C.js";import{D as y}from"./DataTablePage-_dKtm0HL.js";import{_ as A}from"./ModelStatusTag.vue_vue_type_script_setup_true_lang-BCuQEsSn.js";import{g as G,d as P}from"./eval-CGFUI2sL.js";import{_ as R}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./el-scrollbar-CnqWU4CY.js";import"./index-DEuQ2B0Z.js";import"./el-popper-CXiDZrHI.js";import"./index-KnEmF0FL.js";import"./_baseClone-C6YdWYHR.js";import"./_baseIteratee-CfOSjoYo.js";import"./castArray-Cc7cuNko.js";import"./debounce-CqM0EiuE.js";import"./toNumber-Dzu6kJGs.js";import"./raf-CGf5YZRu.js";import"./validator-BEv3fs9p.js";import"./index-BsIWQhw5.js";import"./clamp-MxoDdpzk.js";import"./index-B6n2yrjP.js";import"./scroll-CJw98M_S.js";import"./index-CxrDRhwR.js";import"./index-BkMrw1Qg.js";import"./omit-njl9pMBF.js";import"./el-card-WMAJU1WK.js";import"./el-pagination-CZfi7rql.js";import"./el-select-DinjeS4W.js";import"./vnode-CasYkit1.js";import"./index-C5oiM9Uu.js";import"./directive-CGqZKDhv.js";import"./el-tooltip-l0sNRNKZ.js";import"./status-Dl1fykxa.js";const S={class:"eval-page"},q={class:"capsule-tabs"},I={class:"capsule-tabs"},Q=B({__name:"EvalView",setup(j){const f=N(),s=p("tasks"),d=p(!1),n=p([]),w=p([{rank:1,name:"GPT-4",score:92.5},{rank:2,name:"Claude-3",score:90.1},{rank:3,name:"Qwen-Max",score:85.3}]);async function u(){d.value=!0;try{n.value=await G()||[]}catch{n.value=[]}finally{d.value=!1}}async function k(r){await M.confirm("确定要删除这个评测任务吗?","确认删除",{type:"warning"}),await P(r.id),n.value=n.value.filter(e=>e.id!==r.id),z.success("删除成功"),await u()}function E(){f.push("/model-eval/create")}function m(r){return s.value===r}function x(r){f.push({name:"model-eval-detail",params:{id:r.id}})}return D(()=>{u()}),(r,e)=>{const l=$,g=V;return v(),T("div",S,[s.value==="tasks"?(v(),_(y,{key:0,title:"",data:n.value,loading:d.value,"delete-fn":k,"create-text":"创建评测任务",onCreate:E,"row-key":"id",onRefresh:u},{title:o(()=>[i("div",q,[i("button",{class:c(["capsule-tab-item",{active:m("tasks")}]),onClick:e[0]||(e[0]=t=>s.value="tasks")},"评测任务",2),i("button",{class:c(["capsule-tab-item",{active:m("leaderboard")}]),onClick:e[1]||(e[1]=t=>s.value="leaderboard")},"排行榜",2)])]),columns:o(()=>[a(l,{label:"任务名称",prop:"eval_task_name",align:"center"}),a(l,{label:"评测模型",prop:"model_name",align:"center"}),a(l,{label:"数据集",prop:"dataset",align:"center"}),a(l,{label:"指标",prop:"metric",align:"center"}),a(l,{label:"评分",prop:"score",width:"100",align:"center"}),a(l,{label:"状态",width:"100",align:"center"},{default:o(({row:t})=>[a(A,{status:t.status},null,8,["status"])]),_:1}),a(l,{label:"创建时间",align:"center",width:"180"},{default:o(({row:t})=>[b(L(t.create_time?new Date(t.create_time).toLocaleString("zh-CN"):"-"),1)]),_:1})]),actions:o(({row:t})=>[a(g,{link:"",type:"primary",size:"small",onClick:h=>x(t)},{default:o(()=>[...e[4]||(e[4]=[i("i",{class:"fa fa-file-text-o",style:{"margin-right":"4px"}},null,-1),b("详情 ",-1)])]),_:1},8,["onClick"]),a(g,{link:"",type:"danger",size:"small",onClick:h=>k(t)},{default:o(()=>[...e[5]||(e[5]=[i("i",{class:"fa fa-trash-o",style:{"margin-right":"4px"}},null,-1),b("删除 ",-1)])]),_:1},8,["onClick"])]),_:1},8,["data","loading"])):C("",!0),s.value==="leaderboard"?(v(),_(y,{key:1,title:"",data:w.value,"row-key":"rank"},{title:o(()=>[i("div",I,[i("button",{class:c(["capsule-tab-item",{active:m("tasks")}]),onClick:e[2]||(e[2]=t=>s.value="tasks")},"评测任务",2),i("button",{class:c(["capsule-tab-item",{active:m("leaderboard")}]),onClick:e[3]||(e[3]=t=>s.value="leaderboard")},"排行榜",2)])]),columns:o(()=>[a(l,{label:"排名",prop:"rank",width:"80",align:"center"}),a(l,{label:"模型名称",prop:"name",align:"center"}),a(l,{label:"综合评分",prop:"score",align:"center"})]),_:1},8,["data"])):C("",!0)])}}}),Ve=R(Q,[["__scopeId","data-v-894b0bb7"]]);export{Ve as default};

View File

@@ -1 +1 @@
import{_ as s}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o as t,c,q as o}from"./index-CGB0A5x_.js";const n={},r={class:"simple-page"};function a(_,e){return t(),c("section",r,[...e[0]||(e[0]=[o("h1",null,"使用文档",-1),o("p",null,"第一版系统已接入后端、数据集、模型、微调任务、算力节点和训练日志主链路。",-1)])])}const p=s(n,[["render",a],["__scopeId","data-v-962c8803"]]);export{p as default};
import{_ as s}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o as t,c,q as o}from"./index-Dd84m4NL.js";const n={},r={class:"simple-page"};function a(_,e){return t(),c("section",r,[...e[0]||(e[0]=[o("h1",null,"使用文档",-1),o("p",null,"第一版系统已接入后端、数据集、模型、微调任务、算力节点和训练日志主链路。",-1)])])}const p=s(n,[["render",a],["__scopeId","data-v-962c8803"]]);export{p as default};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{E as T}from"./el-alert-DBfM1mZE.js";import{a as A,E as D}from"./el-form-item-Ct_zBuY0.js";import{E as L}from"./index-CbmPSBt0.js";import{E as j}from"./index-CCavIuTY.js";import{E as z,b as H,a as J}from"./el-select-C59URVI0.js";import{E as K}from"./el-divider-DF2VMDw-.js";import{d as Q,G as W,e as i,w as o,at as X,y as u,z as Y,o as s,s as a,x as b,c as v,ad as k,M as w,g as Z,j as p,A as B,v as ee}from"./index-CGB0A5x_.js";import"./el-scrollbar-p6_f_LH2.js";import"./el-popper-DvBtRO32.js";import"./el-tag-C_D80BPW.js";import{P as te}from"./PageCard-D1lOaeEG.js";import{g as le,a as ae}from"./model-xlHsHa68.js";import"./vnode-DFpZw5lG.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./index-DMVRI44M.js";import"./index-BPwPlcbL.js";import"./index-khuXz7sd.js";import"./scroll-C0BSy_Rk.js";import"./clamp-BqqU4KQ-.js";import"./toNumber-IRhFg6gN.js";import"./_baseIteratee-uVh0OyD5.js";import"./el-card-BWcR1iD2.js";import"./_plugin-vue_export-helper-DlAUqK2U.js";const Ge=Q({__name:"InferenceCreateView",setup(oe){const E=ee(),f=u(),c=u(!1),m=u(""),V=u([]),h=u([]),_=u([]),x=p(()=>V.value.map(t=>({key:`db-${t.id}`,id:t.id,name:t.name,source:"database",model_path:t.path||""}))),M=p(()=>h.value.map(t=>({key:`trained-${t.id}`,id:t.id,name:t.name,source:"trained",model_path:t.merged_path||t.base_model_path||"",merged:t.merged,merging:t.merging,disabled:t.merged===!1}))),G=p(()=>{const t={};for(const e of[...x.value,...M.value])t[e.key]=e;return t}),n=Y({name:"",description:"",model_key:"",gpu_id:0}),I={name:[{required:!0,message:"请输入推理名称",trigger:"blur"}],model_key:[{required:!0,message:"请选择模型",trigger:"change"}]},O=p(()=>G.value[n.model_key]);async function S(){f.value&&await f.value.validate(async t=>{if(!t)return;const e=O.value;if(!e){B.warning("请选择模型");return}c.value=!0,m.value="正在启动模型服务...";try{await new Promise(r=>setTimeout(r,1200)),B.success("模型已启动"),E.push({path:"/model-inference/chat/mock",query:{model:e.name}})}finally{c.value=!1,m.value=""}})}function $(){E.back()}async function q(){try{const[t,e,r]=await Promise.all([le(),ae(),X()]);V.value=t||[],h.value=(e==null?void 0:e.models)||[],_.value=(r==null?void 0:r.gpu)||[],_.value.length>0&&(n.gpu_id=0)}catch{}}return W(q),(t,e)=>{const r=L,d=A,F=K,g=J,C=H,P=z,N=T,U=j,R=D;return s(),i(te,{title:"新建推理"},{default:o(()=>[a(R,{ref_key:"formRef",ref:f,model:n,rules:I,"label-width":"100px"},{default:o(()=>[a(d,{label:"推理名称",prop:"name"},{default:o(()=>[a(r,{modelValue:n.name,"onUpdate:modelValue":e[0]||(e[0]=l=>n.name=l),placeholder:"请输入推理名称",maxlength:"50","show-word-limit":"",style:{"max-width":"400px"}},null,8,["modelValue"])]),_:1}),a(d,{label:"描述"},{default:o(()=>[a(r,{modelValue:n.description,"onUpdate:modelValue":e[1]||(e[1]=l=>n.description=l),type:"textarea",rows:2,maxlength:"200","show-word-limit":"",style:{"max-width":"400px"}},null,8,["modelValue"])]),_:1}),a(F,{"content-position":"left"},{default:o(()=>[...e[4]||(e[4]=[b("选择模型",-1)])]),_:1}),a(d,{label:"选择模型",prop:"model_key"},{default:o(()=>[a(P,{modelValue:n.model_key,"onUpdate:modelValue":e[2]||(e[2]=l=>n.model_key=l),placeholder:"请选择模型",filterable:"",style:{width:"400px"}},{default:o(()=>[a(C,{label:"本地模型"},{default:o(()=>[(s(!0),v(w,null,k(x.value,l=>(s(),i(g,{key:l.key,label:l.name,value:l.key},null,8,["label","value"]))),128))]),_:1}),a(C,{label:"已训练模型"},{default:o(()=>[(s(!0),v(w,null,k(M.value,l=>(s(),i(g,{key:l.key,label:l.name+(l.disabled?"(未合并)":""),value:l.key,disabled:l.disabled},null,8,["label","value","disabled"]))),128))]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(d,{label:"GPU"},{default:o(()=>[a(P,{modelValue:n.gpu_id,"onUpdate:modelValue":e[3]||(e[3]=l=>n.gpu_id=l),style:{width:"400px"}},{default:o(()=>[(s(!0),v(w,null,k(_.value,(l,y)=>(s(),i(g,{key:y,label:`${l.name} (GPU${y})`,value:y},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),m.value?(s(),i(d,{key:0,label:"启动状态"},{default:o(()=>[a(N,{title:m.value,type:"info",closable:!1,"show-icon":""},null,8,["title"])]),_:1})):Z("",!0),a(d,null,{default:o(()=>[a(U,{type:"primary",loading:c.value,onClick:S},{default:o(()=>[...e[5]||(e[5]=[b("开始推理",-1)])]),_:1},8,["loading"]),a(U,{onClick:$},{default:o(()=>[...e[6]||(e[6]=[b("取消",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})}}});export{Ge as default};
import{E as T}from"./el-alert-B_M4eVTG.js";import{a as A,E as D}from"./el-form-item-BMccCMQS.js";import{E as L}from"./index-CxrDRhwR.js";import{E as j}from"./index-9zpOHVFd.js";import{E as z,b as H,a as J}from"./el-select-DinjeS4W.js";import{E as K}from"./el-divider-Y9JqUYBG.js";import{d as Q,G as W,e as i,w as o,at as X,y as u,z as Y,o as s,s as a,x as b,c as v,ad as k,M as w,g as Z,j as p,A as B,v as ee}from"./index-Dd84m4NL.js";import"./el-scrollbar-CnqWU4CY.js";import"./el-popper-CXiDZrHI.js";import"./el-tag-DPsbND_Z.js";import{P as te}from"./PageCard-Bj5UBPkt.js";import{g as le,a as ae}from"./model-SG-pVLXE.js";import"./vnode-CasYkit1.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./index-DEuQ2B0Z.js";import"./index-KnEmF0FL.js";import"./index-C5oiM9Uu.js";import"./scroll-CJw98M_S.js";import"./clamp-MxoDdpzk.js";import"./toNumber-Dzu6kJGs.js";import"./_baseIteratee-CfOSjoYo.js";import"./el-card-WMAJU1WK.js";import"./_plugin-vue_export-helper-DlAUqK2U.js";const Ge=Q({__name:"InferenceCreateView",setup(oe){const E=ee(),f=u(),c=u(!1),m=u(""),V=u([]),h=u([]),_=u([]),x=p(()=>V.value.map(t=>({key:`db-${t.id}`,id:t.id,name:t.name,source:"database",model_path:t.path||""}))),M=p(()=>h.value.map(t=>({key:`trained-${t.id}`,id:t.id,name:t.name,source:"trained",model_path:t.merged_path||t.base_model_path||"",merged:t.merged,merging:t.merging,disabled:t.merged===!1}))),G=p(()=>{const t={};for(const e of[...x.value,...M.value])t[e.key]=e;return t}),n=Y({name:"",description:"",model_key:"",gpu_id:0}),I={name:[{required:!0,message:"请输入推理名称",trigger:"blur"}],model_key:[{required:!0,message:"请选择模型",trigger:"change"}]},O=p(()=>G.value[n.model_key]);async function S(){f.value&&await f.value.validate(async t=>{if(!t)return;const e=O.value;if(!e){B.warning("请选择模型");return}c.value=!0,m.value="正在启动模型服务...";try{await new Promise(r=>setTimeout(r,1200)),B.success("模型已启动"),E.push({path:"/model-inference/chat/mock",query:{model:e.name}})}finally{c.value=!1,m.value=""}})}function $(){E.back()}async function q(){try{const[t,e,r]=await Promise.all([le(),ae(),X()]);V.value=t||[],h.value=(e==null?void 0:e.models)||[],_.value=(r==null?void 0:r.gpu)||[],_.value.length>0&&(n.gpu_id=0)}catch{}}return W(q),(t,e)=>{const r=L,d=A,F=K,g=J,C=H,P=z,N=T,U=j,R=D;return s(),i(te,{title:"新建推理"},{default:o(()=>[a(R,{ref_key:"formRef",ref:f,model:n,rules:I,"label-width":"100px"},{default:o(()=>[a(d,{label:"推理名称",prop:"name"},{default:o(()=>[a(r,{modelValue:n.name,"onUpdate:modelValue":e[0]||(e[0]=l=>n.name=l),placeholder:"请输入推理名称",maxlength:"50","show-word-limit":"",style:{"max-width":"400px"}},null,8,["modelValue"])]),_:1}),a(d,{label:"描述"},{default:o(()=>[a(r,{modelValue:n.description,"onUpdate:modelValue":e[1]||(e[1]=l=>n.description=l),type:"textarea",rows:2,maxlength:"200","show-word-limit":"",style:{"max-width":"400px"}},null,8,["modelValue"])]),_:1}),a(F,{"content-position":"left"},{default:o(()=>[...e[4]||(e[4]=[b("选择模型",-1)])]),_:1}),a(d,{label:"选择模型",prop:"model_key"},{default:o(()=>[a(P,{modelValue:n.model_key,"onUpdate:modelValue":e[2]||(e[2]=l=>n.model_key=l),placeholder:"请选择模型",filterable:"",style:{width:"400px"}},{default:o(()=>[a(C,{label:"本地模型"},{default:o(()=>[(s(!0),v(w,null,k(x.value,l=>(s(),i(g,{key:l.key,label:l.name,value:l.key},null,8,["label","value"]))),128))]),_:1}),a(C,{label:"已训练模型"},{default:o(()=>[(s(!0),v(w,null,k(M.value,l=>(s(),i(g,{key:l.key,label:l.name+(l.disabled?"(未合并)":""),value:l.key,disabled:l.disabled},null,8,["label","value","disabled"]))),128))]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(d,{label:"GPU"},{default:o(()=>[a(P,{modelValue:n.gpu_id,"onUpdate:modelValue":e[3]||(e[3]=l=>n.gpu_id=l),style:{width:"400px"}},{default:o(()=>[(s(!0),v(w,null,k(_.value,(l,y)=>(s(),i(g,{key:y,label:`${l.name} (GPU${y})`,value:y},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),m.value?(s(),i(d,{key:0,label:"启动状态"},{default:o(()=>[a(N,{title:m.value,type:"info",closable:!1,"show-icon":""},null,8,["title"])]),_:1})):Z("",!0),a(d,null,{default:o(()=>[a(U,{type:"primary",loading:c.value,onClick:S},{default:o(()=>[...e[5]||(e[5]=[b("开始推理",-1)])]),_:1},8,["loading"]),a(U,{onClick:$},{default:o(()=>[...e[6]||(e[6]=[b("取消",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})}}});export{Ge as default};

View File

@@ -1 +1 @@
import{E as $,a as q}from"./el-form-item-Ct_zBuY0.js";import{E as z}from"./index-CbmPSBt0.js";import{u as K,E as P}from"./index-CCavIuTY.js";import{E as R}from"./el-checkbox-Ci1DH0Aj.js";import{b as T,i as U,d as N,u as A,a as D,o as u,c as k,e as h,w as t,r as M,f as w,E as j,g,n as E,h as V,j as b,k as C,l as G,m as H,p as J,q as n,s,t as O,v as Q,x as y,y as B,z as W,A as X}from"./index-CGB0A5x_.js";import{_ as S}from"./logo-CxXS7KxG.js";import{_ as Y}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./index-DMVRI44M.js";import"./omit-DaFv1hTo.js";const Z=T({type:{type:String,values:["primary","success","warning","info","danger","default"],default:void 0},underline:{type:[Boolean,String],values:[!0,!1,"always","never","hover"],default:void 0},disabled:Boolean,href:{type:String,default:""},target:{type:String,default:"_self"},icon:{type:U}}),ee={click:l=>l instanceof MouseEvent},ae=["href","target"];var ne=N({name:"ElLink",__name:"link",props:Z,emits:ee,setup(l,{emit:c}){const o=l,i=c,r=A("link");K({scope:"el-link",from:"The underline option (boolean)",replacement:"'always' | 'hover' | 'never'",version:"3.0.0",ref:"https://element-plus.org/en-US/component/link.html#underline"},b(()=>C(o.underline)));const a=D("link"),m=b(()=>{var e;return[a.b(),a.m(o.type??((e=r.value)==null?void 0:e.type)??"default"),a.is("disabled",o.disabled),a.is("underline",d.value==="always"),a.is("hover-underline",d.value==="hover"&&!o.disabled)]}),d=b(()=>{var e;return C(o.underline)?o.underline?"hover":"never":o.underline??((e=r.value)==null?void 0:e.underline)??"hover"});function p(e){o.disabled||i("click",e)}return(e,f)=>(u(),k("a",{class:E(m.value),href:l.disabled||!l.href?void 0:l.href,target:l.disabled||!l.href?void 0:l.target,onClick:p},[l.icon?(u(),h(w(j),{key:0},{default:t(()=>[(u(),h(M(l.icon)))]),_:1})):g("v-if",!0),e.$slots.default?(u(),k("span",{key:1,class:E(w(a).e("inner"))},[V(e.$slots,"default")],2)):g("v-if",!0),e.$slots.icon?V(e.$slots,"icon",{key:2}):g("v-if",!0)],10,ae))}}),le=ne;const oe=G(le),se={class:"login-page"},te={class:"login-panel"},re={class:"login-form-wrap"},ie={class:"login-options"},de=N({__name:"LoginView",setup(l){const c=Q(),o=H(),i=B(),r=B(!1),a=W({username:"",password:""}),m={username:[{required:!0,message:"请输入账号",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]};async function d(){i.value&&await i.value.validate(async p=>{if(p){r.value=!0;try{await o.login(a.username,a.password),X.success("登录成功"),c.push("/dashboard")}catch{}finally{r.value=!1}}})}return(p,e)=>{const f=z,_=q,x=R,F=oe,I=P,L=$;return u(),k("div",se,[e[8]||(e[8]=J('<section class="login-visual" aria-labelledby="platform-title" data-v-5b789cef><div class="login-visual-content" data-v-5b789cef><div class="login-visual-copy" data-v-5b789cef><h1 id="platform-title" data-v-5b789cef>远光软件微调平台</h1><p data-v-5b789cef>大模型微调、评测与推理的一体化工作台</p></div><div class="login-visual-footer" aria-label="平台核心能力" data-v-5b789cef><span data-v-5b789cef>数据准备</span><span aria-hidden="true" data-v-5b789cef>·</span><span data-v-5b789cef>模型训练</span><span aria-hidden="true" data-v-5b789cef>·</span><span data-v-5b789cef>效果评测</span></div></div></section>',1)),n("main",te,[e[6]||(e[6]=n("div",{class:"brand-lockup",role:"img","aria-label":"远光软件"},[n("span",{class:"brand-logo-crop brand-logo-crop-mark","aria-hidden":"true"},[n("img",{src:S,alt:""})]),n("span",{class:"brand-logo-crop brand-logo-crop-wordmark","aria-hidden":"true"},[n("img",{src:S,alt:""})])],-1)),n("div",re,[e[5]||(e[5]=n("div",{class:"login-heading"},[n("span",null,"账号登录"),n("h2",null,"欢迎回来"),n("p",null,"登录后继续使用微调平台")],-1)),s(L,{ref_key:"loginFormRef",ref:i,model:a,rules:m,"label-position":"top",size:"large",onKeyup:O(d,["enter"])},{default:t(()=>[s(_,{label:"账号",prop:"username"},{default:t(()=>[s(f,{modelValue:a.username,"onUpdate:modelValue":e[0]||(e[0]=v=>a.username=v),placeholder:"请输入账号",clearable:""},null,8,["modelValue"])]),_:1}),s(_,{label:"密码",prop:"password"},{default:t(()=>[s(f,{modelValue:a.password,"onUpdate:modelValue":e[1]||(e[1]=v=>a.password=v),type:"password",placeholder:"请输入密码","show-password":""},null,8,["modelValue"])]),_:1}),n("div",ie,[s(x,null,{default:t(()=>[...e[2]||(e[2]=[y("记住密码",-1)])]),_:1}),s(F,{type:"primary",underline:!1},{default:t(()=>[...e[3]||(e[3]=[y("忘记密码?",-1)])]),_:1})]),s(I,{type:"primary",class:"login-btn",loading:r.value,onClick:d},{default:t(()=>[...e[4]||(e[4]=[y(" 登录 ",-1)])]),_:1},8,["loading"])]),_:1},8,["model"])]),e[7]||(e[7]=n("footer",null,"© 2026 远光软件",-1))])])}}}),Ee=Y(de,[["__scopeId","data-v-5b789cef"]]);export{Ee as default};
import{E as $,a as q}from"./el-form-item-BMccCMQS.js";import{E as z}from"./index-CxrDRhwR.js";import{u as K,E as P}from"./index-9zpOHVFd.js";import{E as R}from"./el-checkbox-DmCZOH3C.js";import{b as T,i as U,d as N,u as A,a as D,o as u,c as k,e as h,w as t,r as M,f as w,E as j,g,n as E,h as V,j as b,k as C,l as G,m as H,p as J,q as n,s,t as O,v as Q,x as y,y as B,z as W,A as X}from"./index-Dd84m4NL.js";import{_ as S}from"./logo-CxXS7KxG.js";import{_ as Y}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./index-DEuQ2B0Z.js";import"./omit-njl9pMBF.js";const Z=T({type:{type:String,values:["primary","success","warning","info","danger","default"],default:void 0},underline:{type:[Boolean,String],values:[!0,!1,"always","never","hover"],default:void 0},disabled:Boolean,href:{type:String,default:""},target:{type:String,default:"_self"},icon:{type:U}}),ee={click:l=>l instanceof MouseEvent},ae=["href","target"];var ne=N({name:"ElLink",__name:"link",props:Z,emits:ee,setup(l,{emit:c}){const o=l,i=c,r=A("link");K({scope:"el-link",from:"The underline option (boolean)",replacement:"'always' | 'hover' | 'never'",version:"3.0.0",ref:"https://element-plus.org/en-US/component/link.html#underline"},b(()=>C(o.underline)));const a=D("link"),m=b(()=>{var e;return[a.b(),a.m(o.type??((e=r.value)==null?void 0:e.type)??"default"),a.is("disabled",o.disabled),a.is("underline",d.value==="always"),a.is("hover-underline",d.value==="hover"&&!o.disabled)]}),d=b(()=>{var e;return C(o.underline)?o.underline?"hover":"never":o.underline??((e=r.value)==null?void 0:e.underline)??"hover"});function p(e){o.disabled||i("click",e)}return(e,f)=>(u(),k("a",{class:E(m.value),href:l.disabled||!l.href?void 0:l.href,target:l.disabled||!l.href?void 0:l.target,onClick:p},[l.icon?(u(),h(w(j),{key:0},{default:t(()=>[(u(),h(M(l.icon)))]),_:1})):g("v-if",!0),e.$slots.default?(u(),k("span",{key:1,class:E(w(a).e("inner"))},[V(e.$slots,"default")],2)):g("v-if",!0),e.$slots.icon?V(e.$slots,"icon",{key:2}):g("v-if",!0)],10,ae))}}),le=ne;const oe=G(le),se={class:"login-page"},te={class:"login-panel"},re={class:"login-form-wrap"},ie={class:"login-options"},de=N({__name:"LoginView",setup(l){const c=Q(),o=H(),i=B(),r=B(!1),a=W({username:"",password:""}),m={username:[{required:!0,message:"请输入账号",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]};async function d(){i.value&&await i.value.validate(async p=>{if(p){r.value=!0;try{await o.login(a.username,a.password),X.success("登录成功"),c.push("/dashboard")}catch{}finally{r.value=!1}}})}return(p,e)=>{const f=z,_=q,x=R,F=oe,I=P,L=$;return u(),k("div",se,[e[8]||(e[8]=J('<section class="login-visual" aria-labelledby="platform-title" data-v-5b789cef><div class="login-visual-content" data-v-5b789cef><div class="login-visual-copy" data-v-5b789cef><h1 id="platform-title" data-v-5b789cef>远光软件微调平台</h1><p data-v-5b789cef>大模型微调、评测与推理的一体化工作台</p></div><div class="login-visual-footer" aria-label="平台核心能力" data-v-5b789cef><span data-v-5b789cef>数据准备</span><span aria-hidden="true" data-v-5b789cef>·</span><span data-v-5b789cef>模型训练</span><span aria-hidden="true" data-v-5b789cef>·</span><span data-v-5b789cef>效果评测</span></div></div></section>',1)),n("main",te,[e[6]||(e[6]=n("div",{class:"brand-lockup",role:"img","aria-label":"远光软件"},[n("span",{class:"brand-logo-crop brand-logo-crop-mark","aria-hidden":"true"},[n("img",{src:S,alt:""})]),n("span",{class:"brand-logo-crop brand-logo-crop-wordmark","aria-hidden":"true"},[n("img",{src:S,alt:""})])],-1)),n("div",re,[e[5]||(e[5]=n("div",{class:"login-heading"},[n("span",null,"账号登录"),n("h2",null,"欢迎回来"),n("p",null,"登录后继续使用微调平台")],-1)),s(L,{ref_key:"loginFormRef",ref:i,model:a,rules:m,"label-position":"top",size:"large",onKeyup:O(d,["enter"])},{default:t(()=>[s(_,{label:"账号",prop:"username"},{default:t(()=>[s(f,{modelValue:a.username,"onUpdate:modelValue":e[0]||(e[0]=v=>a.username=v),placeholder:"请输入账号",clearable:""},null,8,["modelValue"])]),_:1}),s(_,{label:"密码",prop:"password"},{default:t(()=>[s(f,{modelValue:a.password,"onUpdate:modelValue":e[1]||(e[1]=v=>a.password=v),type:"password",placeholder:"请输入密码","show-password":""},null,8,["modelValue"])]),_:1}),n("div",ie,[s(x,null,{default:t(()=>[...e[2]||(e[2]=[y("记住密码",-1)])]),_:1}),s(F,{type:"primary",underline:!1},{default:t(()=>[...e[3]||(e[3]=[y("忘记密码?",-1)])]),_:1})]),s(I,{type:"primary",class:"login-btn",loading:r.value,onClick:d},{default:t(()=>[...e[4]||(e[4]=[y(" 登录 ",-1)])]),_:1},8,["loading"])]),_:1},8,["model"])]),e[7]||(e[7]=n("footer",null,"© 2026 远光软件",-1))])])}}}),Ee=Y(de,[["__scopeId","data-v-5b789cef"]]);export{Ee as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{E as A}from"./el-alert-DBfM1mZE.js";import{a as N,E as T}from"./el-form-item-Ct_zBuY0.js";import{E as B}from"./index-CbmPSBt0.js";import{E as I}from"./index-CCavIuTY.js";import{E as R}from"./el-tag-C_D80BPW.js";import{d as P,z as q,G as D,e as r,w as t,j as y,y as E,o as n,s as a,f as F,ar as U,x as m,aa as W,c as j,g as z,A as M,v as G,ac as H}from"./index-CGB0A5x_.js";import{P as L}from"./PageCard-D1lOaeEG.js";import{a as O,m as S}from"./model-xlHsHa68.js";import{_ as J}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./vnode-DFpZw5lG.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./index-DMVRI44M.js";import"./el-card-BWcR1iD2.js";const K={key:0,class:"model-status"},Q=P({__name:"MergeWeightsView",setup(X){const v=H(),b=G(),s=E(!1),u=y(()=>v.query.model||""),w=y(()=>v.query.method||"lora"),i=E([]),_=y(()=>i.value.find(l=>l.name===u.value)),o=q({model_name:u.value,train_method:w.value,base_model_path:""});async function V(){try{const l=await O();i.value=(l==null?void 0:l.models)||[];const e=i.value.find(p=>p.name===u.value);o.base_model_path=(e==null?void 0:e.base_model_path)||""}catch{}}async function k(){if(!o.model_name||!o.base_model_path){M.warning("缺少模型信息");return}s.value=!0;try{await S({model_name:o.model_name,train_method:o.train_method,base_model_path:o.base_model_path}),M.success("合并成功"),b.push("/model-manage")}catch{}finally{s.value=!1}}function x(){b.back()}return D(V),(l,e)=>{const p=A,f=B,d=N,h=I,C=T,c=R;return n(),r(L,{title:"合并权重"},{default:t(()=>[a(p,{type:"info",closable:!1,"show-icon":"",title:"将 LoRA 适配器权重合并到基座模型,合并后可直接用于推理部署。",style:{"margin-bottom":"20px"}}),a(C,{"label-width":"120px",style:{"max-width":"600px"}},{default:t(()=>[a(d,{label:"模型名称"},{default:t(()=>[a(f,{modelValue:o.model_name,"onUpdate:modelValue":e[0]||(e[0]=g=>o.model_name=g),disabled:""},null,8,["modelValue"])]),_:1}),a(d,{label:"训练方法"},{default:t(()=>[a(f,{"model-value":F(U)[o.train_method]||o.train_method,disabled:""},null,8,["model-value"])]),_:1}),a(d,{label:"基座模型路径"},{default:t(()=>[a(f,{modelValue:o.base_model_path,"onUpdate:modelValue":e[1]||(e[1]=g=>o.base_model_path=g),placeholder:"基座模型路径"},null,8,["modelValue"])]),_:1}),a(d,null,{default:t(()=>[a(h,{type:"primary",loading:s.value,onClick:k},{default:t(()=>[m(W(s.value?"合并中...":"开始合并"),1)]),_:1},8,["loading"]),a(h,{onClick:x},{default:t(()=>[...e[2]||(e[2]=[m("取消",-1)])]),_:1})]),_:1})]),_:1}),_.value?(n(),j("div",K,[_.value.merging?(n(),r(c,{key:0,type:"warning"},{default:t(()=>[...e[3]||(e[3]=[m("合并中",-1)])]),_:1})):_.value.merged?(n(),r(c,{key:1,type:"success"},{default:t(()=>[...e[4]||(e[4]=[m("已合并",-1)])]),_:1})):(n(),r(c,{key:2,type:"info"},{default:t(()=>[...e[5]||(e[5]=[m("未合并",-1)])]),_:1}))])):z("",!0)]),_:1})}}}),pe=J(Q,[["__scopeId","data-v-2d4f1cb8"]]);export{pe as default};
import{E as A}from"./el-alert-B_M4eVTG.js";import{a as N,E as T}from"./el-form-item-BMccCMQS.js";import{E as B}from"./index-CxrDRhwR.js";import{E as I}from"./index-9zpOHVFd.js";import{E as R}from"./el-tag-DPsbND_Z.js";import{d as P,z as q,G as D,e as r,w as t,j as y,y as E,o as n,s as a,f as F,ar as U,x as m,aa as W,c as j,g as z,A as M,v as G,ac as H}from"./index-Dd84m4NL.js";import{P as L}from"./PageCard-Bj5UBPkt.js";import{a as O,m as S}from"./model-SG-pVLXE.js";import{_ as J}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./vnode-CasYkit1.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./index-DEuQ2B0Z.js";import"./el-card-WMAJU1WK.js";const K={key:0,class:"model-status"},Q=P({__name:"MergeWeightsView",setup(X){const v=H(),b=G(),s=E(!1),u=y(()=>v.query.model||""),w=y(()=>v.query.method||"lora"),i=E([]),_=y(()=>i.value.find(l=>l.name===u.value)),o=q({model_name:u.value,train_method:w.value,base_model_path:""});async function V(){try{const l=await O();i.value=(l==null?void 0:l.models)||[];const e=i.value.find(p=>p.name===u.value);o.base_model_path=(e==null?void 0:e.base_model_path)||""}catch{}}async function k(){if(!o.model_name||!o.base_model_path){M.warning("缺少模型信息");return}s.value=!0;try{await S({model_name:o.model_name,train_method:o.train_method,base_model_path:o.base_model_path}),M.success("合并成功"),b.push("/model-manage")}catch{}finally{s.value=!1}}function x(){b.back()}return D(V),(l,e)=>{const p=A,f=B,d=N,h=I,C=T,c=R;return n(),r(L,{title:"合并权重"},{default:t(()=>[a(p,{type:"info",closable:!1,"show-icon":"",title:"将 LoRA 适配器权重合并到基座模型,合并后可直接用于推理部署。",style:{"margin-bottom":"20px"}}),a(C,{"label-width":"120px",style:{"max-width":"600px"}},{default:t(()=>[a(d,{label:"模型名称"},{default:t(()=>[a(f,{modelValue:o.model_name,"onUpdate:modelValue":e[0]||(e[0]=g=>o.model_name=g),disabled:""},null,8,["modelValue"])]),_:1}),a(d,{label:"训练方法"},{default:t(()=>[a(f,{"model-value":F(U)[o.train_method]||o.train_method,disabled:""},null,8,["model-value"])]),_:1}),a(d,{label:"基座模型路径"},{default:t(()=>[a(f,{modelValue:o.base_model_path,"onUpdate:modelValue":e[1]||(e[1]=g=>o.base_model_path=g),placeholder:"基座模型路径"},null,8,["modelValue"])]),_:1}),a(d,null,{default:t(()=>[a(h,{type:"primary",loading:s.value,onClick:k},{default:t(()=>[m(W(s.value?"合并中...":"开始合并"),1)]),_:1},8,["loading"]),a(h,{onClick:x},{default:t(()=>[...e[2]||(e[2]=[m("取消",-1)])]),_:1})]),_:1})]),_:1}),_.value?(n(),j("div",K,[_.value.merging?(n(),r(c,{key:0,type:"warning"},{default:t(()=>[...e[3]||(e[3]=[m("合并中",-1)])]),_:1})):_.value.merged?(n(),r(c,{key:1,type:"success"},{default:t(()=>[...e[4]||(e[4]=[m("已合并",-1)])]),_:1})):(n(),r(c,{key:2,type:"info"},{default:t(()=>[...e[5]||(e[5]=[m("未合并",-1)])]),_:1}))])):z("",!0)]),_:1})}}}),pe=J(Q,[["__scopeId","data-v-2d4f1cb8"]]);export{pe as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{E as o}from"./el-tag-C_D80BPW.js";import{d as p,e as n,w as r,j as c,o as l,x as u,aa as m}from"./index-CGB0A5x_.js";import{s as _,a as i}from"./status-Dl1fykxa.js";const T=p({__name:"ModelStatusTag",props:{status:{}},setup(e){const t=e,a=c(()=>({text:i(t.status),type:_(t.status)}));return(f,g)=>{const s=o;return l(),n(s,{type:a.value.type,size:"small",effect:"light"},{default:r(()=>[u(m(a.value.text),1)]),_:1},8,["type"])}}});export{T as _};
import{E as o}from"./el-tag-DPsbND_Z.js";import{d as p,e as n,w as r,j as c,o as l,x as u,aa as m}from"./index-Dd84m4NL.js";import{s as _,a as i}from"./status-Dl1fykxa.js";const T=p({__name:"ModelStatusTag",props:{status:{}},setup(e){const t=e,a=c(()=>({text:i(t.status),type:_(t.status)}));return(f,g)=>{const s=o;return l(),n(s,{type:a.value.type,size:"small",effect:"light"},{default:r(()=>[u(m(a.value.text),1)]),_:1},8,["type"])}}});export{T as _};

View File

@@ -1 +1 @@
import{E as i}from"./el-card-BWcR1iD2.js";import{d as n,e as u,w as p,o as a,c as s,h as o,g as r,q as d,aa as l}from"./index-CGB0A5x_.js";import{_}from"./_plugin-vue_export-helper-DlAUqK2U.js";const h={key:0,class:"page-card-header"},m={class:"page-card-title"},f={key:0,class:"page-card-subtitle"},g={key:0,class:"page-card-extra"},v={class:"page-card-body"},b=n({__name:"PageCard",props:{title:{},subtitle:{},bordered:{type:Boolean,default:!1}},setup(t){return(e,k)=>{const c=i;return a(),u(c,{shadow:"never",class:"page-card"},{default:p(()=>[t.title||e.$slots.header?(a(),s("div",h,[o(e.$slots,"header",{},()=>[d("div",null,[d("h2",m,l(t.title),1),t.subtitle?(a(),s("p",f,l(t.subtitle),1)):r("",!0)])],!0),e.$slots.extra?(a(),s("div",g,[o(e.$slots,"extra",{},void 0,!0)])):r("",!0)])):r("",!0),d("div",v,[o(e.$slots,"default",{},void 0,!0)])]),_:3})}}}),$=_(b,[["__scopeId","data-v-4478be23"]]);export{$ as P};
import{E as i}from"./el-card-WMAJU1WK.js";import{d as n,e as u,w as p,o as a,c as s,h as o,g as r,q as d,aa as l}from"./index-Dd84m4NL.js";import{_}from"./_plugin-vue_export-helper-DlAUqK2U.js";const h={key:0,class:"page-card-header"},m={class:"page-card-title"},f={key:0,class:"page-card-subtitle"},g={key:0,class:"page-card-extra"},v={class:"page-card-body"},b=n({__name:"PageCard",props:{title:{},subtitle:{},bordered:{type:Boolean,default:!1}},setup(t){return(e,k)=>{const c=i;return a(),u(c,{shadow:"never",class:"page-card"},{default:p(()=>[t.title||e.$slots.header?(a(),s("div",h,[o(e.$slots,"header",{},()=>[d("div",null,[d("h2",m,l(t.title),1),t.subtitle?(a(),s("p",f,l(t.subtitle),1)):r("",!0)])],!0),e.$slots.extra?(a(),s("div",g,[o(e.$slots,"extra",{},void 0,!0)])):r("",!0)])):r("",!0),d("div",v,[o(e.$slots,"default",{},void 0,!0)])]),_:3})}}}),$=_(b,[["__scopeId","data-v-4478be23"]]);export{$ as P};

View File

@@ -1 +1 @@
import{_ as o}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o as t,c as n,q as s}from"./index-CGB0A5x_.js";const r={},a={class:"simple-page"};function c(i,e){return t(),n("section",a,[...e[0]||(e[0]=[s("h1",null,"无权访问",-1),s("p",null,"当前账号没有访问该页面的权限,请联系管理员调整角色或页面权限。",-1)])])}const d=o(r,[["render",c],["__scopeId","data-v-9fad40f6"]]);export{d as default};
import{_ as o}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o as t,c as n,q as s}from"./index-Dd84m4NL.js";const r={},a={class:"simple-page"};function c(i,e){return t(),n("section",a,[...e[0]||(e[0]=[s("h1",null,"无权访问",-1),s("p",null,"当前账号没有访问该页面的权限,请联系管理员调整角色或页面权限。",-1)])])}const d=o(r,[["render",c],["__scopeId","data-v-9fad40f6"]]);export{d as default};

View File

@@ -1 +1 @@
import{a as y,E as h}from"./el-form-item-Ct_zBuY0.js";import{E as B}from"./index-CbmPSBt0.js";import{E as R}from"./index-CCavIuTY.js";import{d as S,G as I,e as N,w as l,j as g,z as O,o as m,s as o,q as v,c as x,ad as U,n as V,f as q,bx as F,M as L,x as b,aa as M,A as w,y as j,v as z,ac as D}from"./index-CGB0A5x_.js";import{P}from"./PageCard-D1lOaeEG.js";import{u as A}from"./tools-XKLlGqEK.js";import{_ as G}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./index-DMVRI44M.js";import"./el-card-BWcR1iD2.js";const $={class:"icon-grid"},H=["onClick"],J=S({__name:"ToolCreateView",setup(K){const d=D(),p=z(),n=A(),i=j(),s=g(()=>d.params.id!=null),c=g(()=>s.value?n.getTool(d.params.id):void 0),e=O({id:"",name:"",description:"",url:"",icon:"fa-cog"}),C={name:[{required:!0,message:"请输入工具名称",trigger:"blur"},{max:30,message:"不超过 30 字符",trigger:"blur"}],url:[{required:!0,message:"请输入跳转地址",trigger:"blur"}]};function k(){i.value&&i.value.validate(f=>{f&&(s.value?(n.updateTool(e.id,{...e}),w.success("更新成功")):(n.addTool({...e,id:"custom_"+Date.now()}),w.success("添加成功")),p.push("/tools"))})}function E(){p.back()}return I(()=>{c.value&&Object.assign(e,c.value)}),(f,a)=>{const u=B,r=y,_=R,T=h;return m(),N(P,{title:s.value?"编辑自定义工具":"添加自定义工具"},{default:l(()=>[o(T,{ref_key:"formRef",ref:i,model:e,rules:C,"label-width":"100px",style:{"max-width":"600px"}},{default:l(()=>[o(r,{label:"工具名称",prop:"name"},{default:l(()=>[o(u,{modelValue:e.name,"onUpdate:modelValue":a[0]||(a[0]=t=>e.name=t),placeholder:"请输入工具名称",maxlength:"30","show-word-limit":""},null,8,["modelValue"])]),_:1}),o(r,{label:"工具描述"},{default:l(()=>[o(u,{modelValue:e.description,"onUpdate:modelValue":a[1]||(a[1]=t=>e.description=t),type:"textarea",rows:2,maxlength:"100","show-word-limit":""},null,8,["modelValue"])]),_:1}),o(r,{label:"跳转地址",prop:"url"},{default:l(()=>[o(u,{modelValue:e.url,"onUpdate:modelValue":a[2]||(a[2]=t=>e.url=t),placeholder:"相对路径或完整 URL"},null,8,["modelValue"])]),_:1}),o(r,{label:"图标"},{default:l(()=>[v("div",$,[(m(!0),x(L,null,U(q(F),t=>(m(),x("div",{key:t,class:V(["icon-option",{selected:e.icon===t}]),onClick:Q=>e.icon=t},[v("i",{class:V(["fa",t])},null,2)],10,H))),128))])]),_:1}),o(r,null,{default:l(()=>[o(_,{type:"primary",onClick:k},{default:l(()=>[b(M(s.value?"保存":"添加"),1)]),_:1}),o(_,{onClick:E},{default:l(()=>[...a[3]||(a[3]=[b("取消",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1},8,["title"])}}}),ue=G(J,[["__scopeId","data-v-249def81"]]);export{ue as default};
import{a as y,E as h}from"./el-form-item-BMccCMQS.js";import{E as B}from"./index-CxrDRhwR.js";import{E as R}from"./index-9zpOHVFd.js";import{d as S,G as I,e as N,w as l,j as g,z as O,o as m,s as o,q as v,c as x,ad as U,n as V,f as q,bx as F,M as L,x as b,aa as M,A as w,y as j,v as z,ac as D}from"./index-Dd84m4NL.js";import{P}from"./PageCard-Bj5UBPkt.js";import{u as A}from"./tools-CHnia2_O.js";import{_ as G}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./index-DEuQ2B0Z.js";import"./el-card-WMAJU1WK.js";const $={class:"icon-grid"},H=["onClick"],J=S({__name:"ToolCreateView",setup(K){const d=D(),p=z(),n=A(),i=j(),s=g(()=>d.params.id!=null),c=g(()=>s.value?n.getTool(d.params.id):void 0),e=O({id:"",name:"",description:"",url:"",icon:"fa-cog"}),C={name:[{required:!0,message:"请输入工具名称",trigger:"blur"},{max:30,message:"不超过 30 字符",trigger:"blur"}],url:[{required:!0,message:"请输入跳转地址",trigger:"blur"}]};function k(){i.value&&i.value.validate(f=>{f&&(s.value?(n.updateTool(e.id,{...e}),w.success("更新成功")):(n.addTool({...e,id:"custom_"+Date.now()}),w.success("添加成功")),p.push("/tools"))})}function E(){p.back()}return I(()=>{c.value&&Object.assign(e,c.value)}),(f,a)=>{const u=B,r=y,_=R,T=h;return m(),N(P,{title:s.value?"编辑自定义工具":"添加自定义工具"},{default:l(()=>[o(T,{ref_key:"formRef",ref:i,model:e,rules:C,"label-width":"100px",style:{"max-width":"600px"}},{default:l(()=>[o(r,{label:"工具名称",prop:"name"},{default:l(()=>[o(u,{modelValue:e.name,"onUpdate:modelValue":a[0]||(a[0]=t=>e.name=t),placeholder:"请输入工具名称",maxlength:"30","show-word-limit":""},null,8,["modelValue"])]),_:1}),o(r,{label:"工具描述"},{default:l(()=>[o(u,{modelValue:e.description,"onUpdate:modelValue":a[1]||(a[1]=t=>e.description=t),type:"textarea",rows:2,maxlength:"100","show-word-limit":""},null,8,["modelValue"])]),_:1}),o(r,{label:"跳转地址",prop:"url"},{default:l(()=>[o(u,{modelValue:e.url,"onUpdate:modelValue":a[2]||(a[2]=t=>e.url=t),placeholder:"相对路径或完整 URL"},null,8,["modelValue"])]),_:1}),o(r,{label:"图标"},{default:l(()=>[v("div",$,[(m(!0),x(L,null,U(q(F),t=>(m(),x("div",{key:t,class:V(["icon-option",{selected:e.icon===t}]),onClick:Q=>e.icon=t},[v("i",{class:V(["fa",t])},null,2)],10,H))),128))])]),_:1}),o(r,null,{default:l(()=>[o(_,{type:"primary",onClick:k},{default:l(()=>[b(M(s.value?"保存":"添加"),1)]),_:1}),o(_,{onClick:E},{default:l(()=>[...a[3]||(a[3]=[b("取消",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1},8,["title"])}}}),ue=G(J,[["__scopeId","data-v-249def81"]]);export{ue as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{E as y,a as x}from"./el-form-item-Ct_zBuY0.js";import{E as k}from"./index-CbmPSBt0.js";import{E as U}from"./index-CCavIuTY.js";import{E as C,a as B}from"./el-select-C59URVI0.js";import{a as F,E as I}from"./el-checkbox-Ci1DH0Aj.js";import{E as N,b as R}from"./el-radio-group-B7nPUe8-.js";import{d as G,c as f,q as M,s as o,w as l,o as _,x as r,M as O,ad as S,aa as q,f as z,v as A,y as D,z as L,db as T,A as $}from"./index-CGB0A5x_.js";/* empty css */import"./el-scrollbar-p6_f_LH2.js";import"./el-popper-DvBtRO32.js";import"./el-tag-C_D80BPW.js";import{_ as j}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cgg396Sr.js";import"./_baseClone-CX1E8HTZ.js";import"./raf-CCivjDro.js";import"./index-D2-3cnGo.js";import"./index-DMVRI44M.js";import"./index-BPwPlcbL.js";import"./vnode-DFpZw5lG.js";import"./index-khuXz7sd.js";import"./scroll-C0BSy_Rk.js";import"./clamp-BqqU4KQ-.js";import"./toNumber-IRhFg6gN.js";import"./_baseIteratee-uVh0OyD5.js";import"./omit-DaFv1hTo.js";const H={class:"user-create"},J=G({__name:"UserCreateView",setup(K){const d=A(),n=D(!1),a=L({username:"",display_name:"",password:"platform123",role:"viewer",status:"active",permissions:["dashboard"]}),b=["dashboard","fine-tune","model-eval","model-inference","model-manage","dataset","data-process","data-convert","compute","hardware","logs","user-settings"];async function V(){n.value=!0;try{await T(a),$.success("用户已创建"),d.push("/user-settings")}finally{n.value=!1}}return(P,e)=>{const m=k,s=x,u=B,v=C,p=R,c=N,E=I,w=F,i=U,g=y;return _(),f("section",H,[e[11]||(e[11]=M("h1",null,"创建用户",-1)),o(g,{model:a,"label-width":"110px",class:"user-form"},{default:l(()=>[o(s,{label:"账号"},{default:l(()=>[o(m,{modelValue:a.username,"onUpdate:modelValue":e[0]||(e[0]=t=>a.username=t)},null,8,["modelValue"])]),_:1}),o(s,{label:"显示名称"},{default:l(()=>[o(m,{modelValue:a.display_name,"onUpdate:modelValue":e[1]||(e[1]=t=>a.display_name=t)},null,8,["modelValue"])]),_:1}),o(s,{label:"初始密码"},{default:l(()=>[o(m,{modelValue:a.password,"onUpdate:modelValue":e[2]||(e[2]=t=>a.password=t),type:"password","show-password":""},null,8,["modelValue"])]),_:1}),o(s,{label:"角色"},{default:l(()=>[o(v,{modelValue:a.role,"onUpdate:modelValue":e[3]||(e[3]=t=>a.role=t)},{default:l(()=>[o(u,{label:"管理员",value:"admin"}),o(u,{label:"操作员",value:"operator"}),o(u,{label:"观察员",value:"viewer"})]),_:1},8,["modelValue"])]),_:1}),o(s,{label:"状态"},{default:l(()=>[o(c,{modelValue:a.status,"onUpdate:modelValue":e[4]||(e[4]=t=>a.status=t)},{default:l(()=>[o(p,{value:"active"},{default:l(()=>[...e[7]||(e[7]=[r("启用",-1)])]),_:1}),o(p,{value:"disabled"},{default:l(()=>[...e[8]||(e[8]=[r("禁用",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),o(s,{label:"页面权限"},{default:l(()=>[o(w,{modelValue:a.permissions,"onUpdate:modelValue":e[5]||(e[5]=t=>a.permissions=t)},{default:l(()=>[(_(),f(O,null,S(b,t=>o(E,{key:t,value:t},{default:l(()=>[r(q(t),1)]),_:2},1032,["value"])),64))]),_:1},8,["modelValue"])]),_:1}),o(s,null,{default:l(()=>[o(i,{onClick:e[6]||(e[6]=t=>z(d).back())},{default:l(()=>[...e[9]||(e[9]=[r("返回",-1)])]),_:1}),o(i,{type:"primary",loading:n.value,onClick:V},{default:l(()=>[...e[10]||(e[10]=[r("保存",-1)])]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"])])}}}),Ee=j(J,[["__scopeId","data-v-af832a20"]]);export{Ee as default};
import{E as y,a as x}from"./el-form-item-BMccCMQS.js";import{E as k}from"./index-CxrDRhwR.js";import{E as U}from"./index-9zpOHVFd.js";import{E as C,a as B}from"./el-select-DinjeS4W.js";import{a as F,E as I}from"./el-checkbox-DmCZOH3C.js";import{E as N,b as R}from"./el-radio-group-WtTCRL8H.js";import{d as G,c as f,q as M,s as o,w as l,o as _,x as r,M as O,ad as S,aa as q,f as z,v as A,y as D,z as L,db as T,A as $}from"./index-Dd84m4NL.js";/* empty css */import"./el-scrollbar-CnqWU4CY.js";import"./el-popper-CXiDZrHI.js";import"./el-tag-DPsbND_Z.js";import{_ as j}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./castArray-Cc7cuNko.js";import"./_baseClone-C6YdWYHR.js";import"./raf-CGf5YZRu.js";import"./index-BkMrw1Qg.js";import"./index-DEuQ2B0Z.js";import"./index-KnEmF0FL.js";import"./vnode-CasYkit1.js";import"./index-C5oiM9Uu.js";import"./scroll-CJw98M_S.js";import"./clamp-MxoDdpzk.js";import"./toNumber-Dzu6kJGs.js";import"./_baseIteratee-CfOSjoYo.js";import"./omit-njl9pMBF.js";const H={class:"user-create"},J=G({__name:"UserCreateView",setup(K){const d=A(),n=D(!1),a=L({username:"",display_name:"",password:"platform123",role:"viewer",status:"active",permissions:["dashboard"]}),b=["dashboard","fine-tune","model-eval","model-inference","model-manage","dataset","data-process","data-convert","compute","hardware","logs","user-settings"];async function V(){n.value=!0;try{await T(a),$.success("用户已创建"),d.push("/user-settings")}finally{n.value=!1}}return(P,e)=>{const m=k,s=x,u=B,v=C,p=R,c=N,E=I,w=F,i=U,g=y;return _(),f("section",H,[e[11]||(e[11]=M("h1",null,"创建用户",-1)),o(g,{model:a,"label-width":"110px",class:"user-form"},{default:l(()=>[o(s,{label:"账号"},{default:l(()=>[o(m,{modelValue:a.username,"onUpdate:modelValue":e[0]||(e[0]=t=>a.username=t)},null,8,["modelValue"])]),_:1}),o(s,{label:"显示名称"},{default:l(()=>[o(m,{modelValue:a.display_name,"onUpdate:modelValue":e[1]||(e[1]=t=>a.display_name=t)},null,8,["modelValue"])]),_:1}),o(s,{label:"初始密码"},{default:l(()=>[o(m,{modelValue:a.password,"onUpdate:modelValue":e[2]||(e[2]=t=>a.password=t),type:"password","show-password":""},null,8,["modelValue"])]),_:1}),o(s,{label:"角色"},{default:l(()=>[o(v,{modelValue:a.role,"onUpdate:modelValue":e[3]||(e[3]=t=>a.role=t)},{default:l(()=>[o(u,{label:"管理员",value:"admin"}),o(u,{label:"操作员",value:"operator"}),o(u,{label:"观察员",value:"viewer"})]),_:1},8,["modelValue"])]),_:1}),o(s,{label:"状态"},{default:l(()=>[o(c,{modelValue:a.status,"onUpdate:modelValue":e[4]||(e[4]=t=>a.status=t)},{default:l(()=>[o(p,{value:"active"},{default:l(()=>[...e[7]||(e[7]=[r("启用",-1)])]),_:1}),o(p,{value:"disabled"},{default:l(()=>[...e[8]||(e[8]=[r("禁用",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),o(s,{label:"页面权限"},{default:l(()=>[o(w,{modelValue:a.permissions,"onUpdate:modelValue":e[5]||(e[5]=t=>a.permissions=t)},{default:l(()=>[(_(),f(O,null,S(b,t=>o(E,{key:t,value:t},{default:l(()=>[r(q(t),1)]),_:2},1032,["value"])),64))]),_:1},8,["modelValue"])]),_:1}),o(s,null,{default:l(()=>[o(i,{onClick:e[6]||(e[6]=t=>z(d).back())},{default:l(()=>[...e[9]||(e[9]=[r("返回",-1)])]),_:1}),o(i,{type:"primary",loading:n.value,onClick:V},{default:l(()=>[...e[10]||(e[10]=[r("保存",-1)])]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"])])}}}),Ee=j(J,[["__scopeId","data-v-af832a20"]]);export{Ee as default};

View File

@@ -1 +1 @@
import{_ as o}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o as t,c as r,q as s}from"./index-CGB0A5x_.js";const a={},c={class:"simple-page"};function n(_,e){return t(),r("section",c,[...e[0]||(e[0]=[s("h1",null,"权限设置",-1),s("p",null,"第一版已支持账号页面权限读取与保存,精细化项目/模型/数据集权限将在后续版本补齐。",-1)])])}const p=o(a,[["render",n],["__scopeId","data-v-49c3a2ea"]]);export{p as default};
import{_ as o}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{o as t,c as r,q as s}from"./index-Dd84m4NL.js";const a={},c={class:"simple-page"};function n(_,e){return t(),r("section",c,[...e[0]||(e[0]=[s("h1",null,"权限设置",-1),s("p",null,"第一版已支持账号页面权限读取与保存,精细化项目/模型/数据集权限将在后续版本补齐。",-1)])])}const p=o(a,[["render",n],["__scopeId","data-v-49c3a2ea"]]);export{p as default};

View File

@@ -1 +1 @@
import{E as w}from"./index-CCavIuTY.js";import{E as y}from"./el-tag-C_D80BPW.js";import{a as h,E}from"./el-table-DkdQ6gPU.js";import{v as T}from"./directive-vzjADwzS.js";import{d as x,G as V,K as B,c as C,q as r,s as t,w as o,y as m,da as U,o as k,x as i,f as d,aa as u}from"./index-CGB0A5x_.js";import"./el-scrollbar-p6_f_LH2.js";import"./el-popper-DvBtRO32.js";import"./el-tooltip-l0sNRNKZ.js";import"./el-checkbox-Ci1DH0Aj.js";import{s as N,a as S}from"./status-Dl1fykxa.js";import{_ as D}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./_baseClone-CX1E8HTZ.js";import"./index-DMVRI44M.js";import"./_baseIteratee-uVh0OyD5.js";import"./castArray-Cgg396Sr.js";import"./debounce-Bqww2DS8.js";import"./toNumber-IRhFg6gN.js";import"./index-BPwPlcbL.js";import"./raf-CCivjDro.js";import"./omit-DaFv1hTo.js";const L={class:"user-settings"},$={class:"page-header"},q=x({__name:"UserSettingsView",setup(z){const l=m(!1),n=m([]);async function _(){l.value=!0;try{n.value=await U()}finally{l.value=!1}}return V(_),(c,e)=>{const f=w,a=E,g=y,b=h,v=T;return B((k(),C("section",L,[r("header",$,[e[2]||(e[2]=r("div",null,[r("h1",null,"用户设置"),r("p",null,"管理平台账号、角色状态和页面权限。")],-1)),t(f,{type:"primary",onClick:e[0]||(e[0]=s=>c.$router.push("/user-settings/create"))},{default:o(()=>[...e[1]||(e[1]=[i("创建用户",-1)])]),_:1})]),t(b,{data:n.value},{default:o(()=>[t(a,{prop:"username",label:"账号","min-width":"140"}),t(a,{prop:"display_name",label:"显示名称","min-width":"160"}),t(a,{prop:"role",label:"角色",width:"120"}),t(a,{label:"状态",width:"120"},{default:o(({row:s})=>[t(g,{type:d(N)(s.status),size:"small"},{default:o(()=>[i(u(d(S)(s.status)),1)]),_:2},1032,["type"])]),_:1}),t(a,{label:"权限数",width:"120"},{default:o(({row:s})=>{var p;return[i(u(((p=s.permissions)==null?void 0:p.length)||0),1)]}),_:1}),t(a,{prop:"create_time",label:"创建时间","min-width":"180"})]),_:1},8,["data"])])),[[v,l.value]])}}}),st=D(q,[["__scopeId","data-v-16fa3de4"]]);export{st as default};
import{E as w}from"./index-9zpOHVFd.js";import{E as y}from"./el-tag-DPsbND_Z.js";import{a as h,E}from"./el-table-CknU6KUt.js";import{v as T}from"./directive-CGqZKDhv.js";import{d as x,G as V,K as B,c as C,q as r,s as t,w as o,y as m,da as U,o as k,x as i,f as d,aa as u}from"./index-Dd84m4NL.js";import"./el-scrollbar-CnqWU4CY.js";import"./el-popper-CXiDZrHI.js";import"./el-tooltip-l0sNRNKZ.js";import"./el-checkbox-DmCZOH3C.js";import{s as N,a as S}from"./status-Dl1fykxa.js";import{_ as D}from"./_plugin-vue_export-helper-DlAUqK2U.js";import"./_baseClone-C6YdWYHR.js";import"./index-DEuQ2B0Z.js";import"./_baseIteratee-CfOSjoYo.js";import"./castArray-Cc7cuNko.js";import"./debounce-CqM0EiuE.js";import"./toNumber-Dzu6kJGs.js";import"./index-KnEmF0FL.js";import"./raf-CGf5YZRu.js";import"./omit-njl9pMBF.js";const L={class:"user-settings"},$={class:"page-header"},q=x({__name:"UserSettingsView",setup(z){const l=m(!1),n=m([]);async function _(){l.value=!0;try{n.value=await U()}finally{l.value=!1}}return V(_),(c,e)=>{const f=w,a=E,g=y,b=h,v=T;return B((k(),C("section",L,[r("header",$,[e[2]||(e[2]=r("div",null,[r("h1",null,"用户设置"),r("p",null,"管理平台账号、角色状态和页面权限。")],-1)),t(f,{type:"primary",onClick:e[0]||(e[0]=s=>c.$router.push("/user-settings/create"))},{default:o(()=>[...e[1]||(e[1]=[i("创建用户",-1)])]),_:1})]),t(b,{data:n.value},{default:o(()=>[t(a,{prop:"username",label:"账号","min-width":"140"}),t(a,{prop:"display_name",label:"显示名称","min-width":"160"}),t(a,{prop:"role",label:"角色",width:"120"}),t(a,{label:"状态",width:"120"},{default:o(({row:s})=>[t(g,{type:d(N)(s.status),size:"small"},{default:o(()=>[i(u(d(S)(s.status)),1)]),_:2},1032,["type"])]),_:1}),t(a,{label:"权限数",width:"120"},{default:o(({row:s})=>{var p;return[i(u(((p=s.permissions)==null?void 0:p.length)||0),1)]}),_:1}),t(a,{prop:"create_time",label:"创建时间","min-width":"180"})]),_:1},8,["data"])])),[[v,l.value]])}}}),st=D(q,[["__scopeId","data-v-16fa3de4"]]);export{st as default};

View File

@@ -1 +1 @@
import{cs as T,ct as Q,cu as U,cv as B,cw as X,cx as Z,cy as M,cz as V,cA as D,cB as z,cj as k,cC as G,cD as ee,cE as m,ch as O,cF as K,cG as d,cH as N,cI as b,cJ as re,cK as te,ce as ne,cL as ae}from"./index-CGB0A5x_.js";var S=Object.create,oe=(function(){function e(){}return function(r){if(!T(r))return{};if(S)return S(r);e.prototype=r;var t=new e;return e.prototype=void 0,t}})();function se(e,r){var t=-1,a=e.length;for(r||(r=Array(a));++t<a;)r[t]=e[t];return r}function ce(e,r){for(var t=-1,a=e==null?0:e.length;++t<a&&r(e[t],t,e)!==!1;);return e}function y(e,r,t,a){var g=!t;t||(t={});for(var s=-1,o=r.length;++s<o;){var i=r[s],c=void 0;c===void 0&&(c=e[i]),g?Q(t,i,c):U(t,i,c)}return t}function ie(e){var r=[];if(e!=null)for(var t in Object(e))r.push(t);return r}var fe=Object.prototype,ue=fe.hasOwnProperty;function ge(e){if(!T(e))return ie(e);var r=B(e),t=[];for(var a in e)a=="constructor"&&(r||!ue.call(e,a))||t.push(a);return t}function A(e){return X(e)?Z(e,!0):ge(e)}function le(e,r){return e&&y(r,M(r),e)}function be(e,r){return e&&y(r,A(r),e)}var _=typeof exports=="object"&&exports&&!exports.nodeType&&exports,x=_&&typeof module=="object"&&module&&!module.nodeType&&module,ye=x&&x.exports===_,I=ye?V.Buffer:void 0,C=I?I.allocUnsafe:void 0;function pe(e,r){if(r)return e.slice();var t=e.length,a=C?C(t):new e.constructor(t);return e.copy(a),a}function Te(e,r){return y(e,D(e),r)}var de=Object.getOwnPropertySymbols,R=de?function(e){for(var r=[];e;)k(r,D(e)),e=G(e);return r}:z;function Ae(e,r){return y(e,R(e),r)}function je(e){return ee(e,A,R)}var he=Object.prototype,we=he.hasOwnProperty;function ve(e){var r=e.length,t=new e.constructor(r);return r&&typeof e[0]=="string"&&we.call(e,"index")&&(t.index=e.index,t.input=e.input),t}function j(e){var r=new e.constructor(e.byteLength);return new m(r).set(new m(e)),r}function $e(e,r){var t=r?j(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.byteLength)}var me=/\w*$/;function Oe(e){var r=new e.constructor(e.source,me.exec(e));return r.lastIndex=e.lastIndex,r}var E=O?O.prototype:void 0,F=E?E.valueOf:void 0;function Se(e){return F?Object(F.call(e)):{}}function xe(e,r){var t=r?j(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.length)}var Ie="[object Boolean]",Ce="[object Date]",Ee="[object Map]",Fe="[object Number]",Le="[object RegExp]",Pe="[object Set]",Ue="[object String]",Be="[object Symbol]",Me="[object ArrayBuffer]",De="[object DataView]",Ge="[object Float32Array]",Ke="[object Float64Array]",Ne="[object Int8Array]",_e="[object Int16Array]",Re="[object Int32Array]",He="[object Uint8Array]",Je="[object Uint8ClampedArray]",We="[object Uint16Array]",Ye="[object Uint32Array]";function qe(e,r,t){var a=e.constructor;switch(r){case Me:return j(e);case Ie:case Ce:return new a(+e);case De:return $e(e,t);case Ge:case Ke:case Ne:case _e:case Re:case He:case Je:case We:case Ye:return xe(e,t);case Ee:return new a;case Fe:case Ue:return new a(e);case Le:return Oe(e);case Pe:return new a;case Be:return Se(e)}}function Qe(e){return typeof e.constructor=="function"&&!B(e)?oe(G(e)):{}}var Xe="[object Map]";function Ze(e){return K(e)&&d(e)==Xe}var L=b&&b.isMap,Ve=L?N(L):Ze,ze="[object Set]";function ke(e){return K(e)&&d(e)==ze}var P=b&&b.isSet,er=P?N(P):ke,rr=1,tr=2,nr=4,H="[object Arguments]",ar="[object Array]",or="[object Boolean]",sr="[object Date]",cr="[object Error]",J="[object Function]",ir="[object GeneratorFunction]",fr="[object Map]",ur="[object Number]",W="[object Object]",gr="[object RegExp]",lr="[object Set]",br="[object String]",yr="[object Symbol]",pr="[object WeakMap]",Tr="[object ArrayBuffer]",dr="[object DataView]",Ar="[object Float32Array]",jr="[object Float64Array]",hr="[object Int8Array]",wr="[object Int16Array]",vr="[object Int32Array]",$r="[object Uint8Array]",mr="[object Uint8ClampedArray]",Or="[object Uint16Array]",Sr="[object Uint32Array]",n={};n[H]=n[ar]=n[Tr]=n[dr]=n[or]=n[sr]=n[Ar]=n[jr]=n[hr]=n[wr]=n[vr]=n[fr]=n[ur]=n[W]=n[gr]=n[lr]=n[br]=n[yr]=n[$r]=n[mr]=n[Or]=n[Sr]=!0;n[cr]=n[J]=n[pr]=!1;function p(e,r,t,a,g,s){var o,i=r&rr,c=r&tr,Y=r&nr;if(t&&(o=g?t(e,a,g,s):t(e)),o!==void 0)return o;if(!T(e))return e;var h=ne(e);if(h){if(o=ve(e),!i)return se(e,o)}else{var l=d(e),w=l==J||l==ir;if(re(e))return pe(e,i);if(l==W||l==H||w&&!g){if(o=c||w?{}:Qe(e),!i)return c?Ae(e,be(o,e)):Te(e,le(o,e))}else{if(!n[l])return g?e:{};o=qe(e,l,i)}}s||(s=new te);var v=s.get(e);if(v)return v;s.set(e,o),er(e)?e.forEach(function(f){o.add(p(f,r,t,f,e,s))}):Ve(e)&&e.forEach(function(f,u){o.set(u,p(f,r,t,u,e,s))});var q=Y?c?je:ae:c?A:M,$=h?void 0:q(e);return ce($||e,function(f,u){$&&(u=f,f=e[u]),U(o,u,p(f,r,t,u,e,s))}),o}export{se as a,p as b,y as c,pe as d,xe as e,je as g,Qe as i,A as k};
import{cs as T,ct as Q,cu as U,cv as B,cw as X,cx as Z,cy as M,cz as V,cA as D,cB as z,cj as k,cC as G,cD as ee,cE as m,ch as O,cF as K,cG as d,cH as N,cI as b,cJ as re,cK as te,ce as ne,cL as ae}from"./index-Dd84m4NL.js";var S=Object.create,oe=(function(){function e(){}return function(r){if(!T(r))return{};if(S)return S(r);e.prototype=r;var t=new e;return e.prototype=void 0,t}})();function se(e,r){var t=-1,a=e.length;for(r||(r=Array(a));++t<a;)r[t]=e[t];return r}function ce(e,r){for(var t=-1,a=e==null?0:e.length;++t<a&&r(e[t],t,e)!==!1;);return e}function y(e,r,t,a){var g=!t;t||(t={});for(var s=-1,o=r.length;++s<o;){var i=r[s],c=void 0;c===void 0&&(c=e[i]),g?Q(t,i,c):U(t,i,c)}return t}function ie(e){var r=[];if(e!=null)for(var t in Object(e))r.push(t);return r}var fe=Object.prototype,ue=fe.hasOwnProperty;function ge(e){if(!T(e))return ie(e);var r=B(e),t=[];for(var a in e)a=="constructor"&&(r||!ue.call(e,a))||t.push(a);return t}function A(e){return X(e)?Z(e,!0):ge(e)}function le(e,r){return e&&y(r,M(r),e)}function be(e,r){return e&&y(r,A(r),e)}var _=typeof exports=="object"&&exports&&!exports.nodeType&&exports,x=_&&typeof module=="object"&&module&&!module.nodeType&&module,ye=x&&x.exports===_,I=ye?V.Buffer:void 0,C=I?I.allocUnsafe:void 0;function pe(e,r){if(r)return e.slice();var t=e.length,a=C?C(t):new e.constructor(t);return e.copy(a),a}function Te(e,r){return y(e,D(e),r)}var de=Object.getOwnPropertySymbols,R=de?function(e){for(var r=[];e;)k(r,D(e)),e=G(e);return r}:z;function Ae(e,r){return y(e,R(e),r)}function je(e){return ee(e,A,R)}var he=Object.prototype,we=he.hasOwnProperty;function ve(e){var r=e.length,t=new e.constructor(r);return r&&typeof e[0]=="string"&&we.call(e,"index")&&(t.index=e.index,t.input=e.input),t}function j(e){var r=new e.constructor(e.byteLength);return new m(r).set(new m(e)),r}function $e(e,r){var t=r?j(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.byteLength)}var me=/\w*$/;function Oe(e){var r=new e.constructor(e.source,me.exec(e));return r.lastIndex=e.lastIndex,r}var E=O?O.prototype:void 0,F=E?E.valueOf:void 0;function Se(e){return F?Object(F.call(e)):{}}function xe(e,r){var t=r?j(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.length)}var Ie="[object Boolean]",Ce="[object Date]",Ee="[object Map]",Fe="[object Number]",Le="[object RegExp]",Pe="[object Set]",Ue="[object String]",Be="[object Symbol]",Me="[object ArrayBuffer]",De="[object DataView]",Ge="[object Float32Array]",Ke="[object Float64Array]",Ne="[object Int8Array]",_e="[object Int16Array]",Re="[object Int32Array]",He="[object Uint8Array]",Je="[object Uint8ClampedArray]",We="[object Uint16Array]",Ye="[object Uint32Array]";function qe(e,r,t){var a=e.constructor;switch(r){case Me:return j(e);case Ie:case Ce:return new a(+e);case De:return $e(e,t);case Ge:case Ke:case Ne:case _e:case Re:case He:case Je:case We:case Ye:return xe(e,t);case Ee:return new a;case Fe:case Ue:return new a(e);case Le:return Oe(e);case Pe:return new a;case Be:return Se(e)}}function Qe(e){return typeof e.constructor=="function"&&!B(e)?oe(G(e)):{}}var Xe="[object Map]";function Ze(e){return K(e)&&d(e)==Xe}var L=b&&b.isMap,Ve=L?N(L):Ze,ze="[object Set]";function ke(e){return K(e)&&d(e)==ze}var P=b&&b.isSet,er=P?N(P):ke,rr=1,tr=2,nr=4,H="[object Arguments]",ar="[object Array]",or="[object Boolean]",sr="[object Date]",cr="[object Error]",J="[object Function]",ir="[object GeneratorFunction]",fr="[object Map]",ur="[object Number]",W="[object Object]",gr="[object RegExp]",lr="[object Set]",br="[object String]",yr="[object Symbol]",pr="[object WeakMap]",Tr="[object ArrayBuffer]",dr="[object DataView]",Ar="[object Float32Array]",jr="[object Float64Array]",hr="[object Int8Array]",wr="[object Int16Array]",vr="[object Int32Array]",$r="[object Uint8Array]",mr="[object Uint8ClampedArray]",Or="[object Uint16Array]",Sr="[object Uint32Array]",n={};n[H]=n[ar]=n[Tr]=n[dr]=n[or]=n[sr]=n[Ar]=n[jr]=n[hr]=n[wr]=n[vr]=n[fr]=n[ur]=n[W]=n[gr]=n[lr]=n[br]=n[yr]=n[$r]=n[mr]=n[Or]=n[Sr]=!0;n[cr]=n[J]=n[pr]=!1;function p(e,r,t,a,g,s){var o,i=r&rr,c=r&tr,Y=r&nr;if(t&&(o=g?t(e,a,g,s):t(e)),o!==void 0)return o;if(!T(e))return e;var h=ne(e);if(h){if(o=ve(e),!i)return se(e,o)}else{var l=d(e),w=l==J||l==ir;if(re(e))return pe(e,i);if(l==W||l==H||w&&!g){if(o=c||w?{}:Qe(e),!i)return c?Ae(e,be(o,e)):Te(e,le(o,e))}else{if(!n[l])return g?e:{};o=qe(e,l,i)}}s||(s=new te);var v=s.get(e);if(v)return v;s.set(e,o),er(e)?e.forEach(function(f){o.add(p(f,r,t,f,e,s))}):Ve(e)&&e.forEach(function(f,u){o.set(u,p(f,r,t,u,e,s))});var q=Y?c?je:ae:c?A:M,$=h?void 0:q(e);return ce($||e,function(f,u){$&&(u=f,f=e[u]),U(o,u,p(f,r,t,u,e,s))}),o}export{se as a,p as b,y as c,pe as d,xe as e,je as g,Qe as i,A as k};

View File

@@ -1 +1 @@
import{cK as O,d2 as a,cs as P,cy as p,d3 as A,cl as l,cU as M,co as _,ce as d}from"./index-CGB0A5x_.js";import{h as g,i as m}from"./index-DMVRI44M.js";var C=1,I=2;function L(n,r,e,t){var i=e.length,u=i;if(n==null)return!u;for(n=Object(n);i--;){var f=e[i];if(f[2]?f[1]!==n[f[0]]:!(f[0]in n))return!1}for(;++i<u;){f=e[i];var s=f[0],o=n[s],y=f[1];if(f[2]){if(o===void 0&&!(s in n))return!1}else{var E=new O,c;if(!(c===void 0?a(y,o,C|I,t,E):c))return!1}}return!0}function R(n){return n===n&&!P(n)}function D(n){for(var r=p(n),e=r.length;e--;){var t=r[e],i=n[t];r[e]=[t,i,R(i)]}return r}function h(n,r){return function(e){return e==null?!1:e[n]===r&&(r!==void 0||n in Object(e))}}function G(n){var r=D(n);return r.length==1&&r[0][2]?h(r[0][0],r[0][1]):function(e){return e===n||L(e,n,r)}}var w=1,F=2;function b(n,r){return A(n)&&R(r)?h(l(n),r):function(e){var t=M(e,n);return t===void 0&&t===r?g(e,n):a(r,t,w|F)}}function K(n){return function(r){return r==null?void 0:r[n]}}function S(n){return function(r){return _(r,n)}}function U(n){return A(n)?K(l(n)):S(n)}function T(n){return typeof n=="function"?n:n==null?m:typeof n=="object"?d(n)?b(n[0],n[1]):G(n):U(n)}export{T as b};
import{cK as O,d2 as a,cs as P,cy as p,d3 as A,cl as l,cU as M,co as _,ce as d}from"./index-Dd84m4NL.js";import{h as g,i as m}from"./index-DEuQ2B0Z.js";var C=1,I=2;function L(n,r,e,t){var i=e.length,u=i;if(n==null)return!u;for(n=Object(n);i--;){var f=e[i];if(f[2]?f[1]!==n[f[0]]:!(f[0]in n))return!1}for(;++i<u;){f=e[i];var s=f[0],o=n[s],y=f[1];if(f[2]){if(o===void 0&&!(s in n))return!1}else{var E=new O,c;if(!(c===void 0?a(y,o,C|I,t,E):c))return!1}}return!0}function R(n){return n===n&&!P(n)}function D(n){for(var r=p(n),e=r.length;e--;){var t=r[e],i=n[t];r[e]=[t,i,R(i)]}return r}function h(n,r){return function(e){return e==null?!1:e[n]===r&&(r!==void 0||n in Object(e))}}function G(n){var r=D(n);return r.length==1&&r[0][2]?h(r[0][0],r[0][1]):function(e){return e===n||L(e,n,r)}}var w=1,F=2;function b(n,r){return A(n)&&R(r)?h(l(n),r):function(e){var t=M(e,n);return t===void 0&&t===r?g(e,n):a(r,t,w|F)}}function K(n){return function(r){return r==null?void 0:r[n]}}function S(n){return function(r){return _(r,n)}}function U(n){return A(n)?K(l(n)):S(n)}function T(n){return typeof n=="function"?n:n==null?m:typeof n=="object"?d(n)?b(n[0],n[1]):G(n):U(n)}export{T as b};

View File

@@ -1 +1 @@
import{ce as a}from"./index-CGB0A5x_.js";function e(){if(!arguments.length)return[];var r=arguments[0];return a(r)?r:[r]}export{e as c};
import{ce as a}from"./index-Dd84m4NL.js";function e(){if(!arguments.length)return[];var r=arguments[0];return a(r)?r:[r]}export{e as c};

View File

@@ -1 +1 @@
import{t as n}from"./toNumber-IRhFg6gN.js";function t(d,f,i){return d===d&&(i!==void 0&&(d=d<=i?d:i),f!==void 0&&(d=d>=f?d:f)),d}function c(d,f,i){return i===void 0&&(i=f,f=void 0),i!==void 0&&(i=n(i),i=i===i?i:0),f!==void 0&&(f=n(f),f=f===f?f:0),t(n(d),f,i)}export{c};
import{t as n}from"./toNumber-Dzu6kJGs.js";function t(d,f,i){return d===d&&(i!==void 0&&(d=d<=i?d:i),f!==void 0&&(d=d>=f?d:f)),d}function c(d,f,i){return i===void 0&&(i=f,f=void 0),i!==void 0&&(i=n(i),i=i===i?i:0),f!==void 0&&(f=n(f),f=f===f?f:0),t(n(d),f,i)}export{c};

View File

@@ -1 +1 @@
import{aF as n,aG as t,aI as l}from"./index-CGB0A5x_.js";const p=()=>n("/model-compare"),i=e=>n(`/model-compare/${e}`),u=e=>l(`/model-compare/${e}`),h=e=>t("/model-compare/stop-by-pid",{pid:e}),g=e=>t(`/model-compare/${e}/load`),C=e=>t(`/model-compare/${e}/unload`),y=async e=>{const a=await t("/model-compare/stream-chat",e);return{ok:!0,body:{getReader:()=>{const o=(a==null?void 0:a.response)||"",r=new TextEncoder,s=[o.slice(0,o.length/3),o.slice(o.length/3,2*o.length/3),o.slice(2*o.length/3)];let c=0;return{read:async()=>c>=s.length?{done:!0,value:void 0}:{done:!1,value:r.encode(s[c++])}}}}}},v=e=>t("/model-compare/chat-with-port",e);export{i as a,y as b,v as c,u as d,p as g,g as l,h as s,C as u};
import{aF as n,aG as t,aI as l}from"./index-Dd84m4NL.js";const p=()=>n("/model-compare"),i=e=>n(`/model-compare/${e}`),u=e=>l(`/model-compare/${e}`),h=e=>t("/model-compare/stop-by-pid",{pid:e}),g=e=>t(`/model-compare/${e}/load`),C=e=>t(`/model-compare/${e}/unload`),y=async e=>{const a=await t("/model-compare/stream-chat",e);return{ok:!0,body:{getReader:()=>{const o=(a==null?void 0:a.response)||"",r=new TextEncoder,s=[o.slice(0,o.length/3),o.slice(o.length/3,2*o.length/3),o.slice(2*o.length/3)];let c=0;return{read:async()=>c>=s.length?{done:!0,value:void 0}:{done:!1,value:r.encode(s[c++])}}}}}},v=e=>t("/model-compare/chat-with-port",e);export{i as a,y as b,v as c,u as d,p as g,g as l,h as s,C as u};

View File

@@ -1 +1 @@
import{_ as M,ah as y,T as A,a7 as D,aS as I,aT as w}from"./install-caVZROyC.js";var T=(function(){function s(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=Math.PI*2,this.clockwise=!0}return s})(),x=(function(s){M(r,s);function r(t){var a=s.call(this,t)||this;return a.type="sausage",a}return r.prototype.getDefaultShape=function(){return new T},r.prototype.buildPath=function(t,a){var c=a.cx,e=a.cy,o=Math.max(a.r0||0,0),u=Math.max(a.r,0),l=(u-o)*.5,v=o+l,n=a.startAngle,i=a.endAngle,h=a.clockwise,S=Math.PI*2,d=h?i-n<S:n-i<S;d||(n=i-(h?S:-S));var g=Math.cos(n),f=Math.sin(n),m=Math.cos(i),P=Math.sin(i);d?(t.moveTo(g*o+c,f*o+e),t.arc(g*v+c,f*v+e,l,-Math.PI+n,n,!h)):t.moveTo(g*u+c,f*u+e),t.arc(c,e,u,n,i,!h),t.arc(m*v+c,P*v+e,l,i-Math.PI*2,i-Math.PI,!h),o!==0&&t.arc(c,e,o,i,n,h)},r})(y);function E(s,r,t){r=A(r)&&{coordDimensions:r}||D({encodeDefine:s.getEncode()},r);var a=s.getSource(),c=I(a,r).dimensions,e=new w(c,s);return e.initData(a,t),e}export{x as S,E as c};
import{_ as M,ah as y,T as A,a7 as D,aS as I,aT as w}from"./install-DD1EflGB.js";var T=(function(){function s(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=Math.PI*2,this.clockwise=!0}return s})(),x=(function(s){M(r,s);function r(t){var a=s.call(this,t)||this;return a.type="sausage",a}return r.prototype.getDefaultShape=function(){return new T},r.prototype.buildPath=function(t,a){var c=a.cx,e=a.cy,o=Math.max(a.r0||0,0),u=Math.max(a.r,0),l=(u-o)*.5,v=o+l,n=a.startAngle,i=a.endAngle,h=a.clockwise,S=Math.PI*2,d=h?i-n<S:n-i<S;d||(n=i-(h?S:-S));var g=Math.cos(n),f=Math.sin(n),m=Math.cos(i),P=Math.sin(i);d?(t.moveTo(g*o+c,f*o+e),t.arc(g*v+c,f*v+e,l,-Math.PI+n,n,!h)):t.moveTo(g*u+c,f*u+e),t.arc(c,e,u,n,i,!h),t.arc(m*v+c,P*v+e,l,i-Math.PI*2,i-Math.PI,!h),o!==0&&t.arc(c,e,o,i,n,h)},r})(y);function E(s,r,t){r=A(r)&&{coordDimensions:r}||D({encodeDefine:s.getEncode()},r);var a=s.getSource(),c=I(a,r).dimensions,e=new w(c,s);return e.initData(a,t),e}export{x as S,E as c};

View File

@@ -1 +0,0 @@
import{aF as n,aI as r,aH as p,aG as s}from"./index-CGB0A5x_.js";function m(e={}){return n("/data-process",e)}const l=e=>n(`/data-process/${encodeURIComponent(e)}`),i=e=>s("/data-process",e),R=(e,o)=>p(`/data-process/${encodeURIComponent(e)}`,o),U=(e,o)=>s(`/data-process/${encodeURIComponent(e)}/regenerate`,o),C=e=>r(`/data-process/${encodeURIComponent(e)}`);function I(e,o,t){const c=new FormData;return o.forEach(a=>c.append("files",a)),s(`/data-process/${encodeURIComponent(e)}/source-files`,c,{timeout:300*1e3,onUploadProgress:a=>{if(!a.total)return;const d=Math.round(a.loaded/a.total*100);t==null||t(Math.min(99,Math.max(0,d)))}})}const $=(e,o)=>r(`/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}`),P=(e,o,t={})=>n(`/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}/content`,t),D=(e,o)=>`/modelTF/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}/raw`,f=(e,o)=>n(`/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}/pdf-pages`),g=(e,o)=>{const{query:t,file_name:c,...a}=o;return s(`/data-process/${encodeURIComponent(e)}/external/test`,a)},w=(e,o)=>s(`/data-process/${encodeURIComponent(e)}/external/pull`,o),v=(e,o={})=>s(`/data-process/${encodeURIComponent(e)}/preview/build`,o,{timeout:300*1e3});function h(e,o={}){return n(`/data-process/${encodeURIComponent(e)}/preview`,o)}const k=(e,o,t)=>p(`/data-process/${encodeURIComponent(e)}/preview/${encodeURIComponent(o)}`,t),x=(e,o)=>s(`/data-process/${encodeURIComponent(e)}/preview`,o),T=(e,o)=>r(`/data-process/${encodeURIComponent(e)}/preview/${encodeURIComponent(o)}`),S=e=>s(`/data-process/${encodeURIComponent(e)}/generate`),b=e=>s(`/data-process/${encodeURIComponent(e)}/stop`),F=e=>n(`/data-process/${encodeURIComponent(e)}/progress`);function q(e,o={}){return n(`/data-process/${encodeURIComponent(e)}/results`,o)}const y=(e,o,t)=>p(`/data-process/${encodeURIComponent(e)}/results/${encodeURIComponent(o)}`,t),E=(e,o)=>s(`/data-process/${encodeURIComponent(e)}/results/${encodeURIComponent(o)}/restore`),M=(e,o)=>s(`/data-process/${encodeURIComponent(e)}/publish`,o);export{D as a,f as b,S as c,C as d,F as e,q as f,m as g,v as h,I as i,P as j,l as k,U as l,h as m,k as n,R as o,i as p,w as q,E as r,b as s,g as t,y as u,$ as v,x as w,T as x,M as y};

View File

@@ -0,0 +1 @@
import{aF as a,aI as p,aH as c,aG as t}from"./index-Dd84m4NL.js";function u(e={}){return a("/data-process",e)}const l=e=>a(`/data-process/${encodeURIComponent(e)}`),R=e=>t("/data-process",e),i=(e,o)=>c(`/data-process/${encodeURIComponent(e)}`,o),C=(e,o)=>c(`/data-process/${encodeURIComponent(e)}/workflow-step`,{workflow_step:o}),U=(e,o)=>t(`/data-process/${encodeURIComponent(e)}/regenerate`,o),I=e=>p(`/data-process/${encodeURIComponent(e)}`);function P(e,o,s){const r=new FormData;return o.forEach(n=>r.append("files",n)),t(`/data-process/${encodeURIComponent(e)}/source-files`,r,{timeout:300*1e3,onUploadProgress:n=>{if(!n.total)return;const d=Math.round(n.loaded/n.total*100);s==null||s(Math.min(99,Math.max(0,d)))}})}const $=(e,o)=>p(`/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}`),D=(e,o,s={})=>a(`/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}/content`,s),f=(e,o)=>`/modelTF/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}/raw`,g=(e,o)=>a(`/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}/pdf-pages`),w=(e,o,s={})=>a(`/data-process/${encodeURIComponent(e)}/source-files/${encodeURIComponent(o)}/office-preview`,s,{timeout:6e4}),v=(e,o)=>{const{query:s,file_name:r,...n}=o;return t(`/data-process/${encodeURIComponent(e)}/external/test`,n)},k=(e,o)=>t(`/data-process/${encodeURIComponent(e)}/external/pull`,o),h=(e,o={})=>t(`/data-process/${encodeURIComponent(e)}/preview/start`,o),x=e=>a(`/data-process/${encodeURIComponent(e)}/preview/progress`);function S(e,o={}){return a(`/data-process/${encodeURIComponent(e)}/preview`,o)}const T=(e,o,s)=>c(`/data-process/${encodeURIComponent(e)}/preview/${encodeURIComponent(o)}`,s),F=(e,o)=>t(`/data-process/${encodeURIComponent(e)}/preview`,o),b=(e,o)=>p(`/data-process/${encodeURIComponent(e)}/preview/${encodeURIComponent(o)}`),_=e=>t(`/data-process/${encodeURIComponent(e)}/generate`),q=e=>a(`/data-process/${encodeURIComponent(e)}/progress`),y=e=>t(`/data-process/${encodeURIComponent(e)}/confirm-results`);function E(e,o={}){return a(`/data-process/${encodeURIComponent(e)}/results`,o)}const M=(e,o,s)=>c(`/data-process/${encodeURIComponent(e)}/results/${encodeURIComponent(o)}`,s),j=(e,o)=>t(`/data-process/${encodeURIComponent(e)}/results/${encodeURIComponent(o)}/restore`),z=(e,o,s)=>t(`/data-process/${encodeURIComponent(e)}/results/${encodeURIComponent(o)}/regenerate`,s,{timeout:21e4}),A=(e,o)=>t(`/data-process/${encodeURIComponent(e)}/results/regenerate-batch`,o,{timeout:24e4}),B=(e,o)=>t(`/data-process/${encodeURIComponent(e)}/publish`,o);export{F as A,b as B,B as C,j as D,w as a,f as b,g as c,I as d,_ as e,q as f,u as g,A as h,E as i,x as j,P as k,D as l,l as m,U as n,S as o,C as p,T as q,z as r,h as s,y as t,M as u,i as v,R as w,v as x,k as y,$ as z};

View File

@@ -1 +0,0 @@
function t(e){return e.status==="running"?{label:"生成中",type:"primary"}:e.status==="completed"?e.output_dataset_id?{label:"已发布",type:"success"}:{label:"已生成",type:"warning"}:e.status==="failed"?{label:"生成失败",type:"danger"}:e.status==="stopped"?{label:"已停止",type:"info"}:{label:"待生成",type:"info"}}export{t as d};

View File

@@ -0,0 +1 @@
function t(e){return e.preview_status==="running"||e.preview_status==="queued"?{label:"切分中",type:"primary"}:e.preview_status==="failed"?{label:"切分失败",type:"danger"}:e.preview_status==="cancelled"?{label:"切分已取消",type:"warning"}:e.status==="running"?{label:"生成中",type:"primary"}:e.status==="completed"?e.results_confirmed===!1?{label:"待确认",type:"warning"}:e.output_dataset_id?{label:"已发布",type:"success"}:{label:"已生成",type:"warning"}:e.status==="failed"?{label:"生成失败",type:"danger"}:e.status==="stopped"?{label:"已停止",type:"info"}:{label:"待生成",type:"info"}}export{t as d};

View File

@@ -0,0 +1 @@
import{aF as s,aH as d,aG as o,aI as r}from"./index-Dd84m4NL.js";const i=()=>s("/dataset-manage"),m=e=>s(`/dataset-manage/${e}`),l=e=>o("/dataset-manage",e),p=(e,a)=>d(`/dataset-manage/${e}`,a),g=e=>r(`/dataset-manage/${e}`),$=(e,a)=>{const t=new FormData;return a.forEach(n=>t.append("files",n)),o(`/dataset-manage/upload/${e}`,t,{headers:{"Content-Type":"multipart/form-data"}})},D=e=>s(`/dataset-manage/records/${encodeURIComponent(e)}/sources`),u=e=>s(`/dataset-manage/versions/${encodeURIComponent(e)}`),_=(e,a)=>s(`/dataset-manage/versions/${encodeURIComponent(e)}/${encodeURIComponent(a)}`),v=(e,a,t)=>o(`/dataset-manage/versions/${encodeURIComponent(e)}`,{content:a,description:t.description||"在线编辑",base_version_id:t.baseVersionId,expected_current_version_id:t.expectedCurrentVersionId}),C=(e,a,t)=>d(`/dataset-manage/versions/${encodeURIComponent(e)}/active`,{version_id:a,expected_current_version_id:t}),F=(e,a,t)=>r(`/dataset-manage/versions/${encodeURIComponent(e)}/${encodeURIComponent(a)}`,{expected_current_version_id:t}),U=(e,a,t)=>{const n=`/modelTF/dataset-manage/download/${e}/${a}`;return t?`${n}?version_id=${encodeURIComponent(t)}`:n},I=e=>`/modelTF/dataset-manage/download/${e}`;export{g as a,m as b,$ as c,I as d,l as e,u as f,i as g,_ as h,D as i,v as j,U as k,C as l,F as m,p as u};

View File

@@ -1 +0,0 @@
import{aF as n,aH as d,aG as o,aI as r}from"./index-CGB0A5x_.js";const c=()=>n("/dataset-manage"),m=e=>n(`/dataset-manage/${e}`),l=e=>o("/dataset-manage",e),p=(e,a)=>d(`/dataset-manage/${e}`,a),g=e=>r(`/dataset-manage/${e}`),$=(e,a)=>{const t=new FormData;return a.forEach(s=>t.append("files",s)),o(`/dataset-manage/upload/${e}`,t,{headers:{"Content-Type":"multipart/form-data"}})},D=e=>n(`/dataset-manage/versions/${encodeURIComponent(e)}`),_=(e,a)=>n(`/dataset-manage/versions/${encodeURIComponent(e)}/${encodeURIComponent(a)}`),u=(e,a,t)=>o(`/dataset-manage/versions/${encodeURIComponent(e)}`,{content:a,description:t.description||"在线编辑",base_version_id:t.baseVersionId,expected_current_version_id:t.expectedCurrentVersionId}),v=(e,a,t)=>d(`/dataset-manage/versions/${encodeURIComponent(e)}/active`,{version_id:a,expected_current_version_id:t}),C=(e,a,t)=>r(`/dataset-manage/versions/${encodeURIComponent(e)}/${encodeURIComponent(a)}`,{expected_current_version_id:t}),F=(e,a,t)=>{const s=`/modelTF/dataset-manage/download/${e}/${a}`;return t?`${s}?version_id=${encodeURIComponent(t)}`:s},U=e=>`/modelTF/dataset-manage/download/${e}`;export{U as a,m as b,$ as c,g as d,l as e,D as f,c as g,_ as h,u as i,F as j,v as k,C as l,p as u};

View File

@@ -1 +1 @@
import{cz as S,cs as y}from"./index-CGB0A5x_.js";import{t as b}from"./toNumber-IRhFg6gN.js";var h=function(){return S.Date.now()},R="Expected a function",A=Math.max,F=Math.min;function _(x,i,a){var u,d,m,f,n,r,o=0,E=!1,c=!1,g=!0;if(typeof x!="function")throw new TypeError(R);i=b(i)||0,y(a)&&(E=!!a.leading,c="maxWait"in a,m=c?A(b(a.maxWait)||0,i):m,g="trailing"in a?!!a.trailing:g);function v(e){var t=u,l=d;return u=d=void 0,o=e,f=x.apply(l,t),f}function p(e){return o=e,n=setTimeout(s,i),E?v(e):f}function C(e){var t=e-r,l=e-o,W=i-t;return c?F(W,m-l):W}function k(e){var t=e-r,l=e-o;return r===void 0||t>=i||t<0||c&&l>=m}function s(){var e=h();if(k(e))return I(e);n=setTimeout(s,C(e))}function I(e){return n=void 0,g&&u?v(e):(u=d=void 0,f)}function L(){n!==void 0&&clearTimeout(n),o=0,u=r=d=n=void 0}function M(){return n===void 0?f:I(h())}function T(){var e=h(),t=k(e);if(u=arguments,d=this,r=e,t){if(n===void 0)return p(r);if(c)return clearTimeout(n),n=setTimeout(s,i),v(r)}return n===void 0&&(n=setTimeout(s,i)),f}return T.cancel=L,T.flush=M,T}export{_ as d};
import{cz as S,cs as y}from"./index-Dd84m4NL.js";import{t as b}from"./toNumber-Dzu6kJGs.js";var h=function(){return S.Date.now()},R="Expected a function",A=Math.max,F=Math.min;function _(x,i,a){var u,d,m,f,n,r,o=0,E=!1,c=!1,g=!0;if(typeof x!="function")throw new TypeError(R);i=b(i)||0,y(a)&&(E=!!a.leading,c="maxWait"in a,m=c?A(b(a.maxWait)||0,i):m,g="trailing"in a?!!a.trailing:g);function v(e){var t=u,l=d;return u=d=void 0,o=e,f=x.apply(l,t),f}function p(e){return o=e,n=setTimeout(s,i),E?v(e):f}function C(e){var t=e-r,l=e-o,W=i-t;return c?F(W,m-l):W}function k(e){var t=e-r,l=e-o;return r===void 0||t>=i||t<0||c&&l>=m}function s(){var e=h();if(k(e))return I(e);n=setTimeout(s,C(e))}function I(e){return n=void 0,g&&u?v(e):(u=d=void 0,f)}function L(){n!==void 0&&clearTimeout(n),o=0,u=r=d=n=void 0}function M(){return n===void 0?f:I(h())}function T(){var e=h(),t=k(e);if(u=arguments,d=this,r=e,t){if(n===void 0)return p(r);if(c)return clearTimeout(n),n=setTimeout(s,i),v(r)}return n===void 0&&(n=setTimeout(s,i)),f}return T.cancel=L,T.flush=M,T}export{_ as d};

View File

@@ -1 +1 @@
import{z as E,d7 as P,d as O,bp as z,I as g,w as j,K as R,s as K,L as Z,Z as q,aV as D,y as B,a0 as y,bt as F,P as I,J as S,bL as m,_ as k,a3 as _,aB as G,d8 as H}from"./index-CGB0A5x_.js";function J(e,s){let t;const o=B(!1),n=E({...e,originalPosition:"",originalOverflow:"",visible:!1});function r(l){n.text=l}function c(){const l=n.parent,u=f.ns;if(!l.vLoadingAddClassList){let i=l.getAttribute("loading-number");i=Number.parseInt(i)-1,i?l.setAttribute("loading-number",i.toString()):(y(l,u.bm("parent","relative")),l.removeAttribute("loading-number")),y(l,u.bm("parent","hidden"))}v(),C.unmount()}function v(){var l,u;(u=(l=f.$el)==null?void 0:l.parentNode)==null||u.removeChild(f.$el)}function x(){var l;e.beforeClose&&!e.beforeClose()||(o.value=!0,clearTimeout(t),t=setTimeout(a,400),n.visible=!1,(l=e.closed)==null||l.call(e))}function a(){if(!o.value)return;const l=n.parent;o.value=!1,l.vLoadingAddClassList=void 0,c()}const C=P(O({name:"ElLoading",setup(l,{expose:u}){const{ns:i,zIndex:N}=z("loading");return u({ns:i,zIndex:N}),()=>{const A=n.spinner||n.svg,T=g("svg",{class:"circular",viewBox:n.svgViewBox?n.svgViewBox:"0 0 50 50",...A?{innerHTML:A}:{}},[g("circle",{class:"path",cx:"25",cy:"25",r:"20",fill:"none"})]),V=n.text?g("p",{class:i.b("text")},[n.text]):void 0;return g(q,{name:i.b("fade"),onAfterLeave:a},{default:j(()=>[R(K("div",{style:{backgroundColor:n.background||""},class:[i.b("mask"),n.customClass,i.is("fullscreen",n.fullscreen)]},[g("div",{class:i.b("spinner")},[T,V])]),[[Z,n.visible]])])})}}}));Object.assign(C._context,s??{});const f=C.mount(document.createElement("div"));return{...D(n),setText:r,removeElLoadingChild:v,close:x,handleAfterLeave:a,vm:f,get $el(){return f.$el}}}let p;const L=function(e={},s){if(!F)return;const t=M(e);if(t.fullscreen&&p)return p;const o=J({...t,closed:()=>{var r;(r=t.closed)==null||r.call(t),t.fullscreen&&(p=void 0)}},s??L._context);Y(t,t.parent,o),w(t,t.parent,o),t.parent.vLoadingAddClassList=()=>w(t,t.parent,o);let n=t.parent.getAttribute("loading-number");return n?n=`${Number.parseInt(n)+1}`:n="1",t.parent.setAttribute("loading-number",n),t.parent.appendChild(o.$el),I(()=>o.visible.value=t.visible),t.fullscreen&&(p=o),o},M=e=>{let s;return S(e.target)?s=document.querySelector(e.target)??document.body:s=e.target||document.body,{parent:s===document.body||e.body?document.body:s,background:e.background||"",svg:e.svg||"",svgViewBox:e.svgViewBox||"",spinner:e.spinner||!1,text:e.text||"",fullscreen:s===document.body&&(e.fullscreen??!0),lock:e.lock??!1,customClass:e.customClass||"",visible:e.visible??!0,beforeClose:e.beforeClose,closed:e.closed,target:s}},Y=async(e,s,t)=>{const{nextZIndex:o}=t.vm.zIndex||t.vm._.exposed.zIndex,n={};if(e.fullscreen)t.originalPosition.value=m(document.body,"position"),t.originalOverflow.value=m(document.body,"overflow"),n.zIndex=o();else if(e.parent===document.body){t.originalPosition.value=m(document.body,"position"),await I();for(const r of["top","left"]){const c=r==="top"?"scrollTop":"scrollLeft";n[r]=`${e.target.getBoundingClientRect()[r]+document.body[c]+document.documentElement[c]-Number.parseInt(m(document.body,`margin-${r}`),10)}px`}for(const r of["height","width"])n[r]=`${e.target.getBoundingClientRect()[r]}px`}else t.originalPosition.value=m(s,"position");for(const[r,c]of Object.entries(n))t.$el.style[r]=c},w=(e,s,t)=>{const o=t.vm.ns||t.vm._.exposed.ns;["absolute","fixed","sticky"].includes(t.originalPosition.value)?y(s,o.bm("parent","relative")):k(s,o.bm("parent","relative")),e.fullscreen&&e.lock?k(s,o.bm("parent","hidden")):y(s,o.bm("parent","hidden"))};L._context=null;const b=Symbol("ElLoading"),d=e=>`element-loading-${H(e)}`,h=(e,s)=>{const t=s.instance,o=a=>_(s.value)?s.value[a]:void 0,n=a=>B(S(a)&&(t==null?void 0:t[a])||a),r=a=>n(o(a)||e.getAttribute(d(a))),c=o("fullscreen")??s.modifiers.fullscreen,v={text:r("text"),svg:r("svg"),svgViewBox:r("svgViewBox"),spinner:r("spinner"),background:r("background"),customClass:r("customClass"),fullscreen:c,target:o("target")??(c?void 0:e),body:o("body")??s.modifiers.body,lock:o("lock")??s.modifiers.lock},x=L(v);x._context=$._context,e[b]={options:v,instance:x}},Q=(e,s)=>{for(const t of Object.keys(e))G(e[t])&&(e[t].value=s[t])},$={mounted(e,s){s.value&&h(e,s)},updated(e,s){const t=e[b];if(!s.value){t==null||t.instance.close(),e[b]=null;return}t?Q(t.options,_(s.value)?s.value:{text:e.getAttribute(d("text")),svg:e.getAttribute(d("svg")),svgViewBox:e.getAttribute(d("svgViewBox")),spinner:e.getAttribute(d("spinner")),background:e.getAttribute(d("background")),customClass:e.getAttribute(d("customClass"))}):h(e,s)},unmounted(e){var s;(s=e[b])==null||s.instance.close(),e[b]=null}};$._context=null;export{$ as v};
import{z as E,d7 as P,d as O,bp as z,I as g,w as j,K as R,s as K,L as Z,Z as q,aV as D,y as B,a0 as y,bt as F,P as I,J as S,bL as m,_ as k,a3 as _,aB as G,d8 as H}from"./index-Dd84m4NL.js";function J(e,s){let t;const o=B(!1),n=E({...e,originalPosition:"",originalOverflow:"",visible:!1});function r(l){n.text=l}function c(){const l=n.parent,u=f.ns;if(!l.vLoadingAddClassList){let i=l.getAttribute("loading-number");i=Number.parseInt(i)-1,i?l.setAttribute("loading-number",i.toString()):(y(l,u.bm("parent","relative")),l.removeAttribute("loading-number")),y(l,u.bm("parent","hidden"))}v(),C.unmount()}function v(){var l,u;(u=(l=f.$el)==null?void 0:l.parentNode)==null||u.removeChild(f.$el)}function x(){var l;e.beforeClose&&!e.beforeClose()||(o.value=!0,clearTimeout(t),t=setTimeout(a,400),n.visible=!1,(l=e.closed)==null||l.call(e))}function a(){if(!o.value)return;const l=n.parent;o.value=!1,l.vLoadingAddClassList=void 0,c()}const C=P(O({name:"ElLoading",setup(l,{expose:u}){const{ns:i,zIndex:N}=z("loading");return u({ns:i,zIndex:N}),()=>{const A=n.spinner||n.svg,T=g("svg",{class:"circular",viewBox:n.svgViewBox?n.svgViewBox:"0 0 50 50",...A?{innerHTML:A}:{}},[g("circle",{class:"path",cx:"25",cy:"25",r:"20",fill:"none"})]),V=n.text?g("p",{class:i.b("text")},[n.text]):void 0;return g(q,{name:i.b("fade"),onAfterLeave:a},{default:j(()=>[R(K("div",{style:{backgroundColor:n.background||""},class:[i.b("mask"),n.customClass,i.is("fullscreen",n.fullscreen)]},[g("div",{class:i.b("spinner")},[T,V])]),[[Z,n.visible]])])})}}}));Object.assign(C._context,s??{});const f=C.mount(document.createElement("div"));return{...D(n),setText:r,removeElLoadingChild:v,close:x,handleAfterLeave:a,vm:f,get $el(){return f.$el}}}let p;const L=function(e={},s){if(!F)return;const t=M(e);if(t.fullscreen&&p)return p;const o=J({...t,closed:()=>{var r;(r=t.closed)==null||r.call(t),t.fullscreen&&(p=void 0)}},s??L._context);Y(t,t.parent,o),w(t,t.parent,o),t.parent.vLoadingAddClassList=()=>w(t,t.parent,o);let n=t.parent.getAttribute("loading-number");return n?n=`${Number.parseInt(n)+1}`:n="1",t.parent.setAttribute("loading-number",n),t.parent.appendChild(o.$el),I(()=>o.visible.value=t.visible),t.fullscreen&&(p=o),o},M=e=>{let s;return S(e.target)?s=document.querySelector(e.target)??document.body:s=e.target||document.body,{parent:s===document.body||e.body?document.body:s,background:e.background||"",svg:e.svg||"",svgViewBox:e.svgViewBox||"",spinner:e.spinner||!1,text:e.text||"",fullscreen:s===document.body&&(e.fullscreen??!0),lock:e.lock??!1,customClass:e.customClass||"",visible:e.visible??!0,beforeClose:e.beforeClose,closed:e.closed,target:s}},Y=async(e,s,t)=>{const{nextZIndex:o}=t.vm.zIndex||t.vm._.exposed.zIndex,n={};if(e.fullscreen)t.originalPosition.value=m(document.body,"position"),t.originalOverflow.value=m(document.body,"overflow"),n.zIndex=o();else if(e.parent===document.body){t.originalPosition.value=m(document.body,"position"),await I();for(const r of["top","left"]){const c=r==="top"?"scrollTop":"scrollLeft";n[r]=`${e.target.getBoundingClientRect()[r]+document.body[c]+document.documentElement[c]-Number.parseInt(m(document.body,`margin-${r}`),10)}px`}for(const r of["height","width"])n[r]=`${e.target.getBoundingClientRect()[r]}px`}else t.originalPosition.value=m(s,"position");for(const[r,c]of Object.entries(n))t.$el.style[r]=c},w=(e,s,t)=>{const o=t.vm.ns||t.vm._.exposed.ns;["absolute","fixed","sticky"].includes(t.originalPosition.value)?y(s,o.bm("parent","relative")):k(s,o.bm("parent","relative")),e.fullscreen&&e.lock?k(s,o.bm("parent","hidden")):y(s,o.bm("parent","hidden"))};L._context=null;const b=Symbol("ElLoading"),d=e=>`element-loading-${H(e)}`,h=(e,s)=>{const t=s.instance,o=a=>_(s.value)?s.value[a]:void 0,n=a=>B(S(a)&&(t==null?void 0:t[a])||a),r=a=>n(o(a)||e.getAttribute(d(a))),c=o("fullscreen")??s.modifiers.fullscreen,v={text:r("text"),svg:r("svg"),svgViewBox:r("svgViewBox"),spinner:r("spinner"),background:r("background"),customClass:r("customClass"),fullscreen:c,target:o("target")??(c?void 0:e),body:o("body")??s.modifiers.body,lock:o("lock")??s.modifiers.lock},x=L(v);x._context=$._context,e[b]={options:v,instance:x}},Q=(e,s)=>{for(const t of Object.keys(e))G(e[t])&&(e[t].value=s[t])},$={mounted(e,s){s.value&&h(e,s)},updated(e,s){const t=e[b];if(!s.value){t==null||t.instance.close(),e[b]=null;return}t?Q(t.options,_(s.value)?s.value:{text:e.getAttribute(d("text")),svg:e.getAttribute(d("svg")),svgViewBox:e.getAttribute(d("svgViewBox")),spinner:e.getAttribute(d("spinner")),background:e.getAttribute(d("background")),customClass:e.getAttribute(d("customClass"))}):h(e,s)},unmounted(e){var s;(s=e[b])==null||s.instance.close(),e[b]=null}};$._context=null;export{$ as v};

View File

@@ -1 +1 @@
import{b as p,W as o,R as e,i as a}from"./index-CGB0A5x_.js";import{u as t,r as n,b as r}from"./el-popper-DvBtRO32.js";const d=p({trigger:{...r.trigger,type:e([String,Array])},triggerKeys:{type:e(Array),default:()=>[o.enter,o.numpadEnter,o.space,o.down]},virtualTriggering:r.virtualTriggering,virtualRef:r.virtualRef,effect:{...t.effect,default:"light"},type:{type:e(String)},placement:{type:e(String),default:"bottom"},popperOptions:{type:e(Object),default:()=>({})},id:String,size:{type:String,default:""},splitButton:Boolean,hideOnClick:{type:Boolean,default:!0},loop:{type:Boolean,default:!0},showArrow:{type:Boolean,default:!0},showTimeout:{type:Number,default:150},hideTimeout:{type:Number,default:150},tabindex:{type:e([Number,String]),default:0},maxHeight:{type:e([Number,String]),default:""},popperClass:t.popperClass,popperStyle:t.popperStyle,disabled:Boolean,role:{type:String,values:n,default:"menu"},buttonProps:{type:e(Object)},teleported:t.teleported,appendTo:t.appendTo,persistent:{type:Boolean,default:!0}}),u=p({command:{type:[Object,String,Number],default:()=>({})},disabled:Boolean,divided:Boolean,textValue:String,icon:{type:a}}),s=p({onKeydown:{type:e(Function)}});export{u as a,s as b,d};
import{b as p,W as o,R as e,i as a}from"./index-Dd84m4NL.js";import{u as t,r as n,b as r}from"./el-popper-CXiDZrHI.js";const d=p({trigger:{...r.trigger,type:e([String,Array])},triggerKeys:{type:e(Array),default:()=>[o.enter,o.numpadEnter,o.space,o.down]},virtualTriggering:r.virtualTriggering,virtualRef:r.virtualRef,effect:{...t.effect,default:"light"},type:{type:e(String)},placement:{type:e(String),default:"bottom"},popperOptions:{type:e(Object),default:()=>({})},id:String,size:{type:String,default:""},splitButton:Boolean,hideOnClick:{type:Boolean,default:!0},loop:{type:Boolean,default:!0},showArrow:{type:Boolean,default:!0},showTimeout:{type:Number,default:150},hideTimeout:{type:Number,default:150},tabindex:{type:e([Number,String]),default:0},maxHeight:{type:e([Number,String]),default:""},popperClass:t.popperClass,popperStyle:t.popperStyle,disabled:Boolean,role:{type:String,values:n,default:"menu"},buttonProps:{type:e(Object)},teleported:t.teleported,appendTo:t.appendTo,persistent:{type:Boolean,default:!0}}),u=p({command:{type:[Object,String,Number],default:()=>({})},disabled:Boolean,divided:Boolean,textValue:String,icon:{type:a}}),s=p({onKeydown:{type:e(Function)}});export{u as a,s as b,d};

View File

@@ -1 +1 @@
import{b as N,bI as $,bs as S,d as D,bF as V,a as x,o as l,e as n,w as d,K as M,q as h,n as o,f as e,E as k,h as m,r as A,g as i,c,x as g,aa as v,M as F,s as P,bo as j,L as q,Z as z,y as K,j as E,l as L}from"./index-CGB0A5x_.js";import{f as O,b as Z}from"./vnode-DFpZw5lG.js";const G=["light","dark"],H=N({title:{type:String,default:""},description:{type:String,default:""},type:{type:String,values:$(S),default:"info"},closable:{type:Boolean,default:!0},closeText:{type:String,default:""},showIcon:Boolean,center:Boolean,effect:{type:String,values:G,default:"light"}}),J={close:t=>t instanceof MouseEvent};var Q=D({name:"ElAlert",__name:"alert",props:H,emits:J,setup(t,{emit:w}){const{Close:B}=j,p=t,T=w,r=V(),s=x("alert"),y=K(!0),b=E(()=>S[p.type]),u=E(()=>{var f;if(p.description)return!0;const a=(f=r.default)==null?void 0:f.call(r);return a?O(a).some(I=>!Z(I)):!1}),C=a=>{y.value=!1,T("close",a)};return(a,f)=>(l(),n(z,{name:e(s).b("fade"),persisted:""},{default:d(()=>[M(h("div",{class:o([e(s).b(),e(s).m(t.type),e(s).is("center",t.center),e(s).is(t.effect)]),role:"alert"},[t.showIcon&&(a.$slots.icon||b.value)?(l(),n(e(k),{key:0,class:o([e(s).e("icon"),e(s).is("big",u.value)])},{default:d(()=>[m(a.$slots,"icon",{},()=>[(l(),n(A(b.value)))])]),_:3},8,["class"])):i("v-if",!0),h("div",{class:o(e(s).e("content"))},[t.title||a.$slots.title?(l(),c("span",{key:0,class:o([e(s).e("title"),{"with-description":u.value}])},[m(a.$slots,"title",{},()=>[g(v(t.title),1)])],2)):i("v-if",!0),u.value?(l(),c("p",{key:1,class:o(e(s).e("description"))},[m(a.$slots,"default",{},()=>[g(v(t.description),1)])],2)):i("v-if",!0),t.closable?(l(),c(F,{key:2},[t.closeText?(l(),c("div",{key:0,class:o([e(s).e("close-btn"),e(s).is("customed")]),onClick:C},v(t.closeText),3)):(l(),n(e(k),{key:1,class:o(e(s).e("close-btn")),onClick:C},{default:d(()=>[P(e(B))]),_:1},8,["class"]))],64)):i("v-if",!0)],2)],2),[[q,y.value]])]),_:3},8,["name"]))}}),R=Q;const X=L(R);export{X as E};
import{b as N,bI as $,bs as S,d as D,bF as V,a as x,o as l,e as n,w as d,K as M,q as h,n as o,f as e,E as k,h as m,r as A,g as i,c,x as g,aa as v,M as F,s as P,bo as j,L as q,Z as z,y as K,j as E,l as L}from"./index-Dd84m4NL.js";import{f as O,b as Z}from"./vnode-CasYkit1.js";const G=["light","dark"],H=N({title:{type:String,default:""},description:{type:String,default:""},type:{type:String,values:$(S),default:"info"},closable:{type:Boolean,default:!0},closeText:{type:String,default:""},showIcon:Boolean,center:Boolean,effect:{type:String,values:G,default:"light"}}),J={close:t=>t instanceof MouseEvent};var Q=D({name:"ElAlert",__name:"alert",props:H,emits:J,setup(t,{emit:w}){const{Close:B}=j,p=t,T=w,r=V(),s=x("alert"),y=K(!0),b=E(()=>S[p.type]),u=E(()=>{var f;if(p.description)return!0;const a=(f=r.default)==null?void 0:f.call(r);return a?O(a).some(I=>!Z(I)):!1}),C=a=>{y.value=!1,T("close",a)};return(a,f)=>(l(),n(z,{name:e(s).b("fade"),persisted:""},{default:d(()=>[M(h("div",{class:o([e(s).b(),e(s).m(t.type),e(s).is("center",t.center),e(s).is(t.effect)]),role:"alert"},[t.showIcon&&(a.$slots.icon||b.value)?(l(),n(e(k),{key:0,class:o([e(s).e("icon"),e(s).is("big",u.value)])},{default:d(()=>[m(a.$slots,"icon",{},()=>[(l(),n(A(b.value)))])]),_:3},8,["class"])):i("v-if",!0),h("div",{class:o(e(s).e("content"))},[t.title||a.$slots.title?(l(),c("span",{key:0,class:o([e(s).e("title"),{"with-description":u.value}])},[m(a.$slots,"title",{},()=>[g(v(t.title),1)])],2)):i("v-if",!0),u.value?(l(),c("p",{key:1,class:o(e(s).e("description"))},[m(a.$slots,"default",{},()=>[g(v(t.description),1)])],2)):i("v-if",!0),t.closable?(l(),c(F,{key:2},[t.closeText?(l(),c("div",{key:0,class:o([e(s).e("close-btn"),e(s).is("customed")]),onClick:C},v(t.closeText),3)):(l(),n(e(k),{key:1,class:o(e(s).e("close-btn")),onClick:C},{default:d(()=>[P(e(B))]),_:1},8,["class"]))],64)):i("v-if",!0)],2)],2),[[q,y.value]])]),_:3},8,["name"]))}}),R=Q;const X=L(R);export{X as E};

View File

@@ -1 +1 @@
import{b as j,i as w,aj as z,R as c,ak as m,d as A,B as V,a as E,D as I,o as f,c as y,al as S,e as h,w as _,r as q,f as D,E as F,h as G,n as K,y as L,j as p,J as R,am as J,s as d,an as O,ao as U,x as $,F as H,z as M,a9 as g,l as Q,ab as W}from"./index-CGB0A5x_.js";import{f as X}from"./vnode-DFpZw5lG.js";import{u as C,a as Y,E as Z}from"./el-popper-DvBtRO32.js";const aa=j({size:{type:[Number,String],values:z,validator:a=>m(a)},shape:{type:String,values:["circle","square"]},icon:{type:w},src:{type:String,default:""},alt:String,srcSet:String,fit:{type:c(String),default:"cover"}}),ea={error:a=>a instanceof Event},b=Symbol("avatarGroupContextKey"),ta={size:{type:c([Number,String]),values:z,validator:a=>m(a)},shape:{type:c(String),values:["circle","square"]},collapseAvatars:Boolean,collapseAvatarsTooltip:Boolean,maxCollapseAvatars:{type:Number,default:1},effect:{type:c(String),default:"light"},placement:{type:c(String),values:Y,default:"top"},popperClass:C.popperClass,popperStyle:C.popperStyle,collapseClass:String,collapseStyle:{type:c([String,Array,Object,Boolean]),default:void 0}},sa=["src","alt","srcset"];var la=A({name:"ElAvatar",__name:"avatar",props:aa,emits:ea,setup(a,{emit:n}){const t=a,r=n,e=V(b,void 0),l=E("avatar"),o=L(!1),s=p(()=>t.size??(e==null?void 0:e.size)),v=p(()=>t.shape??(e==null?void 0:e.shape)??"circle"),B=p(()=>{const{icon:i}=t,u=[l.b()];return R(s.value)&&u.push(l.m(s.value)),i&&u.push(l.m("icon")),v.value&&u.push(l.m(v.value)),u}),x=p(()=>m(s.value)?l.cssVarBlock({size:J(s.value)}):void 0),T=p(()=>({objectFit:t.fit}));I(()=>[t.src,t.srcSet],()=>o.value=!1);function P(i){o.value=!0,r("error",i)}return(i,u)=>(f(),y("span",{class:K(B.value),style:S(x.value)},[(a.src||a.srcSet)&&!o.value?(f(),y("img",{key:0,src:a.src,alt:a.alt,srcset:a.srcSet,style:S(T.value),onError:P},null,44,sa)):a.icon?(f(),h(D(F),{key:1},{default:_(()=>[(f(),h(q(a.icon)))]),_:1})):G(i.$slots,"default",{key:2})],6))}}),k=la,N=A({name:"ElAvatarGroup",props:ta,setup(a,{slots:n}){const t=E("avatar-group");return H(b,M({size:g(a,"size"),shape:g(a,"shape")})),()=>{var l;const r=X(((l=n.default)==null?void 0:l.call(n))??[]);let e=r;if(a.collapseAvatars&&r.length>a.maxCollapseAvatars){e=r.slice(0,a.maxCollapseAvatars);const o=r.slice(a.maxCollapseAvatars);e.push(d(Z,{popperClass:a.popperClass,popperStyle:a.popperStyle,placement:a.placement,effect:a.effect,disabled:!a.collapseAvatarsTooltip},{default:()=>d(k,{size:a.size,shape:a.shape,class:a.collapseClass,style:a.collapseStyle},{default:()=>[$("+ "),o.length]}),content:()=>d("div",{class:t.e("collapse-avatars")},[o.map((s,v)=>O(s)?U(s,{key:s.key??v}):s)])}))}return d("div",{class:t.b()},[e])}}});const na=Q(k,{AvatarGroup:N});W(N);export{na as E};
import{b as j,i as w,aj as z,R as c,ak as m,d as A,B as V,a as E,D as I,o as f,c as y,al as S,e as h,w as _,r as q,f as D,E as F,h as G,n as K,y as L,j as p,J as R,am as J,s as d,an as O,ao as U,x as $,F as H,z as M,a9 as g,l as Q,ab as W}from"./index-Dd84m4NL.js";import{f as X}from"./vnode-CasYkit1.js";import{u as C,a as Y,E as Z}from"./el-popper-CXiDZrHI.js";const aa=j({size:{type:[Number,String],values:z,validator:a=>m(a)},shape:{type:String,values:["circle","square"]},icon:{type:w},src:{type:String,default:""},alt:String,srcSet:String,fit:{type:c(String),default:"cover"}}),ea={error:a=>a instanceof Event},b=Symbol("avatarGroupContextKey"),ta={size:{type:c([Number,String]),values:z,validator:a=>m(a)},shape:{type:c(String),values:["circle","square"]},collapseAvatars:Boolean,collapseAvatarsTooltip:Boolean,maxCollapseAvatars:{type:Number,default:1},effect:{type:c(String),default:"light"},placement:{type:c(String),values:Y,default:"top"},popperClass:C.popperClass,popperStyle:C.popperStyle,collapseClass:String,collapseStyle:{type:c([String,Array,Object,Boolean]),default:void 0}},sa=["src","alt","srcset"];var la=A({name:"ElAvatar",__name:"avatar",props:aa,emits:ea,setup(a,{emit:n}){const t=a,r=n,e=V(b,void 0),l=E("avatar"),o=L(!1),s=p(()=>t.size??(e==null?void 0:e.size)),v=p(()=>t.shape??(e==null?void 0:e.shape)??"circle"),B=p(()=>{const{icon:i}=t,u=[l.b()];return R(s.value)&&u.push(l.m(s.value)),i&&u.push(l.m("icon")),v.value&&u.push(l.m(v.value)),u}),x=p(()=>m(s.value)?l.cssVarBlock({size:J(s.value)}):void 0),T=p(()=>({objectFit:t.fit}));I(()=>[t.src,t.srcSet],()=>o.value=!1);function P(i){o.value=!0,r("error",i)}return(i,u)=>(f(),y("span",{class:K(B.value),style:S(x.value)},[(a.src||a.srcSet)&&!o.value?(f(),y("img",{key:0,src:a.src,alt:a.alt,srcset:a.srcSet,style:S(T.value),onError:P},null,44,sa)):a.icon?(f(),h(D(F),{key:1},{default:_(()=>[(f(),h(q(a.icon)))]),_:1})):G(i.$slots,"default",{key:2})],6))}}),k=la,N=A({name:"ElAvatarGroup",props:ta,setup(a,{slots:n}){const t=E("avatar-group");return H(b,M({size:g(a,"size"),shape:g(a,"shape")})),()=>{var l;const r=X(((l=n.default)==null?void 0:l.call(n))??[]);let e=r;if(a.collapseAvatars&&r.length>a.maxCollapseAvatars){e=r.slice(0,a.maxCollapseAvatars);const o=r.slice(a.maxCollapseAvatars);e.push(d(Z,{popperClass:a.popperClass,popperStyle:a.popperStyle,placement:a.placement,effect:a.effect,disabled:!a.collapseAvatarsTooltip},{default:()=>d(k,{size:a.size,shape:a.shape,class:a.collapseClass,style:a.collapseStyle},{default:()=>[$("+ "),o.length]}),content:()=>d("div",{class:t.e("collapse-avatars")},[o.map((s,v)=>O(s)?U(s,{key:s.key??v}):s)])}))}return d("div",{class:t.b()},[e])}}});const na=Q(k,{AvatarGroup:N});W(N);export{na as E};

View File

@@ -1 +1 @@
import{b as y,R as h,d as v,u as g,a as C,o as r,c as l,n as o,f as a,h as d,x as i,aa as f,g as c,q as S,al as b,l as m}from"./index-CGB0A5x_.js";const w=y({header:{type:String,default:""},footer:{type:String,default:""},bodyStyle:{type:h([String,Object,Array,Boolean]),default:""},headerClass:String,bodyClass:String,footerClass:String,shadow:{type:String,values:["always","hover","never"],default:void 0}});var $=v({name:"ElCard",__name:"card",props:w,setup(e){const u=g("card"),s=C("card");return(t,p)=>{var n;return r(),l("div",{class:o([a(s).b(),a(s).is(`${e.shadow||((n=a(u))==null?void 0:n.shadow)||"always"}-shadow`)])},[t.$slots.header||e.header?(r(),l("div",{key:0,class:o([a(s).e("header"),e.headerClass])},[d(t.$slots,"header",{},()=>[i(f(e.header),1)])],2)):c("v-if",!0),S("div",{class:o([a(s).e("body"),e.bodyClass]),style:b(e.bodyStyle)},[d(t.$slots,"default")],6),t.$slots.footer||e.footer?(r(),l("div",{key:1,class:o([a(s).e("footer"),e.footerClass])},[d(t.$slots,"footer",{},()=>[i(f(e.footer),1)])],2)):c("v-if",!0)],2)}}}),k=$;const E=m(k);export{E};
import{b as y,R as h,d as v,u as g,a as C,o as r,c as l,n as o,f as a,h as d,x as i,aa as f,g as c,q as S,al as b,l as m}from"./index-Dd84m4NL.js";const w=y({header:{type:String,default:""},footer:{type:String,default:""},bodyStyle:{type:h([String,Object,Array,Boolean]),default:""},headerClass:String,bodyClass:String,footerClass:String,shadow:{type:String,values:["always","hover","never"],default:void 0}});var $=v({name:"ElCard",__name:"card",props:w,setup(e){const u=g("card"),s=C("card");return(t,p)=>{var n;return r(),l("div",{class:o([a(s).b(),a(s).is(`${e.shadow||((n=a(u))==null?void 0:n.shadow)||"always"}-shadow`)])},[t.$slots.header||e.header?(r(),l("div",{key:0,class:o([a(s).e("header"),e.headerClass])},[d(t.$slots,"header",{},()=>[i(f(e.header),1)])],2)):c("v-if",!0),S("div",{class:o([a(s).e("body"),e.bodyClass]),style:b(e.bodyStyle)},[d(t.$slots,"default")],6),t.$slots.footer||e.footer?(r(),l("div",{key:1,class:o([a(s).e("footer"),e.footerClass])},[d(t.$slots,"footer",{},()=>[i(f(e.footer),1)])],2)):c("v-if",!0)],2)}}}),k=$;const E=m(k);export{E};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{b as B,aS as H,d as P,R as J,am as A,a as L,K as x,I as D,a8 as Q,B as q,f as d,o as c,c as f,q as v,M as g,ad as z,e as I,s as R,bF as T,n as _,h as j,x as K,aa as M,g as X,j as Y,F as Z,ab as ee,l as te}from"./index-CGB0A5x_.js";import{g as se,f as le}from"./vnode-DFpZw5lG.js";import{e as ae}from"./index-CCavIuTY.js";const O=["left","center","right"],re=B({border:Boolean,column:{type:Number,default:3},direction:{type:String,values:["horizontal","vertical"],default:"horizontal"},size:H,title:{type:String,default:""},extra:{type:String,default:""},labelWidth:{type:[String,Number]}}),U="ElDescriptionsItem",ne=B({label:{type:String,default:""},span:{type:Number,default:1},rowspan:{type:Number,default:1},width:{type:[String,Number],default:""},minWidth:{type:[String,Number],default:""},labelWidth:{type:[String,Number]},align:{type:String,values:O,default:"left"},labelAlign:{type:String,values:O},className:{type:String,default:""},labelClassName:{type:String,default:""}}),G=P({name:U,props:ne}),V=Symbol("elDescriptions"),ie=B({row:{type:J(Array),default:()=>[]}});var E=P({name:"ElDescriptionsCell",props:{cell:{type:Object},tag:{type:String,default:"td"},type:{type:String}},setup(){return{descriptions:q(V,{})}},render(){var y;const e=se(this.cell),u=(((y=this.cell)==null?void 0:y.dirs)||[]).map(n=>{const{dir:a,arg:l,modifiers:W,value:$}=n;return[a,$,l,W]}),{border:m,direction:C}=this.descriptions,r=C==="vertical",h=()=>{var n,a,l;return((l=(a=(n=this.cell)==null?void 0:n.children)==null?void 0:a.label)==null?void 0:l.call(a))||e.label},k=()=>{var n,a,l;return(l=(a=(n=this.cell)==null?void 0:n.children)==null?void 0:a.default)==null?void 0:l.call(a)},S=e.span,s=e.rowspan,b=e.align?`is-${e.align}`:"",p=e.labelAlign?`is-${e.labelAlign}`:b,i=e.className,w=e.labelClassName,o={width:A(this.type==="label"?e.labelWidth??this.descriptions.labelWidth??e.width:e.width),minWidth:A(e.minWidth)},t=L("descriptions");switch(this.type){case"label":return x(D(this.tag,{style:o,class:[t.e("cell"),t.e("label"),t.is("bordered-label",m),t.is("vertical-label",r),p,w],colSpan:r?S:1,rowspan:r?1:s},h()),u);case"content":return x(D(this.tag,{style:o,class:[t.e("cell"),t.e("content"),t.is("bordered-content",m),t.is("vertical-content",r),b,i],colSpan:r?S:S*2-1,rowspan:r?s*2-1:s},k()),u);default:{const n=h(),a={},l=A(e.labelWidth??this.descriptions.labelWidth);return l&&(a.width=l,a.display="inline-block"),x(D("td",{style:o,class:[t.e("cell"),b],colSpan:S,rowspan:s},[Q(n)?void 0:D("span",{style:a,class:[t.e("label"),w]},n),D("span",{class:[t.e("content"),i]},k())]),u)}}}});const oe={key:1};var ce=P({name:"ElDescriptionsRow",__name:"descriptions-row",props:ie,setup(e){const u=q(V,{});return(m,C)=>d(u).direction==="vertical"?(c(),f(g,{key:0},[v("tr",null,[(c(!0),f(g,null,z(e.row,(r,h)=>(c(),I(d(E),{key:`tr1-${h}`,cell:r,tag:"th",type:"label"},null,8,["cell"]))),128))]),v("tr",null,[(c(!0),f(g,null,z(e.row,(r,h)=>(c(),I(d(E),{key:`tr2-${h}`,cell:r,tag:"td",type:"content"},null,8,["cell"]))),128))])],64)):(c(),f("tr",oe,[(c(!0),f(g,null,z(e.row,(r,h)=>(c(),f(g,{key:`tr3-${h}`},[d(u).border?(c(),f(g,{key:0},[R(d(E),{cell:r,tag:"td",type:"label"},null,8,["cell"]),R(d(E),{cell:r,tag:"td",type:"content"},null,8,["cell"])],64)):(c(),I(d(E),{key:1,cell:r,tag:"td",type:"both"},null,8,["cell"]))],64))),128))]))}}),pe=ce,de=P({name:"ElDescriptions",__name:"description",props:re,setup(e){const u=e,m=L("descriptions"),C=ae(),r=T();Z(V,u);const h=Y(()=>[m.b(),m.m(C.value)]),k=(s,b,p,i=!1)=>(s.props||(s.props={}),b>p&&(s.props.span=p),i&&(s.props.span=b),s),S=()=>{if(!r.default)return[];const s=le(r.default()).filter(t=>{var y;return((y=t==null?void 0:t.type)==null?void 0:y.name)===U}),b=[];let p=[],i=u.column,w=0;const o=[];return s.forEach((t,y)=>{var W,$,F;const n=((W=t.props)==null?void 0:W.span)||1,a=(($=t.props)==null?void 0:$.rowspan)||1,l=b.length;if(o[l]||(o[l]=0),a>1)for(let N=1;N<a;N++)o[F=l+N]||(o[F]=0),o[l+N]++,w++;if(o[l]>0&&(i-=o[l],o[l]=0),y<s.length-1&&(w+=n>i?i:n),y===s.length-1){const N=u.column-w%u.column;p.push(k(t,N,i,!0)),b.push(p);return}n<i?(i-=n,p.push(t)):(p.push(k(t,n,i)),b.push(p),i=u.column,p=[])}),b};return(s,b)=>(c(),f("div",{class:_(h.value)},[e.title||e.extra||s.$slots.title||s.$slots.extra?(c(),f("div",{key:0,class:_(d(m).e("header"))},[v("div",{class:_(d(m).e("title"))},[j(s.$slots,"title",{},()=>[K(M(e.title),1)])],2),v("div",{class:_(d(m).e("extra"))},[j(s.$slots,"extra",{},()=>[K(M(e.extra),1)])],2)],2)):X("v-if",!0),v("div",{class:_(d(m).e("body"))},[v("table",{class:_([d(m).e("table"),d(m).is("bordered",e.border)])},[v("tbody",null,[(c(!0),f(g,null,z(S(),(p,i)=>(c(),I(pe,{key:i,row:p},null,8,["row"]))),128))])],2)],2)],2))}}),ue=de;const fe=te(ue,{DescriptionsItem:G}),ye=ee(G);export{ye as E,fe as a};
import{b as B,aS as H,d as P,R as J,am as A,a as L,K as x,I as D,a8 as Q,B as q,f as d,o as c,c as f,q as v,M as g,ad as z,e as I,s as R,bF as T,n as _,h as j,x as K,aa as M,g as X,j as Y,F as Z,ab as ee,l as te}from"./index-Dd84m4NL.js";import{g as se,f as le}from"./vnode-CasYkit1.js";import{e as ae}from"./index-9zpOHVFd.js";const O=["left","center","right"],re=B({border:Boolean,column:{type:Number,default:3},direction:{type:String,values:["horizontal","vertical"],default:"horizontal"},size:H,title:{type:String,default:""},extra:{type:String,default:""},labelWidth:{type:[String,Number]}}),U="ElDescriptionsItem",ne=B({label:{type:String,default:""},span:{type:Number,default:1},rowspan:{type:Number,default:1},width:{type:[String,Number],default:""},minWidth:{type:[String,Number],default:""},labelWidth:{type:[String,Number]},align:{type:String,values:O,default:"left"},labelAlign:{type:String,values:O},className:{type:String,default:""},labelClassName:{type:String,default:""}}),G=P({name:U,props:ne}),V=Symbol("elDescriptions"),ie=B({row:{type:J(Array),default:()=>[]}});var E=P({name:"ElDescriptionsCell",props:{cell:{type:Object},tag:{type:String,default:"td"},type:{type:String}},setup(){return{descriptions:q(V,{})}},render(){var y;const e=se(this.cell),u=(((y=this.cell)==null?void 0:y.dirs)||[]).map(n=>{const{dir:a,arg:l,modifiers:W,value:$}=n;return[a,$,l,W]}),{border:m,direction:C}=this.descriptions,r=C==="vertical",h=()=>{var n,a,l;return((l=(a=(n=this.cell)==null?void 0:n.children)==null?void 0:a.label)==null?void 0:l.call(a))||e.label},k=()=>{var n,a,l;return(l=(a=(n=this.cell)==null?void 0:n.children)==null?void 0:a.default)==null?void 0:l.call(a)},S=e.span,s=e.rowspan,b=e.align?`is-${e.align}`:"",p=e.labelAlign?`is-${e.labelAlign}`:b,i=e.className,w=e.labelClassName,o={width:A(this.type==="label"?e.labelWidth??this.descriptions.labelWidth??e.width:e.width),minWidth:A(e.minWidth)},t=L("descriptions");switch(this.type){case"label":return x(D(this.tag,{style:o,class:[t.e("cell"),t.e("label"),t.is("bordered-label",m),t.is("vertical-label",r),p,w],colSpan:r?S:1,rowspan:r?1:s},h()),u);case"content":return x(D(this.tag,{style:o,class:[t.e("cell"),t.e("content"),t.is("bordered-content",m),t.is("vertical-content",r),b,i],colSpan:r?S:S*2-1,rowspan:r?s*2-1:s},k()),u);default:{const n=h(),a={},l=A(e.labelWidth??this.descriptions.labelWidth);return l&&(a.width=l,a.display="inline-block"),x(D("td",{style:o,class:[t.e("cell"),b],colSpan:S,rowspan:s},[Q(n)?void 0:D("span",{style:a,class:[t.e("label"),w]},n),D("span",{class:[t.e("content"),i]},k())]),u)}}}});const oe={key:1};var ce=P({name:"ElDescriptionsRow",__name:"descriptions-row",props:ie,setup(e){const u=q(V,{});return(m,C)=>d(u).direction==="vertical"?(c(),f(g,{key:0},[v("tr",null,[(c(!0),f(g,null,z(e.row,(r,h)=>(c(),I(d(E),{key:`tr1-${h}`,cell:r,tag:"th",type:"label"},null,8,["cell"]))),128))]),v("tr",null,[(c(!0),f(g,null,z(e.row,(r,h)=>(c(),I(d(E),{key:`tr2-${h}`,cell:r,tag:"td",type:"content"},null,8,["cell"]))),128))])],64)):(c(),f("tr",oe,[(c(!0),f(g,null,z(e.row,(r,h)=>(c(),f(g,{key:`tr3-${h}`},[d(u).border?(c(),f(g,{key:0},[R(d(E),{cell:r,tag:"td",type:"label"},null,8,["cell"]),R(d(E),{cell:r,tag:"td",type:"content"},null,8,["cell"])],64)):(c(),I(d(E),{key:1,cell:r,tag:"td",type:"both"},null,8,["cell"]))],64))),128))]))}}),pe=ce,de=P({name:"ElDescriptions",__name:"description",props:re,setup(e){const u=e,m=L("descriptions"),C=ae(),r=T();Z(V,u);const h=Y(()=>[m.b(),m.m(C.value)]),k=(s,b,p,i=!1)=>(s.props||(s.props={}),b>p&&(s.props.span=p),i&&(s.props.span=b),s),S=()=>{if(!r.default)return[];const s=le(r.default()).filter(t=>{var y;return((y=t==null?void 0:t.type)==null?void 0:y.name)===U}),b=[];let p=[],i=u.column,w=0;const o=[];return s.forEach((t,y)=>{var W,$,F;const n=((W=t.props)==null?void 0:W.span)||1,a=(($=t.props)==null?void 0:$.rowspan)||1,l=b.length;if(o[l]||(o[l]=0),a>1)for(let N=1;N<a;N++)o[F=l+N]||(o[F]=0),o[l+N]++,w++;if(o[l]>0&&(i-=o[l],o[l]=0),y<s.length-1&&(w+=n>i?i:n),y===s.length-1){const N=u.column-w%u.column;p.push(k(t,N,i,!0)),b.push(p);return}n<i?(i-=n,p.push(t)):(p.push(k(t,n,i)),b.push(p),i=u.column,p=[])}),b};return(s,b)=>(c(),f("div",{class:_(h.value)},[e.title||e.extra||s.$slots.title||s.$slots.extra?(c(),f("div",{key:0,class:_(d(m).e("header"))},[v("div",{class:_(d(m).e("title"))},[j(s.$slots,"title",{},()=>[K(M(e.title),1)])],2),v("div",{class:_(d(m).e("extra"))},[j(s.$slots,"extra",{},()=>[K(M(e.extra),1)])],2)],2)):X("v-if",!0),v("div",{class:_(d(m).e("body"))},[v("table",{class:_([d(m).e("table"),d(m).is("bordered",e.border)])},[v("tbody",null,[(c(!0),f(g,null,z(S(),(p,i)=>(c(),I(pe,{key:i,row:p},null,8,["row"]))),128))])],2)],2)],2))}}),ue=de;const fe=te(ue,{DescriptionsItem:G}),ye=ee(G);export{ye as E,fe as a};

View File

@@ -1 +1 @@
import{d as L,aW as G,B as q,o as u,c as A,q as R,h as i,n as t,f as e,aa as H,s as $,w as r,e as B,r as Q,bE as x,E as _,g as N,al as O,j as E,bF as ee,a as oe,K as se,Y as K,aX as ae,L as le,Z as te,bg as ne,y as M,F as re,l as ie}from"./index-CGB0A5x_.js";import{u as de}from"./index-CCavIuTY.js";import{E as ce,a as ue}from"./index-C5EKbiob.js";import{F as fe,f as ge}from"./index-BPwPlcbL.js";import{d as me,a as ve,b as j,c as be,e as ye,u as Ce}from"./use-dialog-C7BHP2NJ.js";import{u as he}from"./index-Coa9QRND.js";const pe=(...o)=>f=>{o.forEach(g=>{g.value=f})},we=["aria-level"],ke=["aria-label"],Re=["id"];var $e=L({name:"ElDialogContent",__name:"dialog-content",props:ve,emits:me,setup(o,{expose:f}){const{t:g}=G(),{Close:F}=x,a=o,{dialogRef:m,headerRef:y,bodyId:v,ns:s,style:C}=q(j),{focusTrapRef:h}=q(fe),D=pe(h,m),p=E(()=>!!a.draggable),{resetPosition:w,updatePosition:I,isDragging:P}=he(m,y,p,E(()=>!!a.overflow)),T=E(()=>[s.b(),s.is("fullscreen",a.fullscreen),s.is("draggable",p.value),s.is("dragging",P.value),s.is("align-center",!!a.alignCenter),{[s.m("center")]:a.center}]);return f({resetPosition:w,updatePosition:I}),(n,k)=>(u(),A("div",{ref:e(D),class:t(T.value),style:O(e(C)),tabindex:"-1"},[R("header",{ref_key:"headerRef",ref:y,class:t([e(s).e("header"),o.headerClass,{"show-close":o.showClose}])},[i(n.$slots,"header",{},()=>[R("span",{role:"heading","aria-level":o.ariaLevel,class:t(e(s).e("title"))},H(o.title),11,we)]),o.showClose?(u(),A("button",{key:0,"aria-label":e(g)("el.dialog.close"),class:t(e(s).e("headerbtn")),type:"button",onClick:k[0]||(k[0]=z=>n.$emit("close"))},[$(e(_),{class:t(e(s).e("close"))},{default:r(()=>[(u(),B(Q(o.closeIcon||e(F))))]),_:1},8,["class"])],10,ke)):N("v-if",!0)],2),R("div",{id:e(v),class:t([e(s).e("body"),o.bodyClass])},[i(n.$slots,"default")],10,Re),n.$slots.footer?(u(),A("footer",{key:0,class:t([e(s).e("footer"),o.footerClass])},[i(n.$slots,"footer")],2)):N("v-if",!0)],6))}}),Ee=$e;const Fe=["aria-label","aria-labelledby","aria-describedby"];var De=L({name:"ElDialog",inheritAttrs:!1,__name:"dialog",props:ye,emits:be,setup(o,{expose:f}){const g=o,F=ee();de({scope:"el-dialog",from:"the title slot",replacement:"the header slot",version:"3.0.0",ref:"https://element-plus.org/en-US/component/dialog.html#slots"},E(()=>!!F.title));const a=oe("dialog"),m=M(),y=M(),v=M(),{visible:s,titleId:C,bodyId:h,style:D,overlayDialogStyle:p,rendered:w,transitionConfig:I,zIndex:P,_draggable:T,_alignCenter:n,_overflow:k,penetrable:z,handleClose:S,onModalClick:V,onOpenAutoFocus:U,onCloseAutoFocus:Y,onCloseRequested:J,onFocusoutPrevented:W,bringToFront:X,closing:Z}=Ce(g,m);re(j,{dialogRef:m,headerRef:y,bodyId:h,ns:a,rendered:w,style:D});const d=ue(V);return f({visible:s,dialogContentRef:v,resetPosition:()=>{var l;(l=v.value)==null||l.resetPosition()},handleClose:S}),(l,c)=>(u(),B(ne,{to:o.appendTo,disabled:o.appendTo!=="body"?!1:!o.appendToBody},[$(te,K(e(I),{persisted:""}),{default:r(()=>[se($(e(ce),{"custom-mask-event":"",mask:o.modal,"overlay-class":[o.modalClass??"",`${e(a).namespace.value}-modal-dialog`,e(a).is("penetrable",e(z))],"z-index":e(P)},{default:r(()=>[R("div",{role:"dialog","aria-modal":"true","aria-label":o.title||void 0,"aria-labelledby":o.title?void 0:e(C),"aria-describedby":e(h),class:t([`${e(a).namespace.value}-overlay-dialog`,e(a).is("closing",e(Z))]),style:O(e(p)),onClick:c[0]||(c[0]=(...b)=>e(d).onClick&&e(d).onClick(...b)),onMousedown:c[1]||(c[1]=(...b)=>e(d).onMousedown&&e(d).onMousedown(...b)),onMouseup:c[2]||(c[2]=(...b)=>e(d).onMouseup&&e(d).onMouseup(...b))},[$(e(ge),{loop:"",trapped:e(s),"focus-start-el":"container",onFocusAfterTrapped:e(U),onFocusAfterReleased:e(Y),onFocusoutPrevented:e(W),onReleaseRequested:e(J)},{default:r(()=>[e(w)?(u(),B(Ee,K({key:0,ref_key:"dialogContentRef",ref:v},l.$attrs,{center:o.center,"align-center":e(n),"close-icon":o.closeIcon,draggable:e(T),overflow:e(k),fullscreen:o.fullscreen,"header-class":o.headerClass,"body-class":o.bodyClass,"footer-class":o.footerClass,"show-close":o.showClose,title:o.title,"aria-level":o.headerAriaLevel,onClose:e(S),onMousedown:e(X)}),ae({header:r(()=>[l.$slots.title?i(l.$slots,"title",{key:1}):i(l.$slots,"header",{key:0,close:e(S),titleId:e(C),titleClass:e(a).e("title")})]),default:r(()=>[i(l.$slots,"default")]),_:2},[l.$slots.footer?{name:"footer",fn:r(()=>[i(l.$slots,"footer")]),key:"0"}:void 0]),1040,["center","align-center","close-icon","draggable","overflow","fullscreen","header-class","body-class","footer-class","show-close","title","aria-level","onClose","onMousedown"])):N("v-if",!0)]),_:3},8,["trapped","onFocusAfterTrapped","onFocusAfterReleased","onFocusoutPrevented","onReleaseRequested"])],46,Fe)]),_:3},8,["mask","overlay-class","z-index"]),[[le,e(s)]])]),_:3},16)],8,["to","disabled"]))}}),Ie=De;const ze=ie(Ie);export{ze as E,pe as c};
import{d as L,aW as G,B as q,o as u,c as A,q as R,h as i,n as t,f as e,aa as H,s as $,w as r,e as B,r as Q,bE as x,E as _,g as N,al as O,j as E,bF as ee,a as oe,K as se,Y as K,aX as ae,L as le,Z as te,bg as ne,y as M,F as re,l as ie}from"./index-Dd84m4NL.js";import{u as de}from"./index-9zpOHVFd.js";import{E as ce,a as ue}from"./index-B6n2yrjP.js";import{F as fe,f as ge}from"./index-KnEmF0FL.js";import{d as me,a as ve,b as j,c as be,e as ye,u as Ce}from"./use-dialog-CGW4SdZ1.js";import{u as he}from"./index-BsIWQhw5.js";const pe=(...o)=>f=>{o.forEach(g=>{g.value=f})},we=["aria-level"],ke=["aria-label"],Re=["id"];var $e=L({name:"ElDialogContent",__name:"dialog-content",props:ve,emits:me,setup(o,{expose:f}){const{t:g}=G(),{Close:F}=x,a=o,{dialogRef:m,headerRef:y,bodyId:v,ns:s,style:C}=q(j),{focusTrapRef:h}=q(fe),D=pe(h,m),p=E(()=>!!a.draggable),{resetPosition:w,updatePosition:I,isDragging:P}=he(m,y,p,E(()=>!!a.overflow)),T=E(()=>[s.b(),s.is("fullscreen",a.fullscreen),s.is("draggable",p.value),s.is("dragging",P.value),s.is("align-center",!!a.alignCenter),{[s.m("center")]:a.center}]);return f({resetPosition:w,updatePosition:I}),(n,k)=>(u(),A("div",{ref:e(D),class:t(T.value),style:O(e(C)),tabindex:"-1"},[R("header",{ref_key:"headerRef",ref:y,class:t([e(s).e("header"),o.headerClass,{"show-close":o.showClose}])},[i(n.$slots,"header",{},()=>[R("span",{role:"heading","aria-level":o.ariaLevel,class:t(e(s).e("title"))},H(o.title),11,we)]),o.showClose?(u(),A("button",{key:0,"aria-label":e(g)("el.dialog.close"),class:t(e(s).e("headerbtn")),type:"button",onClick:k[0]||(k[0]=z=>n.$emit("close"))},[$(e(_),{class:t(e(s).e("close"))},{default:r(()=>[(u(),B(Q(o.closeIcon||e(F))))]),_:1},8,["class"])],10,ke)):N("v-if",!0)],2),R("div",{id:e(v),class:t([e(s).e("body"),o.bodyClass])},[i(n.$slots,"default")],10,Re),n.$slots.footer?(u(),A("footer",{key:0,class:t([e(s).e("footer"),o.footerClass])},[i(n.$slots,"footer")],2)):N("v-if",!0)],6))}}),Ee=$e;const Fe=["aria-label","aria-labelledby","aria-describedby"];var De=L({name:"ElDialog",inheritAttrs:!1,__name:"dialog",props:ye,emits:be,setup(o,{expose:f}){const g=o,F=ee();de({scope:"el-dialog",from:"the title slot",replacement:"the header slot",version:"3.0.0",ref:"https://element-plus.org/en-US/component/dialog.html#slots"},E(()=>!!F.title));const a=oe("dialog"),m=M(),y=M(),v=M(),{visible:s,titleId:C,bodyId:h,style:D,overlayDialogStyle:p,rendered:w,transitionConfig:I,zIndex:P,_draggable:T,_alignCenter:n,_overflow:k,penetrable:z,handleClose:S,onModalClick:V,onOpenAutoFocus:U,onCloseAutoFocus:Y,onCloseRequested:J,onFocusoutPrevented:W,bringToFront:X,closing:Z}=Ce(g,m);re(j,{dialogRef:m,headerRef:y,bodyId:h,ns:a,rendered:w,style:D});const d=ue(V);return f({visible:s,dialogContentRef:v,resetPosition:()=>{var l;(l=v.value)==null||l.resetPosition()},handleClose:S}),(l,c)=>(u(),B(ne,{to:o.appendTo,disabled:o.appendTo!=="body"?!1:!o.appendToBody},[$(te,K(e(I),{persisted:""}),{default:r(()=>[se($(e(ce),{"custom-mask-event":"",mask:o.modal,"overlay-class":[o.modalClass??"",`${e(a).namespace.value}-modal-dialog`,e(a).is("penetrable",e(z))],"z-index":e(P)},{default:r(()=>[R("div",{role:"dialog","aria-modal":"true","aria-label":o.title||void 0,"aria-labelledby":o.title?void 0:e(C),"aria-describedby":e(h),class:t([`${e(a).namespace.value}-overlay-dialog`,e(a).is("closing",e(Z))]),style:O(e(p)),onClick:c[0]||(c[0]=(...b)=>e(d).onClick&&e(d).onClick(...b)),onMousedown:c[1]||(c[1]=(...b)=>e(d).onMousedown&&e(d).onMousedown(...b)),onMouseup:c[2]||(c[2]=(...b)=>e(d).onMouseup&&e(d).onMouseup(...b))},[$(e(ge),{loop:"",trapped:e(s),"focus-start-el":"container",onFocusAfterTrapped:e(U),onFocusAfterReleased:e(Y),onFocusoutPrevented:e(W),onReleaseRequested:e(J)},{default:r(()=>[e(w)?(u(),B(Ee,K({key:0,ref_key:"dialogContentRef",ref:v},l.$attrs,{center:o.center,"align-center":e(n),"close-icon":o.closeIcon,draggable:e(T),overflow:e(k),fullscreen:o.fullscreen,"header-class":o.headerClass,"body-class":o.bodyClass,"footer-class":o.footerClass,"show-close":o.showClose,title:o.title,"aria-level":o.headerAriaLevel,onClose:e(S),onMousedown:e(X)}),ae({header:r(()=>[l.$slots.title?i(l.$slots,"title",{key:1}):i(l.$slots,"header",{key:0,close:e(S),titleId:e(C),titleClass:e(a).e("title")})]),default:r(()=>[i(l.$slots,"default")]),_:2},[l.$slots.footer?{name:"footer",fn:r(()=>[i(l.$slots,"footer")]),key:"0"}:void 0]),1040,["center","align-center","close-icon","draggable","overflow","fullscreen","header-class","body-class","footer-class","show-close","title","aria-level","onClose","onMousedown"])):N("v-if",!0)]),_:3},8,["trapped","onFocusAfterTrapped","onFocusAfterReleased","onFocusoutPrevented","onReleaseRequested"])],46,Fe)]),_:3},8,["mask","overlay-class","z-index"]),[[le,e(s)]])]),_:3},16)],8,["to","disabled"]))}}),Ie=De;const ze=ie(Ie);export{ze as E,pe as c};

View File

@@ -1 +1 @@
import{b as d,R as c,d as u,a as v,o as s,c as i,n as o,f as r,h as p,g as f,al as m,j as y,l as S}from"./index-CGB0A5x_.js";const b=d({direction:{type:String,values:["horizontal","vertical"],default:"horizontal"},contentPosition:{type:String,values:["left","center","right"],default:"center"},borderStyle:{type:c(String),default:"solid"}});var g=u({name:"ElDivider",__name:"divider",props:b,setup(t){const l=t,e=v("divider"),n=y(()=>e.cssVar({"border-style":l.borderStyle}));return(a,P)=>(s(),i("div",{class:o([r(e).b(),r(e).m(t.direction)]),style:m(n.value),role:"separator"},[a.$slots.default&&t.direction!=="vertical"?(s(),i("div",{key:0,class:o([r(e).e("text"),r(e).is(t.contentPosition)])},[p(a.$slots,"default")],2)):f("v-if",!0)],6))}}),h=g;const z=S(h);export{z as E};
import{b as d,R as c,d as u,a as v,o as s,c as i,n as o,f as r,h as p,g as f,al as m,j as y,l as S}from"./index-Dd84m4NL.js";const b=d({direction:{type:String,values:["horizontal","vertical"],default:"horizontal"},contentPosition:{type:String,values:["left","center","right"],default:"center"},borderStyle:{type:c(String),default:"solid"}});var g=u({name:"ElDivider",__name:"divider",props:b,setup(t){const l=t,e=v("divider"),n=y(()=>e.cssVar({"border-style":l.borderStyle}));return(a,P)=>(s(),i("div",{class:o([r(e).b(),r(e).m(t.direction)]),style:m(n.value),role:"separator"},[a.$slots.default&&t.direction!=="vertical"?(s(),i("div",{key:0,class:o([r(e).e("text"),r(e).is(t.contentPosition)])},[p(a.$slots,"default")],2)):f("v-if",!0)],6))}}),h=g;const z=S(h);export{z as E};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{b as h,d as p,a as _,o as r,c as n,q as t,f as l,aW as y,h as d,s as g,al as v,n as c,aa as k,g as $,j as f,am as N,l as B}from"./index-CGB0A5x_.js";import{f as w}from"./index-CCavIuTY.js";const V=h({image:{type:String,default:""},imageSize:Number,description:{type:String,default:""}}),x={viewBox:"0 0 79 86",version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},S=["id"],C=["stop-color"],E=["stop-color"],b=["id"],G=["stop-color"],z=["stop-color"],I=["id"],D={stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},P={transform:"translate(-1268.000000, -535.000000)"},j={transform:"translate(1268.000000, 535.000000)"},q=["fill"],L=["fill"],M={transform:"translate(34.500000, 31.500000) scale(-1, 1) rotate(-25.000000) translate(-34.500000, -31.500000) translate(7.000000, 10.000000)"},T=["fill"],U=["fill"],W=["fill"],Z=["fill"],A=["fill"],F={transform:"translate(53.000000, 45.000000)"},H=["fill","xlink:href"],J=["fill","mask"],K=["fill"];var O=p({name:"ImgEmpty",__name:"img-empty",setup(i){const s=_("empty"),e=w();return(o,m)=>(r(),n("svg",x,[t("defs",null,[t("linearGradient",{id:`linearGradient-1-${l(e)}`,x1:"38.8503086%",y1:"0%",x2:"61.1496914%",y2:"100%"},[t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-1")})`,offset:"0%"},null,8,C),t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-4")})`,offset:"100%"},null,8,E)],8,S),t("linearGradient",{id:`linearGradient-2-${l(e)}`,x1:"0%",y1:"9.5%",x2:"100%",y2:"90.5%"},[t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-1")})`,offset:"0%"},null,8,G),t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-6")})`,offset:"100%"},null,8,z)],8,b),t("rect",{id:`path-3-${l(e)}`,x:"0",y:"0",width:"17",height:"36"},null,8,I)]),t("g",D,[t("g",P,[t("g",j,[t("path",{d:"M39.5,86 C61.3152476,86 79,83.9106622 79,81.3333333 C79,78.7560045 57.3152476,78 35.5,78 C13.6847524,78 0,78.7560045 0,81.3333333 C0,83.9106622 17.6847524,86 39.5,86 Z",fill:`var(${l(s).cssVarBlockName("fill-color-3")})`},null,8,q),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-7")})`,transform:"translate(27.500000, 51.500000) scale(1, -1) translate(-27.500000, -51.500000) ",points:"13 58 53 58 42 45 2 45"},null,8,L),t("g",M,[t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-7")})`,transform:"translate(11.500000, 5.000000) scale(1, -1) translate(-11.500000, -5.000000) ",points:"2.84078316e-14 3 18 3 23 7 5 7"},null,8,T),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-5")})`,points:"-3.69149156e-15 7 38 7 38 43 -3.69149156e-15 43"},null,8,U),t("rect",{fill:`url(#linearGradient-1-${l(e)})`,transform:"translate(46.500000, 25.000000) scale(-1, 1) translate(-46.500000, -25.000000) ",x:"38",y:"7",width:"17",height:"36"},null,8,W),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-2")})`,transform:"translate(39.500000, 3.500000) scale(-1, 1) translate(-39.500000, -3.500000) ",points:"24 7 41 7 55 -3.63806207e-12 38 -3.63806207e-12"},null,8,Z)]),t("rect",{fill:`url(#linearGradient-2-${l(e)})`,x:"13",y:"45",width:"40",height:"36"},null,8,A),t("g",F,[t("use",{fill:`var(${l(s).cssVarBlockName("fill-color-8")})`,transform:"translate(8.500000, 18.000000) scale(-1, 1) translate(-8.500000, -18.000000) ","xlink:href":`#path-3-${l(e)}`},null,8,H),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-9")})`,mask:`url(#mask-4-${l(e)})`,transform:"translate(12.000000, 9.000000) scale(-1, 1) translate(-12.000000, -9.000000) ",points:"7 0 24 0 20 18 7 16.5"},null,8,J)]),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-2")})`,transform:"translate(66.000000, 51.500000) scale(-1, 1) translate(-66.000000, -51.500000) ",points:"62 45 79 45 70 58 53 58"},null,8,K)])])])]))}}),Q=O;const R=["src"],X={key:1};var Y=p({name:"ElEmpty",__name:"empty",props:V,setup(i){const s=i,{t:e}=y(),o=_("empty"),m=f(()=>s.description||e("el.table.emptyText")),u=f(()=>({width:N(s.imageSize)}));return(a,l0)=>(r(),n("div",{class:c(l(o).b())},[t("div",{class:c(l(o).e("image")),style:v(u.value)},[i.image?(r(),n("img",{key:0,src:i.image,ondragstart:"return false"},null,8,R)):d(a.$slots,"image",{key:1},()=>[g(Q)])],6),t("div",{class:c(l(o).e("description"))},[a.$slots.description?d(a.$slots,"description",{key:0}):(r(),n("p",X,k(m.value),1))],2),a.$slots.default?(r(),n("div",{key:0,class:c(l(o).e("bottom"))},[d(a.$slots,"default")],2)):$("v-if",!0)],2))}}),t0=Y;const o0=B(t0);export{o0 as E};
import{b as h,d as p,a as _,o as r,c as n,q as t,f as l,aW as y,h as d,s as g,al as v,n as c,aa as k,g as $,j as f,am as N,l as B}from"./index-Dd84m4NL.js";import{f as w}from"./index-9zpOHVFd.js";const V=h({image:{type:String,default:""},imageSize:Number,description:{type:String,default:""}}),x={viewBox:"0 0 79 86",version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},S=["id"],C=["stop-color"],E=["stop-color"],b=["id"],G=["stop-color"],z=["stop-color"],I=["id"],D={stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},P={transform:"translate(-1268.000000, -535.000000)"},j={transform:"translate(1268.000000, 535.000000)"},q=["fill"],L=["fill"],M={transform:"translate(34.500000, 31.500000) scale(-1, 1) rotate(-25.000000) translate(-34.500000, -31.500000) translate(7.000000, 10.000000)"},T=["fill"],U=["fill"],W=["fill"],Z=["fill"],A=["fill"],F={transform:"translate(53.000000, 45.000000)"},H=["fill","xlink:href"],J=["fill","mask"],K=["fill"];var O=p({name:"ImgEmpty",__name:"img-empty",setup(i){const s=_("empty"),e=w();return(o,m)=>(r(),n("svg",x,[t("defs",null,[t("linearGradient",{id:`linearGradient-1-${l(e)}`,x1:"38.8503086%",y1:"0%",x2:"61.1496914%",y2:"100%"},[t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-1")})`,offset:"0%"},null,8,C),t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-4")})`,offset:"100%"},null,8,E)],8,S),t("linearGradient",{id:`linearGradient-2-${l(e)}`,x1:"0%",y1:"9.5%",x2:"100%",y2:"90.5%"},[t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-1")})`,offset:"0%"},null,8,G),t("stop",{"stop-color":`var(${l(s).cssVarBlockName("fill-color-6")})`,offset:"100%"},null,8,z)],8,b),t("rect",{id:`path-3-${l(e)}`,x:"0",y:"0",width:"17",height:"36"},null,8,I)]),t("g",D,[t("g",P,[t("g",j,[t("path",{d:"M39.5,86 C61.3152476,86 79,83.9106622 79,81.3333333 C79,78.7560045 57.3152476,78 35.5,78 C13.6847524,78 0,78.7560045 0,81.3333333 C0,83.9106622 17.6847524,86 39.5,86 Z",fill:`var(${l(s).cssVarBlockName("fill-color-3")})`},null,8,q),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-7")})`,transform:"translate(27.500000, 51.500000) scale(1, -1) translate(-27.500000, -51.500000) ",points:"13 58 53 58 42 45 2 45"},null,8,L),t("g",M,[t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-7")})`,transform:"translate(11.500000, 5.000000) scale(1, -1) translate(-11.500000, -5.000000) ",points:"2.84078316e-14 3 18 3 23 7 5 7"},null,8,T),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-5")})`,points:"-3.69149156e-15 7 38 7 38 43 -3.69149156e-15 43"},null,8,U),t("rect",{fill:`url(#linearGradient-1-${l(e)})`,transform:"translate(46.500000, 25.000000) scale(-1, 1) translate(-46.500000, -25.000000) ",x:"38",y:"7",width:"17",height:"36"},null,8,W),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-2")})`,transform:"translate(39.500000, 3.500000) scale(-1, 1) translate(-39.500000, -3.500000) ",points:"24 7 41 7 55 -3.63806207e-12 38 -3.63806207e-12"},null,8,Z)]),t("rect",{fill:`url(#linearGradient-2-${l(e)})`,x:"13",y:"45",width:"40",height:"36"},null,8,A),t("g",F,[t("use",{fill:`var(${l(s).cssVarBlockName("fill-color-8")})`,transform:"translate(8.500000, 18.000000) scale(-1, 1) translate(-8.500000, -18.000000) ","xlink:href":`#path-3-${l(e)}`},null,8,H),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-9")})`,mask:`url(#mask-4-${l(e)})`,transform:"translate(12.000000, 9.000000) scale(-1, 1) translate(-12.000000, -9.000000) ",points:"7 0 24 0 20 18 7 16.5"},null,8,J)]),t("polygon",{fill:`var(${l(s).cssVarBlockName("fill-color-2")})`,transform:"translate(66.000000, 51.500000) scale(-1, 1) translate(-66.000000, -51.500000) ",points:"62 45 79 45 70 58 53 58"},null,8,K)])])])]))}}),Q=O;const R=["src"],X={key:1};var Y=p({name:"ElEmpty",__name:"empty",props:V,setup(i){const s=i,{t:e}=y(),o=_("empty"),m=f(()=>s.description||e("el.table.emptyText")),u=f(()=>({width:N(s.imageSize)}));return(a,l0)=>(r(),n("div",{class:c(l(o).b())},[t("div",{class:c(l(o).e("image")),style:v(u.value)},[i.image?(r(),n("img",{key:0,src:i.image,ondragstart:"return false"},null,8,R)):d(a.$slots,"image",{key:1},()=>[g(Q)])],6),t("div",{class:c(l(o).e("description"))},[a.$slots.description?d(a.$slots,"description",{key:0}):(r(),n("p",X,k(m.value),1))],2),a.$slots.default?(r(),n("div",{key:0,class:c(l(o).e("bottom"))},[d(a.$slots,"default")],2)):$("v-if",!0)],2))}}),t0=Y;const o0=B(t0);export{o0 as E};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import{b as A,R as y,d as M,a as V,o as l,c as d,n as i,f as s,q as p,al as f,h as B,aa as N,g as P,e as D,w as O,r as R,E as j,j as o,cZ as q,a$ as J,bQ as Q,b0 as U,b1 as Z,b8 as G,J as I,l as H}from"./index-CGB0A5x_.js";const K=A({type:{type:String,default:"line",values:["line","circle","dashboard"]},percentage:{type:Number,default:0,validator:e=>e>=0&&e<=100},status:{type:String,default:"",values:["","success","exception","warning"]},indeterminate:Boolean,duration:{type:Number,default:3},strokeWidth:{type:Number,default:6},strokeLinecap:{type:y(String),default:"round"},textInside:Boolean,width:{type:Number,default:126},showText:{type:Boolean,default:!0},color:{type:y([String,Array,Function]),default:""},striped:Boolean,stripedFlow:Boolean,format:{type:y(Function),default:e=>`${e}%`}}),X=["aria-valuenow"],Y={viewBox:"0 0 100 100"},_=["d","stroke","stroke-linecap","stroke-width"],ee=["d","stroke","opacity","stroke-linecap","stroke-width"],te={key:0};var ae=M({name:"ElProgress",__name:"progress",props:K,setup(e){const k={success:"#13ce66",exception:"#ff4949",warning:"#e6a23c",default:"#20a0ff"},a=e,r=V("progress"),T=o(()=>{const t={width:`${a.percentage}%`,animationDuration:`${a.duration}s`},n=x(a.percentage);return n.includes("gradient")?t.background=n:t.backgroundColor=n,t}),v=o(()=>(a.strokeWidth/a.width*100).toFixed(1)),b=o(()=>["circle","dashboard"].includes(a.type)?Number.parseInt(`${50-Number.parseFloat(v.value)/2}`,10):0),m=o(()=>{const t=b.value,n=a.type==="dashboard";return`
import{b as A,R as y,d as M,a as V,o as l,c as d,n as i,f as s,q as p,al as f,h as B,aa as N,g as P,e as D,w as O,r as R,E as j,j as o,cZ as q,a$ as J,bQ as Q,b0 as U,b1 as Z,b8 as G,J as I,l as H}from"./index-Dd84m4NL.js";const K=A({type:{type:String,default:"line",values:["line","circle","dashboard"]},percentage:{type:Number,default:0,validator:e=>e>=0&&e<=100},status:{type:String,default:"",values:["","success","exception","warning"]},indeterminate:Boolean,duration:{type:Number,default:3},strokeWidth:{type:Number,default:6},strokeLinecap:{type:y(String),default:"round"},textInside:Boolean,width:{type:Number,default:126},showText:{type:Boolean,default:!0},color:{type:y([String,Array,Function]),default:""},striped:Boolean,stripedFlow:Boolean,format:{type:y(Function),default:e=>`${e}%`}}),X=["aria-valuenow"],Y={viewBox:"0 0 100 100"},_=["d","stroke","stroke-linecap","stroke-width"],ee=["d","stroke","opacity","stroke-linecap","stroke-width"],te={key:0};var ae=M({name:"ElProgress",__name:"progress",props:K,setup(e){const k={success:"#13ce66",exception:"#ff4949",warning:"#e6a23c",default:"#20a0ff"},a=e,r=V("progress"),T=o(()=>{const t={width:`${a.percentage}%`,animationDuration:`${a.duration}s`},n=x(a.percentage);return n.includes("gradient")?t.background=n:t.backgroundColor=n,t}),v=o(()=>(a.strokeWidth/a.width*100).toFixed(1)),b=o(()=>["circle","dashboard"].includes(a.type)?Number.parseInt(`${50-Number.parseFloat(v.value)/2}`,10):0),m=o(()=>{const t=b.value,n=a.type==="dashboard";return`
M 50 50
m 0 ${n?"":"-"}${t}
a ${t} ${t} 0 1 1 0 ${n?"-":""}${t*2}

Some files were not shown because too many files have changed in this diff Show More