Commit 8605b4da by cat

zd

parent d3b7283d
import request from "@/utils/request"; import request from '@/utils/request'
// 简单去重:相同 id 的详情请求在同一时刻仅发起一次 // 简单去重:相同 id 的详情请求在同一时刻仅发起一次
const inFlightDetailMap = new Map(); const inFlightDetailMap = new Map()
// 查询会议信息列表 // 查询会议信息列表
export function listHyjyxx(query) { export function listHyjyxx(query) {
return request({ return request({
url: "/hyjyxx/hyjyxx/list", url: '/hyjyxx/hyjyxx/list',
method: "get", method: 'get',
params: query, params: query,
}); })
} }
// 查询会议信息详细 // 查询会议信息详细
export function getHyjyxx(id) { export function getHyjyxx(id) {
const key = String(id); const key = String(id)
if (inFlightDetailMap.has(key)) { if (inFlightDetailMap.has(key)) {
return inFlightDetailMap.get(key); return inFlightDetailMap.get(key)
} }
const p = request({ const p = request({
url: "/hyjyxx/hyjyxx/" + id, url: '/hyjyxx/hyjyxx/hyxx/' + id,
method: "get", // url: "/hyjyxx/hyjyxx/" + id,
method: 'get',
}).finally(() => { }).finally(() => {
// 请求结束后清理,允许后续新的刷新 // 请求结束后清理,允许后续新的刷新
inFlightDetailMap.delete(key); inFlightDetailMap.delete(key)
}); })
inFlightDetailMap.set(key, p); inFlightDetailMap.set(key, p)
return p; return p
} }
// 新增会议信息 // 新增会议信息
export function addHyjyxx(data) { export function addHyjyxx(data) {
return request({ return request({
url: "/hyjyxx/hyjyxx", url: '/hyjyxx/hyjyxx',
method: "post", method: 'post',
data: data, data: data,
}); })
} }
// 修改会议信息 // 修改会议信息
export function updateHyjyxx(data) { export function updateHyjyxx(data) {
return request({ return request({
url: "/hyjyxx/hyjyxx", url: '/hyjyxx/hyjyxx',
method: "put", method: 'put',
data: data, data: data,
}); })
} }
// 删除会议信息 // 删除会议信息
export function delHyjyxx(id) { export function delHyjyxx(id) {
return request({ return request({
url: "/hyjyxx/hyjyxx/" + id, url: '/hyjyxx/hyjyxx/' + id,
method: "delete", method: 'delete',
}); })
} }
//下拉框 //下拉框
export function getHyjyxxAll() { export function getHyjyxxAll() {
return request({ return request({
url: "/hyjyxxMb/hymb/selectHybm", url: '/hyjyxxMb/hymb/selectHybm',
method: "get", method: 'get',
}); })
} }
// 开始转录 // 开始转录
export function startConvert(id) { export function startConvert(id) {
return request({ return request({
url: `/hyjyxx/hyjyxx/hyzl/${id}`, url: `/hyjyxx/hyjyxx/hyzl/${id}`,
method: "post", method: 'post',
}); })
} }
import request from '@/utils/request'
// 查询会议纪要_附件列表
export function listFile(query) {
return request({
url: '/hyjyxxFile/file/list',
method: 'get',
params: query
})
}
// 查询会议纪要_附件详细
export function getFile(id) {
return request({
url: '/hyjyxxFile/file/' + id,
method: 'get'
})
}
// 新增会议纪要_附件
export function addFile(data) {
return request({
url: '/hyjyxxFile/file',
method: 'post',
data: data
})
}
// 修改会议纪要_附件
export function updateFile(data) {
return request({
url: '/hyjyxxFile/file',
method: 'put',
data: data
})
}
// 删除会议纪要_附件
export function delFile(id) {
return request({
url: '/hyjyxxFile/file/' + id,
method: 'delete'
})
}
import request from "@/utils/request"; import request from '@/utils/request'
// 查询验收前期-项目信息列表 // 查询验收前期-项目信息列表
export function listYsqqXmxx(query) { export function listYsqqXmxx(query) {
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx/list", url: '/ysqqXmxx/ysqqXmxx/list',
method: "get", method: 'get',
params: query, params: query,
}); })
} }
// 查询验收前期-项目信息详细 // 查询验收前期-项目信息详细
export function getYsqqXmxx(id) { export function getYsqqXmxx(id) {
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx/" + id, url: '/ysqqXmxx/ysqqXmxx/' + id,
method: "get", method: 'get',
}); })
} }
// 新增验收前期-项目信息 // 新增验收前期-项目信息
export function addYsqqXmxx(data) { export function addYsqqXmxx(data) {
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx", url: '/ysqqXmxx/ysqqXmxx',
method: "post", method: 'post',
data: data, data: data,
}); })
} }
// 修改验收前期-项目信息 // 修改验收前期-项目信息
export function updateYsqqXmxx(data) { export function updateYsqqXmxx(data) {
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx", url: '/ysqqXmxx/ysqqXmxx',
method: "put", method: 'put',
data: data, data: data,
}); })
} }
// 删除验收前期-项目信息 // 删除验收前期-项目信息
export function delYsqqXmxx(id) { export function delYsqqXmxx(id) {
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx/" + id, url: '/ysqqXmxx/ysqqXmxx/' + id,
method: "delete", method: 'delete',
}); })
} }
//提交按钮 //提交按钮
export function startConvert(id) { export function startConvert(id) {
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx/toDys/" + id, url: '/ysqqXmxx/ysqqXmxx/toDys/' + id,
method: "post", method: 'post',
}); })
} }
//撤回按钮 //撤回按钮
export function withdraw(id) { export function withdraw(id) {
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx/toWtj/" + id, url: '/ysqqXmxx/ysqqXmxx/toWtj/' + id,
method: "post", method: 'post',
}); })
} }
export function toDht(id) { export function toDht(id) {
// 参数验证:确保 id 有效
if (!id || id === 'null' || id === 'undefined' || String(id).trim() === '') {
return Promise.reject(new Error('无效的ID参数'))
}
return request({ return request({
url: "/ysqqXmxx/ysqqXmxx/dht/" + id, url: '/ysqqXmxx/ysqqXmxx/dht/' + id,
method: "get", method: 'get',
}); })
} }
...@@ -102,6 +102,19 @@ export const constantRoutes = [ ...@@ -102,6 +102,19 @@ export const constantRoutes = [
], ],
}, },
{ {
path: '/hyjyxxFile',
component: Layout,
hidden: true,
children: [
{
path: 'file/index',
component: () => import('@/views/hyjyxxFile/file/index'),
name: 'HyjyxxFileIndex',
meta: { title: '会议纪要附件', activeMenu: '/hyjyxx/hyjyxx' },
},
],
},
{
path: '/ysqqXmxxJxx/jxx', path: '/ysqqXmxxJxx/jxx',
component: Layout, component: Layout,
hidden: true, hidden: true,
......
...@@ -7,17 +7,26 @@ ...@@ -7,17 +7,26 @@
</div> </div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="16">
<el-card shadow="never" <el-card shadow="never"
body-style="padding: 12px; height: calc(100vh - 220px); overflow: hidden; display: flex; flex-direction: column;background-color:#f6f8fa "> body-style="padding: 12px; height: calc(100vh - 220px); overflow: hidden; display: flex; flex-direction: column;background-color:#f6f8fa ">
<div style="font-weight: 600; margin-bottom: 8px;">转录文本</div> <div style="font-weight: 600; margin-bottom: 8px;">转录文本</div>
<div class="transcript-area flex-scroll" style="margin-left: 10px;"> <div class="transcript-area flex-scroll" style="margin-left: 10px;">
<div style="padding-bottom: 10px;"> <div style="padding-bottom: 10px;">
<div v-for="(segment, index) in transcriptList" :key="index" placement="top"> <div v-for="(segment, index) in transcriptList" :key="index" placement="top" style="margin-bottom: 15px;">
<!-- start: 发言人头部信息 -->
<div class="seg-header"> <div class="seg-header">
<span style="color: #000000; margin-right: 6px;">{{ segment.speaker }}</span> <span class="speaker-name">{{ segment.speaker }}</span>
<span style="color: #C0C4CC;">{{ segment.timestamp || segment.time }}</span> <span class="time-badge time-start">
<i class="el-icon-time"></i>
<span class="time-value">{{ segment.timestamp || segment.time }}</span>
</span>
<span v-if="segment.realTime" class="time-badge time-end">
<i class="el-icon-time"></i>
<span class="time-value">{{ segment.realTime }}</span>
</span>
</div> </div>
<!-- end: 发言人头部信息 -->
<div class="seg-body"> <div class="seg-body">
<el-avatar :class="getAvatarClass(getSpeakerIndex(segment.speaker))"> <el-avatar :class="getAvatarClass(getSpeakerIndex(segment.speaker))">
<img :src="getSpeakerIcon(getSpeakerIndex(segment.speaker))" <img :src="getSpeakerIcon(getSpeakerIndex(segment.speaker))"
...@@ -29,6 +38,20 @@ ...@@ -29,6 +38,20 @@
title="点击跳转到该时间播放">{{ title="点击跳转到该时间播放">{{
segment.content segment.content
|| segment.text }}</div> || segment.text }}</div>
<!-- start: 图片展示区域 -->
<div v-if="segment.file && segment.file.length > 0" class="seg-images">
<el-image
v-for="(imgUrl, imgIndex) in segment.file"
:key="imgIndex"
:src="getImageUrl(imgUrl)"
:preview-src-list="getPreviewImageList(segment.file)"
:initial-index="imgIndex"
fit="cover"
class="seg-image-item"
lazy>
</el-image>
</div>
<!-- end: 图片展示区域 -->
</div> </div>
</div> </div>
</div> </div>
...@@ -39,7 +62,7 @@ ...@@ -39,7 +62,7 @@
</div> </div>
</el-card> </el-card>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="8">
<el-card shadow="never" body-style="padding: 12px; height: calc(100vh - 220px); overflow: auto;"> <el-card shadow="never" body-style="padding: 12px; height: calc(100vh - 220px); overflow: auto;">
<div <div
style="display:flex; align-items:center; justify-content: space-between; margin-bottom: 12px;"> style="display:flex; align-items:center; justify-content: space-between; margin-bottom: 12px;">
...@@ -163,6 +186,27 @@ export default { ...@@ -163,6 +186,27 @@ export default {
const base = process.env.VUE_APP_BASE_API || '' const base = process.env.VUE_APP_BASE_API || ''
return `${base}${path}` return `${base}${path}`
}, },
/**
* 获取图片完整URL
* @param {string} path - 图片路径
* @returns {string} 完整URL
*/
getImageUrl(path) {
if (!path) return ''
// 绝对地址直接返回,相对地址补全网关前缀
if (/^https?:\/\//i.test(path)) return path
const base = process.env.VUE_APP_BASE_API || ''
return `${base}${path}`
},
/**
* 获取预览图片列表(用于图片预览功能)
* @param {Array} fileList - 文件路径数组
* @returns {Array} 完整URL数组
*/
getPreviewImageList(fileList) {
if (!Array.isArray(fileList) || fileList.length === 0) return []
return fileList.map(path => this.getImageUrl(path))
},
load() { load() {
if (!this.id) return if (!this.id) return
if (this._loadedId === this.id) { if (this._loadedId === this.id) {
...@@ -296,12 +340,84 @@ export default { ...@@ -296,12 +340,84 @@ export default {
.seg-header { .seg-header {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 6px; gap: 8px;
flex-wrap: nowrap; flex-wrap: wrap;
white-space: nowrap;
margin-bottom: 8px; margin-bottom: 8px;
} }
/* 发言人名称样式 */
.speaker-name {
color: #303133;
font-weight: 600;
font-size: 14px;
margin-right: 4px;
}
/* 时间标签容器 */
.time-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
line-height: 1;
transition: all 0.3s;
margin-left: -4px;
}
/* 开始时间样式 */
.time-start {
background-color: #ecf5ff;
color: #409eff;
border: 1px solid #b3d8ff;
}
.time-start i {
font-size: 12px;
}
.time-start .time-label {
color: #66b1ff;
font-weight: 500;
}
.time-start .time-value {
color: #409eff;
font-weight: 600;
}
/* 结束时间样式 */
.time-end {
background-color: #f0f9ff;
/* color: #67c23a;
border: 1px solid #c2e7b0; */
color: #ff0000;
border: 1px solid #e7b0b0;
}
.time-end i {
font-size: 12px;
}
.time-end .time-label {
color: #f47777;
/* color: #85ce61; */
font-weight: 500;
}
.time-end .time-value {
color: #ec5656;
/* color: #67c23a; */
font-weight: 600;
}
/* 时间标签悬浮效果 */
.time-badge:hover {
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* 下方头像 + 内容布局 */ /* 下方头像 + 内容布局 */
.seg-body { .seg-body {
display: flex; display: flex;
...@@ -348,7 +464,7 @@ export default { ...@@ -348,7 +464,7 @@ export default {
border: 1px solid #ebeef5; border: 1px solid #ebeef5;
border-radius: 8px; border-radius: 8px;
padding: 8px 10px; padding: 8px 10px;
margin-left: 10px; margin-left:22px;
flex: 1 1 auto; flex: 1 1 auto;
} }
...@@ -357,6 +473,29 @@ export default { ...@@ -357,6 +473,29 @@ export default {
background-color: #f0f8ff; background-color: #f0f8ff;
} }
/* 图片展示区域 */
.seg-images {
margin-top: 10px;
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.seg-image-item {
width: 35px;
height: 35px;
border-radius: 4px;
overflow: hidden;
cursor: pointer;
border: 1px solid #ebeef5;
transition: all 0.3s;
}
.seg-image-item:hover {
border-color: #409EFF;
transform: scale(1.02);
}
/* 11种可区分的颜色,按发言人编号映射 */ /* 11种可区分的颜色,按发言人编号映射 */
.avatar-color-1 { .avatar-color-1 {
color: #14a1ff; color: #14a1ff;
......
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
</el-table-column> </el-table-column>
<el-table-column label="音频文件名称" align="center" prop="ypwjName" min-width="140" show-overflow-tooltip /> <el-table-column label="音频文件名称" align="center" prop="ypwjName" min-width="140" show-overflow-tooltip />
<el-table-column label="会议模版名称" align="center" prop="mbmc" min-width="140" show-overflow-tooltip /> <el-table-column label="会议模版名称" align="center" prop="mbmc" min-width="140" show-overflow-tooltip />
<el-table-column label="会议开始时间" align="center" prop="jxwcsj" width="180"> <el-table-column label="音频开始时间" align="center" prop="jxwcsj" width="180">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.jxwcsj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <span>{{ parseTime(scope.row.jxwcsj, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template> </template>
...@@ -104,13 +104,14 @@ ...@@ -104,13 +104,14 @@
<el-table-column label="备用1" align="center" prop="ext1" /> <el-table-column label="备用1" align="center" prop="ext1" />
<el-table-column label="备用2" align="center" prop="ext2" /> <el-table-column label="备用2" align="center" prop="ext2" />
<el-table-column label="备用3" align="center" prop="ext3" /> --> <el-table-column label="备用3" align="center" prop="ext3" /> -->
<el-table-column label="操作" min-width="120" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" min-width="200" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['hyjyxx:hyjyxx:edit']">修改</el-button> v-hasPermi="['hyjyxx:hyjyxx:edit']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['hyjyxx:hyjyxx:remove']">删除</el-button> v-hasPermi="['hyjyxx:hyjyxx:remove']">删除</el-button>
<el-button size="mini" type="text" icon="el-icon-bottom-right" @click="handleKszr(scope.row)">开始转录</el-button> <el-button size="mini" type="text" icon="el-icon-bottom-right" @click="handleKszr(scope.row)">开始转录</el-button>
<el-button size="mini" type="text" icon="el-icon-document" @click="handleHyjyxxFile(scope.row)">截图管理</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
...@@ -150,7 +151,7 @@ ...@@ -150,7 +151,7 @@
<!-- <el-form-item label="会议纪要" prop="hyjy"> <!-- <el-form-item label="会议纪要" prop="hyjy">
<el-input v-model="form.hyjy" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.hyjy" type="textarea" placeholder="请输入内容" />
</el-form-item> --> </el-form-item> -->
<el-form-item label="会议开始时间" prop="jxwcsj"> <el-form-item label="音频开始时间" prop="jxwcsj">
<el-date-picker clearable v-model="form.jxwcsj" type="datetime" format="yyyy-MM-dd HH:mm:ss" <el-date-picker clearable v-model="form.jxwcsj" type="datetime" format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择会议开始时间" style="width: 100%;"> placeholder="请选择会议开始时间" style="width: 100%;">
</el-date-picker> </el-date-picker>
...@@ -238,6 +239,18 @@ export default { ...@@ -238,6 +239,18 @@ export default {
form: {}, form: {},
// 表单校验 // 表单校验
rules: { rules: {
hymc: [
{ required: true, message: "会议名称不能为空", trigger: "blur" }
],
ypwj: [
{ required: true, message: "会议音频文件不能为空", trigger: "change" }
],
mbmc: [
{ required: true, message: "会议模版不能为空", trigger: "change" }
],
jxwcsj: [
{ required: true, message: "音频开始时间不能为空", trigger: "change" }
]
} }
} }
}, },
...@@ -431,6 +444,14 @@ export default { ...@@ -431,6 +444,14 @@ export default {
this.download('hyjyxx/hyjyxx/export', { this.download('hyjyxx/hyjyxx/export', {
...this.queryParams ...this.queryParams
}, `hyjyxx_${new Date().getTime()}.xlsx`) }, `hyjyxx_${new Date().getTime()}.xlsx`)
},
/** 截图管理按钮操作 */
handleHyjyxxFile(row) {
if (!row || !row.id) {
this.$modal.msgError("未找到会议ID")
return
}
this.$router.push({ path: `/hyjyxxFile/file/index`, query: { hyid: row.id } })
} }
} }
} }
......
<template>
<div class="app-container">
<!-- <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="主键" prop="id">
<el-input
v-model="queryParams.id"
placeholder="请输入主键"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="会议id" prop="hyid">
<el-input
v-model="queryParams.hyid"
placeholder="请输入会议id"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="附件名字" prop="fileName">
<el-input
v-model="queryParams.fileName"
placeholder="请输入附件名字"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="附件时间" prop="fileTime">
<el-date-picker clearable
v-model="queryParams.fileTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择附件时间">
</el-date-picker>
</el-form-item>
<el-form-item label="创建人" prop="createdBy">
<el-input
v-model="queryParams.createdBy"
placeholder="请输入创建人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间" prop="createdTime">
<el-date-picker clearable
v-model="queryParams.createdTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择创建时间">
</el-date-picker>
</el-form-item>
<el-form-item label="备用1" prop="ext1">
<el-input
v-model="queryParams.ext1"
placeholder="请输入备用1"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="备用2" prop="ext2">
<el-input
v-model="queryParams.ext2"
placeholder="请输入备用2"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="备用3" prop="ext3">
<el-input
v-model="queryParams.ext3"
placeholder="请输入备用3"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form> -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['hyjyxxFile:file:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['hyjyxxFile:file:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['hyjyxxFile:file:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['hyjyxxFile:file:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="fileList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="60" align="center" />
<el-table-column label="缩略图" align="center">
<template slot-scope="scope">
<el-image
v-if="scope.row.fileUrl"
:src="getImageUrl(scope.row.fileUrl)"
:preview-src-list="[getImageUrl(scope.row.fileUrl)]"
fit="cover"
style="width: 80px; height: 80px; cursor: pointer;"
lazy
>
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
<span v-else>暂无图片</span>
</template>
</el-table-column>
<el-table-column label="附件时间" align="center" prop="fileTime" width="280">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.fileTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['hyjyxxFile:file:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['hyjyxxFile:file:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改会议纪要_附件对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<!-- 图片上传 -->
<el-form-item label="附件图片" prop="fileUrl">
<el-upload
:headers="upload.headers"
:action="upload.url"
:auto-upload="true"
accept="image/*"
:on-success="handleImageSuccess"
:on-error="handleImageError"
:on-remove="handleImageRemove"
:on-change="handleImageChange"
:file-list="imageFileList"
list-type="picture-card"
>
<i class="el-icon-plus"></i>
<div slot="tip" class="el-upload__tip">支持 jpg/png/gif 格式,大小不超过 10MB(上传新文件将自动替换已有文件)</div>
</el-upload>
</el-form-item>
<!-- 附件时间 -->
<el-form-item label="附件时间" prop="fileTime">
<el-date-picker
clearable
v-model="form.fileTime"
type="datetime"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择附件时间"
style="width: 100%;"
>
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listFile, getFile, delFile, addFile, updateFile } from "@/api/hyjyxxFile/file"
import { getToken } from "@/utils/auth"
export default {
name: "File",
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 会议纪要_附件表格数据
fileList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 图片上传配置
upload: {
headers: { Authorization: "Bearer " + getToken() },
url: process.env.VUE_APP_BASE_API + "/common/upload"
},
// el-upload 图片文件列表(用于编辑时回显)
imageFileList: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
id: null,
hyid: null,
fileUrl: null,
fileName: null,
fileTime: null,
createdBy: null,
createdTime: null,
ext1: null,
ext2: null,
ext3: null
},
// 表单参数
form: {},
// 表单校验
rules: {
fileUrl: [
{ required: true, message: "请上传附件图片", trigger: "change" }
],
fileTime: [
{ required: true, message: "请选择附件时间", trigger: "change" }
]
}
}
},
created() {
// 获取路由参数中的hyid,用于过滤数据
if (this.$route.query.hyid) {
this.queryParams.hyid = this.$route.query.hyid
}
this.getList()
},
methods: {
/** 查询会议纪要_附件列表 */
getList() {
this.loading = true
listFile(this.queryParams).then(response => {
this.fileList = response.rows
this.total = response.total
this.loading = false
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: null,
hyid: null,
fileUrl: null,
fileName: null,
fileTime: null,
createdBy: null,
createdTime: null,
updateBy: null,
updateTime: null,
ext1: null,
ext2: null,
ext3: null
}
this.resetForm("form")
this.imageFileList = []
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
// 如果存在hyid参数,自动填充到表单中
if (this.queryParams.hyid) {
this.form.hyid = this.queryParams.hyid
}
this.open = true
this.title = "添加会议纪要附件"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getFile(id).then(response => {
this.form = response.data
// 回显已上传的图片
this.imageFileList = []
if (this.form && this.form.fileUrl) {
this.imageFileList = [{
name: this.form.fileName || this.getFileName(this.form.fileUrl),
url: this.getImageUrl(this.form.fileUrl)
}]
}
this.open = true
this.title = "修改会议纪要附件"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
const payload = { ...this.form }
// 如果附件时间是Date对象,转换为字符串
if (payload.fileTime instanceof Date) {
payload.fileTime = this.parseTime(payload.fileTime, '{y}-{m}-{d} {h}:{i}:{s}')
}
if (this.form.id != null) {
updateFile(payload).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addFile(payload).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
// 图片上传成功
handleImageSuccess(response, file) {
if (response && response.code === 200) {
// 后端返回的文件名或url字段可能为 fileName/url
this.form.fileUrl = response.fileName || response.url || ""
// 取文件名用于显示/保存到 fileName
this.form.fileName = response.originalFilename || ""
// 更新图片文件列表中的URL(on-change已经更新了文件列表,这里只需要更新URL)
if (this.imageFileList.length > 0) {
const latestFile = this.imageFileList[this.imageFileList.length - 1]
latestFile.url = this.getImageUrl(this.form.fileUrl)
}
this.$modal.msgSuccess("上传成功")
} else {
this.$modal.msgError((response && response.msg) || "上传失败")
}
},
// 图片上传失败
handleImageError() {
this.$modal.msgError("上传失败,请重试")
},
// 图片移除(用于自动替换时清空旧文件)
handleImageRemove() {
this.form.fileUrl = null
this.form.fileName = null
this.imageFileList = []
},
// 图片文件状态改变(实现自动替换)
handleImageChange(file, fileList) {
// 如果文件列表超过1个,只保留最新的文件
if (fileList.length > 1) {
this.imageFileList = [fileList[fileList.length - 1]]
} else {
this.imageFileList = fileList
}
},
// 获取图片绝对地址
getImageUrl(path) {
if (!path) return ""
if (/^https?:\/\//i.test(path)) return path
const base = process.env.VUE_APP_BASE_API || ""
return `${base}${path}`
},
getFileName(fullPath) {
if (!fullPath) return ""
const idx = fullPath.lastIndexOf('/')
return idx >= 0 ? fullPath.slice(idx + 1) : fullPath
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除会议纪要_附件编号为"' + ids + '"的数据项?').then(function() {
return delFile(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('hyjyxxFile/file/export', {
...this.queryParams
}, `file_${new Date().getTime()}.xlsx`)
}
}
}
</script>
\ No newline at end of file
...@@ -304,14 +304,6 @@ export default { ...@@ -304,14 +304,6 @@ export default {
lineStyle: { color: '#00aa66', width: 2 }, lineStyle: { color: '#00aa66', width: 2 },
tooltip: { show: false } tooltip: { show: false }
}) })
// 调试:在每条线之上叠加小点,便于核对路径
series.push({
type: 'scatter',
data: line,
symbolSize: 3,
itemStyle: { color: '#888' },
tooltip: { show: false }
})
} }
// 垂直参考线(可选) // 垂直参考线(可选)
if (this.verticalLineX != null && this.yMin != null && this.yMax != null) { if (this.verticalLineX != null && this.yMin != null && this.yMax != null) {
...@@ -362,7 +354,37 @@ export default { ...@@ -362,7 +354,37 @@ export default {
} }
} : { type: 'value', min: this.yMin, max: this.yMax, scale: false, axisLine: { show: true }, axisTick: { show: true }, axisLabel: { color: '#666' }, splitLine: { show: true, lineStyle: { color: '#9bb3e7', opacity: 0.6 } } }, } : { type: 'value', min: this.yMin, max: this.yMax, scale: false, axisLine: { show: true }, axisTick: { show: true }, axisLabel: { color: '#666' }, splitLine: { show: true, lineStyle: { color: '#9bb3e7', opacity: 0.6 } } },
series, series,
tooltip: { trigger: 'item' } // 提示框
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(33, 41, 54, 0.95)',
borderColor: '#1f6feb',
borderWidth: 0,
padding: [8, 10],
textStyle: { color: '#fff', fontSize: this.compact ? 10 : 12, fontWeight: 500 },
extraCssText: 'box-shadow: 0 6px 16px rgba(0,0,0,.20); border-radius: 8px;',
formatter: params => {
const formatNum = n => {
if (n == null || isNaN(n)) return '-'
return Number(n).toLocaleString('zh-CN')
}
if (params && params.seriesType === 'scatter') {
const d = params.data || []
const name = d[2] || ''
const x = d[0]
const y = d[1]
return (name ? name + '<br/>' : '') + `X:${formatNum(x)}<br/>Y:${formatNum(y)}`
}
if (params && params.seriesType === 'line') {
const d = params.data || []
const x = d[0]
const y = d[1]
return `X:${formatNum(x)}<br/>Y:${formatNum(y)}`
}
const v = Array.isArray(params && params.value) ? params.value[1] : (params && params.value)
return v != null ? formatNum(v) : ''
}
}
} }
}, },
// 渲染或更新图表 // 渲染或更新图表
...@@ -384,15 +406,15 @@ export default { ...@@ -384,15 +406,15 @@ export default {
// 如果有井点散点,最前面占 1 个 series // 如果有井点散点,最前面占 1 个 series
const hasPoints = Array.isArray(this.points) && this.points.length > 0 const hasPoints = Array.isArray(this.points) && this.points.length > 0
const base = hasPoints ? 1 : 0 const base = hasPoints ? 1 : 0
// 每条线我们 push 了两个 series:line 和一个灰色散点 // 现在每条 SEGY 线只对应一个 line series
if (seriesIndex < base) return -1 if (seriesIndex < base) return -1
const offset = seriesIndex - base const offset = seriesIndex - base
// 偶数 -> 折线;奇数 -> 叠加的灰色散点 if (offset < 0 || offset >= this.segyLines.length) return -1
return Math.floor(offset / 2) return offset
} }
const emitPick = (params) => { const emitPick = (params) => {
if (!params || (params.seriesType !== 'line' && params.seriesType !== 'scatter')) return if (!params || params.seriesType !== 'line') return
const idx = getLineIndexBySeries(params.seriesIndex) const idx = getLineIndexBySeries(params.seriesIndex)
if (idx >= 0 && idx < this.segyLines.length) { if (idx >= 0 && idx < this.segyLines.length) {
this.$emit('segyLinePick', { index: idx }) this.$emit('segyLinePick', { index: idx })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment