Commit 478c4876 authored by luwei's avatar luwei

修改

parent 36e2cc19
......@@ -14,6 +14,13 @@ from app.services.data_management_service import DataManagementService
class EvalService:
def __init__(self) -> None:
self._dm = DataManagementService()
self._base_dir = Path(__file__).resolve().parents[2]
def _resolve_model_path(self, file_path: str) -> Path:
p = Path(file_path)
if p.is_absolute():
return p
return self._base_dir / p
# ── dropdown data ─────────────────────────────────────────────────────────
......@@ -39,7 +46,7 @@ class EvalService:
if not pkg:
raise ValueError('数据包不存在')
model_path = Path(model.file_path)
model_path = self._resolve_model_path(model.file_path)
model_name = model.model_name
package_name = pkg.name
......
......@@ -23,7 +23,8 @@ _registry_lock = threading.Lock()
class TrainService:
def __init__(self) -> None:
self._dm = DataManagementService()
self._models_dir = Path(__file__).resolve().parents[2] / 'saved_models'
self._base_dir = Path(__file__).resolve().parents[2]
self._models_dir = self._base_dir / 'saved_models'
self._models_dir.mkdir(parents=True, exist_ok=True)
# ── packages (for dropdown) ──────────────────────────────────────────────
......@@ -147,7 +148,7 @@ class TrainService:
package_id=task.package_id,
package_name=task.package_name,
params=task.params,
file_path=str(model_path),
file_path=model_path.relative_to(self._base_dir).as_posix(),
train_loss=task.train_loss,
val_loss=task.val_loss,
test_loss=task.test_loss,
......@@ -177,7 +178,7 @@ class TrainService:
task.is_saved = 0
# Delete the .pt file only if nothing else references it
model_path = Path(model.file_path)
model_path = self._resolve_model_path(model.file_path)
if model_path.exists():
model_path.unlink(missing_ok=True)
......@@ -186,6 +187,12 @@ class TrainService:
# ── private helpers ───────────────────────────────────────────────────────
def _resolve_model_path(self, file_path: str) -> Path:
"""Return absolute Path whether file_path is relative or absolute."""
p = Path(file_path)
if p.is_absolute():
return p
return self._base_dir / p
def _launch_thread(self, task_id: int, package_id: int, params: dict) -> None:
cancel_event = threading.Event()
with _registry_lock:
......
import{A as e,D as t,Ht as n,I as r,N as i,X as a,d as o,m as s,st as c,t as l,u}from"./_plugin-vue_export-helper-D1RKUtCV.js";import{t as d}from"./echarts-B4btcaVd.js";var f={class:`curve-box`},p={class:`stats-row`},m={class:`stat-card`},h={class:`stat-value`},g={class:`stat-card`},_={class:`stat-value`},v={class:`stat-card`},y={class:`stat-value`},b=l({__name:`DataCurve`,props:{records:{type:Array,default:()=>[]}},setup(l){let b=l,x=c(null),S=null,C=u(()=>(Array.isArray(b.records)?b.records:[]).map((e,t)=>({idx:t,time:e.time||`第${t+1}条`,current:Number(e.current),voltage:Number(e.voltage),actual_temperature:Number(e.actual_temperature)})).filter(e=>Number.isFinite(e.current)||Number.isFinite(e.voltage)||Number.isFinite(e.actual_temperature))),w=u(()=>{let e=C.value.map(e=>e.actual_temperature).filter(e=>Number.isFinite(e));return{count:C.value.length,max:e.length?Math.max(...e):0,min:e.length?Math.min(...e):0}}),T=e=>Number.isFinite(e)?Number(e).toFixed(2):`--`,E=e=>C.value.map(t=>Number.isFinite(t[e])?t[e]:null),D=()=>{if(!x.value)return;S||=d(x.value);let e=C.value.length>0;S.setOption({animation:!0,color:[`#409EFF`,`#67C23A`,`#FF6B6B`],tooltip:{trigger:`axis`,backgroundColor:`rgba(255,255,255,0.96)`,borderColor:`#e2e8f0`,borderWidth:1,textStyle:{color:`#334155`},extraCssText:`box-shadow: 0 10px 30px rgba(15,23,42,0.16); border-radius: 12px;`,formatter(e){if(!e?.length)return``;let t=[`<div style="margin-bottom:6px;font-weight:600;">${e[0].axisValue}</div>`];return e.forEach(e=>{t.push(`<div style="display:flex;align-items:center;gap:6px;min-width:160px;justify-content:space-between;">
<span>${e.marker}${e.seriesName}</span>
<strong>${T(e.data)}</strong>
</div>`)}),t.join(``)}},legend:{bottom:0,itemWidth:18,itemHeight:10,textStyle:{color:`#475569`},data:[`电流(A)`,`电压(V)`,`温度(℃)`]},grid:{top:24,left:24,right:24,bottom:56,containLabel:!0},xAxis:{type:`category`,boundaryGap:!1,data:C.value.map(e=>e.time),axisLabel:{color:`#64748b`,rotate:35},axisLine:{lineStyle:{color:`#94a3b8`}}},yAxis:{type:`value`,axisLabel:{color:`#64748b`},splitLine:{lineStyle:{type:`dashed`,color:`rgba(148, 163, 184, 0.45)`}}},series:[{name:`电流(A)`,type:`line`,smooth:!0,symbol:`circle`,symbolSize:7,data:E(`current`)},{name:`电压(V)`,type:`line`,smooth:!0,symbol:`circle`,symbolSize:7,data:E(`voltage`)},{name:`温度(℃)`,type:`line`,smooth:!0,symbol:`circle`,symbolSize:7,data:E(`actual_temperature`)}],graphic:e?[]:[{type:`text`,left:`center`,top:`middle`,style:{text:`暂无足够数据生成曲线`,fill:`#64748b`,fontSize:14}}]},!0)},O=()=>{S?.resize()};return i(async()=>{await t(),D(),window.addEventListener(`resize`,O)}),a(()=>b.records,async()=>{await t(),D()},{deep:!0}),e(()=>{window.removeEventListener(`resize`,O),S?.dispose(),S=null}),(e,t)=>(r(),s(`div`,f,[o(`div`,p,[o(`div`,m,[t[0]||=o(`div`,{class:`stat-label`},`总条数`,-1),o(`div`,h,n(w.value.count),1)]),o(`div`,g,[t[1]||=o(`div`,{class:`stat-label`},`最高温度`,-1),o(`div`,_,n(T(w.value.max))+` °C`,1)]),o(`div`,v,[t[2]||=o(`div`,{class:`stat-label`},`最低温度`,-1),o(`div`,y,n(T(w.value.min))+` °C`,1)])]),o(`div`,{ref_key:`chartRef`,ref:x,class:`echarts-box`},null,512)]))}},[[`__scopeId`,`data-v-7c9af9ab`]]);export{b as t};
\ No newline at end of file
.curve-box[data-v-7c9af9ab]{flex-direction:column;gap:14px;height:100%;display:flex}.stats-row[data-v-7c9af9ab]{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;display:grid}.stat-card[data-v-7c9af9ab]{background:#f3f6fb;border-radius:14px;padding:14px 16px}.stat-label[data-v-7c9af9ab]{color:#64748b;margin-bottom:8px;font-size:13px}.stat-value[data-v-7c9af9ab]{color:#0f172a;font-size:18px;font-weight:700}.echarts-box[data-v-7c9af9ab]{background:linear-gradient(#fff,#f8fafc);border:1px solid #0f172a1a;border-radius:14px;flex:1;min-height:360px}
This diff is collapsed.
.train-page[data-v-fea158ef]{background:var(--bg-page);flex-direction:column;gap:12px;height:100%;display:flex;overflow-y:auto}.config-card[data-v-fea158ef],.tasks-card[data-v-fea158ef]{border:1px solid var(--border-color);border-radius:4px;flex-shrink:0;box-shadow:var(--shadow-card)!important}.config-card[data-v-fea158ef] .el-card__header,.tasks-card[data-v-fea158ef] .el-card__header{border-bottom:1px solid var(--border-color);background:#f7f8fa;align-items:center;height:44px;padding:0 20px;display:flex}.config-card[data-v-fea158ef] .el-card__body,.tasks-card[data-v-fea158ef] .el-card__body{padding:16px 20px}.tasks-card[data-v-fea158ef]{flex:1;min-height:0;overflow:hidden}.card-title[data-v-fea158ef]{color:var(--text-primary);font-size:14px;font-weight:600}.card-header-row[data-v-fea158ef]{justify-content:space-between;align-items:center;width:100%;display:flex}.train-form .form-row[data-v-fea158ef]{flex-wrap:wrap;gap:24px;margin-bottom:4px;display:flex}.train-form .form-item-wide[data-v-fea158ef]{flex:1;min-width:220px}.train-form .form-item-wide[data-v-fea158ef] .el-form-item__content{display:block}.params-section[data-v-fea158ef]{border-top:1px solid var(--border-color);margin-bottom:8px;padding-top:12px}.params-label[data-v-fea158ef]{color:var(--text-secondary);margin-bottom:12px;font-size:13px;font-weight:600;display:block}.params-grid[data-v-fea158ef]{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px 24px;display:grid}.params-grid[data-v-fea158ef] .el-form-item{margin-bottom:0}.form-action[data-v-fea158ef]{border-top:1px solid var(--border-color);text-align:right;padding-top:16px}.params-cell[data-v-fea158ef]{color:var(--text-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:12px;display:block;overflow:hidden}.muted[data-v-fea158ef]{color:var(--text-tertiary)}.err-text[data-v-fea158ef]{color:#f53f3f;white-space:nowrap;text-overflow:ellipsis;font-size:12px;display:block;overflow:hidden}
import{n as e,r as t,u as n}from"./es-DCOtnflc.js";import{$ as ee,A as r,B as i,Ht as a,I as o,N as s,Q as c,R as l,V as u,_ as d,a as f,at as p,d as m,f as h,ht as g,m as _,st as v,t as y,u as b,v as x}from"./_plugin-vue_export-helper-D1RKUtCV.js";import{c as S,i as C,l as w,n as T,o as E,s as D,t as O}from"./trainManagement-TFX-G3Jl.js";var k={class:`train-page`},A={class:`form-row`},j={class:`params-section`},M={class:`params-grid`},N={class:`form-action`},P={class:`card-header-row`},F={class:`params-cell`},I={key:2,class:`muted`},L={key:0,class:`err-text`},R={key:1},z=`calc(100vh - 520px)`,B=y(Object.assign({},{__name:`index`,setup(y){let B=p({model_name:``,package_id:``,params:{seq_len:20,hidden_size:64,num_layers:2,epochs:50,batch_size:32,learning_rate:.001,train_ratio:.8}}),V=v([]),H=v(!1),U=v([]),W=v(!1),G=null,K=b(()=>U.value.some(e=>e.status===`pending`||e.status===`running`)),q=()=>{G||=setInterval(Y,3e3)},J=()=>{G&&=(clearInterval(G),null)},Y=async()=>{try{U.value=await D(),K.value?q():J()}catch{}},te=async()=>{if(!B.model_name.trim()){t.warning(`请输入模型名称`);return}if(!B.package_id){t.warning(`请选择数据包`);return}H.value=!0;try{await T({model_name:B.model_name.trim(),package_id:B.package_id,params:{...B.params}}),t.success(`训练任务已提交`),B.model_name=``,await Y()}finally{H.value=!1}},ne=async e=>{try{await O(e.id),t.success(`已发送取消请求`),await Y()}catch(e){t.error(e?.message||`取消失败`)}},X=async e=>{try{await S(e.id),t.success(`重新训练已启动`),await Y()}catch(e){t.error(e?.message||`重启失败`)}},re=async e=>{try{await w(e.id),t.success(`模型已保存,可在模型列表中查看`),await Y()}catch(e){t.error(e?.message||`保存失败`)}},Z=async n=>{try{await e.confirm(`确定删除训练任务"${n.model_name}"吗?`,`提示`,{type:`warning`}),await C(n.id),t.success(`已删除`),await Y()}catch{}},ie={pending:{type:`info`,text:`等待中`},running:{type:`warning`,text:`训练中`},completed:{type:`success`,text:`已完成`},failed:{type:`danger`,text:`失败`},cancelled:{type:``,text:`已取消`}},Q=e=>ie[e]||{type:`info`,text:e},$=e=>e?[`序列长度 ${e.seq_len}`,`隐藏层 ${e.hidden_size}`,`层数 ${e.num_layers}`,`轮数 ${e.epochs}`,`批次 ${e.batch_size}`,`学习率 ${e.learning_rate}`,`训练比 ${e.train_ratio}`].join(` / `):`-`,ae=e=>e.train_loss==null?`-`:`训练: ${Number(e.train_loss).toFixed(5)}`+(e.val_loss==null?``:` / 验证: ${Number(e.val_loss).toFixed(5)}`);return s(async()=>{W.value=!0;try{await Promise.all([E().then(e=>V.value=e),Y()])}finally{W.value=!1}}),r(J),(e,t)=>{let r=i(`el-option`),s=i(`el-select`),p=i(`el-form-item`),v=i(`el-input`),y=i(`el-input-number`),b=i(`el-button`),S=i(`el-form`),C=i(`el-card`),w=i(`el-table-column`),T=i(`el-tooltip`),E=i(`el-tag`),D=i(`el-progress`),O=i(`el-table`),G=u(`loading`);return o(),_(`div`,k,[x(C,{class:`config-card`,shadow:`hover`},{header:c(()=>[...t[9]||=[m(`span`,{class:`card-title`},`训练配置`,-1)]]),default:c(()=>[x(S,{model:B,"label-position":`top`,class:`train-form`},{default:c(()=>[m(`div`,A,[x(p,{label:`选择数据包`,required:``,class:`form-item-wide`},{default:c(()=>[x(s,{modelValue:B.package_id,"onUpdate:modelValue":t[0]||=e=>B.package_id=e,placeholder:`请选择数据包`,filterable:``,style:{width:`100%`}},{default:c(()=>[(o(!0),_(f,null,l(V.value,e=>(o(),h(r,{key:e.id,label:`${e.name}${e.data_count} 条)`,value:e.id},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`])]),_:1}),x(p,{label:`模型名称`,required:``,class:`form-item-wide`},{default:c(()=>[x(v,{modelValue:B.model_name,"onUpdate:modelValue":t[1]||=e=>B.model_name=e,placeholder:`请输入模型名称`,maxlength:`100`,"show-word-limit":``},null,8,[`modelValue`])]),_:1})]),m(`div`,j,[t[10]||=m(`span`,{class:`params-label`},`LSTM 超参数`,-1),m(`div`,M,[x(p,{label:`序列长度`},{default:c(()=>[x(y,{modelValue:B.params.seq_len,"onUpdate:modelValue":t[2]||=e=>B.params.seq_len=e,min:5,max:500,step:5,"controls-position":`right`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1}),x(p,{label:`隐藏层大小`},{default:c(()=>[x(y,{modelValue:B.params.hidden_size,"onUpdate:modelValue":t[3]||=e=>B.params.hidden_size=e,min:8,max:1024,step:8,"controls-position":`right`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1}),x(p,{label:`LSTM 层数`},{default:c(()=>[x(y,{modelValue:B.params.num_layers,"onUpdate:modelValue":t[4]||=e=>B.params.num_layers=e,min:1,max:8,"controls-position":`right`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1}),x(p,{label:`训练轮数 (Epochs)`},{default:c(()=>[x(y,{modelValue:B.params.epochs,"onUpdate:modelValue":t[5]||=e=>B.params.epochs=e,min:1,max:2e3,step:10,"controls-position":`right`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1}),x(p,{label:`批次大小 (Batch)`},{default:c(()=>[x(y,{modelValue:B.params.batch_size,"onUpdate:modelValue":t[6]||=e=>B.params.batch_size=e,min:1,max:512,step:8,"controls-position":`right`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1}),x(p,{label:`学习率`},{default:c(()=>[x(y,{modelValue:B.params.learning_rate,"onUpdate:modelValue":t[7]||=e=>B.params.learning_rate=e,min:1e-5,max:1,step:1e-4,precision:5,"controls-position":`right`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1}),x(p,{label:`训练集比例`},{default:c(()=>[x(y,{modelValue:B.params.train_ratio,"onUpdate:modelValue":t[8]||=e=>B.params.train_ratio=e,min:.5,max:.99,step:.05,precision:2,"controls-position":`right`,style:{width:`100%`}},null,8,[`modelValue`])]),_:1})])]),m(`div`,N,[x(b,{type:`primary`,size:`large`,loading:H.value,onClick:te},{default:c(()=>[...t[11]||=[d(` 开始训练 `,-1)]]),_:1},8,[`loading`])])]),_:1},8,[`model`])]),_:1}),x(C,{class:`tasks-card`,shadow:`hover`},{header:c(()=>[m(`div`,P,[t[13]||=m(`span`,{class:`card-title`},`训练记录`,-1),x(b,{icon:g(n),size:`small`,plain:``,loading:W.value,onClick:Y},{default:c(()=>[...t[12]||=[d(` 刷新 `,-1)]]),_:1},8,[`icon`,`loading`])])]),default:c(()=>[ee((o(),h(O,{data:U.value,border:``,stripe:``,height:z},{default:c(()=>[x(w,{prop:`model_name`,label:`模型名称`,"min-width":`140`,"show-overflow-tooltip":``}),x(w,{prop:`package_name`,label:`数据包`,"min-width":`130`,"show-overflow-tooltip":``}),x(w,{label:`参数`,"min-width":`180`,"show-overflow-tooltip":``},{default:c(({row:e})=>[x(T,{content:$(e.params),placement:`top`},{default:c(()=>[m(`span`,F,a($(e.params)),1)]),_:2},1032,[`content`])]),_:1}),x(w,{label:`状态`,width:`100`,align:`center`},{default:c(({row:e})=>[x(E,{type:Q(e.status).type,size:`small`},{default:c(()=>[d(a(Q(e.status).text),1)]),_:2},1032,[`type`])]),_:1}),x(w,{label:`进度`,width:`150`,align:`center`},{default:c(({row:e})=>[e.status===`running`?(o(),h(D,{key:0,percentage:e.progress,"stroke-width":6,"show-text":!0,style:{width:`120px`}},null,8,[`percentage`])):e.status===`completed`?(o(),h(D,{key:1,percentage:100,status:`success`,"stroke-width":6,style:{width:`120px`}})):(o(),_(`span`,I,`—`))]),_:1}),x(w,{label:`损失`,"min-width":`200`,"show-overflow-tooltip":``},{default:c(({row:e})=>[e.status===`failed`?(o(),_(`span`,L,a(e.error_msg||`未知错误`),1)):(o(),_(`span`,R,a(ae(e)),1))]),_:1}),x(w,{prop:`created_at`,label:`创建时间`,width:`160`}),x(w,{label:`操作`,width:`210`,fixed:`right`},{default:c(({row:e})=>[e.status===`running`||e.status===`pending`?(o(),h(b,{key:0,link:``,type:`warning`,onClick:t=>ne(e)},{default:c(()=>[...t[14]||=[d(`取消`,-1)]]),_:1},8,[`onClick`])):e.status===`completed`?(o(),_(f,{key:1},[e.is_saved?(o(),h(E,{key:1,type:`success`,size:`small`,style:{"margin-right":`6px`}},{default:c(()=>[...t[16]||=[d(`已保存`,-1)]]),_:1})):(o(),h(b,{key:0,link:``,type:`primary`,onClick:t=>re(e)},{default:c(()=>[...t[15]||=[d(` 保存模型 `,-1)]]),_:1},8,[`onClick`])),x(b,{link:``,type:`info`,onClick:t=>X(e)},{default:c(()=>[...t[17]||=[d(`重新训练`,-1)]]),_:1},8,[`onClick`]),x(b,{link:``,type:`danger`,onClick:t=>Z(e)},{default:c(()=>[...t[18]||=[d(`删除`,-1)]]),_:1},8,[`onClick`])],64)):(o(),_(f,{key:2},[x(b,{link:``,type:`info`,onClick:t=>X(e)},{default:c(()=>[...t[19]||=[d(`重新训练`,-1)]]),_:1},8,[`onClick`]),x(b,{link:``,type:`danger`,onClick:t=>Z(e)},{default:c(()=>[...t[20]||=[d(`删除`,-1)]]),_:1},8,[`onClick`])],64))]),_:1})]),_:1},8,[`data`])),[[G,W.value]])]),_:1})])}}}),[[`__scopeId`,`data-v-fea158ef`]]);export{B as default};
\ No newline at end of file
.pane-card[data-v-bbcd2093]{border:none;border-right:1px solid var(--border-color);background:var(--bg-white);border-radius:0;flex-direction:column;height:100%;display:flex;overflow:hidden;box-shadow:none!important}.pane-card[data-v-bbcd2093] .el-card__header{border-bottom:1px solid var(--border-color);background:#f7f8fa;align-items:center;height:44px;padding:0 16px;display:flex}.pane-card[data-v-bbcd2093] .el-card__body{flex:1;padding:8px 0;overflow-y:auto}.pane-header[data-v-bbcd2093]{width:100%;color:var(--text-primary);justify-content:space-between;align-items:center;font-size:14px;font-weight:600;display:flex}.tree-node[data-v-bbcd2093]{justify-content:space-between;align-items:center;width:100%;min-width:0;padding-right:4px;display:flex}.tree-main[data-v-bbcd2093]{align-items:center;gap:6px;min-width:0;display:flex}.tree-icon[data-v-bbcd2093]{color:var(--primary);flex-shrink:0;font-size:14px}.tree-name[data-v-bbcd2093]{text-overflow:ellipsis;white-space:nowrap;color:var(--text-primary);font-size:13px;overflow:hidden}.tree-actions[data-v-bbcd2093]{flex-shrink:0;gap:0;display:none}.tree-actions .el-button[data-v-bbcd2093]{color:var(--text-tertiary);padding:0 3px;font-size:13px}.tree-actions .el-button[data-v-bbcd2093]:hover{color:var(--primary)}.tree-node:hover .tree-actions[data-v-bbcd2093]{display:inline-flex}.pane-card[data-v-8f5781ed]{border:none;border-right:1px solid var(--border-color);background:var(--bg-white);border-radius:0;flex-direction:column;height:100%;display:flex;overflow:hidden;box-shadow:none!important}.pane-card[data-v-8f5781ed] .el-card__header{border-bottom:1px solid var(--border-color);background:#f7f8fa;align-items:center;height:44px;padding:0 16px;display:flex}.pane-card[data-v-8f5781ed] .el-card__body{flex:1;padding:12px 16px;overflow:hidden}.pane-header[data-v-8f5781ed]{width:100%;color:var(--text-primary);justify-content:space-between;align-items:center;font-size:14px;font-weight:600;display:flex}.search-bar[data-v-8f5781ed]{gap:8px;margin-bottom:12px;display:flex}.search-bar .el-input[data-v-8f5781ed]{flex:1}[data-v-8f5781ed] .el-table .current-row>td{background:var(--primary-light)!important}[data-v-8f5781ed] .el-table .el-button.is-link{height:auto;padding:0 4px;font-size:13px;line-height:1}.pane-card[data-v-6b2fedfc]{background:var(--bg-white);border:none;border-radius:0;flex-direction:column;height:100%;display:flex;overflow:hidden;box-shadow:none!important}.pane-card[data-v-6b2fedfc] .el-card__header{border-bottom:1px solid var(--border-color);background:#f7f8fa;align-items:center;height:44px;padding:0 16px;display:flex}.pane-card[data-v-6b2fedfc] .el-card__body{flex:1;padding:0;overflow:hidden}.pane-header[data-v-6b2fedfc]{width:100%;color:var(--text-primary);justify-content:space-between;align-items:center;font-size:14px;font-weight:600;display:flex}.pkg-title[data-v-6b2fedfc]{color:var(--text-secondary);margin-left:4px;font-size:13px;font-weight:400}.content-wrap[data-v-6b2fedfc]{height:100%;padding:0 16px 12px}[data-v-6b2fedfc] .el-radio-group .el-radio-button__inner{color:var(--text-secondary);border-color:var(--border-color);background:0 0;padding:4px 12px;font-size:13px}[data-v-6b2fedfc] .el-radio-group .el-radio-button__original-radio:checked+.el-radio-button__inner{color:#fff;background:var(--primary)!important;border-color:var(--primary)!important;box-shadow:none!important}.add-pkg-page[data-v-03a732e5]{flex-direction:column;gap:0;height:100%;display:flex;overflow:hidden}.add-pkg-header[data-v-03a732e5]{background:#ffffffe6;border-bottom:1px solid #e8edf3;flex-shrink:0;align-items:center;gap:16px;padding:12px 20px;display:flex}.add-pkg-title[data-v-03a732e5]{color:#0f172a;font-size:16px;font-weight:600}.section-card[data-v-03a732e5]{background:#fff;border:1px solid #e8edf3;border-radius:8px;padding:16px;overflow:hidden}.section-title[data-v-03a732e5]{color:#0f172a;align-items:center;gap:8px;margin-bottom:12px;font-size:14px;font-weight:600;display:flex}.section-hint[data-v-03a732e5]{color:#64748b;font-size:12px;font-weight:400}.file-search-bar[data-v-03a732e5]{margin-bottom:10px}.file-section[data-v-03a732e5]{flex-shrink:0;margin:12px 12px 0}.section-bottom[data-v-03a732e5]{flex:1;gap:12px;min-height:0;padding:12px;display:flex;overflow:hidden}.form-section[data-v-03a732e5]{flex-shrink:0;width:320px;overflow-y:auto}.preview-section[data-v-03a732e5]{flex-direction:column;flex:1;min-width:0;display:flex;overflow:hidden}.preview-section .section-title[data-v-03a732e5]{flex-shrink:0}.preview-content[data-v-03a732e5]{flex:1;min-height:0;overflow:hidden}.pkg-form[data-v-03a732e5] .el-form-item{margin-bottom:16px}.pkg-page[data-v-bc327363]{background:var(--bg-page);height:100%}.pkg-page.dragging[data-v-bc327363]{-webkit-user-select:none;user-select:none;cursor:col-resize}.pkg-layout[data-v-bc327363]{background:var(--bg-white);border:1px solid var(--border-color);height:100%;box-shadow:var(--shadow-card);align-items:stretch;gap:0;display:flex}.pane-divider[data-v-bc327363]{background:var(--border-color);cursor:col-resize;flex-shrink:0;width:4px;transition:background .15s;position:relative}.pane-divider[data-v-bc327363]:after{content:"";position:absolute;inset:0 -2px}.pane-divider[data-v-bc327363]:hover,.dragging .pane-divider[data-v-bc327363]{background:var(--primary-border)}
This diff is collapsed.
......@@ -5,10 +5,10 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>热实验温度控制系统</title>
<script type="module" crossorigin src="/assets/index-D5S_ELZm.js"></script>
<script type="module" crossorigin src="/assets/index-CvdqK_rU.js"></script>
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-D1RKUtCV.js">
<link rel="modulepreload" crossorigin href="/assets/es-DCOtnflc.js">
<link rel="stylesheet" crossorigin href="/assets/index-BrwBxauG.css">
<link rel="stylesheet" crossorigin href="/assets/index-pfQxyObg.css">
</head>
<body>
<div id="app"></div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment