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;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.dsk.biz.utils.ExcelUtils;
import com.dsk.common.annotation.Log;
import com.dsk.common.constant.GlobalConstants;
import com.dsk.common.core.controller.BaseController;
......@@ -13,7 +14,7 @@ import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.R;
import com.dsk.common.core.page.TableDataInfo;
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.utils.StreamUtils;
import com.dsk.common.utils.StringUtils;
......@@ -25,7 +26,6 @@ import com.dsk.system.domain.SysUser;
import com.dsk.system.domain.vo.SysUserExportVo;
import com.dsk.system.domain.vo.SysUserImportVo;
import com.dsk.system.domain.vo.SysUserVo;
import com.dsk.system.listener.SysUserImportListener;
import com.dsk.system.service.ISysDeptService;
import com.dsk.system.service.ISysPostService;
import com.dsk.system.service.ISysRoleService;
......@@ -106,14 +106,39 @@ public class SysUserController extends BaseController {
@SaCheckPermission("system:user:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
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));
List<SysUserImportVo> resultList = result.getList();
if (!resultList.isEmpty()) {
//ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport));
//List<SysUserImportVo> resultList = result.getList();
//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();
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 {
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
List<Object> list = new ArrayList<>();
list.add(new SysUserImportVo("测试组织", "测试用户昵称", "18888888888", "测试角色"));
list.add(new SysUserImportVo("重庆市轨道交通(集团)有限公司", "刘国海", "18888888888", "运营部部长"));
ExcelUtil.exportTemplate(list, "用户数据", "excel/userImportTemplate.xlsx", response);
}
......
......@@ -9,3 +9,8 @@ VUE_APP_BASE_API = '/prod-api'
# 路由懒加载
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'
# 数字化经营履约全生命链路管理系统/生产环境
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'
# 数字化经营履约全生命链路管理系统/测试环境
VUE_APP_BASE_API = '/prod-api'
\ No newline at end of file
VUE_APP_BASE_API = '/prod-api'
# 子系统地址
VUE_APP_SUB_SYSTEM_ADDRESS = "https://pre-plug.jiansheku.com"
\ No newline at end of file
module.exports = {
presets: [
// 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': {
'development': {
......@@ -10,4 +11,4 @@ module.exports = {
'plugins': ['dynamic-import-node']
}
}
}
\ No newline at end of file
};
\ No newline at end of file
......@@ -70,6 +70,8 @@
"vuex": "3.6.0"
},
"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-eslint": "4.4.6",
"@vue/cli-service": "4.4.6",
......@@ -87,6 +89,7 @@
"sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1",
"vue-styled-components": "^1.6.0",
"vue-template-compiler": "2.6.12"
},
"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 @@
<script>
import iframeToggle from "./IframeToggle/index"
export default {
name: 'AppMain',
components: { iframeToggle },
......@@ -20,7 +19,7 @@ export default {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
return this.$route.fullPath
}
}
}
......
import tab from './tab'
import auth from './auth'
import cache from './cache'
import modal from './modal'
import download from './download'
import tab from './tab';
import auth from './auth';
import cache from './cache';
import modal from './modal';
import download from './download';
import msgBox from "@/components/JsComponents/MaxPageSizeTip.js";
export default {
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 = {
const mutations = {
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(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
......@@ -15,7 +15,7 @@ const mutations = {
)
},
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(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
......@@ -30,15 +30,15 @@ const mutations = {
},
DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
if (v.fullPath === view.fullPath) {
state.visitedViews.splice(i, 1)
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) => {
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) => {
const index = state.cachedViews.indexOf(view.name)
......@@ -47,9 +47,9 @@ const mutations = {
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
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) => {
const index = state.cachedViews.indexOf(view.name)
......@@ -70,14 +70,14 @@ const mutations = {
},
UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
if (v.fullPath === view.fullPath) {
v = Object.assign(v, view)
break
}
}
},
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) {
return
}
......@@ -90,14 +90,14 @@ const mutations = {
state.cachedViews.splice(i, 1)
}
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)
}
return false
})
},
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) {
return
}
......@@ -110,7 +110,7 @@ const mutations = {
state.cachedViews.splice(i, 1)
}
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)
}
return false
......
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken ,setTenantid} from '@/utils/auth'
import { login, logout, getInfo } from '@/api/login';
import { getToken, setToken, removeToken, setTenantid } from '@/utils/auth';
const user = {
state: {
......@@ -8,100 +8,100 @@ const user = {
avatar: '',
roles: [],
permissions: [],
userId:'',
phonenumber:'',
userId: '',
phonenumber: '',
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
state.token = token;
},
SET_NAME: (state, name) => {
state.name = name
state.name = name;
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
state.avatar = avatar;
},
SET_ROLES: (state, roles) => {
state.roles = roles
state.roles = roles;
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
state.permissions = permissions;
},
SET_USERID: (state, userId) => {
state.userId = userId
state.userId = userId;
},
SET_USERPHONE: (state, phonenumber) => {
state.phonenumber = phonenumber
state.phonenumber = phonenumber;
}
},
actions: {
// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
const username = userInfo.username.trim();
const password = userInfo.password;
const code = userInfo.code;
const uuid = userInfo.uuid;
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
setToken(res.data.token)
commit('SET_TOKEN', res.data.token)
setTenantid(res.data.tenantId)
resolve()
setToken(res.data.token);
commit('SET_TOKEN', res.data.token);
setTenantid(res.data.tenantId);
resolve();
}).catch(error => {
reject(error)
})
})
reject(error);
});
});
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.data.user
const avatar = user.avatar ? process.env.VUE_APP_BASE_API + user.avatar : '';
const user = res.data.user;
const avatar = user.avatar ? user.avatar : '';
if (res.data.roles && res.data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.data.roles)
commit('SET_PERMISSIONS', res.data.permissions)
commit('SET_ROLES', res.data.roles);
commit('SET_PERMISSIONS', res.data.permissions);
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
commit('SET_ROLES', ['ROLE_DEFAULT']);
}
commit('SET_NAME', user.nickName)
commit('SET_AVATAR', avatar)
commit('SET_USERID', user.userId)
commit('SET_USERPHONE', user.phonenumber)
resolve(res)
commit('SET_NAME', user.nickName);
commit('SET_AVATAR', avatar);
commit('SET_USERID', user.userId);
commit('SET_USERPHONE', user.phonenumber);
resolve(res);
}).catch(error => {
reject(error)
})
})
reject(error);
});
});
},
// 退出系统
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
removeToken()
resolve()
commit('SET_TOKEN', '');
commit('SET_ROLES', []);
commit('SET_PERMISSIONS', []);
removeToken();
resolve();
}).catch(error => {
reject(error)
})
})
reject(error);
});
});
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
commit('SET_TOKEN', '');
removeToken();
resolve();
});
}
}
}
};
export default user
export default user;
......@@ -401,6 +401,62 @@ export function isNumberStr(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([
// 企业速览
......
......@@ -2,12 +2,44 @@
* @Author: thy
* @Date: 2023-10-26 14:56:41
* @LastEditors: thy
* @LastEditTime: 2023-10-30 14:26:31
* @LastEditTime: 2023-10-31 09:28:26
* @Description: file content
* @FilePath: \dsk-operate-ui\src\utils\postMessageBridge\bridge\index.js
*/
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 @@
<template slot="suffix">
<transition mode="out-in" appear name="fade">
<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>
</template>
</el-input>
......
<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" />
<div class="flex-box part-main">
<div class="part-left">
......@@ -194,9 +194,6 @@ export default {
companyName: 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');
if (titlename) {
titlename.innerText = this.customerInfo.companyName;
......@@ -392,22 +389,48 @@ export default {
margin-right: 16px;
padding-bottom: 16px;
position: fixed;
background: #FFFFFF;
background: #ffffff;
width: 144px;
}
.part-right {
min-width: 1088px;
width: 100%;
background: #FFFFFF;
background: #ffffff;
border-radius: 4px;
margin-left: 160px;
::v-deep .el-table__header-wrapper{
::v-deep .el-table__header-wrapper {
position: sticky;
top:0;
top: 0;
z-index: 9;
}
#groupBox{
#groupBox {
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>
......@@ -10,7 +10,8 @@
<div class="operations-title">{{item.bratingSubjectLevel}}-<span>{{item.ratingDate}}</span></div>
<div class="flex-box operations-info">
<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>
</li>
......@@ -32,38 +33,39 @@
</template>
<script>
import {bondCreditRating} from '@/api/detail/party-a/overview'
var Swiper = require('@/assets/lib/swiper/swiper-bundle.min.js')
import skeleton from '@/views/project/projectList/component/skeleton'
import "@/assets/lib/swiper/swiper-bundle.css"
import NoData from '../../component/noData'
import { bondCreditRating } from '@/api/detail/party-a/overview';
var Swiper = require('@/assets/lib/swiper/swiper-bundle.min.js');
import skeleton from '@/views/project/projectList/component/skeleton';
import "@/assets/lib/swiper/swiper-bundle.css";
import NoData from '../../component/noData';
export default {
name: 'Overview',
props: ['companyId', 'financial'],
components: {
NoData,skeleton
NoData, skeleton
},
data() {
return {
operList: [],
isSkeleton:true,
isSkeleton: true,
gsjyList: [
{ 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_ico3.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_ico1.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_ico4.png'), amount: '' },
{ name: '总负债', ico: require('@/assets/images/detail/overview/gsjy_ico5.png'), amount: '' }
],
}
childFinancial: {}
};
},
created() {
this.handleQuery()
this.handleQuery();
},
mounted() {
this.companySwiper()
this.companySwiper();
},
methods: {
companySwiper(){
companySwiper() {
new Swiper('.swiper-oper', {
slidesPerView: 6,
// 设置点击箭头
......@@ -71,136 +73,142 @@ export default {
nextEl: '.swiper-oper-next',
prevEl: '.swiper-oper-prev',
}
})
});
},
async handleQuery() {
this.isSkeleton = true;
let res = await bondCreditRating({cid: this.companyId})
if(res.code==200){
let res = await bondCreditRating({ cid: this.companyId });
if (res.code == 200) {
this.isSkeleton = false;
this.operList = res.data || []
this.operList = res.data || [];
this.$nextTick(() => {
this.companySwiper()
})
this.companySwiper();
});
}
},
handleFinancial(){
if(this.financial){
let { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities } = this.financial
let jyqkObj = { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities }
handleFinancial() {
if (this.childFinancial) {
let { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities } = this.childFinancial;
let jyqkObj = { totalAssets, belongNetAssets, creditBalance, operatingIncome, totalLiabilities };
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: {
financial(newVal, oldVal) {
this.handleFinancial()
financial: {
handler(newVal, oldVal) {
this.childFinancial = newVal;
this.handleFinancial();
},
deep: true
}
}
}
</script>
<style lang="scss" scoped>
.operations-container{
margin: 0;
padding: 24px 16px;
background: #FFFFFF;
border-radius: 4px;
.part-swiper{
position: relative;
margin-top: 16px;
.swiper-oper{
width: calc(100% - 38px);
height: 96px;
margin-top: 8px;
margin-left: 25px;
overflow: hidden;
.swiper-slide{
.swiper-div{
width: calc(100% - 12px);
height: 96px;
background: url("~@/assets/images/detail/overview/swiper_bg.png") no-repeat;
background-size: 100% 100%;
.operations-title{
margin-right: 22px;
font-weight: bold;
font-size: 20px;
color: #232323;
padding: 24px 16px 0 16px;
span{
font-size: 16px;
}
.operations-container {
margin: 0;
padding: 24px 16px;
background: #ffffff;
border-radius: 4px;
.part-swiper {
position: relative;
margin-top: 16px;
.swiper-oper {
width: calc(100% - 38px);
height: 96px;
margin-top: 8px;
margin-left: 25px;
overflow: hidden;
.swiper-slide {
.swiper-div {
width: calc(100% - 12px);
height: 96px;
background: url("~@/assets/images/detail/overview/swiper_bg.png")
no-repeat;
background-size: 100% 100%;
.operations-title {
margin-right: 22px;
font-weight: bold;
font-size: 20px;
color: #232323;
padding: 24px 16px 0 16px;
span {
font-size: 16px;
}
.operations-info{
padding: 14px 16px 10px 16px;
justify-content: space-between;
font-size: 14px;
color: #232323;
div{
flex-shrink: 0;
}
span{
font-size: 12px;
margin-left: 6px;
img{
width: 10px;
height: 10px;
margin-right: 3px;
}
}
.operations-info {
padding: 14px 16px 10px 16px;
justify-content: space-between;
font-size: 14px;
color: #232323;
div {
flex-shrink: 0;
}
span {
font-size: 12px;
margin-left: 6px;
img {
width: 10px;
height: 10px;
margin-right: 3px;
}
}
}
}
}
.swiper-oper-prev, .swiper-oper-next{
width: 16px;
height: 96px;
background: #F0F5FC;
top: 0;
margin-top: 0;
&.swiper-button-disabled{
opacity: 1;
color:#AAAAAA;
background: #F5F5F5;
}
i{
color: #AAAAAA;
}
&:hover i{
color:#667199;
}
&:after{
content: "";
}
}
.swiper-oper-prev,
.swiper-oper-next {
width: 16px;
height: 96px;
background: #f0f5fc;
top: 0;
margin-top: 0;
&.swiper-button-disabled {
opacity: 1;
color: #aaaaaa;
background: #f5f5f5;
}
i {
color: #aaaaaa;
}
&:hover i {
color: #667199;
}
&:after {
content: "";
}
}
.operations-list{
flex-wrap: wrap;
justify-content: space-between;
.list-item{
width: calc(20% - 12px);
height: 88px;
padding: 18px;
margin-top: 14px;
font-size: 14px;
color: #232323;
border: 1px solid #E2E7EE;
text-align: center;
.list-item-all{
justify-content: center;
img{
width: 24px;
height: 24px;
margin-right: 4px;
}
}
.list-item-amount{
padding-top: 6px;
font-weight: bold;
}
.operations-list {
flex-wrap: wrap;
justify-content: space-between;
.list-item {
width: calc(20% - 12px);
height: 88px;
padding: 18px;
margin-top: 14px;
font-size: 14px;
color: #232323;
border: 1px solid #e2e7ee;
text-align: center;
.list-item-all {
justify-content: center;
img {
width: 24px;
height: 24px;
margin-right: 4px;
}
}
.list-item-amount {
padding-top: 6px;
font-weight: bold;
}
}
}
}
</style>
......@@ -2,28 +2,18 @@
<div class="app-container clue-container">
<div class="common-title">风险概览</div>
<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">
<el-table
:data="viewData"
border
style="width: 100%"
>
<el-table-column
prop="name"
label="风险纬度分布"></el-table-column>
<el-table-column
prop="value"
align="right"
label="数量">
<el-table :data="viewData" border style="width: 100%">
<el-table-column prop="name" label="风险纬度分布"></el-table-column>
<el-table-column prop="value" align="right" label="数量">
<template slot-scope="scope">
<span>{{ scope.row.value }}</span>
</template>
</el-table-column>
<el-table-column
prop="bl"
align="right"
label="占比(%)">
<el-table-column prop="bl" align="right" label="占比(%)">
<template slot-scope="scope">
<span>{{ scope.row.bl }}</span>
</template>
......@@ -31,13 +21,13 @@
</el-table>
</div>
</div>
<no-data v-else/>
<no-data v-else />
</div>
</template>
<script>
import * as echarts from 'echarts'
import NoData from '../../component/noData'
import * as echarts from 'echarts';
import NoData from '../../component/noData';
export default {
name: 'Risk',
props: ['statistic'],
......@@ -46,14 +36,14 @@ export default {
},
data() {
return {
viewData:[
viewData: [
{
name:'开庭公告',
value:'',
category:'credit',
field:'openAnnouncement',
tz:'',
bl:''
name: '开庭公告',
value: '',
category: 'credit',
field: 'openAnnouncement',
tz: '',
bl: ''
},
/*{
name:'企业公告',
......@@ -80,12 +70,12 @@ export default {
bl:''
},*/
{
name:'法院公告',
value:'',
category:'credit',
field:'courtAnnouncement',
tz:'',
bl:''
name: '法院公告',
value: '',
category: 'credit',
field: 'courtAnnouncement',
tz: '',
bl: ''
},
/*{
name:'立案信息',
......@@ -96,75 +86,76 @@ export default {
bl:''
},*/
{
name:'被执行人',
value:'',
category:'credit',
field:'dishonestExecutee',
tz:'',
bl:''
name: '被执行人',
value: '',
category: 'credit',
field: 'dishonestExecutee',
tz: '',
bl: ''
},
{
name:'失信被执行人',
value:'',
category:'credit',
field:'dishonestExecutor',
tz:'',
bl:''
name: '失信被执行人',
value: '',
category: 'credit',
field: 'dishonestExecutor',
tz: '',
bl: ''
},
{
name:'行政处罚',
value:'',
category:'credit',
field:'adminSanction',
tz:'',
bl:''
name: '行政处罚',
value: '',
category: 'credit',
field: 'adminSanction',
tz: '',
bl: ''
},
],
}
childStatistic: {}
};
},
created() {
},
mounted() {
},
methods: {
handView(){
handView() {
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
return number
}).reduce((prev, cur) => prev + cur)
let number = this.childStatistic[item.category] && this.childStatistic[item.category][item.field] ? this.childStatistic[item.category][item.field] : 0;
return number;
}).reduce((prev, cur) => prev + cur);
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 bl = number ? parseFloat(Number(Number(number)/Number(totalVal)*100).toFixed(2)) : 0
let it = {name:item.name, value:number, tz: '', bl:bl}
return it
})
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 it = { name: item.name, value: number, tz: '', bl: bl };
return it;
});
this.viewData.sort((a, b) => {
return a.value < b.value ? 1 : -1;
})
this.$nextTick(()=>{
if(this.viewData[0].value>0){
});
this.$nextTick(() => {
if (this.viewData[0].value > 0) {
this.getDT();
}
})
});
},
getDT(){
let myChart = echarts.init(document.getElementById("echartsRisk"))
getDT() {
let myChart = echarts.init(document.getElementById("echartsRisk"));
let option = {
tooltip: {
trigger: 'item',
borderWidth:0,
backgroundColor:"rgba(255, 255, 255, 0.8)",
borderWidth: 0,
backgroundColor: "rgba(255, 255, 255, 0.8)",
formatter: function (params) {
var result = ''
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>'
if(params.data.tz){
result+='<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;" >'+ params.data.tz +'亿元</p>'
var result = '';
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>';
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.bl+'%</p>'
result += '<p style="color: rgba(35,35,35,0.8);padding: 0;margin: 0;">' + params.data.bl + '%</p>';
return result;
},
extraCssText:'width:150px!important;',
extraCssText: 'width:150px!important;',
},
legend: {
type: 'scroll',
......@@ -172,10 +163,10 @@ export default {
bottom: 20,
data: this.viewData,
pageButtonPosition: 'end',
itemWidth:12,
itemHeight:8,
itemWidth: 12,
itemHeight: 8,
},
color: ['#8A82F3','#5B9CF7','#43BBE0','#8ECF95','#FFDC6B', '#FE9C77', '#E8649B', '#8A82F3'],
color: ['#8A82F3', '#5B9CF7', '#43BBE0', '#8ECF95', '#FFDC6B', '#FE9C77', '#E8649B', '#8A82F3'],
series: [
{
type: 'pie',
......@@ -191,39 +182,43 @@ export default {
}
}
]
}
myChart.setOption(option)
};
myChart.setOption(option);
}
},
watch: {
statistic(newVal, oldVal) {
if(newVal){
this.handView()
}
statistic: {
handler(newVal, oldVal) {
this.childStatistic = newVal;
if (newVal) {
this.handView();
}
},
deep: true
}
}
}
</script>
<style lang="scss" scoped>
.clue-container{
margin: 0;
padding: 24px 16px;
background: #FFFFFF;
border-radius: 4px;
.clue-box{
width: 100%;
justify-content: space-between;
margin-top: 20px;
.clue-echarts{
width: calc(50% - 8px);
}
.table-item{
width: calc(50% - 8px);
::v-deep .el-table--border .el-table__cell{
border-bottom: 0;
}
.clue-container {
margin: 0;
padding: 24px 16px;
background: #ffffff;
border-radius: 4px;
.clue-box {
width: 100%;
justify-content: space-between;
margin-top: 20px;
.clue-echarts {
width: calc(50% - 8px);
}
.table-item {
width: calc(50% - 8px);
::v-deep .el-table--border .el-table__cell {
border-bottom: 0;
}
}
}
}
</style>
<template>
<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" />
<transition name="fade" mode="out-in" appear>
<max-page-size-tip v-if="showMaxPageTip" @closeMaxTip="showMaxPageTip = false"></max-page-size-tip>
</transition>
</div>
</template>
......@@ -39,13 +35,7 @@ export default {
};
},
created() {
if (window.location.host === 'http://szh.jiansheku.com' || window.location.host === 'szh.jiansheku.com') {
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.domain = process.env.VUE_APP_SUB_SYSTEM_ADDRESS;
this.gettokens();
this.iframeObserver();
let that = this;
......@@ -63,7 +53,7 @@ export default {
window.removeEventListener("message", this.pagecapListener, { passive: true });
window.removeEventListener("message", this.linkListener);
// 移除layout样式
this.iframeIns.contentWindow.postMessage("removeHtmlLayoutStyle", { targetOrigin: this.domain, });
this.iframeIns?.contentWindow ? this.iframeIns.contentWindow.postMessage("removeHtmlLayoutStyle", { targetOrigin: this.domain, }) : null;
},
methods: {
linkListener(event) {
......@@ -102,7 +92,9 @@ export default {
const { origin, data } = e;
if (origin != this.domain) return;
if (data == "pageCurrentMaxSize") {
this.showMaxPageTip = true;
this.$maxTip("您可通过筛选工具来查询数据~若有更多需求请联系客服 0262798729!").then(({ done, uid }) => {
done();
});
}
},
gettokens() {
......
......@@ -204,7 +204,7 @@ export default {
// 设置上传的请求头部
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,
// 模板下载地址
......
<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;
import com.alibaba.excel.annotation.ExcelProperty;
import com.dsk.common.annotation.Excel;
import lombok.Data;
import lombok.NoArgsConstructor;
......@@ -23,38 +24,38 @@ public class SysUserImportVo implements Serializable {
/**
* 所属组织
*/
@ExcelProperty(value = "*所属组织")
@Excel(name = "所属组织(必填)")
private String deptName;
/**
* 用户昵称
*/
@ExcelProperty(value = "*用户昵称")
@Excel(name = "用户名称(必填)")
private String nickName;
/**
* 手机号码
*/
@ExcelProperty(value = "*手机号码")
@Excel(name = "手机号码(必填)")
private String phonenumber;
/**
* 用户角色
*/
@ExcelProperty(value = "*用户角色")
@Excel(name = "用户角色")
private String roleName;
/**
* 失败原因
* 该字段无需同步到模板中
*/
@ExcelProperty(value = "失败原因")
@Excel(name = "失败原因")
private String failReason;
public SysUserImportVo(String deptName, String nickName, String phonenumber, String roleName) {
this.deptName = deptName.replace(" ", "");
this.nickName = nickName.replace(" ", "");
this.phonenumber = phonenumber;
this.phonenumber = phonenumber.replace(" ", "");
this.roleName = roleName.replace(" ", "");
}
}
......@@ -3,6 +3,7 @@ package com.dsk.system.service;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.system.domain.SysUser;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.system.domain.vo.SysUserImportVo;
import java.util.List;
......@@ -111,6 +112,15 @@ public interface ISysUserService {
*/
void checkUserAllowed(SysUser user);
/**
* 批量导入(更新)用户
*
* @param userImportList Excel中识别出的用户集合
* @param updateSupport 是否更新标识符
* @return 导入失败用户集合
*/
List<SysUserImportVo> batchImportUser(List<SysUserImportVo> userImportList, boolean updateSupport);
/**
* 校验用户是否有数据权限
*
......
package com.dsk.system.service.impl;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ArrayUtil;
......@@ -22,7 +23,9 @@ import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.PasswordUtils;
import com.dsk.common.utils.StreamUtils;
import com.dsk.common.utils.StringUtils;
import com.dsk.common.utils.ValidatorUtils;
import com.dsk.system.domain.*;
import com.dsk.system.domain.vo.SysUserImportVo;
import com.dsk.system.mapper.*;
import com.dsk.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
......@@ -35,10 +38,7 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* 用户 业务层处理
......@@ -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