测试环境最终

yfy
严飞永 1 month ago
parent 5409ad625b
commit 9e9f7a8c00

@ -5,8 +5,8 @@ VUE_APP_TITLE = 苏州工业园区工业上楼管理系统
ENV = 'development' ENV = 'development'
# 苏州工业园区工业上楼管理系统/开发环境 # 苏州工业园区工业上楼管理系统/开发环境
VUE_APP_BASE_API = 'http://192.168.0.108:7071' # VUE_APP_BASE_API = 'http://192.168.0.108:7071'
# VUE_APP_BASE_API = 'http://39.101.188.84:7071' VUE_APP_BASE_API = 'http://39.101.188.84:7071'
# 路由懒加载 # 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true

@ -7,10 +7,10 @@ ENV = 'production'
# 苏州工业园区工业上楼管理系统/生产环境 # 苏州工业园区工业上楼管理系统/生产环境
VUE_APP_BASE_API = '' # VUE_APP_BASE_API = 'http://114.216.202.175:8008'
# 公司测试环境 # 公司测试环境
# VUE_APP_BASE_API = 'http://39.101.188.84:7071' VUE_APP_BASE_API = 'http://39.101.188.84:7071'
# 正式环境 # 正式环境
# VUE_APP_BASE_API = '/api' # VUE_APP_BASE_API = '/api'

@ -23,6 +23,32 @@ export function getSpanById(id) {
method: "get", method: "get",
}); });
} }
//产业标签 新增数据
export function addCybq(data) {
return request({
url: "/gysl/Cybq/add",
method: "post",
data,
});
}
//产业标签 修改数据
export function updateSpan(data) {
return request({
url: "/gysl/Cybq/edit",
method: "post",
data,
});
}
//产业标签 删除数据
export function deleteSpan(idList) {
return request({
url: "/gysl/Cybq/delete",
method: "delete",
params: {
idList: idList.join(","), // 将数组转换为逗号分隔的字符串
},
});
}
// 通过主键查询单条所有数据(企业端) // 通过主键查询单条所有数据(企业端)
export function getBasicInformationById(id) { export function getBasicInformationById(id) {
@ -947,3 +973,11 @@ export function fetchInvestmentData(params) {
params, params,
}); });
} }
// 提示用户修改密码
export function getNewSysLogininfor() {
return request({
url: "/monitor/logininfor/getNewSysLogininfor",
method: "get",
})
}

