You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1271 lines
32 KiB

<template>
<div style="height: 100%">
<!-- 项目手册管理 -->
<!-- 表单查询项 -->
<div v-if="!previewMode" class="headerbox">
<el-form size="small" :inline="true" label-width="200">
<el-row>
<el-col :span="5">
<el-form-item label="手册名称" style="width: 100%;">
<el-input v-model="queryParams.name" placeholder="请输入手册名称" clearable />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="创建时间">
<el-date-picker
v-model="queryParams.startTime"
type="date"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<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-col>
</el-row>
</el-form>
</div>
<!-- 表格内容区 -->
<div v-if="!previewMode" class="tablebox">
<div class="tablebtntwo">
<!-- <el-button
type="primary"
icon="el-icon-plus"
2 months ago
:loading="exportLoading"
@click="handleExport"
>项目手册导出</el-button
> -->
<el-button
type="primary"
icon="el-icon-plus"
size="small"
@click="handleAdd"
>新增</el-button
>
</div>
<el-table v-loading="loading" :data="postList">
2 months ago
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column label="手册名称" align="center" prop="name" />
<el-table-column label="创建时间" align="center" prop="createTime" />
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
type="text"
2 months ago
style="color: #409eff"
@click="handlePreview(scope.row)"
>预览</el-button
>
<el-button
type="text"
style="color: #67c23a"
@click="handleEdit(scope.row)"
>编辑</el-button
>
<el-button
type="text"
style="color: #409eff"
@click="handleExport(scope.row.id)"
>项目手册导出</el-button
>
2 months ago
<el-button
type="text"
style="color: #f56c6c"
@click="handleDelete(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.current"
:limit.sync="queryParams.size"
@pagination="getList"
/>
</div>
<div v-if="previewMode" class="previewbox">
<div class="preview-header">
<div class="preview-title">
<i class="el-icon-document"></i>
<span>{{ previewData.name || "项目手册预览" }}</span>
</div>
<div class="preview-controls">
<div class="page-counter" v-if="pageCount > 0">
<span>{{ currentPage }} / {{ pageCount }}</span>
</div>
<el-button-group class="navigation-buttons">
<el-button
2 months ago
type="primary"
icon="el-icon-arrow-left"
:disabled="currentPage <= 1"
@click="prevPage"
>上一页</el-button
>
<el-button
2 months ago
type="primary"
icon="el-icon-arrow-right"
:disabled="currentPage >= pageCount"
@click="nextPage"
>下一页</el-button
>
</el-button-group>
<el-button
2 months ago
type="info"
icon="el-icon-back"
@click="previewMode = false"
>返回</el-button
>
</div>
</div>
<div class="preview-content" v-loading="loadingPdf">
<pdf
v-if="pdfData"
:src="pdfData"
:page="currentPage"
@num-pages="pageCount = $event"
@page-loaded="pageLoaded"
@loaded="pdfLoaded"
@error="pdfError"
:scale="pdfScale"
></pdf>
</div>
</div>
<!-- 创建新手册弹框 -->
<el-dialog
:title="editingHandbook ? '编辑手册' : '创建新手册'"
:visible.sync="addDialogVisible"
width="70%"
:close-on-click-modal="false"
:show-close="true"
:before-close="handleAddDialogClose"
class="handbook-dialog"
>
<div class="step-container">
<el-steps :active="activeStep" align-center finish-status="finish ">
<el-step title="封面设置"></el-step>
<el-step title="选择项目"></el-step>
<el-step title="封尾设计"></el-step>
</el-steps>
</div>
<!-- 步骤1封面设置 -->
<div v-if="activeStep === 1" class="step-content">
<div class="cover-form">
<div class="form-row">
<div class="form-col">
<label class="form-label">手册名称</label>
<el-input
v-model="coverForm.title"
placeholder="请输入"
></el-input>
</div>
<div class="form-col">
<label class="form-label">副标题</label>
<el-input
v-model="coverForm.subtitle"
placeholder="请输入"
></el-input>
</div>
</div>
<div class="form-row">
<div class="form-col-full">
<label class="form-label">封面图片</label>
<file-upload
v-model="coverForm.imageUrl"
:limit="1"
:file-size="10"
:file-type="['png', 'jpg', 'jpeg', 'gif']"
></file-upload>
</div>
</div>
</div>
</div>
<!-- 步骤2选择项目 -->
<div v-show="activeStep === 2" class="step-content project-step">
<div class="cover-form">
<div class="project-top">
<div class="search-container">
<div class="search-label">项目名称</div>
<el-input
v-model="projectSearch"
placeholder="请输入"
class="search-input"
></el-input>
<el-button
type="primary"
@click="searchProjects"
class="search-btn"
>查询</el-button
>
<el-button @click="resetProjectSearch" class="search-btn"
>重置</el-button
>
</div>
<div class="project-table">
<el-table
ref="projectTable"
:data="projectList"
@row-click="handleRowClick"
2 months ago
height="200"
:row-key="(row) => row.id"
v-loading="loading"
@select="handleSelect"
@select-all="handleSelectAll"
>
<el-table-column
type="selection"
width="55"
align="center"
:reserve-selection="true"
></el-table-column>
<el-table-column label="序号" width="60" align="center">
<template slot-scope="scope">{{ scope.$index + 1 }}</template>
</el-table-column>
<el-table-column
prop="name"
label="项目名称"
align="center"
></el-table-column>
<el-table-column
prop="xzfl"
label="现状分类"
align="center"
>
<template slot-scope="scope">
<dict-tag :options="dict.type.xzfl" :value="scope.row.xzfl"/>
</template>
</el-table-column>
<el-table-column
prop="xmfrdwxz"
label="项目法人单位"
align="center"
>
</el-table-column>
<el-table-column label="项目建设起止时间" align="center">
<template slot-scope="scope">
<span
>{{
scope.row.begainTime
? scope.row.begainTime.replace(/-/g, ".")
: ""
}}-{{
scope.row.endTime
? scope.row.endTime.replace(/-/g, ".")
: ""
}}</span
>
</template>
</el-table-column>
<el-table-column
prop="ztze"
label="总投资额(万元)"
align="center"
></el-table-column>
<el-table-column
prop="zydmj"
label="总用地面积(平方米)"
align="center"
></el-table-column>
</el-table>
<div class="pagination-box">
<pagination
v-show="projectTotal > 0"
:total="projectTotal"
:page.sync="projectParams.pageNum"
:limit.sync="projectParams.pageSize"
@pagination="handleProjectPagination"
/>
</div>
</div>
</div>
<div
class="selected-projects-container"
v-if="selectedProjects.length > 0"
>
<div class="selected-header">已选中项目</div>
<div class="selected-list">
<div
v-for="(project, index) in selectedProjects"
:key="index"
class="selected-item"
>
<div class="dot-indicator"></div>
<span class="project-name">{{ project.name }}</span>
<el-button
type="text"
icon="el-icon-close"
class="remove-btn"
@click="removeSelectedProject(project)"
></el-button>
</div>
</div>
</div>
</div>
</div>
<div v-if="activeStep === 3" class="step-content">
<div class="cover-form">
<div class="form-row">
<div class="form-col-full">
<label class="form-label">封尾图片</label>
<file-upload
v-model="endForm.imageUrl"
:limit="1"
:file-size="10"
:file-type="['png', 'jpg', 'jpeg', 'gif']"
></file-upload>
</div>
</div>
<div class="form-row">
<div class="form-col">
<label class="form-label">副标题</label>
<el-input
v-model="endForm.subtitle"
placeholder="请输入"
style="width: 60%"
></el-input>
</div>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="prevStep" v-if="activeStep > 1" size="small"
>上一步</el-button
>
<el-button
type="primary"
class="btn-next"
@click="nextStep"
v-if="activeStep < 3"
size="small"
>下一步</el-button
>
<el-button
type="primary"
class="btn-next"
@click="submitHandbook"
v-if="activeStep === 3"
size="small"
>{{ editingHandbook ? "更新手册" : "生成手册" }}</el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
import VueOfficeDocx from "@vue-office/docx";
import pdf from "vue-pdf";
import {
getHandbookPage,
addHandbook,
updateHandbook,
deleteHandbook,
getHandbookDetail,
exportHandbook,
getBasicInformationPage,
} from "@/api/ManageApi/index";
import FileUpload from "@/components/FileUpload3";
export default {
components: {
"vue-office-docx": VueOfficeDocx,
pdf: pdf,
Pagination: () => import("@/components/Pagination"),
FileUpload,
},
// 声明需要使用的字典
dicts: ['xzfl'],
data() {
return {
queryParams: {
current: 1,
size: 10,
name: "",
startTime: "",
},
allPostList: [],
postList: [],
loading: false,
total: 0,
previewMode: false,
previewData: {},
// DOCX文件数据
docxFileData: null,
addDialogVisible: false,
activeStep: 1,
coverForm: {
title: "",
subtitle: "",
imageUrl: "",
},
// 项目选择相关
projectSearch: "",
projectList: [],
selectedProjects: [],
projectParams: {
pageNum: 1,
pageSize: 10,
},
projectTotal: 0,
// 封尾设计
endForm: {
imageUrl: "",
subtitle: "",
},
// 导出相关
selectedRows: [],
exportLoading: false,
selectedProjectIds: [], // 新增存储选中项目的id
// PDF预览相关
pdfData: null,
currentPage: 1,
pageCount: 0,
loadingPdf: false,
pdfScale: 0.9, // 控制PDF缩放比例
editingHandbook: null, // 当前正在编辑的手册对象
};
},
mounted() {
this.getList();
},
methods: {
getList() {
this.loading = true;
getHandbookPage(this.queryParams)
.then((res) => {
this.postList = res.data.records;
this.total = res.data.total;
this.loading = false;
})
.catch(() => {
this.loading = false;
});
},
getHandbookDetail(id) {
getHandbookDetail(id)
.then((res) => {
this.previewData = res.data;
})
.catch(() => {
this.loading = false;
});
},
// 查询
handleQuery() {
this.queryParams.current = 1;
this.getList();
},
// 重置查询
resetQuery() {
this.queryParams = {
current: 1,
size: 10,
title: undefined,
startTime: undefined,
};
this.handleQuery();
},
// 预览文档
handlePreview(row) {
this.previewMode = true;
this.previewData = row;
this.currentPage = 1;
this.pageCount = 0;
this.loadingPdf = true;
this.loadPdfFromApi(row.id);
},
async loadPdfFromApi(id) {
try {
const res = await exportHandbook([id]);
if (!res) {
throw new Error("获取PDF文件失败返回为空");
}
const blob = new Blob([res], { type: "application/pdf" });
this.pdfData = URL.createObjectURL(blob);
} catch (error) {
this.$message.error("PDF加载失败: " + (error.message || "未知错误"));
this.loadingPdf = false;
}
},
pageLoaded() {
this.loadingPdf = false;
},
pdfLoaded() {
this.loadingPdf = false;
},
pdfError(error) {
this.$message.error("PDF渲染失败: " + (error.message || "未知错误"));
this.loadingPdf = false;
},
prevPage() {
if (this.currentPage > 1) {
this.currentPage--;
}
},
nextPage() {
if (this.currentPage < this.pageCount) {
this.currentPage++;
}
},
// 项目手册导出
async handleExport(id) {
try {
this.exportLoading = true;
// const idList = this.selectedRows.map((item) => item.id);
// const res = await exportHandbook(idList);
const res = await exportHandbook([id]);
this.$download.saveAs(res, "项目手册.pdf");
this.$message.success("导出成功");
} catch (error) {
this.$message.error("导出过程中发生错误");
} finally {
this.exportLoading = false;
}
},
handleAdd() {
this.addDialogVisible = true;
this.activeStep = 1;
this.resetAddForm();
this.editingHandbook = null;
this.selectedProjectIds = [];
this.selectedProjects = [];
this.projectParams.pageNum = 1 ;
this.getProjectList();
},
handleAddDialogClose(done) {
this.resetAddForm();
this.editingHandbook = null;
this.selectedProjectIds = [];
this.selectedProjects = [];
done();
},
resetAddForm() {
this.coverForm = {
title: "",
subtitle: "",
imageUrl: "",
};
this.projectSearch = "";
this.endForm = {
imageUrl: "",
subtitle: "",
};
},
nextStep() {
this.activeStep++;
},
prevStep() {
this.activeStep--;
},
getProjectList() {
this.loading = true;
const params = {
current: this.projectParams.pageNum,
size: this.projectParams.pageSize,
name: this.projectSearch || undefined,
};
getBasicInformationPage(params)
.then((response) => {
this.projectList = response.data.records;
this.projectTotal = response.data.total;
if (this.selectedProjectIds.length > 0) {
this.$nextTick(() => {
this.restoreSelection();
});
}
this.loading = false;
})
.catch((error) => {
this.loading = false;
this.$message.error("获取项目列表失败");
});
},
searchProjects() {
this.projectParams.pageNum = 1;
this.getProjectList();
},
resetProjectSearch() {
this.projectSearch = "";
this.projectParams.pageNum = 1;
this.getProjectList();
},
handleRowClick(row) {
this.$refs.projectTable.toggleRowSelection(row);
const selectedRows = this.$refs.projectTable.selection;
const isSelected = selectedRows.some(item => item.id === row.id);
if (isSelected) {
// 如果是选中状态,添加到已选项目中
if (!this.selectedProjectIds.includes(row.id)) {
this.selectedProjectIds.push(row.id);
this.selectedProjects.push(row);
}
} else {
// 如果是取消选中,从已选项目中移除
this.selectedProjectIds = this.selectedProjectIds.filter(id => id !== row.id);
this.selectedProjects = this.selectedProjects.filter(item => item.id !== row.id);
}
},
removeSelectedProject(project) {
// 从选择列表中移除项目
this.selectedProjects = this.selectedProjects.filter(
(item) => item.id !== project.id
);
this.selectedProjectIds = this.selectedProjectIds.filter(
(id) => id !== project.id
);
// 如果项目在当前页面,取消其选择状态
if (this.$refs.projectTable) {
const projectInCurrentPage = this.projectList.find(
(item) => item.id == project.id
);
if (projectInCurrentPage) {
this.$refs.projectTable.toggleRowSelection(
projectInCurrentPage,
false
);
}
}
},
handleProjectPagination() {
this.getProjectList();
},
// 恢复选中状态
restoreSelection() {
if (!this.$refs.projectTable) return;
this.$refs.projectTable.clearSelection();
if (!this.selectedProjectIds.length) return;
this.projectList.forEach((row) => {
if (this.selectedProjectIds.includes(row.id)) {
this.$refs.projectTable.toggleRowSelection(row, true);
}
});
},
// 提交生成手册
submitHandbook() {
if (this.selectedProjects.length === 0) {
this.$message.warning("请至少选择一个项目");
return;
}
2 months ago
const data = {};
if (this.coverForm.imageUrl) data.coverImg = this.coverForm.imageUrl;
if (this.coverForm.title) data.name = this.coverForm.title;
if (this.coverForm.subtitle) data.subtitle = this.coverForm.subtitle;
if (this.endForm.imageUrl) data.tailingImg = this.endForm.imageUrl;
if (this.endForm.subtitle) data.tail = this.endForm.subtitle;
if (this.selectedProjects && this.selectedProjects.length > 0) {
data.xmId = this.selectedProjects.map((project) => project.id).join(",");
}
if (this.editingHandbook) {
data.id = this.editingHandbook.id;
updateHandbook(data)
.then((res) => {
this.$message.success("手册更新成功");
this.addDialogVisible = false;
this.getList();
// 重置编辑状态
this.editingHandbook = null;
})
.catch(() => {
this.$message.error("手册更新失败");
});
} else {
// 新增模式
addHandbook(data)
.then((res) => {
this.$message.success("手册生成成功");
this.addDialogVisible = false;
this.getList();
})
.catch(() => {
this.$message.error("手册生成失败");
});
}
},
// 处理单个项目选择事件
handleSelect(selection, row) {
// 检查是选中还是取消选中
const isSelected = selection.some(item => item.id === row.id);
if (isSelected) {
// 如果是选中,添加到已选列表中
if (!this.selectedProjectIds.includes(row.id)) {
this.selectedProjectIds.push(row.id);
this.selectedProjects.push(row);
}
} else {
// 如果是取消选中,从已选列表中移除
this.selectedProjectIds = this.selectedProjectIds.filter(id => id !== row.id);
this.selectedProjects = this.selectedProjects.filter(item => item.id !== row.id);
}
},
// 处理全选/取消全选事件
handleSelectAll(selection) {
// 获取当前页面所有项目ID
const currentPageIds = this.projectList.map(item => item.id);
// 检查是全选还是取消全选
if (selection.length === 0) {
// 取消全选 - 从已选列表中移除当前页所有项目
this.selectedProjectIds = this.selectedProjectIds.filter(
id => !currentPageIds.includes(id)
);
this.selectedProjects = this.selectedProjects.filter(
project => !currentPageIds.includes(project.id)
);
} else {
// 全选 - 将当前页所有项目添加到已选列表
// 先移除当前页已有的选择,避免重复
const projectIdsNotInCurrentPage = this.selectedProjectIds.filter(
id => !currentPageIds.includes(id)
);
const projectsNotInCurrentPage = this.selectedProjects.filter(
project => !currentPageIds.includes(project.id)
);
// 合并不在当前页的选择和当前页所有项目
this.selectedProjectIds = [...projectIdsNotInCurrentPage, ...currentPageIds];
this.selectedProjects = [...projectsNotInCurrentPage, ...this.projectList];
}
},
// 编辑按钮操作
handleEdit(row) {
// 获取手册详情
this.loading = true;
getHandbookDetail(row.id)
.then((res) => {
const detail = res.data;
this.coverForm = {
title: detail.name,
subtitle: detail.subtitle,
imageUrl: detail.coverImg,
};
this.endForm = {
imageUrl: detail.tailingImg,
subtitle: detail.tail,
};
// 先清空选中状态
this.selectedProjectIds = [];
this.selectedProjects = [];
if (detail.xmId) {
const projectIds = detail.xmId.split(",");
this.selectedProjectIds = projectIds.map((id) => Number(id));
// 设置已选择的项目
if (detail.projectName && Array.isArray(detail.projectName)) {
this.selectedProjects = detail.projectName;
}
this.projectParams.pageNum = 1 ;
this.getProjectList();
}
this.loading = false;
this.addDialogVisible = true;
this.activeStep = 1;
this.editingHandbook = detail;
})
.catch(() => {
this.$message.error("获取手册详情失败");
this.loading = false;
});
},
// 删除按钮操作
handleDelete(row) {
this.$confirm("是否确认删除该手册?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
this.loading = true;
const idList = [row.id];
await deleteHandbook(idList).then(() => {
this.$message.success("删除成功");
this.getList();
});
this.loading = false;
})
.catch(() => {});
},
},
};
</script>
<style scoped lang="scss">
/* 通用容器样式 */
.headerbox,
.tablebox {
background-color: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
border: 1px solid #eee;
margin: 0.5rem;
.el-input {
flex: 1;
max-width: 100%;
}
}
.headerbox {
margin-bottom: 15px;
}
/* 表格样式 */
.tablebtntwo {
width: 100%;
display: flex;
2 months ago
justify-content: left;
margin: 10px 0 20px;
}
.tablebox ::v-deep .el-table {
border-radius: 4px;
overflow: hidden;
.el-table__header-wrapper th {
background-color: #f5f7fa;
color: #606266;
font-weight: 600;
padding: 12px 0;
}
2 months ago
// .el-table__row {
// // transition: all 0.2s;
2 months ago
// // &:hover {
// // background-color: #ecf5ff;
// // }
// }
.el-button--text {
padding: 0 5px;
font-weight: 500;
2 months ago
// transition: all 0.3s;
2 months ago
// &:hover {
// transform: scale(1.05);
// }
}
}
/* PDF预览区域样式 */
.previewbox {
height: calc(100% - 50px);
z-index: 1500;
display: flex;
flex-direction: column;
padding: 20px;
overflow: hidden;
animation: fadeIn 0.3s ease;
}
.preview-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background-color: #ffffff;
border-radius: 8px 8px 0 0;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
flex-shrink: 0;
}
.preview-title {
font-size: 18px;
font-weight: 600;
color: #303133;
display: flex;
align-items: center;
i {
margin-right: 10px;
color: #409eff;
font-size: 20px;
}
}
.preview-controls {
display: flex;
align-items: center;
gap: 15px;
}
.page-counter {
background-color: #ecf5ff;
padding: 6px 12px;
border-radius: 4px;
color: #409eff;
font-size: 14px;
font-weight: 500;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
min-width: 60px;
text-align: center;
}
.navigation-buttons {
display: flex;
gap: 10px;
.el-button {
padding: 7px 15px;
font-weight: 500;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
2 months ago
// transition: all 0.2s ease;
2 months ago
// &:hover:not([disabled]) {
// transform: translateY(-2px);
// box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
// }
&[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
}
}
.preview-content {
flex: 1;
overflow: auto;
background-color: #f5f7fa;
border-radius: 0 0 8px 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
display: flex;
justify-content: center;
position: relative;
width: 100%;
scrollbar-width: none;
span {
width: 100%;
height: 100%;
}
::v-deep canvas {
max-width: 100% !important;
height: auto !important;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
border-radius: 2px;
background-color: white;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 对话框样式 */
.handbook-dialog {
::v-deep .el-dialog__header {
background-color: #1890ff;
.el-dialog__title {
color: #fff;
}
}
::v-deep .el-dialog__headerbtn .el-dialog__close {
color: #fff;
}
::v-deep .el-step__icon {
width: 15px;
height: 15px;
font-size: 0;
border-radius: 50%;
position: relative;
z-index: 2;
border: 2px solid rgb(255, 255, 255);
box-shadow: 0 0 0 2px rgba(136, 137, 137, 0.1);
}
::v-deep {
.is-process {
color: #c0c4cc !important;
font-weight: normal !important;
.el-step__icon {
background: none !important;
background-color: #c0c4cc !important;
}
}
.is-finish .el-step__icon {
background: none !important;
background-color: #1890ff !important;
}
.is-wait .el-step__icon {
background: none !important;
background-color: #c0c4cc !important;
}
}
.el-dialog {
border-radius: 4px;
overflow: hidden;
}
.el-button--primary {
background-color: #1890ff;
border-color: #1890ff;
}
}
/* 表单样式 */
.form-label {
width: 70px;
text-align: right;
padding-right: 10px;
line-height: 32px;
color: #333;
font-size: 14px;
}
/* 表单布局样式 */
.cover-form {
width: 100%;
max-width: 1200px;
}
.form-row {
display: flex;
margin-bottom: 60px;
justify-content: space-around;
@media (max-width: 768px) {
flex-direction: column;
}
}
.form-col {
flex: 1;
margin-right: 20px;
&:last-child {
margin-right: 0;
}
@media (max-width: 768px) {
margin-right: 0;
margin-bottom: 16px;
}
}
.form-col-full {
width: 100%;
}
/* 项目选择区域样式 */
.project-top {
border: 1px solid #1890ff;
padding: 15px 15px 0px 15px;
border-radius: 4px;
margin-bottom: 10px;
}
.search-container {
display: flex;
align-items: center;
margin-bottom: 16px;
background-color: #fff;
}
.search-label {
font-size: 14px;
color: #606266;
margin-right: 8px;
}
.search-input,
.search-date {
width: 30%;
transition: all 0.3s;
margin-right: 30px;
::v-deep .el-input {
flex: 1!important;
max-width: 100%!important;
}
::v-deep .el-input__inner {
width: 100%!important;
}
&:hover {
box-shadow: 0 0 0 1px #409eff;
}
}
.search-btn {
margin-right: 8px;
}
.project-table {
border-radius: 4px;
overflow: hidden;
margin-bottom: 20px;
::v-deep .el-table {
max-height: 400px;
overflow-y: auto;
.el-table__body-wrapper {
overflow-y: auto;
}
.el-table__row {
cursor: pointer;
&:hover {
background-color: #f5f7fa;
}
}
}
}
.pagination-box {
display: flex;
justify-content: right;
2 months ago
// margin: 16px 0;
}
/* 已选项目区域样式 */
.selected-projects-container {
border: 1px solid #1890ff;
padding: 15px 15px 10px 15px;
border-radius: 4px;
2 months ago
max-height: 300px;
display: flex;
flex-direction: column;
}
.selected-header {
font-size: 15px;
font-weight: 500;
color: #333;
margin-bottom: 15px;
}
.selected-list {
display: flex;
flex-direction: column;
gap: 12px;
2 months ago
max-height: 100px;
2 months ago
overflow-y: auto;
padding-right: 10px;
flex: 1;
/* 自定义滚动条样式 */
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb {
background: #c0c4cc;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb:hover {
background: #909399;
}
}
.selected-item {
display: flex;
align-items: center;
padding: 8px 15px;
background-color: #f8f8f8;
border-radius: 4px;
position: relative;
transition: all 0.2s;
&:hover {
background-color: #f0f0f0;
.remove-btn {
opacity: 1;
}
}
}
.dot-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #409eff;
margin-right: 10px;
}
.project-name {
flex: 1;
color: #333;
}
.remove-btn {
opacity: 0.5;
transition: all 0.2s;
color: #909399;
padding: 2px;
margin-left: 8px;
&:hover {
color: #F56C6C;
opacity: 1;
transform: scale(1.1);
}
}
/* 步骤内容区域样式 */
.step-content {
padding: 10px 10%;
min-height: 400px;
}
::v-deep .el-dialog__body {
padding: 20px 15px !important;
}
</style>