This commit is contained in:
Leo_Ding 2026-02-10 13:55:36 +08:00
parent f5826a889f
commit 745f5568bf
9 changed files with 159 additions and 65 deletions

View File

@ -2,13 +2,14 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createLoadingPlugin } from './utils/loading.js' // 引入加载插件;
// 引入 Ant Design Vue 组件
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/reset.css'
const app = createApp(App)
const loadingPlugin = createLoadingPlugin()
app.use(loadingPlugin) // 使用加载插件
app.use(router)
app.use(Antd) // 全局注册所有 Ant Design 组件

87
src/utils/loading.js Normal file
View File

@ -0,0 +1,87 @@
// plugins/loading.js
import { createVNode, render } from 'vue';
import { Spin } from 'ant-design-vue';
const DEFAULT_OPTIONS = {
tip: '加载中...',
size: 'large',
fullscreen: true, // 是否全屏遮罩
};
class LoadingInstance {
constructor(options = {}) {
this.options = { ...DEFAULT_OPTIONS, ...options };
this.vm = null;
this.container = null;
this.show();
}
show() {
const { tip, size, fullscreen } = this.options;
// 创建容器
this.container = document.createElement('div');
if (fullscreen) {
// 全屏模式:覆盖整个视口
this.container.style.position = 'fixed';
this.container.style.top = '0';
this.container.style.left = '0';
this.container.style.width = '100vw';
this.container.style.height = '100vh';
this.container.style.display = 'flex';
this.container.style.justifyContent = 'center';
this.container.style.alignItems = 'center';
this.container.style.backgroundColor = 'rgba(0, 0, 0, 0.2)';
this.container.style.zIndex = '9999';
} else {
// 非全屏:需用户指定挂载点(本示例暂不支持,可扩展)
console.warn('非全屏模式未实现,请传入 target 元素');
}
// 创建 Spin 组件的 VNode
const vnode = createVNode(Spin, {
tip,
size,
spinning: true,
});
// 渲染到容器
render(vnode, this.container);
document.body.appendChild(this.container);
this.vm = vnode;
}
hide() {
if (this.container) {
render(null, this.container); // 卸载
document.body.removeChild(this.container);
this.container = null;
}
}
// 可选:自动在 Promise 完成后隐藏
finishAfter(promise) {
if (promise && typeof promise.then === 'function') {
promise.finally(() => {
this.hide();
});
}
return promise;
}
}
// 插件 install 方法
export function createLoadingPlugin() {
return {
install(app) {
app.config.globalProperties.$loading = {
show(options) {
return new LoadingInstance(options);
},
};
// 如果使用 TypeScript 或需要类型提示,可额外声明
app.provide('$loading', app.config.globalProperties.$loading);
},
};
}

10
src/utils/useLoading.ts Normal file
View File

@ -0,0 +1,10 @@
// composables/useLoading.js
import { getCurrentInstance } from 'vue'
export function useLoading() {
const instance = getCurrentInstance()
if (!instance) {
throw new Error('useLoading() 必须在 setup() 或生命周期钩子中调用')
}
return instance.appContext.config.globalProperties.$loading
}

View File

