diff --git a/packages/canvas/DesignCanvas/src/api/useCanvas.ts b/packages/canvas/DesignCanvas/src/api/useCanvas.ts index 273c7b82..e247bf99 100644 --- a/packages/canvas/DesignCanvas/src/api/useCanvas.ts +++ b/packages/canvas/DesignCanvas/src/api/useCanvas.ts @@ -592,7 +592,7 @@ const exportSchema = () => { return JSON.stringify(pageState.pageSchema) } -const getSchema = () => { +const getSchema = (): RootNode | object => { return pageState.pageSchema || {} } diff --git a/packages/canvas/container/src/container.ts b/packages/canvas/container/src/container.ts index 0d3bd851..e86fa26f 100644 --- a/packages/canvas/container/src/container.ts +++ b/packages/canvas/container/src/container.ts @@ -945,7 +945,7 @@ export const addScript = (src: string) => appendScript(src, getDocument()) * @param {*} messages * @param {*} merge 是否合并,默认是重置所有数据 */ -export const setLocales = (messages: any, merge: any) => { +export const setLocales = (messages: any, merge?: boolean) => { const i18n = getRenderer().getI18n() Object.keys(messages).forEach((lang) => { diff --git a/packages/canvas/types.ts b/packages/canvas/types.ts index 5702a845..31a691b9 100644 --- a/packages/canvas/types.ts +++ b/packages/canvas/types.ts @@ -8,7 +8,7 @@ export interface Node { export type RootNode = Omit & { id?: string css?: string - fileName: string + fileName?: string methods?: Record state?: Record lifeCycles?: Record @@ -16,4 +16,5 @@ export type RootNode = Omit & { bridge?: any inputs?: any[] outputs?: any[] + schema?: any } diff --git a/packages/common/component/Modal.tsx b/packages/common/component/Modal.tsx index 8e350e41..189255bf 100644 --- a/packages/common/component/Modal.tsx +++ b/packages/common/component/Modal.tsx @@ -1,7 +1,18 @@ import { h, render } from 'vue' import { Modal } from '@opentiny/vue' -const confirm = ({ title, status, message, exec, cancel, showFooter = true }) => { +export interface ModalOptions { + title: string + status?: string + message: string | ((...args: any[]) => any) + exec?: (...args: any[]) => any + cancel?: (...args: any[]) => any + showFooter?: boolean +} + +export type ConfirmOptions = ModalOptions + +const confirm = ({ title, status, message, exec, cancel, showFooter = true }: ConfirmOptions) => { Modal.confirm({ title, status, @@ -13,7 +24,7 @@ const confirm = ({ title, status, message, exec, cancel, showFooter = true }) => ) } - }).then((res) => { + }).then((res: string) => { if (res === 'confirm' && typeof exec === 'function') { exec() } else if (typeof cancel === 'function') { @@ -22,7 +33,9 @@ const confirm = ({ title, status, message, exec, cancel, showFooter = true }) => }) } -const message = ({ title, status, message, exec, width = '400' }) => { +export type MessageOptions = Pick & { width?: string } + +const message = ({ title, status, message, exec, width = '400' }: MessageOptions) => { Modal.alert({ title, status, @@ -42,13 +55,13 @@ const message = ({ title, status, message, exec, width = '400' }) => { }) } -const topbox = (options) => { +const topbox = (options: ModalOptions) => { const props = { ...options, modelValue: true } let TopBox = h(Modal, props) const modalEl = document.createElement('div') const close = () => { - TopBox.el.remove() + TopBox.el?.remove() TopBox = null } @@ -60,6 +73,13 @@ const topbox = (options) => { } } +declare global { + interface Window { + topbox?: (options: ModalOptions) => { TopBox: any; close: () => void } + message?: (options: MessageOptions) => void + } +} + window.topbox = topbox window.message = message diff --git a/packages/common/component/Notify.tsx b/packages/common/component/Notify.tsx index c6b99aaa..5846337d 100644 --- a/packages/common/component/Notify.tsx +++ b/packages/common/component/Notify.tsx @@ -9,10 +9,11 @@ const durationMap = { export interface NotifyOptions { [key: string]: any - customClass: string - title: string + title?: string + message: string type: keyof typeof durationMap - position: string + customClass?: string + position?: string } const useNotify = (config: NotifyOptions) => { diff --git a/packages/layout/src/composable/useLayout.js b/packages/layout/src/composable/useLayout.js index 8595eb2f..0d54dc4c 100644 --- a/packages/layout/src/composable/useLayout.js +++ b/packages/layout/src/composable/useLayout.js @@ -59,7 +59,10 @@ const layoutState = reactive({ toolbars: { visiblePopover: false }, - pageStatus: '' + pageStatus: { + state: '', + data: {} + } }) const getMoveDragBarState = () => { return layoutState.isMoveDragBar diff --git a/packages/plugins/block/src/composable/types.ts b/packages/plugins/block/src/composable/types.ts new file mode 100644 index 00000000..5c2132a8 --- /dev/null +++ b/packages/plugins/block/src/composable/types.ts @@ -0,0 +1,107 @@ +export interface Property { + label: { + zh_CN?: string + } + description: { + zh_CN?: string + } + collapse: { + number: number + text: { + zh_CN?: string + } + } + content?: BlockProperty[] +} + +export interface BlockContent { + componentName: string + blockName?: string + fileName: string + css?: string + props: Record + children: any[] + schema: { + properties?: Property[] + events?: Record + } + state?: Record + methods: Record + dataSource?: Record + i18n?: any +} + +export interface BlockOccupier { + id: number + username: string + resetPasswordToken: string +} + +export interface Block { + id?: string | number + name_cn?: string + label: string + path?: string + categories: string[] + public: number + is_published?: number + framework: string + content: BlockContent + occupier?: BlockOccupier | null + created_at?: string | Date + updated_at?: string | Date + histories?: any[] + assets?: any +} + +export interface BlockGroup { + id: string + name: string + desc: string + app: { + id: string | number + name: string + } + blocks: { data: Block }[] + groupId: string + groupName: string +} + +export interface BlockProperty { + linked?: { property: any; blockProperty: any } | null + property: any + defaultValue: any + widget?: any +} + +export interface SchemaData { + langs: Record + methods: Record + state: Record + classNameList: string[] + contentList: any[] +} + +export type ParsePropToDataOptons = Pick & { + prop: { + type: string + key: string + value: any + } +} + +export type ParseChildPropsOptions = Pick & { + child: { + props: Record + [x: string]: any + } +} + +export interface CreateBlockOptions { + name_cn: string + label: string + path?: string + categories: string[] +} + +export type CreateEmptyBlockOptions = Pick diff --git a/packages/plugins/block/src/composable/useBlock.ts b/packages/plugins/block/src/composable/useBlock.ts index 750e8523..a6a93460 100644 --- a/packages/plugins/block/src/composable/useBlock.ts +++ b/packages/plugins/block/src/composable/useBlock.ts @@ -10,7 +10,7 @@ * */ -import { ref, reactive, readonly } from 'vue' +import { ref, reactive, readonly, type DeepReadonly } from 'vue' import { hyphenate } from '@vue/shared' import { extend, copyArray } from '@opentiny/vue-renderless/common/object' import { format } from '@opentiny/vue-renderless/common/date' @@ -32,12 +32,24 @@ import { META_SERVICE } from '@opentiny/tiny-engine-meta-register' import meta from '../../meta' +import type { + Block, + BlockContent, + BlockGroup, + BlockProperty, + CreateBlockOptions, + CreateEmptyBlockOptions, + ParseChildPropsOptions, + ParsePropToDataOptons, + Property, + SchemaData +} from './types' const { SORT_TYPE, SCHEMA_DATA_TYPE, BLOCK_OPENNESS } = constants const NODE_TYPE_PAGE = 'Page' const nameCn = 'name_cn' -const DEFAULT_PROPERTIES = readonly([ +const DEFAULT_PROPERTIES = readonly([ { label: { zh_CN: '基础信息' @@ -55,7 +67,7 @@ const DEFAULT_PROPERTIES = readonly([ } ]) -const DEFAULT_BLOCK = readonly({ +const DEFAULT_BLOCK = readonly>({ componentName: 'Block', fileName: '', css: '', @@ -70,63 +82,63 @@ const DEFAULT_BLOCK = readonly({ dataSource: {} }) -const blockState = reactive({ +const blockState = reactive<{ list: Block[]; current: Block | null }>({ list: [], current: null // 当前画布中正在渲染的区块数据 }) // 区块分组信息 -const groupState = reactive({ +const groupState = reactive<{ list: BlockGroup[]; selected: BlockGroup | object }>({ list: [], selected: {} }) // 区块分类 -const categoryState = reactive({ +const categoryState = reactive<{ list: BlockGroup[] }>({ list: [] }) const getBlockList = () => blockState.list -const setBlockList = (list) => { +const setBlockList = (list: Block[]) => { blockState.list = list } -const addBlock = (block) => { +const addBlock = (block: Block) => { const blockList = getBlockList() blockList.unshift(block) } -const delBlock = (block) => { +const delBlock = (block: Block) => { remove(getBlockList(), block) } // 获取当前画布中的区块信息 const getCurrentBlock = () => blockState.current -const setCurrentBlock = (block) => { +const setCurrentBlock = (block: Block) => { blockState.current = block } const getGroupList = () => groupState.list -const setGroupList = (list) => { +const setGroupList = (list: BlockGroup[]) => { groupState.list = list } const getCategoryList = () => categoryState.list -const setCategoryList = (list) => { +const setCategoryList = (list: BlockGroup[]) => { categoryState.list = list } const getSelectedGroup = () => groupState.selected -const setSelectedGroup = (selected) => { +const setSelectedGroup = (selected: BlockGroup) => { groupState.selected = selected } -const copyCss = (css, classNameList) => { +const copyCss = (css: string, classNameList: string[]) => { classNameList = Array.from(new Set(classNameList)).map((item) => '.' + item) const cssObject = getCssObjectFromStyleStr(css) let styleStr = '' @@ -141,10 +153,10 @@ const copyCss = (css, classNameList) => { return styleStr } -const copySchema = (schema, contentList, methods) => { +const copySchema = (schema: Partial, contentList: string[], methods: Record) => { const content = schema?.properties?.[0]?.content || [] - let emitList = [] - const emitListCopies = {} + let emitList: string[] = [] + const emitListCopies: Record = {} Object.keys(methods).forEach((key) => { const item = JSON.stringify(methods[key].value).match(/emit..*?\)/g) @@ -154,10 +166,16 @@ const copySchema = (schema, contentList, methods) => { }) emitList.forEach((e) => { - let key = e.match(/'.*?'/g)[0].replace(/'/g, '') + const matches = e.match(/'.*?'/g) + + if (!matches || !matches.length) { + return + } + + let key = matches[0].replace(/'/g, '') key = `on${key[0].toLocaleUpperCase() + key.slice(1, key.length)}` - if (schema?.events[key]) { + if (schema?.events?.[key]) { emitListCopies[key] = schema?.events[key] } }) @@ -174,12 +192,12 @@ const copySchema = (schema, contentList, methods) => { return schemaCopies } -const copyMethods = (schema) => { - const methodsListCopies = {} +const copyMethods = (schema: Record) => { + const methodsListCopies: Record = {} // 因为methods方法里面大部分是用户的业务代码(无法复用),所以只需要拷贝一个空方法即可 Object.entries(schema).forEach(([key, value]) => { - const ast = parseExpression(value.value) + const ast: any = parseExpression(value.value) // 清空函数体 if (ast.body?.body) { @@ -194,8 +212,8 @@ const copyMethods = (schema) => { return methodsListCopies } -const copyState = (stateObj = {}, methodsObj = {}) => { - const stateCopies = {} +const copyState = (stateObj: Record = {}, methodsObj: Record = {}) => { + const stateCopies: Record = {} const stateKey = Object.keys(stateObj).map((e) => `state.${e} `) stateKey.forEach((e) => { @@ -210,7 +228,7 @@ const copyState = (stateObj = {}, methodsObj = {}) => { return stateCopies } -const parsePropToData = (data, { prop, langs, state, methods }) => { +const parsePropToData = (data: SchemaData, { prop, langs, state, methods }: ParsePropToDataOptons) => { if (prop.type === SCHEMA_DATA_TYPE.I18n) { data.langs[prop.key] = langs[prop.key] } else if (prop.type === SCHEMA_DATA_TYPE.JSExpression) { @@ -228,9 +246,9 @@ const parsePropToData = (data, { prop, langs, state, methods }) => { } const filterDataFn = - (parseChildProps) => - ({ children = [], langs = {}, methods = {}, state = {} }) => { - const data = { + (parseChildProps: (...args: any[]) => any) => + ({ children = [] as any[], langs = {}, methods = {}, state = {} }) => { + const data: SchemaData = { langs: {}, methods: {}, state: {}, @@ -247,14 +265,14 @@ const filterDataFn = return data } -const parseChildProps = (data, { child, langs, state, methods }) => { +const parseChildProps = (data: SchemaData, { child, langs, state, methods }: ParseChildPropsOptions) => { if (child.props) { Object.entries(child.props).forEach(([propKey, prop]) => { if (typeof prop === 'object') { parsePropToData(data, { prop, langs, state, methods }) } else { if (propKey === 'className' && prop) { - data.classNameList.push(...prop.split(' ').filter((item) => item)) + data.classNameList.push(...prop.split(' ').filter((item: string) => item)) } } }) @@ -271,14 +289,14 @@ const parseChildProps = (data, { child, langs, state, methods }) => { } } -const getBlockPageSchema = (block) => { +const getBlockPageSchema = (block: Block) => { const content = block?.content || {} - content.componentName = content.componentName || content.blockName + content.componentName = content.componentName || content.blockName || '' return content } -const initBlock = async (block = {}, _langs = {}, isEdit) => { +const initBlock = async (block: any = {}, _langs = {}, isEdit?: boolean) => { const { resetBlockCanvasState, setSaved, getSchema } = useCanvas() const { setBreadcrumbBlock } = useBreadcrumb() @@ -305,7 +323,7 @@ const initBlock = async (block = {}, _langs = {}, isEdit) => { }) } -const createBlock = ({ name_cn, label, path, categories }) => { +const createBlock = ({ name_cn, label, path, categories }: CreateBlockOptions) => { const { pageState } = useCanvas() const schema = extend(true, {}, pageState.currentSchema) // 选中 body 节点创建区块时需传递子节点数据 @@ -320,20 +338,20 @@ const createBlock = ({ name_cn, label, path, categories }) => { filterData({ children, langs: getLangs(), - methods: pageState.pageSchema.methods, - state: pageState.pageSchema.state + methods: pageState.pageSchema?.methods, + state: pageState.pageSchema?.state }) ) - const css = copyCss(pageState.pageSchema.css, classNameList) + const css = copyCss(pageState.pageSchema?.css || '', classNameList) const methodsCopies = copyMethods(methods) Object.assign(methods, methodsCopies) - const schemaCopies = copySchema(pageState.pageSchema.schema, contentList, methods) - const stateCopies = copyState(pageState.pageSchema.state, methods) + const schemaCopies = copySchema(pageState.pageSchema?.schema, contentList, methods) + const stateCopies = copyState(pageState.pageSchema?.state, methods) Object.assign(state, stateCopies) - const block = { + const block: Block = { path, [nameCn]: name_cn, label, @@ -355,8 +373,8 @@ const createBlock = ({ name_cn, label, path, categories }) => { initBlock(block, langs) } -const createEmptyBlock = ({ name_cn, label, path, categories }) => { - const block = { +const createEmptyBlock = ({ name_cn, label, path, categories }: CreateEmptyBlockOptions) => { + const block: Block = { path, [nameCn]: name_cn, label, @@ -372,8 +390,8 @@ const createEmptyBlock = ({ name_cn, label, path, categories }) => { initBlock(block) } -const setComponentLinkedValue = ({ propertyName, value }) => { - const { schema } = useCanvas().canvasApi.value?.getCurrent() || {} +const setComponentLinkedValue = ({ propertyName, value }: { propertyName: string; value: any }) => { + const { schema } = useCanvas().canvasApi.value?.getCurrent?.() || {} if (!propertyName || !schema) { return @@ -383,28 +401,28 @@ const setComponentLinkedValue = ({ propertyName, value }) => { schema.props[propertyName] = value } -const getBlockI18n = (block) => block?.content?.i18n || {} +const getBlockI18n = (block: Block) => block?.content?.i18n || {} -const getBlockProperties = (block) => block?.content?.schema?.properties?.[0]?.content || [] +const getBlockProperties = (block: Block) => block?.content?.schema?.properties?.[0]?.content || [] -const addBlockProperty = (property, block) => { +const addBlockProperty = (property: BlockProperty, block: Block) => { if (!block) { return } if (!block.content) { - block.content = {} + block.content = {} as BlockContent } if (!block.content.schema) { - block.content.schema = {} + block.content.schema = {} as BlockContent['schema'] } if (!block.content.schema.properties) { block.content.schema.properties = copyArray(DEFAULT_PROPERTIES) } - block.content.schema.properties[0].content.push(property) + block.content.schema.properties?.[0].content?.push(property) if (property.linked) { setComponentLinkedValue({ @@ -417,7 +435,7 @@ const addBlockProperty = (property, block) => { } } -const editBlockProperty = (property, data) => { +const editBlockProperty = (property: BlockProperty, data: any) => { if (property.linked) { const value = { type: SCHEMA_DATA_TYPE.JSExpression, @@ -431,13 +449,13 @@ const editBlockProperty = (property, data) => { } } -const removePropertyLink = ({ componentProperty }) => { +const removePropertyLink = ({ componentProperty }: { componentProperty: BlockProperty }) => { const linked = componentProperty.linked componentProperty.linked = null - const properties = getBlockProperties(getCurrentBlock()) + const properties = getBlockProperties(getCurrentBlock()!) properties.forEach((property) => { - if (property.linked && property.property === linked.blockProperty) { + if (property.linked && property.property === linked?.blockProperty) { if (componentProperty.widget?.props?.modelValue) { componentProperty.widget.props.modelValue = property.defaultValue } @@ -452,19 +470,19 @@ const removePropertyLink = ({ componentProperty }) => { }) } -const getBlockEvents = (block = {}) => block?.content?.schema?.events || {} +const getBlockEvents = (block = {} as Block) => block?.content?.schema?.events || {} -const addBlockEvent = ({ name, event }, block) => { +const addBlockEvent = ({ name, event }: { name: string; event: any }, block: Block) => { if (!block) { return } if (!block.content) { - block.content = {} + block.content = {} as BlockContent } if (!block.content.schema) { - block.content.schema = {} + block.content.schema = {} as BlockContent['schema'] } if (!block.content.schema.events) { @@ -474,8 +492,8 @@ const addBlockEvent = ({ name, event }, block) => { block.content.schema.events[name] = event } -const removeEventLink = (linkedEventName) => { - const events = getBlockEvents(getCurrentBlock()) +const removeEventLink = (linkedEventName: string) => { + const events = getBlockEvents(getCurrentBlock()!) Object.entries(events).forEach(([name, event]) => { if (linkedEventName === name) { @@ -484,7 +502,7 @@ const removeEventLink = (linkedEventName) => { }) } -const appendEventEmit = ({ eventName, functionName } = {}) => { +const appendEventEmit = ({ eventName, functionName }: { eventName?: string; functionName?: string } = {}) => { if (!eventName || !functionName) { return } @@ -495,8 +513,8 @@ const appendEventEmit = ({ eventName, functionName } = {}) => { const method = getMethods()?.[functionName] if (method?.type === SCHEMA_DATA_TYPE.JSFunction) { - const ast = parseExpression(method.value) - const params = ast.params.map((param) => param.name) + const ast: any = parseExpression(method.value) + const params = ast.params.map((param: { name: string }) => param.name) const emitContent = `this.emit('${hyphenate(eventName.replace(/^on/i, ''))}', ${params.join(',')})` // 如果方法里面已经有了相同的emit语句就不添加了 @@ -534,13 +552,13 @@ const selectedGroup = ref({ ...DEFAULT_GROUPS[0] }) const selectedBlock = ref('') // 已选择的区块数组,用于在当前分组里添加区块 -const selectedBlockArray = ref([]) +const selectedBlockArray = ref([]) // 是否刷新区块列表,在当前分组里添加/删除区块后通知刷新区块列表 const isRefresh = ref(false) // 切换分组时调用 -const groupChange = (group) => { +const groupChange = (group?: BlockGroup) => { if (!group) return // 需要改变selectedGroup的引用地址才能触发tiny-select组件的watch事件 @@ -551,7 +569,7 @@ const groupChange = (group) => { } // 添加设计器默认区块分组 -const addDefaultGroup = (groups) => { +const addDefaultGroup = (groups: BlockGroup[]) => { const result = DEFAULT_GROUPS.map((group) => ({ label: group.groupName, value: group @@ -573,15 +591,23 @@ const addDefaultGroup = (groups) => { } // 是否是设计器默认区块分组 -const isDefaultGroupId = (groupId) => groupId === DEFAULT_GROUP_ID +const isDefaultGroupId = (groupId: string) => groupId === DEFAULT_GROUP_ID -const isAllGroupId = (groupId) => groupId === DEFAULT_GROUPS[0].groupId +const isAllGroupId = (groupId: string) => groupId === DEFAULT_GROUPS[0].groupId // 获取今天的开始时间 const getCurrentDate = () => new Date().setHours(0, 0, 0, 0) +interface DateInfo { + nowDayOfWeek: number + nowDay: number + nowMonth: number + nowYear: number + lastMonth: number +} + // 获取本周的开始时间 -const getCurrentWeek = (date) => { +const getCurrentWeek = (date: DateInfo) => { const { nowDayOfWeek, nowDay, nowMonth, nowYear } = date const weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek + 1) @@ -589,7 +615,7 @@ const getCurrentWeek = (date) => { } // 获取本月的开始时间 -const getCurrentMonth = (date) => { +const getCurrentMonth = (date: DateInfo) => { const { nowMonth, nowYear } = date const monthStartDate = new Date(nowYear, nowMonth, 1) @@ -597,7 +623,7 @@ const getCurrentMonth = (date) => { } // 获取上月的开始时间 -const getLastMonth = (date) => { +const getLastMonth = (date: DateInfo) => { const { nowYear, lastMonth } = date const lastMonthStartDate = new Date(nowYear, lastMonth, 1) @@ -605,7 +631,7 @@ const getLastMonth = (date) => { } // 判断时间戳属于今天/本周/本月/上月/更久以前 -const getDateFromNow = (timeStamp) => { +const getDateFromNow = (timeStamp: number = 0) => { // 当前日期 const now = new Date() const nowDay = now.getDate() @@ -621,7 +647,7 @@ const getDateFromNow = (timeStamp) => { lastMonthDate.setMonth(lastMonthDate.getMonth() - 1) const lastMonth = lastMonthDate.getMonth() - const date = { nowDayOfWeek, nowDay, nowMonth, nowYear, lastMonth } + const date: DateInfo = { nowDayOfWeek, nowDay, nowMonth, nowYear, lastMonth } // 存在currentDateStart与currentWeekStart相同的情况,故不可以用currentDateStart作key const dateMap = new Map([ @@ -629,7 +655,7 @@ const getDateFromNow = (timeStamp) => { ['本周', () => getCurrentWeek(date)], ['本月', () => getCurrentMonth(date)], ['上月', () => getLastMonth(date)], - ['更久以前', () => ''] + ['更久以前', () => 0] ]) for (const [key, value] of dateMap) { @@ -642,14 +668,14 @@ const getDateFromNow = (timeStamp) => { } // 将历史记录分组 -const splitBackupGroups = (data) => { - const backupList = {} +const splitBackupGroups = (data: { updated_at: string | number; message: string; id: string }[]) => { + const backupList: Record = {} if (!data || !data.length) return backupList - data.sort((backup1, backup2) => new Date(backup2.updated_at) - new Date(backup1.updated_at)) + data.sort((backup1, backup2) => new Date(backup2.updated_at).getTime() - new Date(backup1.updated_at).getTime()) data.forEach((item) => { - const updateTime = item.updated_at && new Date(item.updated_at) + const updateTime = item.updated_at ? new Date(item.updated_at) : null const title = getDateFromNow(updateTime?.getTime()) || '' backupList[title] = backupList[title] || [] backupList[title].push({ @@ -663,24 +689,28 @@ const splitBackupGroups = (data) => { } const sortTypeHandlerMap = { - [SORT_TYPE.timeAsc]: (blockList) => { - blockList.sort((block1, block2) => new Date(block1.updated_at) - new Date(block2.updated_at)) + [SORT_TYPE.timeAsc]: (blockList: Block[]) => { + blockList.sort( + (block1, block2) => new Date(block1.updated_at || '').getTime() - new Date(block2.updated_at || '').getTime() + ) }, - [SORT_TYPE.timeDesc]: (blockList) => { - blockList.sort((block1, block2) => new Date(block2.updated_at) - new Date(block1.updated_at)) + [SORT_TYPE.timeDesc]: (blockList: Block[]) => { + blockList.sort( + (block1, block2) => new Date(block2.updated_at || '').getTime() - new Date(block1.updated_at || '').getTime() + ) }, - [SORT_TYPE.alphabetDesc]: (blockList) => { + [SORT_TYPE.alphabetDesc]: (blockList: Block[]) => { // name_cn 包含中文,需要用 localeCompare blockList.sort((block1, block2) => (block2.name_cn || block2.label).localeCompare(block1.name_cn || block1.label)) }, - [SORT_TYPE.alphabetAsc]: (blockList) => { + [SORT_TYPE.alphabetAsc]: (blockList: Block[]) => { // name_cn 包含中文,需要用 localeCompare blockList.sort((block1, block2) => (block1.name_cn || block1.label).localeCompare(block2.name_cn || block2.label)) } } // 排序 -const sort = (blockList, type) => { +const sort = (blockList: Block[], type: string) => { if (blockList.length === 0) return blockList if (sortTypeHandlerMap[type]) { @@ -694,7 +724,7 @@ const sort = (blockList, type) => { } // 在可选区块列表里选择区块 -const check = (block) => { +const check = (block: Block) => { if (selectedBlockArray.value.some((item) => item.id === block.id)) { return } @@ -703,11 +733,11 @@ const check = (block) => { } // 取消选择区块 -const cancelCheck = (block) => { +const cancelCheck = (block: Block) => { selectedBlockArray.value = selectedBlockArray.value.filter((item) => item.id !== block.id) } -const checkAll = (blockList) => { +const checkAll = (blockList: Block[]) => { selectedBlockArray.value = blockList } @@ -715,11 +745,11 @@ const cancelCheckAll = () => { selectedBlockArray.value = [] } -const getBlockAssetsByVersion = (block, version) => { +const getBlockAssetsByVersion = (block: Block, version?: string) => { let assets = block.assets if (version) { - const replaceUri = (uri) => uri.replace(/@\d{1,3}(\.\d{1,3}){0,2}\//, `@${version}/`) + const replaceUri = (uri: string) => uri.replace(/@\d{1,3}(\.\d{1,3}){0,2}\//, `@${version}/`) assets = { ...block.assets, diff --git a/packages/plugins/datasource/src/composable/useDataSource.ts b/packages/plugins/datasource/src/composable/useDataSource.ts index 70fefc62..4b61c8cc 100644 --- a/packages/plugins/datasource/src/composable/useDataSource.ts +++ b/packages/plugins/datasource/src/composable/useDataSource.ts @@ -45,7 +45,27 @@ const compareData = () => { return { isRecordSame, isDataSourceSame, isRemoteDataSame } } -const handleConfirmSave = (dataSourceState, isRecordSame, resolve, isDataSourceSame, callback) => { +interface DataSourceState { + dataSource: Record + record: Record + recordCopies: Record + dataSourceColumn: Record + dataSourceColumnCopies: Record + remoteData: Record + remoteDataCopies: Record + currentRecordId: string + isRecordValidate: boolean + disCard: boolean + remoteConfig: Record +} + +const handleConfirmSave = ( + dataSourceState: DataSourceState, + isRecordSame: boolean, + resolve: (value: unknown) => void, + isDataSourceSame: boolean, + callback: (...args: any[]) => any +) => { let { name, data: { data, columns } @@ -63,7 +83,7 @@ const handleConfirmSave = (dataSourceState, isRecordSame, resolve, isDataSourceS // 数据源数据修改,新增,数据源数据做修改 if (dataSourceState.currentRecordId) { data = data || [] - const index = data.findIndex((item) => item.id === dataSourceState.currentRecordId) + const index = data.findIndex((item: { id: string }) => item.id === dataSourceState.currentRecordId) data[index] = Object.assign(data[index], dataSourceState.record) } else { @@ -85,7 +105,7 @@ const handleConfirmSave = (dataSourceState, isRecordSame, resolve, isDataSourceS const requestData = { name, data: { columns, data, type } } - callback(id, requestData).then((data) => { + callback(id, requestData).then((data: any) => { if (data) { dataSourceState.record = {} dataSourceState.recordCopies = {} @@ -100,7 +120,7 @@ const handleConfirmSave = (dataSourceState, isRecordSame, resolve, isDataSourceS return undefined } -const saveDataSource = (callback) => { +const saveDataSource = (callback: (...args: any[]) => any) => { const { isRecordSame, isDataSourceSame } = compareData() const { confirm } = useModal() diff --git a/packages/plugins/i18n/src/composable/useTranslate.ts b/packages/plugins/i18n/src/composable/useTranslate.ts index 24e300c9..da64d0b0 100644 --- a/packages/plugins/i18n/src/composable/useTranslate.ts +++ b/packages/plugins/i18n/src/composable/useTranslate.ts @@ -19,12 +19,19 @@ import { PROP_DATA_TYPE } from '@opentiny/tiny-engine-common/js/constants' import { useResource, useCanvas, getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' const { HOST_TYPE } = constants -const state = reactive({ +const state = reactive<{ langs: Record }>({ langs: {} }) const currentLanguage = ref('zh_CN') -const i18nResource = reactive({ messages: {}, locales: [] }) +const i18nResource = reactive<{ + messages: Record + locales: any[] + [x: string]: any +}>({ + messages: {}, + locales: [] +}) const i18nApi = '/app-center/api/i18n/entries' const globalParams = { host: '', @@ -60,7 +67,7 @@ const removeI18n = (key = []) => { * @returns */ -const ensureI18n = (obj, send) => { +const ensureI18n = (obj: { [x: string]: any; key: string }, send?: boolean) => { const { locales } = i18nResource const contents = Object.fromEntries(locales.map(({ lang }) => [lang, obj[lang]])) const langs = getLangs() @@ -93,16 +100,16 @@ const ensureI18n = (obj, send) => { } try { - const messages = {} + const messages: Record = {} Object.entries(contents).forEach(([locale, message]) => { messages[locale] = { [key]: message } }) - useCanvas().canvasApi.value?.setLocales(messages, true) + useCanvas().canvasApi.value?.setLocales?.(messages, true) } catch (e) { - throw new Error(e) + throw new Error(String(e)) // 不需要处理,有报错的词条会在画布初始化的时候统一调setLocales这个方法 } @@ -117,12 +124,19 @@ const getI18nData = () => { }) } -const getI18n = async ({ init, local }) => { +export interface I18nOptions { + init?: boolean + local?: any + host?: string + hostType?: string +} + +const getI18n = async ({ init, local }: I18nOptions): Promise => { const { appSchemaState } = useResource() if (local) { const locales = appSchemaState?.langs?.locales || [] - const messages = {} + const messages: Record = {} const langs = getLangs() if (Array.isArray(locales)) { @@ -143,8 +157,8 @@ const getI18n = async ({ init, local }) => { } } -const initI18n = async ({ host, hostType, init, local }) => { - globalParams.host = host +const initI18n = async ({ host, hostType, init, local }: I18nOptions) => { + globalParams.host = host || '' const hostTypeVar = 'host_type' globalParams[hostTypeVar] = hostType || HOST_TYPE.App @@ -165,23 +179,23 @@ const initI18n = async ({ host, hostType, init, local }) => { }) } -const initAppI18n = async (appId) => { +const initAppI18n = async (appId: string) => { if (appId) { await initI18n({ host: appId, hostType: HOST_TYPE.App }) - useCanvas().canvasApi.value?.setLocales(i18nResource.messages) + useCanvas().canvasApi.value?.setLocales?.(i18nResource.messages) } } -const initBlockI18n = async (blockId) => { +const initBlockI18n = async (blockId: string) => { if (blockId) { await initI18n({ host: blockId, hostType: HOST_TYPE.Block }) - useCanvas().canvasApi.value?.setLocales(i18nResource.messages) + useCanvas().canvasApi.value?.setLocales?.(i18nResource.messages) } } @@ -192,12 +206,13 @@ const initBlockLocalI18n = async (langs = {}) => { hostType: HOST_TYPE.Block, local: true }) - useCanvas().canvasApi.value?.setLocales(i18nResource.messages) + useCanvas().canvasApi.value?.setLocales?.(i18nResource.messages) } -const format = (str = '', params = {}) => str.replace(/\$\{(.+?)\}/g, (substr, key) => params[key] || '') +const format = (str = '', params: Record = {}) => + str.replace(/\$\{(.+?)\}/g, (_substr, key: string) => params[key] || '') -const translate = (obj) => { +const translate = (obj: { [x: string]: any }) => { const { type, key = utils.guid() } = obj || {} if (type === PROP_DATA_TYPE.I18N) { @@ -213,13 +228,13 @@ const translate = (obj) => { const getData = () => i18nResource.messages -const batchCreateI18n = ({ host, hostType }) => { +const batchCreateI18n = ({ host, hostType }: Pick) => { if (!host) { return } globalParams.host = host - globalParams.host_type = hostType + globalParams.host_type = hostType || '' const { locales } = i18nResource const langs = getLangs() diff --git a/packages/plugins/materials/src/composable/useResource.ts b/packages/plugins/materials/src/composable/useResource.ts index 10577ebd..9d2d6480 100644 --- a/packages/plugins/materials/src/composable/useResource.ts +++ b/packages/plugins/materials/src/composable/useResource.ts @@ -28,16 +28,39 @@ import { const { COMPONENT_NAME, DEFAULT_INTERCEPTOR } = constants -const appSchemaState = reactive({ +interface AppSchemaState { + dataSource: any[] + pageTree: any[] + langs: { + locales: { + lang: string + }[] + messages: any + } + utils: { [x: string]: any; type: string }[] + globalState: any[] + materialsDeps: { + scripts: any[] + styles: Set + } + componentsMap?: any + dataHandler?: any + willFetch?: any + errorHandler?: any + bridge?: any + isDemo?: boolean +} + +const appSchemaState = reactive({ dataSource: [], pageTree: [], - langs: {}, - utils: {}, + langs: { locales: [], messages: {} }, + utils: [], globalState: [], materialsDeps: { scripts: [], styles: new Set() } }) -function goPage(pageId) { +function goPage(pageId: string) { if (!pageId) { return } @@ -45,7 +68,16 @@ function goPage(pageId) { getMetaApi(META_SERVICE.GlobalService).updatePageId(pageId) } -const initPage = (pageInfo) => { +interface PageInfo { + [x: string]: any + meta: any + id: string + fileName: string + componentName: string + props: any +} + +const initPage = (pageInfo: PageInfo) => { try { if (pageInfo.meta) { const { occupier } = pageInfo.meta @@ -77,12 +109,12 @@ const initPage = (pageInfo) => { * 根据区块 id 初始化应用 * @param {string} blockId 区块 id */ -const initBlock = async (blockId) => { +const initBlock = async (blockId: string) => { const blockApi = getMetaApi(META_APP.BlockManage) const blockContent = await blockApi.getBlockById(blockId) if (blockContent.public_scope_tenants.length) { - blockContent.public_scope_tenants = blockContent.public_scope_tenants.map((e) => e.id) + blockContent.public_scope_tenants = blockContent.public_scope_tenants.map((e: { id: string }) => e.id) } useLayout().layoutState.pageStatus = getCanvasStatus(blockContent?.occupier) diff --git a/packages/toolbars/breadcrumb/src/composable/useBreadcrumb.ts b/packages/toolbars/breadcrumb/src/composable/useBreadcrumb.ts index 02096da8..4bf77874 100644 --- a/packages/toolbars/breadcrumb/src/composable/useBreadcrumb.ts +++ b/packages/toolbars/breadcrumb/src/composable/useBreadcrumb.ts @@ -18,7 +18,7 @@ const CONSTANTS = { BLOCKTEXT: '区块' } -const setBreadcrumbPage = (value: string) => { +const setBreadcrumbPage = (value: any) => { breadcrumbData.value = [CONSTANTS.PAGETEXT, ...value] sessionStorage.setItem('pageInfo', value) }