Compare commits

24 Commits

Author SHA1 Message Date
DESKTOP-AD8UBUJ\ling
2eba5f0140 Merge branch 'main' of http://8.130.49.250:3000/admin/gr_bi_web 2026-03-12 16:48:31 +08:00
DESKTOP-AD8UBUJ\ling
1dacb5a705 序号列宽固定 2026-03-12 16:46:18 +08:00
chy
99b2cc369d 修改单点登录 2026-03-11 00:16:42 +08:00
DESKTOP-AD8UBUJ\ling
0e48245381 Merge branch 'main' of http://8.130.49.250:3000/admin/gr_bi_web
# Conflicts:
#	config/dev.env.js
#	src/views/login.vue
2026-03-07 00:22:49 +08:00
DESKTOP-AD8UBUJ\ling
83a8974dc5 config提交 2026-03-07 00:20:09 +08:00
DESKTOP-AD8UBUJ\ling
76443e343c 单点修改2 2026-03-07 00:13:29 +08:00
chy
c5fdbd6a27 111111112 2026-03-06 22:45:55 +08:00
chy
ace17a95dd Merge branch 'main' of http://8.130.49.250:3000/admin/gr_bi_web
# Conflicts:
#	src/views/login.vue
2026-03-06 22:44:43 +08:00
chy
2125269c6c 1 2026-03-06 22:41:57 +08:00
DESKTOP-AD8UBUJ\ling
1373b56b94 单点修改1 2026-03-06 22:22:42 +08:00
DESKTOP-AD8UBUJ\ling
23f4390a9b 加阅读模式 2026-03-06 08:04:29 +08:00
DESKTOP-AD8UBUJ\ling
1f08afd8d3 下钻配置未清空上次配置问题修复 2026-03-05 15:27:35 +08:00
DESKTOP-AD8UBUJ\ling
c64012e4ea 补充 2026-03-02 21:35:40 +08:00
DESKTOP-AD8UBUJ\ling
cffdd0f7ba 大屏表格下钻 2026-03-02 21:34:56 +08:00
chy
1ba1186ee2 修改统一身份认证 2026-03-02 15:14:07 +08:00
chy
a869e62351 修改统一身份认证 2026-03-02 10:33:39 +08:00
chy
458ac46ca4 添加空字符 2026-02-28 08:46:34 +08:00
mll
8ec6582ffc bigscreen/viewer本页面路由跳转问题 2026-02-27 22:16:22 +08:00
mll
7110ba358c 大屏预览底部空白修复 2026-02-27 22:08:37 +08:00
b6fcf5c32b Merge pull request 'tab20260208' (#3) from tab20260208 into main
Reviewed-on: #3
2026-02-13 12:13:10 +08:00
Erin66
5cce73902d 下钻配置 tabs修改 2026-02-13 00:35:20 +08:00
Erin66
25db88333d Merge branch 'main' into tab20260208 2026-02-12 22:33:43 +08:00
Erin66
ddb542d89b tabs内部虚线区域放大 2026-02-12 22:30:38 +08:00
mll
01e9657d49 no message 2026-02-11 11:58:10 +08:00
17 changed files with 467 additions and 76 deletions

View File

@@ -5,5 +5,7 @@ const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, { module.exports = merge(prodEnv, {
NODE_ENV: '"development"', NODE_ENV: '"development"',
BASE_API: '"http://127.0.0.1:48090"' BASE_API: '"http://127.0.0.1:48090"'
// BASE_API: '"http://192.168.1.241:8080/prod-api"' // BASE_API: '"http://192.168.1.241:8080/prod-api"'
}) })

View File

