From b2555a328ee990e8e25f32040633c2ec2fde8221 Mon Sep 17 00:00:00 2001
From: 祖安之光 <11848914+light-of-zuan@user.noreply.gitee.com>
Date: 星期一, 18 八月 2025 16:47:57 +0800
Subject: [PATCH] 修改新增
---
src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue | 278 ++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 242 insertions(+), 36 deletions(-)
diff --git a/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue b/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue
index 8a81214..239dd6c 100644
--- a/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue
+++ b/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue
@@ -31,44 +31,72 @@
<div class="bottom">
<div class="left">
<span style="font-weight: 600;font-size: 24px">目录</span>
- <el-tree
- v-if="data.treeData"
- style="max-width: 600px;margin-top: 20px"
- :data="data.treeData"
- :props="data.defaultProps"
- :default-expand-all="true"
- :expand-on-click-node="false"
- highlight-current
- @node-click="handleNodeClick"
- ></el-tree>
+ <div class="tree-container tree-hide-scrollbar" v-if="data.treeData">
+ <el-tree
+ ref="treeRef"
+ :data="data.treeData"
+ :props="data.defaultProps"
+ :default-expand-all="true"
+ :expand-on-click-node="false"
+ highlight-current
+ node-key="id"
+ :current-node-key="currentSelectedKey"
+ @node-click="handleNodeClick"
+ >
+ <template #default="{ node,data }">
+ <el-tooltip
+ :content="data.mess"
+ placement="bottom"
+ :disabled="!isTextOverflow(data)"
+ >
+ <span class="tree-text">{{ data.mess }}</span>
+ </el-tooltip>
+ </template>
+ </el-tree>
+ </div>
<el-empty v-else description="暂无数据" />
</div>
<div class="right">
<el-form :model="state.form" size="default" ref="noticeRef" :rules="data.formRules" label-position="left" label-width="125px" >
- <el-form-item label="具体内容" prop="content" >
-
- <t-editor style="width: 100%;" :height="300" ref="myEditor1" :value="state.form.content" ></t-editor>
-<!-- <el-input v-model="state.form.content" :rows="4" type="textarea" />-->
+ <el-form-item label="具体内容" prop="content" v-if="data.isAdmin">
+ <t-editor style="width: 100%;" :height="400" ref="myEditor1" :value="state.form.content" ></t-editor>
</el-form-item>
- <el-form-item label="标准分析" prop="analysis" >
- <t-editor style="width: 100%;" :height="300" ref="myEditor2" :value="state.form.analysis" ></t-editor>
-<!-- <el-input v-model="state.form.analysis" :rows="4" type="textarea" />-->
+ <el-form-item label="具体内容" prop="content" v-else>
+ <div class="ql-container ql-snow" style="height: 500px;width: 100%;margin-top: 10px;" >
+ <div class="ql-editor">
+ <div v-if="state.form.content" class="reviewTable" v-html="state.form.content" @click="showFile($event)"></div>
+ <el-empty v-else description="暂无数据" />
+ </div>
+ </div>
+ </el-form-item>
+ <el-form-item label="标准分析" prop="analysis" v-if="data.isAdmin">
+ <t-editor style="width: 100%;" :height="400" ref="myEditor2" :value="state.form.analysis" ></t-editor>
+ </el-form-item>
+ <el-form-item label="标准分析" prop="content" v-else>
+ <div class="ql-container ql-snow" style="height: 500px;width: 100%;margin-top: 10px;" >
+ <div class="ql-editor">
+ <div v-if="state.form.analysis" class="reviewTable" v-html="state.form.analysis" @click="showFile($event)"></div>
+ <el-empty v-else description="暂无数据" />
+
+ </div>
+ </div>
</el-form-item>
<el-form-item label="应准备材料" prop="dataList">
- <el-button type="primary" @click="openDataDialog('add',{})">新增</el-button>
+ <el-button v-if="data.isAdmin" type="primary" @click="openDataDialog('add',{})">新增</el-button>
</el-form-item>
<el-table style="margin:15px 0;width: 100%" :data="state.form.dataList" :border="true" >
<el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
<el-table-column label="材料名称" prop="name" align="center" />
-<!-- <el-table-column label="材料模板" prop="fileName" align="center" >-->
-<!-- <template #default="scope">-->
-<!-- <el-link v-if="scope.row.fileName" style="" type="primary" @click="downloadFile(scope.row)">{{scope.row.fileName}}</el-link>-->
-<!-- </template>-->
-<!-- </el-table-column>-->
+ <el-table-column label="材料模板" prop="fileName" align="center" >
+ <template #default="scope">
+ <el-link v-if="scope.row.fileName" style="" type="primary" @click="openFile(scope.row.filePath)">{{scope.row.fileName}}</el-link>
+ </template>
+ </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" >
<template #default="scope">
- <el-button link type="primary" @click="openDataDialog('edit',scope.row)" >编辑</el-button>
- <el-button link type="danger" @click="handleDataDelete(scope.row)" >删除</el-button>
+ <el-button v-if="scope.row.filePath" link type="primary" @click="downloadFile(scope.row)" >下载</el-button>
+ <el-button v-if="data.isAdmin" link type="primary" @click="openDataDialog('edit',scope.row)" >编辑</el-button>
+ <el-button v-if="data.isAdmin" link type="danger" @click="handleDataDelete(scope.row)" >删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -92,8 +120,8 @@
<!-- </el-table>-->
</el-form>
<div style="display: flex;align-items: center;justify-content: right;margin-top: 10px">
- <el-button v-if="state.form.id" type="danger" @click="deleteData">删除</el-button>
- <el-button type="primary" @click="addData()">保存</el-button>
+ <el-button v-if="state.form.id && data.isAdmin" type="danger" @click="deleteData">删除</el-button>
+ <el-button v-if="data.isAdmin" type="primary" @click="addData()">保存</el-button>
</div>
</div>
@@ -103,7 +131,7 @@
</div>
</template>
<script setup>
-import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue";
+import {getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs} from "vue";
import Cookies from "js-cookie";
import {ElMessage, ElMessageBox} from "element-plus";
import {getCompany} from "@/api/onlineEducation/company";
@@ -123,6 +151,7 @@
} from "@/api/qualityManage/range";
import axios from "axios";
import TEditor from "@/components/Tinymce/Tinymce.vue";
+import {renderAsync} from "docx-preview";
const { proxy } = getCurrentInstance();
const loading = ref(false);
@@ -130,7 +159,9 @@
const dialogRef = ref();
const myEditor1 = ref();
const myEditor2 = ref();
+const treeRef = ref()
const dialogRecordRef = ref();
+const currentSelectedKey = ref()
const loadingCompany = ref(false)
const data = reactive({
queryParams: {
@@ -191,6 +222,13 @@
state.form.companyId = userInfo.companyId
}
await getList();
+ if(data.treeData.length >0){
+ state.form.catalogueId = data.treeData[0].id
+ currentSelectedKey.value = state.form.catalogueId
+ await getCatalogDataList()
+ await getFileList()
+
+ }
})
const getList = async () => {
@@ -207,12 +245,34 @@
ElMessage.warning(res.message)
}
loading.value = false;
-
}
+const textMeasureRef = ref(null);
+const getMeasureElement = () => {
+ if (!textMeasureRef.value) {
+ const el = document.createElement('span');
+ el.className = 'text-measure-element';
+ el.style.cssText = `
+ position: absolute;
+ visibility: hidden;
+ white-space: nowrap;
+ font-size: 14px; /* 匹配实际字体大小 */
+ `;
+ document.body.appendChild(el);
+ textMeasureRef.value = el;
+ }
+ return textMeasureRef.value;
+};
+// 判断文本是否溢出
+const isTextOverflow = (text) => {
+ const measureEl = getMeasureElement();
+ measureEl.textContent = text.mess;
+ return measureEl.scrollWidth > 300; // 180px 是节点容器实际宽度
+};
+
const handleTree = (val) => {
const traverse = (nodes, currentPath = '') => {
nodes.forEach((node, index) => {
- node.name = `${node.number} ${node.mess}`;
+ node.mess= `${node.number} ${node.mess}`;
// 递归处理子节点(传递当前序号路径)
if (node.children && node.children.length) {
traverse(node.children, node.number);
@@ -239,7 +299,7 @@
}else {
loadingCompany.value = true;
const queryParams = {
- pageSize: 10,
+ pageSize: 100,
pageNum: 1,
}
const res = await getCompany(queryParams)
@@ -255,8 +315,10 @@
const selectValue = async (val) => {
state.form.analysis = ''
state.form.content = ''
- myEditor1.value.myValue = ''
- myEditor2.value.myValue = ''
+ if(data.isAdmin){
+ myEditor1.value.myValue = ''
+ myEditor2.value.myValue = ''
+ }
state.form.id = ''
data.companyList.forEach(item => {
if(item.name === val){
@@ -274,10 +336,15 @@
const handleNodeClick = async (val) => {
state.form.analysis = ''
state.form.content = ''
- myEditor1.value.myValue = ''
- myEditor2.value.myValue = ''
+ if(data.isAdmin){
+ myEditor1.value.myValue = ''
+ myEditor2.value.myValue = ''
+ }
+
+
state.form.id = ''
state.form.catalogueId = val.id
+ currentSelectedKey.value = val.id
await getCatalogDataList()
await getFileList()
}
@@ -451,6 +518,45 @@
ElMessage.warning(res.message)
}
}
+const openFile = async(path)=>{
+ const ext = path.split('.').pop().toLowerCase();
+ if (ext === 'doc') {
+ ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+ }).catch(() => {
+ console.log('取消预览')
+ });
+ return
+ }
+ try {
+ // 1. 获取文件
+ const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+ const arrayBuffer = await response.arrayBuffer();
+ // 2. 创建新窗口
+ const win = window.open('', '_blank')
+ win.document.write(`
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>预览</title>
+ <style>
+ body { margin: 20px; font-family: Arial; }
+ .docx-container { width: 100%; height: 100%; }
+ </style>
+ </head>
+ <body>
+ <div id="container" class="docx-container"></div>
+ </body>
+ </html>
+ `);
+ // 3. 渲染 DOCX
+ await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+ } catch (error) {
+ console.error('预览失败:', error);
+ alert(`预览失败: ${error.message}`);
+ }
+}
const downloadFile = (e)=>{
axios.get(import.meta.env.VITE_APP_BASE_API + '/' +e.filePath,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`},responseType: 'blob'}).then(res=>{
if (res) {
@@ -470,6 +576,40 @@
}
})
}
+
+const showFile = (e) => {
+ if(e.target.nodeName === 'A'){
+ console.log("e",e)
+ e.preventDefault();
+ const file = {
+ fileUrl: e.target.href,
+ fileName: e.target.innerHTML
+ }
+ axios.get( file.fileUrl,{
+ headers:
+ {
+ 'Content-Type': 'application/json',
+ 'Authorization':getToken(),
+ },
+ responseType: 'blob'
+ }
+ ).then(res=>{
+ if (res) {
+ const link = document.createElement('a')
+ let blob = new Blob([res.data],{type: res.data.type})
+ link.style.display = "none";
+ link.href = URL.createObjectURL(blob); // 创建URL
+ link.setAttribute("download", file.fileName);
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ } else {
+ this.$message.error('获取文件失败')
+ }
+ // handleClose();
+ })
+ }
+}
</script>
<style scoped lang="scss">
@@ -482,13 +622,65 @@
margin: 20px;
.left{
- border-right: 1px solid darkgray;
+ //border-right: 1px solid darkgray;
display: flex;
min-width: 240px;
margin: 20px 20px 20px 50px;
flex-direction: column;
:deep(.el-tree){
background: none;
+ }
+ :deep(.el-tooltip )
+ {
+ color: black;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ word-break: break-all;
+ white-space: nowrap;
+ }
+ .tree-text {
+ display: inline-block;
+ max-width: 300px; /* 根据实际容器宽度调整 */
+ white-space: nowrap; /* 强制不换行 */
+ overflow: hidden; /* 隐藏溢出 */
+ text-overflow: ellipsis; /* 显示省略号 */
+ }
+ /* 可选:移除el-tree默认的节点内边距 */
+ .el-tree-node__content {
+ padding-right: 5px;
+ }
+
+ .tree-container {
+ max-width: 600px;
+ margin-top: 20px;
+ height: 100%;
+ max-height: 1200px;
+ box-shadow: 8px 0 15px rgba(0,21,41,0.08);
+ overflow: auto; /* 确保出现滚动条 */
+ }
+
+ /* 隐藏默认滚动条 */
+ .tree-hide-scrollbar::-webkit-scrollbar {
+ width: 5px;
+ background-color: transparent;
+ }
+ .tree-hide-scrollbar::-webkit-scrollbar-thumb {
+ background-color: transparent;
+ border-radius: 4px;
+ }
+ /* 鼠标悬停时显示滚动条 */
+ .tree-hide-scrollbar:hover::-webkit-scrollbar-thumb {
+ background-color: #e1e1e1;
+ }
+ .tree-hide-scrollbar:hover::-webkit-scrollbar-track {
+ background-color: #f5f7fa;
+ }
+ .tree{
+ max-width: 600px;
+ margin-top: 20px;
+ height: 800px;
+ overflow-x: hidden;
+ box-shadow: 8px 0 15px rgba(0,21,41,0.08)
}
}
.right{
@@ -498,6 +690,20 @@
:deep(.el-form-item__label){
font-weight: 600;font-size: 20px
}
+ .reviewTable {
+ :deep(table){
+ border: 1px solid #ccc;
+ text-align: center;
+ }
+ :deep(table td){
+ border: 1px solid #ccc;
+ text-align: center;
+ padding: 0 5px;
+ }
+ :deep(table th){
+ border: 1px solid #ccc;
+ }
+ }
}
}
--
Gitblit v1.9.2