提交 fceaed54 编写于 作者: Mosher's avatar Mosher

update:更新

1、新增代码表类型树节点支持
2、新增树节点自定义图标、自定义标题支持
3、增加部件计数器支持
4、删除多余输出语句
上级 f774df1d
...@@ -39,7 +39,6 @@ const itemClick = (item: IParam) => { ...@@ -39,7 +39,6 @@ const itemClick = (item: IParam) => {
}; };
const hasCounter = (item: any) => { const hasCounter = (item: any) => {
console.log(item.counterId, props.counterData);
if (item.counterId && props.counterData && props.counterData.hasOwnProperty(item.counterId)) { if (item.counterId && props.counterData && props.counterData.hasOwnProperty(item.counterId)) {
return true; return true;
} }
......
import { IParam, ViewDetail } from "../common"; import { IParam, ViewDetail } from "../common";
import { IAppActionService, IAppAuthService, IAppCodeListService, IAppFuncService, IAppNotificationService, IOpenViewService } from "../service"; import { IAppActionService, IAppAuthService, IAppCodeListService, IAppCounterService, IAppFuncService, IAppNotificationService, IOpenViewService } from "../service";
/** /**
...@@ -67,6 +67,17 @@ export interface IApp { ...@@ -67,6 +67,17 @@ export interface IApp {
*/ */
getCodeListService(): IAppCodeListService; getCodeListService(): IAppCodeListService;
/**
* 获取计数器服务
*
* @param {IParam} counterRef 计数器引用
* @param {IParam} [context] 上下文
* @param {IParam} [viewParams] 视图参数
* @return {*} {IAppCounterService}
* @memberof IApp
*/
getCounterService(counterRef: IParam, context?: IParam, viewParams?: IParam): IAppCounterService;
/** /**
* 获取UI服务 * 获取UI服务
* *
......
import { ControlPropsBase, ControlStateBase, IActionParam, IParam, UIBase } from '@core'; import { ControlPropsBase, ControlStateBase, IActionParam, IAppCounterService, IParam, UIBase } from '@core';
/** /**
* @description 部件基类 * @description 部件基类
...@@ -67,6 +67,26 @@ export class ControlBase { ...@@ -67,6 +67,26 @@ export class ControlBase {
this.state.viewParams = viewParams; this.state.viewParams = viewParams;
} }
/**
* @description 使用计数器服务模块
* @memberof ControlBase
*/
public useCounterService() {
const { appCounterRef, context, viewParams } = this.state;
const { counterService } = toRefs(this.state);
if (appCounterRef) {
const _counterService = App.getCounterService(appCounterRef, context, viewParams);
_counterService.execute().then(() => {
counterService.value = _counterService;
});
}
onUnmounted(() => {
if (counterService && counterService.value) {
counterService.value.destory();
}
});
}
/** /**
* 获取当前激活数据 * 获取当前激活数据
* *
...@@ -101,7 +121,10 @@ export class ControlBase { ...@@ -101,7 +121,10 @@ export class ControlBase {
*/ */
public moduleInstall() { public moduleInstall() {
this.setState(); this.setState();
// 处理导航参数
this.useControlContextParams(); this.useControlContextParams();
// 使用计数器服务
this.useCounterService();
return { return {
state: this.state, state: this.state,
name: this.state.controlName, name: this.state.controlName,
......
...@@ -256,6 +256,23 @@ export class TreeControl extends MDControl { ...@@ -256,6 +256,23 @@ export class TreeControl extends MDControl {
} }
} }
} }
// 默认选中
const defualtSelect = items.find((item: any) => item.selected);
if (defualtSelect) {
if (isMultiple && selectedNodes.findIndex((node: any) => node.id === defualtSelect.id) === -1) {
selectedNodes.push(deepCopy(defualtSelect));
// 设置选中样式
selectedKeys.push(defualtSelect.id);
} else if (!isMultiple) {
selectedNodes.splice(0, selectedNodes.length);
currentSelectedNode.value = deepCopy(defualtSelect);
selectedNodes.push(currentSelectedNode.value);
// 设置选中样式
selectedKeys.splice(0, selectedKeys.length);
selectedKeys.push(defualtSelect.id);
}
this.emit("ctrlEvent", { tag: this.props.name, action: "selectionchange", data: selectedNodes });
}
// 回显已选数据 // 回显已选数据
if (echoSelectedNodes && echoSelectedNodes.length > 0) { if (echoSelectedNodes && echoSelectedNodes.length > 0) {
const checkedNodes = items.filter((item: IParam) => { const checkedNodes = items.filter((item: IParam) => {
...@@ -263,6 +280,7 @@ export class TreeControl extends MDControl { ...@@ -263,6 +280,7 @@ export class TreeControl extends MDControl {
if (Object.is(item.srfkey, val.srfkey) && Object.is(item.srfmajortext, val.srfmajortext)) { if (Object.is(item.srfkey, val.srfkey) && Object.is(item.srfmajortext, val.srfmajortext)) {
val.used = true; val.used = true;
selectedNodes.push(val); selectedNodes.push(val);
selectedKeys.push(val.id);
this.emit("ctrlEvent", { tag: this.props.name, action: "selectionchange", data: selectedNodes }); this.emit("ctrlEvent", { tag: this.props.name, action: "selectionchange", data: selectedNodes });
return true; return true;
} }
...@@ -273,14 +291,18 @@ export class TreeControl extends MDControl { ...@@ -273,14 +291,18 @@ export class TreeControl extends MDControl {
echoSelectedNodes = echoSelectedNodes.filter((item: any) => !item.used); echoSelectedNodes = echoSelectedNodes.filter((item: any) => !item.used);
if (!isSelectedAll) { if (!isSelectedAll) {
if (isMultiple) { if (isMultiple) {
selectedNodes.push([...checkedNodes]); checkedNodes.push((node: any) => {
// selectedNodes = selectedNodes.concat(checkedNodes); selectedNodes.push(node);
// TODO 设置选中树节点 selectedKeys.push(node.id);
});
} else { } else {
// TODO 设置选中树节点高亮 // TODO 设置选中树节点高亮
currentSelectedNode.value = deepCopy(checkedNodes[0]); currentSelectedNode.value = deepCopy(checkedNodes[0]);
selectedNodes.splice(0, selectedNodes.length); selectedNodes.splice(0, selectedNodes.length);
selectedNodes.push(currentSelectedNode.value); selectedNodes.push(currentSelectedNode.value);
// 设置选中样式
selectedKeys.splice(0, selectedKeys.length);
selectedKeys.push(currentSelectedNode.value.id);
} }
} }
} }
...@@ -288,7 +310,10 @@ export class TreeControl extends MDControl { ...@@ -288,7 +310,10 @@ export class TreeControl extends MDControl {
// 父节点选中树,选中所有子节点 // 父节点选中树,选中所有子节点
if (isSelectedAll) { if (isSelectedAll) {
const leafNodes = items.filter((item: any) => item.isLeaf); const leafNodes = items.filter((item: any) => item.isLeaf);
selectedNodes = selectedNodes.concat(leafNodes); leafNodes.forEach((node: any) => {
selectedNodes.push(node);
selectedKeys.push(node.id);
});
this.emit("ctrlEvent", { tag: this.props.name, action: 'selectionchange', data: selectedNodes }); this.emit("ctrlEvent", { tag: this.props.name, action: 'selectionchange', data: selectedNodes });
} }
} }
......
.app-tree {
// 设置徽标高度
.node__text-badge {
height: 16px;
}
// 设置节点徽标位置
.ant-badge-count {
height: 16px;
line-height: 16px;
transform: translate(40px, -1px);
}
}
\ No newline at end of file
...@@ -7,3 +7,4 @@ ...@@ -7,3 +7,4 @@
@use './app-tab-view-panel.scss'; @use './app-tab-view-panel.scss';
@use './app-portlet.scss'; @use './app-portlet.scss';
@use './app-grid.scss'; @use './app-grid.scss';
@use './app-tree.scss';
\ No newline at end of file
...@@ -38,13 +38,14 @@ export class ControlVO extends ControlVOBase implements TreeControlVO { ...@@ -38,13 +38,14 @@ export class ControlVO extends ControlVOBase implements TreeControlVO {
{{#if treeNode.psAppCodeList}} {{#if treeNode.psAppCodeList}}
codeList: { codeList: {
codeName: '{{treeNode.psAppCodeList.codeName}}', codeName: '{{treeNode.psAppCodeList.codeName}}',
tag: '{{treeNode.psAppCodeList.codeListTag}}',
type: '{{treeNode.psAppCodeList.codeListType}}' type: '{{treeNode.psAppCodeList.codeListType}}'
}, },
{{/if}} {{/if}}
counterId: '{{treeNode.counterId}}', counterId: '{{treeNode.counterId}}',
counterMode: {{treeNode.counterMode}}, counterMode: {{treeNode.counterMode}},
{{#if treeNode.psSysCss}} {{#if treeNode.psSysCss}}
cssName: '{{treeNode.psSysCss.cssName}}' cssName: '{{treeNode.psSysCss.cssName}}',
{{/if}} {{/if}}
{{#if treeNode.psDETreeNodeDataItems}} {{#if treeNode.psDETreeNodeDataItems}}
deTreeNodeDataItems: [ deTreeNodeDataItems: [
...@@ -184,11 +185,30 @@ export class ControlVO extends ControlVOBase implements TreeControlVO { ...@@ -184,11 +185,30 @@ export class ControlVO extends ControlVOBase implements TreeControlVO {
} }
export const ctrlState = { export const ctrlState = {
appEntityCodeName: '{{ctrl.appEntity.codeName}}',
appDeCodeName:'{{ctrl.appEntity.codeName}}',
appDeLogicName: '{{ctrl.appEntity.logicName}}',
appDeKeyFieldName: '{{#if ctrl.appEntity.keyPSAppDEField}}{{ctrl.appEntity.keyPSAppDEField.codeName}}{{/if}}',
appDeMajorFieldName: '{{#if ctrl.appEntity.majorPSAppDEField}}{{ctrl.appEntity.majorPSAppDEField.codeName}}{{/if}}',
{{#and ctrl.psAppCounterRef ctrl.psAppCounterRef.psAppCounter}}
appCounterRef: {
{{#with ctrl.psAppCounterRef.psAppCounter as | counter |}}
id: '{{ctrl.psAppCounterRef.id}}',
getAction: '{{counter.getPSAppDEAction.codeName}}',
timer: {{#if counter.timer}}{{counter.timer}}{{else}}6000{{/if}},
{{#if counter.psAppDataEntity}}
deCodeName: '{{lowerCase counter.psAppDataEntity.codeName}}'
{{/if}}
{{/with}}
},
counterService: ref(null),
{{/and}}
controlCodeName: '{{ctrl.codeName}}', controlCodeName: '{{ctrl.codeName}}',
controlName: '{{ctrl.name}}', controlName: '{{ctrl.name}}',
controlService: new TreeService<ControlVO>(ControlVO, new {{pascalCase ctrl.psAppDataEntity.codeName}}Service() ), controlService: new TreeService<ControlVO>(ControlVO, new {{pascalCase ctrl.psAppDataEntity.codeName}}Service() ),
currentSelectedNode: {}, currentSelectedNode: {},
data: [], data: [],
outputIconDefault: {{#eq ctrl.outputIconDefault false}}false{{else}}true{{/eq}},
echoSelectedNodes: [], echoSelectedNodes: [],
expandedKeys: [], expandedKeys: [],
selectedKeys: [], selectedKeys: [],
......
<script setup lang="ts"> <script setup lang="ts">
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { IActionParam, IParam, ControlAction, TreeControl, IContext } from '@core'; import { IActionParam, IParam, ControlAction, TreeControl, IContext } from '@core';
import { FileTextOutlined } from '@ant-design/icons-vue';
import { ctrlState } from './{{spinalCase ctrl.codeName}}-tree-state'; import { ctrlState } from './{{spinalCase ctrl.codeName}}-tree-state';
interface Props { interface Props {
...@@ -29,14 +30,39 @@ interface CtrlEmit { ...@@ -29,14 +30,39 @@ interface CtrlEmit {
} }
const emit = defineEmits<CtrlEmit>(); const emit = defineEmits<CtrlEmit>();
// 获取自定义图标
const getCustomIcon = (scriptCode: any) => {
let icon: string = '';
const code = scriptCode.replace(new RegExp('return', 'g'), `icon =`);
eval(code);
return icon;
}
// 获取自定义文本
const getCustomText = (scriptCode: any) => {
let text: string = '';
const code = scriptCode.replace(new RegExp('return', 'g'), `text =`);
eval(code);
return text;
}
// 安装功能模块,提供状态和能力方法 // 安装功能模块,提供状态和能力方法
const { name, state, load, treeNodeSelect } = new TreeControl(ctrlState, props, emit).moduleInstall(); const { name, state, load, treeNodeSelect } = new TreeControl(ctrlState, props, emit).moduleInstall();
{{#and ctrl.psAppCounterRef ctrl.psAppCounterRef.psAppCounter}}
// 获取计数器数据
const counterData = computed(() => {
const { counterService } = state;
if (counterService) {
return counterService.data;
}
return {};
})
{{/and}}
// 暴露内部状态及能力 // 暴露内部状态及能力
defineExpose({ name, state }); defineExpose({ name, state });
</script> </script>
// TODO 树节点待支持图标和自定义绘制
<template> <template>
<a-tree <a-tree
class="app-tree{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}" class="app-tree{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}"
...@@ -46,13 +72,69 @@ defineExpose({ name, state }); ...@@ -46,13 +72,69 @@ defineExpose({ name, state });
:fieldNames="{ title: 'text', key: 'id' }" :fieldNames="{ title: 'text', key: 'id' }"
:checkable="state.isMultiple" :checkable="state.isMultiple"
:multiple="state.isMultiple" :multiple="state.isMultiple"
show-icon
v-model:expandedKeys="state.expandedKeys" v-model:expandedKeys="state.expandedKeys"
v-model:selectedKeys="state.selectedKeys" v-model:selectedKeys="state.selectedKeys"
@select="treeNodeSelect"> @select="treeNodeSelect">
<template #title="{ text, id }"> <template #icon="node">
<div class="app-tree-node"> <span class="app-tree-node__icon">
<span class="tree-node__title">\{{ text }}</span> <template v-if="node.iconCustomCode && node.iconScriptCode">
</div> <span :domPropsInnerHtml="getCustomIcon(node.iconScriptCode)"></span>
</template>
<template v-else-if="node.iconcls">
<i :class="node.iconcls"></i>
</template>
<template v-else-if="node.icon">
<img :src="node.icon" style='width:14px;height:14px;vertical-align: bottom;'/>
</template>
<template v-else-if="state.outputIconDefault">
<FileTextOutlined />
</template>
</span>
</template>
<template #title="node">
{{#if (and ctrl.psAppCounterRef ctrl.psAppCounterRef.psAppCounter)}}
<span
:class="['app-tree-node__text', node.cssName]"
:title="node.tooltip ? node.tooltip : node.text">
<a-badge v-if="node.counterId && counterData.hasOwnProperty(node.counterId)" class="node__text-badge" :count="counterData[node.counterId]">
<template v-if="node.textCustomCode && node.textScriptCode">
<span :domPropsInnerHtml="getCustomText(node.textScriptCode)"></span>
</template>
<template v-else-if="node.html">
<span :domPropsInnerHtml="node.html"></span>
</template>
<template v-else>
<span>\{{node.text}}</span>
</template>
</a-badge>
<template v-else>
<template v-if="node.textCustomCode && node.textScriptCode">
<span :domPropsInnerHtml="getCustomText(node.textScriptCode)"></span>
</template>
<template v-else-if="node.html">
<span :domPropsInnerHtml="node.html"></span>
</template>
<template v-else>
<span>\{{node.text}}</span>
</template>
</template>
</span>
{{else}}
<span
:class="['app-tree-node__text', node.cssName]"
:title="node.tooltip ? node.tooltip : node.text">
<template v-if="node.textCustomCode && node.textScriptCode">
<span :domPropsInnerHtml="getCustomText(node.textScriptCode)"></span>
</template>
<template v-else-if="node.html">
<span :domPropsInnerHtml="node.html"></span>
</template>
<template v-else>
<span>\{{node.text}}</span>
</template>
</span>
{{/if}}
</template> </template>
</a-tree> </a-tree>
</template> </template>
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册