@ -32,6 +32,14 @@ export function register(data) {
}) })
} }
// 刷新方法
export function refreshToken() {
return request({
url: '/refresh',
method: 'post'
})
}
// 获取用户详细信息 // 获取用户详细信息
export function getInfo() { export function getInfo() {
return request({ return request({

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

@ -2,13 +2,13 @@
<div class="navbar"> <div class="navbar">
<div class="navbarleft"> <div class="navbarleft">
<div class="logoimg"> <div class="logoimg">
<img src="../../assets/images/bluelogo@2x.png" alt=""> <img src="../../assets/images/bluelogo@2x.png" alt="" />
<span>苏州工业园区工业上楼管理系统</span> <span>苏州工业园区工业上楼管理系统</span>
</div> </div>
</div> </div>
<div class="right-menu"> <div class="right-menu">
<!-- <bearicon /> --> <!-- <bearicon /> -->
<div class="avatar-container right-menu-item hover-effect" style="display: flex;"> <!-- <div class="avatar-container right-menu-item hover-effect" style="display: flex;">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<div v-if="checkRole(['common','gov'])"> <div v-if="checkRole(['common','gov'])">
<span>{{ name }}</span> <span>{{ name }}</span>
@ -21,91 +21,98 @@
<router-link to="/user/profile" style="margin-left: 10px;margin-top: 1px;" v-if="checkRole(['admin'])"> <router-link to="/user/profile" style="margin-left: 10px;margin-top: 1px;" v-if="checkRole(['admin'])">
<i class="el-icon-user-solid"></i> <i class="el-icon-user-solid"></i>
</router-link> </router-link>
</div> </div> -->
<!-- <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click"> <el-dropdown
class="avatar-container right-menu-item hover-effect"
trigger="click"
>
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img :src="avatar" class="user-avatar"> <img :src="avatar" class="user-avatar" />
<div style="margin-left: 5px;">
<span>{{ name }}</span>
</div>
<i class="el-icon-caret-bottom" /> <i class="el-icon-caret-bottom" />
</div> </div>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<router-link to="/user/profile"> <router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item> <el-dropdown-item>个人中心</el-dropdown-item>
</router-link> </router-link>
<el-dropdown-item @click.native="setting = true"> <!-- <el-dropdown-item @click.native="setting = true">
<span>布局设置</span> <span>布局设置</span>
</el-dropdown-item> </el-dropdown-item> -->
<el-dropdown-item divided @click.native="logout"> <el-dropdown-item divided @click.native="logout">
<span>退出登录</span> <span>退出登录</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> --> </el-dropdown>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from "vuex";
import Breadcrumb from '@/components/Breadcrumb' import Breadcrumb from "@/components/Breadcrumb";
import TopNav from '@/components/TopNav' import TopNav from "@/components/TopNav";
import bearicon from '@/components/bearicon' import bearicon from "@/components/bearicon";
import { checkPermi, checkRole } from "@/utils/permission" import { checkPermi, checkRole } from "@/utils/permission";
export default { export default {
components: { components: {
Breadcrumb, Breadcrumb,
TopNav, TopNav,
bearicon bearicon,
}, },
data() { data() {
return { return {
username: "", username: "",
messages: [], messages: [],
counts: 0 // counts: 0, //
} };
}, },
computed: { computed: {
...mapGetters(["avatar", "name", "sidebarRouters", "nickName"]), ...mapGetters(["avatar", "name", "sidebarRouters", "nickName"]),
// //
showCompanySection() { showCompanySection() {
const isCompany = this.checkRole(['company']) const isCompany = this.checkRole(["company"]);
const isCommon = this.checkRole(['common','gov']) const isCommon = this.checkRole(["common", "gov"]);
return isCompany && !isCommon return isCompany && !isCommon;
}, },
topNav: { topNav: {
get() { get() {
return this.$store.state.settings.topNav return this.$store.state.settings.topNav;
} },
}, },
unreadMessages() { unreadMessages() {
return this.messages.length return this.messages.length;
} },
}, },
mounted() { mounted() {
this.username = this.$store.state.user.nickName this.username = this.$store.state.user.nickName;
}, },
methods: { methods: {
checkPermi, checkPermi,
checkRole, checkRole,
toggleSideBar() { toggleSideBar() {
this.$store.dispatch('app/toggleSideBar') this.$store.dispatch("app/toggleSideBar");
}, },
logout() { logout() {
this.$confirm('确定注销并退出系统吗?', '提示', { this.$confirm("确定注销并退出系统吗?", "提示", {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
type: 'warning' type: "warning",
}).then(() => {
this.$store.dispatch('LogOut').then(() => {
this.$router.replace('/login')
}) })
}).catch(() => { }) .then(() => {
this.$store.dispatch("LogOut").then(() => {
this.$router.replace("/login");
});
})
.catch(() => {});
}, },
handleCommand(command) { handleCommand(command) {
this.$message('点击了: ' + command) this.$message("点击了: " + command);
} },
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -119,7 +126,7 @@ export default {
.logoimg { .logoimg {
display: flex; display: flex;
align-items: center; align-items: center;
gap: .8rem; gap: 0.8rem;
} }
.logoimg img { .logoimg img {
@ -134,7 +141,7 @@ export default {
font-family: AlibabaPuHuiTi; font-family: AlibabaPuHuiTi;
font-weight: 500; font-weight: 500;
font-size: 1.5rem; font-size: 1.5rem;
color: #292C33; color: #292c33;
line-height: 2.06rem; line-height: 2.06rem;
text-align: left; text-align: left;
font-style: normal; font-style: normal;
@ -151,11 +158,11 @@ export default {
height: 100%; height: 100%;
float: left; float: left;
cursor: pointer; cursor: pointer;
transition: background .3s; transition: background 0.3s;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: rgba(0, 0, 0, 0.025);
} }
} }
@ -193,10 +200,10 @@ export default {
&.hover-effect { &.hover-effect {
cursor: pointer; cursor: pointer;
transition: background .3s; transition: background 0.3s;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: rgba(0, 0, 0, 0.025);
} }
} }
} }
@ -234,7 +241,7 @@ export default {
.item { .item {
margin-right: 10px; margin-right: 10px;
margin-top: .5rem; margin-top: 0.5rem;
.el-dropdown-link { .el-dropdown-link {
color: black; color: black;

@ -13,34 +13,78 @@ import { governmentGetInfo } from "@/api/login/index";
NProgress.configure({ showSpinner: false }); NProgress.configure({ showSpinner: false });
const whiteList = ["/login", "/register","/system/singlelogin/login"]; const whiteList = ["/login", "/entLogin", "/register"]; // 白名单路径
const isWhiteList = (path) => { const isWhiteList = (path) => {
return whiteList.some((pattern) => isPathMatch(pattern, path)); return whiteList.some((pattern) => isPathMatch(pattern, path));
}; };
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
if(!extractPrefix(to.path)){ if (!extractPrefix(to.path)) {
store.commit("SET_CRUMBS",false); store.commit("SET_CRUMBS", false);
} }
NProgress.start(); NProgress.start();
const search = window.location.search || window.location.hash.split("?")[1] || "";
const search =
window.location.search || window.location.hash.split("?")[1] || "";
const params = new URLSearchParams(search); const params = new URLSearchParams(search);
const userToken = params.get("userToken"); const userToken = params.get("userToken");
const signature = params.get("signature"); const signature = params.get("signature");
const timespan = params.get("timespan"); const timespan = params.get("timespan");
// =============================
// 🔑 新增:处理 clienttoken 登录逻辑
// =============================
if (window.location.href.includes("clienttoken=")) {
const reg = /[?&]clienttoken=([^&#]+)/;
const match = window.location.href.match(reg);
const clienttoken = match && match[1];
if (clienttoken) {
// 清除 clienttoken 避免死循环
let modifiedUrl = window.location.href.replace(/[?&]clienttoken=[^&#]+/, '');
if (modifiedUrl.endsWith('?') || modifiedUrl.endsWith('&')) {
modifiedUrl = modifiedUrl.slice(0, -1); // 去掉末尾多余的符号
}
// 如果 roles 还未加载,则拉取用户信息
if (store.getters.roles.length === 0) {
isRelogin.show = true;
store.dispatch("SingleSignOnGetInfo", { clientToken: clienttoken })
.then(() => {
isRelogin.show = false;
// 清除 URL 中的 clienttoken 并刷新页面
window.history.replaceState({}, '', modifiedUrl);
// 获取用户权限并生成路由
return store.dispatch("GenerateRoutes");
})
.then((accessRoutes) => {
router.addRoutes(accessRoutes);
next({ ...to, replace: true });
})
.catch((err) => {
// console.error("单点登录失败:", err);
store.dispatch("LogOut").then(() => {
// Message.error("单点登录失败,请重试");
window.location.href = "https://qytt.sipac.gov.cn/ecobrainportal/index.html";
});
});
return;
}
}
}
// 如果已经处理过一次登录逻辑,不再重复执行 // =============================
// 📦 原有政务参数处理逻辑
// =============================
if (from.path === to.path && store.getters.token) { if (from.path === to.path && store.getters.token) {
next(); next();
return; return;
} }
// 如果存在政务参数,并且不在登录页,则强制跳转过去
if (userToken && signature && timespan && to.path !== "/login") { if (userToken && signature && timespan && to.path !== "/login") {
next({ next({
path: "/login", path: "/login",
@ -55,7 +99,6 @@ router.beforeEach((to, from, next) => {
.then((res) => { .then((res) => {
const token = res.data.token; const token = res.data.token;
if (!token) { if (!token) {
// 清除 URL 参数,避免循环
const cleanPath = const cleanPath =
window.location.pathname + window.location.hash.split("?")[0]; window.location.pathname + window.location.hash.split("?")[0];
window.history.replaceState({}, "", cleanPath); window.history.replaceState({}, "", cleanPath);
@ -65,18 +108,15 @@ router.beforeEach((to, from, next) => {
setToken(token); setToken(token);
localStorage.setItem("otherToken", userToken); localStorage.setItem("otherToken", userToken);
// 清除 URL 参数
const cleanPath = const cleanPath =
window.location.pathname + (window.location.hash || ""); window.location.pathname + (window.location.hash || "");
window.history.replaceState({}, "", cleanPath); window.history.replaceState({}, "", cleanPath);
// 如果已有角色信息,直接跳转
if (store.getters.roles.length > 0) { if (store.getters.roles.length > 0) {
next("/"); next("/");
return; return;
} }
// 否则获取用户信息并加载路由
isRelogin.show = true; isRelogin.show = true;
store store
.dispatch("GetInfo") .dispatch("GetInfo")
@ -86,7 +126,7 @@ router.beforeEach((to, from, next) => {
}) })
.then((accessRoutes) => { .then((accessRoutes) => {
router.addRoutes(accessRoutes); router.addRoutes(accessRoutes);
next(to.query.redirect || "/"); // 跳转到目标页或首页 next(to.query.redirect || "/");
}) })
.catch((err) => { .catch((err) => {
console.error("获取用户信息失败:", err); console.error("获取用户信息失败:", err);
@ -98,7 +138,6 @@ router.beforeEach((to, from, next) => {
}) })
.catch((err) => { .catch((err) => {
console.error("政务系统登录失败:", err); console.error("政务系统登录失败:", err);
// 清除 URL 参数,避免循环
const cleanPath = const cleanPath =
window.location.pathname + (window.location.hash || ""); window.location.pathname + (window.location.hash || "");
window.history.replaceState({}, "", cleanPath); window.history.replaceState({}, "", cleanPath);
@ -108,9 +147,10 @@ router.beforeEach((to, from, next) => {
return; return;
} }
// 原始本地登录逻辑 // =============================
// 🔐 原始本地登录逻辑
// =============================
const token = getToken(); const token = getToken();
if (token) { if (token) {
to.meta.title && store.dispatch("settings/setTitle", to.meta.title); to.meta.title && store.dispatch("settings/setTitle", to.meta.title);
if (to.path === "/login") { if (to.path === "/login") {

@ -1,17 +1,24 @@
import { login, logout, getInfo } from "@/api/login"; import { login, logout, getInfo,refreshToken } from "@/api/login";
import { getToken, setToken, removeToken } from "@/utils/auth"; import { getToken, setToken, removeToken, setExpiresIn, getClientToken, setClientToken, removeClientToken, getUSerToken, setUserToken, removeUSerToken } from '@/utils/auth'
import { isHttp, isEmpty } from "@/utils/validate"; import { isHttp, isEmpty } from "@/utils/validate";
import defAva from "@/assets/images/profile.jpg"; import defAva from "@/assets/images/profile.jpg";
import { governmentGetInfo } from "@/api/login"; import { singleSigngetInfo, enterpriseLogout, governmentGetInfo } from "@/api/login/index";
const user = { const user = {
state: { state: {
token: getToken(), token: getToken(),
id: "", clientToken: getClientToken(),
name: "", userToken: getUSerToken(),
avatar: "", id: '',
name: '',
avatar: '',
roles: [], roles: [],
permissions: [], permissions: [],
expires_in: '',
enterpriseId: '',
nickName: '',
userType: '',
deptId: '',
}, },
mutations: { mutations: {
@ -55,7 +62,30 @@ const user = {
}); });
}); });
}, },
// 企业端登录
SingleSignOnGetInfo({ commit, state },info) {
return new Promise((resolve, reject) => {
singleSigngetInfo({clientToken: info.clientToken}).then(res => {
// if (res.data.usertype && res.data.usertype.length > 0) { // 验证返回的roles是否是一个非空数组
// let roles = [];
// roles.push(res.data.usertype)
// commit('SET_ROLES', roles)
// } else {
// commit('SET_ROLES', ['ROLE_DEFAULT'])
// }
setClientToken(info.clientToken)
commit('SET_CLIENTTOKEN', res.data.token)
setToken(res.data.token)
commit('SET_TOKEN', res.data.token)
// commit('SET_USERTYPE', res.data.usertype)
// console.log(res.data.usertype,"res.data.usertype");
// console.log(state.roles,"state.roles");
resolve()
}).catch(error => {
reject(error)
})
})
},
// 政务端登录 // 政务端登录
governmentLogin({ commit, state }, info) { governmentLogin({ commit, state }, info) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -105,23 +135,54 @@ const user = {
}); });
}); });
}, },
// 刷新token
// 退出系统 RefreshToken({commit, state}) {
LogOut({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout(state.token) refreshToken(state.token).then(res => {
setExpiresIn(res.data)
commit('SET_EXPIRES_IN', res.data)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 退出系统
LogOut({ commit, state }) {
if (!state.token && state.clientToken) {
return enterpriseLogout({ clienttoken: state.clientToken })
.then(() => { .then(() => {
commit("SET_TOKEN", ""); commit('SET_CLIENTTOKEN', '');
commit("SET_ROLES", []); removeClientToken();
commit("SET_PERMISSIONS", []); });
removeToken(); } else if (state.token && state.clientToken) {
resolve(); return enterpriseLogout({ clienttoken: state.clientToken })
.then(() => {
commit('SET_CLIENTTOKEN', '');
removeClientToken();
return logout(state.token); // 再调用本地登出
}) })
.catch((error) => { .then(() => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
commit('SET_PERMISSIONS', []);
removeToken();
return Promise.resolve({ userType: state.userType });
});
} else {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
commit('SET_PERMISSIONS', []);
removeToken();
resolve({ userType: state.userType });
}).catch(error => {
reject(error); reject(error);
}); });
}); });
}, }
},
// 前端 登出 // 前端 登出
FedLogOut({ commit }) { FedLogOut({ commit }) {

@ -1,6 +1,9 @@
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token' const TokenKey = 'Admin-Token'
const ClientToken = 'ClientToken'
const UserToken = 'UserToken'
const ExpiresInKey = 'Admin-Expires-In'
export function getToken() { export function getToken() {
return Cookies.get(TokenKey) return Cookies.get(TokenKey)
@ -13,3 +16,42 @@ export function setToken(token) {
export function removeToken() { export function removeToken() {
return Cookies.remove(TokenKey) return Cookies.remove(TokenKey)
} }
export function getExpiresIn() {
return Cookies.get(ExpiresInKey) || -1
}
export function setExpiresIn(time) {
return Cookies.set(ExpiresInKey, time)
}
export function removeExpiresIn() {
return Cookies.remove(ExpiresInKey)
}
// 企业端登录的clientToken
export function getClientToken() {
return Cookies.get(ClientToken)
}
export function setClientToken(token) {
return Cookies.set(ClientToken, token)
}
export function removeClientToken() {
return Cookies.remove(ClientToken)
}
// 政务端登录的userToken
export function getUSerToken() {
return Cookies.get(UserToken)
}
export function setUserToken(token) {
return Cookies.set(UserToken, token)
}
export function removeUSerToken() {
return Cookies.remove(UserToken)
}

@ -730,7 +730,6 @@ export default {
return true; return true;
}, },
// //
//
prepareFormData(formData) { prepareFormData(formData) {
// //
const formatDate = (date) => { const formatDate = (date) => {
@ -742,7 +741,7 @@ export default {
return { return {
...formData, ...formData,
begainTime: formatDate(formData.begainTime), // begainTime begainTime: formatDate(formData.begainTime), // begainTime
endTime: formatDate(formData.endTime), // endTime endTime: formatDate(formData.endTime),
createBy: "", createBy: "",
createId: 0, createId: 0,
createTime: "", createTime: "",

@ -306,7 +306,7 @@ export default {
return; return;
} }
this.$confirm(`确定要删除"${this.TypeMap[type]}"类型及其所有标签吗?`, '提示', { this.$confirm(`确定要删除类型及其所有标签吗?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'

@ -67,7 +67,7 @@ export default {
<style scoped> <style scoped>
.progress-container { .progress-container {
width: 100%; width: 100%;
height: 9rem; height: 100%;
padding: 0 3rem 0 0; padding: 0 3rem 0 0;
overflow: auto; overflow: auto;
font-family: aliregular; font-family: aliregular;

@ -46,8 +46,8 @@
<i class="el-icon-close"></i> <i class="el-icon-close"></i>
</div> </div>
<div class="dialog-content"> <div class="dialog-content">
<!-- @click="goToDetail" --> <!-- @click="goToDetail" -->
<div class="dialog-title">{{ selectedProject.name }}</div> <div class="dialog-title" @click="goToDetail">{{ selectedProject.name }}</div>
<div class="dialog-info"> <div class="dialog-info">
<p><span class="label">状态:</span> <p><span class="label">状态:</span>
<span class="value" :style="{ color: xzflColors[xzflMap[selectedProject.xzfl]] }"> <span class="value" :style="{ color: xzflColors[xzflMap[selectedProject.xzfl]] }">
@ -498,7 +498,7 @@ export default {
/* 所有容器 */ /* 所有容器 */
.container { .container {
position: relative; position: relative;
height: 100%; height: 22rem;
} }
.mapareaone { .mapareaone {

@ -1,9 +1,13 @@
<template> <template>
<div class="login"> <div class="login">
<div class="loginleft"> <div class="loginleft"></div>
</div> <el-form
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> ref="loginForm"
<img src="@/assets/images/logo@2x.png" alt=""> :model="loginForm"
:rules="loginRules"
class="login-form"
>
<img src="@/assets/images/logo@2x.png" alt="" />
<div class="title">苏州工业园区工业上楼管理系统</div> <div class="title">苏州工业园区工业上楼管理系统</div>
<div class="logintabs"> <div class="logintabs">
<el-tabs v-model="activeName" :stretch="true" color="#216CDC"> <el-tabs v-model="activeName" :stretch="true" color="#216CDC">
@ -11,44 +15,98 @@
<el-tab-pane label="政务人员登录" name="second"></el-tab-pane> <el-tab-pane label="政务人员登录" name="second"></el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
<el-form-item prop="username" class="loginitem" style="margin-top: 1rem;"> <el-form-item prop="username" class="loginitem" style="margin-top: 1rem">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号"> <el-input
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon
slot="prefix"
icon-class="user"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password" class="loginitem"> <el-form-item prop="password" class="loginitem">
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" <el-input
@keyup.enter.native="handleLogin"> v-model="loginForm.password"
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="password"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="captchaEnabled" class="loginitem"> <!-- <el-form-item prop="code" v-if="captchaEnabled" class="loginitem">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" <el-input
@keyup.enter.native="handleLogin"> v-model="loginForm.code"
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="validCode"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
<div class="login-code"> <div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" style="width: 8.56rem;" /> <img
:src="codeUrl"
@click="getCode"
class="login-code-img"
style="width: 8.56rem"
/>
</div> </div>
</el-form-item> </el-form-item> -->
<el-checkbox v-model="loginForm.rememberMe" style="margin:1rem 18.6rem 25px 0px;"></el-checkbox> <el-checkbox
<el-form-item style="width:24rem;;margin-top: 1rem;"> v-model="loginForm.rememberMe"
<el-button :loading="loading" size="medium" type="primary" style="width:100%;background: #2B62F1;" style="margin: 1rem 18.6rem 25px 0px"
@click.native.prevent="handleLogin"> >记住密码</el-checkbox
>
<el-form-item style="width: 24rem; margin-top: 1rem">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width: 100%; background: #2b62f1"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"> </span> <span v-if="!loading"> </span>
<span v-else> ...</span> <span v-else> ...</span>
</el-button> </el-button>
<el-button v-if="showGovernmentLoginButton" size="medium" type="primary" class="tongyidenglu" <!-- <el-button
style="width:100%;background: #2B62F1;" @click.native.prevent="handleGovernmentLogin"> v-if="showGovernmentLoginButton"
size="medium"
type="primary"
class="tongyidenglu"
style="width: 100%; background: #2b62f1"
@click.native.prevent="handleGovernmentLogin"
>
<span>政务统一身份认证登录</span> <span>政务统一身份认证登录</span>
</el-button> </el-button> -->
<el-button v-if="showEnterpriseLoginButton" size="medium" type="primary" class="tongyidenglu" <el-button
style="width:100%;background: #2B62F1;" @click.native.prevent="handleEnterpriseLogin"> v-if="showEnterpriseLoginButton"
size="medium"
type="primary"
class="tongyidenglu"
style="width: 100%; background: #2b62f1"
@click.native.prevent="handleEnterpriseLogin"
>
<span>企业统一身份认证登录</span> <span>企业统一身份认证登录</span>
</el-button> </el-button>
</el-form-item> </el-form-item>
<div style="font-size: 0.88rem;color: #333;">主办单位苏州工业园区经济发展委员会</div> <div style="font-size: 0.88rem; color: #333">
主办单位苏州工业园区经济发展委员会
</div>
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div class="el-login-footer"> <div class="el-login-footer">
@ -58,72 +116,73 @@
</template> </template>
<script> <script>
import { getCodeImg } from '@/api/login' import { getCodeImg } from "@/api/login";
import Cookies from 'js-cookie' import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt' import { encrypt, decrypt } from "@/utils/jsencrypt";
import forge from 'node-forge' import forge from "node-forge";
export default { export default {
name: 'Login', name: "Login",
data() { data() {
return { return {
codeUrl: '', codeUrl: "",
activeName: 'second', activeName: "second",
loginForm: { loginForm: {
username: '', username: "",
password: '', password: "",
rememberMe: false, rememberMe: false,
code: '', // code: "",
uuid: '', uuid: "",
loginRole: 2 loginRole: 2,
}, },
loginRules: { loginRules: {
username: [ username: [
{ required: true, trigger: 'blur', message: '请输入您的账号' } { required: true, trigger: "blur", message: "请输入您的账号" },
], ],
password: [ password: [
{ required: true, trigger: 'blur', message: '请输入您的密码' } { required: true, trigger: "blur", message: "请输入您的密码" },
], ],
code: [{ required: true, trigger: 'change', message: '请输入验证码' }] // code: [{ required: true, trigger: "change", message: "" }],
}, },
loading: false, loading: false,
captchaEnabled: true, captchaEnabled: true,
register: false, register: false,
redirect: undefined, redirect: undefined,
a1: `MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl8bS1kYTiMhIS5MZU253bc0ukaxrA1lfCziABFxQrC2c09tMrQGjuH6V1x2ofNBMGhOD9uWN/qkAQy/HwOe/NKUqCw6N0ov6guSrqMDW/BdZ3Bl0rmM1/95jTC1xffFFvej7xWNffIbaPI+bJ4WLX9NViNi9HmT0BRNzJ4d2R86LPPCa+bxLaPjsh2R2tBkbLkUot9769aJaPPiwPCZHMkuQenjHSmpWL0okleqMH8EGX7j6A5A/4IUXPMNKMMzkiSRpsIJ65GJmDAbnR3ZXRfC8MzVBBJB6zr5N0F4N9xZfF+JS/Yx726tCu+rA6GDCyTxtQ/wnKpPdwFP5nUWCWQIDAQAB` a1: `MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl8bS1kYTiMhIS5MZU253bc0ukaxrA1lfCziABFxQrC2c09tMrQGjuH6V1x2ofNBMGhOD9uWN/qkAQy/HwOe/NKUqCw6N0ov6guSrqMDW/BdZ3Bl0rmM1/95jTC1xffFFvej7xWNffIbaPI+bJ4WLX9NViNi9HmT0BRNzJ4d2R86LPPCa+bxLaPjsh2R2tBkbLkUot9769aJaPPiwPCZHMkuQenjHSmpWL0okleqMH8EGX7j6A5A/4IUXPMNKMMzkiSRpsIJ65GJmDAbnR3ZXRfC8MzVBBJB6zr5N0F4N9xZfF+JS/Yx726tCu+rA6GDCyTxtQ/wnKpPdwFP5nUWCWQIDAQAB`,
} };
}, },
watch: { watch: {
$route: { $route: {
handler: function (route) { handler: function (route) {
this.redirect = route.query && route.query.redirect; this.redirect = route.query && route.query.redirect;
}, },
immediate: true immediate: true,
}, },
activeName(newVal) { activeName(newVal) {
if (newVal === 'first') { if (newVal === "first") {
this.loginForm.loginRole = 2 this.loginForm.loginRole = 2;
} else if (newVal === 'second') { } else if (newVal === "second") {
this.loginForm.loginRole = 1 this.loginForm.loginRole = 1;
}
} }
}, },
},
computed: { computed: {
showGovernmentLoginButton() { showGovernmentLoginButton() {
return this.activeName === 'second' return this.activeName === "second";
}, },
showEnterpriseLoginButton() { showEnterpriseLoginButton() {
return this.activeName === 'first' return this.activeName === "first";
} },
}, },
created() { created() {
this.getCode() this.getCode();
this.getCookie() this.getCookie();
}, },
methods: { methods: {
getCode() { getCode() {
getCodeImg().then(res => { getCodeImg().then((res) => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled; this.captchaEnabled =
res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (this.captchaEnabled) { if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img; this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid; this.loginForm.uuid = res.uuid;
@ -131,46 +190,50 @@ export default {
}); });
}, },
getCookie() { getCookie() {
const username = Cookies.get('username') const username = Cookies.get("username");
const password = Cookies.get('password') const password = Cookies.get("password");
const rememberMe = Cookies.get('rememberMe') const rememberMe = Cookies.get("rememberMe");
this.loginForm = { this.loginForm = {
username: username === undefined ? this.loginForm.username : username, username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password), password:
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) password === undefined ? this.loginForm.password : decrypt(password),
} rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
};
}, },
handleLogin() { handleLogin() {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate((valid) => {
if (valid) { if (valid) {
this.loading = true; this.loading = true;
if (this.loginForm.rememberMe) { if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 }); Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); Cookies.set("password", encrypt(this.loginForm.password), {
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); expires: 30,
});
Cookies.set("rememberMe", this.loginForm.rememberMe, {
expires: 30,
});
} else { } else {
Cookies.remove("username"); Cookies.remove("username");
Cookies.remove("password"); Cookies.remove("password");
Cookies.remove('rememberMe'); Cookies.remove("rememberMe");
} }
// 2048 RSA // 2048 RSA
const lines = []; const lines = [];
lines.push('-----BEGIN PUBLIC KEY-----'); lines.push("-----BEGIN PUBLIC KEY-----");
for (let i = 0; i < this.a1.length; i += 64) { for (let i = 0; i < this.a1.length; i += 64) {
lines.push(this.a1.slice(i, i + 64)); lines.push(this.a1.slice(i, i + 64));
} }
lines.push('-----END PUBLIC KEY-----'); lines.push("-----END PUBLIC KEY-----");
lines.join('\n') lines.join("\n");
const publicKey = forge.pki.publicKeyFromPem(lines.join('\n')); const publicKey = forge.pki.publicKeyFromPem(lines.join("\n"));
// //
var dataBytes = forge.util.encodeUtf8(this.loginForm.password); var dataBytes = forge.util.encodeUtf8(this.loginForm.password);
// //
var encryptedBytes = publicKey.encrypt(dataBytes, 'RSA-OAEP', { var encryptedBytes = publicKey.encrypt(dataBytes, "RSA-OAEP", {
md: forge.md.sha256.create(), md: forge.md.sha256.create(),
mgf1: { mgf1: {
md: forge.md.sha1.create() md: forge.md.sha1.create(),
} },
}); });
// Base64 // Base64
var encryptedBase64 = forge.util.encode64(encryptedBytes); var encryptedBase64 = forge.util.encode64(encryptedBytes);
@ -181,39 +244,41 @@ export default {
password: encryptedBase64, password: encryptedBase64,
code: this.loginForm.code, code: this.loginForm.code,
uuid: this.loginForm.uuid, uuid: this.loginForm.uuid,
loginRole: this.activeName === 'first' ? 2 : 1 loginRole: this.activeName === "first" ? 2 : 1,
}; };
this.$store.dispatch('Login', loginData) this.$store
.dispatch("Login", loginData)
.then(() => { .then(() => {
this.$router.push({ path: this.redirect || '/' }).catch(() => { }); this.$router.push({ path: this.redirect || "/" }).catch(() => {});
}) })
.catch((error) => { .catch((error) => {
this.loading = false; this.loading = false;
if (this.captchaEnabled) { if (this.captchaEnabled) {
this.getCode(); this.getCode();
} }
console.error('登录失败:', error); console.error("登录失败:", error);
}); });
} }
}); });
}, },
handleGovernmentLogin() { handleGovernmentLogin() {
location.href = 'https://qyt.sipac.gov.cn/sipsg-enterprise-mobile-manage/#/login' location.href =
"https://qyt.sipac.gov.cn/sipsg-enterprise-mobile-manage/#/login";
}, },
handleEnterpriseLogin() { handleEnterpriseLogin() {
location.href = process.env.VUE_APP_BASE_API + "/system/singlelogin/login"; location.href =
} process.env.VUE_APP_BASE_API + "/system/singlelogin/login";
} },
} },
};
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-tabs__active-bar { ::v-deep .el-tabs__active-bar {
width: 2rem !important; width: 2rem !important;
margin-left: 3rem; margin-left: 3rem;
background-color: #216CDC; background-color: #216cdc;
height: 0.21rem; height: 0.21rem;
border-radius: 0.16rem; border-radius: 0.16rem;
} }
@ -225,14 +290,14 @@ export default {
::v-deep .el-tabs__item { ::v-deep .el-tabs__item {
font-size: 1rem; font-size: 1rem;
padding: 0 20px; padding: 0 20px;
color: #3D424C; color: #3d424c;
font-family: Alibaba PuHuiTi; font-family: Alibaba PuHuiTi;
font-weight: 400; font-weight: 400;
color: #3D424C; color: #3d424c;
} }
::v-deep .el-tabs__item.is-active { ::v-deep .el-tabs__item.is-active {
color: #216CDC; color: #216cdc;
} }
::v-deep .el-tabs__nav-wrap::after { ::v-deep .el-tabs__nav-wrap::after {
@ -250,14 +315,14 @@ export default {
align-items: center; align-items: center;
border-radius: 6px 0 0 6px; border-radius: 6px 0 0 6px;
height: 100%; height: 100%;
background-image: url('../assets/images/loginbackground.png'); background-image: url("../assets/images/loginbackground.png");
background-size: cover; background-size: cover;
} }
.loginleft { .loginleft {
width: 35rem; width: 35rem;
height: 40rem; height: 40rem;
background-image: url('../assets/images/loginleft.png'); background-image: url("../assets/images/loginleft.png");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
@ -268,7 +333,7 @@ export default {
font-family: Alibaba PuHuiTi; font-family: Alibaba PuHuiTi;
font-weight: 500; font-weight: 500;
font-size: 2rem; font-size: 2rem;
color: #292C33; color: #292c33;
line-height: 3.5rem; line-height: 3.5rem;
text-align: center; text-align: center;
margin-top: 1rem; margin-top: 1rem;
@ -349,7 +414,7 @@ export default {
} }
.el-tabs__item.is-active { .el-tabs__item.is-active {
color: #216CDC; color: #216cdc;
position: relative; position: relative;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
} }

@ -12,20 +12,20 @@
label-width="200" label-width="200"
> >
<el-row> <el-row>
<el-col :span="5"> <!-- <el-col :span="5">
<el-form-item label="企业名称" style="width: 100%"> <el-form-item label="企业名称" style="width: 100%">
<el-input <el-input
v-model="queryParams.name" v-model="queryParams.epname"
placeholder="请输入企业名称" placeholder="请输入企业名称"
clearable clearable
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="5"> <el-col :span="5">
<el-form-item label="标签代码" style="width: 100%"> <el-form-item label="标签代码" style="width: 100%">
<el-input <el-input
v-model="queryParams.bqdm" v-model="queryParams.catalogueid"
placeholder="请输入标签代码" placeholder="请输入标签代码"
clearable clearable
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
@ -35,7 +35,7 @@
<el-col :span="5"> <el-col :span="5">
<el-form-item label="标签状态" style="width: 100%"> <el-form-item label="标签状态" style="width: 100%">
<el-input <el-input
v-model="queryParams.bqzt" v-model="queryParams.status"
placeholder="请输入标签状态" placeholder="请输入标签状态"
clearable clearable
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
@ -43,18 +43,6 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="5"> <el-col :span="5">
<el-form-item label="用户类型">
<el-input
v-model="queryParams.yhlx"
placeholder="请输入用户类型"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item> <el-form-item>
<el-button <el-button
type="primary" type="primary"
@ -72,11 +60,20 @@
</div> </div>
<!-- 表格内容区 --> <!-- 表格内容区 -->
<div class="table-container"> <div class="table-container">
<!-- 导出行 -->
<div class="table-header">
<el-row :gutter="4" class="mb8">
<el-col :span="1.5">
<el-button type="primary" icon="el-icon-plus" @click="handleAdd"
>新增</el-button
>
</el-col>
</el-row>
</div>
<div class="table-wrapper"> <div class="table-wrapper">
<el-table <el-table
v-loading="loading" v-loading="loading"
:data="postList" :data="postList"
@selection-change="handleSelectionChange"
stripe stripe
height="100%" height="100%"
> >
@ -90,20 +87,20 @@
<el-table-column <el-table-column
label="企业名称" label="企业名称"
align="center" align="center"
prop="name" prop="epname"
width="200" width="200"
/> />
<el-table-column <el-table-column
label="统一信用代码" label="统一信用代码"
align="center" align="center"
prop="tyshxydm" prop="uscc"
width="200" width="200"
/> />
<el-table-column label="标签代码" align="center" prop="bqdm" /> <el-table-column label="标签代码" align="center" prop="catalogueid" />
<el-table-column <!-- <el-table-column
label="有效状态" label="有效状态"
align="center" align="center"
prop="state" prop="status"
width="200" width="200"
/> />
<el-table-column <el-table-column
@ -111,14 +108,14 @@
align="center" align="center"
width="130" width="130"
prop="yhlx" prop="yhlx"
/> /> -->
<el-table-column <el-table-column
label="标签注释" label="标签注释"
align="center" align="center"
width="180" width="180"
prop="bqzs" prop="lablenotes"
/> />
<el-table-column label="标签状态" align="center" prop="bqzt" /> <el-table-column label="标签状态" align="center" prop="status" />
<el-table-column <el-table-column
label="操作" label="操作"
align="center" align="center"
@ -129,13 +126,18 @@
<el-button type="text" @click="getAdd(scope.row, 'detail')" <el-button type="text" @click="getAdd(scope.row, 'detail')"
>详情</el-button >详情</el-button
> >
<el-button
type="text"
@click="handleDelete(scope.row)"
style="color: red"
>删除</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<div class="pagination-wrapper"> <div class="pagination-wrapper">
<pagination <pagination
:total="total" :total="total"
:page.sync="queryParams.current" :page.sync="queryParams.current"
:limit.sync="queryParams.size" :limit.sync="queryParams.size"
@ -144,132 +146,111 @@
</div> </div>
</div> </div>
<!-- 详情弹窗 --> <!-- 新增/编辑弹窗 -->
<el-dialog title="详情" :visible.sync="dialogVisible" width="50%"> <el-dialog
<el-form :model="detailData" label-width="200px"> :title="dialogTitle"
<el-row> :visible.sync="dialogFormVisible"
<el-col :span="12"> width="50%"
<el-form-item label="企业名称:"> >
<span>{{ detailData.name }}</span> <el-form ref="form" :model="form" label-width="200px">
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="统一信用代码:">
<span>{{ detailData.tyshxydm }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="标签标记场景代码:">
<span>{{ detailData.bqdm }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标签代码:">
<span>{{ detailData.state }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="标签值编码:">
<span>{{ detailData.bqzbm }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="有效状态:">
<span>{{ detailData.state }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="标签注释:"> <el-form-item label="企业名称">
<span>{{ detailData.bqzs }}</span> <el-input v-model="form.epname" placeholder="请输入企业名称" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户类型:"> <el-form-item label="统一社会信用代码">
<span>{{ detailData.yhlx }}</span> <el-input
v-model="form.uscc"
placeholder="请输入统一社会信用代码"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="标签标记用户:"> <el-form-item label="标签代码">
<span>{{ detailData.bqzt }}</span> <el-input
v-model="form.catalogueid"
placeholder="请输入标签代码"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="标签标记单位:"> <el-form-item label="标签注释">
<span>{{ detailData.bqbjdw }}</span> <el-input
v-model="form.lablenotes"
placeholder="请输入标签注释"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="标签状态:"> <el-form-item label="标签状态">
<span>{{ detailData.bqzt }}</span> <el-input v-model="form.status" placeholder="请输入标签状态" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数据来源名称:">
<span>{{ detailData.sjlymc }}</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button> <div slot="footer">
</span> <el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm"></el-button>
</div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { getCybqInformationPage, getSpanById } from "@/api/ManageApi/index"; import { getCybqInformationPage, getSpanById, addCybq, updateSpan,deleteSpan} from "@/api/ManageApi/index";
import { checkPermi, checkRole } from "@/utils/permission"; import { checkPermi, checkRole } from "@/utils/permission";
export default { export default {
dicts: ["xzfl"], dicts: ["xzfl"],
data() { data() {
return { return {
// //
dialogFormVisible: false,
dialogTitle: '',
form: {
id: null,
epname: "",
uscc: "",
catalogueid: "",
state: "",
yhlx: "",
lablenotes: "",
status: "",
dw_timestamp: "",
codekey: "",
sceneid: "",
status: "",
bqbjdw: ""
},
//
loading: true, loading: true,
//
ids: [], ids: [],
//
single: true, single: true,
//
multiple: true, multiple: true,
//
showSearch: true, showSearch: true,
//
total: 0, total: 0,
//
postList: [], postList: [],
//
queryParams: { queryParams: {
current: 1, current: 1,
size: 10, size: 10,
bqdm: undefined, catalogueid: undefined,
bqzt: undefined, status: undefined,
yhlx: undefined, yhlx: undefined,
name: undefined, epname: undefined,
startTime: undefined, startTime: undefined,
endTime: undefined, endTime: undefined,
status: undefined, status: undefined,
}, },
//
dialogVisible: false,
//
detailData: {},
}; };
}, },
created() { created() {
@ -278,67 +259,119 @@ export default {
methods: { methods: {
checkPermi, checkPermi,
checkRole, checkRole,
/** 查询项目列表 */
/** 获取列表 */
getList() { getList() {
this.loading = true; this.loading = true;
//api
getCybqInformationPage(this.queryParams) getCybqInformationPage(this.queryParams)
.then((response) => { .then((response) => {
this.postList = [...response.data.records]; const records = response.data?.records || [];
this.total = response.data.total; this.postList = records;
this.total = response.data?.total || 0;
this.loading = false; this.loading = false;
}) })
.catch(); .catch(() => {
this.loading = false;
});
}, },
// /** 新增按钮点击 */
handleSelectionChange(selection) { handleAdd() {
this.ids = selection.map((item) => item.id); this.dialogTitle = "新增产业标签";
this.single = selection.length !== 1; this.form = {
this.multiple = !selection.length; id: null,
epname: "",
uscc: "",
catalogueid: "",
state: "",
yhlx: "",
lablenotes: "",
status: "",
dw_timestamp: "",
codekey: "",
sceneid: "",
status: "",
bqbjdw: ""
};
this.dialogFormVisible = true;
}, },
/** 详情按钮操作 */ /** 编辑按钮点击(即“详情”) */
/** 详情按钮操作 */
getAdd(row) { getAdd(row) {
this.loading = true; this.dialogTitle = "编辑产业标签";
getSpanById(row.id) getSpanById(row.id).then(response => {
.then((response) => { const data = response.data;
this.detailData = response.data; this.form = {
this.dialogVisible = true; id: data.id,
this.loading = false; epname: data.epname,
uscc: data.uscc,
catalogueid: data.catalogueid,
state: data.state,
yhlx: data.yhlx,
lablenotes: data.lablenotes,
status: data.status,
dw_timestamp: data.dw_timestamp,
codekey: data.codekey,
sceneid: data.sceneid,
status: data.status,
bqbjdw: data.bqbjdw
};
this.dialogFormVisible = true;
}).catch(() => {
this.$message.error("获取数据失败");
});
},
/** 提交表单(新增或修改) */
submitForm() {
const apiRequest = this.form.id ? updateSpan : addCybq;
apiRequest(this.form)
.then(() => {
this.$message.success(this.form.id ? '更新成功' : '新增成功');
this.getList(); //
this.dialogFormVisible = false;
}) })
.catch((error) => { .catch(() => {
this.$message.error("获取详情失败:" + error.message); this.$message.error(this.form.id ? '更新失败' : '新增失败');
this.loading = false; });
},
/** 删除按钮点击 */
handleDelete(row) {
this.$confirm("是否确认删除所选数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
deleteSpan([row.id]).then(() => {
this.$message.success("删除成功");
this.getList();
}); });
}).catch(() => {});
},
/** 搜索与重置 */
handleQuery() {
this.queryParams.current = 1;
this.getList();
}, },
/** 重置按钮操作 */
resetQuery() { resetQuery() {
this.queryParams = { this.queryParams = {
current: 1, current: 1,
size: 10, size: 10,
bqdm: undefined, catalogueid: undefined,
bqzt: undefined, status: undefined,
yhlx: undefined, yhlx: undefined,
name: undefined, epname: undefined,
startTime: undefined, startTime: undefined,
endTime: undefined, endTime: undefined,
status: undefined, status: undefined,
}; };
this.getList(); this.getList();
}, }
}
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.current = 1;
this.getList();
},
},
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.container { .container {
display: flex; display: flex;

@ -1,4 +1,5 @@
<template> <template>
<!-- 这是测试的页面 -->
<div class="dashboard-container"> <div class="dashboard-container">
<!-- 1 --> <!-- 1 -->
<div class="dashboard-row"> <div class="dashboard-row">
@ -23,14 +24,14 @@
<MapArea /> <MapArea />
</div> </div>
<div class="dashboard-col narrow"> <div class="dashboard-col narrow">
<div class="itemhead" style="margin: .5rem 0 0 0;"> <div class="itemhead" style="margin: 0.5rem 0 0 0">
<span>功能区</span> <span>功能区</span>
</div> </div>
<div class="relaitem"> <div class="relaitem">
<FunctionArea :years="years" /> <FunctionArea :years="years" />
</div> </div>
<div class="itemhead" style="margin: 0;"> <div class="itemhead" style="margin: 0">
<span>投资主体</span> <span>投资主体</span>
</div> </div>
<div class="relaitem"> <div class="relaitem">
@ -57,12 +58,36 @@
<Cydxml /> <Cydxml />
</div> </div>
</div> </div>
<div class="dashboard-col" style="height: 11rem">
<div class="itemhead">
<!-- <span>产业导向细分产业分析</span> -->
<span>年度任务完成情况</span>
</div>
<div class="relaitem" style="height: 9rem">
<!-- <Cydxxfgl /> -->
<Ndwcqk />
</div>
</div>
</div>
<!-- 4 -->
<div class="dashboard-row">
<div class="dashboard-col">
<div class="itemhead">
<span>储备项目统计分析</span>
</div>
<div class="relaitem">
<Cbxm />
</div>
</div>
<div class="dashboard-col"> <div class="dashboard-col">
<div class="itemhead"> <div class="itemhead">
<span>产业导向细分产业分析</span> <span>产业导向细分产业分析</span>
<!-- <span>年度任务完成情况</span> -->
</div> </div>
<div class="relaitem"> <div class="relaitem">
<Cydxxfgl /> <Cydxxfgl />
<!-- <Ndwcqk /> -->
</div> </div>
</div> </div>
</div> </div>
@ -70,16 +95,19 @@
</template> </template>
<script> <script>
import AllArea from '@/views/components/analysis/all.vue' import AllArea from "@/views/components/analysis/all.vue";
import FunctionArea from '@/views/components/analysis/function.vue' import FunctionArea from "@/views/components/analysis/function.vue";
import InvestArea from '@/views/components/analysis/invest.vue' import InvestArea from "@/views/components/analysis/invest.vue";
import Message from '@/views/components/analysis/message.vue' import Message from "@/views/components/analysis/message.vue";
import ProjectList from '@/views/components/analysis/projectList.vue' import ProjectList from "@/views/components/analysis/projectList.vue";
import MapArea from '@/views/components/analysis/map.vue' import MapArea from "@/views/components/analysis/map.vue";
import Cyeshuju from '@/views/components/analysis/chanyeshuju.vue' import Cyeshuju from "@/views/components/analysis/chanyeshuju.vue";
import Cydxml from '@/views/components/analysis/chanyedxml.vue' import Cydxml from "@/views/components/analysis/chanyedxml.vue";
import Cydxxfgl from '@/views/components/analysis/chanyexfgl.vue' import Cydxxfgl from "@/views/components/analysis/chanyexfgl.vue";
import { investall, fungong } from '@/api/ManageApi/index' import Cbxm from "@/views/components/analysis/chubeixm.vue";
import Ndwcqk from "@/views/components/analysis/ndwcqk.vue";
import { investall, fungong ,getNewSysLogininfor} from "@/api/ManageApi/index";
import Cookies from "js-cookie";
export default { export default {
components: { components: {
@ -91,30 +119,68 @@ export default {
MapArea, MapArea,
Cyeshuju, Cyeshuju,
Cydxml, Cydxml,
Cydxxfgl Cydxxfgl,
Cbxm,
Ndwcqk,
}, },
data() { data() {
return { return {
years: new Date().getFullYear().toString(), years: new Date().getFullYear().toString(),
allnumber: { allnumber: {
touzinumber: 0 touzinumber: 0,
}, },
functionnumber: { functionnumber: {
functionnumber: 0 functionnumber: 0,
} },
}; };
}, },
mounted() {
getNewSysLogininfor()
.then(res => {
const lastLoginTime = res.data?.loginTime;
if (!lastLoginTime) {
return;
}
if (!res.data) {
if (Cookies.get("newSysLogininfor") != 2) {
this.$confirm(
`您上次登录时间为${lastLoginTime},建议修改密码`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
)
.then(() => {
Cookies.set("newSysLogininfor", 2);
})
.catch(() => {
Cookies.set("newSysLogininfor", 2);
});
}
}
})
.catch(err => {
console.error('获取登录信息失败:', err);
});
},
methods: { methods: {
handleYearChange(years) { handleYearChange(years) {
this.years = years; this.years = years;
console.log("index.vue: handleYearChange called with years:", years);
}, },
async getData() { async getData() {
const response = await investall(); const response = await investall();
if (response && response.data) { if (response && response.data) {
const totalCount = response.data.reduce((sum, item) => sum + item.count, 0); const totalCount = response.data.reduce(
(sum, item) => sum + item.count,
0
);
this.allnumber = { this.allnumber = {
touzinumber: totalCount touzinumber: totalCount,
}; };
} }
}, },
@ -122,22 +188,22 @@ export default {
const response2 = await fungong(); const response2 = await fungong();
if (response2 && response2.data) { if (response2 && response2.data) {
const totalCount2 = response2.data.reduce( const totalCount2 = response2.data.reduce(
(sum, item) => sum + item.count, 0 (sum, item) => sum + item.count,
0
); );
this.functionnumber = { this.functionnumber = {
functionnumber: totalCount2 functionnumber: totalCount2,
} };
}
} }
}, },
},
created() { created() {
this.getData(); this.getData();
this.getfuncdata(); this.getfuncdata();
} },
}; };
</script> </script>
<style scoped> <style scoped>
.dashboard-container { .dashboard-container {
display: flex; display: flex;
@ -153,19 +219,17 @@ export default {
display: flex; display: flex;
flex: 1; flex: 1;
gap: 0.5rem; gap: 0.5rem;
} }
.dashboard-rowtwo { .dashboard-rowtwo {
display: flex; display: flex;
flex: 2; height: auto;
gap: 0.5rem; gap: 0.5rem;
} }
.dashboard-col { .dashboard-col {
flex: 1; flex: 1;
background-color: #FFFFFF; background-color: #ffffff;
border-radius: 0.5rem; border-radius: 0.5rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -182,12 +246,22 @@ export default {
.itemhead { .itemhead {
width: 100%; width: 100%;
border-left: 0.25rem solid #2B62F1; border-left: 0.25rem solid #2b62f1;
margin: 0.5rem 0; margin: 0.5rem 0;
margin: 0.5rem 0; margin: 0.5rem 0;
height: 1.25rem; height: 1.25rem;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
.top {
width: auto;
display: flex;
margin-bottom: 10px;
font-size: 0.88rem;
color: gray !important;
justify-content: flex-end;
}
} }
.relaitem { .relaitem {
@ -210,7 +284,7 @@ export default {
font-family: DINbold; font-family: DINbold;
font-weight: 500; font-weight: 500;
font-size: 1.25rem; font-size: 1.25rem;
color: #292C33; color: #292c33;
text-align: left; text-align: left;
font-style: normal; font-style: normal;
text-transform: none; text-transform: none;
@ -220,7 +294,7 @@ export default {
font-family: alibold; font-family: alibold;
font-weight: 400; font-weight: 400;
font-size: 0.68rem; font-size: 0.68rem;
color: #9E9E9E; color: #9e9e9e;
text-align: left; text-align: left;
font-style: normal; font-style: normal;
text-transform: none; text-transform: none;
@ -231,7 +305,7 @@ export default {
font-family: alibold; font-family: alibold;
font-weight: 600; font-weight: 600;
font-size: 1rem; font-size: 1rem;
color: #3D424C; color: #3d424c;
line-height: 1.69rem; line-height: 1.69rem;
text-align: left; text-align: left;
font-style: normal; font-style: normal;
@ -240,7 +314,7 @@ export default {
.mainarea { .mainarea {
flex: 1; flex: 1;
padding: 0 0 0 .5rem; padding: 0 0 0 0.5rem;
overflow: auto; overflow: auto;
} }
@ -254,6 +328,4 @@ export default {
.bgcicon { .bgcicon {
padding: 0 !important; padding: 0 !important;
} }
</style> </style>

@ -23,14 +23,14 @@
<svg-icon icon-class="email" />用户邮箱 <svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ user.email }}</div> <div class="pull-right">{{ user.email }}</div>
</li> </li>
<li class="list-group-item"> <!-- <li class="list-group-item">
<svg-icon icon-class="tree" />所属部门 <svg-icon icon-class="tree" />所属部门
<div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div> <div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div>
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<svg-icon icon-class="peoples" />所属角色 <svg-icon icon-class="peoples" />所属角色
<div class="pull-right">{{ roleGroup }}</div> <div class="pull-right">{{ roleGroup }}</div>
</li> </li> -->
<li class="list-group-item"> <li class="list-group-item">
<svg-icon icon-class="date" />创建日期 <svg-icon icon-class="date" />创建日期
<div class="pull-right">{{ user.createTime }}</div> <div class="pull-right">{{ user.createTime }}</div>

@ -21,6 +21,25 @@ import { updateUserPwd } from "@/api/system/user";
export default { export default {
data() { data() {
const validatePasswordComplexity = (rule, value, callback) => {
const hasNumber = /\d/.test(value);
const hasUpper = /[A-Z]/.test(value);
const hasLower = /[a-z]/.test(value);
const hasSpecial = /[^a-zA-Z0-9]/.test(value);
if (!hasNumber) {
callback(new Error("密码必须包含至少一个数字"));
} else if (!hasUpper) {
callback(new Error("密码必须包含至少一个大写字母"));
} else if (!hasLower) {
callback(new Error("密码必须包含至少一个小写字母"));
} else if (!hasSpecial) {
callback(new Error("密码必须包含至少一个特殊字符(如!@#$%^&*等)"));
} else {
callback();
}
};
const equalToPassword = (rule, value, callback) => { const equalToPassword = (rule, value, callback) => {
if (this.user.newPassword !== value) { if (this.user.newPassword !== value) {
callback(new Error("两次输入的密码不一致")); callback(new Error("两次输入的密码不一致"));
@ -28,13 +47,13 @@ export default {
callback(); callback();
} }
}; };
return { return {
user: { user: {
oldPassword: undefined, oldPassword: undefined,
newPassword: undefined, newPassword: undefined,
confirmPassword: undefined confirmPassword: undefined
}, },
//
rules: { rules: {
oldPassword: [ oldPassword: [
{ required: true, message: "旧密码不能为空", trigger: "blur" } { required: true, message: "旧密码不能为空", trigger: "blur" }
@ -42,7 +61,8 @@ export default {
newPassword: [ newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" }, { required: true, message: "新密码不能为空", trigger: "blur" },
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }, { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" } { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\ |", trigger: "blur" },
{ validator: validatePasswordComplexity, trigger: "blur" } //
], ],
confirmPassword: [ confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" }, { required: true, message: "确认密码不能为空", trigger: "blur" },
@ -55,7 +75,7 @@ export default {
submit() { submit() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {
if (valid) { if (valid) {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => { updateUserPwd(this.user.oldPassword, this.user.newPassword).then(() => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
}); });
} }

@ -40,14 +40,14 @@ module.exports = {
// webpack-dev-server 相关配置 // webpack-dev-server 相关配置
devServer: { devServer: {
host: '0.0.0.0', host: '0.0.0.0',
public:'192.168.0.119', // public:'192.168.0.119',
port: port, port: port,
open: true, open: true,
proxy: { proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy // detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: { [process.env.VUE_APP_BASE_API]: {
target: `http://192.168.0.108:7071/`, // target: `http://192.168.0.108:7071/`,
// target: `http://39.101.188.84:7071/`, target: `http://39.101.188.84:7071/`,
changeOrigin: true, changeOrigin: true,
pathRewrite: { pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: '' ['^' + process.env.VUE_APP_BASE_API]: ''

Loading…
Cancel
Save