提交 5fcc7d67 编写于 作者: sq3536's avatar sq3536

Merge remote-tracking branch 'origin/master'

......@@ -139,7 +139,7 @@ public class CodegenConfig {
}
else {
String path=file.getPath().replace("\\","/");
templateDefinitions.add(new TemplateDefinition(path.replace(this.getTemplateDir(),"").toString()));
templateDefinitions.add(new TemplateDefinition(Paths.get("/",path.replace(this.getTemplateDir(),"")).toString()));
}
}
......
{
"printWidth": 120,
"tabWidth": 2,
"semicolons": true,
"singleQuote": true,
"jsxQuotes": false,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "avoid",
"proseWrap": "never",
"htmlWhitespaceSensitivity": "ignore",
"vueIndentScriptAndStyle": false,
"endOfLine": "lf",
"overrides": [
{
"files": ".prettierrc",
"options": {
"parser": "json"
}
}
]
}
# Vue 3 + Typescript + Vite
This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
## Type Support For `.vue` Imports in TS
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's `.vue` type support plugin by running `Volar: Switch TS Plugin on/off` from VSCode command palette.
// Generated by 'unplugin-auto-import'
// We suggest you to commit this file into source control
declare global {
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const EffectScope: typeof import('vue')['EffectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
}
export {}
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/vue-next/pull/3399
declare module 'vue' {
export interface GlobalComponents {
DefaultViewLayout: typeof import('./src/components/layout/DefaultViewLayout/DefaultViewLayout.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
IconText: typeof import('./src/components/render/IconText/IconText.vue')['default']
}
}
export { }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
{
"name": "ibiz-vue3",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"dependencies": {
"element-plus": "^1.2.0-beta.6",
"font-awesome": "^4.7.0",
"qx-util": "^0.0.10",
"ramda": "^0.27.1",
"rxjs": "^7.4.0",
"vue": "^3.2.23",
"vue-global-api": "^0.4.1"
},
"devDependencies": {
"@types/node": "^16.11.12",
"@types/ramda": "^0.27.60",
"@types/sass": "^1.43.1",
"@vitejs/plugin-vue": "^1.10.2",
"sass": "^1.45.0",
"typescript": "^4.4.4",
"unplugin-auto-import": "^0.5.3",
"unplugin-vue-components": "^0.17.9",
"vite": "^2.7.0",
"vue-tsc": "^0.28.10"
}
}
<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import { EditView } from './views/EditView'
</script>
<template>
<EditView :context="{}" />
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
\ No newline at end of file
export * from './custom'
export * from './editors'
export * from './layout'
export * from './render'
\ No newline at end of file
<script setup lang="ts">
// props声明和默认值处理
interface Props {
viewCaption?: string
showHeader?: boolean
}
const props = withDefaults(defineProps<Props>(), {
// 设定默认值,可选属性可以在这初始化
showHeader: true,
})
const slots = useSlots();
const showHeader = computed(()=> props.showHeader && (props.viewCaption || slots.header || slots['header-left'] || slots['header-left'] || slots['header-right'] || slots['header-bottom']))
</script>
<template>
<div class="ibiz-view-layout ibiz-view-layout--default">
<div v-if="showHeader" class="ibiz-view-layout__header">
<div class="ibiz-view-layout__header-content">
<slot name="header">
<div class="ibiz-view-layout__header-left">
<slot name="header-left">{{$props.viewCaption}}</slot>
</div>
<div class="ibiz-view-layout__header-right">
<slot name="header-right" />
</div>
</slot>
</div>
<slot name="header-bottom" />
</div>
<slot />
<slot name="footer" />
</div>
</template>
<style lang="scss" scoped>
.ibiz-view-layout {
height: 100%;
width: 100%;
}
.ibiz-view-layout__header-content{
display: flex;
justify-content: space-between;
.ibiz-view-layout__caption{
font-weight: 600;
}
}
</style>
\ No newline at end of file
import DefaultViewLayout from './DefaultViewLayout.vue'
export const IbizDefaultViewLayout = DefaultViewLayout;
\ No newline at end of file
<script setup lang="ts">
// props声明和默认值处理
interface Props {
text?: string
iconClass?: string,
imgPath?: string,
position?: 'left' | 'right',
size?: 'large' | 'default' | 'small',
}
const props = withDefaults(defineProps<Props>(), {
position: 'left',
size: 'default',
})
const hasIcon = computed(() => props.iconClass || props.imgPath)
const extraClass = {
"ibiz-icon-text--no-icon": !hasIcon.value,
[`ibiz-icon-text--${props.position}`]: hasIcon.value,
}
</script>
<template>
<div
:class="[
{
[`ibiz-icon-text--${$props.position}`]: hasIcon,
},
`ibiz-icon-text--${$props.size}`,
'ibiz-icon-text'
]"
>
<template v-if="$props.position == 'left'">
<i v-if="$props.iconClass" :class="'ibiz-icon-text__icon ' + $props.iconClass" />
<img v-else-if="$props.imgPath" class="ibiz-icon-text__icon-img" :src="$props.imgPath" />
</template>
<span class="ibiz-icon-text__text" v-if="$props.text">{{ $props.text }}</span>
<template v-if="$props.position == 'right'">
<i v-if="$props.iconClass" :class="'ibiz-icon-text__icon ' + $props.iconClass" />
<img v-else-if="$props.imgPath" class="ibiz-icon-text__icon-img" :src="$props.imgPath" />
</template>
</div>
</template>
<style lang="scss" scoped>
// 基线对齐
.ibiz-icon-text__icon,.ibiz-icon-text__icon-img{
vertical-align: bottom;
}
// 默认大小
.ibiz-icon-text--default{
font-size: 16px;
.ibiz-icon-text__icon,.ibiz-icon-text__icon-img{
width: 16px;
height: 16px;
}
}
.ibiz-icon-text--large{
font-size: 24px;
.ibiz-icon-text__icon,.ibiz-icon-text__icon-img{
width: 24px;
height: 24px;
}
}
// 位置
.ibiz-icon-text--left .ibiz-icon-text__text{
margin-left: 5px;
}
.ibiz-icon-text--right .ibiz-icon-text__text{
margin-right: 5px;
}
</style>
\ No newline at end of file
import IconText from './IconText.vue'
export const IbizIconText = IconText;
\ No newline at end of file
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
export * from './interface';
export * from './modules';
export * from './runtime';
export * from './service';
export * from './utils'
\ No newline at end of file
import { IParam } from "./i-param";
/**
* @description 视图状态参数
* @export
* @interface IActionParam
*/
export interface IActionParam {
/**
* @description 标识(视图名称、部件名称、编辑器名称,统一使用codename)
* @type {string}
* @memberof IActionParam
*/
tag: string;
/**
* @description 触发行为
* @type {('LOAD' | 'SAVE' | 'REMOVE' | 'AUTOLOAD' | 'LOADDRAFT' | 'FILTER' | 'REFRESH_PARENT' | string)}
* @memberof IActionParam
*/
action: 'LOAD' | 'SAVE' | 'REMOVE' | 'AUTOLOAD' | 'LOADDRAFT' | 'FILTER' | 'REFRESH_PARENT' | string;
/**
* @description 数据
* @type {IParam}
* @memberof IActionParam
*/
data: IParam;
}
\ No newline at end of file
export interface ControlAction {
/**
* 加载行为(单数据)
*/
loadAction?: string;
/**
* 获取行为(多数据)
*/
fetchAction?: string;
/**
* 加载草稿行为
*/
loadDraftAction?: string;
/**
* 新建行为
*/
createAction?: string;
/**
* 删除行为
*/
removeAction?: string;
/**
* 更新行为
*/
updateAction?: string;
}
export * from './i-context';
export * from './i-param';
export * from './i-action-param';
export * from './i-control-action';
\ No newline at end of file
import { Ref } from 'vue';
import { deepCopy } from '../../utils';
/**
* 为源响应式对象上的某个属性新创建一个单向的Ref,类似于vue的toRef但区别在于,修改返回的Ref,不会影响源响应对象的该属性。而源响应对象上的属性值变化会响应式影响到返回的Ref
*
* @param object 源响应对象,可以是ref对象,也可以是reactive对象
* @param key 响应对象上的属性的key值
*
* ```ts
* const object = ref({foo: 1});
* // 或者 const object = reactive({foo: 1})
* const foo = toOneWayRef(object, 'foo');
* foo.value = 2;
* console.log(object.foo) // 1
* console.log(foo.value) // 2
* object.foo = 3
* console.log(object.foo) // 3
* console.log(foo.value) // 3
* ```
* ps:如果要维持props的父对于props修改的响应性,props必须是Ref
* ```ts
* const father = reactive({ props: { foo: 1 }})
* const props = toRef(father,'props');
* const foo = toOneWayRef(props, 'foo');
* const foo1 = toOneWayRef(props.value,'foo')
* father.props = {foo: 3}
* console.log(father.props.foo) // 3
* console.log(foo.value) // 3
* console.log(foo1.value) // 1
* ```
*
*/
export function toOneWayRef<T extends object, K extends keyof T>(object: Ref<T> | T, key: K): Ref<T[K]>{
// 创建空的Ref
const propertyRef: Ref<T[K]> = ref({}) as any;
// 用watch来监听源响应对象的key属性,并建立单向响应
watch(
() => isRef(object) ? (object.value as T)[key] : object[key],
(newVal: any, oldVal: any) => {
// 用immediate来初始化最初的值,用deepCopy来切断与源值的关联
propertyRef.value = deepCopy(newVal) as T[K];
},
{
immediate: true,
deep: true,
},
);
return propertyRef;
}
export * from './common'
export * from './views'
export * from './widgets'
\ No newline at end of file
import { MainViewProps } from "@ibiz-core";
/**
* 编辑视图props
*/
export interface EditViewProps extends MainViewProps {
}
\ No newline at end of file
import { MainViewState } from "@ibiz-core";
/**
* 编辑视图状态
*/
export interface EditViewState extends MainViewState {
}
\ No newline at end of file
import { EditViewProps, EditViewState, MainView } from '@ibiz-core';
/**
* 编辑视图
* @export
* @class ViewBase
*/
export class EditView extends MainView {
/**
* 视图状态
*/
public declare viewState: EditViewState;
/**
* 使用加载功能模块
* @param props 传入的props
*/
public useLoad(props: EditViewProps){
const { viewSubject } = this.viewState;
onMounted(()=>{
viewSubject.next({tag: 'form', action: "load", data: {}})
})
}
/**
* 安装视图所有功能模块的方法
* @param props 传入的Props
* @param [emit] 事件
*/
public moduleInstall(props: EditViewProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
this.useLoad(props);
return {
...superParams,
state: this.viewState,
};
}
}
export * from './edit-view-prop'
export * from './edit-view-state'
export * from './edit-view'
\ No newline at end of file
export * from './view-base'
export * from './main-view'
export * from './edit-view'
\ No newline at end of file
export * from './main-view-prop'
export * from './main-view-state'
export * from './main-view'
\ No newline at end of file
import { ViewPropsBase } from '@ibiz-core';
/**
* 实体部件的props
*/
export interface MainViewProps extends ViewPropsBase {
}
import { ControlAction, ViewStateBase } from '@ibiz-core';
/**
* 实体部件状态
*/
export interface MainViewState extends ViewStateBase {
/**
* 视图所有部件的部件行为
*/
controlsAction: Record<string,ControlAction>;
}
import { ViewBase, MainViewProps, MainViewState } from '@ibiz-core';
/**
* 实体部件
* @export
* @class ViewBase
*/
export class MainView extends ViewBase {
/**
* 部件状态
*/
public declare viewState: MainViewState;
/**
* 根据props调整设置部件state
* @param props 传入的Props
*/
public setState(props: MainViewProps) {
super.setState(props);
// 只读属性处理:把props的属性的Ref赋给state,以维持响应性。
}
/**
* 打开编辑视图功能模块
* @todo
* @param props
*/
public useOpenData(props: MainViewProps) {}
/**
* 打开新建视图功能模块
* @todo
* @param props
*/
public useNewData(props: MainViewProps) {}
/**
* 安装部件所有功能模块的方法
* @param props 传入的Props
* @param [emit] 事件
*/
public moduleInstall(props: MainViewProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
return {
...superParams,
state: this.viewState,
};
}
}
export * from './view-prop-base'
export * from './view-state-base'
export * from './view-base'
\ No newline at end of file
import { ViewPropsBase, ViewStateBase, toOneWayRef } from '@ibiz-core';
/**
* 视图基类
*/
export class ViewBase {
/**
* 视图状态
*/
public viewState: ViewStateBase;
/**
* 构造方法,初始化状态
* @param {*} options 配置参数
*/
constructor(options: any) {
this.viewState = reactive(options);
}
/**
* 根据props调整设置部分视图基类
* @param props 传入的Props
*/
public setState(props: ViewPropsBase) {
// todo 项目级配置入口,优先级大于平台,提供全局的一次性配置
// 只读属性处理:把props的属性的Ref赋给state,以维持响应性。
this.viewState.viewSubject = toRef(props, 'viewSubject') as any;
}
/**
* 使用视图上下文参数逻辑块
* @param props 传入的Props
*/
public useViewContextParams(props: ViewPropsBase) {
const context = toOneWayRef(props, 'context');
const viewParams = toOneWayRef(props, 'viewParams');
// 把Ref赋值到State上进行解包
this.viewState.context = context;
this.viewState.viewParams = viewParams;
// 视图部分额外处理
// todo 导航参数处理,自定义参数处理。
// todo viewparams 视图级隔离,如果没有用导航参数这些指定,则把上一层的都消除。
return { context, viewParams };
}
/**
* 使用计数器服务模块
* @todo
* @param props
*/
public useCounterService(props: ViewPropsBase){}
/**
* 安装视图所有功能模块的方法
* @param props 传入的Props
* @param [emit] 事件
*/
public moduleInstall(props: ViewPropsBase, emit?: Function) {
this.setState(props);
this.useViewContextParams(props);
this.useCounterService(props);
return {
state: this.viewState,
};
}
}
import { Subject } from "rxjs";
/**
* 视图props的基类
*/
export interface ViewPropsBase {
/**
* 上下文参数(外部传入)
*/
context?: any;
/**
* 视图参数(外部传入)
*/
viewParams?: any;
/**
* 视图参数(外部传入)
*/
viewSubject?: Subject<any>;
/**
* 视图打开方式,路由、模态、内嵌,默认为路由方式
*/
openType?: "ROUTE" | "MODAL" | "EMBED";
}
\ No newline at end of file
import { Subject } from "rxjs";
/**
* 视图基类状态
*/
export interface ViewStateBase {
/**
* 视图名称
*/
viewName: string;
/**
* 视图代码名称
*/
viewCodeName: string;
/**
* 上下文参数
*/
context: any;
/**
* 视图参数
*/
viewParams: any;
/**
* 视图参数(外部传入)
*/
viewSubject: Subject<any>;
// 声明任意属性
[propName: string]: any;
}
import { ControlPropsBase, ControlStateBase, toOneWayRef } from '@ibiz-core';
/**
* 部件基类
*/
export class ControlBase {
/**
* 部件状态
*/
public controlState: ControlStateBase;
/**
* 构造方法,初始化状态
* @param {*} options 配置参数
*/
constructor(options: any) {
this.controlState = reactive(options);
}
/**
* 根据props调整设置部分部件基类
* @param props 传入的Props
*/
public setState(props: ControlPropsBase) {
// toDo 项目级配置入口,优先级大于平台,提供全局的一次性配置
// 只读属性处理:把props的属性的Ref赋给state,以维持响应性。
this.controlState.viewSubject = toRef(props, 'viewSubject') as any;
}
/**
* 使用部件上下文参数逻辑块
* @param props 传入的Props
*/
public useControlContextParams(props: ControlPropsBase) {
const context = toOneWayRef(props, 'context');
const viewParams = toOneWayRef(props, 'viewParams');
// 把Ref赋值到State上进行解包
this.controlState.context = context;
this.controlState.viewParams = viewParams;
return { context, viewParams };
}
/**
* 安装部件所有功能模块的方法
* @param props 传入的Props
* @param [emit] 事件
*/
public moduleInstall(props: ControlPropsBase, emit?: Function) {
this.setState(props);
this.useControlContextParams(props);
return {
state: this.controlState,
};
}
}
import { Subject } from "rxjs";
/**
* 部件props的基类
*/
export interface ControlPropsBase {
/**
* 上下文参数(外部传入)
*/
context?: any;
/**
* 视图参数(外部传入)
*/
viewParams?: any;
/**
* 视图参数(外部传入)
*/
viewSubject: Subject<any>;
}
\ No newline at end of file
import { Subject } from "rxjs";
/**
* 部件基类状态
*/
export interface ControlStateBase {
/**
* 部件名称
*/
controlName: string;
/**
* 部件代码名称
*/
controlCodeName: string;
/**
* 上下文参数
*/
context: any;
/**
* 视图参数
*/
viewParams: any;
/**
* 视图参数(外部传入)
*/
viewSubject: Subject<any>;
// 声明任意属性
// [propName: string]: any;
}
\ No newline at end of file
export * from './control-prop-base'
export * from './control-state-base'
export * from './control-base'
\ No newline at end of file
import { MainControlProps } from "@ibiz-core";
/**
* 表单部件的props
*/
export interface FormControlProps extends MainControlProps {
}
\ No newline at end of file
import { MainControlState } from '@ibiz-core';
/**
* 表单部件状态
*/
export interface FormControlState extends MainControlState {
/**
* 表单数据对象
*/
data: any;
}
import { deepCopy, FormControlProps, FormControlState, MainControl } from '@ibiz-core';
import { SyncSeriesHook } from "qx-util";
/**
* 表单部件
* @export
* @class ControlBase
*/
export class FormControl extends MainControl {
/**
* 部件状态
*/
public declare controlState: FormControlState;
/**
* 修改表单的数据对象的某一属性的值。
* 可通过模块扩展增加一系列相关后续操作。
* @param name 属性名称
* @param value 属性值
*/
public async formDataChange(name: string, value: any){
this.controlState.data[name] = value;
}
/**
* 使用加载功能模块
* @param props 传入的props
*/
public useLoad(props: FormControlProps){
const { viewSubject, controlName } = this.controlState;
/**
* 加载方法
* @param [opt={}]
*/
const load = async (opt: any = {})=>{
try {
const loadAction = this.controlState.controlAction.loadAction;
const { controlService, context, viewParams, showBusyIndicator } = this.controlState;
const dataRef = toRef(this.controlState, 'data');
if(!loadAction){
return;
}
let _context = deepCopy(context);
let _viewParams = deepCopy(viewParams);
const response = await controlService.get(loadAction, _context, {viewParams: _viewParams}, showBusyIndicator );
if (!response.status || response.status !== 200) {
return
}
dataRef.value = response.data;
} catch (error) {
// todo 错误异常处理
}
}
// 订阅viewSubject,监听load行为
if(viewSubject){
let subscription = viewSubject.subscribe((args: any)=>{
if(args.tag == controlName && args.action == "load"){
load(args.data)
}
})
// 部件卸载时退订viewSubject
onUnmounted(()=>{
subscription.unsubscribe();
})
}
return {
load: load
}
}
/**
* 安装部件所有功能模块的方法
* @param props 传入的Props
* @param [emit] 事件
*/
public moduleInstall(props: FormControlProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
const { load } = this.useLoad(props)
// 扩展表单数值变化的后续逻辑
const superFormDataChange = this.formDataChange.bind(this);
this.formDataChange = async (name: string , value: any) => {
await superFormDataChange(name, value)
}
return {
...superParams,
state: this.controlState,
load,
formDataChange: this.formDataChange,
};
}
}
export * from './form-control-prop'
export * from './form-control-state'
export * from './form-control'
\ No newline at end of file
export * from './control-base'
export * from './main-control'
export * from './form-control'
\ No newline at end of file
export * from './main-control-prop'
export * from './main-control-state'
export * from './main-control'
\ No newline at end of file
import { ControlAction, ControlPropsBase } from "@ibiz-core";
/**
* 实体部件的props
*/
export interface MainControlProps extends ControlPropsBase {
/**
* 是否显示处理提示(外部控制,优先级高于state)
*/
showBusyIndicator?: boolean;
/**
* 部件行为
*/
controlAction: ControlAction;
}
\ No newline at end of file
import { ControlAction, ControlStateBase } from "@ibiz-core";
/**
* 实体部件状态
*/
export interface MainControlState extends ControlStateBase {
/**
* 是否显示处理提示
*/
showBusyIndicator?: boolean;
/**
* 部件行为
*/
controlAction: ControlAction;
/**
* 部件服务
*/
controlService: any
}
\ No newline at end of file
import { ControlBase, MainControlProps, MainControlState } from '@ibiz-core';
/**
* 实体部件
* @export
* @class ControlBase
*/
export class MainControl extends ControlBase {
/**
* 部件状态
*/
public declare controlState: MainControlState;
/**
* 根据props调整设置部件state
* @param props 传入的Props
*/
public setState(props: MainControlProps) {
super.setState(props);
// 只读属性处理:把props的属性的Ref赋给state,以维持响应性。
this.controlState.showBusyIndicator = toRef(props, 'showBusyIndicator') as any;
this.controlState.controlAction = toRef(props, 'controlAction') as any;
}
/**
* 安装部件所有功能模块的方法
* @param props 传入的Props
* @param [emit] 事件
*/
public moduleInstall(props: MainControlProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
return {
...superParams,
state: this.controlState,
};
}
}
import { deepCopy } from '@ibiz-core';
export class ControlVOBase {
/**
* 后台数据对象
* @protected
*/
protected $DO: any = {};
/**
* 自有属性名称集合
*/
public $ownKeys: string[] = [];
/**
* 用后台数据对象创建部件数据对象
* @param data 后台数据
*/
constructor(data?: any) {
this.setDo(data);
}
/**
* 拷贝后台原始数据对象并保存在$DO里面
* @param data 后台数据
*/
public setDo(data: any) {
if (data) {
this.$DO = deepCopy(data);
}
}
/**
* 返回后台数据
* 已经深拷贝可以修改赋值。
*/
public getDo() {
return deepCopy(this.$DO);
}
/**
* 清空数据对象,会做以下操作:
* - 后台数据$DO赋值{}
* - 没有后台映射的自有属性赋值undefined
* - delete其他非保留属性
*/
public clear() {
for (const key of Object.keys(this)) {
if (key == '$DO') {
// 后台数据$DO赋值{}
this.$DO = {};
} else if (this.$ownKeys.indexOf(key) != -1) {
// 没有后台映射的自有属性赋值undefined
this[key] = undefined;
} else if (key != '$ownKeys') {
// delete其他非保留属性
delete this[key];
}
}
}
/**
* 用后台数据重置数据对象
* @param data 后台数据
*/
public reSet(data: any){
this.clear();
this.setDo(data);
}
// 声明任意属性
[propName: string]: any;
}
export class ControlServiceBase {
/**
* 请求前处理函数
*
* @param [context={}]
* @param [data={}]
* @param [opts={}]
*/
public handleRequestData(context: any, data: any, opts: any = {}) {
return { context, data };
}
/**
* 请求后处理函数
*
* @param [context={}]
* @param [data={}]
* @param [opts={}]
*/
public handleResponse(response: any, opts: any = {}) {
return response;
}
}
/**
* 实体服务基类
* @export
* @class EntityService
*/
export class EntityService{
// TODO
public GET(){}
}
\ No newline at end of file
export * from './control-service'
export * from './entity'
\ No newline at end of file
import { clone } from 'ramda';
/**
* 克隆方法
* @param {Record<any, any>} data
* @return {*} {Record<any, any>}
*/
export function deepCopy(data: Record<any, any>): Record<any, any> {
return clone(data);
}
/**
* 除undefined,null,NaN以外都为true
* @param {*} arg
* @return {*} {boolean}
*/
export function hasValue(arg: any): boolean {
return arg !== undefined && arg !== null && arg === arg;
}
/**
* 判断是否是对象
* @param val
* @return {*}
*/
export function isObject(val: any) {
return val !== null && typeof val === 'object';
}
import 'font-awesome/css/font-awesome.min.css'
import '@/style/index.scss'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
import {{page.codeName}} from "./{{page.codeName.spinalCase}}.vue";
export { {{page.codeName}} };
export const ViewConfig = {
viewCodeName: '{{page.codeName}}',
viewName: '{{page.name}}',
viewCaption: '{{page.caption}}',
{{#page.ctrls}}
{{#eq controlType "TOOLBAR"}}
{{lowerCase codeName}}:{
name:'{{name}}',
items:[
{{#pSDEToolbarItems}}
{ name:'{{name}}',caption:'{{caption}}',groupExtractMode:'{{groupExtractMode}}',itemType:'{{itemType}}',noPrivDisplayMode:'{{noPrivDisplayMode}}',showIcon:{{showIcon}},showCaption:{{showCaption}},tooltip:'{{tooltip}}' },
{{/pSDEToolbarItems}}
]
},
{{/eq}}
{{#eq controlType "FORM"}}
{{lowerCase codeName}}:{
name:'{{name}}',
codeName:'{{codeName}}',
action:{
'createAction': 'Create'
}
}
{{/eq}}
{{/page.ctrls}}
};
\ No newline at end of file
edit@
{{page.codeName}}--{{page.appModule}}
getPSAppDataEntity {{page.getPSAppDataEntity.codeName}}
psAppDataEntity {{page.psAppDataEntity.codeName}}
pSAppDataEntity {{page.pSAppDataEntity.codeName}}
<script setup lang="ts">
import { Subject } from 'rxjs'
import { EditView, IActionParam } from '@ibiz-core'
import { ViewConfig } from './{{page.codeName.spinalCase}}-config'
{{#page.ctrls}}
这里是页面视图 ctrl的代码名称 {{codeName}}
{{/page.ctrls}}
{{#neq controlType "TOOLBAR"}}
import { {{codeName}} } from '@widgets/{{appEntity.codeName.spinalCase}}/{{codeName.spinalCase}}';
{{/neq}}
{{/page.ctrls}}
import { IbizDefaultViewLayout, IbizIconText } from '@components';
// props声明和默认值处理
interface Props {
context: any;
viewParams?: any;
openType?: "ROUTE" | "MODAL" | "EMBED";
viewSubject?: Subject<any>;
}
const props = withDefaults(defineProps<Props>(), {
// 设定默认值,可选属性可以在这初始化
viewSubject: () => new Subject<any>()
})
// emit声明
interface ViewEmit {
(name: "CLOSE", value: IActionParam): void;
(name: "VIEWCHANGE", value: IActionParam): void;
}
const emit = defineEmits<ViewEmit>();
// 安装功能模块,提供状态和能力方法
const { state } = new EditView(ViewConfig).moduleInstall(props);
</script>
<template>
<IbizDefaultViewLayout class="ibiz-edit-view">
<template v-slot:header-left>
<IbizIconText class="ibiz-view__caption" size="large" text="state.viewCaption" />
</template>
<template v-slot:header-right>
<span>工具栏部件</span>
</template>
<EditForm
:showBusyIndicator="true"
:context="state.context"
:viewParams="state.viewParams"
:controlAction="state.controlsAction"
:viewSubject="state.viewSubject"
></EditForm>
</IbizDefaultViewLayout>
</template>
这里是页面视图所属应用实体的代码名称{{page.appEntity.codeName}}
\ No newline at end of file
<style scoped>
.ibiz-view-container {
height: 100%;
width: 100%;
}
</style>
\ No newline at end of file
// 通用样式
html,body{
height: 100%;
}
body{
margin: 0;
}
// 视图样式
.ibiz-view__caption{
font-weight: 600;
}
\ No newline at end of file
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"skipLibCheck": true,
"lib": ["esnext", "dom"],
"baseUrl": ".",
"paths": {
"@ibiz-core":["src/ibiz-core"],
"@ibiz-core/*":["src/ibiz-core/*"],
"@service":["src/service"],
"@service/*":["src/service/*"],
"@components":["src/components"],
"@components/*":["src/components/*"],
"@views":["src/views"],
"@views/*":["src/views/*"],
"@widgets":["src/widgets"],
"@widgets/*":["src/widgets/*"],
"@static":["public"],
"@static/*":["public/*"],
"@/*": ["src/*"],
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "components.d.ts","auto-imports.d.ts"],
"exclude": ["node_modules"]
}
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
// 自动导入element-plus
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
'@ibiz-core': path.resolve(__dirname, 'src/ibiz-core'),
'@service': path.resolve(__dirname, 'src/service'),
'@components': path.resolve(__dirname, 'src/components'),
'@views': path.resolve(__dirname, 'src/views'),
'@widgets': path.resolve(__dirname, 'src/widgets'),
'@static': path.resolve(__dirname, 'public'),
'@': path.resolve(__dirname, 'src'),
},
},
plugins: [
vue(),
// 自动导入
AutoImport({
imports: ['vue'],
resolvers: [ElementPlusResolver()],
}),
Components({
dts: true,
resolvers: [ElementPlusResolver()],
}),
],
});
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册