From 009360b4637ef3d0a7222d2aa394355ded6600ef Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Tue, 5 Aug 2025 21:11:22 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E6=97=A5?= =?UTF-8?q?=E5=8E=86=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A8=A1=E5=BC=8F=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=91=A8=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom-calendar/custom-calendar.scss | 20 ++++++++ .../custom-calendar/custom-calendar.tsx | 51 ++++++++++++++----- .../custom-calendar/use-custom-calendar.ts | 28 ++++++++++ 3 files changed, 85 insertions(+), 14 deletions(-) diff --git a/src/control/calendar/components/custom-calendar/custom-calendar.scss b/src/control/calendar/components/custom-calendar/custom-calendar.scss index f4ae9034..a4d53814 100644 --- a/src/control/calendar/components/custom-calendar/custom-calendar.scss +++ b/src/control/calendar/components/custom-calendar/custom-calendar.scss @@ -201,6 +201,26 @@ min-width: 120px; } } + @include e(calendar-user){ + *{ + font-family: '微软雅黑 Bold'; + } + } + @include e(calendar-user-header){ + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding: 0 16px; + @include m('left'){ + font-family: '微软雅黑 Bold'; + } + @include m('right'){ + .el-date-editor.el-date-editor--week.el-input{ + width: 250px + } + } + } .el-date-editor.el-input, .el-date-editor.el-input__wrapper { diff --git a/src/control/calendar/components/custom-calendar/custom-calendar.tsx b/src/control/calendar/components/custom-calendar/custom-calendar.tsx index f36fdef2..683731da 100644 --- a/src/control/calendar/components/custom-calendar/custom-calendar.tsx +++ b/src/control/calendar/components/custom-calendar/custom-calendar.tsx @@ -1,11 +1,11 @@ -import { defineComponent, SetupContext, onMounted } from 'vue'; +import { defineComponent, SetupContext } from 'vue'; import dayjs from 'dayjs'; import { useNamespace } from '@ibiz-template/vue3-util'; import { showTitle } from '@ibiz-template/core'; import CalendarDaily from '../calendar-daily'; import CalendarWeek from '../calendar-week'; import CalendarUser from '../calendar-user'; -import { useCustomCalendar } from './use-custom-calendar'; +import { useCustomCalendar, calcCurrentWeekRange } from './use-custom-calendar'; import './custom-calendar.scss'; import { CustomCalendarEmits, @@ -43,10 +43,6 @@ export const CustomCalendar = defineComponent({ 'custom-calendar', ); - onMounted(() => { - pickDay(dayjs(new Date())); - }); - /** * 绘制周 */ @@ -170,7 +166,9 @@ export const CustomCalendar = defineComponent({ @@ -205,14 +203,39 @@ export const CustomCalendar = defineComponent({ * @return {*} */ const renderUser = () => { + const weekRange = calcCurrentWeekRange(new Date(realSelectedDay.value)); return ( - handleEVentClick(value)} - onEventDblClick={(value: IParams) => handleEVentDblClick(value)} - v-slots={slots} - > +
+
+
+ {weekRange + .map(_date => { + return dayjs(new Date(_date)).format('YYYY年MM月DD日'); + }) + .join(' ~ ')} +
+
+ +
+
+ handleEVentClick(value)} + onEventDblClick={(value: IParams) => handleEVentDblClick(value)} + v-slots={slots} + > +
); }; diff --git a/src/control/calendar/components/custom-calendar/use-custom-calendar.ts b/src/control/calendar/components/custom-calendar/use-custom-calendar.ts index ff7cfa7e..4fdc6f3a 100644 --- a/src/control/calendar/components/custom-calendar/use-custom-calendar.ts +++ b/src/control/calendar/components/custom-calendar/use-custom-calendar.ts @@ -357,3 +357,31 @@ export const useCustomCalendar = ( selectLegend, }; }; + +/** + * 计算一周范围 + * + * @export + * @param {Date} date + * @return {*} {string[]} + */ +export function calcCurrentWeekRange(date: Date): string[] { + let monday; + let sunday; + const day = date.getDay(); + if (day === 0) { + // 今天星期天 + monday = dayjs(new Date(date.getTime() - 6 * 86400000)).format( + 'YYYY-MM-DD', + ); + sunday = dayjs(date).format('YYYY-MM-DD'); + } else { + monday = dayjs(new Date(date.getTime() - (day - 1) * 86400000)).format( + 'YYYY-MM-DD', + ); + sunday = dayjs(new Date(date.getTime() + (7 - day) * 86400000)).format( + 'YYYY-MM-DD', + ); + } + return [monday, sunday]; +} -- Gitee From 4445f900d86682bc6c4b1b3bd0dee725f479025a Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Tue, 5 Aug 2025 21:12:58 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20drtab=E6=B5=81=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=94=9A=E7=82=B9=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + src/control/drtab/drtab.controller.ts | 39 +++++ src/control/drtab/drtab.tsx | 1 + src/control/drtab/flow-drtab.scss | 74 +++++++++- src/control/drtab/flow-drtab.tsx | 198 ++++++++++++++++++++++++-- src/locale/en/index.ts | 2 + src/locale/zh-CN/index.ts | 2 + 7 files changed, 302 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fab8a6ff..f4cc9d5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Added +- drtab流布局新增锚点栏功能,日历新增控件参数defaultdatetime,用于初始化默认时间,日历用户自定义模式支持周范围选择 - 新增看板分页栏 - 新增卡片拖拽 - 新增列表新建和拖拽功能 diff --git a/src/control/drtab/drtab.controller.ts b/src/control/drtab/drtab.controller.ts index cbc1500a..893e0ed7 100644 --- a/src/control/drtab/drtab.controller.ts +++ b/src/control/drtab/drtab.controller.ts @@ -102,6 +102,45 @@ export class DRTabController return `${userId}_${this.view.model.codeName}_${this.model.codeName}`; } + /** + * 是否启用锚点栏 + * + * @readonly + * @type {boolean} + * @memberof DRTabController + */ + get enableAnchor(): boolean { + if (this.controlParams.enablenavbar) { + return this.controlParams.enablenavbar === 'true'; + } + return ibiz.config.drtab.enablenavbar; + } + + /** + * 导航栏位置 + * + * @readonly + * @type {string} + * @memberof DRTabController + */ + get navbarpos(): string { + return ( + (this.controlParams.navbarpos as string)?.toLowerCase() || + (ibiz.config.drtab.navbarpos as string).toLowerCase() + ); + } + + /** + * 导航栏宽度 + * + * @readonly + * @type {string} + * @memberof DRTabController + */ + get navbarwidth(): string { + return this.controlParams.navbarwidth || ibiz.config.drtab.navbarwidth; + } + /** * Router 对象 * diff --git a/src/control/drtab/drtab.tsx b/src/control/drtab/drtab.tsx index c3196963..b56580b1 100644 --- a/src/control/drtab/drtab.tsx +++ b/src/control/drtab/drtab.tsx @@ -250,6 +250,7 @@ export const DRTabControl = defineComponent({ showHeader={this.tabPosition === 'flow'} counterData={this.counterData} activeTab={this.activeTab} + controller={this.c} > ); } diff --git a/src/control/drtab/flow-drtab.scss b/src/control/drtab/flow-drtab.scss index f0f2b44c..98453323 100644 --- a/src/control/drtab/flow-drtab.scss +++ b/src/control/drtab/flow-drtab.scss @@ -1,14 +1,13 @@ @include b('flow-drtab'){ width: 100%; height: 100%; - overflow: auto; + overflow: hidden; background-color: getCssVar(color,bg,0);; @include e('container'){ - display: flex; - flex-direction: column; - gap: getCssVar(spacing,base); + height: 100%; + overflow: auto; } - @include e('tab-item'){ + @include e('tab-item'){ background-color: getCssVar(color,bg,1); border-radius: getCssVar(border-radius,medium); @include m('label'){ @@ -19,6 +18,9 @@ @include m('tab-view'){ padding:getCssVar(spacing,tight) 0; } + & + .#{bem(flow-drtab,tab-item)}{ + margin-top: getCssVar(spacing,base);; + } } @include e('counter'){ font-size: getCssVar(font-size,regular); @@ -27,4 +29,66 @@ .#{bem('flow-drtab')}{ background-color: inherit; } + @include when('enable-anchor'){ + display:flex; + gap: getCssVar(spacing,base); + @include e('container'){ + flex: 1; + } + @include e('anchor-bar'){ + display: flex; + min-width: 200px; + padding: getCssVar(spacing,base) 0; + background-color: white; + @include when('topleft'){ + align-items: start; + } + @include when('bottomleft'){ + align-items: end; + } + @include when('topright'){ + flex-direction: row-reverse; + align-items: start; + } + @include when('bottomright'){ + flex-direction: row-reverse; + align-items: end; + } + @include when('middleleft'){ + align-items: center; + } + @include when(middleright){ + flex-direction: row-reverse; + align-items: center; + } + } + @include e('anchor-items'){ + width: 100%; + max-height: 100%; + overflow: auto; + } + @include e('anchor-item'){ + width: 100%; + height: 32px; + padding: 0 getCssVar(spacing,base); + font-family: '微软雅黑 Bold'; + line-height: 32px; + cursor: pointer; + + &:hover{ + color: getCssVar('color','primary-hover-text'); + background-color: getCssVar('color','primary'); + } + @include when('active'){ + color: getCssVar('color','primary-hover-text'); + background-color: getCssVar('color','primary'); + } + } + @include when('left'){ + flex-direction:row; + } + @include when(right){ + flex-direction: row-reverse; + } + } } \ No newline at end of file diff --git a/src/control/drtab/flow-drtab.tsx b/src/control/drtab/flow-drtab.tsx index 69f7b3e3..7c17769c 100644 --- a/src/control/drtab/flow-drtab.tsx +++ b/src/control/drtab/flow-drtab.tsx @@ -4,13 +4,17 @@ import { PropType, ref, watch, + onActivated, resolveComponent, + nextTick, + computed, Ref, } from 'vue'; import { useNamespace } from '@ibiz-template/vue3-util'; import { isNil } from 'ramda'; import { createUUID } from 'qx-util'; import './flow-drtab.scss'; +import { DRTabController } from './drtab.controller'; export const FlowDrtab = defineComponent({ name: 'FlowDrtab', @@ -43,33 +47,114 @@ export const FlowDrtab = defineComponent({ type: Object as PropType, default: () => {}, }, + controller: { + type: Object as PropType, + default: () => {}, + }, }, setup(props) { const ns = useNamespace('flow-drtab'); const uuid = createUUID(); + const c = props.controller; + // 导航项 const navtag = ref(''); + // 视图列表 const viewList: Ref = ref([]); + // 导航栏位置 + const navbarpos = ref(); + // 导航栏宽度 + const navBarWidth = ref(200); + // 观察滚动项元素id数组 + const observerIds: string[] = []; + // 滚动高度 + const scrollTop = ref(0); + navbarpos.value = c.navbarpos; + navBarWidth.value = c.navbarwidth; + + // 所有导航项元素id + const allNavTags = computed(() => { + if (props.pagesstate) { + return props.pagesstate.map(item => { + const target = props.drtabpages.find(page => { + return page.id === item.tag; + }); + return `${target?.appViewId}_${item.tag}`; + }); + } + return []; + }); - // 滚定到目标 + // 滚动到目标 const scrollToTarget = () => { if (navtag.value) { - const el = document.getElementById(`${uuid}_${navtag.value}`); + const el = document.getElementById(`${navtag.value}`); if (el) { el.scrollIntoView(); } } }; + // 计算当前选中激活项 + const computeSelectItem = () => { + if (observerIds.length > 0) { + navtag.value = observerIds[0]; + } + }; + + // 创建 Intersection Observer 对象,用来观察滚动元素 + const observer = new IntersectionObserver( + (entries: IntersectionObserverEntry[]) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + // 当元素进入视口时执行的操作 + if (entry.target && entry.target.id) { + if (observerIds.length > 0) { + const curIndex = allNavTags.value?.findIndex( + tag => tag === entry.target.id, + ); + const index = allNavTags.value?.findIndex( + tag => tag === observerIds[0], + ); + if (curIndex < index) { + observerIds.unshift(entry.target.id); + } else { + observerIds.push(entry.target.id); + } + } else { + observerIds.push(entry.target.id); + } + } + } else if (entry.target && entry.target.id) { + // 当元素离开视口时执行的操作 + const index = observerIds.indexOf(entry.target.id); + if (index >= 0) { + observerIds.splice(index, 1); + } + } + }); + computeSelectItem(); + }, + ); + // 分页视图挂载完成 - const onViewMounted = () => { - scrollToTarget(); + const onViewMounted = (item: IData) => { + const target = props.drtabpages.find(page => { + return page.id === item.tag; + }); + const el = document.getElementById(`${target?.appViewId}_${item.tag}`); + if (el) { + observer.observe(el); + } }; watch( () => props.activeTab, (newVal, oldVal) => { if (newVal && newVal.tag !== oldVal?.tag) { - navtag.value = newVal.tag; + const target = props.drtabpages.find(page => { + return page.id === newVal.tag; + }); + navtag.value = `${target?.appViewId}_${newVal.tag}`; scrollToTarget(); } }, @@ -98,6 +183,17 @@ export const FlowDrtab = defineComponent({ immediate: true, }, ); + + // 重新进入时回滚到上次离开位置 + onActivated(() => { + nextTick(() => { + const el = document.getElementById(`${uuid}`); + if (el) { + el.scrollTop = scrollTop.value; + } + }); + }); + // 计算视图默认宽高 const calcStyle = (tag: string) => { const target = viewList.value.find(item => { @@ -111,7 +207,71 @@ export const FlowDrtab = defineComponent({ } }; - return { ns, uuid, onViewMounted, calcStyle }; + // 点击锚点栏 + const onClickBar = (item: IData) => { + const target = props.drtabpages.find(page => { + return page.id === item.tag; + }); + const el = document.getElementById(`${target?.appViewId}_${item.tag}`); + if (el) { + el.scrollIntoView({ + behavior: 'smooth', + }); + } + }; + + // 绘制锚点栏 + const renderAnchorBar = () => { + // 是否启用锚点栏 + if (c.enableAnchor) { + return ( +
+
+ {props.pagesstate.map(item => { + const target = props.drtabpages.find(page => { + return page.id === item.tag; + }); + return ( +
onClickBar(item)} + > + {item.caption} +
+ ); + })} +
+
+ ); + } + }; + + const handleScroll = () => { + const el = document.getElementById(`${uuid}`); + if (el) { + scrollTop.value = el.scrollTop; + } + }; + + return { + c, + ns, + uuid, + navbarpos, + onViewMounted, + calcStyle, + renderAnchorBar, + handleScroll, + }; }, render() { const tabs = this.pagesstate.map((item: IData) => { @@ -126,7 +286,10 @@ export const FlowDrtab = defineComponent({ return null; } return ( -
+
{this.showHeader && (
{item.sysImage && ( @@ -153,15 +316,30 @@ export const FlowDrtab = defineComponent({ context: this.context, params: this.params, viewId: target.appViewId, - onMounted: this.onViewMounted, + onMounted: () => this.onViewMounted(item), })}
); }); return ( -
-
{tabs}
+
+ {this.renderAnchorBar()} +
+ {tabs} +
); }, diff --git a/src/locale/en/index.ts b/src/locale/en/index.ts index 9b2e2fdc..aafafc32 100644 --- a/src/locale/en/index.ts +++ b/src/locale/en/index.ts @@ -349,6 +349,7 @@ export default { today: 'Today', tomorrow: 'To Morrow', nextweek: 'Next Week', + selectdate: 'Select Date', }, calendarmonth: { lastmonth: 'Last Month', @@ -387,6 +388,7 @@ export default { saturday: 'Sat', sunday: 'Sun', }, + selectWeekRange: 'Select week range', }, }, chart: { diff --git a/src/locale/zh-CN/index.ts b/src/locale/zh-CN/index.ts index 99b9107a..8545bb00 100644 --- a/src/locale/zh-CN/index.ts +++ b/src/locale/zh-CN/index.ts @@ -316,6 +316,7 @@ export default { tip: '全天', tomorrow: '明天', nextweek: '下周', + selectdate: '选择日期', }, calendarmonth: { weeks: { @@ -349,6 +350,7 @@ export default { saturday: '周六', sunday: '周日', }, + selectWeekRange: '选择周范围', }, }, chart: { -- Gitee From f53dc8c05a1440d454b52e844414a94de19174fd Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Wed, 6 Aug 2025 09:52:27 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0drtab=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E9=85=8D=E7=BD=AE=E4=B8=BA=E9=A9=BC=E5=B3=B0=E5=86=99?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/custom-calendar/custom-calendar.scss | 10 +--------- src/control/drtab/drtab.controller.ts | 8 ++++---- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/control/calendar/components/custom-calendar/custom-calendar.scss b/src/control/calendar/components/custom-calendar/custom-calendar.scss index a4d53814..c8c4fd74 100644 --- a/src/control/calendar/components/custom-calendar/custom-calendar.scss +++ b/src/control/calendar/components/custom-calendar/custom-calendar.scss @@ -201,20 +201,12 @@ min-width: 120px; } } - @include e(calendar-user){ - *{ - font-family: '微软雅黑 Bold'; - } - } @include e(calendar-user-header){ display: flex; align-items: center; justify-content: space-between; width: 100%; - padding: 0 16px; - @include m('left'){ - font-family: '微软雅黑 Bold'; - } + padding: 0 getCssVar(spacing-base); @include m('right'){ .el-date-editor.el-date-editor--week.el-input{ width: 250px diff --git a/src/control/drtab/drtab.controller.ts b/src/control/drtab/drtab.controller.ts index 893e0ed7..f63620c9 100644 --- a/src/control/drtab/drtab.controller.ts +++ b/src/control/drtab/drtab.controller.ts @@ -113,7 +113,7 @@ export class DRTabController if (this.controlParams.enablenavbar) { return this.controlParams.enablenavbar === 'true'; } - return ibiz.config.drtab.enablenavbar; + return ibiz.config.drtab.enableNavbar; } /** @@ -126,7 +126,7 @@ export class DRTabController get navbarpos(): string { return ( (this.controlParams.navbarpos as string)?.toLowerCase() || - (ibiz.config.drtab.navbarpos as string).toLowerCase() + (ibiz.config.drtab.navbarPos as string).toLowerCase() ); } @@ -137,8 +137,8 @@ export class DRTabController * @type {string} * @memberof DRTabController */ - get navbarwidth(): string { - return this.controlParams.navbarwidth || ibiz.config.drtab.navbarwidth; + get navbarwidth(): string | number { + return this.controlParams.navbarwidth || ibiz.config.drtab.navbarWidth; } /** -- Gitee