Commit 88c8a729 authored by tanyang's avatar tanyang

Merge remote-tracking branch 'origin/V20230915' into V20230915

parents ea4ddedf f51e3fe9
...@@ -6,6 +6,7 @@ import cn.hutool.core.bean.BeanUtil; ...@@ -6,6 +6,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.dsk.biz.utils.ExcelUtils;
import com.dsk.common.annotation.Log; import com.dsk.common.annotation.Log;
import com.dsk.common.constant.GlobalConstants; import com.dsk.common.constant.GlobalConstants;
import com.dsk.common.core.controller.BaseController; import com.dsk.common.core.controller.BaseController;
...@@ -13,7 +14,7 @@ import com.dsk.common.core.domain.PageQuery; ...@@ -13,7 +14,7 @@ import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.R; import com.dsk.common.core.domain.R;
import com.dsk.common.core.page.TableDataInfo; import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.enums.BusinessType; import com.dsk.common.enums.BusinessType;
import com.dsk.common.excel.ExcelResult; import com.dsk.common.exception.ServiceException;
import com.dsk.common.helper.LoginHelper; import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.StreamUtils; import com.dsk.common.utils.StreamUtils;
import com.dsk.common.utils.StringUtils; import com.dsk.common.utils.StringUtils;
...@@ -25,7 +26,6 @@ import com.dsk.system.domain.SysUser; ...@@ -25,7 +26,6 @@ import com.dsk.system.domain.SysUser;
import com.dsk.system.domain.vo.SysUserExportVo; import com.dsk.system.domain.vo.SysUserExportVo;
import com.dsk.system.domain.vo.SysUserImportVo; import com.dsk.system.domain.vo.SysUserImportVo;
import com.dsk.system.domain.vo.SysUserVo; import com.dsk.system.domain.vo.SysUserVo;
import com.dsk.system.listener.SysUserImportListener;
import com.dsk.system.service.ISysDeptService; import com.dsk.system.service.ISysDeptService;
import com.dsk.system.service.ISysPostService; import com.dsk.system.service.ISysPostService;
import com.dsk.system.service.ISysRoleService; import com.dsk.system.service.ISysRoleService;
...@@ -106,14 +106,39 @@ public class SysUserController extends BaseController { ...@@ -106,14 +106,39 @@ public class SysUserController extends BaseController {
@SaCheckPermission("system:user:import") @SaCheckPermission("system:user:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<List<SysUserImportVo>> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { public R<List<SysUserImportVo>> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); //ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport));
List<SysUserImportVo> resultList = result.getList(); //List<SysUserImportVo> resultList = result.getList();
if (!resultList.isEmpty()) { //if (!resultList.isEmpty()) {
// String key = GlobalConstants.BATCH_IMPORT_FAIL_USERS + LoginHelper.getUserId();
// RedisUtils.setCacheList(key, resultList);
// return R.fail(resultList);
//}
//return R.ok(result.getAnalysis());
//识别Excel内容
List<SysUserImportVo> userImportList = new ExcelUtils<>(SysUserImportVo.class).importExcel(file.getInputStream(), 2);
if (userImportList.isEmpty()) {
throw new ServiceException("表格中不存在待导入数据!");
}
for (SysUserImportVo userImportVo : userImportList) {
System.out.println("👉🏻:"+userImportVo);
}
//开始导入业务
List<SysUserImportVo> failImportUsers = userService.batchImportUser(userImportList, updateSupport);
//将导入失败用户存入Redis并返回给前端
if (!failImportUsers.isEmpty()) {
String key = GlobalConstants.BATCH_IMPORT_FAIL_USERS + LoginHelper.getUserId(); String key = GlobalConstants.BATCH_IMPORT_FAIL_USERS + LoginHelper.getUserId();
RedisUtils.setCacheList(key, resultList); //删除旧的
return R.fail(resultList); RedisUtils.deleteObject(key);
//写入新的
RedisUtils.setCacheList(key, failImportUsers);
return R.fail(failImportUsers);
} }
return R.ok(result.getAnalysis());
return R.ok();
} }
/** /**
...@@ -122,7 +147,7 @@ public class SysUserController extends BaseController { ...@@ -122,7 +147,7 @@ public class SysUserController extends BaseController {
@PostMapping("/importTemplate") @PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) { public void importTemplate(HttpServletResponse response) {
List<Object> list = new ArrayList<>(); List<Object> list = new ArrayList<>();
list.add(new SysUserImportVo("测试组织", "测试用户昵称", "18888888888", "测试角色")); list.add(new SysUserImportVo("重庆市轨道交通(集团)有限公司", "刘国海", "18888888888", "运营部部长"));
ExcelUtil.exportTemplate(list, "用户数据", "excel/userImportTemplate.xlsx", response); ExcelUtil.exportTemplate(list, "用户数据", "excel/userImportTemplate.xlsx", response);
} }
......
...@@ -9,3 +9,8 @@ VUE_APP_BASE_API = '/prod-api' ...@@ -9,3 +9,8 @@ VUE_APP_BASE_API = '/prod-api'
# 路由懒加载 # 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true
# 子系统地址
# VUE_APP_SUB_SYSTEM_ADDRESS = "https://pre-plug.jiansheku.com"
VUE_APP_SUB_SYSTEM_ADDRESS = "http://192.168.60.104:3400"
\ No newline at end of file
...@@ -6,3 +6,6 @@ ENV = 'production' ...@@ -6,3 +6,6 @@ ENV = 'production'
# 数字化经营履约全生命链路管理系统/生产环境 # 数字化经营履约全生命链路管理系统/生产环境
VUE_APP_BASE_API = 'https://szhapi.jiansheku.com' VUE_APP_BASE_API = 'https://szhapi.jiansheku.com'
# 子系统地址
VUE_APP_SUB_SYSTEM_ADDRESS = "https://plug.jiansheku.com"
\ No newline at end of file
...@@ -9,4 +9,7 @@ ENV = 'test' ...@@ -9,4 +9,7 @@ ENV = 'test'
# 数字化经营履约全生命链路管理系统/测试环境 # 数字化经营履约全生命链路管理系统/测试环境
VUE_APP_BASE_API = '/prod-api' VUE_APP_BASE_API = '/prod-api'
\ No newline at end of file
# 子系统地址
VUE_APP_SUB_SYSTEM_ADDRESS = "https://pre-plug.jiansheku.com"
\ No newline at end of file
module.exports = { module.exports = {
presets: [ presets: [
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
'@vue/cli-plugin-babel/preset' '@vue/cli-plugin-babel/preset',
['@vue/babel-preset-jsx', { 'injectH': false }]
], ],
'env': { 'env': {
'development': { 'development': {
...@@ -10,4 +11,4 @@ module.exports = { ...@@ -10,4 +11,4 @@ module.exports = {
'plugins': ['dynamic-import-node'] 'plugins': ['dynamic-import-node']
} }
} }
} };
\ No newline at end of file \ No newline at end of file
...@@ -70,6 +70,8 @@ ...@@ -70,6 +70,8 @@
"vuex": "3.6.0" "vuex": "3.6.0"
}, },
"devDependencies": { "devDependencies": {
"@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
"@vue/babel-preset-jsx": "^1.4.0",
"@vue/cli-plugin-babel": "4.4.6", "@vue/cli-plugin-babel": "4.4.6",
"@vue/cli-plugin-eslint": "4.4.6", "@vue/cli-plugin-eslint": "4.4.6",
"@vue/cli-service": "4.4.6", "@vue/cli-service": "4.4.6",
...@@ -87,6 +89,7 @@ ...@@ -87,6 +89,7 @@
"sass-loader": "10.1.1", "sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5", "script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1", "svg-sprite-loader": "5.1.1",
"vue-styled-components": "^1.6.0",
"vue-template-compiler": "2.6.12" "vue-template-compiler": "2.6.12"
}, },
"engines": { "engines": {
......
/*
* @Author: thy
* @Date: 2023-10-31 09:33:14
* @LastEditors: thy
* @LastEditTime: 2023-11-02 17:17:32
* @Description: file content
* @FilePath: \dsk-operate-ui\src\components\JsComponents\MaxPageSizeTip.js
*/
import styled from "vue-styled-components";
import Vue from "vue";
import { v4 } from "uuid";
import maxTipTitleIcon from "@/assets/images/market/max-tip-title-icon.svg";
import closeMaxTipIcon from "@/assets/images/market/close-max-tip-icon.svg";
const maxPageSizeTipContainer = styled.div`
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
z-index: 1200;
`;
const maxPageTipContainer = styled.div`
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 340px;
height: 112px;
background: #ffffff;
border: 1px solid #e5e6eb;
box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.1);
border-radius: 4px;
padding: 20px;
box-sizing: border-box;
.top-title-container {
display: flex;
align-items: center;
.max-tip-icon {
width: 24px;
height: 24px;
}
.tip-title {
color: #1d2129;
font-size: 16px;
line-height: 24px;
font-weight: 400;
margin-left: 16px;
margin-right: 16px;
width: 228px;
}
.max-tip-close-icon {
width: 16px;
height: 16px;
align-self: flex-start;
cursor: pointer;
}
}
.max-page-tip-content {
margin-top: 4px;
padding-left: 40px;
padding-right: 32px;
box-sizing: border-box;
.max-page-content-inner {
color: #1d2129;
font-size: 14px;
line-height: 22px;
}
}
`;
const MaxPageSizeTip = {
name: "maxPageSizeTip",
render(createElement) {
return (
<transition name="fade" mode="out-in" appear>
<maxPageSizeTipContainer vOn:click_stop={this.closeMaxTip.bind()} class="max-page-size-tip">
<maxPageTipContainer vOn:click_stop={""}>
<div class="max-page-tip-inner">
<div class="top-title-container">
<img src={maxTipTitleIcon} alt="" class="max-tip-icon"></img>
<span class="tip-title">数据查询已达到上限</span>
<img src={closeMaxTipIcon} alt="" class="max-tip-close-icon" vOn:click_stop={this.closeMaxTip.bind()}></img>
</div>
<div class="max-page-tip-content">
<div class="max-page-content-inner">
{this.msg}
</div>
</div>
</div>
</maxPageTipContainer>
</maxPageSizeTipContainer>
</transition>
);
},
};
/**
*
* @param {string} msg 展示的信息
* @param {Function} closeHandle 关闭弹窗的回调
* @returns
*/
function showMaxPageSizeTip(msg = "") {
return new Promise((resolve, reject) => {
try {
// 生成构造函数
const maxMsgBox = Vue.extend(MaxPageSizeTip);
// 实例化
const instance = new maxMsgBox({
data() {
return {
msg
};
},
methods: {
// 关闭弹窗
closeMaxTip() {
resolve({
uid: v4(),
done: this.doneHandle
});
},
// 关闭回调
doneHandle() {
// 卸载组件
instance.$destroy();
instance.$el.remove();
}
},
});
// 初始化组件
instance.$mount();
// 添加到body中
document.body.appendChild(instance.$el);
} catch (error) {
reject(error);
}
});
}
export default showMaxPageSizeTip;
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
<script> <script>
import iframeToggle from "./IframeToggle/index" import iframeToggle from "./IframeToggle/index"
export default { export default {
name: 'AppMain', name: 'AppMain',
components: { iframeToggle }, components: { iframeToggle },
...@@ -20,7 +19,7 @@ export default { ...@@ -20,7 +19,7 @@ export default {
return this.$store.state.tagsView.cachedViews return this.$store.state.tagsView.cachedViews
}, },
key() { key() {
return this.$route.path return this.$route.fullPath
} }
} }
} }
......
import tab from './tab' import tab from './tab';
import auth from './auth' import auth from './auth';
import cache from './cache' import cache from './cache';
import modal from './modal' import modal from './modal';
import download from './download' import download from './download';
import msgBox from "@/components/JsComponents/MaxPageSizeTip.js";
export default { export default {
install(Vue) { install(Vue) {
// 页签操作 // 页签操作
Vue.prototype.$tab = tab Vue.prototype.$tab = tab;
// 认证对象 // 认证对象
Vue.prototype.$auth = auth Vue.prototype.$auth = auth;
// 缓存对象 // 缓存对象
Vue.prototype.$cache = cache Vue.prototype.$cache = cache;
// 模态框对象 // 模态框对象
Vue.prototype.$modal = modal Vue.prototype.$modal = modal;
// 下载文件 // 下载文件
Vue.prototype.$download = download Vue.prototype.$download = download;
// 页码超出限制提示
Vue.prototype.$maxTip = msgBox;
} }
} };
...@@ -7,7 +7,7 @@ const state = { ...@@ -7,7 +7,7 @@ const state = {
const mutations = { const mutations = {
ADD_IFRAME_VIEW: (state, view) => { ADD_IFRAME_VIEW: (state, view) => {
if (state.iframeViews.some(v => v.path === view.path)) return if (state.iframeViews.some(v => v.fullPath === view.fullPath)) return
state.iframeViews.push( state.iframeViews.push(
Object.assign({}, view, { Object.assign({}, view, {
title: view.meta.title || 'no-name' title: view.meta.title || 'no-name'
...@@ -15,7 +15,7 @@ const mutations = { ...@@ -15,7 +15,7 @@ const mutations = {
) )
}, },
ADD_VISITED_VIEW: (state, view) => { ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return if (state.visitedViews.some(v => v.fullPath === view.fullPath)) return
state.visitedViews.push( state.visitedViews.push(
Object.assign({}, view, { Object.assign({}, view, {
title: view.meta.title || 'no-name' title: view.meta.title || 'no-name'
...@@ -30,15 +30,15 @@ const mutations = { ...@@ -30,15 +30,15 @@ const mutations = {
}, },
DEL_VISITED_VIEW: (state, view) => { DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) { for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) { if (v.fullPath === view.fullPath) {
state.visitedViews.splice(i, 1) state.visitedViews.splice(i, 1)
break break
} }
} }
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) state.iframeViews = state.iframeViews.filter(item => item.fullPath !== view.fullPath)
}, },
DEL_IFRAME_VIEW: (state, view) => { DEL_IFRAME_VIEW: (state, view) => {
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) state.iframeViews = state.iframeViews.filter(item => item.fullPath !== view.fullPath)
}, },
DEL_CACHED_VIEW: (state, view) => { DEL_CACHED_VIEW: (state, view) => {
const index = state.cachedViews.indexOf(view.name) const index = state.cachedViews.indexOf(view.name)
...@@ -47,9 +47,9 @@ const mutations = { ...@@ -47,9 +47,9 @@ const mutations = {
DEL_OTHERS_VISITED_VIEWS: (state, view) => { DEL_OTHERS_VISITED_VIEWS: (state, view) => {
state.visitedViews = state.visitedViews.filter(v => { state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path return v.meta.affix || v.fullPath === view.fullPath
}) })
state.iframeViews = state.iframeViews.filter(item => item.path === view.path) state.iframeViews = state.iframeViews.filter(item => item.fullPath === view.fullPath)
}, },
DEL_OTHERS_CACHED_VIEWS: (state, view) => { DEL_OTHERS_CACHED_VIEWS: (state, view) => {
const index = state.cachedViews.indexOf(view.name) const index = state.cachedViews.indexOf(view.name)
...@@ -70,14 +70,14 @@ const mutations = { ...@@ -70,14 +70,14 @@ const mutations = {
}, },
UPDATE_VISITED_VIEW: (state, view) => { UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) { for (let v of state.visitedViews) {
if (v.path === view.path) { if (v.fullPath === view.fullPath) {
v = Object.assign(v, view) v = Object.assign(v, view)
break break
} }
} }
}, },
DEL_RIGHT_VIEWS: (state, view) => { DEL_RIGHT_VIEWS: (state, view) => {
const index = state.visitedViews.findIndex(v => v.path === view.path) const index = state.visitedViews.findIndex(v => v.fullPath === view.fullPath)
if (index === -1) { if (index === -1) {
return return
} }
...@@ -90,14 +90,14 @@ const mutations = { ...@@ -90,14 +90,14 @@ const mutations = {
state.cachedViews.splice(i, 1) state.cachedViews.splice(i, 1)
} }
if(item.meta.link) { if(item.meta.link) {
const fi = state.iframeViews.findIndex(v => v.path === item.path) const fi = state.iframeViews.findIndex(v => v.fullPath === item.fullPath)
state.iframeViews.splice(fi, 1) state.iframeViews.splice(fi, 1)
} }
return false return false
}) })
}, },
DEL_LEFT_VIEWS: (state, view) => { DEL_LEFT_VIEWS: (state, view) => {
const index = state.visitedViews.findIndex(v => v.path === view.path) const index = state.visitedViews.findIndex(v => v.fullPath === view.fullPath)
if (index === -1) { if (index === -1) {
return return
} }
...@@ -110,7 +110,7 @@ const mutations = { ...@@ -110,7 +110,7 @@ const mutations = {
state.cachedViews.splice(i, 1) state.cachedViews.splice(i, 1)
} }
if(item.meta.link) { if(item.meta.link) {
const fi = state.iframeViews.findIndex(v => v.path === item.path) const fi = state.iframeViews.findIndex(v => v.fullPath === item.fullPath)
state.iframeViews.splice(fi, 1) state.iframeViews.splice(fi, 1)
} }
return false return false
......
import { login, logout, getInfo } from '@/api/login' import { login, logout, getInfo } from '@/api/login';
import { getToken, setToken, removeToken ,setTenantid} from '@/utils/auth' import { getToken, setToken, removeToken, setTenantid } from '@/utils/auth';
const user = { const user = {
state: { state: {
...@@ -8,100 +8,100 @@ const user = { ...@@ -8,100 +8,100 @@ const user = {
avatar: '', avatar: '',
roles: [], roles: [],
permissions: [], permissions: [],
userId:'', userId: '',
phonenumber:'', phonenumber: '',
}, },
mutations: { mutations: {
SET_TOKEN: (state, token) => { SET_TOKEN: (state, token) => {
state.token = token state.token = token;
}, },
SET_NAME: (state, name) => { SET_NAME: (state, name) => {
state.name = name state.name = name;
}, },
SET_AVATAR: (state, avatar) => { SET_AVATAR: (state, avatar) => {
state.avatar = avatar state.avatar = avatar;
}, },
SET_ROLES: (state, roles) => { SET_ROLES: (state, roles) => {
state.roles = roles state.roles = roles;
}, },
SET_PERMISSIONS: (state, permissions) => { SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions state.permissions = permissions;
}, },
SET_USERID: (state, userId) => { SET_USERID: (state, userId) => {
state.userId = userId state.userId = userId;
}, },
SET_USERPHONE: (state, phonenumber) => { SET_USERPHONE: (state, phonenumber) => {
state.phonenumber = phonenumber state.phonenumber = phonenumber;
} }
}, },
actions: { actions: {
// 登录 // 登录
Login({ commit }, userInfo) { Login({ commit }, userInfo) {
const username = userInfo.username.trim() const username = userInfo.username.trim();
const password = userInfo.password const password = userInfo.password;
const code = userInfo.code const code = userInfo.code;
const uuid = userInfo.uuid const uuid = userInfo.uuid;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => { login(username, password, code, uuid).then(res => {
setToken(res.data.token) setToken(res.data.token);
commit('SET_TOKEN', res.data.token) commit('SET_TOKEN', res.data.token);
setTenantid(res.data.tenantId) setTenantid(res.data.tenantId);
resolve() resolve();
}).catch(error => { }).catch(error => {
reject(error) reject(error);
}) });
}) });
}, },
// 获取用户信息 // 获取用户信息
GetInfo({ commit, state }) { GetInfo({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getInfo().then(res => { getInfo().then(res => {
const user = res.data.user const user = res.data.user;
const avatar = user.avatar ? process.env.VUE_APP_BASE_API + user.avatar : ''; const avatar = user.avatar ? user.avatar : '';
if (res.data.roles && res.data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 if (res.data.roles && res.data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.data.roles) commit('SET_ROLES', res.data.roles);
commit('SET_PERMISSIONS', res.data.permissions) commit('SET_PERMISSIONS', res.data.permissions);
} else { } else {
commit('SET_ROLES', ['ROLE_DEFAULT']) commit('SET_ROLES', ['ROLE_DEFAULT']);
} }
commit('SET_NAME', user.nickName) commit('SET_NAME', user.nickName);
commit('SET_AVATAR', avatar) commit('SET_AVATAR', avatar);
commit('SET_USERID', user.userId) commit('SET_USERID', user.userId);
commit('SET_USERPHONE', user.phonenumber) commit('SET_USERPHONE', user.phonenumber);
resolve(res) resolve(res);
}).catch(error => { }).catch(error => {
reject(error) reject(error);
}) });
}) });
}, },
// 退出系统 // 退出系统
LogOut({ commit, state }) { LogOut({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout(state.token).then(() => { logout(state.token).then(() => {
commit('SET_TOKEN', '') commit('SET_TOKEN', '');
commit('SET_ROLES', []) commit('SET_ROLES', []);
commit('SET_PERMISSIONS', []) commit('SET_PERMISSIONS', []);
removeToken() removeToken();
resolve() resolve();
}).catch(error => { }).catch(error => {
reject(error) reject(error);
}) });
}) });
}, },
// 前端 登出 // 前端 登出
FedLogOut({ commit }) { FedLogOut({ commit }) {
return new Promise(resolve => { return new Promise(resolve => {
commit('SET_TOKEN', '') commit('SET_TOKEN', '');
removeToken() removeToken();
resolve() resolve();
}) });
} }
} }
} };
export default user export default user;
...@@ -401,6 +401,62 @@ export function isNumberStr(str) { ...@@ -401,6 +401,62 @@ export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str); return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str);
} }
/**
*
* @param {string} originUrl 需要获取参数的url 默认当前url
* @param {RegExp} reg key需要剔除的特殊字符 默认过滤问号
* @returns {{[key : string] : any}} 查询对象 键值对
*/
export const getUrlSearchQuery = (originUrl = location.href, reg = new RegExp("\\?", "gi")) => {
const url = new URL(originUrl);
const params = url.searchParams.entries();
let _temp = {};
for (const [key, value] of params) {
_temp[key.replace(reg, "")] = (value ? decodeURIComponent(value) : "");
}
return _temp;
};
/**
* 对象转换为查询字符串
* @param {{[key:string] : any}} query
*/
export const paramsToQuery = (query) => {
try {
if (Object.prototype.toString.call(query) !== "[object Object]") return "";
const params = new URLSearchParams(query);
let searchStrArray = [];
params.forEach((value, key) => {
if (params.has(key)) {
searchStrArray.push(`${key}=${decodeURIComponent(value)}`);
}
});
searchStrArray = searchStrArray.join("&");
return searchStr;
} catch (error) {
console.log(error);
}
};
/**
* 查询字符串转对象
* @param {string} text
*/
export const searchTextToQuery = (text) => {
try {
if (text) {
const url = new URLSearchParams(text);
const _temp = {};
url.forEach((value, key) => {
_temp[key] = value;
});
return JSON.parse(JSON.stringify(_temp));
}
} catch (error) {
console.log(error);
}
};
// 甲方详情左侧菜单映射 // 甲方详情左侧菜单映射
export const detailSideBar = new Map([ export const detailSideBar = new Map([
// 企业速览 // 企业速览
......
...@@ -2,12 +2,44 @@ ...@@ -2,12 +2,44 @@
* @Author: thy * @Author: thy
* @Date: 2023-10-26 14:56:41 * @Date: 2023-10-26 14:56:41
* @LastEditors: thy * @LastEditors: thy
* @LastEditTime: 2023-10-30 14:26:31 * @LastEditTime: 2023-10-31 09:28:26
* @Description: file content * @Description: file content
* @FilePath: \dsk-operate-ui\src\utils\postMessageBridge\bridge\index.js * @FilePath: \dsk-operate-ui\src\utils\postMessageBridge\bridge\index.js
*/ */
class PostMessageBridge { class PostMessageBridge {
constructor() { // 当前系统
_currenySystem = null;
// 目标系统
_targetSystem = null;
// 目标域
_targetOriginUrl = null;
// 事件调度中心
_eventHandlers = new Map();
/**
*
* @param {{
* currenySystem : Window || undefined;
* targetSystem : Window || undefined;
* targetOriginUrl : string || undefined;
* }} options
*/
constructor(options) {
this._currenySystem = options.currenySystem;
this._targetSystem = options.targetSystem;
this._targetOriginUrl = options.targetOriginUrl || "*";
}
/**
* 订阅消息
* @param {{
* id : string;
* method : string;
* params : object;
* }} messageEvent
*/
receiveMessage(messageEvent) {
} }
} }
\ No newline at end of file
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
<template slot="suffix"> <template slot="suffix">
<transition mode="out-in" appear name="fade"> <transition mode="out-in" appear name="fade">
<img src="@/assets/images/enterprise/search-input-clear-icon.svg" alt="" <img src="@/assets/images/enterprise/search-input-clear-icon.svg" alt=""
@click.stop="searchParam.companyName = '';handleSearch" v-show="showClearIcon"> @click.stop="searchParam.companyName = '';handleSearch()" v-show="showClearIcon">
</transition> </transition>
</template> </template>
</el-input> </el-input>
......
<template> <template>
<div class="app-container part-container"> <div class="app-container part-container details-of-party">
<Header :company-id="companyId" :companyInfo="companyInfo" :cooDetail="cooDetail" v-if="companyId" @close-detail="closeDetail" /> <Header :company-id="companyId" :companyInfo="companyInfo" :cooDetail="cooDetail" v-if="companyId" @close-detail="closeDetail" />
<div class="flex-box part-main"> <div class="flex-box part-main">
<div class="part-left"> <div class="part-left">
...@@ -194,9 +194,6 @@ export default { ...@@ -194,9 +194,6 @@ export default {
companyName: this.customerInfo.companyName companyName: this.customerInfo.companyName
}; };
document.getElementById('tagTitle').innerText = this.customerInfo.companyName; document.getElementById('tagTitle').innerText = this.customerInfo.companyName;
// let lists = this.$store.state.tagsView.visitedViews
// lists.forEach(item=>{
// if(item.fullPath == this.$route.fullPath){
let titlename = document.getElementById('tagTitles'); let titlename = document.getElementById('tagTitles');
if (titlename) { if (titlename) {
titlename.innerText = this.customerInfo.companyName; titlename.innerText = this.customerInfo.companyName;
...@@ -392,22 +389,48 @@ export default { ...@@ -392,22 +389,48 @@ export default {
margin-right: 16px; margin-right: 16px;
padding-bottom: 16px; padding-bottom: 16px;
position: fixed; position: fixed;
background: #FFFFFF; background: #ffffff;
width: 144px; width: 144px;
} }
.part-right { .part-right {
min-width: 1088px; min-width: 1088px;
width: 100%; width: 100%;
background: #FFFFFF; background: #ffffff;
border-radius: 4px; border-radius: 4px;
margin-left: 160px; margin-left: 160px;
::v-deep .el-table__header-wrapper{ ::v-deep .el-table__header-wrapper {
position: sticky; position: sticky;
top:0; top: 0;
z-index: 9; z-index: 9;
} }
#groupBox{ #groupBox {
height: 100%; height: 100%;
} }
} }
.details-of-party {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
margin: 0px;
padding: 16px 24px;
box-sizing: border-box;
::v-deep .header-container {
.part-header {
margin-top: 0px;
}
}
::v-deep .part-main {
height: calc(100% - 56px - 12px);
.part-right {
margin-left: 160px;
width: calc(100% - 160px);
overflow: auto;
}
}
}
</style> </style>
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
<div class="operations-title">{{item.bratingSubjectLevel}}-<span>{{item.ratingDate}}</span></div> <div class="operations-title">{{item.bratingSubjectLevel}}-<span>{{item.ratingDate}}</span></div>
<div class="flex-box operations-info"> <div class="flex-box operations-info">
<div>{{item.bondType || '--'}}</div> <div>{{item.bondType || '--'}}</div>
<span class="text-cl1" :title="item.creditRatingAgency"><img src="@/assets/images/detail/overview/oper_source.png">{{item.creditRatingAgency || '--'}}</span> <span class="text-cl1" :title="item.creditRatingAgency"><img
src="@/assets/images/detail/overview/oper_source.png">{{item.creditRatingAgency || '--'}}</span>
</div> </div>
</div> </div>
</li> </li>
...@@ -32,38 +33,39 @@ ...@@ -32,38 +33,39 @@
</template> </template>
<script> <script>
import {bondCreditRating} from '@/api/detail/party-a/overview' import { bondCreditRating } from '@/api/detail/party-a/overview';
var Swiper = require('@/assets/lib/swiper/swiper-bundle.min.js') var Swiper = require('@/assets/lib/swiper/swiper-bundle.min.js');
import skeleton from '@/views/project/projectList/component/skeleton' import skeleton from '@/views/project/projectList/component/skeleton';
import "@/assets/lib/swiper/swiper-bundle.css" import "@/assets/lib/swiper/swiper-bundle.css";
import NoData from '../../component/noData' import NoData from '../../component/noData';
export default { export default {
name: 'Overview', name: 'Overview',
props: ['companyId', 'financial'], props: ['companyId', 'financial'],
components: { components: {
NoData,skeleton NoData, skeleton
}, },
data() { data() {
return { return {
operList: [], operList: [],
isSkeleton:true, isSkeleton: true,
gsjyList: [ gsjyList: [
{ name: '总资产', ico: require('@/assets/images/detail/overview/gsjy_ico1.png'), amount: ''}, { name: '总资产', ico: require('@/assets/images/detail/overview/gsjy_ico1.png'), amount: '' },
{ name: '净资产', ico: require('@/assets/images/detail/overview/gsjy_ico2.png'), amount: ''}, { name: '净资产', ico: require('@/assets/images/detail/overview/gsjy_ico2.png'), amount: '' },
{ name: '授信余额', ico: require('@/assets/images/detail/overview/gsjy_ico3.png'), amount: ''}, { name: '授信余额', ico: require('@/assets/images/detail/overview/gsjy_ico3.png'), amount: '' },
{ name: '营业收入', ico: require('@/assets/images/detail/overview/gsjy_ico4.png'), amount: ''}, { name: '营业收入', ico: require('@/assets/images/detail/overview/gsjy_ico4.png'), amount: '' },
{ name: '总负债', ico: require('@/assets/images/detail/overview/gsjy_ico5.png'), amount: ''} { name: '总负债', ico: require('@/assets/images/detail/overview/gsjy_ico5.png'), amount: '' }
], ],
} childFinancial: {}
};
}, },
created() { created() {
this.handleQuery() this.handleQuery();
}, },
mounted() { mounted() {
this.companySwiper() this.companySwiper();
}, },
methods: { methods: {
companySwiper(){ companySwiper() {
new Swiper('.swiper-oper', { new Swiper('.swiper-oper', {
slidesPerView: 6, slidesPerView: 6,
// 设置点击箭头 // 设置点击箭头
...@@ -71,136 +73,142 @@ export default { ...@@ -71,136 +73,142 @@ export default {
nextEl: '.swiper-oper-next', nextEl: '.swiper-oper-next',
prevEl: '.swiper-oper-prev', prevEl: '.swiper-oper-prev',
} }
}) });
}, },
async handleQuery() { async handleQuery() {
this.isSkeleton = true; this.isSkeleton = true;
let res = await bondCreditRating({cid: this.companyId}) let res = await bondCreditRating({ cid: this.companyId });
if(res.code==200){ if (res.code == 200) {
this.isSkeleton = false; this.isSkeleton = false;
this.operList = res.data || [] this.operList = res.data || [];
this.$nextTick(() => { this.$nextTick(() => {
this.companySwiper() this.companySwiper();
}) });
} }
}, },
handleFinancial(){ handleFinancial() {
if(this.financial){ if (this.childFinancial) {
let { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities } = this.financial let { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities } = this.childFinancial;
let jyqkObj = { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities } let jyqkObj = { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities };
this.gsjyList.forEach((item, index) => { this.gsjyList.forEach((item, index) => {
item.amount = jyqkObj[Object.keys(jyqkObj)[index]]?parseFloat(jyqkObj[Object.keys(jyqkObj)[index]].toFixed(2)):0 item.amount = jyqkObj[Object.keys(jyqkObj)[index]] ? parseFloat(jyqkObj[Object.keys(jyqkObj)[index]].toFixed(2)) : 0;
}) });
} }
} }
}, },
watch: { watch: {
financial(newVal, oldVal) { financial: {
this.handleFinancial() handler(newVal, oldVal) {
this.childFinancial = newVal;
this.handleFinancial();
},
deep: true
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.operations-container{ .operations-container {
margin: 0; margin: 0;
padding: 24px 16px; padding: 24px 16px;
background: #FFFFFF; background: #ffffff;
border-radius: 4px; border-radius: 4px;
.part-swiper{ .part-swiper {
position: relative; position: relative;
margin-top: 16px; margin-top: 16px;
.swiper-oper{ .swiper-oper {
width: calc(100% - 38px); width: calc(100% - 38px);
height: 96px; height: 96px;
margin-top: 8px; margin-top: 8px;
margin-left: 25px; margin-left: 25px;
overflow: hidden; overflow: hidden;
.swiper-slide{ .swiper-slide {
.swiper-div{ .swiper-div {
width: calc(100% - 12px); width: calc(100% - 12px);
height: 96px; height: 96px;
background: url("~@/assets/images/detail/overview/swiper_bg.png") no-repeat; background: url("~@/assets/images/detail/overview/swiper_bg.png")
background-size: 100% 100%; no-repeat;
.operations-title{ background-size: 100% 100%;
margin-right: 22px; .operations-title {
font-weight: bold; margin-right: 22px;
font-size: 20px; font-weight: bold;
color: #232323; font-size: 20px;
padding: 24px 16px 0 16px; color: #232323;
span{ padding: 24px 16px 0 16px;
font-size: 16px; span {
} font-size: 16px;
} }
.operations-info{ }
padding: 14px 16px 10px 16px; .operations-info {
justify-content: space-between; padding: 14px 16px 10px 16px;
font-size: 14px; justify-content: space-between;
color: #232323; font-size: 14px;
div{ color: #232323;
flex-shrink: 0; div {
} flex-shrink: 0;
span{ }
font-size: 12px; span {
margin-left: 6px; font-size: 12px;
img{ margin-left: 6px;
width: 10px; img {
height: 10px; width: 10px;
margin-right: 3px; height: 10px;
} margin-right: 3px;
} }
} }
} }
} }
} }
.swiper-oper-prev, .swiper-oper-next{ }
width: 16px; .swiper-oper-prev,
height: 96px; .swiper-oper-next {
background: #F0F5FC; width: 16px;
top: 0; height: 96px;
margin-top: 0; background: #f0f5fc;
&.swiper-button-disabled{ top: 0;
opacity: 1; margin-top: 0;
color:#AAAAAA; &.swiper-button-disabled {
background: #F5F5F5; opacity: 1;
} color: #aaaaaa;
i{ background: #f5f5f5;
color: #AAAAAA; }
} i {
&:hover i{ color: #aaaaaa;
color:#667199; }
} &:hover i {
&:after{ color: #667199;
content: ""; }
} &:after {
content: "";
} }
} }
.operations-list{ }
flex-wrap: wrap; .operations-list {
justify-content: space-between; flex-wrap: wrap;
.list-item{ justify-content: space-between;
width: calc(20% - 12px); .list-item {
height: 88px; width: calc(20% - 12px);
padding: 18px; height: 88px;
margin-top: 14px; padding: 18px;
font-size: 14px; margin-top: 14px;
color: #232323; font-size: 14px;
border: 1px solid #E2E7EE; color: #232323;
text-align: center; border: 1px solid #e2e7ee;
.list-item-all{ text-align: center;
justify-content: center; .list-item-all {
img{ justify-content: center;
width: 24px; img {
height: 24px; width: 24px;
margin-right: 4px; height: 24px;
} margin-right: 4px;
}
.list-item-amount{
padding-top: 6px;
font-weight: bold;
} }
} }
.list-item-amount {
padding-top: 6px;
font-weight: bold;
}
} }
} }
}
</style> </style>
...@@ -2,28 +2,18 @@ ...@@ -2,28 +2,18 @@
<div class="app-container clue-container"> <div class="app-container clue-container">
<div class="common-title">风险概览</div> <div class="common-title">风险概览</div>
<div class="flex-box clue-box" v-if="viewData[0].value>0"> <div class="flex-box clue-box" v-if="viewData[0].value>0">
<div class="clue-echarts"><div id="echartsRisk" style="width: 100%;height:300px; margin: 0 auto;"></div></div> <div class="clue-echarts">
<div id="echartsRisk" style="width: 100%;height:300px; margin: 0 auto;"></div>
</div>
<div class="table-item"> <div class="table-item">
<el-table <el-table :data="viewData" border style="width: 100%">
:data="viewData" <el-table-column prop="name" label="风险纬度分布"></el-table-column>
border <el-table-column prop="value" align="right" label="数量">
style="width: 100%"
>
<el-table-column
prop="name"
label="风险纬度分布"></el-table-column>
<el-table-column
prop="value"
align="right"
label="数量">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.value }}</span> <span>{{ scope.row.value }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column prop="bl" align="right" label="占比(%)">
prop="bl"
align="right"
label="占比(%)">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.bl }}</span> <span>{{ scope.row.bl }}</span>
</template> </template>
...@@ -31,13 +21,13 @@ ...@@ -31,13 +21,13 @@
</el-table> </el-table>
</div> </div>
</div> </div>
<no-data v-else/> <no-data v-else />
</div> </div>
</template> </template>
<script> <script>
import * as echarts from 'echarts' import * as echarts from 'echarts';
import NoData from '../../component/noData' import NoData from '../../component/noData';
export default { export default {
name: 'Risk', name: 'Risk',
props: ['statistic'], props: ['statistic'],
...@@ -46,14 +36,14 @@ export default { ...@@ -46,14 +36,14 @@ export default {
}, },
data() { data() {
return { return {
viewData:[ viewData: [
{ {
name:'开庭公告', name: '开庭公告',
value:'', value: '',
category:'credit', category: 'credit',
field:'openAnnouncement', field: 'openAnnouncement',
tz:'', tz: '',
bl:'' bl: ''
}, },
/*{ /*{
name:'企业公告', name:'企业公告',
...@@ -80,12 +70,12 @@ export default { ...@@ -80,12 +70,12 @@ export default {
bl:'' bl:''
},*/ },*/
{ {
name:'法院公告', name: '法院公告',
value:'', value: '',
category:'credit', category: 'credit',
field:'courtAnnouncement', field: 'courtAnnouncement',
tz:'', tz: '',
bl:'' bl: ''
}, },
/*{ /*{
name:'立案信息', name:'立案信息',
...@@ -96,75 +86,76 @@ export default { ...@@ -96,75 +86,76 @@ export default {
bl:'' bl:''
},*/ },*/
{ {
name:'被执行人', name: '被执行人',
value:'', value: '',
category:'credit', category: 'credit',
field:'dishonestExecutee', field: 'dishonestExecutee',
tz:'', tz: '',
bl:'' bl: ''
}, },
{ {
name:'失信被执行人', name: '失信被执行人',
value:'', value: '',
category:'credit', category: 'credit',
field:'dishonestExecutor', field: 'dishonestExecutor',
tz:'', tz: '',
bl:'' bl: ''
}, },
{ {
name:'行政处罚', name: '行政处罚',
value:'', value: '',
category:'credit', category: 'credit',
field:'adminSanction', field: 'adminSanction',
tz:'', tz: '',
bl:'' bl: ''
}, },
], ],
} childStatistic: {}
};
}, },
created() { created() {
}, },
mounted() { mounted() {
}, },
methods: { methods: {
handView(){ handView() {
let totalVal = this.viewData.map(item => { let totalVal = this.viewData.map(item => {
let number = this.statistic[item.category]&&this.statistic[item.category][item.field]?this.statistic[item.category][item.field]:0 let number = this.childStatistic[item.category] && this.childStatistic[item.category][item.field] ? this.childStatistic[item.category][item.field] : 0;
return number return number;
}).reduce((prev, cur) => prev + cur) }).reduce((prev, cur) => prev + cur);
this.viewData = this.viewData.map(item => { this.viewData = this.viewData.map(item => {
let number = this.statistic[item.category]&&this.statistic[item.category][item.field]?this.statistic[item.category][item.field]:0 let number = this.childStatistic[item.category] && this.childStatistic[item.category][item.field] ? this.childStatistic[item.category][item.field] : 0;
let bl = number ? parseFloat(Number(Number(number)/Number(totalVal)*100).toFixed(2)) : 0 let bl = number ? parseFloat(Number(Number(number) / Number(totalVal) * 100).toFixed(2)) : 0;
let it = {name:item.name, value:number, tz: '', bl:bl} let it = { name: item.name, value: number, tz: '', bl: bl };
return it return it;
}) });
this.viewData.sort((a, b) => { this.viewData.sort((a, b) => {
return a.value < b.value ? 1 : -1; return a.value < b.value ? 1 : -1;
}) });
this.$nextTick(()=>{ this.$nextTick(() => {
if(this.viewData[0].value>0){ if (this.viewData[0].value > 0) {
this.getDT(); this.getDT();
} }
}) });
}, },
getDT(){ getDT() {
let myChart = echarts.init(document.getElementById("echartsRisk")) let myChart = echarts.init(document.getElementById("echartsRisk"));
let option = { let option = {
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
borderWidth:0, borderWidth: 0,
backgroundColor:"rgba(255, 255, 255, 0.8)", backgroundColor: "rgba(255, 255, 255, 0.8)",
formatter: function (params) { formatter: function (params) {
var result = '' var result = '';
result+='<h3 style="color: #232226;padding: 0 0 5px 0;margin: 0;">'+ params.data.name +'</h3>' result += '<h3 style="color: #232226;padding: 0 0 5px 0;margin: 0;">' + params.data.name + '</h3>';
result+='<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;">'+ params.data.value +'个</p>' result += '<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;">' + params.data.value + '个</p>';
if(params.data.tz){ if (params.data.tz) {
result+='<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;" >'+ params.data.tz +'亿元</p>' result += '<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;" >' + params.data.tz + '亿元</p>';
} }
result+='<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;">'+ params.data.bl+'%</p>' result += '<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;">' + params.data.bl + '%</p>';
return result; return result;
}, },
extraCssText:'width:150px!important;', extraCssText: 'width:150px!important;',
}, },
legend: { legend: {
type: 'scroll', type: 'scroll',
...@@ -172,10 +163,10 @@ export default { ...@@ -172,10 +163,10 @@ export default {
bottom: 20, bottom: 20,
data: this.viewData, data: this.viewData,
pageButtonPosition: 'end', pageButtonPosition: 'end',
itemWidth:12, itemWidth: 12,
itemHeight:8, itemHeight: 8,
}, },
color: ['#8A82F3','#5B9CF7','#43BBE0','#8ECF95','#FFDC6B', '#FE9C77', '#E8649B', '#8A82F3'], color: ['#8A82F3', '#5B9CF7', '#43BBE0', '#8ECF95', '#FFDC6B', '#FE9C77', '#E8649B', '#8A82F3'],
series: [ series: [
{ {
type: 'pie', type: 'pie',
...@@ -191,39 +182,43 @@ export default { ...@@ -191,39 +182,43 @@ export default {
} }
} }
] ]
} };
myChart.setOption(option) myChart.setOption(option);
} }
}, },
watch: { watch: {
statistic(newVal, oldVal) { statistic: {
if(newVal){ handler(newVal, oldVal) {
this.handView() this.childStatistic = newVal;
} if (newVal) {
this.handView();
}
},
deep: true
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.clue-container{ .clue-container {
margin: 0; margin: 0;
padding: 24px 16px; padding: 24px 16px;
background: #FFFFFF; background: #ffffff;
border-radius: 4px; border-radius: 4px;
.clue-box{ .clue-box {
width: 100%; width: 100%;
justify-content: space-between; justify-content: space-between;
margin-top: 20px; margin-top: 20px;
.clue-echarts{ .clue-echarts {
width: calc(50% - 8px); width: calc(50% - 8px);
} }
.table-item{ .table-item {
width: calc(50% - 8px); width: calc(50% - 8px);
::v-deep .el-table--border .el-table__cell{ ::v-deep .el-table--border .el-table__cell {
border-bottom: 0; border-bottom: 0;
}
} }
} }
} }
}
</style> </style>
<template> <template>
<div v-loading="loading" class="market-container"> <div v-loading="loading" class="market-container">
<iframe id="companyIframe" class="market-iframe" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" width="100%" :src="src" /> <iframe id="companyIframe" class="market-iframe" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" width="100%" :src="src" />
<transition name="fade" mode="out-in" appear>
<max-page-size-tip v-if="showMaxPageTip" @closeMaxTip="showMaxPageTip = false"></max-page-size-tip>
</transition>
</div> </div>
</template> </template>
...@@ -39,13 +35,7 @@ export default { ...@@ -39,13 +35,7 @@ export default {
}; };
}, },
created() { created() {
if (window.location.host === 'http://szh.jiansheku.com' || window.location.host === 'szh.jiansheku.com') { this.domain = process.env.VUE_APP_SUB_SYSTEM_ADDRESS;
this.domain = 'https://plug.jiansheku.com';
} else {
this.domain = 'https://pre-plug.jiansheku.com';
// this.domain = 'http://192.168.60.8:3400';
// this.domain = 'http://192.168.60.210:3400';
}
this.gettokens(); this.gettokens();
this.iframeObserver(); this.iframeObserver();
let that = this; let that = this;
...@@ -63,7 +53,7 @@ export default { ...@@ -63,7 +53,7 @@ export default {
window.removeEventListener("message", this.pagecapListener, { passive: true }); window.removeEventListener("message", this.pagecapListener, { passive: true });
window.removeEventListener("message", this.linkListener); window.removeEventListener("message", this.linkListener);
// 移除layout样式 // 移除layout样式
this.iframeIns.contentWindow.postMessage("removeHtmlLayoutStyle", { targetOrigin: this.domain, }); this.iframeIns?.contentWindow ? this.iframeIns.contentWindow.postMessage("removeHtmlLayoutStyle", { targetOrigin: this.domain, }) : null;
}, },
methods: { methods: {
linkListener(event) { linkListener(event) {
...@@ -102,7 +92,9 @@ export default { ...@@ -102,7 +92,9 @@ export default {
const { origin, data } = e; const { origin, data } = e;
if (origin != this.domain) return; if (origin != this.domain) return;
if (data == "pageCurrentMaxSize") { if (data == "pageCurrentMaxSize") {
this.showMaxPageTip = true; this.$maxTip("您可通过筛选工具来查询数据~若有更多需求请联系客服 0262798729!").then(({ done, uid }) => {
done();
});
} }
}, },
gettokens() { gettokens() {
......
...@@ -204,7 +204,7 @@ export default { ...@@ -204,7 +204,7 @@ export default {
// 设置上传的请求头部 // 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() }, headers: { Authorization: "Bearer " + getToken() },
// 上传的地址 // 上传的地址
url: process.env.VUE_APP_BASE_API + `${process.env.ENV == "production" ? "business/open/tender/importData/" : "/business/open/tender/importData/"}${this.detailId ? this.detailId : parseInt(this.$route.query.id)}`, url: process.env.VUE_APP_BASE_API + `"/business/open/tender/importData/"}${this.detailId ? this.detailId : parseInt(this.$route.query.id)}`,
// 展示上传结果 // 展示上传结果
showResult: false, showResult: false,
// 模板下载地址 // 模板下载地址
......
<template>
<div class="subsystem-iframe-container">
<div @click="$router.push({path : '/subsystem',query : ({id:1})})">11</div>
</div>
</template>
<script>
import { getUrlSearchQuery } from "@/utils/";
export default {
name: "subsystemIframeContainer",
data() {
return {
};
},
//可访问data属性
created() {
console.log(this.$route);
console.log(getUrlSearchQuery());
},
//计算集
computed: {
},
//方法集
methods: {
},
// 渲染方法
render(createElement) {
}
}
</script>
<style lang="scss" scoped>
.subsystem-iframe-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 16px 24px;
box-sizing: border-box;
}
</style>
package com.dsk.system.domain.vo; package com.dsk.system.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.dsk.common.annotation.Excel;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
...@@ -23,38 +24,38 @@ public class SysUserImportVo implements Serializable { ...@@ -23,38 +24,38 @@ public class SysUserImportVo implements Serializable {
/** /**
* 所属组织 * 所属组织
*/ */
@ExcelProperty(value = "*所属组织") @Excel(name = "所属组织(必填)")
private String deptName; private String deptName;
/** /**
* 用户昵称 * 用户昵称
*/ */
@ExcelProperty(value = "*用户昵称") @Excel(name = "用户名称(必填)")
private String nickName; private String nickName;
/** /**
* 手机号码 * 手机号码
*/ */
@ExcelProperty(value = "*手机号码") @Excel(name = "手机号码(必填)")
private String phonenumber; private String phonenumber;
/** /**
* 用户角色 * 用户角色
*/ */
@ExcelProperty(value = "*用户角色") @Excel(name = "用户角色")
private String roleName; private String roleName;
/** /**
* 失败原因 * 失败原因
* 该字段无需同步到模板中 * 该字段无需同步到模板中
*/ */
@ExcelProperty(value = "失败原因") @Excel(name = "失败原因")
private String failReason; private String failReason;
public SysUserImportVo(String deptName, String nickName, String phonenumber, String roleName) { public SysUserImportVo(String deptName, String nickName, String phonenumber, String roleName) {
this.deptName = deptName.replace(" ", ""); this.deptName = deptName.replace(" ", "");
this.nickName = nickName.replace(" ", ""); this.nickName = nickName.replace(" ", "");
this.phonenumber = phonenumber; this.phonenumber = phonenumber.replace(" ", "");
this.roleName = roleName.replace(" ", ""); this.roleName = roleName.replace(" ", "");
} }
} }
...@@ -3,6 +3,7 @@ package com.dsk.system.service; ...@@ -3,6 +3,7 @@ package com.dsk.system.service;
import com.dsk.common.core.domain.PageQuery; import com.dsk.common.core.domain.PageQuery;
import com.dsk.system.domain.SysUser; import com.dsk.system.domain.SysUser;
import com.dsk.common.core.page.TableDataInfo; import com.dsk.common.core.page.TableDataInfo;
import com.dsk.system.domain.vo.SysUserImportVo;
import java.util.List; import java.util.List;
...@@ -111,6 +112,15 @@ public interface ISysUserService { ...@@ -111,6 +112,15 @@ public interface ISysUserService {
*/ */
void checkUserAllowed(SysUser user); void checkUserAllowed(SysUser user);
/**
* 批量导入(更新)用户
*
* @param userImportList Excel中识别出的用户集合
* @param updateSupport 是否更新标识符
* @return 导入失败用户集合
*/
List<SysUserImportVo> batchImportUser(List<SysUserImportVo> userImportList, boolean updateSupport);
/** /**
* 校验用户是否有数据权限 * 校验用户是否有数据权限
* *
......
package com.dsk.system.service.impl; package com.dsk.system.service.impl;
import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
...@@ -22,7 +23,9 @@ import com.dsk.common.helper.LoginHelper; ...@@ -22,7 +23,9 @@ import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.PasswordUtils; import com.dsk.common.utils.PasswordUtils;
import com.dsk.common.utils.StreamUtils; import com.dsk.common.utils.StreamUtils;
import com.dsk.common.utils.StringUtils; import com.dsk.common.utils.StringUtils;
import com.dsk.common.utils.ValidatorUtils;
import com.dsk.system.domain.*; import com.dsk.system.domain.*;
import com.dsk.system.domain.vo.SysUserImportVo;
import com.dsk.system.mapper.*; import com.dsk.system.mapper.*;
import com.dsk.system.service.ISysUserService; import com.dsk.system.service.ISysUserService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
...@@ -35,10 +38,7 @@ import org.springframework.cache.annotation.Cacheable; ...@@ -35,10 +38,7 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/** /**
* 用户 业务层处理 * 用户 业务层处理
...@@ -250,6 +250,73 @@ public class SysUserServiceImpl implements ISysUserService, UserService { ...@@ -250,6 +250,73 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
} }
} }
@Override
@Transactional(rollbackFor = Exception.class)
public List<SysUserImportVo> batchImportUser(List<SysUserImportVo> userImportList, boolean updateSupport) {
//导入失败用户集合
ArrayList<SysUserImportVo> failImportUsers = new ArrayList<>();
//导入成功用户数量
int successNum = 0;
//导入失败用户数量
int failureNum = 0;
for (SysUserImportVo userVo : userImportList) {
//无需判断字段是否为空,若查不到,直接存入导入失败的用户集合
SysUser user = this.baseMapper.selectUserByPhonenumber(userVo.getPhonenumber());
SysDept dept = this.deptMapper.selectOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptName, userVo.getDeptName()));
SysRole role = this.roleMapper.selectOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleName, userVo.getRoleName()));
try {
if (ObjectUtil.isNull(dept)) {
throw new ServiceException("部门不存在");
}
if (ObjectUtil.isNull(role)) {
throw new ServiceException("角色不存在");
}
// 验证是否存在这个用户
if (ObjectUtil.isNull(user)) {
user = BeanUtil.toBean(userVo, SysUser.class);
user.setUserName(userVo.getPhonenumber());
user.setDeptId(dept.getDeptId());
user.setDept(dept);
user.setRoleId(role.getRoleId());
user.setRoleIds(new Long[]{role.getRoleId()});
ValidatorUtils.validate(user);
user.setCreateBy(LoginHelper.getUsername());
this.insertUser(user);
} else if (updateSupport) {
Long userId = user.getUserId();
user = BeanUtil.toBean(userVo, SysUser.class);
user.setUserId(userId);
user.setUserName(userVo.getPhonenumber());
user.setDeptId(dept.getDeptId());
user.setDept(dept);
user.setRoleId(role.getRoleId());
user.setRoleIds(new Long[]{role.getRoleId()});
ValidatorUtils.validate(user);
this.checkUserAllowed(user);
this.checkUserDataScope(user.getUserId());
user.setUpdateBy(LoginHelper.getUsername());
this.updateUser(user);
log.info(++successNum + "、账号 " + user.getUserName() + " 更新成功");
} else {
userVo.setFailReason("手机号已存在");
log.error(++failureNum + "、账号 " + user.getUserName() + " 已存在");
failImportUsers.add(userVo);
}
} catch (Exception e) {
userVo.setFailReason(e.getMessage());
failImportUsers.add(userVo);
log.error(++failureNum + "、账号 " + userVo.getPhonenumber() + " 导入失败:", e);
}
}
return failImportUsers;
}
/** /**
* 校验用户是否有数据权限 * 校验用户是否有数据权限
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment