Commit 4999bad8 by liangzhen

多标签路由

1 parent 13af0300
Showing with 851 additions and 883 deletions
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<svg
:class="{'is-active':isActive}"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
</div>
</template>
<script>
export default {
name: 'Hamburger',
props: {
isActive: {
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit('toggleClick')
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
vertical-align: middle;
width: 20px;
height: 20px;
}
.hamburger.is-active {
transform: rotate(180deg);
}
</style>
<template>
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
<slot />
</el-scrollbar>
</template>
<script>
const tagAndTagSpacing = 4 // tagAndTagSpacing
export default {
name: 'ScrollPane',
data() {
return {
left: 0
}
},
computed: {
scrollWrapper() {
return this.$refs.scrollContainer.$refs.wrap
}
},
methods: {
handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 40
const $scrollWrapper = this.scrollWrapper
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
},
moveToTarget(currentTag) {
const $container = this.$refs.scrollContainer.$el
const $containerWidth = $container.offsetWidth
const $scrollWrapper = this.scrollWrapper
const tagList = this.$parent.$refs.tag
let firstTag = null
let lastTag = null
// find first tag and last tag
if (tagList.length > 0) {
firstTag = tagList[0]
lastTag = tagList[tagList.length - 1]
}
if (firstTag === currentTag) {
$scrollWrapper.scrollLeft = 0
} else if (lastTag === currentTag) {
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
} else {
// find preTag and nextTag
const currentIndex = tagList.findIndex(item => item === currentTag)
const prevTag = tagList[currentIndex - 1]
const nextTag = tagList[currentIndex + 1]
// the tag's offsetLeft after of nextTag
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
// the tag's offsetLeft before of prevTag
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
}
}
}
}
}
</script>
<style lang="scss" scoped>
.scroll-container {
white-space: nowrap;
position: relative;
overflow: hidden;
width: 100%;
/deep/ {
.el-scrollbar__bar {
bottom: 0px;
}
.el-scrollbar__wrap {
height: 49px;
}
}
}
</style>
<template>
<div id="tags-view-container" class="tags-view-container flex-c">
<!-- <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> -->
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
<!-- @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''" -->
<router-link
v-for="tag in visitedViews"
ref="tag"
:key="tag.path"
:class="[isActive(tag) ? 'active' : '', {'length1': visitedViews.length == 1}]"
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
tag="span"
class="tags-view-item"
@contextmenu.prevent.native="openMenu(tag, $event)"
>
{{ tag.title }}
<span
v-if="!isAffix(tag) && visitedViews.length > 1"
class="el-icon-close"
@click.prevent.stop="closeSelectedTag(tag)"
/>
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)">刷新</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭</li>
<li @click="closeOthersTags(selectedTag)">关闭其他</li>
<!-- <li @click="closeAllTags(selectedTag)">关闭所有</li> -->
</ul>
</div>
</template>
<script>
import ScrollPane from './ScrollPane'
import Hamburger from '@/components/Hamburger'
import { routes } from '@/router'
import { mapGetters } from 'vuex'
export default {
components: { ScrollPane, Hamburger },
data() {
return {
visible: false,
top: 0,
left: 0,
selectedTag: {},
affixTags: [],
}
},
computed: {
visitedViews() {
return this.$store.state.tagsView.visitedViews
},
...mapGetters([
'sidebar'
])
// routes() {
// return this.$store.state.permission.routes
// },
},
watch: {
$route() {
this.addTags()
this.moveToCurrentTag()
},
visible(value) {
if (value) {
document.body.addEventListener('click', this.closeMenu)
} else {
document.body.removeEventListener('click', this.closeMenu)
}
},
},
mounted() {
this.initTags()
this.addTags()
// 页面刷新前缓存和赋值
this.beforeUnload()
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
// 刷新前缓存tab
beforeUnload() {
// 监听页面刷新
window.addEventListener('beforeunload', () => {
// visitedViews数据结构太复杂无法直接JSON.stringify处理,先转换需要的数据
let tabViews = this.visitedViews.map((item) => {
return {
fullPath: item.fullPath,
hash: item.hash,
meta: { ...item.meta },
name: item.name,
params: { ...item.params },
path: item.path,
query: { ...item.query },
title: item.title,
}
})
sessionStorage.setItem('tabViews', JSON.stringify(tabViews))
})
// 页面初始化加载判断缓存中是否有数据
let oldViews = JSON.parse(sessionStorage.getItem('tabViews')) || []
if (oldViews.length > 0) {
this.$store.state.tagsView.visitedViews = oldViews
}
},
isActive(route) {
return route.path === this.$route.path
},
isAffix(tag) {
return tag.meta && tag.meta.affix
},
filterAffixTags(routes, basePath = '/') {
let tags = []
routes.forEach((route) => {
if (route.meta && route.meta.affix) {
const tagPath = path.resolve(basePath, route.path)
tags.push({
fullPath: tagPath,
path: tagPath,
name: route.name,
meta: { ...route.meta },
})
}
if (route.children) {
const tempTags = this.filterAffixTags(route.children, route.path)
if (tempTags.length >= 1) {
tags = [...tags, ...tempTags]
}
}
})
return tags
},
initTags() {
const affixTags = (this.affixTags = this.filterAffixTags(routes))
for (const tag of affixTags) {
// Must have tag name
if (tag.name) {
this.$store.dispatch('tagsView/addVisitedView', tag)
}
}
},
addTags() {
const { name } = this.$route
if (name) {
this.$store.dispatch('tagsView/addView', this.$route)
}
return false
},
moveToCurrentTag() {
const tags = this.$refs.tag
this.$nextTick(() => {
for (const tag of tags) {
if (tag.to.path === this.$route.path) {
this.$refs.scrollPane.moveToTarget(tag)
// when query is different then update
if (tag.to.fullPath !== this.$route.fullPath) {
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
}
break
}
}
})
},
refreshSelectedTag(view) {
this.$store.dispatch('tagsView/delCachedView', view).then(() => {
const { fullPath } = view
this.$nextTick(() => {
this.$router.replace({
path: '/redirect' + fullPath,
})
})
})
},
closeSelectedTag(view) {
this.$store
.dispatch('tagsView/delView', view)
.then(({ visitedViews }) => {
if (this.isActive(view)) {
this.toLastView(visitedViews, view)
}
})
},
closeOthersTags() {
this.$router.push(this.selectedTag)
this.$store
.dispatch('tagsView/delOthersViews', this.selectedTag)
.then(() => {
this.moveToCurrentTag()
})
},
closeAllTags(view) {
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
if (this.affixTags.some((tag) => tag.path === view.path)) {
return
}
this.toLastView(visitedViews, view)
})
},
toLastView(visitedViews, view) {
const latestView = visitedViews.slice(-1)[0]
if (latestView) {
this.$router.push(latestView.fullPath)
} else {
// now the default is to redirect to the home page if there is no tags-view,
// you can adjust it according to your needs.
this.$router.push('/')
}
},
openMenu(tag, e) {
const menuMinWidth = 105
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
const offsetWidth = this.$el.offsetWidth // container width
const maxLeft = offsetWidth - menuMinWidth // left boundary
const left = e.clientX - offsetLeft + 15 // 15: margin right
if (left > maxLeft) {
this.left = maxLeft
} else {
this.left = left
}
this.top = e.clientY - 40
this.visible = true
this.selectedTag = tag
},
closeMenu() {
this.visible = false
},
handleScroll() {
this.closeMenu()
},
},
}
</script>
<style lang="scss" scoped>
@import '@/styles/common.scss';
/deep/ .scroll-container .el-scrollbar__wrap {
scrollbar-width: none;
}
.hamburger-container {
cursor: pointer;
}
.length1 {
padding-right: 20px!important;
}
.tags-view-container {
height: 34px;
width: 100%;
background: #fff;
border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
text-align: left;
/deep/ .el-scrollbar__wrap {
overflow-x: hidden;
}
.tags-view-wrapper {
.tags-view-item {
display: inline-block;
position: relative;
cursor: pointer;
height: 26px;
line-height: 26px;
// border: 1px solid #d8dce5;
color: #495060;
// background: #fff;
background: transparent;
padding: 0 8px;
font-size: 12px;
margin-left: 5px;
margin-top: 4px;
&:first-of-type {
margin-left: 15px;
}
&:last-of-type {
margin-right: 15px;
}
@mixin tagActive() {
color: $color-primary;
background-size: 100% 100%;
&::before {
content: '';
// background: #fff;
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
position: relative;
margin-right: 2px;
}
}
&:hover {
color: $color-primary;
}
&.active {
// background-color: #409eff;
// color: #fff;
// border-color: #409eff;
@include tagActive;
}
}
}
.contextmenu {
margin: 0;
background: #fff;
z-index: 3000;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
}
</style>
<style lang="scss">
//reset element css of el-icon-close
.tags-view-wrapper {
line-height: 45px;
.tags-view-item {
.el-icon-close {
width: 16px;
height: 16px;
vertical-align: 2px;
border-radius: 50%;
text-align: center;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
transform-origin: 100% 50%;
&:before {
transform: scale(0.6);
display: inline-block;
vertical-align: -3px;
}
&:hover {
background-color: #b4bccc;
color: #fff;
}
}
}
}
</style>
......@@ -3,6 +3,7 @@ import App from './App.vue'
import router from './router'
import * as echarts from 'echarts'
import ElementUI from 'element-ui'
import store from './store';
import 'element-ui/lib/theme-chalk/index.css'
import './styles/element-variables.scss'
import './styles/common.scss'
......@@ -49,5 +50,6 @@ Date.prototype.format = function (fmt) {
}
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app')
import { getAllBreadcrumbList } from '@/utils'
import { routes } from '@/router'
// import { menuOptions } from '@/views/Main/menu'
const getters = {
// 递归处理后的所有面包屑导航列表
breadcrumbListGet: (state) => getAllBreadcrumbList(routes),
// tag 路由标签
cachedViews: (state) => state.tagsView.cachedViews,
sidebar: (state) => state.app.sidebar,
colSetting: (state) => state.app.colSetting,
}
export default getters
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)
const modulesFiles = require.context('./modules', true, /\.js$/)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
export default new Vuex.Store({
state: {},
getters,
mutations: {},
actions: {},
modules,
})
const state = {
graphData: [], // 业务能力视图数据
dataSubjectRelationshipGraphData: [], // 数据主题关系视图数据
technicalFrameworkGraphData: {
techFrameLeftData: {},
techFrameMiddleData: [],
techFrameRightData: {},
}, // 技术框架视图数据
safeManagementGraphData: {
safeTopData: {},
safeMidLeftData: {},
safeMidCenterData: {},
safeMidRightData: {},
safeBottomData: {},
}, // 安全管理体系视图
microservicesGraphData: [], // 微服务总视图
}
const mutations = {
CHANGE_GRAPH_DATA: (state, data) => {
state.graphData = data
},
CHANGE_DATA_SUB_GRAPH_DATA: (state, data) => {
state.dataSubjectRelationshipGraphData = data
},
CHANGE_TECH_FRAME_DATA: (state, data) => {
state.technicalFrameworkGraphData = data
},
CHANGE_SAFE_MANAGEMENT_DATA: (state, data) => {
state.safeManagementGraphData = data
},
CHANGE_MICROSERVICES_GRAPH_DATA: (state, data) => {
state.microservicesGraphData = data
},
}
export default {
namespaced: true,
state,
mutations,
}
const state = {
visitedViews: [],
cachedViews: []
}
const mutations = {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (view.meta.keepAlive) {
state.cachedViews.push(view.name)
}
},
DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
},
DEL_CACHED_VIEW: (state, view) => {
const index = state.cachedViews.indexOf(view.name)
index > -1 && state.cachedViews.splice(index, 1)
},
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path
})
},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
const index = state.cachedViews.indexOf(view.name)
if (index > -1) {
state.cachedViews = state.cachedViews.slice(index, index + 1)
} else {
// if index = -1, there is no cached tags
state.cachedViews = []
}
},
DEL_ALL_VISITED_VIEWS: state => {
// keep affix tags
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags
},
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
},
UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
}
}
}
const actions = {
addView({ dispatch }, view) {
dispatch('addVisitedView', view)
dispatch('addCachedView', view)
},
addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view)
},
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},
delView({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delVisitedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},
delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delOthersVisitedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersCachedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_CACHED_VIEWS', view)
resolve([...state.cachedViews])
})
},
delAllViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delAllVisitedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
},
updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
......@@ -16,11 +16,7 @@ export function trendsRules(type) {
url: "/mainLayout/auxiliarySelection",
children: [],
},
// {
// name: "项目评估结果确认更改",
// url: "/mainLayout/confirmChanges",
// children: [],
// },
{
name: "评估结果查看",
url: "/mainLayout/assistedViewing",
......@@ -242,11 +238,7 @@ export function trendsRules(type) {
url: "/assesszc/auxiliaryInspection",
children: [],
},
{
name: "自查结果确认更改",
url: "/assesszc/confirmChanges",
children: [],
},
// {
// name: "自查问题下发",
......@@ -305,11 +297,7 @@ export function trendsRules(type) {
url: "/mainLayout/auxiliaryInspection",
children: [],
},
// {
// name: "项目评估结果确认更改",
// url: "/mainLayout/confirmChanges",
// children: [],
// },
{
name: "评估结果查看",
url: "/mainLayout/assistedViewing",
......
<template>
<div class="main">
<div class="close">
<i class="el-icon-circle-close" @click="cancel()"></i>
</div>
<p class="title">国网辽宁电力-桌面终端管理系统合规性检查评估</p>
<div class="continer">
<p class="xqtitle"><span></span>问题清单</p>
<el-table
ref="multipleTable"
:data="tableData"
tooltip-effect="dark myTooltips"
style="width: 100%"
header-cell-class-name="custom-th-background"
class="eltable"
:row-class-name="tableRowClassName"
:span-method="arraySpanMethod"
border
>
<el-table-column label="项目环节" prop="projectStagetext" width="150">
</el-table-column>
<el-table-column label="序号" width="100" type="index">
</el-table-column>
<el-table-column label="问题检查项" prop="quesCheckItem">
</el-table-column>
<el-table-column label="检查说明" prop="checkDesc"> </el-table-column>
<el-table-column label="评估问题" prop="evalQues">
<!-- <template slot-scope="scope">
<el-input v-model="scope.row.evalQues"></el-input>
</template> -->
</el-table-column>
<el-table-column label="问题截图" width="auto">
<template slot-scope="scope">
<el-image
class="imgList"
v-for="(img, index) in scope.row.images"
:key="index"
:src="img"
:preview-src-list="scope.row.images"
@click="handleImageClick(scope.row.images)"
></el-image>
</template>
</el-table-column>
</el-table>
</div>
<div class="bottom">
<!-- <p class="JYtitle"><span></span>建议</p>
<el-input
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
placeholder="输入建议"
v-model="textarea1"
class="textarea"
>
</el-input> -->
<p class="Btn">
<span @click="cancel()">取消</span
><span @click="confirmNo()">确认无需整改</span>
<span @click="confirm()">确认需整改</span>
</p>
</div>
</div>
</template>
<script>
import {
selWtqdpostEvalQuesInfo,
qrzgqrbgSelQuesInfo,
qrwzgqrbgSelQuesInfo,
presignedUrl
} from "@/api/index";
export default {
data() {
return {
tableData: [],
mergingRows: [],
mergingPos: 0,
clqparams: {},
textarea1: "",
};
},
mounted() {
this.clqparams = JSON.parse(this.$route.query.qrparams);
console.log(this.clqparams, "this.clqparams");
this.init(this.clqparams);
},
methods: {
async init(type) {
let params = type;
console.log(params, "333");
let res = await selWtqdpostEvalQuesInfo(params);
console.log(res, "0000");
if (res.code == "200") {
this.tableData = res.data.records;
this.tableData.forEach((item) => {
switch (item.projectStage) {
case 1:
this.$set(item, "projectStagetext", "1.可研");
break;
case 2:
this.$set(item, "projectStagetext", "2.计划");
break;
case 3:
this.$set(item, "projectStagetext", "3.采购");
break;
case 4:
this.$set(item, "projectStagetext", "4.合同");
break;
case 5:
this.$set(item, "projectStagetext", "5.执行");
break;
case 6:
this.$set(item, "projectStagetext", "6.结决算及转资");
break;
}
let urlStr = item.url;
let arrUrl = [];
let showUrlList = [];
// 有url拆分调接口换预览
if (urlStr) {
console.log(urlStr, "urlStr");
if (urlStr.includes(",")) {
arrUrl = item.url.split(",");
} else {
arrUrl.push(urlStr);
}
console.log(arrUrl, "arrUrlarrUrl");
arrUrl.forEach(async (showUrl) => {
let paramsUrl = {
url: showUrl,
};
let resUrl = await presignedUrl(paramsUrl);
showUrlList.push(resUrl.msg);
});
console.log(showUrlList, "showUrlList");
this.$set(item, "images", showUrlList);
}
});
this.total = res.data.total * 1;
this.dataPretreatment();
}
},
//表格颜色
tableRowClassName({ row, rowIndex }) {
if (rowIndex % 2 == 1) {
return "warning-row";
}
return "";
},
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
//第一列
const _row = this.mergingRows[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
},
dataPretreatment() {
for (let i = 0; i < this.tableData.length; i++) {
// tabledata 表格数据源
if (i === 0) {
this.mergingRows.push(1);
this.mergingPos = 0;
} else {
if (
this.tableData[i].projectStage ===
this.tableData[i - 1].projectStage
) {
//哪些数据是要合并的 合并的条件是什么
this.mergingRows[this.mergingPos] += 1;
this.mergingRows.push(0);
} else {
this.mergingRows.push(1);
this.mergingPos = i;
}
}
}
},
cancel() {
console.log('电击取消')
this.$router.go(-1);
},
//确认更改
async confirm() {
let params = {
projectId: this.clqparams.projectId,
batchId: this.clqparams.batchId,
};
let res = await qrzgqrbgSelQuesInfo(params);
if (res.code == "200") {
this.$router.go(-1);
} else {
this.$message("确认失败");
}
},
//确认无更改
async confirmNo() {
let params = {
projectId: this.clqparams.projectId,
batchId: this.clqparams.batchId,
};
let res = await qrwzgqrbgSelQuesInfo(params);
if (res.code == "200") {
this.$router.go(-1);
} else {
this.$message("确认失败");
}
},
},
};
</script>
<style lang="scss" scoped>
.main {
font-size: 14px;
position: relative;
height: 100%;
width: 100%;
box-sizing: border-box;
overflow-x: hidden;
.bottom {
width:calc(100% - 246px);
position:fixed;
bottom: -15px;
right: 0;
z-index: 100;
background-color: #f5f5f6;
line-height: 80px;
.textarea {
margin-top: 1px;
}
.Btn {
line-height: 80px;
span {
display: inline-block;
width: 95px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 5px;
margin-right: 32px;
background-color: #0d867f;
border: 1px solid #0d867f;
color: #fff;
}
span:first-of-type {
border: 1px solid grey;
color: #000;
background-color: #fff;
}
}
}
.JYtitle {
width: 100%;
height: 20px;
text-align: left;
font-size: 18px;
// margin-top: 1px;
padding-left: 10px;
line-height: 20px;
span {
display: inline-block;
width: 5px;
height: 30px;
background: #0d867f;
margin-right: 24px;
vertical-align: middle;
border-radius: 3px;
}
}
}
.close {
position: absolute;
right: 20px;
top: 20px;
.el-icon-circle-close {
font-size: 30px;
// background-color: #0d867f;
// color: #fff;
}
}
.title {
text-align: left;
background-color: #fff;
height: 40px;
line-height: 40px;
color: grey;
font-size: 15px;
}
.continer {
width: 100%;
height: 800px;
overflow-y: auto;
background-color: #f5f5f6;
padding: 10px;
padding-top: 0;
}
.tableTitle {
background: #0d867f;
color: #f5f5f6;
height: 40px;
line-height: 40px;
text-align: left;
padding-left: 20px;
font-weight: 600;
font-size: 15px;
}
.eltable {
width: 100%;
box-sizing: border-box;
margin-bottom: 50px;
}
/deep/ .el-table .warning-row {
background: #f0ffff;
// color: #2785e6;
}
.elpagination {
text-align: right;
margin-right: 100px;
}
/deep/.el-table {
width: 100%;
.el-table__header-wrapper table,
.el-table__body-wrapper table {
width: 100% !important;
}
.el-table__body,
.el-table__footer,
.el-table__header {
table-layout: auto;
}
}
/deep/.el-table th.el-table__cell.is-leaf,
.el-table td.el-table__cell {
text-align: center;
}
/deep/ .el-icon-folder-delete {
margin-right: 10px;
}
/deep/.el-table th.el-table__cell.is-leaf,
.el-table td.el-table__cell {
text-align: center;
}
/deep/ .el-table__cell {
text-align: center;
}
.xqtitle {
width: 100%;
height: 20px;
text-align: left;
font-size: 18px;
padding: 20px 0;
border-bottom: 1px solid gainsboro;
margin-top: 1px;
span {
display: inline-block;
width: 5px;
height: 20px;
background: #0d867f;
margin-right: 14px;
vertical-align: middle;
}
}
.imgList {
/deep/ .el-image__inner {
width: 60px;
height: 60px;
}
}
</style>
\ No newline at end of file
......@@ -24,12 +24,6 @@
clearable
></el-input>
</el-form-item>
<el-form-item label="后评估批次状态:" prop="batchState" class="fromItem">
<el-select v-model="ruleForm.batchState" placeholder="请选择" clearable>
<el-option label="执行中" value="3"></el-option>
<el-option label="已完成" value="5"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目编码:" prop="projectId" class="fromItem">
<el-input
v-model="ruleForm.projectId"
......@@ -59,18 +53,24 @@
</el-select>
</el-form-item>
<el-form-item label="项目审核状态:" prop="reviewStatus" class="fromItem">
<el-select
v-model="ruleForm.reviewStatus"
<el-form-item
label="项目审核状态:"
prop="postEvalState"
class="fromItem"
>
<el-select
v-model="ruleForm.postEvalState"
placeholder="请选择"
clearable
>
<el-option label="无问题" value="0"></el-option>
<el-option label="需整改" value="1"></el-option>
<el-option label="已整改" value="2"></el-option>
<el-option label="已归档" value="3"></el-option>
<el-option label="材料未上传" value="0"></el-option>
<el-option label="待评估" value="1"></el-option>
<el-option label="需整改" value="2"></el-option>
<el-option label="已整改" value="3"></el-option>
<el-option label="已归档" value="4"></el-option>
</el-select>
</el-form-item>
<el-form-item
label="实际评估日期:"
prop="lastUpdateTime"
......@@ -123,13 +123,7 @@
<el-table-column prop="batchName" label="后评估批次名称">
</el-table-column>
<el-table-column prop="expertName" label="评审专家"> </el-table-column>
<el-table-column
prop="batchStateText"
label="后评估批次状态"
width="120"
>
</el-table-column>
<el-table-column prop="projectId" label="项目编码" width="120"> </el-table-column>
<el-table-column prop="projectId" label="项目编码" width="140"> </el-table-column>
<el-table-column
prop="projectName"
......@@ -145,7 +139,7 @@
<el-table-column prop="projectCategory" label="建设形式" width="120">
</el-table-column>
<el-table-column prop="reviewStatusText" label="项目审核状态" width="120">
<el-table-column prop="postEvalStateText" label="项目审核状态" width="120">
</el-table-column>
<el-table-column prop="planReviewDate" label="计划评估日期">
......@@ -174,7 +168,7 @@
>
<div class="dialog">
<h3>
项目名称:一期项目-电力营销-2023年网上国网(网上国网V1.0)-设计开发项目
项目名称{{ listData.projectName }}
</h3>
<el-tabs v-model="activeName" @tab-click="handleClick">
......@@ -387,7 +381,10 @@ export default {
};
},
mounted() {
this.ruleForm.batchName = this.$route.query.batchName;
this.ruleForm.projectId = this.$route.query.projCode;
this.submitForm();
},
methods: {
timeChange(time) {
......@@ -412,19 +409,18 @@ export default {
if (res.code == "200") {
this.tableData = res.data.records;
this.tableData.forEach((item) => {
if (item.batchState == "3") {
this.$set(item, "batchStateText", "执行中");
} else if (item.batchState == "5") {
this.$set(item, "batchStateText", "已完成");
}
if (item.reviewStatus == "0") {
this.$set(item, "reviewStatusText", "无问题");
} else if (item.reviewStatus == "1") {
this.$set(item, "reviewStatusText", "需整改");
} else if (item.reviewStatus == "2") {
this.$set(item, "reviewStatusText", "已整改");
}else if (item.reviewStatus == "3") {
this.$set(item, "reviewStatusText", "已归档");
if (item.postEvalState == "" || item.postEvalState == null) {
this.$set(item, "postEvalStateText", "材料未上传");
} else if (item.postEvalState == "0") {
this.$set(item, "postEvalStateText", "材料未上传");
} else if (item.postEvalState == 1) {
this.$set(item, "postEvalStateText", "待评估");
} else if (item.postEvalState == 2) {
this.$set(item, "postEvalStateText", "需整改");
}else if (item.postEvalState == 3) {
this.$set(item, "postEvalStateText", "已整改");
}else if (item.postEvalState == 4) {
this.$set(item, "postEvalStateText", "已归档");
}
this.$set(
item,
......@@ -441,6 +437,7 @@ export default {
this.pageSize = 10;
this.ruleForm.createStartTime = "";
this.ruleForm.createEndTime = "";
this.ruleForm.dates=[]
this.submitForm();
},
//详情
......
......@@ -190,7 +190,7 @@
</div>
</div>
<p class="Btn">
<span @click="cancel()">取消</span><span @click="save()">保存</span>
<span @click="cancel()">取消</span><span @click="save()">保存</span> <span @click="submitNexts()">提交</span>
</p>
</div>
</template>
......@@ -250,6 +250,42 @@ export default {
this.init(this.clqparams);
},
methods: {
//提交问题清单
async submitNexts() {
// this.$router.push({
// path: "/mainLayout/Compliancefz",
// query: {
// clqparams: JSON.stringify(this.clqparams),
// },
// });
this.$confirm("您确定检查完所有流程并去提交?", "提示", {
confirmButtonText: "是",
cancelButtonText: "继续检查",
distinguishCancelAndClose: true,
type: "warning",
})
.then(() => {
this.save();
this.$router.push({
path: "/mainLayout/Compliancefz",
query: {
clqparams: JSON.stringify(this.clqparams),
},
});
})
.catch((action) => {
});
},
// 放大图片
handlePictureCardPreview(file) {
console.log("点击放大");
......@@ -285,7 +321,7 @@ export default {
beforeAvatarUpload(file) {
this.file = file;
const isJPG = file.type === "image/jpeg" || file.type === "image/png";
const isLt2M = this.file.size / 1024 < 2000;
const isLt2M = this.file.size / 1024 < 1000;
console.log(this.file.size / 1024, "this.file.size this.file.size ");
if (!isJPG) {
this.$message.error("上传图片只能是 JPG 或 PNG 格式!");
......@@ -293,7 +329,7 @@ export default {
}
if (!isLt2M) {
this.hideUploadEdit = false;
this.$message.error("上传图片大小不能超过 2000k!");
this.$message.error("上传图片大小不能超过 1000k!");
}
return isJPG && isLt2M;
},
......@@ -621,35 +657,35 @@ export default {
// console.log("来了么222222", this.fileList);
// },
},
beforeRouteLeave(to,from,next){
if(JSON.stringify(this.questionList) ==JSON.stringify(this.oldQuestionList)){
console.log('相同么')
next({replace: true,redirect: '/mainLayout/auxiliaryInspection'})
// beforeRouteLeave(to,from,next){
// if(JSON.stringify(this.questionList) ==JSON.stringify(this.oldQuestionList)){
// console.log('相同么')
// next({replace: true,redirect: '/mainLayout/auxiliaryInspection'})
}else{
console.log('不同么')
setTimeout(() => {
this.$confirm("是否保存?", "提示", {
confirmButtonText: "是",
cancelButtonText: "否",
distinguishCancelAndClose: true,
type: "warning",
}).then(() => {
this.save('leave');
next({replace: true,redirect: '/mainLayout/auxiliaryInspection'})
})
.catch((action) => {
console.log(action, "actionaction");
if (action === "cancel") {
next({replace: true,redirect: '/mainLayout/auxiliaryInspection'})
} else {
// next()
}
});
},16)
}
// }else{
// console.log('不同么')
// setTimeout(() => {
// this.$confirm("是否保存?", "提示", {
// confirmButtonText: "是",
// cancelButtonText: "否",
// distinguishCancelAndClose: true,
// type: "warning",
// }).then(() => {
// this.save('leave');
// next({replace: true,redirect: '/mainLayout/auxiliaryInspection'})
// })
// .catch((action) => {
// console.log(action, "actionaction");
// if (action === "cancel") {
// next({replace: true,redirect: '/mainLayout/auxiliaryInspection'})
// } else {
// // next()
// }
// });
// },16)
// }
}
// }
};
</script>
......
......@@ -52,7 +52,8 @@
</el-table>
</div>
<p class="Btn" v-if="!ishow">
<span @click="cancel()">取消</span><span @click="save('add')">确定</span>
<span @click="cancel()">取消</span>
<!-- <span @click="save('add')">确定</span> -->
<span @click="save('upLoad')">提交</span>
</p>
</div>
......@@ -197,23 +198,29 @@ export default {
console.log(params, "this.clqparams");
// return
if (type == "add") {
console.log(params, "this.zjtableDatathis.zjtableData");
let res = await bcpostEvalQuesInfo(params);
if (res.code == "200") {
this.$router.go(-1);
} else {
this.$message("保存失败");
}
} else {
// if (type == "add") {
// console.log(params, "this.zjtableDatathis.zjtableData");
// let res = await bcpostEvalQuesInfo(params);
// if (res.code == "200") {
// // this.$router.go(-1);
// this.$message("保存成功");
// } else {
// this.$message("保存失败");
// }
// } else {
let res = await tjpostEvalQuesInfo(params);
if (res.code == "200") {
this.$router.go(-1);
// this.$router.go(-1);
this.$router.push({
path: "/mainLayout/auxiliaryInspection",
});
this.$message("提交成功");
} else {
this.$message("上传失败");
this.$message("提交失败");
}
}
},
// },
},
};
</script>
......@@ -282,7 +289,7 @@ export default {
padding-top: 0;
// display: flex;
// padding: 0 20px;
padding-bottom: 20px;
padding-bottom:80px;
position: relative;
}
......
<template>
<div class="main">
<div class="close">
<i class="el-icon-circle-close" @click="cancel()"></i>
</div>
<p class="title">国网辽宁电力-桌面终端管理系统合规性检查评估</p>
<div class="continer">
<p class="xqtitle"><span></span>问题清单</p>
<el-table
ref="multipleTable"
:data="tableData"
tooltip-effect="dark myTooltips"
style="width: 100%"
header-cell-class-name="custom-th-background"
class="eltable"
:row-class-name="tableRowClassName"
:span-method="arraySpanMethod"
border
>
<el-table-column label="项目环节" prop="projectStagetext" width="150">
</el-table-column>
<el-table-column label="序号" width="100" type="index">
</el-table-column>
<el-table-column label="问题检查项" prop="quesCheckItem">
</el-table-column>
<el-table-column label="检查说明" prop="checkDesc"> </el-table-column>
<el-table-column label="评估问题" prop="evalQues">
<!-- <template slot-scope="scope">
<el-input v-model="scope.row.evalQues"></el-input>
</template> -->
</el-table-column>
<el-table-column label="问题截图" width="auto">
<template slot-scope="scope">
<el-image
class="imgList"
v-for="(img, index) in scope.row.images"
:key="index"
:src="img"
:preview-src-list="scope.row.images"
@click="handleImageClick(scope.row.images)"
></el-image>
</template>
</el-table-column>
</el-table>
</div>
<div class="bottom">
<!-- <p class="JYtitle"><span></span>建议</p>
<el-input
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
placeholder="输入建议"
v-model="textarea1"
class="textarea"
>
</el-input> -->
<p class="Btn">
<span @click="cancel()">取消</span
><span @click="confirmNo()">确认无需整改</span>
<span @click="confirm()">确认需整改</span>
</p>
</div>
</div>
</template>
<script>
import {
selWtqdpostEvalQuesInfo,
qrzgqrbgSelQuesInfo,
qrwzgqrbgSelQuesInfo,
presignedUrl
} from "@/api/index";
export default {
data() {
return {
tableData: [],
mergingRows: [],
mergingPos: 0,
clqparams: {},
textarea1: "",
};
},
mounted() {
this.clqparams = JSON.parse(this.$route.query.qrparams);
console.log(this.clqparams, "this.clqparams");
this.init(this.clqparams);
},
methods: {
async init(type) {
let params = type;
console.log(params, "333");
let res = await selWtqdpostEvalQuesInfo(params);
console.log(res, "0000");
if (res.code == "200") {
this.tableData = res.data.records;
this.tableData.forEach((item) => {
switch (item.projectStage) {
case 1:
this.$set(item, "projectStagetext", "1.可研");
break;
case 2:
this.$set(item, "projectStagetext", "2.计划");
break;
case 3:
this.$set(item, "projectStagetext", "3.采购");
break;
case 4:
this.$set(item, "projectStagetext", "4.合同");
break;
case 5:
this.$set(item, "projectStagetext", "5.执行");
break;
case 6:
this.$set(item, "projectStagetext", "6.结决算及转资");
break;
}
let urlStr = item.url;
let arrUrl = [];
let showUrlList = [];
// 有url拆分调接口换预览
if (urlStr) {
console.log(urlStr, "urlStr");
if (urlStr.includes(",")) {
arrUrl = item.url.split(",");
} else {
arrUrl.push(urlStr);
}
console.log(arrUrl, "arrUrlarrUrl");
arrUrl.forEach(async (showUrl) => {
let paramsUrl = {
url: showUrl,
};
let resUrl = await presignedUrl(paramsUrl);
showUrlList.push(resUrl.msg);
});
console.log(showUrlList, "showUrlList");
this.$set(item, "images", showUrlList);
}
});
this.total = res.data.total * 1;
this.dataPretreatment();
}
},
//表格颜色
tableRowClassName({ row, rowIndex }) {
if (rowIndex % 2 == 1) {
return "warning-row";
}
return "";
},
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
//第一列
const _row = this.mergingRows[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
},
dataPretreatment() {
for (let i = 0; i < this.tableData.length; i++) {
// tabledata 表格数据源
if (i === 0) {
this.mergingRows.push(1);
this.mergingPos = 0;
} else {
if (
this.tableData[i].projectStage ===
this.tableData[i - 1].projectStage
) {
//哪些数据是要合并的 合并的条件是什么
this.mergingRows[this.mergingPos] += 1;
this.mergingRows.push(0);
} else {
this.mergingRows.push(1);
this.mergingPos = i;
}
}
}
},
cancel() {
console.log('电击取消')
this.$router.go(-1);
},
//确认更改
async confirm() {
let params = {
projectId: this.clqparams.projectId,
batchId: this.clqparams.batchId,
};
let res = await qrzgqrbgSelQuesInfo(params);
if (res.code == "200") {
this.$router.go(-1);
} else {
this.$message("确认失败");
}
},
//确认无更改
async confirmNo() {
let params = {
projectId: this.clqparams.projectId,
batchId: this.clqparams.batchId,
};
let res = await qrwzgqrbgSelQuesInfo(params);
if (res.code == "200") {
this.$router.go(-1);
} else {
this.$message("确认失败");
}
},
},
};
</script>
<style lang="scss" scoped>
.main {
font-size: 14px;
position: relative;
height: 100%;
width: 100%;
box-sizing: border-box;
overflow-x: hidden;
.bottom {
width:calc(100% - 246px);
position:fixed;
bottom: -15px;
right: 0;
z-index: 100;
background-color: #f5f5f6;
line-height: 80px;
.textarea {
margin-top: 1px;
}
.Btn {
line-height: 80px;
span {
display: inline-block;
width: 95px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 5px;
margin-right: 32px;
background-color: #0d867f;
border: 1px solid #0d867f;
color: #fff;
}
span:first-of-type {
border: 1px solid grey;
color: #000;
background-color: #fff;
}
}
}
.JYtitle {
width: 100%;
height: 20px;
text-align: left;
font-size: 18px;
// margin-top: 1px;
padding-left: 10px;
line-height: 20px;
span {
display: inline-block;
width: 5px;
height: 30px;
background: #0d867f;
margin-right: 24px;
vertical-align: middle;
border-radius: 3px;
}
}
}
.close {
position: absolute;
right: 20px;
top: 20px;
.el-icon-circle-close {
font-size: 30px;
// background-color: #0d867f;
// color: #fff;
}
}
.title {
text-align: left;
background-color: #fff;
height: 40px;
line-height: 40px;
color: grey;
font-size: 15px;
}
.continer {
width: 100%;
height: 800px;
overflow-y: auto;
background-color: #f5f5f6;
padding: 10px;
padding-top: 0;
}
.tableTitle {
background: #0d867f;
color: #f5f5f6;
height: 40px;
line-height: 40px;
text-align: left;
padding-left: 20px;
font-weight: 600;
font-size: 15px;
}
.eltable {
width: 100%;
box-sizing: border-box;
margin-bottom: 50px;
}
/deep/ .el-table .warning-row {
background: #f0ffff;
// color: #2785e6;
}
.elpagination {
text-align: right;
margin-right: 100px;
}
/deep/.el-table {
width: 100%;
.el-table__header-wrapper table,
.el-table__body-wrapper table {
width: 100% !important;
}
.el-table__body,
.el-table__footer,
.el-table__header {
table-layout: auto;
}
}
/deep/.el-table th.el-table__cell.is-leaf,
.el-table td.el-table__cell {
text-align: center;
}
/deep/ .el-icon-folder-delete {
margin-right: 10px;
}
/deep/.el-table th.el-table__cell.is-leaf,
.el-table td.el-table__cell {
text-align: center;
}
/deep/ .el-table__cell {
text-align: center;
}
.xqtitle {
width: 100%;
height: 20px;
text-align: left;
font-size: 18px;
padding: 20px 0;
border-bottom: 1px solid gainsboro;
margin-top: 1px;
span {
display: inline-block;
width: 5px;
height: 20px;
background: #0d867f;
margin-right: 14px;
vertical-align: middle;
}
}
.imgList {
/deep/ .el-image__inner {
width: 60px;
height: 60px;
}
}
</style>
\ No newline at end of file
<template>
<div class="main">
<div class="main">
<TagsView></TagsView>
<router-view></router-view>
</div>
</template>
<script>
import TagsView from '@/components/TagsView/index.vue'
export default {
components: {
TagsView,
},
data(){
return{
currentDate:""
}
}
,
mounted(){
},
......
<template>
<div>
<p>这是首页</p>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
\ No newline at end of file
......@@ -77,8 +77,6 @@ export default {
this.$route.path == "/mainLayout/Compliance"
) {
this.activeIndex = "/mainLayout/auxiliaryInspection";
} else if (this.$route.path == "/mainLayout/qrCompliance") {
this.activeIndex = "/mainLayout/confirmChanges";
} else if (this.$route.path == "/mainLayout/Compliancexf") {
if (this.$route.query.fromType == "fzcx") {
this.activeIndex = "/mainLayout/auxiliaryQuery";
......@@ -182,8 +180,6 @@ export default {
this.$route.path == "/mainLayout/Compliance"
) {
this.activeIndex = "/mainLayout/auxiliaryInspection";
} else if (this.$route.path == "/mainLayout/qrCompliance") {
this.activeIndex = "/mainLayout/confirmChanges";
} else if (this.$route.path == "/mainLayout/Compliancexf") {
if (this.$route.query.fromType == "fzcx") {
this.activeIndex = "/mainLayout/auxiliaryQuery";
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!