@@ -8,6 +8,14 @@ export function login (data) {
}) })
} }
export function logincas (data) {
return request({
url: 'accessUser/logincas',
method: 'post',
data
})
}
export function logout () { export function logout () {
return request({ return request({
url: 'accessUser/logout', url: 'accessUser/logout',
@@ -15,6 +23,18 @@ export function logout () {
}) })
} }
export function outlogcas (data) {
console.log(data)
return request({
url: 'accessUser/outlogcas',
method: 'post',
data
})
}
// 登录之后 根据旧修改密码 // 登录之后 根据旧修改密码
export function reqUpdatePassword (data) { export function reqUpdatePassword (data) {
return request({ return request({

View File

@@ -271,7 +271,6 @@ export default {
return { top: top, left: left } return { top: top, left: left }
}, },
objToOne(obj) { objToOne(obj) {
console.log(obj)
let tmpData = {} let tmpData = {}
for (let index in obj) { for (let index in obj) {
if (typeof obj[index] == 'object' && !this.isArrayFn(obj[index])) { if (typeof obj[index] == 'object' && !this.isArrayFn(obj[index])) {

View File

@@ -6,7 +6,6 @@ export default router
const whiteList = ['/login', '/aj/**', '/el/**', '/bigscreen/viewer', '/excelreport/viewer'] const whiteList = ['/login', '/aj/**', '/el/**', '/bigscreen/viewer', '/excelreport/viewer']
// 判断是否需要登录权限 以及是否登录 // 判断是否需要登录权限 以及是否登录
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
NProgress.start() NProgress.start()
let token = getToken(); let token = getToken();
let lideeUser = getAccessUser(); let lideeUser = getAccessUser();
@@ -18,6 +17,7 @@ router.beforeEach((to, from, next) => {
next() next()
} }
}else { }else {
if (whiteList.includes(to.path)) { if (whiteList.includes(to.path)) {
next() next()
}else { }else {

View File

@@ -250,7 +250,8 @@ export const constantRouterMap = [
component: () => import('@/views/bigscreenDesigner/viewer'), component: () => import('@/views/bigscreenDesigner/viewer'),
hidden: true, hidden: true,
meta: { meta: {
requireAuth: true requireAuth: true,
keepAlive: true,
} }
}, },
{ {

View File

@@ -32,6 +32,7 @@ const user = {
const repCode = response.repCode const repCode = response.repCode
const repData = response.repData const repData = response.repData
if (repCode === '0000') { if (repCode === '0000') {
commit('SET_TOKEN', repData.token) commit('SET_TOKEN', repData.token)
commit('SET_ACCESSUSER', repData.accessUser) commit('SET_ACCESSUSER', repData.accessUser)
resolve(response) resolve(response)

View File

@@ -1,5 +1,6 @@
import axios from 'axios' import axios from 'axios'
import { Message, MessageBox } from 'element-ui' import { Message, MessageBox } from 'element-ui'
import router from '../router'
import store from '../store' import store from '../store'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
// 创建axios实例 // 创建axios实例
@@ -41,7 +42,13 @@ service.interceptors.response.use(
// sessionStorage.clear() // sessionStorage.clear()
// localStorage.clear() // localStorage.clear()
localStorage.removeItem('AJReportToken') localStorage.removeItem('AJReportToken')
window.location.href = "/"; router.push({
path: '/login',
query: {
redirect: location.hash.substring(1)
}
})
// window.location.href = "/index?redirect=" + location.hash.substring(1);
}) })
} }
else if (res.code !== '200') { else if (res.code !== '200') {

View File

@@ -27,7 +27,7 @@
v-for="(it, idx) in item.list" v-for="(it, idx) in item.list"
:key="idx" :key="idx"
draggable="true" draggable="true"
@dragstart="dragStart(it.code)" @dragstart="dragStart(it.code, $event)"
@dragend="dragEnd()" @dragend="dragEnd()"
> >
<div class="tools-item"> <div class="tools-item">
@@ -290,6 +290,8 @@
:type="widget.type" :type="widget.type"
:bigscreen="{ bigscreenWidth, bigscreenHeight }" :bigscreen="{ bigscreenWidth, bigscreenHeight }"
@onActivated="setOptionsOnClickWidget" @onActivated="setOptionsOnClickWidget"
@onChildActivated="setOptionsOnClickInnerWidget"
@onTabsHeaderMouseDown="onTabsHeaderMouseDown($event)"
@contextmenu.prevent.native="rightClick($event, index)" @contextmenu.prevent.native="rightClick($event, index)"
@mousedown.prevent.native="widgetsClick($event, index)" @mousedown.prevent.native="widgetsClick($event, index)"
@mouseup.prevent.native="grade = false" @mouseup.prevent.native="grade = false"
@@ -449,6 +451,8 @@ export default {
rect : null, //框选矩形对象 rect : null, //框选矩形对象
openMulDrag: false, //批量拖拽开关 openMulDrag: false, //批量拖拽开关
moveWidgets:{}, //记录移动的组件的起始left和top属性 moveWidgets:{}, //记录移动的组件的起始left和top属性
// 记录当前是否选中了 Tabs 内部子组件,如果为 null 则表示选中的是顶层组件或大屏
innerWidgetSelected: null,
}; };
}, },
computed: { computed: {
@@ -988,9 +992,14 @@ export default {
getPXUnderScale(px) { getPXUnderScale(px) {
return this.bigscreenScaleInWorkbench * px; return this.bigscreenScaleInWorkbench * px;
}, },
dragStart(widgetCode) { dragStart(widgetCode, evt) {
this.dragWidgetCode = widgetCode; this.dragWidgetCode = widgetCode;
this.currentWidgetTotal = this.widgets.length; // 当前操作面板上有多少各组件 this.currentWidgetTotal = this.widgets.length; // 当前操作面板上有多少各组件
// 通过 dataTransfer 传递组件 code便于 Tabs 等嵌套容器在 drop 时读取(不依赖父组件链)
if (evt && evt.dataTransfer) {
evt.dataTransfer.setData("application/x-widget-code", widgetCode);
evt.dataTransfer.effectAllowed = "copy";
}
}, },
dragEnd() { dragEnd() {
/** /**
@@ -1017,12 +1026,48 @@ export default {
}); });
}, },
dragOver(evt) { dragOver(evt) {
// 鼠标在 Tabs 标签内容区内时不处理,让 tab 内容区成为 drop 目标,避免工作台抢走
if (evt.target && evt.target.closest && (evt.target.closest(".tab-content") || evt.target.closest("[data-tab-content]"))) {
return;
}
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
evt.dataTransfer.dropEffect = "copy"; evt.dataTransfer.dropEffect = "copy";
}, },
// 拖动一个组件放到工作区中去,在拖动结束时,放到工作区对应的坐标点上去 // 拖动一个组件放到工作区中去,在拖动结束时,放到工作区对应的坐标点上去
widgetOnDragged(evt) { widgetOnDragged(evt) {
// 若落在 Tabs 标签内容区内,由 widgetTabs 自己处理,不在此处添加到主画布
if (evt.target && evt.target.closest && (evt.target.closest(".tab-content") || evt.target.closest("[data-tab-content]"))) {
return;
}
// 若落在 Tabs 组件的外层容器上(如 avue-draggable委托给对应 Tabs 加入当前激活的 tab
const widgetsRef = this.$refs.widgets;
const widgetList = Array.isArray(widgetsRef) ? widgetsRef : (widgetsRef ? [widgetsRef] : []);
if (evt.target && widgetList.length) {
for (let i = 0; i < widgetList.length; i++) {
const w = widgetList[i];
if (!w || !w.$el || !w.$el.contains(evt.target)) continue;
if (this.widgets[i] && this.widgets[i].type === "widget-tabs") {
const findTabs = (comp) => {
if (!comp) return null;
if (typeof comp.addWidgetFromDrop === "function") return comp;
if (comp.$children && comp.$children.length) {
for (let j = 0; j < comp.$children.length; j++) {
const found = findTabs(comp.$children[j]);
if (found) return found;
}
}
return null;
};
const tabsComp = findTabs(w);
if (tabsComp) {
tabsComp.addWidgetFromDrop(evt);
return;
}
}
break;
}
}
let widgetType = this.dragWidgetCode; let widgetType = this.dragWidgetCode;
// 获取结束坐标和列名 // 获取结束坐标和列名
@@ -1058,6 +1103,7 @@ export default {
options: tool.options, options: tool.options,
}; };
// 处理默认值 // 处理默认值
console.log(widgetType)
const widgetJsonValue = this.getWidgetConfigValue(widgetJson); const widgetJsonValue = this.getWidgetConfigValue(widgetJson);
widgetJsonValue.value.position.left = widgetJsonValue.value.position.left =
@@ -1138,6 +1184,118 @@ export default {
}); });
this.widgetOptions = this.deepClone(this.widgets[obj.index]["options"]); this.widgetOptions = this.deepClone(this.widgets[obj.index]["options"]);
}, },
/**
* 选中 Tabs 组件内部的子组件,展示该子组件的右侧配置
*/
setOptionsOnClickInnerWidget(payload) {
if (!payload) return;
console.log('setOptionsOnClickInnerWidget payload:', payload);
const { rootWidgetIndex, tabIndex, childIndex } = payload;
const rootIndex = typeof rootWidgetIndex === "number" ? rootWidgetIndex : 0;
const rootWidget = this.widgets[rootIndex];
if (!rootWidget || !rootWidget.value) return;
// 1. 兼容两种存储位置value.setup.tabsList / options.setup 里的 tabsList
const setupObj = rootWidget.value.setup || {};
let tabsList = setupObj.tabsList;
if (!tabsList || !tabsList.length) {
const setupArr = rootWidget.options && rootWidget.options.setup ? rootWidget.options.setup : [];
const tabsItem = setupArr.find(it => it.name === "tabsList");
if (tabsItem && Array.isArray(tabsItem.value)) {
tabsList = tabsItem.value;
}
}
tabsList = tabsList || [];
const targetTab = tabsList[tabIndex];
if (!targetTab || !targetTab.children || !targetTab.children[childIndex]) {
console.warn("Tabs 子组件未找到:", { rootIndex, tabIndex, childIndex, tabsList });
return;
}
let childWidget = targetTab.children[childIndex];
// 2. 确保子组件有 options老数据里可能只有 type + value
if (!childWidget.options) {
try {
const tool = getToolByCode(childWidget.type);
if (tool && tool.options) {
childWidget.options = this.deepClone(tool.options);
} else {
console.warn("未找到子组件 options 配置:", childWidget.type);
}
} catch (e) {
console.error("为子组件补全 options 失败:", e);
}
}
// 3. 用实际 position 回填到 options.position 中,保证坐标表单显示正确
if (childWidget.options && Array.isArray(childWidget.options.position)) {
const pos = (childWidget.value && childWidget.value.position) ? childWidget.value.position : {};
childWidget.options.position.forEach((el) => {
if (pos.hasOwnProperty(el.name)) {
el.value = pos[el.name];
}
});
}
// 4. 记录当前选中的内部子组件路径 & 切换右侧到子组件配置
this.innerWidgetSelected = {
rootWidgetIndex: rootIndex,
tabIndex,
childIndex,
};
this.screenCode = "";
this.widgetIndex = rootIndex;
this.activeName = "first";
this.widgetOptions = this.deepClone(childWidget.options || {});
},
/**
* Tabs 标题栏按下:启动整块 Tabs 的拖动(因 Tabs 外层 avue-draggable 已禁用)
*/
onTabsHeaderMouseDown(payload) {
if (!payload || !payload.event || typeof payload.rootWidgetIndex !== 'number') return;
const rootIndex = payload.rootWidgetIndex;
const widget = this.widgets[rootIndex];
if (!widget || !widget.value || !widget.value.position) return;
// 选中 Tabs 组件本身,触发蓝色点框和右侧配置
this.innerWidgetSelected = null;
this.widgetsClickFocus(rootIndex);
const evt = payload.event;
const workbenchRect = document.getElementById('workbench') && document.getElementById('workbench').getBoundingClientRect();
if (!workbenchRect) return;
const scale = this.currentSizeRangeIndex === this.defaultSize.index
? this.bigscreenScaleInWorkbench
: this.sizeRange[this.currentSizeRangeIndex] / 100;
const startX = evt.clientX;
const startY = evt.clientY;
const startLeft = widget.value.position.left;
const startTop = widget.value.position.top;
const onMove = (e) => {
const dx = (e.clientX - startX) / scale;
const dy = (e.clientY - startY) / scale;
let newLeft = startLeft + dx;
let newTop = startTop + dy;
if (newLeft < 0) newLeft = 0;
if (newTop < 0) newTop = 0;
if (newLeft + widget.value.position.width > this.bigscreenWidth) {
newLeft = this.bigscreenWidth - widget.value.position.width;
}
if (newTop + widget.value.position.height > this.bigscreenHeight) {
newTop = this.bigscreenHeight - widget.value.position.height;
}
this.$set(widget.value.position, 'left', newLeft);
this.$set(widget.value.position, 'top', newTop);
};
const onUp = () => {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
};
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
},
widgetsClick(event,index) { widgetsClick(event,index) {
console.log("widgetsClick"); console.log("widgetsClick");
//判断是否按住了Ctrl按钮表示Ctrl多选 //判断是否按住了Ctrl按钮表示Ctrl多选
@@ -1237,10 +1395,40 @@ export default {
console.log(newSetup); console.log(newSetup);
this.widgetOptions.setup = newSetup; this.widgetOptions.setup = newSetup;
} else { } else {
for (let i = 0; i < this.widgets.length; i++) { // 如果当前选中的是 Tabs 内部子组件,优先更新内部子组件的配置
if (this.widgetIndex == i) { if (this.innerWidgetSelected) {
this.widgets[i].value[key] = this.deepClone(val); const { rootWidgetIndex, tabIndex, childIndex } = this.innerWidgetSelected;
this.setDefaultValue(this.widgets[i].options[key], val); const rootWidget = this.widgets[rootWidgetIndex];
if (rootWidget && rootWidget.value && rootWidget.value.setup) {
const tabsList = rootWidget.value.setup.tabsList || [];
const targetTab = tabsList[tabIndex];
if (targetTab && targetTab.children && targetTab.children[childIndex]) {
const childWidget = targetTab.children[childIndex];
// 更新子组件的 value 和 options
if (!childWidget.value) {
this.$set(childWidget, "value", {});
}
childWidget.value[key] = this.deepClone(val);
if (childWidget.options && childWidget.options[key]) {
this.setDefaultValue(childWidget.options[key], val);
}
// 回写到 rootWidget 的 setup 中,保证 Tabs 组件保存时能带上最新配置
rootWidget.value.setup.tabsList = tabsList;
const setupArr = rootWidget.options && rootWidget.options.setup ? rootWidget.options.setup : [];
setupArr.forEach((item) => {
if (item.name === "tabsList") {
item.value = tabsList;
}
});
}
}
} else {
// 普通顶层组件的配置更新逻辑保持不变
for (let i = 0; i < this.widgets.length; i++) {
if (this.widgetIndex == i) {
this.widgets[i].value[key] = this.deepClone(val);
this.setDefaultValue(this.widgets[i].options[key], val);
}
} }
} }
} }

View File

@@ -259,7 +259,7 @@ export default {
}, },
// 列表查询 // 列表查询
async handleQueryPageList() { async handleQueryPageList() {
debugger
// 将特殊参数值urlcode处理 // 将特殊参数值urlcode处理
// 默认的排序 // 默认的排序
if ( if (

View File

@@ -538,7 +538,10 @@ export default {
}, },
handleCollapse(val){ handleCollapse(val){
this.dialogVisibleDrillDrown=true this.dialogVisibleDrillDrown=true
this.screenData=val.drill_drown_setting?val.drill_drown_setting:this.screenData this.screenData=val.drill_drown_setting?val.drill_drown_setting:{
dashboard: { },
widgets: []
}
}, },
// 获取图层数据 // 获取图层数据
getLayerData(val) { getLayerData(val) {

View File

@@ -66,6 +66,14 @@ export const widgetTable = {
placeholder: '', placeholder: '',
value: false value: false
}, },
{
type: 'el-switch',
label: '序号',
name: 'isIndex',
required: false,
placeholder: '',
value: false
},
{ {
type: 'el-input-number', type: 'el-input-number',
label: '边框宽度', label: '边框宽度',
@@ -314,8 +322,44 @@ export const widgetTable = {
value: 1 value: 1
}, },
] ]
} },
], ],
{
type: 'el-switch',
label: '开启下钻',
name: 'is_drill_drown',
required: false,
placeholder: '',
value: false,
},
{
type: 'el-collapse',
label: '下钻配置',
name: 'drill_drown_setting',
relactiveDom:'is_drill_drown',
relactiveDomValue:true,
required: false,
placeholder: '',
value:''
},
{
type: 'el-switch',
label: '阅读模式',
name: 'is_read_mode',
required: false,
placeholder: '',
value: false,
},
{
type: 'vue-color',
label: '阅读模式颜色',
name: 'read_color',
relactiveDom:'is_read_mode',
relactiveDomValue:true,
required: false,
placeholder: '',
value:''
},
{ {
type: 'dynamic-add-table', type: 'dynamic-add-table',
label: '', label: '',

View File

@@ -119,5 +119,10 @@ export default {
} }
.pickWrap{ .pickWrap{
display:flex; display:flex;
&::v-deep() {
.el-input__prefix{
height:28px;
}
} }
}
</style> </style>

View File

@@ -355,9 +355,16 @@ export default {
}, },
setActiveTab() { setActiveTab() {
const tabs = this.tabsList; const tabs = this.tabsList;
if (tabs && tabs.length > 0) { if (!tabs || tabs.length === 0) return;
this.activeTab = tabs[0].name || 'tab0';
// 如果当前 activeTab 还在 tabs 中,则保持不变,避免每次数据变化都跳回第一个标签
if (this.activeTab) {
const exist = tabs.some((t, i) => (t.name || `tab${i}`) === this.activeTab);
if (exist) return;
} }
// 当前没有选中标签,或原选中标签已被删除时,才默认选中第一个
this.activeTab = tabs[0].name || 'tab0';
}, },
handleTabClick(tab) { handleTabClick(tab) {
const currentTab = this.tabsList.find(t => (t.name || `tab${this.tabsList.indexOf(t)}`) === tab.name); const currentTab = this.tabsList.find(t => (t.name || `tab${this.tabsList.indexOf(t)}`) === tab.name);
@@ -824,6 +831,7 @@ export default {
.tab-content-empty { .tab-content-empty {
width: 100%; width: 100%;
height: 100%; height: 100%;
min-height: 200px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@@ -3,26 +3,45 @@
<superslide v-if="hackReset" :options="options" class="txtScroll-top" ref="superslide"> <superslide v-if="hackReset" :options="options" class="txtScroll-top" ref="superslide">
<!--表头--> <!--表头-->
<div class="title"> <div class="title">
<div
v-if="isIndex"
:style="[headerTableStyle,{width:'50px',flexShrink: 0}, tableRowHeight()]">
序号
</div>
<div v-for="(item, index) in header" :key="index" <div v-for="(item, index) in header" :key="index"
:style="[headerTableStyle, tableFiledWidth(index), tableRowHeight()]"> :style="[headerTableStyle, tableFiledWidth(index), tableRowHeight()]">
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
<!--数据--> <!--数据-->
<div class="bd"> <div class="bd" @click="handleClick">
<ul class="infoList"> <ul class="infoList">
<li v-for="(item, index) in list" :key="index" :style="tableRowHeight()"> <li v-for="(item, index) in list" :key="index" :style="tableRowHeight()">
<div v-for="(itemChild, idx) in header" <div
@mouseenter="handleMouseSeen(index, -1)" @mouseleave="handleMouseLeave"
v-if="isIndex"
:style="[
bodyTableStyle,
tableReadColor(index, -1),{width:'50px',flexShrink: 0},
bodyTable(index),
tableRowHeight()
]"
>
{{ index + 1 }}
</div>
<div @mouseenter="handleMouseSeen(index, idx)" @mouseleave="handleMouseLeave" v-for="(itemChild, idx) in header"
:key="idx" :key="idx"
:style="[ :style="[
bodyTableStyle, bodyTableStyle,
bodyTable(index), bodyTable(index),
tableFiledWidth(idx), tableFiledWidth(idx),
tableReadColor(index, idx),
tableRowHeight() tableRowHeight()
]" ]"
> >
{{ item[itemChild.key] }} {{ item[itemChild.key] }}
</div> </div>
</li> </li>
</ul> </ul>
</div> </div>
@@ -98,10 +117,12 @@ export default {
}, },
header: [], header: [],
list: [], list: [],
hoverIndex: {},
optionsSetUp: {}, optionsSetUp: {},
optionsPosition: {}, optionsPosition: {},
optionsData: {}, optionsData: {},
flagInter: null, flagInter: null,
isIndex: false,
// 新增导出对话框相关数据 // 新增导出对话框相关数据
exportDialogVisible: false, exportDialogVisible: false,
exporting: false, exporting: false,
@@ -131,6 +152,7 @@ export default {
}, },
headerTableStyle() { headerTableStyle() {
const headStyle = this.optionsSetUp; const headStyle = this.optionsSetUp;
this.isIndex=headStyle.isIndex
return { return {
"text-align": headStyle.textAlignHeader, "text-align": headStyle.textAlignHeader,
"font-size": headStyle.fontSizeHeader + "px", "font-size": headStyle.fontSizeHeader + "px",
@@ -216,6 +238,7 @@ export default {
value: { value: {
handler(val) { handler(val) {
this.optionsSetUp = val.setup; this.optionsSetUp = val.setup;
this.optionsPosition = val.position; this.optionsPosition = val.position;
this.optionsData = val.data; this.optionsData = val.data;
this.initData(); this.initData();
@@ -238,6 +261,17 @@ export default {
window.removeEventListener('resize', this.handleResize); window.removeEventListener('resize', this.handleResize);
}, },
methods: { methods: {
handleMouseSeen(index, idx){
this.hoverIndex = {index, idx}
},
handleMouseLeave(){
this.hoverIndex = {}
},
handleClick(){
if(!!this.optionsSetUp.is_drill_drown){
this.$emit('oepnTheDrillView',this.optionsSetUp.drill_drown_setting)
}
},
initData() { initData() {
this.handlerRollFn(); this.handlerRollFn();
this.handlerHead(); this.handlerHead();
@@ -341,6 +375,14 @@ export default {
} }
return styleJson; return styleJson;
}, },
tableReadColor(index, idx){
let styleJson = {};
if (this.optionsSetUp.is_read_mode && (this.hoverIndex.index === index || this.hoverIndex.idx === idx)) {
styleJson["background-color"] = this.optionsSetUp.read_color;console.log(styleJson["background-color"],this.hoverIndex,1231231)
}
return styleJson;
},
// 添加的方法 - 设备类型检测 // 添加的方法 - 设备类型检测
checkDeviceType() { checkDeviceType() {
this.screenWidth = window.innerWidth; this.screenWidth = window.innerWidth;

View File

@@ -20,8 +20,8 @@
<el-dialog <el-dialog
:title="''" :title="''"
class="dialogDrillDrown dialogDrillDrownView" :visible.sync="visiableDrillView"> class="dialogDrillDrown dialogDrillDrownView" :visible.sync="visiableDrillView">
<drill-drown-view :screenData="screenData"></drill-drown-view> <drill-drown-view :screenData="screenData"></drill-drown-view>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@@ -133,9 +133,9 @@ export default {
<style lang="scss"> <style lang="scss">
.layout { .layout {
width: 100%; width: 100%;
height: auto;
text-align: center; text-align: center;
overflow:hidden
} }
.dialogDrillDrownView .el-dialog{ .dialogDrillDrownView .el-dialog{
width:auto; width:auto;

View File

@@ -82,6 +82,8 @@ import Hamburger from "@/components/Hamburger";
import { getStorageItem } from "@/utils/storage"; import { getStorageItem } from "@/utils/storage";
import { reqUpdatePassword } from "@/api/login"; import { reqUpdatePassword } from "@/api/login";
import { transPsw } from "@/utils/encrypted"; import { transPsw } from "@/utils/encrypted";
import {getAccessUser} from "@/utils/auth";
import {outlogcas} from "@/api/login";
export default { export default {
data() { data() {
@@ -156,11 +158,34 @@ export default {
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(() => { }).then(() => {
sessionStorage.clear(); debugger
localStorage.clear(); //获取登录人
this.$router.push("/login"); let user = getAccessUser()
console.log(user.loginName)
debugger
this.outlogincasapi();
debugger
console.log(user.loginName)
// sessionStorage.clear();
// localStorage.clear();
// this.$router.push("/login");
}); });
}, },
async outlogincasapi() {
debugger
const obj = {
loginName: "admin",
password: "demo",
verifyCode: "",
};
const { code, data } = await outlogcas(obj);
sessionStorage.clear();
localStorage.clear();
this.$router.push("/login");
},
// 修改密码 // 修改密码
updatePassword() { updatePassword() {
this.wordVisible = true; this.wordVisible = true;

View File

@@ -1,7 +1,5 @@
<template> <template>
<div class="login_container"> <div class="login_container">
<div class="login_contant"> <div class="login_contant">
<img src="@/assets/images/login.jpg" alt="image" class="login_img" /> <img src="@/assets/images/login.jpg" alt="image" class="login_img" />
<el-form <el-form
@@ -13,27 +11,24 @@
label-position="left" label-position="left"
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
> >
<div class="title_container"> <div class="title_container">国瑞药业驾驶舱平台</div>
智慧大屏 <div style="height: 30px"></div>
</div>
<div style="height: 30px;"></div>
<div class="form_fields"> <div class="form_fields">
<el-form-item prop="loginName">
<el-form-item prop="loginName"> <el-input
<el-input ref="loginName"
ref="loginName" v-model="loginForm.loginName"
v-model="loginForm.loginName" placeholder="用户名"
placeholder="用户名" name="loginName"
name="loginName" type="text"
type="text" tabindex="1"
tabindex="1" autocomplete="on"
autocomplete="on" @focus="setTop('0')"
@focus="setTop('0')" @change="getPsw"
@change="getPsw" />
/> </el-form-item>
</el-form-item>
<div> <div>
<div style="height: 20px;"></div> <div style="height: 20px"></div>
<input <input
name="password" name="password"
@@ -62,7 +57,7 @@
@keyup.native="checkCapslock" @keyup.native="checkCapslock"
/> />
<span class="show_pwd" @click="showPwd"> <span class="show_pwd" @click="showPwd">
<div style="height: 10px;"></div> <div style="height: 10px"></div>
<i class="el-icon-view" /> <i class="el-icon-view" />
</span> </span>
</el-form-item> </el-form-item>
@@ -75,13 +70,13 @@
<p>记住密码</p> <p>记住密码</p>
</div> </div>
</div> </div>
<div style="height: 30px;"></div> <div style="height: 30px"></div>
<el-button <el-button
:loading="loading" :loading="loading"
type="primary" type="primary"
class="login_btn" class="login_btn"
@click.native.prevent="handleLogin" @click.native.prevent="handleLogin"
> </el-button > </el-button
> >
</el-form> </el-form>
</div> </div>
@@ -100,13 +95,14 @@
import Verify from "@/components/verifition/Verify"; import Verify from "@/components/verifition/Verify";
import cookies from "js-cookie"; import cookies from "js-cookie";
import { Decrypt, Encrypt } from "@/utils/index"; import { Decrypt, Encrypt } from "@/utils/index";
import { login } from "@/api/login"; import { login, logincas } from "@/api/login";
import { transPsw } from "@/utils/encrypted"; import { transPsw } from "@/utils/encrypted";
import { setToken, setAccessUser } from "@/utils/auth"; import { setToken, getToken, setAccessUser } from "@/utils/auth";
export default { export default {
name: "Login", name: "Login",
components: { components: {
Verify Verify,
}, },
data() { data() {
return { return {
@@ -115,11 +111,13 @@ export default {
loginForm: { loginForm: {
loginName: "", loginName: "",
password: "", password: "",
verifyCode: "" verifyCode: "",
}, },
loginRules: { loginRules: {
loginName: [{ required: true, message: "用户名必填", trigger: "blur" }], loginName: [{ required: true, message: "用户名必填", trigger: "blur" }],
password: [{ required: true, message: "用户密码必填", trigger: "blur" }] password: [
{ required: true, message: "用户密码必填", trigger: "blur" },
],
}, },
passwordType: "password", passwordType: "password",
capsTooltip: false, capsTooltip: false,
@@ -127,25 +125,45 @@ export default {
redirect: undefined, redirect: undefined,
otherQuery: {}, otherQuery: {},
needCaptcha: false, needCaptcha: false,
centerDialogVisible: false centerDialogVisible: false,
}; };
}, },
watch: { watch: {
$route: { $route: {
// 监听路由获取上个路由from的地址和参数 // 监听路由获取上个路由from的地址和参数
handler: function(route) { handler: function (route) {
const query = route.query; const query = route.query;
if (query) { if (query) {
this.redirect = query.redirect; this.redirect = query.redirect;
this.otherQuery = this.getOtherQuery(query); this.otherQuery = this.getOtherQuery(query);
} }
}, },
immediate: true immediate: true,
} },
}, },
mounted() { mounted() {
this.handleLoginFocus(); this.handleLoginFocus();
//获取url传参 ticket url
const ticket = this.$route.query.ticket;
let token = getToken();
console.log(ticket);
console.log(token);
if (ticket == undefined && token == null) {
//跳转统一身份认证
var isTs = true;
if (isTs) {
window.location.href = 'http://192.168.1.241/login?redirect=/lig/oauth2/oauth2/application&appid=330b4ecb60c9a6802b957fe1e5a5ecd3&url=http%3A%2F%2F192.168.1.241%3A8080%2F%23%2Flogin'+(this.redirect?'&ssUrl='+this.redirect:'');
// window.location.href = 'http://localhost/login?redirect=/lig/oauth2/oauth2/application&appid=330b4ecb60c9a6802b957fe1e5a5ecd3&url=http%3A%2F%2Flocalhost%3A9528%2F%23%2Flogin'+(this.redirect?'&ssUrl='+this.redirect:'');
}
} else if (ticket != undefined && token == null) {
//请求登录
this.logincasapi();
} else {
}
}, },
created() {},
methods: { methods: {
handleLoginFocus() { handleLoginFocus() {
if (this.loginForm.loginName === "") { if (this.loginForm.loginName === "") {
@@ -181,7 +199,7 @@ export default {
}, },
// 滑动验证码 // 滑动验证码
useVerify() { useVerify() {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate((valid) => {
if (valid) { if (valid) {
this.$refs.verify.show(); this.$refs.verify.show();
} else { } else {
@@ -198,7 +216,7 @@ export default {
}, },
// 登录操作 // 登录操作
handleLogin() { handleLogin() {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate((valid) => {
if (valid) { if (valid) {
this.loading = true; this.loading = true;
// 登录失败次数过多需要展示滑动验证码 // 登录失败次数过多需要展示滑动验证码
@@ -212,11 +230,41 @@ export default {
} }
}); });
}, },
async logincasapi() {
const ticket = this.$route.query.ticket;
const obj = {
loginName: ticket,
password: "demo",
verifyCode: "",
};
const { code, data } = await logincas(obj);
this.loading = false;
if (code != "200") return;
setToken(data.token);
setAccessUser(data);
debugger
// 选中记住密码时 把密码存到cookie里,时效15天
this.rememberPsw &&
cookies.set(
`u_${this.loginForm.loginName}`,
Encrypt(this.loginForm.password),
{ expires: 15 }
);
if (data && data.captcha) {
this.needCaptcha = true;
} else {
this.needCaptcha = false;
this.$router.push({
path: this.redirect || "/index",
query: this.otherQuery,
});
}
},
async loginApi() { async loginApi() {
const obj = { const obj = {
loginName: this.loginForm.loginName, loginName: this.loginForm.loginName,
password: transPsw(this.loginForm.password), password: transPsw(this.loginForm.password),
verifyCode: "" verifyCode: "",
}; };
const { code, data } = await login(obj); const { code, data } = await login(obj);
this.loading = false; this.loading = false;
@@ -236,7 +284,7 @@ export default {
this.needCaptcha = false; this.needCaptcha = false;
this.$router.push({ this.$router.push({
path: this.redirect || "/index", path: this.redirect || "/index",
query: this.otherQuery query: this.otherQuery,
}); });
} }
}, },
@@ -247,8 +295,8 @@ export default {
} }
return acc; return acc;
}, {}); }, {});
} },
} },
}; };
</script> </script>
@@ -260,15 +308,14 @@ export default {
opacity: 10; opacity: 10;
background: #fff; background: #fff;
} }
.delete { .delete {
color: #fff; color: #fff;
} }
.login_container { .login_container {
.el-input { .el-input {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
} }
.el-form-item { .el-form-item {
@@ -345,7 +392,7 @@ export default {
position: relative; position: relative;
width: 100%; width: 100%;
//height: calc(100% - 60px); //height: calc(100% - 60px);
height: 100%; height: 100%;
.login_img { .login_img {
display: block; display: block;
width: 100%; width: 100%;
@@ -359,22 +406,21 @@ export default {
min-width: 460px; min-width: 460px;
width: 22%; width: 22%;
height: 400px; height: 400px;
background-color: #006DD9; background-color: #006dd9;
opacity: 0.6; opacity: 0.6;
padding: 30px; padding: 30px;
overflow: hidden; overflow: hidden;
.title_container { .title_container {
position: relative; position: relative;
font-size: 22px; font-size: 22px;
color: #fff; color: #fff;
text-align: center; text-align: center;
} }
.form_fields { .form_fields {
position: relative; position: relative;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
.show_pwd { .show_pwd {
position: absolute; position: absolute;
right: 10px; right: 10px;
@@ -427,7 +473,7 @@ export default {
.login_btn { .login_btn {
min-width: 400px; min-width: 400px;
height: 40px; height: 40px;
background: #0BA1F8; background: #0ba1f8;
border: none; border: none;
// border-radius: 10px; // border-radius: 10px;
font-size: 20px; font-size: 20px;