|
|
@@ -69,6 +69,7 @@
|
|
|
<div
|
|
|
v-if="bibForm.eventName"
|
|
|
class="event-name-preview draggable-element"
|
|
|
+ v-loading="fontPreviewLoading"
|
|
|
:style="{
|
|
|
fontSize: Math.min(bibForm.fontSize, 56) + 'px',
|
|
|
color: bibForm.fontColorHex,
|
|
|
@@ -88,6 +89,9 @@
|
|
|
<!-- 示例数字 12345 -->
|
|
|
<div
|
|
|
class="draggable-element number-element"
|
|
|
+ v-loading="fontPreviewLoading"
|
|
|
+ element-loading-text="加载字体..."
|
|
|
+ element-loading-background="rgba(255, 255, 255, 0.7)"
|
|
|
:style="{
|
|
|
left: (bibForm.numberX || 50) + '%',
|
|
|
top: (bibForm.numberY || 50) + '%',
|
|
|
@@ -163,14 +167,27 @@
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="字体设置">
|
|
|
- <div style="display: flex; gap: 15px; align-items: center">
|
|
|
- <el-select v-model="bibForm.fontName" placeholder="字体" style="width: 100px">
|
|
|
+ <div style="display: flex; gap: 15px; align-items: center; flex-wrap: wrap">
|
|
|
+ <el-select v-model="bibForm.fontName" filterable clearable placeholder="字体" style="width: 100px">
|
|
|
<el-option label="黑体" value="simhei"></el-option>
|
|
|
<el-option label="宋体" value="simsun"></el-option>
|
|
|
<el-option label="微软雅黑" value="yahei"></el-option>
|
|
|
+ <el-option v-if="bibForm.isCustomFont" :label="bibForm.customFontName" :value="bibForm.customFontNameValue"></el-option>
|
|
|
</el-select>
|
|
|
<el-input-number v-model="bibForm.fontSize" :min="8" :max="198" placeholder="字体大小" style="width: 140px"></el-input-number>
|
|
|
<el-color-picker v-model="bibForm.fontColor" @change="handleFontColorChange"></el-color-picker>
|
|
|
+ <el-upload
|
|
|
+ class="font-upload"
|
|
|
+ :auto-upload="true"
|
|
|
+ :show-file-list="false"
|
|
|
+ :action="uploadUrl"
|
|
|
+ :headers="uploadHeaders"
|
|
|
+ :on-success="handleFontUploadSuccess"
|
|
|
+ accept=".ttf,.otf"
|
|
|
+ >
|
|
|
+ <el-button type="primary" link icon="Upload">上传字体</el-button>
|
|
|
+ </el-upload>
|
|
|
+ <el-button type="primary" link icon="FolderOpened" @click="openCloudFontDialog">云端字体库</el-button>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
@@ -231,11 +248,31 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 云端字体选择对话框 -->
|
|
|
+ <el-dialog v-model="cloudFontVisible" title="选择云端字体" width="600px" append-to-body>
|
|
|
+ <el-table v-loading="fontLoading" :data="fontList" @row-click="handleCloudFontSelect" highlight-current-row>
|
|
|
+ <el-table-column label="字体名称" align="center" prop="originalName" />
|
|
|
+ <el-table-column label="上传时间" align="center" prop="createTime" width="180" />
|
|
|
+ <el-table-column label="操作" align="center" width="100">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button link type="primary" @click="handleCloudFontSelect(scope.row)">选择</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="cloudFontVisible = false">取 消</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { ref, reactive, nextTick, getCurrentInstance } from 'vue';
|
|
|
import { createBibTask } from '@/api/system/gameEvent/task';
|
|
|
+import { listOss } from '@/api/system/oss';
|
|
|
+import { getToken } from '@/utils/auth';
|
|
|
import type { UploadInstance } from 'element-plus';
|
|
|
import { parseTime } from '@/utils/ruoyi';
|
|
|
|
|
|
@@ -294,8 +331,24 @@ const bibForm = reactive({
|
|
|
barcodeScale: 1,
|
|
|
numberScale: 1,
|
|
|
eventScale: 1,
|
|
|
+ // 字体相关
|
|
|
+ fontOssId: null as number | null,
|
|
|
+ isCustomFont: false,
|
|
|
+ customFontName: '',
|
|
|
+ customFontNameValue: '' // 存储自定义字体的内部标识符,如 CustomFont_123
|
|
|
});
|
|
|
|
|
|
+const uploadHeaders = ref({
|
|
|
+ Authorization: 'Bearer ' + getToken(),
|
|
|
+ clientid: import.meta.env.VITE_APP_CLIENT_ID
|
|
|
+});
|
|
|
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload');
|
|
|
+
|
|
|
+const cloudFontVisible = ref(false);
|
|
|
+const fontLoading = ref(false);
|
|
|
+const fontPreviewLoading = ref(false); // 字体预览加载状态
|
|
|
+const fontList = ref<any[]>([]);
|
|
|
+
|
|
|
const bgImageFile = ref<File | null>(null);
|
|
|
const logoImageFile = ref<File | null>(null);
|
|
|
const bgImageUrl = ref<string>('');
|
|
|
@@ -405,6 +458,12 @@ const resetBibForm = () => {
|
|
|
selectedElement.value = '';
|
|
|
// 重置画布比例
|
|
|
canvasScale.value = 1;
|
|
|
+
|
|
|
+ // 重置自定义字体
|
|
|
+ bibForm.fontOssId = null;
|
|
|
+ bibForm.isCustomFont = false;
|
|
|
+ bibForm.customFontName = '';
|
|
|
+ bibForm.customFontNameValue = '';
|
|
|
|
|
|
// 清除上传的文件
|
|
|
if (bgUploadRef.value) {
|
|
|
@@ -491,6 +550,84 @@ const handleFontColorChange = (color: string) => {
|
|
|
bibForm.fontColorHex = color;
|
|
|
};
|
|
|
|
|
|
+// 上传字体成功回调
|
|
|
+const handleFontUploadSuccess = (response: any) => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ const ossData = response.data;
|
|
|
+ loadCustomFont(ossData.url, ossData.originalName, ossData.ossId);
|
|
|
+ proxy?.$modal.msgSuccess('字体上传成功');
|
|
|
+ } else {
|
|
|
+ proxy?.$modal.msgError(response.msg || '上传失败');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 打开云端字体对话框
|
|
|
+const openCloudFontDialog = async () => {
|
|
|
+ cloudFontVisible.value = true;
|
|
|
+ fontLoading.value = true;
|
|
|
+ try {
|
|
|
+ const res = await listOss({ fileSuffix: '.ttf' } as any);
|
|
|
+ const resOtf = await listOss({ fileSuffix: '.otf' } as any);
|
|
|
+ fontList.value = [...(res.rows || []), ...(resOtf.rows || [])];
|
|
|
+ } finally {
|
|
|
+ fontLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 选择云端字体
|
|
|
+const handleCloudFontSelect = (row: any) => {
|
|
|
+ loadCustomFont(row.url, row.originalName, row.ossId);
|
|
|
+ cloudFontVisible.value = false;
|
|
|
+};
|
|
|
+
|
|
|
+// 加载并注册自定义字体以供预览
|
|
|
+const loadCustomFont = async (url: string, name: string, ossId: number) => {
|
|
|
+ // 1. 处理名称:去除后缀
|
|
|
+ const cleanName = name.replace(/\.[^/.]+$/, "");
|
|
|
+ const fontFamily = `CustomFont_${ossId}`;
|
|
|
+
|
|
|
+ // 2. 检查缓存:如果该字体已经加载过,直接应用
|
|
|
+ const existingFont = Array.from(document.fonts).find(f => f.family === fontFamily);
|
|
|
+ if (existingFont && existingFont.status === 'loaded') {
|
|
|
+ bibForm.fontName = fontFamily;
|
|
|
+ bibForm.fontOssId = ossId;
|
|
|
+ bibForm.isCustomFont = true;
|
|
|
+ bibForm.customFontName = cleanName;
|
|
|
+ bibForm.customFontNameValue = fontFamily;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ fontPreviewLoading.value = true;
|
|
|
+ try {
|
|
|
+ const fontFace = new FontFace(fontFamily, `url(${url})`);
|
|
|
+ // 显式添加到集合中
|
|
|
+ document.fonts.add(fontFace);
|
|
|
+
|
|
|
+ // 3. 等待加载完成
|
|
|
+ await fontFace.load();
|
|
|
+
|
|
|
+ // 4. 更新状态
|
|
|
+ bibForm.fontName = fontFamily;
|
|
|
+ bibForm.fontOssId = ossId;
|
|
|
+ bibForm.isCustomFont = true;
|
|
|
+ bibForm.customFontName = cleanName;
|
|
|
+ bibForm.customFontNameValue = fontFamily;
|
|
|
+
|
|
|
+ proxy?.$modal.msgSuccess(`成功加载字体: ${cleanName}`);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载字体文件失败:', error);
|
|
|
+ proxy?.$modal.msgError('加载预览字体失败');
|
|
|
+
|
|
|
+ // 即使加载失败也记录信息
|
|
|
+ bibForm.fontName = fontFamily;
|
|
|
+ bibForm.fontOssId = ossId;
|
|
|
+ bibForm.isCustomFont = true;
|
|
|
+ bibForm.customFontName = cleanName;
|
|
|
+ } finally {
|
|
|
+ fontPreviewLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
// 开始拖拽
|
|
|
const startDrag = (event: MouseEvent, target: string) => {
|
|
|
event.preventDefault();
|
|
|
@@ -709,6 +846,7 @@ const handleCreateTask = async () => {
|
|
|
|
|
|
// 其他通用参数
|
|
|
fontName: bibForm.fontName || 'simhei',
|
|
|
+ fontOssId: bibForm.fontOssId,
|
|
|
fontSize: bibForm.fontSize || 36,
|
|
|
fontColor: parseInt((bibForm.fontColor || '#000000').replace('#', ''), 16),
|
|
|
eventName: bibForm.eventName || '',
|