1
0
mirror of https://github.com/ZeroCatDev/Classworks.git synced 2025-07-02 00:59:23 +00:00
Classworks/assets/DataMigration-C7wFOqC9.js

2 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{g as q,p as Y,j as E,k as r,a0 as P,aL as te,f as se,a8 as ae,aM as re,G as g,H as G,a3 as F,ab as ie,_ as W,R as O,a_ as S,a$ as $,Q as b,F as x,D as v,E as o,T as K,J as d,X as I,Y as w,V as _,S as T,Z as f,U as z,W as N,C as D,au as oe,ao as le,b0 as ne,I as ue,ap as ce,aw as de,ax as me,av as Q,a2 as X}from"./index-DpRopL3V.js";import{a as j,V as R}from"./VRow-CnmWQtpQ.js";import{a as H,e as ge,m as fe,V}from"./VTextField-BILbZBCf.js";import{a as B,b as he,c as ye,d as pe}from"./VCheckboxBtn-BMVogzxc.js";import{V as M}from"./VAlert-BS51CJh5.js";import{V as ve}from"./VDataTable-DBs8j_KF.js";import{V as ke}from"./VChip-BTSKEMFl.js";import{V as Se}from"./VSkeletonLoader-Dq0HmBpQ.js";import{V as we}from"./VContainer-SydirbBl.js";import"./VMenu-CTAx5lBf.js";const be=Y({...he({falseIcon:"$radioOff",trueIcon:"$radioOn"})},"VRadio"),U=q()({name:"VRadio",props:be(),setup(t,e){let{slots:l}=e;return E(()=>{const n=B.filterProps(t);return r(B,P(n,{class:["v-radio",t.class],style:t.style,type:"radio"}),l)}),{}}}),De=Y({height:{type:[Number,String],default:"auto"},...fe(),...ie(pe(),["multiple"]),trueIcon:{type:F,default:"$radioOn"},falseIcon:{type:F,default:"$radioOff"},type:{type:String,default:"radio"}},"VRadioGroup"),J=q()({name:"VRadioGroup",inheritAttrs:!1,props:De(),emits:{"update:modelValue":t=>!0},setup(t,e){let{attrs:l,slots:n}=e;const s=te(),i=se(()=>t.id||`radio-group-${s}`),a=ae(t,"modelValue");return E(()=>{const[u,m]=re(l),c=H.filterProps(t),h=B.filterProps(t),y=n.label?n.label({label:t.label,props:{for:i.value}}):t.label;return r(H,P({class:["v-radio-group",t.class],style:t.style},u,c,{modelValue:a.value,"onUpdate:modelValue":p=>a.value=p,id:i.value}),{...n,default:p=>{let{id:k,messagesId:L,isDisabled:A,isReadonly:C}=p;return g(G,null,[y&&r(ge,{id:k.value},{default:()=>[y]}),r(ye,P(h,{id:k.value,"aria-describedby":L.value,defaultsTarget:"VRadio",trueIcon:t.trueIcon,falseIcon:t.falseIcon,type:t.type,disabled:A.value,readonly:C.value,"aria-labelledby":y?k.value:void 0,multiple:!1},m,{modelValue:a.value,"onUpdate:modelValue":ee=>a.value=ee}),n)])}})}),{}}}),Ve={name:"MigrationTool",data(){return{classNumber:"",machineId:"",migrationType:"server",serverUrl:"",targetStorage:"kv-server",targetServerUrl:"https://kv.wuyuan.dev",startDate:this.getDateString(new Date(Date.now()-30*24*60*60*1e3)),endDate:this.getDateString(new Date),loading:!1,scanning:!1,migrating:!1,showServerPreview:!1,showResult:!1,migrationSuccess:!1,migrationError:null,migrationStats:{total:0,success:0,failed:0},migrationResults:[],localDbItems:[],serverItems:[],selectedItems:[],headers:[{title:"类型",key:"type",sortable:!0},{title:"键名",key:"key",sortable:!0},{title:"日期",key:"date",sortable:!0},{title:"大小",key:"size",sortable:!0}]}},computed:{displayItems(){return this.migrationType==="local"?this.localDbItems:this.serverItems},canMigrate(){return this.classNumber&&this.machineId&&this.displayItems.length>0&&(this.targetStorage!=="kv-server"||this.targetServerUrl)}},async mounted(){try{await this.initMachineId(),this.classNumber=b("server.classNumber"),this.serverUrl=b("server.domain"),this.migrationType=b("server.provider")}catch(t){console.error("初始化设备ID失败:",t)}},methods:{getItemType(t){return t?t.raw?t.raw.type:t.type:""},getItemDate(t){return t?t.raw?t.raw.date:t.date:null},getDateString(t){return t.toISOString().split("T")[0]},async initMachineId(){this.machineId=b("device.uuid")},getRequestHeaders(){const t={Accept:"application/json"},e=b("server.siteKey");return e&&(t["x-site-key"]=e),t},async scanLocalDatabase(){if(!this.classNumber){this.$emit("message",{text:"请先输入班级编号",type:"error"});return}this.scanning=!0,this.localDbItems=[];try{const t=await $("ClassworksDB",2);if(t.objectStoreNames.contains("homework")&&t.objectStoreNames.contains("config")){const l=t.transaction("homework","readonly").objectStore("homework"),s=(await l.getAllKeys()).filter(u=>u.startsWith(`homework_${this.classNumber}_`));for(const u of s){const m=await l.get(u),c=u.split("_")[2];let h=null;if(c){const[y,p,k]=c.split("-");h=new Date(y,p-1,k)}this.localDbItems.push({type:"homework",key:u,originalKey:u,date:h,size:this.getDataSize(m)+" KB",value:m})}const i=`config_${this.classNumber}`,a=await t.get("config",i);a&&this.localDbItems.push({type:"config",key:i,originalKey:i,date:null,size:this.getDataSize(a)+" KB",value:a})}if(t.objectStoreNames.contains("kv")){const l=t.transaction("kv","readonly").objectStore("kv"),s=(await l.getAllKeys()).filter(i=>i.startsWith(`${this.classNumber}/`));for(const i of s){const a=await l.get(i),u=i.includes(`/${this.classNumber}/classworks-config`);let m=null;if(!u){const c=i.match(/classworks-data-(\d{4})(\d{2})(\d{2})/);if(c){const[,h,y,p]=c;m=new Date(h,parseInt(y)-1,p)}}this.localDbItems.push({type:u?"config":"homework",key:i,originalKey:i,date:m,size:this.getDataSize(a)+" KB",value:a,isKv:!0})}}}catch(t){console.error("扫描本地数据库失败:",t),this.$emit("message",{text:"扫描数据库失败: "+t.message,type:"error"})}finally{this.scanning=!1}},getDataSize(t){if(!t)return 0;const e=typeof t=="string"?t:JSON.stringify(t);return Math.round(e.length*2/1024*100)/100},formatDate(t){return t?t.toLocaleDateString():"配置 (无日期)"},async previewServerData(){var t;if(!this.serverUrl||!this.classNumber||!this.startDate||!this.endDate){this.$emit("message",{text:"请填写完整的服务器信息和时间范围",type:"error"});return}this.loading=!0,this.serverItems=[];try{try{const s=`${this.serverUrl}/${this.classNumber}/config`,i=await S.get(s,{headers:this.getRequestHeaders()});i.data&&this.serverItems.push({type:"config",key:`config_${this.classNumber}`,originalKey:s,date:null,size:this.getDataSize(i.data)+" KB",value:i.data})}catch(s){console.warn("无法获取配置:",s)}const e=new Date(this.startDate),l=new Date(this.endDate),n=this.getDateArray(e,l);for(const s of n){const i=this.formatDateForServer(s);try{const a=`${this.serverUrl}/${this.classNumber}/homework?date=${i}`,u=await S.get(a,{headers:this.getRequestHeaders()});u.data&&u.data.status!=!1&&(console.log(u.data),this.serverItems.push({type:"homework",key:`homework_${this.classNumber}_${i}`,originalKey:a,date:s,size:this.getDataSize(u.data)+" KB",value:u.data}))}catch(a){((t=a.response)==null?void 0:t.status)!==404&&console.warn(`无法获取 ${i} 的数据:`,a)}}this.showServerPreview=!0}catch(e){console.error("预览服务器数据失败:",e),this.$emit("message",{text:"预览数据失败: "+e.message,type:"error"})}finally{this.loading=!1}},getDateArray(t,e){const l=[],n=new Date(t);for(;n<=e;)l.push(new Date(n)),n.setDate(n.getDate()+1);return l},formatDateForServer(t){const e=t.getFullYear(),l=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${e}-${l}-${n}`},formatDateForKv(t){const e=t.getFullYear(),l=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${e}${l}${n}`},async migrateToLocalKv(t){try{const e=await $("ClassworksDB",2,{upgrade(s){s.objectStoreNames.contains("kv")||s.createObjectStore("kv")}}),l=typeof t.value=="string"?JSON.parse(t.value):t.value;if(this.getItemType(t)==="config"){if(l.studentList&&Array.isArray(l.studentList)){const s=l.studentList.map((a,u)=>({id:u+1,name:a}));await e.put("kv",JSON.stringify(s),"classworks-list-main");const i={...l};delete i.studentList,await e.put("kv",JSON.stringify(i),"classworks-config")}else await e.put("kv",JSON.stringify(l),"classworks-config");return{success:!0,message:"配置已迁移"}}else{const s=this.getItemDate(t);let i;if(s)i=this.formatDateForKv(s);else{const a=t.key.match(/(\d{4})-(\d{2})-(\d{2})/);if(a){const[,u,m,c]=a;i=`${u}${m}${c}`}else return{success:!1,message:"无法确定日期格式"}}return await e.put("kv",JSON.stringify(l),`classworks-data-${i}`),{success:!0,message:`${i} 数据已迁移`}}}catch(e){return console.error("本地KV迁移失败:",e),{success:!1,message:e.message}}},async migrateToServerKv(t){var e,l;try{const n=typeof t.value=="string"?JSON.parse(t.value):t.value;if(this.getItemType(t)==="config"){if(n.studentList&&Array.isArray(n.studentList)){const i=n.studentList.map((c,h)=>({id:h+1,name:c})),a={...n};delete a.studentList;const u={"classworks-list-main":i,"classworks-config":a},m=await S.post(`${this.targetServerUrl}/${this.machineId}/_batchimport`,u,{headers:this.getRequestHeaders()});if(m.data&&m.data.successful>0&&(this.migrationResults.push({key:"classworks-config",success:!0,message:"配置已批量迁移到服务器"}),this.migrationStats.success++,m.data.failed>0&&m.data.errors))for(const c of m.data.errors)this.migrationResults.push({key:c.key,success:!1,message:c.error||"配置迁移失败"}),this.migrationStats.failed++}else await S.post(`${this.targetServerUrl}/${this.machineId}/classworks-config`,n,{headers:this.getRequestHeaders()});return{success:!0,message:"配置已迁移到服务器"}}else{const i=this.getItemDate(t);let a;if(i)a=this.formatDateForKv(i);else{const u=t.key.match(/(\d{4})-(\d{2})-(\d{2})/);if(u){const[,m,c,h]=u;a=`${m}${c}${h}`}else return{success:!1,message:"无法确定日期格式"}}return await S.post(`${this.targetServerUrl}/${this.machineId}/classworks-data-${a}`,n,{headers:this.getRequestHeaders()}),{success:!0,message:`${a} 数据已迁移到服务器`}}}catch(n){return console.error("服务器KV迁移失败:",n),{success:!1,message:((l=(e=n.response)==null?void 0:e.data)==null?void 0:l.message)||n.message}}},async batchMigrateToServerKv(t){var e,l;try{const n=t.filter(a=>this.getItemType(a)==="config"),s=t.filter(a=>this.getItemType(a)==="homework");if(n.length>0){const a=n[0],u=typeof a.value=="string"?JSON.parse(a.value):a.value;if(u.studentList&&Array.isArray(u.studentList)){const m=u.studentList.map((p,k)=>({id:k+1,name:p})),c={...u};delete c.studentList;const h={"classworks-list-main":m,"classworks-config":c},y=await S.post(`${this.targetServerUrl}/${this.machineId}/_batchimport`,h,{headers:this.getRequestHeaders()});if(y.data&&y.data.successful>0&&(this.migrationResults.push({key:"classworks-config",success:!0,message:"配置已批量迁移到服务器"}),this.migrationStats.success++,y.data.failed>0&&y.data.errors))for(const p of y.data.errors)this.migrationResults.push({key:p.key,success:!1,message:p.error||"配置迁移失败"}),this.migrationStats.failed++}else await S.post(`${this.targetServerUrl}/${this.machineId}/classworks-config`,u,{headers:this.getRequestHeaders()});this.migrationResults.push({key:a.key,success:!0,message:"配置已迁移到服务器"}),this.migrationStats.success++}const i=100;for(let a=0;a<s.length;a+=i){const u=s.slice(a,a+i),m={};for(const c of u){const h=typeof c.value=="string"?JSON.parse(c.value):c.value,y=this.getItemDate(c);let p;if(y)p=this.formatDateForKv(y);else{const k=c.key.match(/(\d{4})-(\d{2})-(\d{2})/);if(k){const[,L,A,C]=k;p=`${L}${A}${C}`}else{this.migrationResults.push({key:c.key,success:!1,message:"无法确定日期格式"}),this.migrationStats.failed++;continue}}m[`classworks-data-${p}`]=h}if(Object.keys(m).length>0){const c=await S.post(`${this.targetServerUrl}/${this.machineId}/_batchimport`,m,{headers:this.getRequestHeaders()});if(c.data&&(c.data.successful>0&&(this.migrationResults.push({key:`批量数据 (${Object.keys(m).length}项)`,success:!0,message:`成功迁移 ${c.data.successful} 项数据到服务器`}),this.migrationStats.success+=c.data.successful),c.data.failed>0&&c.data.errors))for(const h of c.data.errors)this.migrationResults.push({key:h.key,success:!1,message:h.error||"迁移失败"}),this.migrationStats.failed+=c.data.failed}}return{success:!0}}catch(n){return console.error("批量迁移到服务器失败:",n),{success:!1,message:((l=(e=n.response)==null?void 0:e.data)==null?void 0:l.message)||n.message}}},async startMigration(){if(!this.canMigrate){this.$emit("message",{text:"无法开始迁移,请检查配置",type:"error"});return}this.migrating=!0,this.migrationResults=[],this.migrationStats={total:this.displayItems.length,success:0,failed:0};try{if(this.targetStorage==="kv-local"){const t=this.displayItems.filter(l=>this.getItemType(l)==="config"),e=this.displayItems.filter(l=>this.getItemType(l)==="homework");for(const l of t)await this.migrateItem(l);for(const l of e)await this.migrateItem(l)}else await this.batchMigrateToServerKv(this.displayItems);this.migrationSuccess=this.migrationStats.failed===0,this.showResult=!0,O("server.provider",this.targetStorage),this.targetStorage==="kv-server"&&O("server.domain",this.targetServerUrl)}catch(t){console.error("迁移过程出错:",t),this.migrationSuccess=!1,this.migrationError=t.message,this.showResult=!0}finally{this.migrating=!1}},async migrateItem(t){try{let e;this.targetStorage==="kv-local"?e=await this.migrateToLocalKv(t):e=await this.migrateToServerKv(t),this.migrationResults.push({key:t.key,success:e.success,message:e.message}),e.success?this.migrationStats.success++:this.migrationStats.failed++}catch(e){console.error(`迁移 ${t.key} 失败:`,e),this.migrationResults.push({key:t.key,success:!1,message:e.message}),this.migrationStats.failed++}}}},Ie={key:0,class:"mt-4"},_e={class:"d-flex align-center mt-4"},Te={key:0,class:"mt-4"},xe={class:"d-flex justify-end mb-6"},Ke={key:1};function Re(t,e,l,n,s,i){return v(),x("div",null,[r(T,{class:"mb-6"},{default:o(()=>[r(K,null,{default:o(()=>e[11]||(e[11]=[d("迁移设置")])),_:1,__:[11]}),r(I,null,{default:o(()=>[r(j,null,{default:o(()=>[r(R,{cols:"12",md:"6"},{default:o(()=>[r(V,{modelValue:s.classNumber,"onUpdate:modelValue":e[0]||(e[0]=a=>s.classNumber=a),label:"班级编号",hint:"请输入需要迁移的班级编号","persistent-hint":"","prepend-icon":"mdi-account-group"},null,8,["modelValue"])]),_:1}),r(R,{cols:"12",md:"6"},{default:o(()=>[r(V,{modelValue:s.machineId,"onUpdate:modelValue":e[1]||(e[1]=a=>s.machineId=a),label:"设备标识 (UUID)",hint:"系统已自动填充设备标识,通常无需修改","persistent-hint":"","prepend-icon":"mdi-identifier",readonly:""},null,8,["modelValue"])]),_:1})]),_:1}),r(J,{modelValue:s.migrationType,"onUpdate:modelValue":e[2]||(e[2]=a=>s.migrationType=a),class:"mt-2"},{default:o(()=>[r(U,{value:"local",label:"本地数据迁移"}),r(U,{value:"server",label:"服务器数据迁移"})]),_:1},8,["modelValue"]),s.migrationType==="server"?(v(),x("div",Ie,[r(V,{modelValue:s.serverUrl,"onUpdate:modelValue":e[3]||(e[3]=a=>s.serverUrl=a),label:"服务器地址",hint:"输入服务器域名例如https://example.com","persistent-hint":"","prepend-icon":"mdi-server"},null,8,["modelValue"]),r(M,{density:"compact",type:"info",variant:"outlined",class:"mt-2"},{default:o(()=>e[12]||(e[12]=[d(" 服务器接口格式:"),g("br",null,null,-1),d(" - 配置接口:域名/班号/config"),g("br",null,null,-1),d(" - 作业数据接口:域名/班号/homework?date=YYYY-MM-DD ")])),_:1,__:[12]}),g("div",_e,[r(_,{color:"warning",class:"mr-2"},{default:o(()=>e[13]||(e[13]=[d("mdi-calendar-range")])),_:1,__:[13]}),e[14]||(e[14]=g("span",{class:"text-subtitle-1"},"选择迁移时间范围:",-1))]),r(j,{class:"mt-1"},{default:o(()=>[r(R,{cols:"12",md:"6"},{default:o(()=>[r(V,{modelValue:s.startDate,"onUpdate:modelValue":e[4]||(e[4]=a=>s.startDate=a),label:"开始日期",type:"date","prepend-icon":"mdi-calendar-start"},null,8,["modelValue"])]),_:1}),r(R,{cols:"12",md:"6"},{default:o(()=>[r(V,{modelValue:s.endDate,"onUpdate:modelValue":e[5]||(e[5]=a=>s.endDate=a),label:"结束日期",type:"date","prepend-icon":"mdi-calendar-end"},null,8,["modelValue"])]),_:1})]),_:1})])):w("",!0)]),_:1})]),_:1}),r(T,{class:"mb-6"},{default:o(()=>[r(K,{class:"d-flex align-center"},{default:o(()=>[g("span",null,f(s.migrationType==="local"?"本地数据库内容":"服务器数据内容"),1),r(z),r(N,{color:"primary",onClick:e[6]||(e[6]=a=>s.migrationType==="local"?i.scanLocalDatabase():i.previewServerData()),loading:s.loading||s.scanning},{default:o(()=>[d(f(s.migrationType==="local"?"扫描数据":"加载数据"),1)]),_:1},8,["loading"])]),_:1}),r(I,null,{default:o(()=>[i.displayItems.length===0&&!s.loading&&!s.scanning?(v(),D(M,{key:0,type:"info"},{default:o(()=>[d(f(s.migrationType==="local"?'尚未扫描本地数据或未找到可迁移的数据。点击"扫描数据"按钮开始扫描。':'尚未预览服务器数据或未找到可迁移的数据。点击"加载数据"按钮开始查询。'),1)]),_:1})):w("",!0),i.displayItems.length>0?(v(),D(ve,{key:1,headers:s.headers,items:i.displayItems,"items-per-page":10,"item-value":"key",class:"elevation-1"},{"item.type":o(({item:a})=>[r(ke,{color:i.getItemType(a)==="config"?"primary":"secondary",size:"small"},{default:o(()=>[d(f(i.getItemType(a)==="config"?"配置":"作业数据"),1)]),_:2},1032,["color"])]),"item.date":o(({item:a})=>[d(f(i.formatDate(i.getItemDate(a))),1)]),_:2},1032,["headers","items"])):w("",!0),i.displayItems.length>0?(v(),D(M,{key:2,type:"info",density:"compact",class:"mt-2"},{default:o(()=>e[15]||(e[15]=[d(" 系统将迁移表格中显示的所有数据项,迁移前请确认数据完整性。 ")])),_:1,__:[15]})):w("",!0),s.loading||s.scanning?(v(),D(Se,{key:3,type:"table"})):w("",!0)]),_:1})]),_:1}),r(T,{class:"mb-6"},{default:o(()=>[r(K,null,{default:o(()=>e[16]||(e[16]=[d("迁移目标")])),_:1,__:[16]}),r(I,null,{default:o(()=>[r(J,{modelValue:s.targetStorage,"onUpdate:modelValue":e[7]||(e[7]=a=>s.targetStorage=a)},{default:o(()=>[r(U,{value:"kv-local",label:"本地 KV 存储"}),r(U,{value:"kv-server",label:"服务器 KV 存储"})]),_:1},8,["modelValue"]),s.targetStorage==="kv-server"?(v(),x("div",Te,[r(V,{modelValue:s.targetServerUrl,"onUpdate:modelValue":e[8]||(e[8]=a=>s.targetServerUrl=a),label:"目标服务器地址",hint:"输入KV服务器地址例如https://example.com/kv-api","persistent-hint":"","prepend-icon":"mdi-server-network"},null,8,["modelValue"])])):w("",!0)]),_:1})]),_:1}),g("div",xe,[r(N,{color:"success",onClick:i.startMigration,loading:s.migrating,disabled:!i.canMigrate},{default:o(()=>e[17]||(e[17]=[d(" 开始迁移 ")])),_:1,__:[17]},8,["onClick","loading","disabled"])]),r(X,{modelValue:s.showResult,"onUpdate:modelValue":e[10]||(e[10]=a=>s.showResult=a),"max-width":"600"},{default:o(()=>[r(T,null,{default:o(()=>[r(K,{class:"d-flex align-center"},{default:o(()=>[r(_,{color:s.migrationSuccess?"success":"error",class:"mr-2"},{default:o(()=>[d(f(s.migrationSuccess?"mdi-check-circle":"mdi-alert-circle"),1)]),_:1},8,["color"]),g("span",null,f(s.migrationSuccess?"迁移成功":"迁移失败"),1)]),_:1}),r(I,null,{default:o(()=>[s.migrationError?(v(),D(M,{key:0,type:"error",class:"mb-4"},{default:o(()=>[d(f(s.migrationError),1)]),_:1})):w("",!0),s.migrationSuccess?(v(),x("div",Ke,[g("p",null," 成功迁移 "+f(s.migrationStats.success)+" 项数据到 "+f(s.targetStorage==="kv-local"?"本地":"服务器")+" KV 存储。 ",1),r(oe,{class:"my-4"}),r(le,null,{default:o(()=>[r(ne,null,{default:o(()=>e[18]||(e[18]=[d("迁移详情")])),_:1,__:[18]}),(v(!0),x(G,null,ue(s.migrationResults,(a,u)=>(v(),D(ce,{key:u},{default:o(()=>[r(de,null,{default:o(()=>[d(f(a.key),1)]),_:2},1024),r(me,null,{default:o(()=>[d(f(a.success?"成功":"失败")+" "+f(a.message),1)]),_:2},1024)]),_:2},1024))),128))]),_:1})])):w("",!0)]),_:1}),r(Q,null,{default:o(()=>[r(z),r(N,{color:"primary",onClick:e[9]||(e[9]=a=>s.showResult=!1)},{default:o(()=>e[19]||(e[19]=[d(" 关闭 ")])),_:1,__:[19]})]),_:1})]),_:1})]),_:1},8,["modelValue"])])}const Z=W(Ve,[["render",Re]]),Me={name:"DataMigrationPage",components:{MigrationTool:Z},data(){const t=new Date,e=new Date;return e.setMonth(t.getMonth()-3),{showMigrationDialog:!1,isAutoMigrating:!1,today:t,sixMonthsAgo:e,classNumber:"",serverDomain:"",dataProvider:""}},computed:{dataSourceText(){switch(this.dataProvider){case"server":return"服务器";case"indexeddb":return"本地数据库";case"kv-local":return"本地 KV 存储";case"kv-server":return"远程 KV 存储";case"classworkscloud":return"Classworks 云";default:return"未知来源"}}},async mounted(){this.loadSettings(),this.serverDomain=="https://class.wuyuan.dev"&&(await this.startAutoMigration(),this.$router.push("/"))},methods:{loadSettings(){this.classNumber=b("server.classNumber"),this.serverDomain=b("server.domain"),this.dataProvider=b("server.provider"),this.showMigrationDialog=this.dataProvider==="server"||this.dataProvider==="indexeddb"},formatDate(t){return t.toLocaleDateString()},async startAutoMigration(){if(!this.$refs.migrationTool){console.error("MigrationTool组件引用不可用");return}this.isAutoMigrating=!0;try{const t=this.$refs.migrationTool;t.classNumber=this.classNumber,t.migrationType=this.dataProvider==="server"?"server":"local",t.serverUrl=this.serverDomain,t.targetStorage="kv-server",t.startDate=this.formatDateString(this.sixMonthsAgo),t.endDate=this.formatDateString(this.today),this.dataProvider==="server"?await t.previewServerData():await t.scanLocalDatabase(),t.displayItems.length>0?await t.startMigration():console.warn("没有找到可迁移的数据"),O("server.provider","classworkscloud")}catch(t){console.error("自动迁移失败:",t)}finally{this.isAutoMigrating=!1,this.showMigrationDialog=!1}},formatDateString(t){const e=t.getFullYear(),l=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${e}-${l}-${n}`}},metaInfo:{title:"数据迁移工具"}},Ne={class:"d-flex align-center mb-6"},Ue={class:"ml-3 mt-1"};function Le(t,e,l,n,s,i){const a=Z;return v(),D(we,null,{default:o(()=>[r(j,null,{default:o(()=>[r(R,{cols:"12"},{default:o(()=>[g("div",Ne,[r(_,{size:"x-large",color:"primary",class:"mr-3"},{default:o(()=>e[2]||(e[2]=[d("mdi-database-sync")])),_:1,__:[2]}),e[3]||(e[3]=g("div",null,[g("h1",{class:"text-h4"},"数据迁移工具"),g("div",{class:"text-subtitle-1 text-grey"}," 将现有数据迁移至 KV 存储系统 ")],-1))]),r(T,{class:"mb-6",variant:"tonal",color:"info",density:"compact"},{default:o(()=>[r(I,{class:"d-flex align-center"},{default:o(()=>[r(_,{color:"info",class:"mr-2"},{default:o(()=>e[4]||(e[4]=[d("mdi-information-outline")])),_:1,__:[4]}),e[5]||(e[5]=g("span",null,"使用此工具可以将数据从旧存储系统迁移到新的 KV 存储系统,选择本地或云端迁移,以确保数据不会丢失。",-1))]),_:1,__:[5]})]),_:1}),r(a,{ref:"migrationTool"},null,512)]),_:1})]),_:1}),r(X,{modelValue:s.showMigrationDialog,"onUpdate:modelValue":e[1]||(e[1]=u=>s.showMigrationDialog=u),"max-width":"500",persistent:""},{default:o(()=>[r(T,null,{default:o(()=>[r(K,{class:"text-h5 d-flex align-center"},{default:o(()=>[r(_,{color:"primary",size:"large",class:"mr-3"},{default:o(()=>e[6]||(e[6]=[d("mdi-database-sync")])),_:1,__:[6]}),e[7]||(e[7]=d(" 一键数据迁移 "))]),_:1,__:[7]}),r(I,{class:"mt-4"},{default:o(()=>[e[8]||(e[8]=g("p",null," 系统将自动读取您的配置并将过去半年的数据迁移至Classworks KV数据库中 ",-1)),r(M,{color:"info",variant:"outlined",density:"compact",class:"mt-4",icon:"mdi-information-outline"},{default:o(()=>[g("ul",Ue,[g("li",null,"数据源: "+f(i.dataSourceText),1),g("li",null,"班级: "+f(s.classNumber),1),g("li",null,"服务器: "+f(s.serverDomain||"本地存储"),1),g("li",null," 迁移范围: "+f(i.formatDate(s.sixMonthsAgo))+" 至 "+f(i.formatDate(s.today)),1)])]),_:1})]),_:1,__:[8]}),r(Q,null,{default:o(()=>[r(z),r(N,{color:"grey-darken-1",variant:"text",onClick:e[0]||(e[0]=u=>s.showMigrationDialog=!1)},{default:o(()=>e[9]||(e[9]=[d(" 稍后再说 ")])),_:1,__:[9]}),r(N,{color:"primary",size:"large",variant:"elevated",onClick:i.startAutoMigration,loading:s.isAutoMigrating,disabled:s.isAutoMigrating},{default:o(()=>[r(_,{left:"",class:"mr-2"},{default:o(()=>e[10]||(e[10]=[d("mdi-database-export")])),_:1,__:[10]}),e[11]||(e[11]=d(" 开始一键迁移 "))]),_:1,__:[11]},8,["onClick","loading","disabled"])]),_:1})]),_:1})]),_:1},8,["modelValue"])]),_:1})}const Je=W(Me,[["render",Le]]);export{Je as default};