提交 57a53487 编写于 作者: tony001's avatar tony001

Merge branch 'master' into 2020.07.12

上级 7a214458
## v7.0.0-alpha.17 [2020-8-9]
### Bug修复
修复系统级的操作标识异常问题
修复表格新增插件异常问题
修复表格单击行绑定数据异常bug
修复表格合计行样式问题
### 功能新增及优化
#### 模板
新增支持前后端分离部署
新增动态代码表预定义代码表支持
新增数据选择(调用接口)组件
新增部件样式表支持
优化数据服务逻辑
优化代码表服务基类、动态代码表
优化导航参数处理逻辑
优化数据拷贝逻辑
优化组织、部门、人员控件只绑定id逻辑
优化部件关联外键值
#### 基础文件
新增前后端分离部署
新增下拉列表控件支持树状代码表
新增数据选择(调用接口)组件
优化数据拷贝逻辑
优化组织、部门、人员控件只绑定id逻辑
## v7.0.0-alpha.16 [2020-8-2]
### Bug修复
......
......@@ -12,6 +12,7 @@ import { authServiceRegister } from '@/authservice/auth-service-register';
import { utilServiceRegister } from '@/utilservice/util-service-register';
import { entityServiceRegister } from '@/service/entity-service-register';
import { counterServiceRegister } from '@/counter/counter-service-register';
import { codeListRegister } from '@codelist/codelist-register';
import InputBox from './components/input-box/input-box.vue'
import AppKeepAlive from './components/app-keep-alive/app-keep-alive.vue'
......@@ -38,6 +39,7 @@ import AppFormGroup from './components/app-form-group/app-form-group.vue'
import AppFormItem from './components/app-form-item/app-form-item.vue'
import AppPicker from './components/app-picker/app-picker.vue'
import AppMpicker from './components/app-mpicker/app-mpicker.vue'
import AppUpicker from './components/app-upicker/app-upicker.vue'
import AppFormGroup2 from './components/app-form-group2/app-form-group2.vue'
import AppFormItem2 from './components/app-form-item2/app-form-item2.vue'
import CodeList from './components/codelist/codelist.vue'
......@@ -89,6 +91,8 @@ window['utilServiceRegister'] = utilServiceRegister;
window['entityServiceRegister'] = entityServiceRegister;
// 全局挂载计数器服务注册中心
window['counterServiceRegister'] = counterServiceRegister;
// 全局挂载代码表服务注册中心
window['codeListRegister'] = codeListRegister;
export const AppComponents = {
install(v: any, opt: any) {
......@@ -127,6 +131,7 @@ export const AppComponents = {
v.component('app-form-item',AppFormItem);
v.component('app-picker', AppPicker);
v.component('app-mpicker', AppMpicker);
v.component('app-upicker', AppUpicker);
v.component('app-form-group2', AppFormGroup2);
v.component('app-form-item2', AppFormItem2);
v.component('codelist', CodeList);
......
......@@ -6,6 +6,7 @@
<script lang="ts">
import { Vue, Component, Watch, Prop, Model } from 'vue-property-decorator';
import CodeListService from '@/service/app/codelist-service';
@Component({
})
export default class AppDepartmentSelect extends Vue {
......@@ -18,6 +19,20 @@ export default class AppDepartmentSelect extends Vue {
*/
@Prop() public url?: any;
/**
* 代码表标识
*
* @memberof AppDepartmentSelect
*/
@Prop() public tag?:string;
/**
* 代码表类型
*
* @memberof AppDepartmentSelect
*/
@Prop() public codelistType?:string;
/**
* 过滤项
*
......@@ -88,7 +103,7 @@ export default class AppDepartmentSelect extends Vue {
* @type {*}
* @memberof AppDepartmentSelect
*/
public oldurl: any[] = [];
public oldurl: any;
/**
* 获取节点数据
......@@ -121,14 +136,14 @@ export default class AppDepartmentSelect extends Vue {
}
this.oldurl = _url;
// 缓存机制
const result:any = this.$store.getters.getCopyData(_url);
const result:any = this.$store.getters.getDepData(_url);
if(result){
this.Nodesdata = result;
return;
}
this.$http.get(_url).then((response: any) => {
this.Nodesdata = response.data;
this.$store.commit('addDepData', { srfkey: this.filter, orgData: response.data });
this.$store.commit('addDepData', { srfkey: _url, depData: response.data });
}).catch((response: any) => {
if (!response || !response.status || !response.data) {
this.$Notice.error({ title: (this.$t('app.commonWords.error') as string), desc: (this.$t('app.commonWords.sysException') as string) });
......@@ -163,13 +178,19 @@ export default class AppDepartmentSelect extends Vue {
// 单选
if(!this.multiple){
if(this.fillMap && Object.keys(this.fillMap).length >0){
let templateValue = {};
let templateValue:any = {};
Object.keys(this.fillMap).forEach((item:any) =>{
if(this.data && this.data[this.fillMap[item]]){
Object.assign(templateValue,{[item]:this.data[this.fillMap[item]]});
}
})
this.selectTreeValue = JSON.stringify([templateValue]);
if(!templateValue.label && templateValue.id && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
this.fillLabel(templateValue,templateValue.id,(templateValue:any) =>{
this.selectTreeValue = JSON.stringify([templateValue]);
});
}else{
this.selectTreeValue = JSON.stringify([templateValue]);
}
}
}else{
// 多选
......@@ -188,8 +209,30 @@ export default class AppDepartmentSelect extends Vue {
})
}
})
this.selectTreeValue = JSON.stringify(tempArray);
let tempflag:boolean = false;
if(tempArray.length >0 && tempArray.length >0){
tempArray.forEach((item:any) =>{
if(!item.label) tempflag = true;
})
}
if(tempflag && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
let tempStatus:number = 0;
tempArray.forEach((item:any) =>{
if(!item.label){
tempStatus += 1;
this.fillLabel(item,item.id,(result:any) =>{
item = result;
tempStatus -= 1;
if(tempStatus === 0){
this.selectTreeValue = JSON.stringify(tempArray);
}
})
}
})
}else{
this.selectTreeValue = JSON.stringify(tempArray);
}
}
}
}
......@@ -208,10 +251,35 @@ export default class AppDepartmentSelect extends Vue {
let _name = this.fillMap[attribute];
let values = selectArr.map((item:any) => item[attribute]);
let _value = $event === "[]" ? null : values.join(",");
this.$emit('select-change',{name: this.fillMap[attribute], value: _value})
setTimeout(() => {
this.$emit('select-change',{name: this.fillMap[attribute], value: _value});
},0);
});
}
}
/**
* 填充label
*
* @memberof AppOrgSelect
*/
public fillLabel(tempObject:any,valueItem:any,callback:any){
if(!tempObject.label && tempObject.id && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
let codeListService:CodeListService = new CodeListService();
codeListService.getItems(this.tag).then((items:any) =>{
if(items && items.length >0){
let result:any = items.find((item:any) =>{
return item.id === valueItem;
})
Object.assign(tempObject,{label:result.label});
}
callback(tempObject);
}).catch((error:any) =>{
console.log(error);
})
}
}
}
</script>
......
......@@ -21,6 +21,7 @@
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
import CodeListService from '@/service/app/codelist-service';
@Component({})
export default class AppGroupSelect extends Vue {
......@@ -64,6 +65,20 @@ export default class AppGroupSelect extends Vue {
*/
@Prop() data: any;
/**
* 代码表标识
*
* @memberof AppGroupSelect
*/
@Prop() public tag?:string;
/**
* 代码表类型
*
* @memberof AppGroupSelect
*/
@Prop() public codelistType?:string;
/**
* 过滤属性标识
*
......@@ -126,12 +141,12 @@ export default class AppGroupSelect extends Vue {
* @type {*}
* @memberof AppGroupSelect
*/
@Watch('value')
onValueChange(newVal: any) {
@Watch('data',{immediate:true,deep:true})
onValueChange(newVal: any, oldVal: any) {
this.selects = [];
if (newVal) {
let item: any = {};
item.label = newVal.split(',');
item.label = this.data[this.name]?this.data[this.name].split(','):[];
if(this.valueitem) {
item.id = this.data[this.valueitem] ? this.data[this.valueitem].split(',') : [];
}
......@@ -140,13 +155,24 @@ export default class AppGroupSelect extends Vue {
item[this.fillmap[key]] = this.data[key] ? this.data[key].split(',') : [];
}
}
item.label.forEach((val: string, index: number) => {
let _item: any = {};
for(let key in item) {
_item[key] = item[key][index] ? item[key][index] : null;
}
this.selects.push(_item)
})
const callback:any = (item:any) =>{
item.label.forEach((val: string, index: number) => {
let _item: any = {};
for(let key in item) {
_item[key] = item[key][index] ? item[key][index] : null;
}
this.selects.push(_item)
})
}
if(item.label.length == 0 && item.id.length > 0){
this.fillLabel(item,item.id,(result:any) =>{
item.label = result.label;
callback(item);
});
}else{
callback(item);
}
}
}
......@@ -259,7 +285,6 @@ export default class AppGroupSelect extends Vue {
}
});
} else {
item = this.selects.length > 0 ? this.selects[0] : {};
item[this.name] = this.selects.length > 0 ? this.selects[0].label : null;
if(this.valueitem) {
item[this.valueitem] = this.selects.length > 0 ? this.selects[0].id : null;
......@@ -273,7 +298,34 @@ export default class AppGroupSelect extends Vue {
for(let key in item) {
this.$emit('formitemvaluechange', { name: key, value: item[key] });
}
}
}
/**
* 填充label
*
* @memberof AppGroupSelect
*/
public fillLabel(tempObject:any,valueItem:Array<any>,callback:any){
if(tempObject.label.length === 0 && tempObject.id.length >0 && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
let codeListService:CodeListService = new CodeListService();
codeListService.getItems(this.tag).then((items:any) =>{
if(items && items.length >0 && valueItem.length >0){
let tempLabel:Array<any> = [];
valueItem.forEach((value:any) =>{
let result:any = items.find((item:any) =>{
return item.id === value;
})
tempLabel.push(result.label);
})
Object.assign(tempObject,{label:tempLabel});
}
callback(tempObject);
}).catch((error:any) =>{
console.log(error);
})
}
}
}
</script>
......
......@@ -6,6 +6,8 @@
<script lang = 'ts'>
import { Vue, Component, Prop, Watch } from "vue-property-decorator";
import { Http } from '@/utils';
import CodeListService from "@service/app/codelist-service";
import { observable } from 'rxjs';
@Component({})
export default class AppOrgSelect extends Vue {
......@@ -37,6 +39,20 @@ export default class AppOrgSelect extends Vue {
*/
@Prop() public filter?:string;
/**
* 代码表标识
*
* @memberof AppOrgSelect
*/
@Prop() public tag?:string;
/**
* 代码表类型
*
* @memberof AppOrgSelect
*/
@Prop() public codelistType?:string;
/**
* 是否多选
*
......@@ -138,13 +154,19 @@ export default class AppOrgSelect extends Vue {
// 单选
if(!this.multiple){
if(this.fillMap && Object.keys(this.fillMap).length >0){
let templateValue = {};
Object.keys(this.fillMap).forEach((item:any) =>{
if(this.data && this.data[this.fillMap[item]]){
Object.assign(templateValue,{[item]:this.data[this.fillMap[item]]});
let templateValue:any = {};
Object.keys(this.fillMap).forEach((item:any) =>{
if(this.data && this.data[this.fillMap[item]]){
Object.assign(templateValue,{[item]:this.data[this.fillMap[item]]});
}
})
if(!templateValue.label && templateValue.id && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
this.fillLabel(templateValue,templateValue.id,(templateValue:any) =>{
this.selectTreeValue = JSON.stringify([templateValue]);
});
}else{
this.selectTreeValue = JSON.stringify([templateValue]);
}
})
this.selectTreeValue = JSON.stringify([templateValue]);
}
}else{
// 多选
......@@ -163,8 +185,30 @@ export default class AppOrgSelect extends Vue {
})
}
})
this.selectTreeValue = JSON.stringify(tempArray);
let tempflag:boolean = false;
if(tempArray.length >0 && tempArray.length >0){
tempArray.forEach((item:any) =>{
if(!item.label) tempflag = true;
})
}
if(tempflag && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
let tempStatus:number = 0;
tempArray.forEach((item:any) =>{
if(!item.label){
tempStatus += 1;
this.fillLabel(item,item.id,(result:any) =>{
item = result;
tempStatus -= 1;
if(tempStatus === 0){
this.selectTreeValue = JSON.stringify(tempArray);
}
})
}
})
}else{
this.selectTreeValue = JSON.stringify(tempArray);
}
}
}
}
......@@ -175,7 +219,7 @@ export default class AppOrgSelect extends Vue {
*/
public loadTreeData(requestUrl:string){
if(this.filter){
const result:any = this.$store.getters.getCopyData(this.filter);
const result:any = this.$store.getters.getOrgData(this.filter);
if(result){
this.NodesData = result;
return;
......@@ -209,7 +253,9 @@ export default class AppOrgSelect extends Vue {
tempValue.forEach((value:any,index:number) =>{
tempResult += index>0?`,${value[item]}`:`${value[item]}`;
})
this.emitValue(this.fillMap[item],tempResult);
setTimeout(() => {
this.emitValue(this.fillMap[item],tempResult);
}, 0);
})
}
}else{
......@@ -225,7 +271,9 @@ export default class AppOrgSelect extends Vue {
const tempValue:any = JSON.parse($event)[0];
if(this.fillMap && Object.keys(this.fillMap).length >0){
Object.keys(this.fillMap).forEach((item:any) =>{
this.emitValue(this.fillMap[item],tempValue[item]);
setTimeout(() => {
this.emitValue(this.fillMap[item],tempValue[item]);
}, 0);
})
}
}else{
......@@ -247,6 +295,28 @@ export default class AppOrgSelect extends Vue {
this.$emit('select-change',{name:name,value:value});
}
/**
* 填充label
*
* @memberof AppOrgSelect
*/
public fillLabel(tempObject:any,valueItem:any,callback:any){
if(!tempObject.label && tempObject.id && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
let codeListService:CodeListService = new CodeListService();
codeListService.getItems(this.tag).then((items:any) =>{
if(items && items.length >0){
let result:any = items.find((item:any) =>{
return item.id === valueItem;
})
Object.assign(tempObject,{label:result.label});
}
callback(tempObject);
}).catch((error:any) =>{
console.log(error);
})
}
}
}
</script>
......
.app-upicker {
width: 100%;
.el-select {
.el-input__suffix {
display: none;
}
}
.text-value {
.el-icon-circle-close {
display: none;
}
}
.text-value:hover {
.el-icon-circle-close {
display: inline-block;
}
}
.ivu-icon-ios-open-outline {
margin-top: -2px;
margin-left: 5px;
font-size: 15px;
}
}
\ No newline at end of file
<template>
<div class='app-upicker'>
<el-select ref="appUpicker" :value="refvalue" size='small' filterable
@change="onSelect" :disabled="disabled" style='width:100%;' clearable
@clear="onClear" @visible-change="onSelectOpen">
<template v-if="items">
<el-option v-for="(_item,index) in items" :key="index" :value="_item.value" :label="_item.label"></el-option>
</template>
</el-select>
<span style='position: absolute;right: 5px;color: #c0c4cc;top:0;font-size: 13px;'>
<i v-show="open" class='el-icon-arrow-up' @click="closeDropdown"></i>
<i v-show="!open" class='el-icon-arrow-down' @click="openDropdown"></i>
</span>
</div>
</template>
<script lang = 'ts'>
import { Component, Vue, Prop, Model, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
import { AppModal } from '@/utils';
@Component({
})
export default class AppUpicker extends Vue {
/**
* 请求到的数据
* @type {any[]}
* @memberof AppUpicker
*/
public itemList: any[] = []
/**
* 列表项请求路径
*
* @type {string}
* @memberof AppUpicker
*/
public url: string = '';
/**
* 请求参数和请求数据的映射关系
*
* @type {*}
* @memberof AppUpicker
*/
public interaction:any = {};
/**
* 编辑器参数
*
* @type {*}
* @memberof AppUpicker
*/
@Prop() public itemParams?: any;
/**
* 视图上下文
*
* @type {*}
* @memberof AppUpicker
*/
@Prop() public context!: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppUpicker
*/
@Prop() public viewparams!: any;
/**
* 表单数据
*
* @type {*}
* @memberof AppUpicker
*/
@Prop() public data!: any;
/**
* 属性项名称
*
* @type {string}
* @memberof AppUpicker
*/
@Prop() public name!: string;
/**
* 是否启用
*
* @type {boolean}
* @memberof AppUpicker
*/
@Prop() public disabled?: boolean;
/**
* 是否显示按钮
*
* @type {boolean}
* @memberof AppUpicker
*/
@Prop({default:true}) public showButton?: boolean;
/**
* 局部上下文导航参数
*
* @type {any}
* @memberof AppUpicker
*/
@Prop() public localContext!:any;
/**
* 局部导航参数
*
* @type {any}
* @memberof AppUpicker
*/
@Prop() public localParam!:any;
/**
* 值项名称
*
* @type {string}
* @memberof AppUpicker
*/
@Prop() public valueitem!: string;
/**
* 排序
*
* @type {string}
* @memberof AppUpicker
*/
@Prop() public sort?: string;
/**
* 值
*
* @type {*}
* @memberof AppUpicker
*/
@Model('change') public value?: any;
/**
* 当前值
*
* @type {string}
* @memberof AppUpicker
*/
public curvalue: string = '';
/**
* 下拉数组
* @type {any[]}
* @memberof AppUpicker
*/
public items: any[] = [];
/**
* 下拉图标指向状态管理
* @type {boolean}
* @memberof AppUpicker
*/
public open: boolean = false;
/**
* 输入状态
*
* @type {boolean}
* @memberof AppUpicker
*/
public inputState: boolean = false;
/**
* 获取关联数据项值
*
* @readonly
* @memberof AppUpicker
*/
get refvalue() {
if (this.valueitem && this.data) {
return this.data[this.valueitem];
}
return this.curvalue;
}
/**
* 值变化
*
* @param {*} newVal
* @param {*} oldVal
* @memberof AppUpicker
*/
@Watch('value',{immediate:true})
public onValueChange(newVal: any, oldVal: any) {
this.analysis(this.itemParams);
if(newVal){
this.curvalue = newVal;
const value = this.data[this.valueitem];
const index = this.items.findIndex((item: any) => Object.is(item.value, value));
if (index !== -1) {
return;
}
this.items = [];
if (value) {
this.items.push({text: newVal, value: value});
}
}
}
/**
* vue 生命周期
*
* @memberof AppUpicker
*/
public created() {
// 解析编辑器参数
this.analysis(this.itemParams);
}
/**
* 解析编辑器参数
* @param {*} itemparams
*
* @memberof AppUpicker
*/
public analysis(itemparams:any) {
Object.keys(itemparams).forEach((param)=>{
if(param==='path'){
this.url = itemparams[param]
}else{
this.interaction[param] = itemparams[param]
}
})
}
/**
* 请求下拉列表数据
* @param {string} url
*
* @memberof AppUpicker
*/
public fectchItemList(url:string) {
let arg:any = {};
this.handlePublicParams(arg);
this.$http
.get(url,arg.param)
.then((response: any) => {
if (response && response.status==200 && response.data) {
this.itemList = response.data;
// 提取需要的值(value,label)
this.extractItem(this.itemList,this.items);
}
})
.catch((response: any) => {
if (!response || !response.status || !response.data) {
this.$Notice.error({
title: this.$t("app.commonWords.error") as string,
desc: this.$t("app.commonWords.sysException") as string,
});
return;
}
});
}
/**
* 解析下拉列表数据
* @param {any[]} itemList 请求到的数据
* @param {any[]} items 下拉数组
*
* @memberof AppUpicker
*/
public extractItem(itemList:any[],items:any[]) {
this.items = [];
itemList.forEach((item) => {
this.items.push({
label: item[this.interaction.label],
value: item[this.interaction.value],
});
});
}
/**
* 下拉切换回调
* @param flag
*
* @memberof AppUpicker
*/
public onSelectOpen(flag: boolean): void {
this.open = flag;
if (this.open) {
this.fectchItemList(this.url);
}
}
/**
* 下拉选中
*
* @param {string} val
* @memberof AppUpicker
*/
public onSelect(val: string) {
let index = this.items.findIndex((item) => Object.is(item.value, val));
if (index >= 0) {
let item:any = this.items[index];
if (this.valueitem) {
this.$emit('formitemvaluechange', { name: this.valueitem, value: item.value });
}
if (this.name) {
this.$emit('formitemvaluechange', { name: this.name, value: item.label });
}
}
}
/**
* 清除
*
* @memberof AppUpicker
*/
public onClear($event: any): void {
if (this.valueitem) {
this.$emit('formitemvaluechange', { name: this.valueitem, value: '' });
}
if (this.name) {
this.$emit('formitemvaluechange', { name: this.name, value: '' });
}
this.$forceUpdate();
}
/**
* 公共参数处理
*
* @param {*} arg
* @returns
* @memberof AppUpicker
*/
public handlePublicParams(arg: any): boolean {
if (!this.data) {
this.$Notice.error({ title: (this.$t('components.appPicker.error') as any), desc: (this.$t('components.appPicker.formdataException') as any) });
return false;
}
// 合并表单参数
arg.param = this.viewparams ? JSON.parse(JSON.stringify(this.viewparams)) : {};
arg.context = this.context ? JSON.parse(JSON.stringify(this.context)) : {};
// 附加参数处理
if (this.localContext && Object.keys(this.localContext).length >0) {
let _context = this.$util.computedNavData(this.data,arg.context,arg.param,this.localContext);
Object.assign(arg.context,_context);
}
if (this.localParam && Object.keys(this.localParam).length >0) {
let _param = this.$util.computedNavData(this.data,arg.param,arg.param,this.localParam);
Object.assign(arg.param,_param);
}
return true;
}
/**
* 展开下拉
*
* @memberof AppUpicker
*/
public openDropdown() {
const appUpicker: any = this.$refs.appUpicker;
if(appUpicker) {
appUpicker.focus();
}
}
/**
* 收起下拉
*
* @memberof AppUpicker
*/
public closeDropdown() {
const appUpicker: any = this.$refs.appUpicker;
if(appUpicker) {
appUpicker.blur();
}
}
}
</script>
<style lang="less">
@import './app-upicker.less';
</style>
.ivu-select-multiple .ivu-select-item-selected:after{
display: none;
}
.dropdown-list-mpicker-container{
.tree-dropdown-list-mpicker{
width: 100%;
.el-input__inner{
height: 32px !important;
line-height: 32px !important;
}
.el-input__icon{
line-height: 32px;
}
}
}
<template>
<i-select
class='dropdown-list-mpicker'
multiple
:transfer="true"
transfer-class-name="dropdown-list-mpicker-transfer"
v-model="currentVal"
:disabled="disabled === true ? true : false"
:clearable="true"
:filterable="filterable === true ? true : false"
@on-open-change="onClick"
:placeholder="$t('components.dropDownListMpicker.placeholder')">
<i-option v-for="(item, index) in items" :key="index" :value="item.value.toString()" :label="item.text">
<Checkbox :value = "(currentVal.indexOf(item.value.toString()))==-1?false:true">
{{Object.is(codelistType,'STATIC') ? $t('codelist.'+tag+'.'+item.value) : item.text}}
</Checkbox>
</i-option>
</i-select>
<div class="dropdown-list-mpicker-container">
<i-select
v-if="!hasChildren"
class='dropdown-list-mpicker'
multiple
:transfer="true"
transfer-class-name="dropdown-list-mpicker-transfer"
v-model="currentVal"
:disabled="disabled === true ? true : false"
:clearable="true"
:filterable="filterable === true ? true : false"
@on-open-change="onClick"
:placeholder="$t('components.dropDownListMpicker.placeholder')">
<i-option v-for="(item, index) in items" :key="index" :value="item.value.toString()" :label="item.text">
<Checkbox :value = "(currentVal.indexOf(item.value.toString()))==-1?false:true">
{{Object.is(codelistType,'STATIC') ? $t('codelist.'+tag+'.'+item.value) : item.text}}
</Checkbox>
</i-option>
</i-select>
<ibiz-select-tree v-if="hasChildren" class="tree-dropdown-list-mpicker" :disabled="disabled" :NodesData="items" v-model="currentVal" :multiple="true"></ibiz-select-tree>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service";
import { Util } from '@/utils';
@Component({
})
export default class DropDownListMpicker extends Vue {
......@@ -32,6 +37,13 @@ export default class DropDownListMpicker extends Vue {
*/
public codeListService:CodeListService = new CodeListService({ $store: this.$store });
/**
* 是否有子集
* @type {boolean}
* @memberof DropDownListMpicker
*/
public hasChildren:boolean = false;
/**
* 当前选中值
* @type {any}
......@@ -131,6 +143,14 @@ export default class DropDownListMpicker extends Vue {
* @memberof DropDownListMpicker
*/
set currentVal(val: any) {
if(this.hasChildren && val){
let tempVal:any = JSON.parse(val);
if(tempVal.length >0){
val = tempVal.map((item:any) =>{
return item.value;
})
}
}
const type: string = this.$util.typeOf(val);
val = Object.is(type, 'null') || Object.is(type, 'undefined') ? [] : val;
let value = val.length > 0 ? val.join(this.valueSeparator) : '';
......@@ -143,9 +163,45 @@ export default class DropDownListMpicker extends Vue {
* @memberof DropDownListMpicker
*/
get currentVal() {
if(this.hasChildren){
if(this.itemValue){
let list:Array<any> = [];
let selectedvalueArray:Array<any> = [];
let curSelectedValue:Array<any> = this.itemValue.split(this.valueSeparator);
this.getItemList(list,this.items);
if(curSelectedValue.length > 0){
curSelectedValue.forEach((selectedVal:any) =>{
let tempResult:any = list.find((item:any) =>{
return item.value == selectedVal;
})
selectedvalueArray.push(tempResult);
})
}
return selectedvalueArray.length >0?JSON.stringify(selectedvalueArray):null;
}else{
return null;
}
}
return this.itemValue? this.itemValue.split(this.valueSeparator):[];
}
/**
* 获取代码表列表
*
* @memberof DropDownListMpicker
*/
public getItemList(list:Array<any>,items:Array<any>){
if(items && items.length >0){
items.forEach((item:any) =>{
if(item.children){
this.getItemList(list,item.children);
}
list.push(item);
})
}
}
/**
* 代码表
*
......@@ -186,6 +242,7 @@ export default class DropDownListMpicker extends Vue {
const codelist = this.$store.getters.getCodeList(this.tag);
if (codelist) {
this.items = [...JSON.parse(JSON.stringify(codelist.items))];
this.handleLevelCodeList(Util.deepCopy(this.items));
} else {
console.log(`----${this.tag}----${(this.$t('app.commonWords.codeNotExist') as string)}`);
}
......@@ -198,6 +255,7 @@ export default class DropDownListMpicker extends Vue {
let _param = data.param;
this.codeListService.getItems(this.tag,_context,_param).then((res:any) => {
this.items = res;
this.handleLevelCodeList(Util.deepCopy(this.items));
}).catch((error:any) => {
console.log(`----${this.tag}----${(this.$t('app.commonWords.codeNotExist') as string)}`);
});
......@@ -220,11 +278,57 @@ export default class DropDownListMpicker extends Vue {
let _param = data.param;
this.codeListService.getItems(this.tag,_context,_param).then((res:any) => {
this.items = res;
this.handleLevelCodeList(Util.deepCopy(this.items));
}).catch((error:any) => {
console.log(`----${this.tag}----${(this.$t('app.commonWords.codeNotExist') as string)}`);
});
}
}
/**
* 处理层级代码表
*
* @param {*} items
* @memberof DropDownListMpicker
*/
public handleLevelCodeList(items: Array<any>){
if(items && items.length >0){
this.hasChildren = items.some((item:any) =>{
return item.pvalue;
})
if(this.hasChildren){
let list:Array<any> = [];
items.forEach((codeItem:any) =>{
if(!codeItem.pvalue){
let valueField:string = codeItem.value;
this.setChildCodeItems(valueField,items,codeItem);
list.push(codeItem);
}
})
this.items = list;
}
}
}
/**
* 计算子类代码表
*
* @param {*} items
* @memberof DropDownListMpicker
*/
public setChildCodeItems(pValue:string,result:Array<any>,codeItem:any){
result.forEach((item:any) =>{
if(item.pvalue == pValue){
let valueField:string = item.value;
this.setChildCodeItems(valueField,result,item);
if(!codeItem.children){
codeItem.children = [];
}
codeItem.children.push(item);
}
})
}
}
</script>
......
.dropdown-list{
display: inline-block;
}
.dropdown-list-container{
.dropdown-list{
display: inline-block;
}
.tree-dropdown-list{
width: 100%;
.el-input__inner{
height: 32px !important;
line-height: 32px !important;
}
.el-input__icon{
line-height: 32px;
}
}
}
\ No newline at end of file
<template>
<i-select
<div class="dropdown-list-container">
<i-select v-if="!hasChildren"
class='dropdown-list'
:transfer="true"
v-model="currentVal"
......@@ -9,12 +10,15 @@
@on-open-change="onClick"
:placeholder="$t('components.dropDownList.placeholder')">
<i-option v-for="(item, index) in items" :key="index" :value="item.value">{{($t('codelist.'+tag+'.'+item.value)!== ('codelist.'+tag+'.'+item.value))?$t('codelist.'+tag+'.'+item.value) : item.text}}</i-option>
</i-select>
</i-select>
<ibiz-select-tree v-if="hasChildren" class="tree-dropdown-list" :disabled="disabled" :NodesData="items" v-model="currentVal" :multiple="false"></ibiz-select-tree>
</div>
</template>
<script lang="ts">
import { Vue, Component, Watch, Prop, Model } from 'vue-property-decorator';
import CodeListService from "@service/app/codelist-service";
import { Util } from '@/utils';
@Component({
})
......@@ -42,6 +46,13 @@ export default class DropDownList extends Vue {
*/
public queryParam:any;
/**
* 是否有子集
* @type {boolean}
* @memberof DropDownList
*/
public hasChildren:boolean = false;
/**
* 当前选中值
* @type {any}
......@@ -152,6 +163,10 @@ export default class DropDownList extends Vue {
* @memberof DropDownList
*/
set currentVal(val: any) {
if(this.hasChildren && val){
let tempVal:any = JSON.parse(val);
val = tempVal.length >0?tempVal[0].value:null;
}
const type: string = this.$util.typeOf(val);
val = Object.is(type, 'null') || Object.is(type, 'undefined') ? undefined : val;
this.$emit('change', val);
......@@ -163,9 +178,33 @@ export default class DropDownList extends Vue {
* @memberof DropDownList
*/
get currentVal() {
if(this.hasChildren && this.itemValue){
let list:Array<any> = [];
this.getItemList(list,this.items);
let result:any = list.find((item:any) =>{
return item.value == this.itemValue;
})
return JSON.stringify([result]);
}
return this.itemValue;
}
/**
* 获取代码表列表
*
* @memberof DropDownList
*/
public getItemList(list:Array<any>,items:Array<any>){
if(items && items.length >0){
items.forEach((item:any) =>{
if(item.children){
this.getItemList(list,item.children);
}
list.push(item);
})
}
}
/**
* 代码表
*
......@@ -287,6 +326,51 @@ export default class DropDownList extends Vue {
}catch(error){
console.warn('代码表值类型和属性类型不匹配,自动强制转换异常,请修正代码表值类型和属性类型匹配');
}
this.handleLevelCodeList(Util.deepCopy(this.items));
}
/**
* 处理层级代码表
*
* @param {*} items
* @memberof DropDownList
*/
public handleLevelCodeList(items: Array<any>){
if(items && items.length >0){
this.hasChildren = items.some((item:any) =>{
return item.pvalue;
})
if(this.hasChildren){
let list:Array<any> = [];
items.forEach((codeItem:any) =>{
if(!codeItem.pvalue){
let valueField:string = codeItem.value;
this.setChildCodeItems(valueField,items,codeItem);
list.push(codeItem);
}
})
this.items = list;
}
}
}
/**
* 计算子类代码表
*
* @param {*} items
* @memberof DropDownList
*/
public setChildCodeItems(pValue:string,result:Array<any>,codeItem:any){
result.forEach((item:any) =>{
if(item.pvalue == pValue){
let valueField:string = item.value;
this.setChildCodeItems(valueField,result,item);
if(!codeItem.children){
codeItem.children = [];
}
codeItem.children.push(item);
}
})
}
}
</script>
......
......@@ -3,13 +3,14 @@ import { AuthServiceRegister } from '@/authservice/auth-service-register';
import { UtilServiceRegister } from '@/utilservice/util-service-register';
import { EntityServiceRegister } from '@/service/entity-service-register';
import { CounterServiceRegister } from '@/counter/counter-service-register';
import { CodeListRegister } from '@codelist/codelist-register';
declare global {
interface Window {
uiServiceRegister: UIServiceRegister,
authServiceRegister: AuthServiceRegister,
utilServiceRegister: UtilServiceRegister,
entityServiceRegister: EntityServiceRegister,
counterServiceRegister: CounterServiceRegister
counterServiceRegister: CounterServiceRegister,
codeListRegister:CodeListRegister
}
}
\ No newline at end of file
import store from '@/store';
import EntityService from '../entity-service';
/**
* 动态代码表服务类
*
* @export
* @class CodeListService
*/
export default class CodeListService {
/**
* Vue 状态管理器
*
* @private
* @type {(any | null)}
* @memberof CodeListService
*/
private $store: any;
constructor(opts: any = {}) {
this.$store = store;
}
/**
* 获取状态管理器
*
* @returns {(any | null)}
* @memberof CodeListService
*/
public getStore(): any {
return this.$store;
}
/**
* 动态代码表缓存(加载中)
*
* @type {Map<string,any>}
* @memberof CodeListService
*/
public static codelistCache:Map<string,any> = new Map();
/**
* 动态代码表缓存(已完成)
*
* @type {Map<string,any>}
* @memberof CodeListService
*/
public static codelistCached:Map<string,any> = new Map();
/**
* 数据服务基类
*
* @type {Minorentity}
* @memberof CodeListService
*/
public entityService:EntityService = new EntityService();
/**
* 获取代码表服务
*
* @protected
* @param {string} name 实体名称
* @returns {Promise<any>}
* @memberof EntityService
*/
public getService(name: string): Promise<any> {
return (window as any)['codeListRegister'].getService(name);
}
/**
* 获取静态代码表
*
* @param {string} tag 代码表标识
* @returns {Promise<any[]>}
* @memberof CodeListService
*/
public getStaticItems(tag: string):Promise<any[]>{
return new Promise((resolve:any,reject:any) =>{
const codelist = this.$store.getters.getCodeList(tag);
if (codelist) {
let items: Array<any> = [...JSON.parse(JSON.stringify(codelist.items))];
resolve(items);
}
})
}
/**
* 获取预定义代码表
*
* @param {string} tag 代码表标识
* @returns {Promise<any[]>}
* @memberof CodeListService
*/
public getPredefinedItems(tag: string,data?: any, isloading?: boolean):Promise<any[]>{
return new Promise((resolve:any,reject:any) =>{
if(CodeListService.codelistCached.get(`${tag}`)){
let items:any = CodeListService.codelistCached.get(`${tag}`).items;
if(items.length >0) resolve(items);
}
const callback:Function = (tag:string,promise:Promise<any>) =>{
promise.then((res:any) =>{
let result:any = res.data;
if(result.items && result.items.length > 0){
CodeListService.codelistCached.set(`${tag}`,{items:result.items});
return resolve(result.items);
}else{
return resolve([]);
}
}).catch((result:any) =>{
return reject(result);
})
}
// 加载中,UI又需要数据,解决连续加载同一代码表问题
if(CodeListService.codelistCache.get(`${tag}`)){
callback(tag,CodeListService.codelistCache.get(`${tag}`));
}else{
let result:Promise<any> = this.entityService.getPredefinedCodelist(tag);
CodeListService.codelistCache.set(`${tag}`,result);
callback(tag,result);
}
})
}
/**
* 获取动态代码表
*
* @param {string} tag 代码表标识
* @param {string} context
* @returns {Promise<any[]>}
* @memberof CodeListService
*/
public getItems(tag: string,context:any = {}, data?: any, isloading?: boolean): Promise<any[]> {
let _this: any = this;
if(context && context.srfsessionid){
delete context.srfsessionid;
}
return new Promise((resolve:any,reject:any) =>{
this.getService(tag).then((codelist:any) =>{
if(Object.is(codelist.predefinedType,"RUNTIME")){
this.getPredefinedItems(tag).then((res:any) =>{
resolve(res);
})
return;
}
let isEnableCache:boolean = codelist.isEnableCache;
let cacheTimeout:any = codelist.cacheTimeout;
// 启用缓存
if(isEnableCache){
// 加载完成,从本地缓存获取
if(CodeListService.codelistCached.get(`${JSON.stringify(context)}-${JSON.stringify(data)}-${tag}`)){
let items:any = CodeListService.codelistCached.get(`${JSON.stringify(context)}-${JSON.stringify(data)}-${tag}`).items;
if(items.length >0){
if(cacheTimeout !== -1){
if(new Date().getTime() > codelist.expirationTime){
codelist.getItems(context,data,isloading).then((result:any) =>{
CodeListService.codelistCached.set(`${JSON.stringify(context)}-${JSON.stringify(data)}-${tag}`,{items:result});
codelist.expirationTime = new Date().getTime() + cacheTimeout;
resolve(result);
}).catch((error:any) =>{
Promise.reject([]);
})
}else{
return resolve(items);
}
}else{
return resolve(items);
}
}
}
if (codelist) {
const callback:Function = (context:any ={},data:any ={},tag:string,promise:Promise<any>) =>{
promise.then((result:any) =>{
if(result.length > 0){
CodeListService.codelistCached.set(`${JSON.stringify(context)}-${JSON.stringify(data)}-${tag}`,{items:result});
return resolve(result);
}else{
return resolve([]);
}
}).catch((result:any) =>{
return reject(result);
})
}
// 加载中,UI又需要数据,解决连续加载同一代码表问题
if(CodeListService.codelistCache.get(`${JSON.stringify(context)}-${JSON.stringify(data)}-${tag}`)){
callback(context,data,tag,CodeListService.codelistCache.get(`${JSON.stringify(context)}-${JSON.stringify(data)}-${tag}`));
}else{
let result:Promise<any> = codelist.getItems(context,data,isloading);
CodeListService.codelistCache.set(`${JSON.stringify(context)}-${JSON.stringify(data)}-${tag}`,result);
if(cacheTimeout !== -1){
codelist.expirationTime = new Date().getTime() + cacheTimeout;
}
callback(context,data,tag,result);
}
}
}else{
if (codelist) {
codelist.getItems(context,data,isloading).then((result:any) =>{
resolve(result);
}).catch((error:any) =>{
Promise.reject([]);
})
}else{
return Promise.reject([]);
}
}
}).catch((error:any) =>{
console.warn("获取代码表异常");
return Promise.reject([]);
})
})
}
}
\ No newline at end of file
import { Store } from 'vuex';
import { Http } from '@/utils';
import CodeListService from "@service/app/codelist-service";
......@@ -10,15 +9,6 @@ import CodeListService from "@service/app/codelist-service";
*/
export default class EntityService {
/**
* Vue 状态管理器
*
* @private
* @type {(any | null)}
* @memberof EntityService
*/
private $store: Store<any> | null = null;
/**
* 获取实体数据服务
*
......@@ -101,19 +91,30 @@ export default class EntityService {
* @memberof EntityService
*/
constructor(opts: any = {}) {
this.$store = opts.$store;
this.tempStorage = localStorage;
this.initBasicData();
}
/**
* 获取状态管理器
* 获取代码表
*
* @returns {(any | null)}
* @memberof EntityService
*/
public getStore(): Store<any> | null {
return this.$store;
public getCodeList(tag:string,codelistType:string,context:any = {},param:any ={}){
return new Promise((resolve:any,reject:any) =>{
let codeListService = new CodeListService();
if(tag && Object.is(codelistType,"STATIC")){
codeListService.getStaticItems(tag).then((items:any) =>{
resolve(items);
})
}else if(tag && Object.is(codelistType,"DYNAMIC")){
codeListService.getItems(tag,context,param).then((res:any) => {
resolve(res);
}).catch((error:any) => {
reject(`${tag}代码表不存在`);
});
}
})
}
/**
......@@ -988,4 +989,15 @@ export default class EntityService {
return Http.getInstance().post(`/v7/changepwd`,data,isloading);
}
/**
* 获取数字字典
*
* @param tag
* @param data
* @param isloading
*/
public async getPredefinedCodelist(tag:string,data: any = {}, isloading?: boolean): Promise<any> {
return Http.getInstance().get(`/dictionarys/codelist/${tag}`,data,isloading);
}
}
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册