测试环境最终

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

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

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

@ -13,34 +13,78 @@ import { governmentGetInfo } from "@/api/login/index";
NProgress.configure({ showSpinner: false });
const whiteList = ["/login", "/register","/system/singlelogin/login"];
const whiteList = ["/login", "/entLogin", "/register"]; // 白名单路径
const isWhiteList = (path) => {
return whiteList.some((pattern) => isPathMatch(pattern, path));
};
router.beforeEach((to, from, next) => {
if(!extractPrefix(to.path)){
store.commit("SET_CRUMBS",false);
if (!extractPrefix(to.path)) {
store.commit("SET_CRUMBS", false);
}
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 userToken = params.get("userToken");
const signature = params.get("signature");
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) {
next();
return;
}
// 如果存在政务参数,并且不在登录页,则强制跳转过去
if (userToken && signature && timespan && to.path !== "/login") {
next({
path: "/login",
@ -55,7 +99,6 @@ router.beforeEach((to, from, next) => {
.then((res) => {
const token = res.data.token;
if (!token) {
// 清除 URL 参数,避免循环
const cleanPath =
window.location.pathname + window.location.hash.split("?")[0];
window.history.replaceState({}, "", cleanPath);
@ -65,18 +108,15 @@ router.beforeEach((to, from, next) => {
setToken(token);
localStorage.setItem("otherToken", userToken);
// 清除 URL 参数
const cleanPath =
window.location.pathname + (window.location.hash || "");
window.history.replaceState({}, "", cleanPath);
// 如果已有角色信息,直接跳转
if (store.getters.roles.length > 0) {
next("/");
next("/");
return;
}
// 否则获取用户信息并加载路由
isRelogin.show = true;
store
.dispatch("GetInfo")
@ -86,7 +126,7 @@ router.beforeEach((to, from, next) => {
})
.then((accessRoutes) => {
router.addRoutes(accessRoutes);
next(to.query.redirect || "/"); // 跳转到目标页或首页
next(to.query.redirect || "/");
})
.catch((err) => {
console.error("获取用户信息失败:", err);
@ -98,7 +138,6 @@ router.beforeEach((to, from, next) => {
})
.catch((err) => {
console.error("政务系统登录失败:", err);
// 清除 URL 参数,避免循环
const cleanPath =
window.location.pathname + (window.location.hash || "");
window.history.replaceState({}, "", cleanPath);
@ -108,9 +147,10 @@ router.beforeEach((to, from, next) => {
return;
}
// 原始本地登录逻辑
// =============================
// 🔐 原始本地登录逻辑
// =============================
const token = getToken();
if (token) {
to.meta.title && store.dispatch("settings/setTitle", to.meta.title);
if (to.path === "/login") {
@ -151,4 +191,4 @@ router.beforeEach((to, from, next) => {
router.afterEach(() => {
NProgress.done();
});
});

@ -1,17 +1,24 @@
import { login, logout, getInfo } from "@/api/login";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { login, logout, getInfo,refreshToken } from "@/api/login";
import { getToken, setToken, removeToken, setExpiresIn, getClientToken, setClientToken, removeClientToken, getUSerToken, setUserToken, removeUSerToken } from '@/utils/auth'
import { isHttp, isEmpty } from "@/utils/validate";
import defAva from "@/assets/images/profile.jpg";
import { governmentGetInfo } from "@/api/login";
import { singleSigngetInfo, enterpriseLogout, governmentGetInfo } from "@/api/login/index";
const user = {
state: {
token: getToken(),
id: "",
name: "",
avatar: "",
clientToken: getClientToken(),
userToken: getUSerToken(),
id: '',
name: '',
avatar: '',
roles: [],
permissions: [],
expires_in: '',
enterpriseId: '',
nickName: '',
userType: '',
deptId: '',
},
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) {
return new Promise((resolve, reject) => {
@ -105,23 +135,54 @@ const user = {
});
});
},
// 退出系统
LogOut({ commit, state }) {
// 刷新token
RefreshToken({commit, state}) {
return new Promise((resolve, reject) => {
logout(state.token)
.then(() => {
commit("SET_TOKEN", "");
commit("SET_ROLES", []);
commit("SET_PERMISSIONS", []);
removeToken();
resolve();
})
.catch((error) => {
reject(error);
});
});
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(() => {
commit('SET_CLIENTTOKEN', '');
removeClientToken();
});
} else if (state.token && state.clientToken) {
return enterpriseLogout({ clienttoken: state.clientToken })
.then(() => {
commit('SET_CLIENTTOKEN', '');
removeClientToken();
return logout(state.token); // 再调用本地登出
})
.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);
});
});
}
},
// 前端 登出
FedLogOut({ commit }) {

@ -1,6 +1,9 @@
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
const ClientToken = 'ClientToken'
const UserToken = 'UserToken'
const ExpiresInKey = 'Admin-Expires-In'
export function getToken() {
return Cookies.get(TokenKey)
@ -13,3 +16,42 @@ export function setToken(token) {
export function removeToken() {
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;
},
//
//
prepareFormData(formData) {
//
const formatDate = (date) => {
@ -742,7 +741,7 @@ export default {
return {
...formData,
begainTime: formatDate(formData.begainTime), // begainTime
endTime: formatDate(formData.endTime), // endTime
endTime: formatDate(formData.endTime),
createBy: "",
createId: 0,
createTime: "",

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

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

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

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

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

@ -1,4 +1,5 @@
<template>
<!-- 这是测试的页面 -->
<div class="dashboard-container">
<!-- 1 -->
<div class="dashboard-row">
@ -23,14 +24,14 @@
<MapArea />
</div>
<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>
</div>
<div class="relaitem">
<FunctionArea :years="years" />
</div>
<div class="itemhead" style="margin: 0;">
<div class="itemhead" style="margin: 0">
<span>投资主体</span>
</div>
<div class="relaitem">
@ -57,12 +58,36 @@
<Cydxml />
</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="itemhead">
<span>产业导向细分产业分析</span>
<!-- <span>年度任务完成情况</span> -->
</div>
<div class="relaitem">
<Cydxxfgl />
<!-- <Ndwcqk /> -->
</div>
</div>
</div>
@ -70,16 +95,19 @@
</template>
<script>
import AllArea from '@/views/components/analysis/all.vue'
import FunctionArea from '@/views/components/analysis/function.vue'
import InvestArea from '@/views/components/analysis/invest.vue'
import Message from '@/views/components/analysis/message.vue'
import ProjectList from '@/views/components/analysis/projectList.vue'
import MapArea from '@/views/components/analysis/map.vue'
import Cyeshuju from '@/views/components/analysis/chanyeshuju.vue'
import Cydxml from '@/views/components/analysis/chanyedxml.vue'
import Cydxxfgl from '@/views/components/analysis/chanyexfgl.vue'
import { investall, fungong } from '@/api/ManageApi/index'
import AllArea from "@/views/components/analysis/all.vue";
import FunctionArea from "@/views/components/analysis/function.vue";
import InvestArea from "@/views/components/analysis/invest.vue";
import Message from "@/views/components/analysis/message.vue";
import ProjectList from "@/views/components/analysis/projectList.vue";
import MapArea from "@/views/components/analysis/map.vue";
import Cyeshuju from "@/views/components/analysis/chanyeshuju.vue";
import Cydxml from "@/views/components/analysis/chanyedxml.vue";
import Cydxxfgl from "@/views/components/analysis/chanyexfgl.vue";
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 {
components: {
@ -91,30 +119,68 @@ export default {
MapArea,
Cyeshuju,
Cydxml,
Cydxxfgl
Cydxxfgl,
Cbxm,
Ndwcqk,
},
data() {
return {
years: new Date().getFullYear().toString(),
allnumber: {
touzinumber: 0
touzinumber: 0,
},
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: {
handleYearChange(years) {
this.years = years;
console.log("index.vue: handleYearChange called with years:", years);
},
async getData() {
const response = await investall();
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 = {
touzinumber: totalCount
touzinumber: totalCount,
};
}
},
@ -122,22 +188,22 @@ export default {
const response2 = await fungong();
if (response2 && response2.data) {
const totalCount2 = response2.data.reduce(
(sum, item) => sum + item.count, 0
(sum, item) => sum + item.count,
0
);
this.functionnumber = {
functionnumber: totalCount2
}
functionnumber: totalCount2,
};
}
}
},
},
created() {
this.getData();
this.getfuncdata();
}
},
};
</script>
<style scoped>
.dashboard-container {
display: flex;
@ -153,19 +219,17 @@ export default {
display: flex;
flex: 1;
gap: 0.5rem;
}
.dashboard-rowtwo {
display: flex;
flex: 2;
height: auto;
gap: 0.5rem;
}
.dashboard-col {
flex: 1;
background-color: #FFFFFF;
background-color: #ffffff;
border-radius: 0.5rem;
display: flex;
flex-direction: column;
@ -182,12 +246,22 @@ export default {
.itemhead {
width: 100%;
border-left: 0.25rem solid #2B62F1;
border-left: 0.25rem solid #2b62f1;
margin: 0.5rem 0;
margin: 0.5rem 0;
height: 1.25rem;
display: flex;
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 {
@ -210,7 +284,7 @@ export default {
font-family: DINbold;
font-weight: 500;
font-size: 1.25rem;
color: #292C33;
color: #292c33;
text-align: left;
font-style: normal;
text-transform: none;
@ -220,7 +294,7 @@ export default {
font-family: alibold;
font-weight: 400;
font-size: 0.68rem;
color: #9E9E9E;
color: #9e9e9e;
text-align: left;
font-style: normal;
text-transform: none;
@ -231,7 +305,7 @@ export default {
font-family: alibold;
font-weight: 600;
font-size: 1rem;
color: #3D424C;
color: #3d424c;
line-height: 1.69rem;
text-align: left;
font-style: normal;
@ -240,7 +314,7 @@ export default {
.mainarea {
flex: 1;
padding: 0 0 0 .5rem;
padding: 0 0 0 0.5rem;
overflow: auto;
}
@ -254,6 +328,4 @@ export default {
.bgcicon {
padding: 0 !important;
}
</style>
</style>

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

@ -21,6 +21,25 @@ import { updateUserPwd } from "@/api/system/user";
export default {
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) => {
if (this.user.newPassword !== value) {
callback(new Error("两次输入的密码不一致"));
@ -28,13 +47,13 @@ export default {
callback();
}
};
return {
user: {
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined
},
//
rules: {
oldPassword: [
{ required: true, message: "旧密码不能为空", trigger: "blur" }
@ -42,7 +61,8 @@ export default {
newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" },
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\ |", trigger: "blur" },
{ validator: validatePasswordComplexity, trigger: "blur" } //
],
confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" },
@ -55,7 +75,7 @@ export default {
submit() {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(() => {
this.$modal.msgSuccess("修改成功");
});
}

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

Loading…
Cancel
Save