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

4月11号提交

上级 c74558da
......@@ -15,7 +15,7 @@ import view_${subctrl.getName()} from '@widgets/app/${srffilepath2(subctrl.getCo
<#if ctrl.getPSLayoutPanels?? && ctrl.getPSLayoutPanels()??>
<#list ctrl.getPSLayoutPanels() as panel>
import layout_${panel.getName()} from '@widgets/${srffilepath2(panel.getPSDataEntity().getCodeName())}/${srffilepath2(panel.getCodeName())}-${panel.getControlType()?lower_case}/${srffilepath2(panel.getCodeName())}-${panel.getControlType()?lower_case}';
import layout_${panel.getName()} from '@widgets/${srffilepath2(panel.getPSDataEntity().getCodeName())}/${srffilepath2(panel.getCodeName())}-${panel.getControlType()?lower_case}/${srffilepath2(panel.getCodeName())}-${panel.getControlType()?lower_case}.vue';
</#list>
</#if>
<#if import_block??>${import_block}</#if>
......
......@@ -3,7 +3,15 @@ import { Vue, Component, Prop, Provide, Emit, Watch, Model } from 'vue-property-
import { CreateElement } from 'vue';
import { Subject, Subscription } from 'rxjs';
import { ControlInterface } from '@/interface/control';
import { UICounter,UIActionTool } from '@/utils';
import { UIActionTool,Util } from '@/utils';
<#if ctrl.getPSAppCounterRefs?? && ctrl.getPSAppCounterRefs()??>
<#list ctrl.getPSAppCounterRefs() as singleCounterRef>
<#if singleCounterRef.getPSAppCounter()??>
<#assign appCounter = singleCounterRef.getPSAppCounter()/>
import ${srfclassname('${appCounter.getCodeName()}')}CounterService from '@/counter/${srffilepath2(appCounter.getCodeName())}/${srffilepath2(appCounter.getCodeName())}-counter';
</#if>
</#list>
</#if>
<#if appde??>
import ${srfclassname('${appde.getCodeName()}')}Service from '@/service/${srffilepath2(appde.getCodeName())}/${srffilepath2(appde.getCodeName())}-service';
</#if>
......@@ -27,6 +35,7 @@ import ${srfclassname('${curAppEntity.getCodeName()}')}UIService from '@/uiservi
@Component({
components: {
<#if component_block??>${component_block}</#if>
}
})
export default class ${srfclassname('${ctrl.codeName}')}Base extends Vue implements ControlInterface {
......@@ -82,6 +91,33 @@ export default class ${srfclassname('${ctrl.codeName}')}Base extends Vue impleme
return '${ctrl.getControlType()}'
}
<#if ctrl.getPSAppCounterRefs?? && ctrl.getPSAppCounterRefs()??>
<#assign counterRefs = ''/>
<#list ctrl.getPSAppCounterRefs() as singleCounterRef>
<#if singleCounterRef.getPSAppCounter()??>
<#assign appCounter = singleCounterRef.getPSAppCounter()/>
<#assign counterRefs>${counterRefs}this.${srfclassname('${appCounter.getCodeName()}')}counterservice<#if singleCounterRef_has_next>,</#if></#assign>
/**
* ${srfclassname('${appCounter.getCodeName()}')}CounterService计数器服务对象
*
* @type {${srfclassname('${appCounter.getCodeName()}')}CounterService}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected ${srfclassname('${appCounter.getCodeName()}')}counterservice: ${srfclassname('${appCounter.getCodeName()}')}CounterService = new ${srfclassname('${appCounter.getCodeName()}')}CounterService();
</#if>
</#list>
/**
* 计数器服务对象集合
*
* @type {Array<*>}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected counterServiceArray:Array<any> = [${counterRefs}];
</#if>
/**
* 建构部件服务对象
*
......@@ -162,3 +198,19 @@ ${P.getLogicCode(uiAction, "LOGIC.vue").code}
let _this: any = this;
_this.$emit('closeview', args);
}
/**
* 计数器刷新
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public counterRefresh(){
const _this:any =this;
if(_this.counterServiceArray && _this.counterServiceArray.length >0){
_this.counterServiceArray.forEach((item:any) =>{
if(item.refreshData && item.refreshData instanceof Function){
item.refreshData();
}
})
}
}
<script lang='ts'>
import { Vue, Component, Prop, Provide, Emit, Watch, Model } from 'vue-property-decorator';
import { CreateElement } from 'vue';
import { Subject, Subscription } from 'rxjs';
import { ControlInterface } from '@/interface/control';
import { UIActionTool,Util } from '@/utils';
<#if ctrl.getPSAppCounterRefs?? && ctrl.getPSAppCounterRefs()??>
<#list ctrl.getPSAppCounterRefs() as singleCounterRef>
<#if singleCounterRef.getPSAppCounter()??>
<#assign appCounter = singleCounterRef.getPSAppCounter()/>
import ${srfclassname('${appCounter.getCodeName()}')}CounterService from '@/counter/${srffilepath2(appCounter.getCodeName())}/${srffilepath2(appCounter.getCodeName())}-counter';
</#if>
</#list>
</#if>
<#if appde??>
import ${srfclassname('${appde.getCodeName()}')}Service from '@/service/${srffilepath2(appde.getCodeName())}/${srffilepath2(appde.getCodeName())}-service';
</#if>
import ${srfclassname('${ctrl.codeName}')}Service from './${srffilepath2(ctrl.codeName)}-${ctrl.getControlType()?lower_case}-service';
<#if ctrl.getPSUIActions?? && ctrl.getPSUIActions()??>
<#list ctrl.getPSUIActions() as uiAction>
<#if uiAction.getPSAppDataEntity()??>
<#assign curAppEntity = uiAction.getPSAppDataEntity()/>
<#if !P.exists("importService", curAppEntity.getId(), "")>
import ${srfclassname('${curAppEntity.getCodeName()}')}UIService from '@/uiservice/${srffilepath2(curAppEntity.getCodeName())}/${srffilepath2(curAppEntity.getCodeName())}-ui-service';
</#if>
</#if>
</#list>
</#if>
<#-- 语言资源入口 -->
<#ibizinclude>
./LANGBASE.vue.ftl
</#ibizinclude>
<#if import_block??>${import_block}</#if>
@Component({
components: {
<#if component_block??>${component_block}</#if>
}
})
export default class <#if ctrl.getPSAppDataEntity()??>${srfclassname('${ctrl.getPSAppDataEntity().getCodeName()}')}</#if>${srfclassname('${ctrl.codeName}')}Base extends Vue implements ControlInterface {
/**
* 名称
*
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected name?: string;
/**
* 视图通讯对象
*
* @type {Subject<ViewState>}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected viewState!: Subject<ViewState>;
/**
* 应用上下文
*
* @type {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected context: any;
/**
* 视图参数
*
* @type {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected viewparams: any;
/**
* 视图状态事件
*
* @protected
* @type {(Subscription | undefined)}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected viewStateEvent: Subscription | undefined;
/**
* 获取部件类型
*
* @returns {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected getControlType(): string {
return '${ctrl.getControlType()}'
}
<#if ctrl.getPSAppCounterRefs?? && ctrl.getPSAppCounterRefs()??>
<#assign counterRefs = ''/>
<#list ctrl.getPSAppCounterRefs() as singleCounterRef>
<#if singleCounterRef.getPSAppCounter()??>
<#assign appCounter = singleCounterRef.getPSAppCounter()/>
<#assign counterRefs>${counterRefs}this.${srfclassname('${appCounter.getCodeName()}')}counterservice<#if singleCounterRef_has_next>,</#if></#assign>
/**
* ${srfclassname('${appCounter.getCodeName()}')}CounterService计数器服务对象
*
* @type {${srfclassname('${appCounter.getCodeName()}')}CounterService}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected ${srfclassname('${appCounter.getCodeName()}')}counterservice: ${srfclassname('${appCounter.getCodeName()}')}CounterService = new ${srfclassname('${appCounter.getCodeName()}')}CounterService();
</#if>
</#list>
/**
* 计数器服务对象集合
*
* @type {Array<*>}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected counterServiceArray:Array<any> = [${counterRefs}];
</#if>
/**
* 建构部件服务对象
*
* @type {${srfclassname('${ctrl.codeName}')}Service}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected service: ${srfclassname('${ctrl.codeName}')}Service = new ${srfclassname('${ctrl.codeName}')}Service({ $store: this.$store });
<#if appde??>
/**
* 实体服务对象
*
* @type {${srfclassname('${appde.getCodeName()}')}Service}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected appEntityService: ${srfclassname('${appde.getCodeName()}')}Service = new ${srfclassname('${appde.getCodeName()}')}Service({ $store: this.$store });
</#if>
<#if ctrl.getPSControls?? && ctrl.getPSControls()??>
<#list ctrl.getPSControls() as childCtrl>
<#if childCtrl.getControlType()??>
<#if childCtrl.getHookEventNames()??>
<#list childCtrl.getHookEventNames() as eventName>
/**
* ${childCtrl.name} 部件 ${eventName?lower_case} 事件
*
* @param {*} [args={}]
* @param {*} $event
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected ${childCtrl.name}_${eventName?lower_case}($event: any, $event2?: any) {
<#if childCtrl.getPSControlLogics(eventName)??>
<#list childCtrl.getPSControlLogics(eventName) as ctrlLogic>
<#if ctrlLogic.getLogicType?? && ctrlLogic.getLogicType() == "APPVIEWENGINE" && ctrlLogic.getPSAppViewEngine()??>
this.${ctrlLogic.getPSAppViewEngine().getName()}.onCtrlEvent('${childCtrl.name}', '${eventName?lower_case}', $event);
<#else>
<#if ctrlLogic.getEventArg()?? && ctrlLogic.getEventArg()?length gt 0>
if (Object.is($event.tag, '${ctrlLogic.getEventArg()}')) {
this.${ctrlLogic.name}($event, '<#if ctrlLogic.getLogicTag()?length gt 0>${ctrlLogic.getLogicTag()}</#if>', $event2);
}
<#else>
this.${ctrlLogic.name}($event, '<#if ctrlLogic.getLogicTag()?length gt 0>${ctrlLogic.getLogicTag()}</#if>', $event2);
</#if>
</#if>
</#list>
</#if>
}
</#list>
</#if>
</#if>
</#list>
</#if>
<#if ctrl.getPSAppViewLogics?? && ctrl.getPSAppViewLogics()??>
<#list ctrl.getPSAppViewLogics() as logic>
<#if logic.getLogicTrigger() == "CUSTOM" || logic.getLogicTrigger() == "CTRLEVENT">
${P.getLogicCode(logic, "LOGIC.vue").code}
</#if>
</#list>
</#if>
<#if ctrl.getPSUIActions?? && ctrl.getPSUIActions()??>
<#list ctrl.getPSUIActions() as uiAction>
<#if !uiAction.getPSAppDataEntity()??>
${P.getLogicCode(uiAction, "LOGIC.vue").code}
</#if>
</#list>
</#if>
/**
* 关闭视图
*
* @param {any[]} args
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected closeView(args: any[]): void {
let _this: any = this;
_this.$emit('closeview', args);
}
/**
* 计数器刷新
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public counterRefresh(){
const _this:any =this;
if(_this.counterServiceArray && _this.counterServiceArray.length >0){
_this.counterServiceArray.forEach((item:any) =>{
if(item.refreshData && item.refreshData instanceof Function){
item.refreshData();
}
})
}
}
......@@ -4,14 +4,18 @@
name='${ctrl.name}'
ref='${ctrl.name}'
:viewparams="viewparams"
:context="context"
:context="context"
<#if ctrl.getPSAppDataEntity()??>parentName = "${ctrl.getPSAppDataEntity().getCodeName()}"</#if>
<#if view.getViewType() == 'DEEDITVIEW4'>
:isShowSlot="false"
</#if>
<#if ctrl.getHookEventNames()??>
<#list ctrl.getHookEventNames() as eventName>
@${eventName?lower_case}='${ctrl.name}_${eventName?lower_case}($event)'
</#list>
</#if>
@closeview='closeView($event)'>
<#if view.hasPSControl('form')>
<#if view.getViewType() != 'DEEDITVIEW4' && view.hasPSControl('form')>
${P.getCtrlCode('form', 'CONTROL.html').code}
</#if>
</view_${ctrl.getName()}>
\ No newline at end of file
<#-- content -->
<#assign content>
:isSingleSelect="isSingleSelect"
:isSingleSelect="isSingleSelect"
<#if view.getViewType() == 'DEPICKUPGRIDVIEW'>
:selectedData="selectedData"
</#if>
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
<#if view.getViewType() == "DEGRIDVIEW" || view.getViewType() == "DEGRIDVIEW9">
<#if view.getViewType() == "DEGRIDVIEW" || view.getViewType() == "DEGRIDVIEW9">
:isOpenEdit="${view.isRowEditDefault()?c}"
:gridRowActiveMode="gridRowActiveMode"
@save="onSave"
</#if>
</#if>
updateAction="<#if ctrl.getUpdatePSControlAction()?? && ctrl.getUpdatePSControlAction().getPSAppDEMethod()??>${ctrl.getUpdatePSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
removeAction="<#if ctrl.getRemovePSControlAction()?? && ctrl.getRemovePSControlAction().getPSAppDEMethod()??>${ctrl.getRemovePSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
loaddraftAction="<#if ctrl.getGetDraftPSControlAction()?? && ctrl.getGetDraftPSControlAction().getPSAppDEMethod()??>${ctrl.getGetDraftPSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
loadAction="<#if ctrl.getGetPSControlAction()?? && ctrl.getGetPSControlAction().getPSAppDEMethod()??>${ctrl.getGetPSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
createAction="<#if ctrl.getCreatePSControlAction()?? && ctrl.getCreatePSControlAction().getPSAppDEMethod()??>${ctrl.getCreatePSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
fetchAction="<#if ctrl.getFetchPSControlAction()?? && ctrl.getFetchPSControlAction().getPSAppDEMethod()??>${ctrl.getFetchPSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
<#if view.getViewType() == 'DEGRIDEXPVIEW'>
:isSelectFirstDefault="true"
</#if>
<#if view.getPSAppViewLogics?? && view.getPSAppViewLogics()??>
<#list view.getPSAppViewLogics() as logic>
<#if logic.getPFLogicCodeType() == 'APP_NEWDATA'>
:newdata="newdata"
</#if>
<#if logic.getPFLogicCodeType() == 'APP_OPENDATA'>
:opendata="opendata"
</#if>
</#list>
</#if>
</#assign>
<#ibizinclude>
./DEFAULT.html.ftl
......
......@@ -10,6 +10,13 @@
*/
public getDataItems(): any[] {
return [
<#-- 表单保留字段start -->
{
name: 'srfwfmemo',
prop: 'srfwfmemo',
dataType: 'TEXT',
},
<#-- 表单保留字段end -->
<#-- 表单项 -->
<#if ctrl.getPSDEFormItems()??>
<#list ctrl.getPSDEFormItems() as dataitem>
......
......@@ -103,7 +103,7 @@ import ${srfclassname('${_appde.getCodeName()}')}Service from '@/service/${srffi
*/
@Errorlog
public wfstart(action: string,context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
data = this.handleDataWithKey(data);
data = this.handleWFData(data);
context = this.handleRequestData(action,context,data).context;
return new Promise((resolve: any, reject: any) => {
let result: Promise<any>;
......@@ -134,7 +134,7 @@ import ${srfclassname('${_appde.getCodeName()}')}Service from '@/service/${srffi
*/
@Errorlog
public wfsubmit(action: string,context: any = {}, data: any = {}, isloading?: boolean): Promise<any> {
data = this.handleDataWithKey(data);
data = this.handleWFData(data,true);
context = this.handleRequestData(action,context,data).context;
return new Promise((resolve: any, reject: any) => {
let result: Promise<any>;
......@@ -297,8 +297,7 @@ import ${srfclassname('${_appde.getCodeName()}')}Service from '@/service/${srffi
result = this.appEntityService.GetDraft(Context,Data, isloading);
}
result.then((response) => {
this.handleResponse(action, response, true);
this.mergeDefaults(response);
this.handleResponse(action, response, true);
resolve(response);
}).catch(response => {
reject(response);
......@@ -360,6 +359,9 @@ import ${srfclassname('${_appde.getCodeName()}')}Service from '@/service/${srffi
}
}
});
if(data && data.viewparams){
Object.assign(requestData,data.viewparams);
}
let tempContext:any = JSON.parse(JSON.stringify(context));
if(tempContext && tempContext.srfsessionid){
tempContext.srfsessionkey = tempContext.srfsessionid;
......@@ -368,74 +370,6 @@ import ${srfclassname('${_appde.getCodeName()}')}Service from '@/service/${srffi
return {context:tempContext,data:requestData};
}
/**
* 处理返回数据
*
* @param {string} action
* @param {*} response
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
public handleResponse(action: string, response: any,isCreate:boolean = false) {
response.data = this.handleResponseData(action, response.data,isCreate);
}
/**
* 处理返回数据
*
* @param {string} action
* @param {*} response
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
public handleResponseData(action: string, data: any = {},isCreate?:boolean){
let mode: any = this.getMode();
if (!mode && mode.getDataItems instanceof Function) {
return data;
}
let item: any = {};
let dataItems: any[] = mode.getDataItems();
dataItems.forEach(dataitem => {
let val = data.hasOwnProperty(dataitem.prop) ? data[dataitem.prop] : null;
if (!val) {
val = data.hasOwnProperty(dataitem.name) ? data[dataitem.name] : null;
}
if((isCreate === undefined || isCreate === null ) && Object.is(dataitem.dataType, 'GUID') && Object.is(dataitem.name, 'srfkey') && (val && !Object.is(val, ''))){
isCreate = true;
}
item[dataitem.name] = val;
});
if (isCreate) {
if(!item.srfuf){
Object.assign(item, {
srfuf: '0'
});
}
} else {
if(!item.srfuf){
Object.assign(item, {
srfuf: '1'
});
}
}
return item;
}
/**
* 合并配置的默认值
* @param {*}
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
public mergeDefaults(response:any = {}){
if(response.data){
<#list ctrl.getAllPSDEFormDetails() as formdetail><#t>
<#if formdetail.getCreateDV?? && formdetail.getCreateDV()??><#t>
<#if !(formdetail.getCreateDV() == '')><#t>
Object.assign(response.data,{'${formdetail.getCodeName()?lower_case}':'${formdetail.getCreateDV()}'});
</#if>
</#if>
</#list>
}
}
<#ibizinclude>
./SERVICE_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
......@@ -4,7 +4,17 @@
<tabs :animated="false" class='tabexppanel' name='${ctrl.name}' @on-click="tabPanelClick">
<#list ctrl.getPSControls() as tabviewpanel>
<tab-pane :index="${tabviewpanel_index}" name='${tabviewpanel.name}' tab='${ctrl.name}' class='<#if tabviewpanel.getPSSysCss?? && tabviewpanel.getPSSysCss()??>${tabviewpanel.getPSSysCss().getCssName()}</#if>'
label= '${tabviewpanel.getCaption()}' >
:label="(h) =>{
return h('div', [
h('span', '${tabviewpanel.getCaption()}'),
h('Badge', {
props: {
count: <#if tabviewpanel.getPSSysCounterRef()?? && tabviewpanel.getPSSysCounterRef().getPSAppCounter()??><#assign appCounter = tabviewpanel.getPSSysCounterRef().getPSAppCounter()/>${srfclassname('${appCounter.getCodeName()}')}counterservice.counterData.<#if tabviewpanel.getCounterId()??>${tabviewpanel.getCounterId()}</#if><#else>undefined</#if>,
type: 'primary'
}
})
])
}" >
${P.getCtrlCode(tabviewpanel, 'CONTROL.html').code}
</tab-pane>
</#list>
......@@ -50,7 +60,16 @@
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected activiedTabViewPanel: string = '<#list ctrl.getPSControls() as tabviewpanel><#if tabviewpanel_index==0>${tabviewpanel.name}</#if></#list>';
/**
* 分页视图面板数据变更
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public tabViewPanelDatasChange(){
this.counterRefresh();
}
/**
* vue 生命周期
*
......
......@@ -4,7 +4,8 @@
<${srffilepath2(embedddevedview.getCodeName())}
class='viewcontainer2'
:viewdata="JSON.stringify(context)"
:viewparam="JSON.stringify(viewparams)"
:viewparam="JSON.stringify(viewparams)"
@viewload="viewDatasChange($event)"
:viewDefaultUsage="false" >
</${srffilepath2(embedddevedview.getCodeName())}></#if>
</div>
......@@ -39,7 +40,7 @@
* @type {boolean}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected isActivied: boolean = false;
protected isActivied: boolean = true;
/**
* vue 生命周期
......@@ -62,15 +63,28 @@
if (!Object.is(tag, this.name)) {
return;
}
if (!this.isActivied) {
this.$nextTick(() => {
this.isActivied = true;
});
}
<#if view.getPSAppViewEngines()??>
this.$forceUpdate();
<#else>
this.isActivied = false;
this.$nextTick(() => {
this.isActivied = true;
});
</#if>
});
}
}
/**
* 视图数据变化
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected viewDatasChange($event:any){
this.$emit('viewpanelDatasChange',$event);
}
/**
* vue 生命周期
*
......
<#assign content>
@viewpanelDatasChange = "tabViewPanelDatasChange"
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
......@@ -4,15 +4,15 @@
<#if ctrl.render??>
${ctrl.render.code}
<#else>
<div v-for = "item in items" :key="item.srfmajortext" :class="['app-list-item', {'isSelect': item.isselected === true ? true : false}]" @click="handleClick" @dblclick="item">
<#if ctrl.getItemPSLayoutPanel()??>
<#assign panel = ctrl.getItemPSLayoutPanel()>
<layout_${panel.getName()} name='${panel.name}' data={item}></layout_${panel.getName()}>
<#elseif ctrl.itemRender??>
<div v-for = "item in items" :key="item.srfmajortext" :class="['app-list-item', {'isSelect': item.isselected === true ? true : false}]" @click="handleClick(item)" @dblclick="handleDblClick(item)">
<#if ctrl.getItemPSLayoutPanel()??>
<#assign panel = ctrl.getItemPSLayoutPanel()>
<layout_${panel.getName()} name='${panel.name}' :data="item"></layout_${panel.getName()}>
<#elseif ctrl.itemRender??>
${ctrl.itemRender.code}
<#else>
<#else>
{{item.srfmajortext}}
</#if>
</#if>
</div>
</#if>
</div>
......@@ -25,7 +25,7 @@
../@MACRO/CONTROL/CONTROL_HEADER-BASE.vue.ftl
</#ibizinclude>
/**
/**
* 获取多项数据
*
* @returns {any[]}
......@@ -46,35 +46,29 @@
}
/**
* 显示处理提示
* 是否默认选中第一条数据
*
* @type {boolean}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop({ default: true }) protected showBusyIndicator?: boolean;
@Prop({ default: false }) protected isSelectFirstDefault!: boolean;
/**
* 结果集
* 显示处理提示
*
* @type {string}
* @type {boolean}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected searchAction!: string;
// 加载
@Prop() protected loadAction!: string;
// 更新
@Prop() protected updateAction!: string;
// 删除
@Prop() protected removeAction!: string;
@Prop({ default: true }) protected showBusyIndicator?: boolean;
/**
* 当前页
* 部件行为--fetch
*
* @type {number}
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected pageNumber: number = 1;
@Prop() protected fetchAction!: string;
/**
* 当前页
......@@ -196,10 +190,10 @@
}
/**
* 加载更多
*
* @memberof Mob
*/
* 加载更多
*
* @memberof Mob
*/
protected loadMore(){
if(this.totalRecord>this.items.length)
{
......@@ -221,15 +215,15 @@
}
/**
* 表格数据加载
* 列表数据加载
*
* @private
* @param {*} [arg={}]
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
private load(opt: any = {}): void {
if(!this.loadAction){
this.$Notice.error({ title: '错误', desc: '${view.getName()}视图列表loadAction参数未配置' });
if(!this.fetchAction){
this.$Notice.error({ title: '错误', desc: '${view.getName()}视图列表fetchAction参数未配置' });
return;
}
const arg: any = {...opt};
......@@ -241,8 +235,8 @@
const parentdata: any = {};
this.$emit('beforeload', parentdata);
Object.assign(arg, parentdata);
const post: Promise<any> = this.service.search(this.loadAction, arg, this.showBusyIndicator);
Object.assign(arg,{viewparams:this.viewparams});
const post: Promise<any> = this.service.search(this.fetchAction, this.context?JSON.parse(JSON.stringify(this.context)):{}, arg, this.showBusyIndicator);
post.then((response: any) => {
if (!response || response.status !== 200) {
if (response.errorMessage) {
......@@ -251,15 +245,19 @@
return;
}
const data: any = response.data;
this.items = [];
if (Object.keys(data).length > 0) {
let datas = JSON.parse(JSON.stringify(data));
datas.map((item: any) => {
Object.assign(item, { isselected: false });
});
this.totalRecord = response.total;
this.items.push(...datas);
this.totalRecord = data.total;
}
this.$emit('load', this.items);
if(this.isSelectFirstDefault){
this.handleClick(this.items[0]);
}
}, (response: any) => {
if (response && response.status === 401) {
return;
......@@ -267,7 +265,7 @@
this.$Notice.error({ title: '错误', desc: response.errorMessage });
});
}
<#--
/**
* 删除
*
......@@ -307,8 +305,8 @@
datas.forEach((data: any) => {
keys.push(data.srfkey);
});
const post: Promise<any> = this.service.delete(this.removeAction, { ${ctrl.getPSAppDataEntity().codeName?lower_case}: keys.join(';') }, this.showBusyIndicator);
const context:any = JSON.parse(JSON.stringify(this.context));
const post: Promise<any> = this.service.delete(this.removeAction, Object.assign(context,{ ${ctrl.getPSAppDataEntity().codeName?lower_case}: keys.join(';') }),Object.assign({ ${ctrl.getPSAppDataEntity().codeName?lower_case}: keys.join(';') },{viewparams:this.viewparams}), this.showBusyIndicator);
return new Promise((resolve: any, reject: any) => {
post.then((response: any) => {
if (!response || response.status !== 200) {
......@@ -348,7 +346,7 @@
onCancel: () => { }
});
return removeData;
}
} -->
/**
* 选择数据
......
<#assign handler = ctrl.getPSAjaxControlHandler() />
<#-- content -->
<#assign content>
searchAction='search${handler.getPSDEDataSet().getCodeName()?lower_case}'
fetchAction='<#if ctrl.getFetchPSControlAction()?? && ctrl.getFetchPSControlAction().getPSAppDEMethod()??>${ctrl.getFetchPSControlAction().getPSAppDEMethod().getCodeName()}</#if>'
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
loadAction="loadAction"
<#if view.getViewType() == 'DELISTEXPVIEW'>
:isSelectFirstDefault="true"
</#if>
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
......
......@@ -9,10 +9,10 @@
line-height: 34px;
}
.app-list-item.isSelect {
background: #f3f3f3;
background: #ecf5ff;
}
.app-list-item:hover {
background: #f3f3f3;
background: #ecf5ff;
}
}
.app-list-empty {
......
......@@ -65,10 +65,6 @@
name:'page',
prop:'page'
},
{
name:'srfparentdata',
prop:'srfparentdata'
}
]
}
......
......@@ -2,10 +2,6 @@
../@MACRO/SERVICE/SERVICE_HEADER.ts.ftl
</#ibizinclude>
/**
* 查询数据
*
......@@ -18,7 +14,7 @@
*/
@Errorlog
public search(action: string, context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
const {data:Data,context:Context} = this.handleRequestData(action,context,data);
const {data:Data,context:Context} = this.handleRequestData(action,context,data,true);
return new Promise((resolve: any, reject: any) => {
const _appEntityService: any = this.appEntityService;
let result: Promise<any>;
......@@ -48,7 +44,7 @@
*/
@Errorlog
public delete(action: string, context: any = {},data: any = {}, isloading?: boolean): Promise<any> {
const {data:Data,context:Context} = this.handleRequestData(action,context,data);
const {data:Data,context:Context} = this.handleRequestData(action,context,data,true);
return new Promise((resolve: any, reject: any) => {
const _appEntityService: any = this.appEntityService;
let result: Promise<any>;
......@@ -66,8 +62,6 @@
});
}
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
此差异已折叠。
<#assign content>
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
<#if view.getViewType() == 'DELISTEXPVIEW'>
:viewUID="viewUID"
</#if>
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
.app-list-exp-bar {
> .ivu-split-horizontal {
> .ivu-split-trigger-con {
height: 100%;
width: 1px;
}
> .ivu-split-pane {
> div {
height: 100%;
overflow: auto;
display: flex;
flex-direction: column;
.list-exp-bar-header {
line-height: 50px;
border-bottom: 1px solid #ddd;
>div {
font-size: 18px;
i {
font-size: 20px;
margin-top: -2px;
}
}
}
.container-header{
display: flex;
justify-content: space-between;
align-items: center;
.search-container {
width: 30%;
height: 48px;
padding: 10px 10px 10px 0;
min-width: 200px;
max-width: 400px;
}
.toolbar-container{
padding: 4px;
}
}
.list-exp-bar-content {
<#-- 计算高度 -->
<#if ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 88px);
<#elseif ctrl.isShowTitleBar() && !ctrl.isEnableSearch()>
height: calc(100% - 40px);
<#elseif !ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 38px);
<#else>
height: 100%;
</#if>
overflow: auto;
padding: 16px 0;
margin-bottom: 10px;
}
.list-exp-bar-content2 {
height: 100%;
overflow: auto;
flex-grow: 1;
}
}
}
> .right-pane.ivu-split-pane {
> div {
padding-left: 10px;
}
}
> .left-pane.ivu-split-pane {
padding-right: 10px;
}
}
> .ivu-split-vertical{
> .ivu-split-pane {
> div {
height: 100%;
overflow: auto;
display: flex;
flex-direction: column;
.list-exp-bar-header {
line-height: 50px;
border-bottom: 1px solid #ddd;
>div {
font-size: 18px;
i {
font-size: 20px;
margin-top: -2px;
}
}
}
.container-header{
display: flex;
justify-content: space-between;
align-items: center;
.search-container {
width: 30%;
height: 48px;
padding: 10px 10px 10px 0;
min-width: 200px;
max-width: 400px;
}
.toolbar-container{
padding: 4px;
}
}
.list-exp-bar-content {
<#-- 计算高度 -->
<#if ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 88px);
<#elseif ctrl.isShowTitleBar() && !ctrl.isEnableSearch()>
height: calc(100% - 40px);
<#elseif !ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 38px);
<#else>
height: 100%;
</#if>
overflow: auto;
margin-bottom: 10px;
}
.list-exp-bar-content2 {
height: 100%;
overflow: auto;
flex-grow: 1;
}
}
}
> .top-pane.ivu-split-pane {
> div {
padding-bottom: 10px;
}
}
> .bottom-pane.ivu-split-pane {
padding-top: 10px;
}
}
}
<#ibizinclude>
../@MACRO/CSS/DEFAULT.less.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/CONTROL/CONTROL.vue.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/MODEL/MODEL_HEADER.ts.ftl
</#ibizinclude>
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof ${srfclassname('${ctrl.getCodeName()}')}${srfclassname('${ctrl.name}')}Mode
*/
public getDataItems(): any[] {
return [
]
}
<#ibizinclude>
../@MACRO/MODEL/MODEL_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_HEADER.ts.ftl
</#ibizinclude>
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
CTRLTYPE=LISTEXPBAR
\ No newline at end of file
此差异已折叠。
<#assign content>
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
<#if view.getViewType() == 'DEDATAVIEWEXPVIEW'>
:viewUID="viewUID"
</#if>
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
.app-dataview-exp-bar {
> .ivu-split-horizontal {
> .ivu-split-trigger-con {
height: 100%;
width: 1px;
}
> .ivu-split-pane {
> div {
height: 100%;
overflow: auto;
display: flex;
flex-direction: column;
.dataview-exp-bar-header {
line-height: 50px;
border-bottom: 1px solid #ddd;
>div {
font-size: 18px;
i {
font-size: 20px;
margin-top: -2px;
}
}
}
.container-header{
display: flex;
justify-content: space-between;
align-items: center;
.search-container {
width: 30%;
height: 48px;
padding: 10px 10px 10px 0;
min-width: 200px;
max-width: 400px;
}
.toolbar-container{
padding: 4px;
}
}
.dataview-exp-bar-content {
<#-- 计算高度 -->
<#if ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 88px);
<#elseif ctrl.isShowTitleBar() && !ctrl.isEnableSearch()>
height: calc(100% - 40px);
<#elseif !ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 38px);
<#else>
height: 100%;
</#if>
overflow: auto;
padding: 16px 0;
margin-bottom: 10px;
}
.dataview-exp-bar-content2 {
height: 100%;
overflow: auto;
flex-grow: 1;
}
}
}
> .right-pane.ivu-split-pane {
> div {
padding-left: 10px;
}
}
> .left-pane.ivu-split-pane {
padding-right: 10px;
}
}
> .ivu-split-vertical{
> .ivu-split-pane {
> div {
height: 100%;
.dataview-exp-bar-header {
line-height: 50px;
border-bottom: 1px solid #ddd;
>div {
font-size: 18px;
i {
font-size: 20px;
margin-top: -2px;
}
}
}
.container-header{
display: flex;
justify-content: space-between;
align-items: center;
.search-container {
width: 30%;
height: 48px;
padding: 10px 10px 10px 0;
min-width: 200px;
max-width: 400px;
}
.toolbar-container{
padding: 4px;
}
}
.dataview-exp-bar-content {
<#-- 计算高度 -->
<#if ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 88px);
<#elseif ctrl.isShowTitleBar() && !ctrl.isEnableSearch()>
height: calc(100% - 40px);
<#elseif !ctrl.isShowTitleBar() && ctrl.isEnableSearch()>
height: calc(100% - 38px);
<#else>
height: 100%;
</#if>
overflow: auto;
margin-bottom: 10px;
}
.dataview-exp-bar-content2 {
height: 100%;
overflow: auto;
flex-grow: 1;
}
}
}
> .top-pane.ivu-split-pane {
> div {
padding-bottom: 10px;
}
}
> .bottom-pane.ivu-split-pane {
padding-top: 10px;
}
}
}
<#ibizinclude>
../@MACRO/CSS/DEFAULT.less.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/CONTROL/CONTROL.vue.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/MODEL/MODEL_HEADER.ts.ftl
</#ibizinclude>
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof ${srfclassname('${ctrl.getCodeName()}')}${srfclassname('${ctrl.name}')}Mode
*/
public getDataItems(): any[] {
return [
]
}
<#ibizinclude>
../@MACRO/MODEL/MODEL_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_HEADER.ts.ftl
</#ibizinclude>
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
CTRLTYPE=DATAVIEWEXPBAR
\ No newline at end of file
<template>
<layout class="app-wizard">
<#if ctrl.getPSDEWizard?? && ctrl.getPSDEWizard()?? && ctrl.getPSDEWizard().getPSDEWizardSteps?? && ctrl.getPSDEWizard().getPSDEWizardSteps()??>
<el-steps class="wizard-steps" :active="wizardForms.indexOf(activeForm)" finish-status="success">
<#list ctrl.getPSDEWizard().getPSDEWizardSteps() as step>
<el-step title="${step.getTitle()}"></el-step>
</#list>
</el-steps>
</#if>
<i-content class="app-wizard-content">
<#if ctrl.getPSDEEditForms()??>
<#list ctrl.getPSDEEditForms() as form>
......@@ -47,7 +54,7 @@
@Prop() protected initAction!: string;
/**
* 部件行为--remove
* 部件行为--finish
*
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
......@@ -69,7 +76,7 @@
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public getDatas(): any[] {
return [];
return [this.formParam];
}
/**
......@@ -79,7 +86,7 @@
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public getData(): any {
return null;
return this.formParam;
}
/**
......@@ -185,11 +192,11 @@
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public regFormActions() {
<#if ctrl.getPSDEWizard()?? && ctrl.getPSDEWizard().getPSDEWizardForms()??>
<#if ctrl.getPSDEWizard()?? && ctrl.getPSDEWizard().getPSDEWizardForms()??>
<#list ctrl.getPSDEWizard().getPSDEWizardForms() as form>
this.regFormAction('${ctrl.name}_form_${form.getFormTag()}', [<#if form.getStepActions()??><#list form.getStepActions() as action><#if action_index gt 0>,</#if>'${action}'</#list></#if>]);
</#list>
</#if>
</#if>
}
/**
......@@ -211,7 +218,8 @@
<#if ctrl.getPSDEWizard()?? && ctrl.getPSDEWizard().getInitPSDEAction()??>
<#assign action = ctrl.getPSDEWizard().getInitPSDEAction()>
const arg: any = { ...opt };
const post: Promise<any> = this.service.init(this.initAction, this.context, arg, this.showBusyIndicator);
Object.assign(arg,{viewparams:this.viewparams});
const post: Promise<any> = this.service.init(this.initAction, JSON.parse(JSON.stringify(this.context)), arg, this.showBusyIndicator);
post.then((response: any) => {
if (response && response.status === 200) {
this.formParam = response.data;
......@@ -250,7 +258,8 @@
<#assign action = ctrl.getPSDEWizard().getFinishPSDEAction()>
let arg: any = {};
Object.assign(arg, this.formParam);
const post: Promise<any> = this.service.finish(this.initAction, this.context, arg, this.showBusyIndicator);
Object.assign(arg,{viewparams:this.viewparams});
const post: Promise<any> = this.service.finish(this.finishAction, JSON.parse(JSON.stringify(this.context)), arg, this.showBusyIndicator);
post.then((response: any) => {
if (response && response.status === 200) {
const data = response.data;
......@@ -289,12 +298,7 @@
Object.assign(this.formParam, args);
if(Object.is(this.curState, 'NEXT')) {
this.historyForms.push(name);
if(args.srfnextform) {
this.activeForm = '${ctrl.name}_form_' + args.srfnextform;
setTimeout(() => {
this.formLoad();
}, 1);
} else if (this.getNextForm()) {
if (this.getNextForm()) {
this.activeForm = this.getNextForm();
setTimeout(() => {
this.formLoad();
......@@ -302,8 +306,7 @@
} else {
this.doFinish();
}
}
if(Object.is(this.curState, 'FINISH')) {
}else if(Object.is(this.curState, 'FINISH')) {
this.doFinish();
}
}
......@@ -380,7 +383,7 @@
}
/**
* 是否
* 是否
*
* @param {string} type
* @memberof ${srfclassname('${ctrl.codeName}')}
......@@ -396,4 +399,8 @@
<#ibizinclude>
../@MACRO/CONTROL/CONTROL_BOTTOM-BASE.vue.ftl
</#ibizinclude>
<#ibizinclude>
../@MACRO/CONTROL/CONTROL-BASE.style.ftl
</#ibizinclude>
\ No newline at end of file
.app-wizard {
background: #fff;
height: 100%;
.wizard-steps{
padding: 10px 50px;
border-bottom: 1px solid #ddd;
margin-bottom: 10px;
.el-step__head.is-process{
border-color: #7e8187;
color: #7e8187;
}
.el-step__title.is-process{
color: #7e8187;
}
.el-step__head.is-success{
border-color: #1890ff;
color: #1890ff;
}
.el-step__title.is-success{
color: #1890ff;
}
}
.app-wizard-content{
height: 100%;
overflow-y: auto;
......
<template>
<div class='items multieditviewpanel'>
<div v-for="item in items" class='item' :key="item.id">
<div v-for="(item,index) in items" class='item' :key="index">
<#if ctrl.getEmbeddedPSAppView()??>
<${srffilepath2(ctrl.getEmbeddedPSAppView().getCodeName())}
class="viewcontainer2"
:viewdata ="viewdata(item)"
:viewdata="toString(item.viewdata)"
:viewparam="toString(item.viewparam)"
:viewDefaultUsage="false"
:panelState="panelState"
@viewdataschange="viewDataChange"
......@@ -124,14 +125,15 @@
}
}
/**
* 视图数据
* 对象转字符串
*
* @type {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected viewdata(item:any): string{
return JSON.stringify(item.viewdata);
protected toString(item:any): string{
return JSON.stringify(item);
}
/**
......@@ -254,6 +256,29 @@
}
}
/**
* vue 生命周期
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected destroyed() {
this.afterDestroy();
}
/**
* 执行destroyed后的逻辑
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected afterDestroy() {
if (this.viewStateEvent) {
this.viewStateEvent.unsubscribe();
}
<#if destroyed_block??>
${destroyed_block}
</#if>
}
/**
* 保存数据
*
......@@ -281,7 +306,7 @@
datas.forEach((arg: any) => {
let id: string = arg[parameterName] ? arg[parameterName] : this.$util.createUUID();
let item: any = { id: id, viewdata: {} };
let item: any = { id: id, viewdata: {}, viewparam: {} };
Object.assign(item.viewdata, this.$viewTool.getIndexViewParam());
Object.assign(item.viewdata, this.context);
......@@ -300,6 +325,9 @@
Object.assign(item.viewdata, { [parameterName]: arg[parameterName] });
}
});
//合并视图参数
Object.assign(item.viewparam, this.viewparams);
this.items.push(item);
});
}
......@@ -317,9 +345,9 @@
return;
}
let arg: any = {};
Object.assign(arg, data);
Object.assign(arg, data,{viewparams:this.viewparams});
this.items = [];
const promice: Promise<any> = this.service.get(this.fetchAction,this.context,arg, this.showBusyIndicator);
const promice: Promise<any> = this.service.get(this.fetchAction,JSON.parse(JSON.stringify(this.context)),arg, this.showBusyIndicator);
promice.then((response: any) => {
if (!response.status || response.status !== 200) {
if (response.errorMessage) {
......@@ -351,7 +379,7 @@
this.$Notice.error({ title: '错误', desc: '${view.getName()}视图多编辑视图面板loaddraftAction参数未配置' });
return;
}
const promice: Promise<any> = this.service.loadDraft(this.loaddraftAction,this.context,{}, this.showBusyIndicator);
const promice: Promise<any> = this.service.loadDraft(this.loaddraftAction,JSON.parse(JSON.stringify(this.context)),{viewparams:this.viewparams}, this.showBusyIndicator);
promice.then((response: any) => {
if (!response.status || response.status !== 200) {
if (response.errorMessage) {
......@@ -445,29 +473,6 @@
this.setViewDirty(item, $event);
}
/**
* vue 生命周期
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected destroyed() {
this.afterDestroy();
}
/**
* 执行destroyed后的逻辑
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected afterDestroy() {
if (this.viewStateEvent) {
this.viewStateEvent.unsubscribe();
}
<#if destroyed_block??>
${destroyed_block}
</#if>
}
<#ibizinclude>
../@MACRO/CONTROL/CONTROL_BOTTOM-BASE.vue.ftl
</#ibizinclude>
......
<#ibizinclude>./MACRO.ftl</#ibizinclude>
<#ibizinclude>
../@MACRO/CONTROL/LANGBASE.vue.ftl
</#ibizinclude>
......@@ -5,23 +6,27 @@
<#if item.getTooltip()?? && item.getTooltip() != ''>
<tooltip :transfer="true" :max-width="600">
<#if deuiaction.getUIActionTag() == 'ExportExcel'>
<app-export-excel :item="toolBarModels.${item.name}" @exportexcel="${ctrl.name}_click({ tag: '${item.name}' }, $event)"></app-export-excel>
<app-export-excel :item="toolBarModels.${item.name}" :caption="$t('${langbase}.${item.name}.caption')" @exportexcel="${ctrl.name}_click({ tag: '${item.name}' }, $event)"></app-export-excel>
<#else>
<i-button v-show="toolBarModels.${item.name}.visabled" :disabled="toolBarModels.${item.name}.disabled" class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>' @click="${ctrl.name}_click({ tag: '${item.name}' }, $event)">
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
</i-button>
<@badge item>
<i-button v-show="toolBarModels.${item.name}.visabled" :disabled="toolBarModels.${item.name}.disabled" class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>' @click="${ctrl.name}_click({ tag: '${item.name}' }, $event)">
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
</i-button>
</@badge>
</#if>
<div slot='content'>{{<#if langbase??>$t('${langbase}.${item.name}.tip')<#else>'${item.getTooltip()}'</#if>}}</div>
</tooltip>
<#else>
<#if deuiaction.getUIActionTag() == 'ExportExcel'>
<app-export-excel :item="toolBarModels.${item.name}" @exportexcel="${ctrl.name}_click({ tag: '${item.name}' }, $event)"></app-export-excel>
<app-export-excel :item="toolBarModels.${item.name}" :caption="$t('${langbase}.${item.name}.caption')" @exportexcel="${ctrl.name}_click({ tag: '${item.name}' }, $event)"></app-export-excel>
<#else>
<i-button v-show="toolBarModels.${item.name}.visabled" :disabled="toolBarModels.${item.name}.disabled" class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>' @click="${ctrl.name}_click({ tag: '${item.name}' }, $event)">
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
</i-button>
<@badge item>
<i-button v-show="toolBarModels.${item.name}.visabled" :disabled="toolBarModels.${item.name}.disabled" class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>' @click="${ctrl.name}_click({ tag: '${item.name}' }, $event)">
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
</i-button>
</@badge>
</#if>
</#if>
<#ibizinclude>./MACRO.ftl</#ibizinclude>
<#ibizinclude>
../@MACRO/CONTROL/LANGBASE.vue.ftl
</#ibizinclude>
<dropdown v-show="toolBarModels.${item.name}.visabled" trigger='click'>
<#if item.getTooltip()?? && item.getTooltip() != ''>
<tooltip :transfer="true" :max-width="600">
<i-button class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>'>
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
<icon type="ios-arrow-down"></icon>
</i-button>
<@badge item>
<i-button class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>'>
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
<icon type="ios-arrow-down"></icon>
</i-button>
</@badge>
<div slot='content'><#if langbase??>{{<#if langbase??>$t('${langbase}.${item.name}.tip')<#else>'${item.getTooltip()}'</#if>}}</#if></div>
</tooltip>
<#else>
<i-button class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>'>
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
<icon type="ios-arrow-down"></icon>
</i-button>
<@badge item>
<i-button class='<#if item.getPSSysCss()??> ${item.getPSSysCss().getCssName()}</#if>'>
<#if item.isShowIcon()><i class='<#if item.getPSSysImage()??><#assign img=item.getPSSysImage()><#if img.getCssClass()?? && (img.getCssClass()?length gt 0)>${img.getCssClass()}</#if></#if>'></i></#if>
<#if item.isShowCaption()><span class='caption'>{{<#if langbase??>$t('${langbase}.${item.name}.caption')<#else>'${item.getCaption()}'</#if>}}</span></#if>
<icon type="ios-arrow-down"></icon>
</i-button>
</@badge>
</#if>
<#if item.getPSDEToolbarItems()??>
<dropdown-menu slot='list'>
......
<#assign deuiaction=item.getPSUIAction()>
<#if deuiaction.getUIActionTag() == 'ExportExcel'>
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', caption: '${item.caption}', disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '<#if deuiaction.getDataAccessAction()??>${deuiaction.getDataAccessAction()}</#if>', uiaction: { tag: '${deuiaction.getUIActionTag()}', target: '${deuiaction.getActionTarget()}' }<#if view.hasPSControl("GRID")><#assign gridhandler = view.getPSControl("GRID").getPSAjaxControlHandler()>, MaxRowCount: <#if gridhandler?? && gridhandler.getPSDEDataExport()??>${gridhandler.getPSDEDataExport().getMaxRowCount()?c}<#elseif sys.getDEDataExportMaxRowCount() gt 0>${sys.getDEDataExportMaxRowCount()?c}<#else>10000</#if></#if> },
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', <#if item.isShowCaption()>caption: '${item.caption}',</#if> disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '<#if deuiaction.getDataAccessAction()??>${deuiaction.getDataAccessAction()}</#if>', uiaction: { tag: '${deuiaction.getUIActionTag()}', target: '${deuiaction.getActionTarget()}' }<#if view.hasPSControl("GRID")><#assign gridhandler = view.getPSControl("GRID").getPSAjaxControlHandler()>, MaxRowCount: <#if gridhandler?? && gridhandler.getPSDEDataExport()??>${gridhandler.getPSDEDataExport().getMaxRowCount()?c}<#elseif sys.getDEDataExportMaxRowCount() gt 0>${sys.getDEDataExportMaxRowCount()?c}<#else>10000</#if></#if> },
<#elseif deuiaction.getUIActionTag() == 'ToggleRowEdit'>
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', caption: '${item.caption}', disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '<#if deuiaction.getDataAccessAction()??>${deuiaction.getDataAccessAction()}</#if>', uiaction: { tag: '${deuiaction.getUIActionTag()}', target: '${deuiaction.getActionTarget()}' } },
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', <#if item.isShowCaption()>caption: '${item.caption}', </#if>disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '<#if deuiaction.getDataAccessAction()??>${deuiaction.getDataAccessAction()}</#if>', uiaction: { tag: '${deuiaction.getUIActionTag()}', target: '${deuiaction.getActionTarget()}' } },
<#else>
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', caption: '${item.caption}', disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '<#if deuiaction.getDataAccessAction()??>${deuiaction.getDataAccessAction()}</#if>', uiaction: { tag: '${deuiaction.getUIActionTag()}', target: '${deuiaction.getActionTarget()}' } },
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', <#if item.isShowCaption()>caption: '${item.caption}', </#if>disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '<#if deuiaction.getDataAccessAction()??>${deuiaction.getDataAccessAction()}</#if>', uiaction: { tag: '${deuiaction.getUIActionTag()}', target: '${deuiaction.getActionTarget()}' } },
</#if>
\ No newline at end of file
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', caption: '${item.caption}', disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '', uiaction: { } },
${item.getName()?lower_case}: { name: '${item.getName()?lower_case}', <#if item.isShowCaption()>caption: '${item.caption}', </#if>disabled: false, type: '${item.getItemType()}', visabled: true, dataaccaction: '', uiaction: { } },
<#if item.getPSDEToolbarItems()??>
<#list item.getPSDEToolbarItems() as toolbarItem>
${P.getPartCode(toolbarItem).code}
......
<#macro badge item>
<#if item.getPSUIAction?? && item.getPSUIAction()?? && item.getPSUIAction().getPSAppCounter?? && item.getPSUIAction().getPSAppCounter()??>
<#assign uiaction = item.getPSUIAction() />
<#assign counter = uiaction.getPSAppCounter() />
<Badge type="primary" :count="${srfclassname('${counter.getCodeName()}')}counterservice.counterData.<#if uiaction.getCounterId()??>${uiaction.getCounterId()}</#if>">
<#nested>
</Badge>
<#else>
<#nested>
</#if>
</#macro>
\ No newline at end of file
......@@ -66,7 +66,7 @@
<template v-else>
<template v-if="item1.type =='MENUITEM'">
<el-menu-item v-show="!item1.hidden" :index="item1.name" :key="item1.id">
<template v-if="item1.icon && item.icon != ''">
<template v-if="item1.icon && item1.icon != ''">
<img :src="item1.icon" class='app-menu-icon' />
</template>
<template v-else-if="item1.iconcls && item1.iconcls != ''">
......@@ -92,7 +92,7 @@
<template v-else>
<template v-if="item0.type =='MENUITEM'">
<el-menu-item v-show="!item0.hidden" :index="item0.name" :key="item0.id">
<template v-if="item0.icon && item.icon != ''">
<template v-if="item0.icon && item0.icon != ''">
<img :src="item0.icon" class='app-menu-icon' />
</template>
<template v-else-if="item0.iconcls && item0.iconcls != ''">
......@@ -260,17 +260,6 @@ import ${srfclassname('${ctrl.codeName}')}Model from './${srffilepath2(ctrl.code
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Provide() trigger: string = 'click';
<#if ctrl.getPSSysCounter?? && ctrl.getPSSysCounter()??>
<#assign sysCounter = ctrl.getPSSysCounter()/>
/**
* 计数器对象
*
* @type {(UICounter | null)}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected ${sysCounter.getCodeName()}: UICounter | null = null;
</#if>
/**
* 计数器数据
......@@ -294,19 +283,6 @@ import ${srfclassname('${ctrl.codeName}')}Model from './${srffilepath2(ctrl.code
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected afterCreated(){
<#if ctrl.getPSSysCounter?? && ctrl.getPSSysCounter()??>
<#assign sysCounter = ctrl.getPSSysCounter()/>
this.${sysCounter.getCodeName()} = new UICounter({
name: '${sysCounter.getCodeName()}',
counterId: '${sysCounter.id}',
timer: ${sysCounter.timer?c},
url: ``,
});
this.${sysCounter.getCodeName()}.uiCounterData.subscribe((data: any) => {
this.counterdata = {};
Object.assign(this.counterdata, data);
});
</#if>
if (Object.is(this.mode, 'horizontal')) {
this.trigger = 'hover';
}
......@@ -338,13 +314,6 @@ import ${srfclassname('${ctrl.codeName}')}Model from './${srffilepath2(ctrl.code
if (this.viewStateEvent) {
this.viewStateEvent.unsubscribe();
}
<#if ctrl.getPSSysCounter?? && ctrl.getPSSysCounter()??>
<#assign sysCounter = ctrl.getPSSysCounter()/>
if(this.${sysCounter.getCodeName()}) {
this.${sysCounter.getCodeName()}.uiCounterData.unsubscribe();
this.${sysCounter.getCodeName()}.close();
}
</#if>
<#if destroyed_block??>
${destroyed_block}
</#if>
......@@ -543,7 +512,7 @@ ${P.getLogicCode(singleFuncs,"LOGIC.vue").code}
private dataProcess(items: any[]): void {
items.forEach((_item: any) => {
if (_item.expanded) {
this.defaultOpeneds.push(_item.id);
this.defaultOpeneds.push(_item.name);
}
if (_item.items && _item.items.length > 0) {
this.dataProcess(_item.items)
......
/*** BRGIN:菜单样式 ***/
.app-app-menu {
overflow: auto;
overflow-y: auto;
overflow-x: hidden;
height: calc(100% - 58px);
> .el-menu {
border-right: 0;
......@@ -83,6 +84,11 @@
box-shadow: 0 0 0 0px #fff;
}
}
> span{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.ivu-divider-horizontal {
width: calc(100% - 12px);
......
......@@ -2,24 +2,22 @@
../@MACRO/CSS/DEFAULT.less.ftl
</#ibizinclude>
/*** BEGIN:potal菜单 ***/
.porlet{
>.app-app-menu{
>.ivu-row{
.ivu-card{
.ivu-card-body{
>p{
>.app-menus{
display: flex;
flex-wrap: wrap;
>div{
width: 100%;
margin-right: 10px;
.ivu-card-body{
>div{
display: flex;
>span{
margin-right: 12px;
}
.app-app-menu{
>.ivu-row{
.ivu-card{
.ivu-card-body{
>p{
>.app-menus{
display: flex;
flex-wrap: wrap;
>div{
width: 100%;
margin-right: 10px;
.ivu-card-body{
>div{
display: flex;
>span{
margin-right: 12px;
}
}
}
......@@ -29,4 +27,4 @@
}
}
}
}
\ No newline at end of file
}
......@@ -17,7 +17,8 @@ ${item.render.code}
</#list>
</#if>
]"
:viewParam="context"
:context="context"
:viewparams="viewparams"
parameterName='${appde.getCodeName()?lower_case}'
refviewtype='<#if refView.getPSViewType()??>${refView.getPSViewType().getId()}</#if>'
refreshitems='<#if item.getRefreshItems()??>${item.getRefreshItems()}</#if>'
......
<#ibizinclude>
../../@MACRO/LANG_FUN.ftl
</#ibizinclude>
<template>
${P.getPartCode(item,'FORM').code}
</template>
......@@ -483,7 +486,7 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
<#-- END:是否应用实体视图 -->
const view: any = {
viewname: '${srffilepath2(dataview.getCodeName())}',
title: '${dataview.getTitle()}',
title: this.<@getViewLanguageTitle dataview />,
height: ${dataview.getHeight()?c},
width: ${dataview.getWidth()?c},
<#if formdetail.getParamViewParamJO()??>
......@@ -695,8 +698,8 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
return;
}
const arg: any = { ...opt };
Object.assign(arg,this.viewparams);
const get: Promise<any> = this.service.get(this.loadAction,this.context, arg, this.showBusyIndicator);
Object.assign(arg,{viewparams:this.viewparams});
const get: Promise<any> = this.service.get(this.loadAction,JSON.parse(JSON.stringify(this.context)), arg, this.showBusyIndicator);
get.then((response: any) => {
if (response && response.status === 200) {
const data = response.data;
......@@ -732,8 +735,8 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
return;
}
const arg: any = { ...opt } ;
Object.assign(arg,this.viewparams);
let post: Promise<any> = this.service.loadDraft(this.loaddraftAction,this.context, arg, this.showBusyIndicator);
Object.assign(arg,{viewparams:this.viewparams});
let post: Promise<any> = this.service.loadDraft(this.loaddraftAction,JSON.parse(JSON.stringify(this.context)), arg, this.showBusyIndicator);
post.then((response: any) => {
if (!response.status || response.status !== 200) {
if (response.errorMessage) {
......@@ -788,8 +791,8 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
const data = this.getValues();
Object.assign(arg, data);
const action: any = Object.is(data.srfuf, '1') ? this.updateAction : this.createAction;
Object.assign(arg,this.viewparams);
const post: Promise<any> = this.service.add(action,this.context, arg, this.showBusyIndicator);
Object.assign(arg,{viewparams:this.viewparams});
const post: Promise<any> = this.service.add(action,JSON.parse(JSON.stringify(this.context)), arg, this.showBusyIndicator);
post.then((response: any) => {
if (!response.status || response.status !== 200) {
if (response.errorMessage) {
......@@ -815,13 +818,6 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
this.$Notice.error({ title: '错误', desc: '系统异常' });
return;
}
const { data: _data } = response;
if (Object.is(_data.status, 'BAD_REQUEST') && _data.parameters && _data.parameters.fieldErrors) {
this.resetValidates();
this.fillValidates(_data.parameters.fieldErrors)
}
this.$Notice.error({ title: _data.title, desc: _data.message });
});
}
......@@ -844,8 +840,8 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
const data = this.getValues();
Object.assign(arg, data);
const action: any = Object.is(data.srfuf, '1') ? this.updateAction : this.createAction;
Object.assign(arg,this.viewparams);
const post: Promise<any> = this.service.add(action,this.context,arg, this.showBusyIndicator);
Object.assign(arg,{viewparams:this.viewparams});
const post: Promise<any> = this.service.add(action,JSON.parse(JSON.stringify(this.context)),arg, this.showBusyIndicator);
return new Promise((resolve: any, reject: any) => {
post.then((response: any) => {
if (!response.status || response.status !== 200) {
......@@ -880,13 +876,6 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
reject(response);
return;
}
const { data: _data } = response;
if (Object.is(_data.status, 'BAD_REQUEST') && _data.parameters && _data.parameters.fieldErrors) {
this.resetValidates();
this.fillValidates(_data.parameters.fieldErrors)
}
this.$Notice.error({ title: _data.title, desc: _data.message });
reject(response);
});
})
......
<template>
<div class = "drtab">
<tabs :animated='false' class='app-dr-tab' name='name' @on-click="tabPanelClick">
<#list ctrl.getRootItem().getAllItems() as dritem>
<tab-pane :index='${dritem_index?c}' name='${dritem.getId()?lower_case}' tab='name' class='' :disabled='false'
<#list ctrl.getRootItem().getAllItems() as dritem>
<tab-pane <#if dritem_index == 0>v-if="isShowSlot"</#if> :index='${dritem_index?c}' name='${dritem.getId()?lower_case}' tab='name' class='' :disabled='items[${dritem_index?c}].disabled'
label='${dritem.text}'>
<#if dritem.getId()?lower_case == 'form'>
<#if dritem.getId()?lower_case == 'form'>
<div class='main-data'>
<slot></slot>
</div>
<#else>
<#else>
<component
v-if="Object.is(this.selection.id, '${dritem.getId()?lower_case}') && this.selection.view && !Object.is(this.selection.view.viewname, '')"
:is="selection.view.viewname"
......@@ -18,9 +18,9 @@
:viewDefaultUsage="false"
:key="this.$util.createUUID()">
</component>
</#if>
</#if>
</tab-pane>
</#list>
</#list>
</tabs>
</div>
......@@ -28,12 +28,27 @@
<#ibizinclude>
../@MACRO/CONTROL/CONTROL_HEADER-BASE.vue.ftl
</#ibizinclude>
/**
* 是否显示插槽
*
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
@Prop({default:true}) protected isShowSlot?: boolean;
/**
* 应用实体参数名称
*
* @type string
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
@Prop() protected parentName!: string;
/**
* 获取多项数据
*
* @returns {any[]}
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
public getDatas(): any[] {
return this.items;
......@@ -43,7 +58,7 @@
* 获取单项树
*
* @returns {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
public getData(): any {
return this.selection;
......@@ -53,7 +68,7 @@
* 数据选中项
*
* @type {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected selection: any = {};
......@@ -62,7 +77,7 @@
*
* @private
* @type {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
private parentData: any = {};
......@@ -70,7 +85,7 @@
* 关系栏数据项
*
* @type {any[]}
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected items: any[] = [
<#list ctrl.getRootItem().getAllItems() as dritem>
......@@ -87,7 +102,7 @@
/**
* 生命周期
*
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected created(): void {
this.afterCreated();
......@@ -96,7 +111,7 @@
/**
* 执行created后的逻辑
*
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected afterCreated(){
if (this.viewState) {
......@@ -105,8 +120,7 @@
return;
}
if (Object.is('state', action)) {
Object.assign(this.parentData, data);
const state = !this.parentData.${ctrl.getPSAppDataEntity().getCodeName()?lower_case} ? true : false;
const state = !this.context.${ctrl.getPSAppDataEntity().getCodeName()?lower_case} ? true : false;
this.setItemDisabled(state);
}
});
......@@ -119,7 +133,7 @@
/**
* vue 生命周期
*
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected destroyed() {
this.afterDestroy();
......@@ -128,7 +142,7 @@
/**
* 执行destroyed后的逻辑
*
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected afterDestroy() {
if (this.viewStateEvent) {
......@@ -145,7 +159,7 @@
* @private
* @param {*} [arg={}]
* @returns {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
private getDRTabItem(arg: any = {}): any {
let expmode = arg.nodetype.toUpperCase();
......@@ -170,7 +184,7 @@
* 设置关系项状态
*
* @param {boolean} state
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected setItemDisabled(state: boolean): void {
this.items.forEach((item: any) => {
......@@ -188,7 +202,7 @@
* @private
* @param {string} id
* @returns {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
private getItem(id: string): any {
const arr: any[] = this.items.filter((_item: any) => Object.is(_item.id, id));
......@@ -202,7 +216,7 @@
* 选中节点
*
* @param {*} $event
* @memberof ${srfclassname('${ctrl.codeName}')}
* @memberof ${srfclassname('${ctrl.codeName}')}Base
*/
protected tabPanelClick($event: any): void {
const item = this.getItem($event);
......@@ -214,6 +228,7 @@
const refview = this.getDRTabItem({ nodetype: item.id });
this.selection = {};
const _context: any = { ...JSON.parse(JSON.stringify(this.context)) };
Object.assign(_context,{srfparentdename:this.parentName,srfparentkey:_context[this.parentName.toLowerCase()]});
const _params: any = { ...JSON.parse(JSON.stringify(this.viewparams)) };
if (refview && refview.parentdatajo) {
Object.assign(_context, refview.parentdatajo);
......
......@@ -129,8 +129,7 @@
return;
}
if (Object.is('state', action)) {
Object.assign(this.parentData, data);
const state = !this.parentData.${ctrl.getPSAppDataEntity().getCodeName()?lower_case} ? true : false;
const state = !this.context.${ctrl.getPSAppDataEntity().getCodeName()?lower_case} ? true : false;
this.setItemDisabled(this.items, state);
}
});
......@@ -245,7 +244,7 @@
const refview = this.getDRBarItem({ nodetype: item.drviewid });
this.selection = {};
const _context: any = { ...JSON.parse(JSON.stringify(this.parentData)) };
const _context: any = { ...JSON.parse(JSON.stringify(this.context)) };
const _params: any = { ...JSON.parse(JSON.stringify(this.viewparams)) };
if (refview && refview.parentdatajo) {
Object.assign(_context, refview.parentdatajo);
......
<#-- 绘图X轴 -->
<#if item.render??>
${item.render.code}
<#else>
{
<#if item.getIndex()??>gridIndex:${item.getIndex()},</#if>
position:<#if item.getPosition()?? && item.getPosition() =='bottom'>"bottom"<#else>"top"</#if>,
type:<#if item.getType()??>'${item.getType()}'<#else>'category'</#if>,
name:<#if item.getCaption()??>'${item.getCaption()}'</#if>,
<#if item.getMinValue()??>min:${item.getMinValue()},</#if>
<#if item.getMaxValue()??>max:${item.getMaxValue()},</#if>
}
</#if>
\ No newline at end of file
<#-- 绘图Y轴 -->
<#if item.render??>
${item.render.code}
<#else>
{
<#if item.getIndex()??>gridIndex:${item.getIndex()},</#if>
position:<#if item.getPosition()?? && item.getPosition() =='bottom'>"bottom"<#else>"top"</#if>,
type:<#if item.getType()?? && item.getType() == 'numeric'>'value'<#else>'${item.getType()}'</#if>,
name:<#if item.getCaption()??>'${item.getCaption()}'</#if>,
<#if item.getMinValue()??>min:${item.getMinValue()},</#if>
<#if item.getMaxValue()??>max:${item.getMaxValue()},</#if>
}
</#if>
\ No newline at end of file
<#-- 绘图网格start -->
<#if item.render??>
${item.render.code}
<#else>
{
}
</#if>
<#-- 绘图网格end -->
\ No newline at end of file
<#-- 柱状图序列start -->
<#if item.render??>
${item.render.code}
<#else>
{
id:'<#if item.getName()??>${item.getName()?lower_case}</#if>',
name:'<#if item.getCaption()??>${item.getCaption()}</#if>',
type:'bar',
xAxisIndex:${item.getIndex()},
yAxisIndex:${item.getIndex()},
datasetIndex:${item.getIndex()},
encode: {
<#if item.getPSChartSeriesEncode()??><#assign chartSeriesEncode = item.getPSChartSeriesEncode() /></#if>
x: [<#if chartSeriesEncode.getX()??><#list chartSeriesEncode.getX() as xValue>'${xValue?lower_case}'<#if xValue_has_next>,</#if></#list></#if>],
y: [<#if chartSeriesEncode.getY()??><#list chartSeriesEncode.getY() as yValue>'${yValue?lower_case}'<#if yValue_has_next>,</#if></#list></#if>]
}
}
</#if>
<#-- 柱状图序列end -->
\ No newline at end of file
<#-- 折线图序列start -->
<#if item.render??>
${item.render.code}
<#else>
{
id:'<#if item.getName()??>${item.getName()?lower_case}</#if>',
name:'<#if item.getCaption()??>${item.getCaption()}</#if>',
type:'funnel',
datasetIndex:${item.getIndex()},
<#compress><#if item.getLeft()?? && item.getLeft() != "">left:"${item.getLeft()}",</#if>
<#if item.getTop()?? && item.getTop() != 0>top:"${item.getTop()}",</#if>
<#if item.getBottom()?? && item.getBottom() != 0>bottom:"${item.getBottom()}",</#if>
<#if item.getRight()?? && item.getRight() != "">right:"${item.getRight()}",</#if>
<#if item.getWidth()?? && item.getWidth() != "">width:"${item.getWidth()}",</#if>
<#if item.getHeight()?? && item.getHeight() != "">height:"${item.getHeight()}",</#if>
<#if item.getMinValue()?? && item.getMinValue() != 0 >min:"${item.getMinValue()}",</#if>
<#if item.getMaxValue()?? && item.getMaxValue() != 0 >max:"${item.getMaxSize()}",</#if>
<#if item.getMinSize()?? && item.getMinSize() != "">minSize:"${item.getMinSize()}",</#if>
<#if item.getMaxSize()?? && item.getMaxSize() != "">maxSize: "${item.getMaxSize()}",</#if>
<#if item.getFunnelAlign()?? && item.getFunnelAlign() != "">funnelAlign:"${item.getFunnelAlign()}",</#if></#compress>
seriesLayoutBy:"${item.getSeriesLayoutBy()}",
sort: 'descending',
encode:{
<#if item.getPSChartSeriesEncode()??><#assign chartSeriesEncode = item.getPSChartSeriesEncode() /></#if>
itemName:"<#if chartSeriesEncode.getCategory()??>${chartSeriesEncode.getCategory()?lower_case}<#else>${item.getCatalogField()?lower_case}</#if>",
value:"<#if chartSeriesEncode.getValue()??>${chartSeriesEncode.getValue()?lower_case}<#else>${item.getValueField()?lower_case}</#if>"
}
}
</#if>
<#-- 折线图序列end -->
\ No newline at end of file
<#-- 折线图序列start -->
<#if item.render??>
${item.render.code}
<#else>
{
id:'<#if item.getName()??>${item.getName()?lower_case}</#if>',
name:'<#if item.getCaption()??>${item.getCaption()}</#if>',
type:'line',
xAxisIndex:${item.getIndex()},
yAxisIndex:${item.getIndex()},
datasetIndex:${item.getIndex()},
encode: {
<#if item.getPSChartSeriesEncode()??><#assign chartSeriesEncode = item.getPSChartSeriesEncode() /></#if>
x: [<#if chartSeriesEncode.getX()??><#list chartSeriesEncode.getX() as xValue>'${xValue?lower_case}'<#if xValue_has_next>,</#if></#list></#if>],
y: [<#if chartSeriesEncode.getY()??><#list chartSeriesEncode.getY() as yValue>'${yValue?lower_case}'<#if yValue_has_next>,</#if></#list></#if>]
}
}
</#if>
<#-- 折线图序列end -->
\ No newline at end of file
<#-- 折线图序列start -->
<#if item.render??>
${item.render.code}
<#else>
{
id:'<#if item.getName()??>${item.getName()?lower_case}</#if>',
name:'<#if item.getCaption()??>${item.getCaption()}</#if>',
type:'pie',
datasetIndex:${item.getIndex()},
<#compress><#if item.getLeft()?? && item.getLeft() != "">left:"${item.getLeft()}",</#if>
<#if item.getTop()?? && item.getTop() != 0>top:"${item.getTop()}",</#if>
<#if item.getBottom()?? && item.getBottom() != 0>bottom:"${item.getBottom()}",</#if>
<#if item.getRight()?? && item.getRight() != "">right:"${item.getRight()}",</#if>
<#if item.getWidth()?? && item.getWidth() != "">width:"${item.getWidth()}",</#if>
<#if item.getHeight()?? && item.getHeight() != "">height:"${item.getHeight()}",</#if></#compress>
seriesLayoutBy:"${item.getSeriesLayoutBy()}",
encode:{
<#if item.getPSChartSeriesEncode()??><#assign chartSeriesEncode = item.getPSChartSeriesEncode() /></#if>
itemName:"<#if chartSeriesEncode.getCategory()??>${chartSeriesEncode.getCategory()?lower_case}<#else>${item.getCatalogField()?lower_case}</#if>",
value:"<#if chartSeriesEncode.getValue()??>${chartSeriesEncode.getValue()?lower_case}<#else>${item.getValueField()?lower_case}</#if>"
}
}
</#if>
<#-- 折线图序列end -->
\ No newline at end of file
此差异已折叠。
<#assign content>
fetchAction="<#if ctrl.getFetchPSControlAction()?? && ctrl.getFetchPSControlAction().getPSAppDEMethod()??>${ctrl.getFetchPSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/CSS/DEFAULT.less.ftl
</#ibizinclude>
.app-data-chart {
width: 100%;
height: 100%;
}
\ No newline at end of file
<#ibizinclude>
../@MACRO/CONTROL/CONTROL.vue.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/MODEL/MODEL_HEADER.ts.ftl
</#ibizinclude>
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof ${srfclassname('${ctrl.getCodeName()}')}${srfclassname('${ctrl.name}')}Mode
*/
public getDataItems(): any[] {
return [
{
name:'query',
prop:'query'
},
]
}
<#ibizinclude>
../@MACRO/MODEL/MODEL_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_HEADER.ts.ftl
</#ibizinclude>
/**
* 查询数据
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
@Errorlog
public search(action: string,context: any = {}, data: any = {}, isloading?: boolean): Promise<any> {
const {data:Data,context:Context} = this.handleRequestData(action,context,data,true);
return new Promise((resolve: any, reject: any) => {
const _appEntityService: any = this.appEntityService;
let result: Promise<any>;
if (_appEntityService[action] && _appEntityService[action] instanceof Function) {
result = _appEntityService[action](Context,Data, isloading);
}else{
result =_appEntityService.FetchDefault(Context,Data, isloading);
}
result.then((response) => {
resolve(response);
}).catch(response => {
reject(response);
});
});
}
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
CTRLTYPE=CHART#NEW
\ No newline at end of file
<template>
<div class="app-data-chart <#if ctrl.getPSSysCss()??><#assign singleCss = ctrl.getPSSysCss()> ${singleCss.getCssName()}</#if>">
<#if ctrl.render??><#t>
${ctrl.render.code}
<#else><#t>
<div class="app-charts" :id="chartId" style="<#if ctrl.getWidth() gt 0>width: ${ctrl.getWidth()};</#if>height: <#if ctrl.getHeight() gt 0>${ctrl.getHeight()}px<#else>100%</#if>;padding: 6px 0;"></div>
</#if>
</div>
</template>
<#assign import_block>
import echarts from 'echarts';
</#assign>
<#ibizinclude>
../@MACRO/CONTROL/CONTROL_HEADER-BASE.vue.ftl
</#ibizinclude>
/**
* 获取多项数据
*
* @returns {any[]}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public getDatas(): any[] {
return [];
}
/**
* 获取单项树
*
* @returns {*}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public getData(): any {
return null;
}
/**
* 显示处理提示
*
* @type {boolean}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop({ default: true }) protected showBusyIndicator!: boolean;
/**
* 部件行为--fetch
*
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected fetchAction!: string;
/**
* Vue声明周期(组件初始化完毕)
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public created() {
this.afterCreated();
}
/**
* 执行created后的逻辑
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public afterCreated(){
if (this.viewState) {
this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }) => {
if (!Object.is(tag, this.name)) {
return;
}
if (Object.is('load', action)) {
this.load(data);
}
});
}
}
/**
* vue 生命周期
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected destroyed() {
this.afterDestroy();
}
/**
* 执行destroyed后的逻辑
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected afterDestroy() {
if (this.viewStateEvent) {
this.viewStateEvent.unsubscribe();
}
<#if destroyed_block??>
${destroyed_block}
</#if>
}
/**
* 图表div绑定的id
*
* @type {}
* @memberof ${srfclassname('${ctrl.name}')}
*/
public chartId:string = this.$util.createUUID();
/**
* echarts图表对象
*
* @type {}
* @memberof ${srfclassname('${ctrl.name}')}
*/
public myChart:any;
/**
* 初始化图表所需参数
*
* @type {}
* @memberof ${srfclassname('${ctrl.name}')}
*/
public chartOption:any = {};
/**
* 图表基础配置参数
*
* @returns {*}
* @memberof ${srfclassname('${ctrl.name}')}Service
*/
public defaultConfig: any = {
<#-- 获取模板对象:BEGIN -->
<#assign title=ctrl.getPSDEChartTitle()>
<#list ctrl.getPSDEChartSerieses() as series>
<#-- 暂只支持第一个序列 -->
<#if series_index == 0>
<#assign chartSeries = series/>
</#if>
</#list>
<#-- 获取模板对象:END -->
<#-- 公共配置:BEGIN -->
title: {
show: <#if title.isShowTitle()>true<#else>false</#if>,
<#if title.getTitle()??>
text: '${title.getTitle()}',
</#if>
<#if title.getSubTitle()??>
subtext: '${title.getSubTitle()}'
</#if>
},
legend: {top: 20},
toolbox: {
show: true,
feature: {
dataView: {
show: true,
readOnly: true,
title: '数据视图'
},
saveAsImage: {
show: true,
title: '保存为图片'
}
}
},
<#-- 公共配置:END -->
<#-- 饼图配置:BEGIN -->
<#if chartSeries.getSeriesType() == 'pie'>
tooltip: { trigger: 'item' },
<#-- 饼图配置:END -->
<#-- 折线图,柱状图配置:BEGIN -->
<#elseif chartSeries.getSeriesType() == 'line' || chartSeries.getSeriesType() == 'bar'>
<#assign xAxes = chartSeries.getXPSDEChartAxes() />
<#assign yAxes = chartSeries.getYPSDEChartAxes() />
tooltip: { trigger: 'axis' },
<#if xAxes??>
xAxis: {
<#if xAxes.getAxesType?? && xAxes.getAxesType()??>
type: '${xAxes.getAxesType()}',
</#if>
<#if xAxes.getAxesPos?? && xAxes.getAxesPos()??>
position: '${xAxes.getAxesPos()}',
</#if>
<#if xAxes.getCaption?? && xAxes.getCaption()??>
name: '${xAxes.getCaption()}',
</#if>
<#if xAxes.getMaxValue?? && xAxes.getMaxValue()??>
max: '${xAxes.getMaxValue()}',
</#if>
<#if xAxes.getMinValue?? && xAxes.getMinValue()??>
min: '${xAxes.getMinValue()}',
</#if>
},
</#if>
<#if yAxes??>
yAxis: {
<#if yAxes.getAxesType?? && yAxes.getAxesType()??>
type: '<#if yAxes.getAxesType() == 'numeric'>value<#else>${yAxes.getAxesType()}</#if>',
</#if>
<#if yAxes.getAxesPos?? && yAxes.getAxesPos()??>
position: '${yAxes.getAxesPos()}',
</#if>
<#if yAxes.getCaption?? && yAxes.getCaption()??>
name: '${yAxes.getCaption()}',
</#if>
<#if yAxes.getMaxValue?? && yAxes.getMaxValue()??>
max: '${yAxes.getMaxValue()}',
</#if>
<#if yAxes.getMinValue?? && yAxes.getMinValue()??>
min: '${yAxes.getMinValue()}',
</#if>
},
</#if>
</#if>
<#-- 折线图,柱状图配置:BEGIN -->
}
/**
* 深度合并对象,把secondObj的内容合并给firstObj,返回合并后的firstObj
* @param {} firstObj 被合并对象
* @param {} secondObj 合并对象
* @memberof ${srfclassname('${ctrl.name}')}
*/
public deepObjectMerge(firstObj: any, secondObj: any) {
for (let key in secondObj) {
firstObj[key] =
firstObj[key] && firstObj[key].toString() === "[object Object]"
? this.deepObjectMerge(firstObj[key], secondObj[key])
: (firstObj[key] = secondObj[key]);
}
return firstObj;
}
/**
* 刷新
*
* @param {*} [opt={}]
* @memberof ${srfclassname('${ctrl.name}')}
*/
protected refresh(opt: any = {}) {
this.load(opt);
}
/**
* 获取图表数据
*
* @returns {*}
* @memberof ${srfclassname('${ctrl.name}')}
*/
public load(opt?:any) {
let _this = this;
const arg: any = { ...opt };
const parentdata: any = {};
this.$emit('beforeload', parentdata);
Object.assign(arg, parentdata);
Object.assign(arg,{viewparams:this.viewparams});
this.service.search(this.fetchAction,JSON.parse(JSON.stringify(this.context)),arg,this.showBusyIndicator).then((res) => {
if (res) {
_this.chartOption = _this.deepObjectMerge(_this.defaultConfig, res.data);
_this.drawCharts();
}
}).catch((error) => {
console.error(error);
});
}
/**
* 绘制图表
*
* @returns {*}
* @memberof ${srfclassname('${ctrl.name}')}
*/
public drawCharts(){
if(!this.myChart){
let element:any = document.getElementById(this.chartId);
this.myChart = echarts.init(element);
}
this.myChart.setOption(this.chartOption);
this.myChart.resize();
}
<#ibizinclude>
../@MACRO/CONTROL/CONTROL_BOTTOM-BASE.vue.ftl
</#ibizinclude>
<#ibizinclude>
../@MACRO/CONTROL/CONTROL-BASE.style.ftl
</#ibizinclude>
\ No newline at end of file
<#assign content>
fetchAction="<#if ctrl.getFetchPSControlAction()?? && ctrl.getFetchPSControlAction().getPSAppDEMethod()??>${ctrl.getFetchPSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/CSS/DEFAULT.less.ftl
</#ibizinclude>
.app-data-chart {
width: 100%;
height: 100%;
}
\ No newline at end of file
<#ibizinclude>
../@MACRO/CONTROL/CONTROL.vue.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/MODEL/MODEL_HEADER.ts.ftl
</#ibizinclude>
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof ${srfclassname('${ctrl.getCodeName()}')}${srfclassname('${ctrl.name}')}Mode
*/
public getDataItems(): any[] {
return [
{
name:'query',
prop:'query'
},
]
}
<#ibizinclude>
../@MACRO/MODEL/MODEL_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_HEADER.ts.ftl
</#ibizinclude>
/**
* 查询数据
*
* @param {string} action
* @param {*} [context={}]
* @param {*} [data={}]
* @param {boolean} [isloading]
* @returns {Promise<any>}
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
@Errorlog
public search(action: string,context: any = {}, data: any = {}, isloading?: boolean): Promise<any> {
const {data:Data,context:Context} = this.handleRequestData(action,context,data,true);
return new Promise((resolve: any, reject: any) => {
const _appEntityService: any = this.appEntityService;
let result: Promise<any>;
if (_appEntityService[action] && _appEntityService[action] instanceof Function) {
result = _appEntityService[action](Context,Data, isloading);
}else{
result =_appEntityService.FetchDefault(Context,Data, isloading);
}
result.then((response) => {
this.handleSeries(response);
resolve(response);
}).catch(response => {
reject(response);
});
});
}
<#-- 暂只支持第一个序列 -->
<#list ctrl.getPSDEChartSerieses() as series>
<#if series_index == 0>
<#assign chartSeries = series/>
</#if>
</#list>
/**
* 生成图表数据
*
* @param {*} response
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
public handleSeries(response: any) {
let chartOption:any = {};
<#-- 获取x轴的分类属性字段 -->
<#if chartSeries.getCatalogField?? && chartSeries.getCatalogField()??>
<#assign catalogField = chartSeries.getCatalogField()>
let catalogFields: any = [<#rt>
<#list catalogField?split(";") as field>
"${field?lower_case}",<#t>
</#list>
];<#lt>
</#if>
<#-- 获取y轴值属性字段和中文名称 -->
<#if chartSeries.getValueField?? && chartSeries.getValueField()??>
<#assign valueField = chartSeries.getValueField()>
let valueFields: any = [<#rt>
<#list valueField?split(";") as field>
[ "${field?lower_case}", "${de.getPSDEField(field).getLogicName()}" ],<#t>
</#list>
];<#lt>
</#if>
// 数据按分类属性分组处理
let xFields:any = [];
let yFields:any = [];
valueFields.forEach((field: any,index: number) => {
yFields[index] = [];
});
response.data.forEach((item:any) => {
if(xFields.indexOf(item[catalogFields[0]]) > -1){
let num = xFields.indexOf(item[catalogFields[0]]);
valueFields.forEach((field: any,index: number) => {
yFields[index][num] += item[field[0]];
});
}else{
xFields.push(item[catalogFields[0]]);
valueFields.forEach((field: any,index: number) => {
yFields[index].push(item[field[0]]);
});
}
});
<#-- 折线图和柱状图需要配置xAxis,饼图不需要 -->
<#if chartSeries.getSeriesType() == 'line' || chartSeries.getSeriesType() == 'bar'>
chartOption.xAxis = { data: xFields };
</#if>
<#-- 配置series -->
let series: any = [];
valueFields.forEach((field: any,index: number) => {
let yData: any = [];
xFields.forEach((item:any, num: number) => {
<#if chartSeries.getSeriesType() == 'line' || chartSeries.getSeriesType() == 'bar'>
yData.push(yFields[index][num]);
<#elseif chartSeries.getSeriesType() == 'pie'>
yData.push({value: yFields[index][num], name: item});
</#if>
});
yData.sort(function (a:any, b:any) { return a.value - b.value; });
series.push({
name:field[1],
type:"${chartSeries.getSeriesType()}",
data:yData,
<#-- 饼图额外配置 -->
<#if chartSeries.getSeriesType() == 'pie'>
top:"40px",
left: (100/valueFields.length)*index+"%",
right: (100/valueFields.length)*(valueFields.length-index-1)+"%",
animationType: 'scale',
animationEasing: 'elasticOut',
animationDelay: function (idx: any) {
return Math.random() * 200;
}
</#if>
});
});
chartOption.series = series;
response.data = chartOption;
}
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
CTRLTYPE=CHART
\ No newline at end of file
<template>
<div class='dashboard'>
<row>
<row v-if="isEnableCustomized">
<app-build @handleClick="handleClick"></app-build>
</row>
<row v-if="!isHasCustomized">
<#list ctrl.getPSPortlets() as portlet><#t>
<#if portlet.getPortletType?? && portlet.getPortletType()??><#t>
<#assign layout='TABLE_24COL'><#if portlet.getPSLayoutPos()??><#if portlet.getPSLayoutPos().getParentPSLayout()??><#assign layout='${portlet.getPSLayoutPos().getParentPSLayout().getLayout()}'></#if></#if><#t>
......@@ -66,13 +69,73 @@ ${P.getCtrlCode(portlet, 'CONTROL.html').code}
</#if>
</#list>
</row>
<row v-if="isHasCustomized" style="width: 100%;min-height: calc(100% - 40px);">
<div class="container" style="position: relative;width:100%;">
<template v-for="(item, index) of modelDta">
<#noparse><div :key="index" :style="{zIndex: 10, position: 'absolute', height: item.h*layoutRowH + 'px', width: `calc(100% / ${layoutColNum} * ${item.w})`,top: item.y*layoutRowH + 'px', left: `calc(100% / ${layoutColNum} * ${item.x})`,'padding':'8px'}"></#noparse>
<component :key="$util.createUUID()" :is="item.componentName" :name="item.portletCodeName" :context="JSON.parse(JSON.stringify(context))" :viewDefaultUsage="false" :viewState="viewState"></component>
</div>
</template>
</div>
</row>
</div>
</template>
<#assign import_block>
import UtilService from '@/utilservice/util-service';
</#assign>
<#ibizinclude>
../@MACRO/CONTROL/CONTROL_HEADER-BASE.vue.ftl
</#ibizinclude>
/**
* 是否支持看板定制
*
* @protected
* @type {(boolean)}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected isEnableCustomized!:boolean;
/**
* 是否已有看板定制
*
* @protected
* @type {(boolean)}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected isHasCustomized:boolean = false;
/**
* 模型数据
*
* @protected
* @type {(*)}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected modelDta:any;
/**
* modleId
*
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected modelId:string = "dashboard_<#if ctrl.getPSAppDataEntity()??>${ctrl.getPSAppDataEntity().getCodeName()?lower_case}<#else>app</#if>_${ctrl.getCodeName()?lower_case}";
/**
* 建构功能服务对象
*
* @type {UtilService}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected utilService:UtilService = new UtilService();
/**
* 功能服务名称
*
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected utilServiceName:string = "<#if ctrl.getPSAppDynaDashboardUtil?? && ctrl.getPSAppDynaDashboardUtil()??>${ctrl.getPSAppDynaDashboardUtil().getCodeName()?lower_case}</#if>";
/**
* 获取多项数据
......@@ -109,17 +172,118 @@ ${P.getCtrlCode(portlet, 'CONTROL.html').code}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected afterCreated(){
if (this.viewState) {
this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }) => {
if (!Object.is(tag, this.name)) {
return;
}
const refs: any = this.$refs;
Object.keys(refs).forEach((name: string) => {
this.viewState.next({ tag: name, action: action, data: data });
});
if (this.viewState) {
this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }) => {
if (!Object.is(tag, this.name)) {
return;
}
if (Object.is('load', action)) {
this.loadModel();
}
});
}
}
/**
* 动态设计水平列数
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public layoutColNum:number = 12;
/**
* 动态设计单元格高度,80px
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public layoutRowH:number = 80;
/**
* 通知状态
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
public notifyState(){
this.$nextTick(() =>{
if (this.isHasCustomized) {
if (this.modelDta && this.modelDta.length > 0) {
this.modelDta.forEach((item: any) => {
this.viewState.next({
tag: item.portletCodeName,
action: "load",
data: JSON.parse(JSON.stringify(this.viewparams))
});
});
}
} else {
if (this.viewState) {
const refs: any = this.$refs;
Object.keys(refs).forEach((name: string) => {
this.viewState.next({
tag: name,
action: "load",
data: JSON.parse(JSON.stringify(this.viewparams))
});
});
}
}
})
}
/**
* 加载布局与数据模型
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected loadModel(){
if(this.isEnableCustomized){
this.utilService.getService(this.utilServiceName).then((service:any) =>{
service.loadModelData(JSON.parse(JSON.stringify(this.context)),{modelid:this.modelId}).then((res:any) =>{
if(res && res.status == 200){
const data:any = res.data;
if(data && data.length >0){
this.isHasCustomized = true;
this.modelDta = data;
this.$forceUpdate();
}else{
this.isHasCustomized = false;
}
this.notifyState();
}else{
console.error("加载面板模型异常");
this.isHasCustomized = false;
this.notifyState();
}
})
})
}else{
this.notifyState();
}
}
/**
* 处理私人定制按钮
*
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected handleClick(){
const view:any ={
viewname: 'app-portal-design',
title: '面板设计',
width: 1600,
placement: 'DRAWER_RIGHT'
}
const viewparam:any ={
modelid:this.modelId,
utilServiceName:this.utilServiceName,
appdeName:<#if ctrl.getPSAppDataEntity?? && ctrl.getPSAppDataEntity()??>'${ctrl.getPSAppDataEntity().getCodeName()}'<#else>'app'</#if>
}
const appdrawer = this.$appdrawer.openDrawer(view, JSON.parse(JSON.stringify(this.context)), viewparam);
appdrawer.subscribe((result: any) => {
if(Object.is(result.ret,'OK')){
this.loadModel();
}
});
}
/**
......
<#assign content>
:isEnableCustomized = "${ctrl.isEnableCustomized()?c}"
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
......@@ -18,7 +18,7 @@
}
}
}
}
}
}
<#ibizinclude>
......
......@@ -5,7 +5,7 @@
<#else><#t>
<row v-if="items.length > 0" :gutter="20" type="flex" justify="start">
<a v-for="(item,index) in items" :key="index" :href = "item.starturl">
<i-col <#if ctrl.getCardColLG() gt 0> lg={${ctrl.getCardColLG()?c}}</#if><#if ctrl.getCardColMD() gt 0> md={${ctrl.getCardColMD()?c}}</#if><#if ctrl.getCardColSM() gt 0> sm={${ctrl.getCardColSM()?c}}</#if><#if ctrl.getCardColXS() gt 0> xs={${ctrl.getCardColXS()?c}}</#if> style="<#if ctrl.getCardHeight() gt 0>height: ${ctrl.getCardHeight()?c}<#else>min-height: 170</#if>px;<#if ctrl.getCardWidth() gt 0> width: ${ctrl.getCardWidth()?c}px;</#if>margin-bottom: 10px;">
<i-col <#if ctrl.getCardColLG() gt 0> :lg="${ctrl.getCardColLG()?c}"</#if><#if ctrl.getCardColMD() gt 0> :md="${ctrl.getCardColMD()?c}"</#if><#if ctrl.getCardColSM() gt 0> :sm="${ctrl.getCardColSM()?c}"</#if><#if ctrl.getCardColXS() gt 0> :xs="${ctrl.getCardColXS()?c}"</#if> style="<#if ctrl.getCardHeight() gt 0>height: ${ctrl.getCardHeight()?c}<#else>min-height: 170</#if>px;<#if ctrl.getCardWidth() gt 0> width: ${ctrl.getCardWidth()?c}px;</#if>margin-bottom: 10px;">
<div :class="[ item.isselected === true ? 'isselected' : false, 'single-card-data' ]" @click="handleClick(item)" @dblclick="handleDblClick(item)">
<#if ctrl.getItemPSLayoutPanel()??>
<#assign panel = ctrl.getItemPSLayoutPanel()>
......@@ -14,9 +14,11 @@
${ctrl.itemRender.code}
<#else>
<img v-if="item.srficonpath" :src="item.srficonpath" class="single-card-img" />
<img v-else src="/assets/img/noimg.jpg" class="single-card-img" />
<img v-else src="/assets/img/noimg2.png" class="single-card-img" />
<div class="single-card-default">
<span>{{item.srfmajortext}}</span>
<Tooltip :content="item.srfmajortext">
{{item.srfmajortext}}
</Tooltip>
</div>
</#if>
</div>
......@@ -31,7 +33,7 @@
<#ibizinclude>
../@MACRO/CONTROL/CONTROL_HEADER-BASE.vue.ftl
</#ibizinclude>
/**
/**
* 获取多项数据
*
* @returns {any[]}
......@@ -51,6 +53,14 @@
return null;
}
/**
* 是否默认选中第一条数据
*
* @type {boolean}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop({ default: false }) protected isSelectFirstDefault!: boolean;
/**
* 显示处理提示
*
......@@ -58,27 +68,21 @@
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop({ default: true }) protected showBusyIndicator?: boolean;
/**
* 结果集
* 部件行为--fetch
*
* @type {string}
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
// 加载
@Prop() protected fetchAction!: string;
// 更新
@Prop() protected updateAction!: string;
// 删除
@Prop() protected removeAction!: string;
/**
* 是否单选
*
* @type {boolean}
* @memberof Market
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
@Prop() protected isSingleSelect?: boolean;
......@@ -133,7 +137,7 @@
* 当前页
*
* @type {number}
* @memberof Main
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected curPage: number = 1;
......@@ -148,7 +152,7 @@
/**
* Vue声明周期,组件挂载完毕
*
* @memberof Container
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected mounted () {
this.afterMounted();
......@@ -172,7 +176,7 @@
/**
* Vue声明周期,组件创建完毕
*
* @memberof Container
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected created() {
this.afterCreated();
......@@ -192,6 +196,9 @@
if (Object.is(action,'load')) {
this.refresh(data)
}
if (Object.is(action,'filter')) {
this.refresh(data)
}
});
}
}
......@@ -199,7 +206,7 @@
/**
* 加载更多
*
* @memberof Mob
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected loadMore(){
if(this.totalRecord>this.items.length)
......@@ -213,7 +220,7 @@
* 刷新
*
* @param {*} [opt={}]
* @memberof Main
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
protected refresh(opt: any = {}) {
this.curPage = 1;
......@@ -252,6 +259,10 @@
* @memberof ${srfclassname('${ctrl.codeName}')}
*/
private load(opt: any = {}): void {
if(!this.fetchAction){
this.$Notice.error({ title: '错误', desc: '${view.getName()}视图列表fetchAction参数未配置' });
return;
}
const arg: any = {...opt};
const page: any = {};
if (this.isEnablePagingBar) {
......@@ -261,8 +272,8 @@
const parentdata: any = {};
this.$emit('beforeload', parentdata);
Object.assign(arg, parentdata);
const post: Promise<any> = this.service.search(this.fetchAction, this.context, arg, this.showBusyIndicator);
let viewparamResult:any = Object.assign(arg,this.viewparams);
const post: Promise<any> = this.service.search(this.fetchAction,JSON.parse(JSON.stringify(this.context)), {viewparams:viewparamResult}, this.showBusyIndicator);
post.then((response: any) => {
if (!response || response.status !== 200) {
if (response.errorMessage) {
......@@ -270,17 +281,20 @@
}
return;
}
const data: any = response.data.records;
const data: any = response.data;
this.items = [];
if (Object.keys(data).length > 0) {
let datas = JSON.parse(JSON.stringify(data));
datas.map((item: any) => {
Object.assign(item, { isselected: false });
});
this.totalRecord = response.total;
this.items.push(...datas);
this.totalRecord = data.total;
}
this.$emit('load', this.items);
if(this.isSelectFirstDefault){
this.handleClick(this.items[0]);
}
}, (response: any) => {
if (response && response.status === 401) {
return;
......@@ -288,7 +302,7 @@
this.$Notice.error({ title: '错误', desc: response.errorMessage });
});
}
<#--
/**
* 删除
*
......@@ -324,7 +338,8 @@
datas.forEach((data: any) => {
keys.push(data.srfkey);
});
const post: Promise<any> = this.service.delete(this.removeAction, { ${ctrl.getPSAppDataEntity().codeName?lower_case}: keys.join(';') }, this.showBusyIndicator);
const context:any = JSON.parse(JSON.stringify(this.context));
const post: Promise<any> = this.service.delete(this.removeAction, Object.assign(context,{ ${ctrl.getPSAppDataEntity().codeName?lower_case}: keys.join(';') }),Object.assign({ ${ctrl.getPSAppDataEntity().codeName?lower_case}: keys.join(';') },{viewparams:this.viewparams}), this.showBusyIndicator);
return new Promise((resolve: any, reject: any) => {
post.then((response: any) => {
if (!response || response.status !== 200) {
......@@ -346,10 +361,6 @@
reject(response);
return;
}
const { data: _data } = response;
this.$Notice.error({ title: _data.title, desc: _data.message });
reject(response);
});
});
}
......@@ -364,7 +375,7 @@
onCancel: () => { }
});
return removeData;
}
} -->
/**
* 选择数据
......
......@@ -2,9 +2,11 @@
<#assign content>
:isSingleSelect="isSingleSelect"
fetchAction="<#if ctrl.getFetchPSControlAction()?? && ctrl.getFetchPSControlAction().getPSAppDEMethod()??>${ctrl.getFetchPSControlAction().getPSAppDEMethod().getCodeName()}</#if>"
removeAction="Remove"
<#-- removeAction 配置暂无 -->
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
<#if view.getViewType() == 'DEDATAVIEWEXPVIEW'>
:isSelectFirstDefault="true"
</#if>
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
......
......@@ -11,11 +11,15 @@
cursor: pointer;
border: 1px solid transparent;
.single-card-default {
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
text-align: center;
.ivu-tooltip{
.ivu-tooltip-rel{
width: 150px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
text-align: center;
}
}
}
.single-card-img {
width: 150px;
......
......@@ -17,7 +17,7 @@
*/
@Errorlog
public search(action: string,context: any = {}, data: any = {}, isloading?: boolean): Promise<any> {
const {data:Data,context:Context} = this.handleRequestData(action,context,data);
const {data:Data,context:Context} = this.handleRequestData(action,context,data,true);
return new Promise((resolve: any, reject: any) => {
const _appEntityService: any = this.appEntityService;
let result: Promise<any>;
......@@ -47,7 +47,7 @@
*/
@Errorlog
public delete(action: string,context: any = {}, data: any = {}, isloading?: boolean): Promise<any> {
const {data:Data,context:Context} = this.handleRequestData(action,context,data);
const {data:Data,context:Context} = this.handleRequestData(action,context,data,true);
return new Promise((resolve: any, reject: any) => {
const _appEntityService: any = this.appEntityService;
let result: Promise<any>;
......@@ -65,86 +65,6 @@
});
}
/**
* 处理返回数据
*
* @param {string} action
* @param {*} response
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
public handleResponse(action: string, response: any) {
response.data = this.handleResPonseData(action, response);
}
/**
* 处理数据
*
* @param {string} action 行为名称
* @param {*} [data]
* @returns
* @memberof ${srfclassname('${ctrl.codeName}')}Service
*/
public handleResPonseData(action: string, data: any) {
let result = {};
if(data.status){
Object.assign(result,{status:data.status});
}
if(data.headers){
if(data.headers['x-page']){
Object.assign(result,{page:Number(data.headers['x-page'])});
}
if(data.headers['x-per-page']){
Object.assign(result,{size:Number(data.headers['x-per-page'])});
}
if(data.headers['x-total']){
Object.assign(result,{total:Number(data.headers['x-total'])});
}
}
let mode: any = this.getMode();
if (!mode && mode.getDataItems instanceof Function) {
Object.assign(result,{records:data.data});
return data;
}
let dataItems: any[] = mode.getDataItems();
let tempData:any = data.data;
if (!tempData) {
Object.assign(result,{records:tempData});
} else if (tempData instanceof Array) {
if(tempData.length > 0){
let tempArray:any = [];
tempData.forEach((item:any) =>{
let tempItem:any = {};
dataItems.forEach(dataitem => {
let val = item.hasOwnProperty(dataitem.prop) ? item[dataitem.prop] : null;
if (!val) {
val = item.hasOwnProperty(dataitem.name) ? item[dataitem.name] : null;
}
tempItem[dataitem.name] = val;
});
tempArray.push(tempItem);
});
Object.assign(result,{records:tempArray});
}else{
Object.assign(result,{records:[]});
}
} else {
if(Object.keys(tempData).length>0){
let tempItem:any = {};
dataItems.forEach(dataitem => {
let val = tempData.hasOwnProperty(dataitem.prop) ? tempData[dataitem.prop] : null;
if (!val) {
val = tempData.hasOwnProperty(dataitem.name) ? tempData[dataitem.name] : null;
}
tempItem[dataitem.name] = val;
});
Object.assign(result,{records:[tempItem]});
}else{
Object.assign(result,{records:[]});
}
}
return result;
}
<#ibizinclude>
......
此差异已折叠。
<#assign content>
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
<#if view.getViewType() == 'DECALENDAREXPVIEW'>
:viewUID="viewUID"
</#if>
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
此差异已折叠。
<#ibizinclude>
../@MACRO/CONTROL/CONTROL.vue.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/MODEL/MODEL_HEADER.ts.ftl
</#ibizinclude>
/**
* 获取数据项集合
*
* @returns {any[]}
* @memberof ${srfclassname('${ctrl.getCodeName()}')}${srfclassname('${ctrl.name}')}Mode
*/
public getDataItems(): any[] {
return [
]
}
<#ibizinclude>
../@MACRO/MODEL/MODEL_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_HEADER.ts.ftl
</#ibizinclude>
<#ibizinclude>
../@MACRO/SERVICE/SERVICE_BOTTOM.ts.ftl
</#ibizinclude>
\ No newline at end of file
CTRLTYPE=CALENDAREXPBAR
\ No newline at end of file
此差异已折叠。
<#assign content>
:showBusyIndicator="${ctrl.isShowBusyIndicator()?c}"
<#if view.getViewType() == 'DECALENDAREXPVIEW'>
:isSelectFirstDefault="true"
</#if>
</#assign>
<#ibizinclude>
../@MACRO/HTML/DEFAULT.html.ftl
</#ibizinclude>
\ No newline at end of file
此差异已折叠。
<#ibizinclude>
../@MACRO/CONTROL/CONTROL.vue.ftl
</#ibizinclude>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
CTRLTYPE=CALENDAR
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册