Merge branch 'ai-hub' into ai-hub-dark
This commit is contained in:
60
Yi.Ai.Vue3/.build/plugins/git-hash.ts
Normal file
60
Yi.Ai.Vue3/.build/plugins/git-hash.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import type { Plugin } from 'vite';
|
||||
import { execSync } from 'node:child_process';
|
||||
import path from 'node:path';
|
||||
|
||||
/**
|
||||
* 获取 Git 提交哈希值插件
|
||||
* Git 仓库在上一级目录
|
||||
*/
|
||||
export default function gitHashPlugin(): Plugin {
|
||||
let gitHash = 'unknown';
|
||||
let gitBranch = 'unknown';
|
||||
let gitDate = 'unknown';
|
||||
|
||||
try {
|
||||
// Git 仓库在上一级目录
|
||||
const execOptions = { cwd: path.resolve(__dirname, '../../..'), encoding: 'utf-8' as BufferEncoding };
|
||||
|
||||
// 获取完整的 commit hash
|
||||
gitHash = execSync('git rev-parse HEAD', execOptions)
|
||||
.toString()
|
||||
.trim();
|
||||
|
||||
// 获取短 hash (前7位)
|
||||
const shortHash = gitHash.substring(0, 7);
|
||||
|
||||
// 获取分支名
|
||||
gitBranch = execSync('git rev-parse --abbrev-ref HEAD', execOptions)
|
||||
.toString()
|
||||
.trim();
|
||||
|
||||
// 获取提交时间
|
||||
gitDate = execSync('git log -1 --format=%cd --date=iso', execOptions)
|
||||
.toString()
|
||||
.trim();
|
||||
|
||||
console.log(`\n📦 Git Info:`);
|
||||
console.log(` Branch: ${gitBranch}`);
|
||||
console.log(` Commit: ${shortHash}`);
|
||||
console.log(` Date: ${gitDate}\n`);
|
||||
|
||||
gitHash = shortHash; // 使用短 hash
|
||||
} catch (error: any) {
|
||||
console.warn('⚠️ 无法获取 Git 信息:', error?.message || error);
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'vite-plugin-git-hash',
|
||||
config() {
|
||||
// 在 config 钩子中返回配置
|
||||
return {
|
||||
define: {
|
||||
__GIT_HASH__: JSON.stringify(gitHash),
|
||||
__GIT_BRANCH__: JSON.stringify(gitBranch),
|
||||
__GIT_DATE__: JSON.stringify(gitDate),
|
||||
__BUILD_TIME__: JSON.stringify(new Date().toISOString()),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -10,12 +10,14 @@ import Components from 'unplugin-vue-components/vite';
|
||||
import viteCompression from 'vite-plugin-compression';
|
||||
|
||||
import envTyped from 'vite-plugin-env-typed';
|
||||
import gitHashPlugin from './git-hash';
|
||||
import createSvgIcon from './svg-icon';
|
||||
|
||||
const root = path.resolve(__dirname, '../../');
|
||||
|
||||
function plugins({ mode, command }: ConfigEnv): PluginOption[] {
|
||||
return [
|
||||
gitHashPlugin(),
|
||||
UnoCSS(),
|
||||
envTyped({
|
||||
mode,
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
<body>
|
||||
<!-- 加载动画容器 -->
|
||||
<div id="yixinai-loader" class="loader-container">
|
||||
<div class="loader-title">意心Ai 3.2</div>
|
||||
<div class="loader-title">意心Ai 3.3</div>
|
||||
<div class="loader-subtitle">海外地址,仅首次访问预计加载约10秒,无需梯子</div>
|
||||
<div class="loader-logo">
|
||||
<div class="pulse-box"></div>
|
||||
|
||||
@@ -26,6 +26,17 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
|
||||
app.use(store);
|
||||
|
||||
// 输出构建信息
|
||||
console.log(
|
||||
`%c 意心AI 3.3 %c Build Info `,
|
||||
'background:#35495e; padding: 4px; border-radius: 3px 0 0 3px; color: #fff',
|
||||
'background:#41b883; padding: 4px; border-radius: 0 3px 3px 0; color: #fff',
|
||||
);
|
||||
// console.log(`🔹 Git Branch: ${__GIT_BRANCH__}`);
|
||||
console.log(`🔹 Git Commit: ${__GIT_HASH__}`);
|
||||
// console.log(`🔹 Commit Date: ${__GIT_DATE__}`);
|
||||
// console.log(`🔹 Build Time: ${__BUILD_TIME__}`);
|
||||
|
||||
// 挂载 Vue 应用
|
||||
// mount 完成说明应用初始化完毕,此时手动通知 loading 动画结束
|
||||
app.mount('#app');
|
||||
|
||||
@@ -130,6 +130,49 @@ function handleRemove(file: UploadFile) {
|
||||
fileList.value.splice(index, 1);
|
||||
}
|
||||
|
||||
// Handle paste event for reference images
|
||||
function handlePaste(event: ClipboardEvent) {
|
||||
const items = event.clipboardData?.items;
|
||||
if (!items) return;
|
||||
|
||||
for (const item of items) {
|
||||
if (item.type.startsWith('image/')) {
|
||||
event.preventDefault();
|
||||
|
||||
if (fileList.value.length >= 2) {
|
||||
ElMessage.warning('最多只能上传2张参考图');
|
||||
return;
|
||||
}
|
||||
|
||||
const file = item.getAsFile();
|
||||
if (!file) return;
|
||||
|
||||
// Check file size
|
||||
const isLt5M = file.size / 1024 / 1024 < 5;
|
||||
if (!isLt5M) {
|
||||
ElMessage.error('图片大小不能超过 5MB!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Create object URL for preview
|
||||
const url = URL.createObjectURL(file);
|
||||
const filename = `pasted-image-${Date.now()}.${file.type.split('/')[1] || 'png'}`;
|
||||
|
||||
const uploadFile: UploadUserFile = {
|
||||
name: filename,
|
||||
url,
|
||||
raw: file,
|
||||
uid: Date.now(),
|
||||
status: 'ready',
|
||||
};
|
||||
|
||||
fileList.value.push(uploadFile);
|
||||
ElMessage.success('已粘贴图片');
|
||||
break; // Only handle the first image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fileToBase64(file: File): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
@@ -356,10 +399,14 @@ defineExpose({
|
||||
onMounted(() => {
|
||||
fetchTokens();
|
||||
fetchModels();
|
||||
// Add paste event listener for reference images
|
||||
document.addEventListener('paste', handlePaste);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stopPolling();
|
||||
// Remove paste event listener
|
||||
document.removeEventListener('paste', handlePaste);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -474,7 +521,7 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</el-upload>
|
||||
<div class="text-xs text-gray-400 mt-2 flex justify-between items-center flex-wrap gap-2">
|
||||
<span>最多2张,< 5MB (支持 JPG/PNG/WEBP)</span>
|
||||
<span>最多2张,< 5MB (支持 JPG/PNG/WEBP,可粘贴)</span>
|
||||
<el-checkbox v-model="compressImage" label="压缩图片" size="small" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
11
Yi.Ai.Vue3/types/global.d.ts
vendored
11
Yi.Ai.Vue3/types/global.d.ts
vendored
@@ -1 +1,12 @@
|
||||
declare module "virtual:svg-icons-register";
|
||||
|
||||
// Git 构建信息
|
||||
declare const __GIT_HASH__: string;
|
||||
declare const __GIT_BRANCH__: string;
|
||||
declare const __GIT_DATE__: string;
|
||||
declare const __BUILD_TIME__: string;
|
||||
|
||||
// 全局加载器方法
|
||||
interface Window {
|
||||
__hideAppLoader?: () => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user