提交 a31915b3 编写于 作者: ibizdev's avatar ibizdev

ibizdev提交

上级 c8011d91
......@@ -123,12 +123,12 @@ export default class AppMpicker extends Vue {
* @param newVal
* @param val
*/
@Watch('curvalue', { deep: true })
@Watch('curvalue', {immediate:true, deep: true })
oncurvalueChange(newVal: any, val: any) {
this.value = [];
this.selectItems = [];
if (newVal) {
this.selectItems = JSON.parse(newVal);
this.selectItems = this.parseValue(JSON.parse(newVal));
this.selectItems.forEach((item: any) => {
this.value.push(item[this.deKeyField]);
let index = this.items.findIndex((i) => Object.is(i[this.deKeyField], item[this.deKeyField]));
......@@ -187,7 +187,7 @@ export default class AppMpicker extends Vue {
let index = this.items.findIndex((item) => Object.is(item[this.deKeyField], select));
if (index >= 0) {
let item = this.items[index];
val.push({ [this.deKeyField]: item[this.deKeyField], [this.deMajorField]: item.text });
val.push({ [this.deKeyField]: item[this.deKeyField], [this.deMajorField]: item[this.deMajorField] });
} else {
index = this.selectItems.findIndex((item: any) => Object.is(item[this.deKeyField], select));
if (index >= 0) {
......@@ -196,7 +196,7 @@ export default class AppMpicker extends Vue {
}
}
});
let value = val.length > 0 ? JSON.stringify(val) : '';
let value = val.length > 0 ? JSON.stringify(this.formatValue(val)) : '';
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
}
......@@ -211,7 +211,7 @@ export default class AppMpicker extends Vue {
let index = this.selectItems.findIndex((item: any) => Object.is(item[this.deKeyField], tag));
if (index >= 0) {
this.selectItems.splice(index, 1);
let value = this.selectItems.length > 0 ? JSON.stringify(this.selectItems) : '';
let value = this.selectItems.length > 0 ? JSON.stringify(this.formatValue(this.selectItems)) : '';
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
}
......@@ -256,13 +256,50 @@ export default class AppMpicker extends Vue {
});
}
if (this.name && this.activeData) {
let value = selects.length > 0 ? JSON.stringify(selects) : '';
let value = selects.length > 0 ? JSON.stringify(this.formatValue(selects)) : '';
this.$emit('formitemvaluechange', { name: this.name, value: value });
}
})
}
}
/**
* 解析值,把srfkey和srfmajortext解析成实体属性名
*
* @param {any[]} value 需要转换的数组
* @memberof AppMpicker
*/
public parseValue(value: any[]){
let result = [];
if(this.deKeyField !== "srfkey" || this.deMajorField !== "srfmajortext"){
value.forEach((item: any) => {
result.push({[this.deMajorField]: item.srfmajortext, [this.deKeyField]: item.srfkey});
});
}else{
result = value;
}
return result;
}
/**
* 格式化值,把实体属性名格式化成srfkey和srfmajortext
*
* @param {any[]} value 需要转换的数组
* @memberof AppMpicker
*/
public formatValue(value: any[]){
let result = [];
if(this.deKeyField !== "srfkey" || this.deMajorField !== "srfmajortext"){
value.forEach((item: any) => {
result.push({srfmajortext : item[this.deMajorField], srfkey : item[this.deKeyField]});
});
}else{
result = value;
}
return result;
}
}
</script>
<style lang="less">
......
......@@ -26,94 +26,112 @@ const tinymceCode:any = tinymce;
@Component({})
export default class AppRichTextEditor extends Vue {
/**
* 传入值
*
* @type {*}
* @memberof AppRichTextEditor
*/
@Prop() value?: any;
/**
* 监听value值
*/
@Watch('value', { immediate: true, deep: true })
oncurrentContent(newval: any, val: any) {
if (newval) {
if(this.editor){
tinymceCode.remove('#' + this.id);
}
this.init(newval);
}
}
/**
* 输入name
*
* @type {string}
* @memberof AppRichTextEditor
*/
@Prop() name?: string;
/**
* 输入高度
*
* @type {*}
* @memberof AppRichTextEditor
*/
@Prop() height?: any;
/**
* 是否禁用
*
* @type {boolean}
* @memberof AppRichTextEditor
*/
@Prop() disabled?: any;
/**
* 当前语言,默认中文
*/
public langu: any = localStorage.getItem('local') ? localStorage.getItem('local') : 'zh_CN' ;
@Prop() disabled?: boolean;
/**
* 监听语言变化
*/
@Watch('$i18n.locale')
onLocaleChange(newval: any, val: any) {
console.log("语言变更"+newval)
this.langu = newval;
if(this.editor){
tinymceCode.remove('#' + this.id);
}
this.init('');
}
/**
* 语言映射文件
* 表单状态
*
* @type {Subject<any>}
* @memberof AppRichTextEditor
*/
public languMap:any = {
'zh-CN': 'zh_CN',
'en-US': 'en_US',
};
@Prop() public formState?: Subject<any>;
/**
* 上传文件路径
*
* @type {string}
* @memberof AppRichTextEditor
*/
public uploadUrl = Environment.BaseUrl + Environment.UploadFile;
/**
* 下载路径
*
* @type {string}
* @memberof AppRichTextEditor
*/
public downloadUrl = Environment.BaseUrl + Environment.ExportFile;
/**
* 当前富文本
*
* @type {*}
* @memberof AppRichTextEditor
*/
public editor: any = null;
/**
* 当前富文本id
*
* @type {string}
* @memberof AppRichTextEditor
*/
id: string = this.$util.createUUID();
public id: string = this.$util.createUUID();
/**
* 表单状态
*
* @type {Subject<any>}
* 当前语言,默认中文
*
* @type {*}
* @memberof AppRichTextEditor
*/
@Prop() public formState?: Subject<any>;
public langu: any = localStorage.getItem('local') ? localStorage.getItem('local') : 'zh_CN' ;
/**
* 语言映射文件
*
* @type {*}
* @memberof AppRichTextEditor
*/
public languMap:any = {
'zh-CN': 'zh_CN',
'en-US': 'en_US',
};
/**
* 是否处于激活状态
*
* @type {boolean}
* @memberof AppRichTextEditor
*/
public isActived:boolean = true;
/**
* 是否需要初始化
*
* @type {boolean}
* @memberof AppRichTextEditor
*/
public isNeedInit:boolean = false;
/**
* 生命周期
......@@ -125,40 +143,92 @@ export default class AppRichTextEditor extends Vue {
this.formState.subscribe(({ type, data }) => {
if (Object.is('load', type)) {
if (!this.value) {
if(this.editor){
tinymceCode.remove('#' + this.id);
}
this.init(this.value);
this.init();
}
}
});
}
}
/**
* 生命周期:激活
*
* @memberof AppRichTextEditor
*/
public activated(){
this.isActived = true;
if(this.isNeedInit){
this.init();
this.isNeedInit = false;
}
}
/**
* 初始化富文本
* 生命周期:缓存
*
* @memberof AppRichTextEditor
*/
public deactivated(){
this.isActived = false;
}
/**
* 生命周期:初始化富文本
*
* @memberof AppRichTextEditor
*/
public mounted() {
this.init('');
this.init();
}
/**
* 销毁富文本
* 生命周期:销毁富文本
*
* @memberof AppRichTextEditor
*/
public destoryed(){
tinymceCode.remove(this.editor);
if(this.editor){
tinymceCode.remove('#' + this.id);
}
}
/**
* 监听value值
*
* @memberof AppRichTextEditor
*/
@Watch('value', { immediate: true, deep: true })
oncurrentContent(newval: any, val: any) {
if (newval) {
this.init();
}
}
/**
* 监听语言变化
*/
@Watch('$i18n.locale')
onLocaleChange(newval: any, val: any) {
this.langu = newval;
if(this.isActived){
this.init();
}else{
this.isNeedInit = true;
}
}
/**
* 初始化富文本
* @param val
*
* @memberof AppRichTextEditor
*/
public init(val: any) {
public init() {
this.destoryed();
let richtexteditor = this;
tinymceCode.init({
selector: '#' + this.id,
selector: '#' + richtexteditor.id,
width: 'calc( 100% - 2px )',
height: this.height,
height: richtexteditor.height,
min_height: 400,
branding: false,
plugins: ['link', 'paste', 'table', 'image', 'codesample', 'code', 'fullscreen', 'preview'],
......@@ -177,13 +247,13 @@ export default class AppRichTextEditor extends Vue {
paste_data_images: true,
codesample_content_css: 'assets/tinymce/prism.css',
skin_url: './assets/tinymce/skins/lightgray',
language_url: './assets/tinymce/langs/' + this.languMap[this.langu] + '.js',
language:this.languMap[this.langu],
language_url: './assets/tinymce/langs/' + richtexteditor.languMap[richtexteditor.langu] + '.js',
language:richtexteditor.languMap[richtexteditor.langu],
setup: (editor: any) => {
this.editor = editor;
richtexteditor.editor = editor;
editor.on('blur', () => {
const content = editor.getContent();
this.$emit('change', content);
richtexteditor.$emit('change', content);
});
},
images_upload_handler: (bolbinfo: any, success: any, failure: any) => {
......@@ -202,13 +272,13 @@ export default class AppRichTextEditor extends Vue {
});
},
init_instance_callback: (editor: any) => {
this.editor = editor;
let value = (this.value && this.value.length > 0) ? this.value : '';
if (this.editor) {
this.editor.setContent(value);
richtexteditor.editor = editor;
let value = (richtexteditor.value && richtexteditor.value.length > 0) ? richtexteditor.value : '';
if (richtexteditor.editor) {
richtexteditor.editor.setContent(value);
}
if (this.disabled) {
this.editor.setMode('readonly');
if (richtexteditor.disabled) {
richtexteditor.editor.setMode('readonly');
}
}
});
......@@ -216,8 +286,10 @@ export default class AppRichTextEditor extends Vue {
/**
* 上传文件
* @param url
* @param formData
*
* @param url 路径
* @param formData 文件对象
* @memberof AppRichTextEditor
*/
public uploadFile(url: string, formData: any) {
let _this = this;
......
......@@ -108,6 +108,11 @@ export default class AppSpan extends Vue {
public load(){
if(!this.value || this.tag){
return; //代码表走codelist组件
}else if(this.editorType === "ADDRESSPICKUP"){
JSON.parse(this.value).forEach((item:any,index:number) => {
this.text += index === 0 ? item.srfmajortext : ","+item.srfmajortext;
});
}else{
this.text = this.value;
}
......
......@@ -396,17 +396,17 @@ export default class IBZDepartmentEditViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......@@ -814,7 +814,7 @@ export default class IBZDepartmentEditViewBase extends Vue {
if (args.length > 0) {
Object.assign(data, { srfsourcekey: args[0].srfkey })
}
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }],params, $event, xData);
} else if (xData && xData.copy instanceof Function) {
const data2: any = {};
if (args.length > 0) {
......
......@@ -497,17 +497,17 @@ export default class IBZDepartmentGridViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......@@ -1189,7 +1189,7 @@ export default class IBZDepartmentGridViewBase extends Vue {
const _this: any = this;
if (_this.newdata && _this.newdata instanceof Function) {
const data: any = {};
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }], params, $event, xData);
} else {
_this.$Notice.error({ title: '错误', desc: 'newdata 视图处理逻辑不存在,请添加!' });
}
......@@ -1267,7 +1267,7 @@ export default class IBZDepartmentGridViewBase extends Vue {
if (args.length > 0) {
Object.assign(data, { srfsourcekey: args[0].srfkey })
}
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }],params, $event, xData);
} else if (xData && xData.copy instanceof Function) {
const data2: any = {};
if (args.length > 0) {
......
......@@ -356,17 +356,17 @@ export default class IBZDepartmentPickupGridViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......
<template>
<div class="view-container depickupview ibzdepartment-pickup-view">
<app-studioaction :viewTitle="$t(model.srfTitle)" viewName="ibzdepartmentpickupview"></app-studioaction>
<card class='view-card' :dis-hover="true" :padding="0" :bordered="false">
<card class='view-card view-no-caption' :dis-hover="true" :padding="0" :bordered="false">
<div class="content-container pickup-view">
<view_pickupviewpanel
:viewState="viewState"
......@@ -350,17 +350,17 @@ export default class IBZDepartmentPickupViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......
......@@ -376,17 +376,17 @@ export default class IBZEmployeeChangePwdViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......
......@@ -396,17 +396,17 @@ export default class IBZEmployeeEditViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......@@ -814,7 +814,7 @@ export default class IBZEmployeeEditViewBase extends Vue {
if (args.length > 0) {
Object.assign(data, { srfsourcekey: args[0].srfkey })
}
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }],params, $event, xData);
} else if (xData && xData.copy instanceof Function) {
const data2: any = {};
if (args.length > 0) {
......
......@@ -508,17 +508,17 @@ export default class IBZEmployeeGridViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......@@ -1230,7 +1230,7 @@ export default class IBZEmployeeGridViewBase extends Vue {
const _this: any = this;
if (_this.newdata && _this.newdata instanceof Function) {
const data: any = {};
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }], params, $event, xData);
} else {
_this.$Notice.error({ title: '错误', desc: 'newdata 视图处理逻辑不存在,请添加!' });
}
......@@ -1308,7 +1308,7 @@ export default class IBZEmployeeGridViewBase extends Vue {
if (args.length > 0) {
Object.assign(data, { srfsourcekey: args[0].srfkey })
}
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }],params, $event, xData);
} else if (xData && xData.copy instanceof Function) {
const data2: any = {};
if (args.length > 0) {
......
......@@ -396,17 +396,17 @@ export default class IBZOrganizationEditViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......@@ -814,7 +814,7 @@ export default class IBZOrganizationEditViewBase extends Vue {
if (args.length > 0) {
Object.assign(data, { srfsourcekey: args[0].srfkey })
}
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }],params, $event, xData);
} else if (xData && xData.copy instanceof Function) {
const data2: any = {};
if (args.length > 0) {
......
......@@ -497,17 +497,17 @@ export default class IBZOrganizationGridViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......@@ -1179,7 +1179,7 @@ export default class IBZOrganizationGridViewBase extends Vue {
const _this: any = this;
if (_this.newdata && _this.newdata instanceof Function) {
const data: any = {};
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }], params, $event, xData);
} else {
_this.$Notice.error({ title: '错误', desc: 'newdata 视图处理逻辑不存在,请添加!' });
}
......@@ -1257,7 +1257,7 @@ export default class IBZOrganizationGridViewBase extends Vue {
if (args.length > 0) {
Object.assign(data, { srfsourcekey: args[0].srfkey })
}
_this.newdata([{ ...data }], params, $event, xData);
_this.newdata([{ ...data }],[{ ...data }],params, $event, xData);
} else if (xData && xData.copy instanceof Function) {
const data2: any = {};
if (args.length > 0) {
......
......@@ -358,17 +358,17 @@ export default class IBZOrganizationOptionViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......
......@@ -356,17 +356,17 @@ export default class IBZOrganizationPickupGridViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......
<template>
<div class="view-container depickupview ibzorganization-pickup-view">
<app-studioaction :viewTitle="$t(model.srfTitle)" viewName="ibzorganizationpickupview"></app-studioaction>
<card class='view-card' :dis-hover="true" :padding="0" :bordered="false">
<card class='view-card view-no-caption' :dis-hover="true" :padding="0" :bordered="false">
<div class="content-container pickup-view">
<view_pickupviewpanel
:viewState="viewState"
......@@ -350,17 +350,17 @@ export default class IBZOrganizationPickupViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......
......@@ -333,17 +333,17 @@ export default class OUIndexViewBase extends Vue {
}
}else{
// 先从导航上下文取数,没有再从导航参数(URL)取数,如果导航上下文和导航参数都没有则为null
if(this.context[curNavData.value]){
if(this.context[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.context[curNavData.value],
value: this.context[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
});
}else{
if(this.viewparams[curNavData.value]){
if(this.viewparams[(curNavData.value).toLowerCase()]){
Object.defineProperty(tempData, item, {
value: this.viewparams[curNavData.value],
value: this.viewparams[(curNavData.value).toLowerCase()],
writable : true,
enumerable : true,
configurable : true
......
......@@ -587,12 +587,12 @@ export default class EntityService {
* createBatch接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {*} [data]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof EntityService
*/
public async createBatch(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
public async createBatch(context: any = {},data: any, isloading?: boolean): Promise<any> {
return Http.getInstance().post(`/${this.APPDENAME}/batch`,data,isloading);
}
......@@ -600,12 +600,12 @@ export default class EntityService {
* updateBatch接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {*} [data]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof EntityService
*/
public async updateBatch(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
public async updateBatch(context: any = {},data: any, isloading?: boolean): Promise<any> {
return Http.getInstance().put(`/${this.APPDENAME}/batch`,data,isloading);
}
......@@ -613,12 +613,12 @@ export default class EntityService {
* removeBatch接口方法
*
* @param {*} [context={}]
* @param {*} [data={}]
* @param {*} [data]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof EntityService
*/
public async removeBatch(context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
public async removeBatch(context: any = {},data: any, isloading?: boolean): Promise<any> {
return Http.getInstance().delete(`/${this.APPDENAME}/batch`,isloading,data);
}
......
......@@ -78,7 +78,7 @@ export class Http {
axios({
method: 'post',
url: url,
data: { ...params },
data: params,
headers: { 'Content-Type': 'application/json;charset=UTF-8', 'Accept': 'application/json' },
// transformResponse: [(data: any) => {
// let _data: any = null;
......
......@@ -2,7 +2,7 @@
<i-form :model="this.data" class='app-search-form' ref='searchform' style="">
<input style="display:none;"/>
<row>
<i-col span="20">
<i-col span="20" class="form-content">
<row>
<i-col v-show="detailsModel.n_deptcode_like.visible" :style="{}" :sm="{ span: 12, offset: 0 }" :md="{ span: 12, offset: 0 }" :lg="{ span: 12, offset: 0 }" :xl="{ span: 8, offset: 0 }">
<app-form-item name='n_deptcode_like' :itemRules="this.rules.n_deptcode_like" class='' :caption="$t('entities.ibzdepartment.default_searchform.details.n_deptcode_like')" uiStyle="DEFAULT" :labelWidth="130" :isShowCaption="true" :error="detailsModel.n_deptcode_like.error" :isEmptyCaption="false" labelPos="LEFT">
......@@ -24,7 +24,7 @@
</i-col>
</row>
</i-col>
<i-col span="4">
<i-col span="4" class="search-button">
<row v-show="Object.keys(data).length>0">
<i-button class='search_reset' size="default" type="primary" @click="onSearch">{{$t('app.searchButton.search')}}</i-button>
<i-button class='search_reset' size="default" @click="onReset">{{this.$t('app.searchButton.reset')}}</i-button>
......
......@@ -13,6 +13,9 @@
margin-right: 12px;
margin-bottom: 8px;
}
.search-button{
text-align: right;
}
}
.app-search-form-flex {
height: 100%;
......
......@@ -1830,7 +1830,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public createDefault(){
if (this.data.hasOwnProperty('showorder')) {
this.data['showorder'] = '1';
this.data['showorder'] = 1;
}
}
......
......@@ -533,7 +533,7 @@ export default class MainBase extends Vue implements ControlInterface {
* @type {number}
* @memberof AppIndex
*/
protected checkboxColWidth: number = 80;
protected checkboxColWidth: number = 50;
/**
* 是否允许拖动列宽
......
......@@ -2,7 +2,7 @@
<i-form :model="this.data" class='app-search-form' ref='searchform' style="">
<input style="display:none;"/>
<row>
<i-col span="20">
<i-col span="20" class="form-content">
<row>
<i-col v-show="detailsModel.n_usercode_like.visible" :style="{}" :sm="{ span: 12, offset: 0 }" :md="{ span: 12, offset: 0 }" :lg="{ span: 12, offset: 0 }" :xl="{ span: 8, offset: 0 }">
<app-form-item name='n_usercode_like' :itemRules="this.rules.n_usercode_like" class='' :caption="$t('entities.ibzemployee.default_searchform.details.n_usercode_like')" uiStyle="DEFAULT" :labelWidth="130" :isShowCaption="true" :error="detailsModel.n_usercode_like.error" :isEmptyCaption="false" labelPos="LEFT">
......@@ -24,7 +24,7 @@
</i-col>
</row>
</i-col>
<i-col span="4">
<i-col span="4" class="search-button">
<row v-show="Object.keys(data).length>0">
<i-button class='search_reset' size="default" type="primary" @click="onSearch">{{$t('app.searchButton.search')}}</i-button>
<i-button class='search_reset' size="default" @click="onReset">{{this.$t('app.searchButton.reset')}}</i-button>
......
......@@ -13,6 +13,9 @@
margin-right: 12px;
margin-bottom: 8px;
}
.search-button{
text-align: right;
}
}
.app-search-form-flex {
height: 100%;
......
......@@ -2169,7 +2169,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public createDefault(){
if (this.data.hasOwnProperty('showorder')) {
this.data['showorder'] = '1';
this.data['showorder'] = 1;
}
}
......
......@@ -549,7 +549,7 @@ export default class MainBase extends Vue implements ControlInterface {
* @type {number}
* @memberof AppIndex
*/
protected checkboxColWidth: number = 80;
protected checkboxColWidth: number = 50;
/**
* 是否允许拖动列宽
......
......@@ -2,7 +2,7 @@
<i-form :model="this.data" class='app-search-form' ref='searchform' style="">
<input style="display:none;"/>
<row>
<i-col span="20">
<i-col span="20" class="form-content">
<row>
<i-col v-show="detailsModel.n_orgid_like.visible" :style="{}" :sm="{ span: 12, offset: 0 }" :md="{ span: 12, offset: 0 }" :lg="{ span: 12, offset: 0 }" :xl="{ span: 8, offset: 0 }">
<app-form-item name='n_orgid_like' :itemRules="this.rules.n_orgid_like" class='' :caption="$t('entities.ibzorganization.default_searchform.details.n_orgid_like')" uiStyle="DEFAULT" :labelWidth="130" :isShowCaption="true" :error="detailsModel.n_orgid_like.error" :isEmptyCaption="false" labelPos="LEFT">
......@@ -30,7 +30,7 @@
</i-col>
</row>
</i-col>
<i-col span="4">
<i-col span="4" class="search-button">
<row v-show="Object.keys(data).length>0">
<i-button class='search_reset' size="default" type="primary" @click="onSearch">{{$t('app.searchButton.search')}}</i-button>
<i-button class='search_reset' size="default" @click="onReset">{{this.$t('app.searchButton.reset')}}</i-button>
......
......@@ -13,6 +13,9 @@
margin-right: 12px;
margin-bottom: 8px;
}
.search-button{
text-align: right;
}
}
.app-search-form-flex {
height: 100%;
......
......@@ -1733,7 +1733,7 @@ export default class MainBase extends Vue implements ControlInterface {
*/
public createDefault(){
if (this.data.hasOwnProperty('showorder')) {
this.data['showorder'] = '1';
this.data['showorder'] = 1;
}
}
......
......@@ -526,7 +526,7 @@ export default class MainBase extends Vue implements ControlInterface {
* @type {number}
* @memberof AppIndex
*/
protected checkboxColWidth: number = 80;
protected checkboxColWidth: number = 50;
/**
* 是否允许拖动列宽
......
......@@ -32,17 +32,11 @@
<hudson.tasks.Shell>
<command>
BUILD_ID=DONTKILLME
echo "registry.cn-shanghai.aliyuncs.com/ibizsys"
source /etc/profile
rm -rf ibzou
git clone -b master $para2 ibzou/
export NODE_OPTIONS=--max-old-space-size=4096
cd ibzou/
mvn clean package -Pweb
cd ibzou-app/ibzou-app-web
mvn -Pweb docker:build
mvn -Pweb docker:push
docker -H $para1 stack deploy --compose-file=src/main/docker/ibzou-app-web.yaml ibzlab-rt --with-registry-auth
</command>
</hudson.tasks.Shell>
</builders>
......
......@@ -9,6 +9,6 @@ CMD echo "The application will start in ${IBZ_SLEEP}s..." && \
sleep ${IBZ_SLEEP} && \
java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /ibzou-app-web.jar
EXPOSE 30001
EXPOSE 8080
ADD ibzou-app-web.jar /ibzou-app-web.jar
......@@ -3,11 +3,9 @@ services:
ibzou-app-web:
image: registry.cn-shanghai.aliyuncs.com/ibizsys/ibzou-app-web:latest
ports:
- "30001:30001"
- "8080:8080"
networks:
- agent_network
environment:
SPRING_CLOUD_NACOS_DISCOVERY_IP: 172.16.180.237
deploy:
mode: replicated
replicas: 1
......
server:
port: 30001
\ No newline at end of file
port: 8080
\ No newline at end of file
server:
port: 30001
port: 8080
#zuul网关路由设置
zuul:
......
......@@ -65,6 +65,7 @@ public class IBZDepartment extends EntityMP implements Serializable {
/**
* 上级部门
*/
@DEField(name = "pdeptid")
@TableField(value = "pdeptid")
@JSONField(name = "parentdeptid")
@JsonProperty("parentdeptid")
......
......@@ -58,6 +58,7 @@ public class IBZOrganization extends EntityMP implements Serializable {
/**
* 上级单位
*/
@DEField(name = "porgid")
@TableField(value = "porgid")
@JSONField(name = "parentorgid")
@JsonProperty("parentorgid")
......
{
"unires":[
],
"predefineddatarange":[{"id":"ALL","name":"全部数据"},{"id":"CURORG","name":"当前单位"},{"id":"PORG","name":"上级单位"},{"id":"SORG","name":"下级单位"},{"id":"CURORGDEPT","name":"当前部门"},{"id":"PORGDEPT","name":"上级部门"},{"id":"SORGDEPT","name":"下级部门"}],
"entities":[
{
......@@ -26,4 +27,3 @@
]
}
......@@ -19,16 +19,6 @@
<artifactId>ibzou-core</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
</dependencies>
<properties>
......
......@@ -88,7 +88,10 @@ public class apiSecurityConfig extends WebSecurityConfigurerAdapter {
"/**/fonts/**",
"/**/js/**",
"/**/img/**",
"/"
"/",
"/webjars/**",
"/swagger-resources/**",
"/v2/**"
).permitAll()
// 服务中暂时只为重构用户身份,不进行身份认证
.anyRequest().permitAll()
......
......@@ -77,8 +77,8 @@ public class IBZOrganizationResource {
}
@PreAuthorize("hasPermission(#ibzorganization_id,'Update',{this.getEntity(),'Sql'})")
@ApiOperation(value = "UpdateBatch", tags = {"UpdateBatch" }, notes = "UpdateBatch")
@RequestMapping(method = RequestMethod.POST, value = "/ibzorganizations/updatebatch")
@ApiOperation(value = "UpdateBatch", tags = {"IBZOrganization" }, notes = "UpdateBatch")
@RequestMapping(method = RequestMethod.PUT, value = "/ibzorganizations/batch")
public ResponseEntity<Boolean> updateBatch(@RequestBody List<IBZOrganizationDTO> ibzorganizationdtos) {
ibzorganizationService.updateBatch(ibzorganizationMapping.toDomain(ibzorganizationdtos));
return ResponseEntity.status(HttpStatus.OK).body(true);
......@@ -99,8 +99,8 @@ public class IBZOrganizationResource {
}
@PreAuthorize("hasPermission('','Create',{this.getEntity(),'Sql'})")
@ApiOperation(value = "createBatch", tags = {"createBatch" }, notes = "createBatch")
@RequestMapping(method = RequestMethod.POST, value = "/ibzorganizations/createbatch")
@ApiOperation(value = "createBatch", tags = {"IBZOrganization" }, notes = "createBatch")
@RequestMapping(method = RequestMethod.POST, value = "/ibzorganizations/batch")
public ResponseEntity<Boolean> createBatch(@RequestBody List<IBZOrganizationDTO> ibzorganizationdtos) {
ibzorganizationService.createBatch(ibzorganizationMapping.toDomain(ibzorganizationdtos));
return ResponseEntity.status(HttpStatus.OK).body(true);
......@@ -115,7 +115,7 @@ public class IBZOrganizationResource {
return ResponseEntity.status(HttpStatus.OK).body(ibzorganizationService.save(ibzorganizationMapping.toDomain(ibzorganizationdto)));
}
@ApiOperation(value = "SaveBatch", tags = {"SaveBatch" }, notes = "SaveBatch")
@ApiOperation(value = "SaveBatch", tags = {"IBZOrganization" }, notes = "SaveBatch")
@RequestMapping(method = RequestMethod.POST, value = "/ibzorganizations/savebatch")
public ResponseEntity<Boolean> saveBatch(@RequestBody List<IBZOrganizationDTO> ibzorganizationdtos) {
ibzorganizationService.saveBatch(ibzorganizationMapping.toDomain(ibzorganizationdtos));
......@@ -133,8 +133,8 @@ public class IBZOrganizationResource {
return ResponseEntity.status(HttpStatus.OK).body(ibzorganizationService.remove(ibzorganization_id));
}
@ApiOperation(value = "RemoveBatch", tags = {"RemoveBatch" }, notes = "RemoveBatch")
@RequestMapping(method = RequestMethod.POST, value = "/ibzorganizations/removebatch")
@ApiOperation(value = "RemoveBatch", tags = {"IBZOrganization" }, notes = "RemoveBatch")
@RequestMapping(method = RequestMethod.DELETE, value = "/ibzorganizations/batch")
public ResponseEntity<Boolean> removeBatch(@RequestBody List<String> ids) {
ibzorganizationService.removeBatch(ids);
return ResponseEntity.status(HttpStatus.OK).body(true);
......
package cn.ibizlab.swagger;
import cn.ibizlab.util.security.SpringContextHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static com.google.common.base.Predicates.or;
import static springfox.documentation.builders.PathSelectors.regex;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.plugin.core.PluginRegistrySupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.readers.operation.OperationParameterReader;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket docket() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.groupName("DEFAULT")
.pathMapping("/")
.apiInfo(
new ApiInfoBuilder()
.title("DEFAULT")
.build()
)
.select()
.apis(RequestHandlerSelectors.basePackage("cn.ibizlab"))
//.paths(or(regex("/rest/.*")))
.paths(PathSelectors.any())
.build()
;
removeDefaultPlugin();
return docket ;
}
@Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("microservice")
.pathMapping("/")
.apiInfo(
new ApiInfoBuilder()
.title("microservice")
.version("1")
.build()
)
.select()
.apis(RequestHandlerSelectors.basePackage("cn.ibizlab.api"))
//.paths(or(regex("/rest/api/.*")))
.paths(PathSelectors.any())
.build()
;
}
private void removeDefaultPlugin() {
// 从spring容器中获取swagger插件注册表
PluginRegistry<OperationBuilderPlugin, DocumentationType> pluginRegistry = SpringContextHolder.getBean("operationBuilderPluginRegistry");
// 插件集合
List<OperationBuilderPlugin> plugins = pluginRegistry.getPlugins();
// 从spring容器中获取需要删除的插件
OperationParameterReader operationParameterReader = SpringContextHolder.getBean(OperationParameterReader.class);
if(operationParameterReader==null)
return ;
// 原plugins集合不能修改,创建新集合,通过反射替换
if (pluginRegistry.contains(operationParameterReader)) {
List<OperationBuilderPlugin> plugins_new = new ArrayList<OperationBuilderPlugin>(plugins);
plugins_new.remove(operationParameterReader);
try {
Field field = PluginRegistrySupport.class.getDeclaredField("plugins");
field.setAccessible(true);
field.set(pluginRegistry, plugins_new);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
......@@ -75,5 +75,15 @@
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
</dependencies>
</project>
......@@ -11,6 +11,11 @@ import java.lang.annotation.Target;
@Target({ ElementType.FIELD})
public @interface DEField
{
/**
* 属性名称
* @return
*/
String name() default "";
/**
* 是否为数据主键
* @return
......
package cn.ibizlab.util.cache;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import cn.ibizlab.util.cache.cacheManager.CaffeineCacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;
/**
* Caffeine缓存配置类
*/
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnProperty("ibiz.enableCaffeineCache")
public class CaffeineCacheConfig {
@Autowired
private CacheProperties cacheProperties;
@Autowired
private CaffeineCacheManager caffeineCacheManager;
@Bean
@Primary
public CacheManager cacheManager() {
String specification = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(specification)) {
caffeineCacheManager.setCaffeineSpec(CaffeineSpec.parse(specification));
}
return caffeineCacheManager;
}
}
\ No newline at end of file
package cn.ibizlab.util.cache;
import com.alibaba.fastjson.parser.ParserConfig;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import cn.ibizlab.util.cache.cacheManager.LayeringCacheManager;
import cn.ibizlab.util.cache.redis.KryoRedisSerializer;
import cn.ibizlab.util.cache.redis.StringRedisSerializer;
import cn.ibizlab.util.enums.RedisChannelTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.util.StringUtils;
/**
* 缓存配置类
* 1级缓存为caffeine
* 2级缓存为redis
*/
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnProperty("ibiz.enableRedisCache")
public class RedisCacheConfig {
@Autowired
private RedisCacheWriter redisCacheWriter;
@Autowired
private RedisCacheConfiguration configuration;
@Autowired
LayeringCacheManager layeringCacheManager;
@Autowired
private CacheProperties cacheProperties;
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
return RedisCacheManager.create(connectionFactory);
}
@Bean
public RedisCacheWriter redisCacheWriter(RedisConnectionFactory connectionFactory){
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
return redisCacheWriter;
}
/**
* 重写Redis序列化方式,使用Json方式:
* 当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer,StringRedisTemplate默认使用的是StringRedisSerializer。
* Spring Data JPA为我们提供了下面的Serializer:
* GenericToStringSerializer、Jackson2JsonRedisSerializer、JacksonJsonRedisSerializer、JdkSerializationRedisSerializer、OxmSerializer、StringRedisSerializer。
* 在此我们将自己配置RedisTemplate并定义Serializer。
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
KryoRedisSerializer<Object> kryoRedisSerializer = new KryoRedisSerializer<>(Object.class);
redisTemplate.setValueSerializer(kryoRedisSerializer);// 设置值(value)的序列化采用KryoRedisSerializer。
redisTemplate.setHashValueSerializer(kryoRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());// 设置键(key)的序列化采用StringRedisSerializer。
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
@Primary
public CacheManager cacheManager() {
setCaffeineCacheConfig(layeringCacheManager);//Caffeine缓存设置
layeringCacheManager.setRedisCacheWriter(redisCacheWriter);
layeringCacheManager.setRedisConfiguration(configuration);
return layeringCacheManager;
}
private void setCaffeineCacheConfig(LayeringCacheManager layeringCacheManager) {
String specification = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(specification)) {
layeringCacheManager.setCaffeineSpec(CaffeineSpec.parse(specification));
}
}
/**
* 监听redis指定频道
* @param redisConnectionFactory
* @param messageListener
* @return
*/
@Bean
RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListener) {
final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());
container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());
return container;
}
}
\ No newline at end of file
package cn.ibizlab.util.cache.cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
/**
* 自定义的redis缓存
*/
public class CusRedisCache extends RedisCache {
public CusRedisCache(String name, RedisCacheWriter redisCacheWriter, RedisCacheConfiguration configuration) {
super(name, redisCacheWriter, configuration);
}
}
package cn.ibizlab.util.cache.cache;
import cn.ibizlab.util.cache.listener.RedisPublisher;
import cn.ibizlab.util.enums.RedisChannelTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.AbstractValueAdaptingCache;
import org.springframework.cache.support.NullValue;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.RedisOperations;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* 缓存分层类
* 1级缓存为caffeine
* 2级缓存为redis
*/
public class LayeringCache extends AbstractValueAdaptingCache {
Logger logger = LoggerFactory.getLogger(LayeringCache.class);
/**
* 缓存的名称
*/
private final String name;
/**
* redis缓存
*/
private RedisCache redisCache;
/**
* Caffeine缓存
*/
private final CaffeineCache caffeineCache;
/**
* redis消息发布
*/
RedisOperations<? extends Object, ? extends Object> redisOperations;
public LayeringCache(String name ,RedisOperations redisOperations, com.github.benmanes.caffeine.cache.Cache<Object, Object> caffeineCache,
RedisCacheWriter redisCacheWriter, RedisCacheConfiguration configuration) {
super(true);
this.name = name;
this.redisCache = new CusRedisCache(name, redisCacheWriter, configuration);
this.caffeineCache = new CaffeineCache(name, caffeineCache, true);
this.redisOperations=redisOperations;
}
@Override
public String getName() {
return this.name;
}
@Override
public Object getNativeCache() {
return this;
}
@Override
public ValueWrapper get(Object key) {
// 查询一级缓存
ValueWrapper wrapper = caffeineCache.get(key);
logger.debug("查询一级缓存 key:{},value:{}", key,wrapper);
if (wrapper == null) {
// 查询二级缓存
wrapper = redisCache.get(key);
caffeineCache.put(key, wrapper == null ? null : wrapper.get());
logger.debug("查询二级缓存,并将数据放到一级缓存。 key:{}", key);
}
return wrapper;
}
@Override
public <T> T get(Object key, Class<T> type) {
// 查询一级缓存
T value = caffeineCache.get(key, type);
logger.debug("查询一级缓存 key:{}", key);
if (value == null) {
// 查询二级缓存
value = redisCache.get(key, type);
caffeineCache.put(key, value);
logger.debug("查询二级缓存,并将数据放到一级缓存。 key:{}", key);
}
return value;
}
@SuppressWarnings("unchecked")
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
// 查询一级缓存,如果一级缓存没有值则调用getForSecondaryCache(k, valueLoader)查询二级缓存
T value = (T) caffeineCache.getNativeCache().get(key, k -> getSecondCache(k, valueLoader));
if(value==null) {
// 直接查询二级缓存
value = (T) getSecondCache(key, valueLoader);
}
if (value instanceof NullValue) {
return null;
}
return value;
}
@Override
public void put(Object key, Object value) {
caffeineCache.put(key, value);
redisCache.put(key, value);
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
caffeineCache.putIfAbsent(key, value);
return redisCache.putIfAbsent(key, value);
}
@Override
public void evict(Object key) {
redisCache.evict(key); //清除redis中的二级缓存
caffeineCache.evict(key);//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", name);
message.put("key", key);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
logger.debug(String.format("清除二级缓存数据[%s]", key));
}
@Override
public void clear() {
redisCache.clear(); //清除redis中的二级缓存
caffeineCache.clear();//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", name);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
}
@Override
protected Object lookup(Object key) {
Object value = caffeineCache.get(key);
logger.debug("查询一级缓存 key:{}", key);
if (value == null) {
value = redisCache.get(key);
logger.debug("查询二级缓存 key:{}", key);
}
return value;
}
/**
* 查询二级缓存
* @param key
* @param valueLoader
* @return
*/
private <T> Object getSecondCache(Object key, Callable<T> valueLoader) {
T value = redisCache.get(key, valueLoader);
logger.debug("查询二级缓存 key:{}", key);
return toStoreValue(value);
}
/**
* 获取caffeine缓存
* @return
*/
public CaffeineCache getFirstCache() {
return this.caffeineCache;
}
}
package cn.ibizlab.util.cache.cacheManager;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* Caffeine本地缓存
*/
@Data
@Component
@ConditionalOnProperty("ibiz.enableCaffeineCache")
public class CaffeineCacheManager implements CacheManager {
private static final int DEFAULT_EXPIRE_AFTER_WRITE = 1;
private static final int DEFAULT_INITIAL_CAPACITY = 5;
private static final int DEFAULT_MAXIMUM_SIZE = 1_000;
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
/**
* 缓存默认设置
*/
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(DEFAULT_EXPIRE_AFTER_WRITE, TimeUnit.HOURS)
.initialCapacity(DEFAULT_INITIAL_CAPACITY)
.maximumSize(DEFAULT_MAXIMUM_SIZE);
/**
* 获取缓存对象
* @param name
* @return
*/
@Override
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
cache = createCache(name);
this.cacheMap.put(name, cache);
}
}
}
return cache;
}
/**
* 获取缓存名
* @return
*/
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
/**
* 创建缓存
* @param name
* @return
*/
protected Cache createCache(String name) {
return new CaffeineCache(name, this.cacheBuilder.build(), true);
}
/**
* 缓存配置[缓存容量大小、时长等]
* @param caffeineSpec
*/
public void setCaffeineSpec(CaffeineSpec caffeineSpec) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineSpec);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
this.cacheBuilder = cacheBuilder;
refreshKnownCaches();
}
}
/**
* 使用该CacheManager的当前状态重新创建已知的缓存。
*/
private void refreshKnownCaches() {
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
entry.setValue(createCache(entry.getKey()));
}
}
}
package cn.ibizlab.util.cache.cacheManager;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import lombok.Data;
import cn.ibizlab.util.cache.cache.LayeringCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* 缓存分层类
* 1级缓存为caffeine
* 2级缓存为redis
*/
@Data
@Component
@ConditionalOnProperty("ibiz.enableRedisCache")
public class LayeringCacheManager implements CacheManager {
private static final int DEFAULT_EXPIRE_AFTER_WRITE = 1;
private static final int DEFAULT_INITIAL_CAPACITY = 5;
private static final int DEFAULT_MAXIMUM_SIZE = 1_000;
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
public RedisCacheWriter redisCacheWriter;
public RedisCacheConfiguration redisConfiguration;
@Autowired
public RedisTemplate<String, Object> redisTemplate;
/**
* 缓存默认设置
*/
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(DEFAULT_EXPIRE_AFTER_WRITE, TimeUnit.HOURS)
.initialCapacity(DEFAULT_INITIAL_CAPACITY)
.maximumSize(DEFAULT_MAXIMUM_SIZE);
/**
* 获取缓存对象
* @param name
* @return
*/
@Override
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
cache = createCache(name);
this.cacheMap.put(name, cache);
}
}
}
return cache;
}
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
protected Cache createCache(String name) {
return new LayeringCache(name,redisTemplate,this.cacheBuilder.build(),redisCacheWriter,redisConfiguration);
}
/**
* 使用该CacheManager的当前状态重新创建已知的缓存
*/
private void refreshKnownCaches() {
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
entry.setValue(createCache(entry.getKey()));
}
}
public void setCaffeineSpec(CaffeineSpec caffeineSpec) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineSpec);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
this.cacheBuilder = cacheBuilder;
refreshKnownCaches();
}
}
}
package cn.ibizlab.util.cache.listener;
import cn.ibizlab.util.cache.cache.LayeringCache;
import cn.ibizlab.util.enums.RedisChannelTopic;
import cn.ibizlab.util.cache.layering.LayeringCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
* redis消息的订阅者
*/
@Profile("prod")
@Component
@ConditionalOnProperty("ibiz.enableRedisCache")
public class RedisMessageListener extends MessageListenerAdapter {
private static final Logger logger = LoggerFactory.getLogger(RedisPublisher.class);
@Autowired
......@@ -38,7 +41,7 @@ public class RedisMessageListener extends MessageListenerAdapter {
map= (Map<String, Object>) result;
}
if(StringUtils.isEmpty(map)|| (!map.containsKey("cacheName"))|| (!map.containsKey("key"))){
logger.info("解析缓存数据失败,无法获取指定值!");
logger.debug("解析缓存数据失败,无法获取指定值!");
return ;
}
logger.debug("redis消息订阅者接收到频道【{}】发布的消息。消息内容:{}", channelTopic.getChannelTopicStr(), result.toString());
......
......@@ -10,6 +10,7 @@ import org.springframework.cglib.beans.BeanMap;
import org.springframework.data.annotation.Transient;
import org.springframework.util.AlternativeJdkIdGenerator;
import java.io.Serializable;
import org.springframework.util.StringUtils;
import java.util.*;
public class EntityBase implements Serializable {
......@@ -68,14 +69,11 @@ public class EntityBase implements Serializable {
public Object get(String field) {
field=field.toLowerCase();
Hashtable<String,String> keys=DEFieldCacheMap.getFieldKeys(this.getClass().getName());
if(keys.containsKey(field))
return getMap().get(keys.get(field));
else if(keys.containsKey(field.replace("_","")))
return getMap().get(keys.get(field.replace("_","")));
String fieldRealName=DEFieldCacheMap.getFieldRealName(this.getClass(),field);
if(!StringUtils.isEmpty(fieldRealName))
return getMap().get(fieldRealName);
else
return this.extensionparams.get(field);
return this.extensionparams.get(field.toLowerCase());
}
......@@ -87,13 +85,15 @@ public class EntityBase implements Serializable {
@JsonAnySetter
public void set(String field, Object value) {
field=field.toLowerCase();
Hashtable<String,String> keys=DEFieldCacheMap.getFieldKeys(this.getClass().getName());
if(keys.containsKey(field))
getMap().put(keys.get(field),value);
else if(keys.containsKey(field.replace("_","")))
getMap().put(keys.get(field.replace("_","")),value);
String fieldRealName=DEFieldCacheMap.getFieldRealName(this.getClass(),field);
if(!StringUtils.isEmpty(fieldRealName)) {
if (value == null)
getMap().put(fieldRealName, null);
else
getMap().put(fieldRealName, DEFieldCacheMap.fieldValueOf(this.getClass(), fieldRealName, value));
}
else
this.extensionparams.put(field,value);
this.extensionparams.put(field.toLowerCase(),value);
}
}
\ No newline at end of file
package cn.ibizlab.util.filter;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
......@@ -9,6 +10,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
......@@ -48,13 +51,15 @@ public class QueryWrapperContext<T> extends SearchContextBase implements ISearch
if(ObjectUtils.isEmpty(it_sort))
return page;
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
Class<T> type = (Class<T>)parameterizedType.getActualTypeArguments()[0];
while (it_sort.hasNext()) {
Sort.Order sort_order = it_sort.next();
if(sort_order.getDirection()== Sort.Direction.ASC){
asc_fieldList.add(sort_order.getProperty());
asc_fieldList.add(DEFieldCacheMap.getFieldColumnName(type,sort_order.getProperty()));
}
else if(sort_order.getDirection()== Sort.Direction.DESC){
desc_fieldList.add(sort_order.getProperty());
desc_fieldList.add(DEFieldCacheMap.getFieldColumnName(type,sort_order.getProperty()));
}
}
......
package cn.ibizlab.util.helper;
import cn.ibizlab.util.annotation.DEField;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
/**
......@@ -17,103 +20,186 @@ public class DEFieldCacheMap {
private static Hashtable<String, Hashtable<String,String>> cacheKey = new Hashtable<>();
private static Hashtable<String, Hashtable<String,DEField>> cacheDEField = new Hashtable<>();
private static Hashtable<String, String> cacheDEKeyField = new Hashtable<>();
private static Object objLock1=new Object();
private static Object objLock2=new Object();
private static Object objLock3=new Object();
/**
* 将实体对象中的属性存入缓存中
* @param className
* @param
* @return
*/
public static Hashtable<String,Field> getFieldMap(String className) {
public static <T> Hashtable<String,Field> getFieldMap(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheMap.containsKey(className))
return cacheMap.get(className);
synchronized (objLock1) {
if(cacheMap.containsKey(className))
return cacheMap.get(className);
Class clazz = null;
try {
clazz = Class.forName(className);
}
catch (Exception ex) {
cacheMap.put(className, new Hashtable<String,Field>());
return cacheMap.get(className);
}
Hashtable<String,Field> result = cacheMap.get(className);
if (result == null) {
result=new Hashtable<String,Field>();
Field[] fields=clazz.getDeclaredFields();
for(Field field:fields){
result.put(field.getName(),field);
Hashtable<String,Field> result = new Hashtable<String,Field>();
List<Field> list=new ArrayList<Field>();
Hashtable<String,String> keys=new Hashtable<String,String>();
Hashtable<String,DEField> defields=new Hashtable<>();
Hashtable<String,String> dekeyfields=new Hashtable<>();
Field[] fields=clazz.getDeclaredFields();
for(Field field:fields){
result.put(field.getName(),field);
list.add(field);
keys.put(field.getName().toLowerCase(),field.getName());
DEField deField=field.getAnnotation(DEField.class);
if(!ObjectUtils.isEmpty(deField)) {
defields.put(field.getName(),deField);
if(deField.isKeyField())
cacheDEKeyField.put(className,field.getName());
}
cacheMap.put(className, result);
}
cacheMap.put(className, result);
cacheList.put(className,list);
cacheKey.put(className,keys);
cacheDEField.put(className,defields);
return result;
}
}
public static Hashtable<String,Field> getFieldMap(String className) {
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheMap.containsKey(className))
return cacheMap.get(className);
Class clazz = null;
try {
clazz = Class.forName(className);
return getFieldMap(clazz);
}
catch (Exception ex) {
cacheMap.put(className, new Hashtable<String,Field>());
return cacheMap.get(className);
}
}
/**
* 从缓存中查询实体对象属性列表
* @param className
* 从缓存中查询实体对象属性集合
* @param
* @return
*/
public static List<Field> getFields(String className) {
public static <T> Hashtable<String,DEField> getDEFields(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheDEField.containsKey(className))
return cacheDEField.get(className);
else{
DEFieldCacheMap.getFieldMap(clazz);
return cacheDEField.get(className);
}
}
/**
* 从缓存中查询实体对象主键
* @param
* @return
*/
public static <T> String getDEKeyField(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheDEKeyField.containsKey(className))
return cacheDEKeyField.get(className);
else{
DEFieldCacheMap.getFieldMap(clazz);
return cacheDEKeyField.get(className);
}
}
/**
* 从缓存中查询实体对象属性列表
* @param
* @return
*/
public static <T> List<Field> getFields(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheList.containsKey(className))
return cacheList.get(className);
else{
DEFieldCacheMap.getFieldMap(clazz);
return cacheList.get(className);
}
}
synchronized (objLock2) {
if (cacheList.containsKey(className))
return cacheList.get(className);
Hashtable<String,Field> fieldmap=DEFieldCacheMap.getFieldMap(className);
Iterator it = fieldmap.keySet().iterator();
List<Field> list=new ArrayList<Field>();
while(it.hasNext()) {
Object key = it.next();
if(fieldmap.get(key.toString())!=null)
list.add(fieldmap.get(key.toString()));
}
cacheList.put(className,list);
return list;
public static List<Field> getFields(String className) {
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheList.containsKey(className))
return cacheList.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheList.get(className);
}
}
/**
* 从缓存中查询实体对象属性列表
* @param className
* @param
* @return
*/
public static Hashtable<String,String> getFieldKeys(String className) {
public static <T> Hashtable<String,String> getFieldKeys(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheKey.containsKey(className))
return cacheKey.get(className);
else{
DEFieldCacheMap.getFieldMap(clazz);
return cacheKey.get(className);
}
}
synchronized (objLock3) {
if (cacheKey.containsKey(className))
return cacheKey.get(className);
Hashtable<String,Field> fieldmap=DEFieldCacheMap.getFieldMap(className);
Iterator it = fieldmap.keySet().iterator();
Hashtable<String,String> list=new Hashtable<String,String>();
while(it.hasNext()) {
Object key = it.next();
list.put(key.toString().toLowerCase(),key.toString());
}
cacheKey.put(className,list);
return list;
public static <T> String getFieldRealName(Class<T> clazz,String fieldname) {
fieldname=fieldname.toLowerCase();
Hashtable<String,String> keys=DEFieldCacheMap.getFieldKeys(clazz);
if(keys.containsKey(fieldname))
return keys.get(fieldname);
else if(keys.containsKey(fieldname.replace("_","")))
return keys.get(fieldname.replace("_",""));
else
return "";
}
public static <T> Field getField(Class<T> clazz,String fieldname) {
String fieldRealName=DEFieldCacheMap.getFieldRealName(clazz,fieldname);
if(!StringUtils.isEmpty(fieldRealName))
return DEFieldCacheMap.getFieldMap(clazz).get(fieldRealName);
else
return null;
}
public static <T> String getFieldColumnName(Class<T> clazz,String fieldname) {
Field field = DEFieldCacheMap.getField(clazz,fieldname);
if(field!=null) {
DEField deField=field.getAnnotation(DEField.class);
if(deField!=null&&deField.name()!=null)
return deField.name();
}
return fieldname;
}
public static <T> Object fieldValueOf(Class<T> clazz,String fieldname,Object fieldValue) {
if(fieldValue==null)
return null;
Object resultValue=fieldValue;
Field field = DEFieldCacheMap.getField(clazz,fieldname);
if(field!=null) {
Class<?> type=field.getType();
resultValue = DataObject.objectValueOf(type,fieldValue);
}
return resultValue;
}
}
\ No newline at end of file
......@@ -32,7 +32,7 @@ public class PermissionSyncJob implements ApplicationRunner {
@Value("${ibiz.enablePermissionValid:false}")
boolean enablePermissionValid; //是否开启权限校验
@Value("${ibiz.systemid:110B1A3E-4944-47C8-B4C4-EC15FB8982F3}")
@Value("${ibiz.systemid:2C40DFCD-0DF5-47BF-91A5-C45F810B0001}")
private String systemId;
@Override
......
package cn.ibizlab.util.rest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import cn.ibizlab.util.security.AuthenticationUser;
@RestController
@RequestMapping(value = "")
......@@ -19,7 +16,14 @@ public class AppController {
@RequestMapping(method = RequestMethod.GET, value = "/appdata")
public ResponseEntity<JSONObject> getAppData() {
JSONObject appData = new JSONObject() ;
JSONArray uniRes=new JSONArray();
JSONObject userPermission=AuthenticationUser.getAuthenticationUser().getPermissionList();
if(!ObjectUtils.isEmpty(userPermission)){
uniRes = userPermission.getJSONArray("unires");
}
appData.put("unires",uniRes);
return ResponseEntity.status(HttpStatus.OK).body(appData);
}
......
......@@ -74,7 +74,7 @@ public class AuthPermissionEvaluator implements PermissionEvaluator {
return false;
//获取当前用户权限列表
JSONObject userPermission= AuthenticationUser.getAuthenticationUser().getPermisionList();
JSONObject userPermission= AuthenticationUser.getAuthenticationUser().getPermissionList();
if(userPermission==null)
return false;
......@@ -88,7 +88,7 @@ public class AuthPermissionEvaluator implements PermissionEvaluator {
String entityName = entity.getClass().getSimpleName();
//获取实体行为权限信息
JSONObject permissionList=userPermission.getJSONObject("userPermissionList");
JSONObject permissionList=userPermission.getJSONObject("entities");
//检查是否有操作权限[create.update.delete.read]
if(!validDEActionHasPermission(permissionList,entityName,action)){
......@@ -106,7 +106,7 @@ public class AuthPermissionEvaluator implements PermissionEvaluator {
String entityName = entity.getClass().getSimpleName();
//获取数据集权限信息
JSONObject permissionList=userPermission.getJSONObject("userPermissionList");
JSONObject permissionList=userPermission.getJSONObject("entities");
if(StringUtils.isEmpty(entityName)|| StringUtils.isEmpty(dataSetName))
return false;
......@@ -145,8 +145,8 @@ public class AuthPermissionEvaluator implements PermissionEvaluator {
if (StringUtils.isEmpty(entity))
return false;
JSONObject userPermission= AuthenticationUser.getAuthenticationUser().getPermisionList();
JSONObject permissionList=userPermission.getJSONObject("userPermissionList");
JSONObject userPermission= AuthenticationUser.getAuthenticationUser().getPermissionList();
JSONObject permissionList=userPermission.getJSONObject("entities");
String entityName = entity.getClass().getSimpleName();
if(action.equalsIgnoreCase("create")){
......
......@@ -61,7 +61,7 @@ public class AuthenticationUser implements UserDetails
private Collection<GrantedAuthority> authorities;
@JsonIgnore
private int superuser;
private JSONObject permisionList;
private JSONObject permissionList;
private String orglevel;//单位级别
private String deptlevel;//部门级别
@JsonIgnore
......
package cn.ibizlab.util.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;
import feign.*;
import feign.codec.Decoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* 自定义feigen客户端配置
*
* @author
*/
@Service
public class RemoteService {
/**
* FeignClientFactoryBean
*/
@Autowired
protected FeignContext feignContext;
/**
* FeignClient 默认LoadBalancerFeignClient
*/
@Autowired
private Client feignClient;
private static final Map<String, Object> FEIGN_CLIENTS = new ConcurrentHashMap<>();
/**
* 定义远程通用接口
*/
public interface RemoteFeignClient {
@RequestMapping(method = RequestMethod.POST, value = "/{path}")
JSONObject post( @PathVariable("path") String path, @RequestHeader("Authorization") String token,@RequestBody Map param);
@RequestMapping(method = RequestMethod.GET, value = "/{path}")
JSONObject request( @PathVariable("path") String path, @RequestHeader("Authorization") String token,Map param);
@RequestMapping(method = RequestMethod.GET, value = "/{path}")
JSONObject get( @PathVariable("path") String path, @RequestHeader("Authorization") String token);
@RequestMapping(method = RequestMethod.PUT, value = "/{path}")
JSONObject put( @PathVariable("path") String path, @RequestHeader("Authorization") String token,@RequestBody Map param);
@RequestMapping(method = RequestMethod.DELETE, value = "/{path}")
JSONObject delete( @PathVariable("path") String path, @RequestHeader("Authorization") String token);
}
/**
* @param serverId
* @return
*/
public RemoteFeignClient getClient(String serverId) {
return this.create(RemoteFeignClient.class, serverId);
}
/**
* 设置编码解码器为FastJson
*
* @param clazz
* @param serviceId
* @param <T>
* @return
*/
private <T> T create(Class<T> clazz, String serviceId) {
Object object = FEIGN_CLIENTS.get(serviceId);
if (Objects.isNull(object)) {
object = Feign.builder()
//decoder指定对象解码方式
.decoder(this.feignDecoder())
.client(feignClient)
//options方法指定连接超时时长及响应超时时长
.options(new Request.Options(5000, 5000))
//retryer方法指定重试策略
//.retryer(new Retryer.Default(5000, 5000, 3))
.contract(feignContext.getInstance(serviceId, Contract.class))
//target方法绑定接口与服务端地址。返回类型为绑定的接口类型。
.target(clazz, "http://"+serviceId);
FEIGN_CLIENTS.put(serviceId, object);
}
return (T) object;
}
private Decoder feignDecoder() {
return new SpringDecoder(feignHttpMessageConverter());
}
/**
* 设置解码器为fastjson
*
* @return
*/
private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter());
return () -> httpMessageConverters;
}
private FastJsonHttpMessageConverter getFastJsonConverter() {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<>();
MediaType mediaTypeJson = MediaType.valueOf(MediaType.APPLICATION_JSON_UTF8_VALUE);
supportedMediaTypes.add(mediaTypeJson);
converter.setSupportedMediaTypes(supportedMediaTypes);
FastJsonConfig config = new FastJsonConfig();
config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer());
config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
converter.setFastJsonConfig(config);
return converter;
}
@Configuration
public class FeignTokenInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
HttpServletRequest request = getServletRequest();
if (null == request){
return;
}
template.header("uid", getHeaders(request));
}
private HttpServletRequest getServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
private String getHeaders(HttpServletRequest request){
return request.getHeader("uid");
}
}
}
\ No newline at end of file
package cn.ibizlab.util.web;
import cn.ibizlab.util.filter.SearchContextBase;
import com.fasterxml.classmate.ResolvedType;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.EnumTypeDeterminer;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spi.service.contexts.ParameterContext;
import springfox.documentation.spring.web.plugins.DocumentationPluginsManager;
import springfox.documentation.spring.web.readers.parameter.ExpansionContext;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Predicates.*;
import static com.google.common.collect.Lists.*;
import static springfox.documentation.schema.Collections.*;
import static springfox.documentation.schema.Maps.*;
import static springfox.documentation.schema.Types.*;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class IBZOperationParameterReader implements OperationBuilderPlugin {
private final ModelAttributeParameterExpander expander;
private final EnumTypeDeterminer enumTypeDeterminer;
@Autowired
private DocumentationPluginsManager pluginsManager;
@Autowired
public IBZOperationParameterReader(
ModelAttributeParameterExpander expander,
EnumTypeDeterminer enumTypeDeterminer) {
this.expander = expander;
this.enumTypeDeterminer = enumTypeDeterminer;
}
@Override
public void apply(OperationContext context) {
context.operationBuilder().parameters(context.getGlobalOperationParameters());
context.operationBuilder().parameters(readParameters(context));
}
@Override
public boolean supports(DocumentationType delimiter) {
return true;
}
private List<Parameter> readParameters(final OperationContext context) {
List<ResolvedMethodParameter> methodParameters = context.getParameters();
List<Parameter> parameters = newArrayList();
for (ResolvedMethodParameter methodParameter : methodParameters) {
ResolvedType alternate = context.alternateFor(methodParameter.getParameterType());
if (!shouldIgnore(methodParameter, alternate, context.getIgnorableParameterTypes())) {
ParameterContext parameterContext = new ParameterContext(methodParameter,
new ParameterBuilder(),
context.getDocumentationContext(),
context.getGenericsNamingStrategy(),
context);
if (shouldExpand(methodParameter, alternate)) {
parameters.addAll(
expander.expand(
new ExpansionContext("", alternate, context)));
} else {
parameters.add(pluginsManager.parameter(parameterContext));
}
}
}
return FluentIterable.from(parameters).filter(not(hiddenParams())).toList();
}
private Predicate<Parameter> hiddenParams() {
return new Predicate<Parameter>() {
@Override
public boolean apply(Parameter input) {
return input.isHidden();
}
};
}
private boolean shouldIgnore(
final ResolvedMethodParameter parameter,
ResolvedType resolvedParameterType,
final Set<Class> ignorableParamTypes) {
if (ignorableParamTypes.contains(resolvedParameterType.getErasedType())) {
return true;
}
return FluentIterable.from(ignorableParamTypes)
.filter(isAnnotation())
.filter(parameterIsAnnotatedWithIt(parameter)).size() > 0;
}
private Predicate<Class> parameterIsAnnotatedWithIt(final ResolvedMethodParameter parameter) {
return new Predicate<Class>() {
@Override
public boolean apply(Class input) {
return parameter.hasParameterAnnotation(input);
}
};
}
private Predicate<Class> isAnnotation() {
return new Predicate<Class>() {
@Override
public boolean apply(Class input) {
return Annotation.class.isAssignableFrom(input);
}
};
}
private boolean shouldExpand(final ResolvedMethodParameter parameter, ResolvedType resolvedParamType) {
return !parameter.hasParameterAnnotation(RequestBody.class)
&& !parameter.hasParameterAnnotation(RequestPart.class)
&& !parameter.hasParameterAnnotation(RequestParam.class)
&& !parameter.hasParameterAnnotation(PathVariable.class)
&& !isBaseType(typeNameFor(resolvedParamType.getErasedType()))
&& !enumTypeDeterminer.isEnum(resolvedParamType.getErasedType())
&& !isContainerType(resolvedParamType)
&& !isMapType(resolvedParamType)
&& !SearchContextBase.class.isAssignableFrom(resolvedParamType.getErasedType());
}
}
......@@ -78,7 +78,9 @@ ribbon:
ConnectTimeout: 60000
#系统是否开启权限验证、是否开启缓存
#缓存模式:关闭缓存(无配置项)、本地缓存(enableCaffeineCache=true-默认)、caffeine+redis两级缓存(enableRedisCache=true)
ibiz:
enablePermissionValid: false
enableCache: true
enableCaffeineCache: true
#enableRedisCache: true
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册