@ -30,7 +30,7 @@ const selectedKeys = ref(['/document/introdution']);
const menuItems = [
{ key: '/document/introdution', label: '简介' },
{ key: '/document/start', label: '快速开始' },
{ key: '/document/video', label: '视频教程' },
// { key: '/document/video', label: '' },
{ key: '/document/study', label: '学术资源加速' },
{
key: '', label: '如何选择GPU',

View File

@ -10,8 +10,8 @@
<p>🎉 现在注册即送<code>炼丹会员</code>有效期1个月<a href="student/">认证学生</a>直接升级炼丹会员 <a
href="member/">了解会员及认证</a>🎉</p>
<p>👉 <a href="https://www.autodl.com"
target="_blank">AutoDL</a>的目标是为用户提供稳定可靠价格公道的GPU算力让GPU不再是您成为数据科学家道路上的拦路石</p>
<p>👉 观看官方录制的官方<a href="video/">使用视频</a></p>
target="_blank">亼算云</a>的目标是为用户提供稳定可靠价格公道的GPU算力让GPU不再是您成为数据科学家道路上的拦路石</p>
<!-- <p>👉 观看官方录制的官方<a href="video/">使用视频</a></p> -->
<p>👉必看文档</p>
<ol>
<li><a href="quick_start/">快速开始</a></li>

View File

@ -2,39 +2,39 @@
<div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="_1">快速开始<a class="headerlink" href="#_1" title="Permanent link"></a></h1>
<h1 id="_1">快速开始</h1>
<hr>
<blockquote>
<p>AutoDL实例中的数据包括环境在关机后将全部保存开机后无需再次配置和上传数据总而言之实例在数据在但是连续关机15天实例将被释放详见<a
<p>亼算云实例中的数据包括环境在关机后将全部保存开机后无需再次配置和上传数据总而言之实例在数据在但是连续关机15天实例将被释放详见<a
href="../instance_data/">实例数据保留说明</a></p>
</blockquote>
<h2 id="_2">创建实例<a class="headerlink" href="#_2" title="Permanent link"></a></h2>
<h2 id="_2">创建实例</h2>
<p>注册后进入控制台在我的实例菜单下点击租用新实例</p>
<p><img alt="image_20250226144908" src="../quick_start.assets/image_20250226144908.png"></p>
<p></p>
<p>在租用实例页面选择<strong>计费方式</strong><strong>地区</strong><strong>GPU型号</strong><strong>GPU数量</strong>然后选择合适的<strong>空闲主机</strong><strong>镜像</strong>内置了不同的深度学习框架的基础镜像和社区镜像最后创建即可
</p>
<blockquote>
<p>如果你需要更大的硬盘用于存放数据那么请留意硬盘这列可扩容大小数据盘的路径请参考<a href="../env/">文档</a></p>
</blockquote>
<p><img alt="image_20250226145836" src="../quick_start.assets/image_20250226145836.png">
<img alt="image_20250306103333" src="../quick_start.assets/image_20250306103333.png">
<p>
</p>
<p>创建完成后等待自动开机今后主要用到的操作入口见截图中</p>
<blockquote>
<p>请注意实例状态显示运行中开始计费如不使用请及时关机停止计费计费规则详见<a href="../price/">计费说明</a></p>
</blockquote>
<p><img alt="image_20250226153436" src="../quick_start.assets/image_20250226153436.png"></p>
<h2 id="_3">上传数据<a class="headerlink" href="#_3" title="Permanent link"></a></h2>
<p></p>
<h2 id="_3">上传数据</h2>
<p>开机后在这个正在运行中的实例上找到快捷工具JupyterLab点击打开在下面的截图中找到上传按钮即可上传数据如需上传文件夹或更高级的上传方式等请查阅<a
href="../scp/">上传数据文档</a></p>
<p><img alt="image_20250226153633" src="../quick_start.assets/image_20250226153633.png"></p>
<h2 id="_4">终端训练<a class="headerlink" href="#_4" title="Permanent link"></a></h2>
<p></p>
<h2 id="_4">终端训练</h2>
<p>在打开的JupyterLab页面中打开终端如需使用其他IDE远程开发请参考<a href="../vscode/">VSCode(推荐)</a><a
href="../pycharm/">PyCharm</a></p>
<p><img alt="image_20250226153713" src="../quick_start.assets/image_20250226153713.png"></p>
<p></p>
<p>在终端中执行您的Python命令等完成训练</p>
<p><img alt="image_20250226153804" src="../quick_start.assets/image_20250226153804.png"></p>
<h2 id="_5">进阶<a class="headerlink" href="#_5" title="Permanent link"></a></h2>
<p></p>
<h2 id="_5">进阶</h2>
<ol>
<li><a href="../gpu/">如何选择GPU</a></li>
<li><a href="../base_config/">配置环境</a></li>

View File

@ -2,13 +2,13 @@
<div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="_1">学术资源加速<a class="headerlink" href="#_1" title="Permanent link"></a></h1>
<h2 id="_2">公开服务<a class="headerlink" href="#_2" title="Permanent link"></a></h2>
<h1 id="_1">学术资源加速</h1>
<h2 id="_2">公开服务</h2>
<p>点击访问网址站点内有具体教程</p>
<p>Github <a href="https://ghproxy.link/" target="_blank">https://ghproxy.link/</a>
点击后查看当前可用的域名地址然后点击地址跳转查看文档</p>
<p>HuggingFace镜像站<a href="https://hf-mirror.com/" target="_blank">https://hf-mirror.com/</a></p>
<h2 id="autodl">AutoDL内置服务<a class="headerlink" href="#autodl" title="Permanent link"></a></h2>
<h2 id="autodl">AutoDL内置服务</h2>
<blockquote>
<p>声明限于学术使用github和huggingface网络速度慢的问题以下为方便用户学术用途使用相关资源提供的加速代理不承诺稳定性保证此外如遭遇恶意攻击等将随时停止该加速服务</p>
</blockquote>
@ -42,11 +42,11 @@ for line in output.splitlines():
<pre><span></span><code>unset http_proxy &amp;&amp; unset https_proxy
</code></pre>
</div>
<h3 id="_3">速度对比<a class="headerlink" href="#_3" title="Permanent link"></a></h3>
<h3 id="_3">速度对比</h3>
<p>未使用加速</p>
<p><img alt="image-20220902184957292" src="../Untitled.assets/image-20220902184957292.png"></p>
<p></p>
<p>使用加速</p>
<p><img alt="image-20220902185038755" src="../Untitled.assets/image-20220902185038755.png"></p>
<p></p>
</article>
</div>

View File

@ -13,7 +13,7 @@
</div>
</template>
<div v-for="item in bannerList" :key="item.id" class="banner-slide">
<img :src="item.image_url" alt="" srcset="" width="100%" height="100%">
<img :src="item.image_url" alt="" srcset="" width="100%" height="100%" @click="router.push(item.link_url)" style="cursor: pointer;">
</div>
</a-carousel>
</div>
@ -50,12 +50,15 @@
<span style="font-size: 24px;font-weight: bold;color: #5b85fe;">¥{{ value.price }}</span>
<span style="font-size: 12px;">/小时</span>
</div>
<div style="padding-bottom: 40px;line-height: 40px;">
<div style="line-height: 40px;padding-bottom: 20px;">
<!-- 修改这里添加单位 -->
<div>内存{{ value.memory }}GB</div>
<div>显存{{ value.vram }}GB</div>
<div>GPU{{ value.gpu_num }}</div>
</div>
<div style="padding-bottom: 30px;">
<a-button type="primary" @click="router.push('/layout/market')" block>立即购买</a-button>
</div>
</div>
</div>
</div>
@ -69,7 +72,7 @@
</div>
</div>
<div class="avatary_list">
<div class="avatary_item" v-for="item in advantageList">
<div v-for="(item, index) in advantageList" :key="index">
<div>
<div class="title" style="font-size: 28px;">{{ item.title }}</div>
<div class="subtitle" style="text-align: left;font-size: 18px;line-height:30px;">{{ item.description }}</div>
@ -116,7 +119,7 @@
<script lang="ts" setup>
import { LeftCircleOutlined, RightCircleOutlined } from '@ant-design/icons-vue';
import { ref } from 'vue'
import { ref,onBeforeMount } from 'vue'
import { useRouter } from 'vue-router';
import { getBannerList, getGpuList, getAdvantage, getHotProduct,getApiOneList } from '@/apis/home';
import one from '@/assets/1.png'
@ -130,6 +133,7 @@ import defaultBanner3 from '@/assets/12.png';
import defaultBanner4 from '@/assets/333.png';
import defaultBanner from '@/assets/333.png';
import { get } from 'http';
import { on } from 'events';
const router = useRouter();
const listColor = ref(['#7ed321', '#21d3c0', '#35a4de'])
const source = ref<any[]>([])
@ -139,7 +143,16 @@ const bannerList = ref<any[]>([
{ id: 0, image_url: defaultBanner3 },
{ id: 1, image_url: defaultBanner4 }
]);
import { useLoading } from '@/utils/useLoading'
const $loading = useLoading()
onBeforeMount(async () => {
const loading = $loading.show({ tip: '拼命加载中...' })
await fetchBannerList();
await getOneList();
await getGPUList();
await getAdvantageList();
loading.hide()
})
const onChange = (current: number) => {
console.log(current);
};
@ -151,22 +164,8 @@ const fetchBannerList = async () => {
const res: any = await getBannerList();
//
if (res && Array.isArray(res) && res.length > 0) {
const processedList = res.map((item: any, index: number) => {
// itemid
const processedItem = {
id: item.id || index,
image_url: item.image_url || defaultBanner
};
// http
if (processedItem.image_url && processedItem.image_url.startsWith('http://')) {
processedItem.image_url = processedItem.image_url.replace('http://', 'https://');
}
return processedItem;
});
bannerList.value = processedList;
bannerList.value = res.map(item=>({image_url: 'http://36.133.78.46:8040'+item.image_url, link_url: item.link_url}));
console.log('轮播图数据:', bannerList.value);
} else {
// API使
bannerList.value = [{ id: 0, image_url: defaultBanner }];
@ -229,20 +228,7 @@ const getGPUList = async () => {
const getAdvantageList = async () => {
try {
const res: any = await getAdvantage();
const list = res || [];
// item img
list.forEach((item: any, index: number) => {
if (index === 0) {
item.img = one;
} else if (index === 1) {
item.img = two;
} else if (index === 2) {
item.img = three;
} else {
item.img = firth;
}
});
const list = res.map((item:any)=>({title: item.title, description: item.description,image_url: 'http://36.133.78.46:8040'+item.image_url})) || [];
advantageList.value = list;
} catch (error: any) {
console.error('产品优势请求失败:', error);
@ -252,10 +238,7 @@ const getAdvantageList = async () => {
fetchBannerList();
getGPUList();
getAdvantageList();
getOneList();
</script>
<style scoped lang="scss">
.banner-slide {
@ -336,7 +319,7 @@ getOneList();
// grid-template-columns: repeat(2, 1fr);
// gap: 50px;
&>div {
&>div:not(:nth-child(2n)) {
display: flex;
// flex-direction: column;
align-items: flex-start;
@ -350,7 +333,20 @@ getOneList();
align-items: flex-start;
}
}
&>div:not(:nth-child(2n+1)) {
display: flex;
flex-direction: row-reverse;
align-items: flex-start;
justify-content: space-between;
gap: 100px;
&>div {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
}
}
.title {
color: #59b2f2;
font-size: 18px;

View File

@ -19,6 +19,6 @@
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/apis/index.ts"],
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/apis/index.ts", "src/utils/loading.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}