diff --git a/src/components/BasicSign/Sign.vue b/src/components/BasicSign/Sign.vue
index ef42b32..54b7627 100644
--- a/src/components/BasicSign/Sign.vue
+++ b/src/components/BasicSign/Sign.vue
@@ -156,20 +156,31 @@ export default {
return await new Promise(async (resolve) => {
this.listeners.push((res) => {
if (res) {
- const byteCharacters = atob(res.split(',')[1]);
- const byteNumbers = new Array(byteCharacters.length);
- for (let i = 0; i < byteCharacters.length; i++) {
- byteNumbers[i] = byteCharacters.charCodeAt(i);
+ // 基础数据,所有平台都支持
+ const result = {
+ base64: res
+ };
+
+ // 以下代码仅在 H5 环境中执行,因为微信小程序不支持 Blob、File、URL.createObjectURL
+ // #ifdef H5
+ try {
+ const byteCharacters = atob(res.split(',')[1]);
+ const byteNumbers = new Array(byteCharacters.length);
+ for (let i = 0; i < byteCharacters.length; i++) {
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
+ }
+ const byteArray = new Uint8Array(byteNumbers);
+ const blob = new Blob([byteArray], {type: 'image/svg+xml'});
+ const fileName = 'sign.svg';
+ const file = new File([blob], fileName, {type: 'image/svg+xml'});
+ result.blob = URL.createObjectURL(file);
+ result.file = file;
+ } catch (e) {
+ console.error('处理签名文件失败:', e);
}
- const byteArray = new Uint8Array(byteNumbers);
- const blob = new Blob([byteArray], {type: 'image/svg+xml'});
- const fileName = 'sign.svg';
- const file = new File([blob], fileName, {type: 'image/svg+xml'});
- resolve({
- base64: res,
- blob: URL.createObjectURL(file),
- file
- });
+ // #endif
+
+ resolve(result);
} else {
resolve(res);
}
diff --git a/src/pages/base/jl/detail.vue b/src/pages/base/jl/detail.vue
index 2f96908..0732ab8 100644
--- a/src/pages/base/jl/detail.vue
+++ b/src/pages/base/jl/detail.vue
@@ -27,7 +27,7 @@
更多
-
+
收起
@@ -152,9 +152,37 @@ const currentStudent = computed(() => userStore.curXs);
const descPreview = computed(() => {
if (!noticeDetail.value?.jlms) return '';
- const div = document.createElement('div');
- div.innerHTML = noticeDetail.value.jlms;
- return div.innerText.replace(/\n/g, '').slice(0, 100) + (div.innerText.length > 100 ? '...' : '');
+ // 使用正则表达式去除 HTML 标签,兼容所有平台
+ const text = noticeDetail.value.jlms
+ .replace(/<[^>]+>/g, '') // 去除 HTML 标签
+ .replace(/ /g, '\u3000') // 转换为中文全角空格(保留段落缩进)
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/&/g, '&')
+ .replace(/"/g, '"')
+ .replace(/“/g, '"') // 左双引号
+ .replace(/”/g, '"') // 右双引号
+ .replace(/‘/g, "'") // 左单引号
+ .replace(/’/g, "'") // 右单引号
+ .replace(/—/g, '—') // 长破折号
+ .replace(/–/g, '–') // 短破折号
+ .replace(/…/g, '…') // 省略号
+ .replace(/·/g, '·') // 间隔号
+ .replace(/\d+;/g, '') // 移除数字型 HTML 实体
+ .replace(/[\r\n]+/g, ' ') // 将换行符转换为空格
+ .replace(/[ \t]+/g, ' ') // 只合并普通空格和制表符,保留全角空格
+ .trim();
+
+ return text.slice(0, 100) + (text.length > 100 ? '...' : '');
+});
+
+// 处理完整内容,移除段落开头的多余空格(因为 CSS 已设置 text-indent)
+const processedContent = computed(() => {
+ if (!noticeDetail.value?.jlms) return '';
+ // 将段落开头的 4个 替换为空(CSS 会自动添加 2em 缩进)
+ return noticeDetail.value.jlms
+ .replace(/( \s*){4}/g, '') // 移除 4个连续的 (可能有空格分隔)
+ .replace(/( ){4}/g, ''); // 移除紧挨着的 4个
});
// 获取文件名
@@ -600,6 +628,18 @@ watch(studentList, (list) => {
font-size: 14px;
color: #666;
line-height: 1.5;
+ white-space: pre-wrap; // 保留空格和换行
+ word-wrap: break-word; // 自动换行
+ }
+
+ // 使用深度选择器为 rich-text 内部的段落设置缩进
+ .desc-rich-text ::v-deep p {
+ text-indent: 2em; // 段落首行缩进2个字符
+ margin: 0.5em 0; // 段落间距
+ }
+
+ .desc-rich-text ::v-deep p:first-child {
+ text-indent: 0; // 第一个段落(标题)不缩进
}
}
diff --git a/src/pages/base/jl/detailwb.vue b/src/pages/base/jl/detailwb.vue
index b85aca5..f2ce7c2 100644
--- a/src/pages/base/jl/detailwb.vue
+++ b/src/pages/base/jl/detailwb.vue
@@ -2,7 +2,14 @@
- 加载中...
+
+
+
+
+ 加载中...
+
+
+
@@ -27,7 +34,7 @@
更多
-
+
收起
@@ -153,9 +160,37 @@ const currentStudent = computed(() => userStore.curXs);
const descPreview = computed(() => {
if (!noticeDetail.value?.jlms) return '';
- const div = document.createElement('div');
- div.innerHTML = noticeDetail.value.jlms;
- return div.innerText.replace(/\n/g, '').slice(0, 100) + (div.innerText.length > 100 ? '...' : '');
+ // 使用正则表达式去除 HTML 标签,兼容所有平台
+ const text = noticeDetail.value.jlms
+ .replace(/<[^>]+>/g, '') // 去除 HTML 标签
+ .replace(/ /g, '\u3000') // 转换为中文全角空格(保留段落缩进)
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/&/g, '&')
+ .replace(/"/g, '"')
+ .replace(/“/g, '"') // 左双引号
+ .replace(/”/g, '"') // 右双引号
+ .replace(/‘/g, "'") // 左单引号
+ .replace(/’/g, "'") // 右单引号
+ .replace(/—/g, '—') // 长破折号
+ .replace(/–/g, '–') // 短破折号
+ .replace(/…/g, '…') // 省略号
+ .replace(/·/g, '·') // 间隔号
+ .replace(/\d+;/g, '') // 移除数字型 HTML 实体
+ .replace(/[\r\n]+/g, ' ') // 将换行符转换为空格
+ .replace(/[ \t]+/g, ' ') // 只合并普通空格和制表符,保留全角空格
+ .trim();
+
+ return text.slice(0, 100) + (text.length > 100 ? '...' : '');
+});
+
+// 处理完整内容,移除段落开头的多余空格(因为 CSS 已设置 text-indent)
+const processedContent = computed(() => {
+ if (!noticeDetail.value?.jlms) return '';
+ // 将段落开头的 4个 替换为空(CSS 会自动添加 2em 缩进)
+ return noticeDetail.value.jlms
+ .replace(/( \s*){4}/g, '') // 移除 4个连续的 (可能有空格分隔)
+ .replace(/( ){4}/g, ''); // 移除紧挨着的 4个
});
// 获取文件名
@@ -552,7 +587,52 @@ watch(studentList, (list) => {
}
}
-.loading-indicator,
+/* 加载遮罩层样式 */
+.loading-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.6);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 9999;
+}
+
+.loading-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: rgba(255, 255, 255, 0.95);
+ border-radius: 12px;
+ padding: 30px 40px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+}
+
+.loading-spinner {
+ width: 40px;
+ height: 40px;
+ border: 4px solid #f3f3f3;
+ border-top: 4px solid #409eff;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+ margin-bottom: 15px;
+}
+
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+.loading-text {
+ font-size: 15px;
+ color: #333;
+ font-weight: 500;
+}
+
.empty-state {
text-align: center;
color: #999;
@@ -639,6 +719,18 @@ watch(studentList, (list) => {
font-size: 14px;
color: #666;
line-height: 1.5;
+ white-space: pre-wrap; // 保留空格和换行
+ word-wrap: break-word; // 自动换行
+ }
+
+ // 使用深度选择器为 rich-text 内部的段落设置缩进
+ .desc-rich-text ::v-deep p {
+ text-indent: 2em; // 段落首行缩进2个字符
+ margin: 0.5em 0; // 段落间距
+ }
+
+ .desc-rich-text ::v-deep p:first-child {
+ text-indent: 0; // 第一个段落(标题)不缩进
}
}