Browse Source

报表UI优化好了

张洋 1 month ago
parent
commit
d2d3059502

+ 113 - 65
bin/Win32/Debug/zhipuzi_pos_windows/skin/baobiao_page.xml

@@ -1,79 +1,127 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <Window>
 <Window>
-	
 	<BaobiaoPage>
 	<BaobiaoPage>
-		<VerticalLayout>
-			<HorizontalLayout height="53" padding="0,0,0,0" bkcolor="#FFFFFFFF">
-				<VerticalLayout width="100" height="53">
-					<Button name="btn_jintian" text="今天" textcolor="#FF43A947" font="18" height="50" width="100" padding="0,0,0,0" normalimage="" hotimage="" pushedimage="" bordersize="0" bkcolor="#00FFFFFF"></Button>
-					<Control name="btn_jintian_line" width="60" height="3" bkcolor="#FF43A947" padding="20,0,20,0"></Control>
-				</VerticalLayout>
-				
-				<VerticalLayout width="100" height="53">
-					<Button name="btn_zuotian" text="昨天" font="18" height="50" width="100" padding="0,0,0,0" normalimage="" hotimage="" pushedimage="" bordersize="0" bkcolor="#00FFFFFF"></Button>
-					<Control name="btn_zuotian_line" visible="false" width="60" height="3" bkcolor="#FF43A947" padding="20,0,20,0"></Control>
-				</VerticalLayout>
-				
-				<VerticalLayout width="100" height="53">
-					<Button name="btn_qitian" text="最近7天" font="18" height="50" width="100" padding="0,0,0,0" normalimage="" hotimage="" pushedimage="" bordersize="0" bkcolor="#00FFFFFF"></Button>
-					<Control name="btn_qitian_line" visible="false" width="60" height="3" bkcolor="#FF43A947" padding="20,0,20,0"></Control>
-				</VerticalLayout>
-				
-				<VerticalLayout width="100" height="53">
-					<Button name="btn_sanshitian" text="最近30天" font="18" height="50" width="100" padding="0,0,0,0" normalimage="" hotimage="" pushedimage="" bordersize="0" bkcolor="#00FFFFFF"></Button>
-					<Control name="btn_sanshitian_line" visible="false" width="60" height="3" bkcolor="#FF43A947" padding="20,0,20,0"></Control>
-				</VerticalLayout>
+		<!-- 第五十六轮改版:顶部一体化工具条(P1)+ 彩色数字胶囊(C3)+ 2 列 3 行。
+		     全部圆角走 8x 超采样 PNG 九宫格,不使用 borderround(GDI 1-bit Region 必锯齿)。
+		     inset 的 right 必须为 0,否则 vscrollbar 会被一起收缩,右边留不出贴边滚动条;
+		     右侧留白改由各子项自己的 padding="0,0,28,0" 承担。 -->
+		<VerticalLayout name="data_layout" visible="false" bkcolor="#FFF5F7FA" vscrollbar="true" inset="28,0,0,0" childpadding="16">
+			<Control height="8" />
+
+			<!-- 顶部一体化工具条:左侧胶囊 Tab,右侧统计区间 -->
+			<HorizontalLayout padding="0,0,28,0" height="64" bkimage="file='bb_card10.png' corner='10,10,10,10'" inset="20,8,8,8" childvalign="vcenter">
+				<HorizontalLayout name="bb_tabs" width="440" maxheight="48" bkimage="file='bb_tabs_bg.png' corner='24,24,24,24'" inset="4,4,4,4" childvalign="vcenter">
+					<!-- 选中态与悬浮、按下态由 C++ 的 SetActiveTab 统一切换。
+					     这里必须显式写 hotimage 与 pushedimage:main.xml 全局 Default 给所有
+					     按钮默认套 btn_green_* 三态图,不覆盖的话悬浮和按下
+					     会突然变成全局绿按钮样式,与胶囊 Tab 完全不协调。
+					     横排子项只认 maxheight,写 height 无效(UIHorizontalLayout.cpp:160)。 -->
+					<Button name="btn_jintian" text="今天" font="115" textcolor="#FFFFFFFF" hottextcolor="#FFFFFFFF" pushedtextcolor="#FFFFFFFF" width="108" maxheight="40" normalimage="file='bb_tab_active.png' corner='20,20,20,20'" hotimage="file='bb_tab_active_hot.png' corner='20,20,20,20'" pushedimage="file='bb_tab_active_pushed.png' corner='20,20,20,20'" />
+					<Button name="btn_zuotian" text="昨天" font="15" textcolor="#FF5F6368" hottextcolor="#FF2E9B5C" pushedtextcolor="#FF2E9B5C" width="108" maxheight="40" hotimage="file='bb_tab_hover.png' corner='20,20,20,20'" pushedimage="file='bb_tab_pushed.png' corner='20,20,20,20'" />
+					<Button name="btn_qitian" text="最近7天" font="15" textcolor="#FF5F6368" hottextcolor="#FF2E9B5C" pushedtextcolor="#FF2E9B5C" width="108" maxheight="40" hotimage="file='bb_tab_hover.png' corner='20,20,20,20'" pushedimage="file='bb_tab_pushed.png' corner='20,20,20,20'" />
+					<Button name="btn_sanshitian" text="最近30天" font="15" textcolor="#FF5F6368" hottextcolor="#FF2E9B5C" pushedtextcolor="#FF2E9B5C" width="108" maxheight="40" hotimage="file='bb_tab_hover.png' corner='20,20,20,20'" pushedimage="file='bb_tab_pushed.png' corner='20,20,20,20'" />
+				</HorizontalLayout>
+				<Control />
+				<Label text="统计区间" font="12" textcolor="#FF8A9099" maxheight="17" autocalcwidth="true" />
+				<Label name="bb_range_value" text="--" font="114" textcolor="#FF1F2329" maxheight="20" padding="12,0,12,0" autocalcwidth="true" />
+				<Label name="bb_update_time" text="--" font="12" textcolor="#FF8A9099" maxheight="17" autocalcwidth="true" />
 			</HorizontalLayout>
 			</HorizontalLayout>
 
 
-			<HorizontalLayout>
-				<VerticalLayout name="data_layout" visible="false">
-					<Label text="营业概况" font="20" padding="20,20,0,0" height="30"></Label>
-					
-					<HorizontalLayout name="baobiao_page_yingye_items">					
-						<VerticalLayout bkcolor="#FFFFFFFF" width="240" height="126" padding="20,15,0,0">
-							<Label name="waimai_num" text="" font="20" padding="20,25,0,0"></Label>
-							<Label text="外卖订单数量" padding="20,15,0,0" textcolor="#FF777777"></Label>
+			<!-- 营业概况分组卡 -->
+			<VerticalLayout padding="0,0,28,0" bkimage="file='bb_card10.png' corner='10,10,10,10'" inset="22,18,22,18" childpadding="14">
+				<HorizontalLayout height="22" childvalign="vcenter">
+					<Control width="3" maxheight="15" bkcolor="#FF2E9B5C" borderround="3,3" />
+					<Control width="10" />
+					<Label text="营业概况" font="116" textcolor="#FF1F2329" maxheight="22" autocalcwidth="true" />
+					<Control />
+					<Label text="含外卖、店内与会员储值" font="12" textcolor="#FF8A9099" maxheight="17" autocalcwidth="true" />
+				</HorizontalLayout>
+
+				<VerticalLayout childpadding="12">
+					<!-- 第 1 行:外卖 -->
+					<HorizontalLayout height="88" childpadding="12">
+						<VerticalLayout maxheight="88" bkimage="file='bb_card8.png' corner='8,8,8,8'" inset="20,16,20,16">
+							<HorizontalLayout childvalign="vcenter">
+								<VerticalLayout childpadding="4" childvalign="vcenter">
+									<Label text="外卖订单数量" font="13" textcolor="#FF5F6368" height="18" />
+									<Label name="waimai_num_sub" text="占总订单 --" font="12" textcolor="#FFA8ADB3" height="17" />
+								</VerticalLayout>
+								<Label name="waimai_num" showhtml="true" font="122" textcolor="#FF4A90E2" maxheight="34" bkimage="file='bb_pill_blue.png' corner='17,17,17,17'" textpadding="14,4,14,4" padding="20,0,0,0" autocalcwidth="true" text="--{x 4}{c #77ACE9}{f 12}单{/f}{/c}" />
+							</HorizontalLayout>
 						</VerticalLayout>
 						</VerticalLayout>
-						
-						<VerticalLayout bkcolor="#FFFFFFFF" width="240" height="126" padding="20,15,0,0">
-							<Label name="waimai_value" text="" font="20" padding="20,25,0,0"></Label>
-							<Label text="外卖营业额" padding="20,15,0,0" textcolor="#FF777777"></Label>
+
+						<VerticalLayout maxheight="88" bkimage="file='bb_card8.png' corner='8,8,8,8'" inset="20,16,20,16">
+							<HorizontalLayout childvalign="vcenter">
+								<VerticalLayout childpadding="4" childvalign="vcenter">
+									<Label text="外卖营业额" font="13" textcolor="#FF5F6368" height="18" />
+									<Label name="waimai_value_sub" text="客单价 --" font="12" textcolor="#FFA8ADB3" height="17" />
+								</VerticalLayout>
+								<Label name="waimai_value" showhtml="true" font="122" textcolor="#FF4A90E2" maxheight="34" bkimage="file='bb_pill_blue.png' corner='17,17,17,17'" textpadding="14,4,14,4" padding="20,0,0,0" autocalcwidth="true" text="{c #77ACE9}{f 14}¥{/f}{/c}{x 3}--" />
+							</HorizontalLayout>
 						</VerticalLayout>
 						</VerticalLayout>
-						
-						<VerticalLayout bkcolor="#FFFFFFFF" width="240" height="126" padding="20,15,0,0">
-							<Label name="diannei_num" text="" font="20" padding="20,25,0,0"></Label>
-							<Label text="店内订单数量" padding="20,15,0,0" textcolor="#FF777777"></Label>
+					</HorizontalLayout>
+
+					<!-- 第 2 行:店内 -->
+					<HorizontalLayout height="88" childpadding="12">
+						<VerticalLayout maxheight="88" bkimage="file='bb_card8.png' corner='8,8,8,8'" inset="20,16,20,16">
+							<HorizontalLayout childvalign="vcenter">
+								<VerticalLayout childpadding="4" childvalign="vcenter">
+									<Label text="店内订单数量" font="13" textcolor="#FF5F6368" height="18" />
+									<Label name="diannei_num_sub" text="占总订单 --" font="12" textcolor="#FFA8ADB3" height="17" />
+								</VerticalLayout>
+								<Label name="diannei_num" showhtml="true" font="122" textcolor="#FFE08A17" maxheight="34" bkimage="file='bb_pill_org.png' corner='17,17,17,17'" textpadding="14,4,14,4" padding="20,0,0,0" autocalcwidth="true" text="--{x 4}{c #E8A750}{f 12}单{/f}{/c}" />
+							</HorizontalLayout>
 						</VerticalLayout>
 						</VerticalLayout>
-						
-						<VerticalLayout bkcolor="#FFFFFFFF" width="240" height="126" padding="20,15,0,0">
-							<Label name="diannei_value" text="" font="20" padding="20,25,0,0"></Label>
-							<Label text="店内营业额" padding="20,15,0,0" textcolor="#FF777777"></Label>
+
+						<VerticalLayout maxheight="88" bkimage="file='bb_card8.png' corner='8,8,8,8'" inset="20,16,20,16">
+							<HorizontalLayout childvalign="vcenter">
+								<VerticalLayout childpadding="4" childvalign="vcenter">
+									<Label text="店内营业额" font="13" textcolor="#FF5F6368" height="18" />
+									<Label name="diannei_value_sub" text="客单价 --" font="12" textcolor="#FFA8ADB3" height="17" />
+								</VerticalLayout>
+								<Label name="diannei_value" showhtml="true" font="122" textcolor="#FFE08A17" maxheight="34" bkimage="file='bb_pill_org.png' corner='17,17,17,17'" textpadding="14,4,14,4" padding="20,0,0,0" autocalcwidth="true" text="{c #E8A750}{f 14}¥{/f}{/c}{x 3}--" />
+							</HorizontalLayout>
 						</VerticalLayout>
 						</VerticalLayout>
-						
-						<VerticalLayout bkcolor="#FFFFFFFF" width="240" height="126" padding="20,15,0,0">
-							<Label name="huiyuan_num" text="" font="20" padding="20,25,0,0"></Label>
-							<Label text="新增会员数量" padding="20,15,0,0" textcolor="#FF777777"></Label>
+					</HorizontalLayout>
+
+					<!-- 第 3 行:会员 -->
+					<HorizontalLayout height="88" childpadding="12">
+						<VerticalLayout maxheight="88" bkimage="file='bb_card8.png' corner='8,8,8,8'" inset="20,16,20,16">
+							<HorizontalLayout childvalign="vcenter">
+								<VerticalLayout childpadding="4" childvalign="vcenter">
+									<Label text="新增会员数量" font="13" textcolor="#FF5F6368" height="18" />
+									<Label name="huiyuan_num_sub" text="新客占订单 --" font="12" textcolor="#FFA8ADB3" height="17" />
+								</VerticalLayout>
+								<Label name="huiyuan_num" showhtml="true" font="122" textcolor="#FF2E9B5C" maxheight="34" bkimage="file='bb_pill_grn.png' corner='17,17,17,17'" textpadding="14,4,14,4" padding="20,0,0,0" autocalcwidth="true" text="--{x 4}{c #62B585}{f 12}人{/f}{/c}" />
+							</HorizontalLayout>
 						</VerticalLayout>
 						</VerticalLayout>
-						
-						<VerticalLayout bkcolor="#FFFFFFFF" width="240" height="126" padding="20,15,0,0">
-							<Label name="huiyuan_value" text="" font="20" padding="20,25,0,0"></Label>
-							<Label text="会员储值金额" padding="20,15,0,0" textcolor="#FF777777"></Label>
+
+						<VerticalLayout maxheight="88" bkimage="file='bb_card8.png' corner='8,8,8,8'" inset="20,16,20,16">
+							<HorizontalLayout childvalign="vcenter">
+								<VerticalLayout childpadding="4" childvalign="vcenter">
+									<Label text="会员储值金额" font="13" textcolor="#FF5F6368" height="18" />
+									<Label name="huiyuan_value_sub" text="笔均 --" font="12" textcolor="#FFA8ADB3" height="17" />
+								</VerticalLayout>
+								<Label name="huiyuan_value" showhtml="true" font="122" textcolor="#FF2E9B5C" maxheight="34" bkimage="file='bb_pill_grn.png' corner='17,17,17,17'" textpadding="14,4,14,4" padding="20,0,0,0" autocalcwidth="true" text="{c #62B585}{f 14}¥{/f}{/c}{x 3}--" />
+							</HorizontalLayout>
 						</VerticalLayout>
 						</VerticalLayout>
 					</HorizontalLayout>
 					</HorizontalLayout>
 				</VerticalLayout>
 				</VerticalLayout>
-				
-				<HorizontalLayout name="loading">
-					<Control></Control>
-					<VerticalLayout width="24">
-						<Control></Control>
-						<HorizontalLayout height="24">
-							<GifAnim bkimage="loading.gif" autosize="true"></GifAnim>
-						</HorizontalLayout>
-						<Control></Control>
-					</VerticalLayout>
-					<Control></Control>
-				</HorizontalLayout>
-			</HorizontalLayout>
+			</VerticalLayout>
+
+			<Control height="12" />
 		</VerticalLayout>
 		</VerticalLayout>
+
+		<HorizontalLayout name="loading">
+			<Control></Control>
+			<VerticalLayout width="24">
+				<Control></Control>
+				<HorizontalLayout height="24">
+					<GifAnim bkimage="loading.gif" autosize="true"></GifAnim>
+				</HorizontalLayout>
+				<Control></Control>
+			</VerticalLayout>
+			<Control></Control>
+		</HorizontalLayout>
 	</BaobiaoPage>
 	</BaobiaoPage>
-</Window>
+</Window>

BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_card10.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_card8.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_pill_blue.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_pill_grn.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_pill_org.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_tab_active.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_tab_active_hot.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_tab_active_pushed.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_tab_hover.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_tab_pushed.png


BIN
bin/Win32/Debug/zhipuzi_pos_windows/skin/bb_tabs_bg.png


+ 14 - 8
bin/Win32/Debug/zhipuzi_pos_windows/skin/jiaoban_page.xml

@@ -1,12 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Window>
 <Window>
 	<JiaobanPage>
 	<JiaobanPage>
-		<VerticalLayout name="data_layout" visible="false" bkcolor="#FFF5F7FA" vscrollbar="true" inset="28,24,28,0" childpadding="16">
-			<HorizontalLayout name="jiaoban_error_tip" visible="false" height="44" bkimage="file='jb_tip_error.png' corner='16,16,16,16'" inset="16,0,16,0" childvalign="vcenter">
+		<VerticalLayout name="data_layout" visible="false" bkcolor="#FFF5F7FA" vscrollbar="true" inset="28,0,0,0" childpadding="16">
+			<!-- 第五十二轮:顶部留白 8+childpadding16=24(原 inset.top=24)。
+			     inset 的 top/right 会把 vscrollbar 一起收缩(UIVerticalLayout.cpp SetPos 先应用
+			     inset 再 ProcessScrollBar),所以 top/right 归零让滚动条贴顶贴右,留白改由子项承担 -->
+			<Control height="8" />
+			<HorizontalLayout name="jiaoban_error_tip" visible="false" padding="0,0,28,0" height="44" bkimage="file='jb_tip_error.png' corner='16,16,16,16'" inset="16,0,16,0" childvalign="vcenter">
 				<Label name="jiaoban_error_text" text="" font="14" textcolor="#FFE14B4A" maxheight="20" />
 				<Label name="jiaoban_error_text" text="" font="14" textcolor="#FFE14B4A" maxheight="20" />
 				<Button name="jiaoban_error_retry_btn" width="72" maxheight="28" text="重试" font="14" textcolor="#FFE14B4A" normalimage="file='jb_btn_retry_normal.png'" hotimage="file='jb_btn_retry_hot.png'" pushedimage="file='jb_btn_retry_pushed.png'" />
 				<Button name="jiaoban_error_retry_btn" width="72" maxheight="28" text="重试" font="14" textcolor="#FFE14B4A" normalimage="file='jb_btn_retry_normal.png'" hotimage="file='jb_btn_retry_hot.png'" pushedimage="file='jb_btn_retry_pushed.png'" />
 			</HorizontalLayout>
 			</HorizontalLayout>
-			<HorizontalLayout name="jiaoban_top_bar" height="96" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="6,20,6,20">
+			<HorizontalLayout name="jiaoban_top_bar" padding="0,0,28,0" height="96" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="6,20,6,20">
 				<VerticalLayout inset="28,2,28,2" childpadding="8" childvalign="vcenter">
 				<VerticalLayout inset="28,2,28,2" childpadding="8" childvalign="vcenter">
 					<Label text="交班账号" font="12" textcolor="#FF8A9099" height="17" />
 					<Label text="交班账号" font="12" textcolor="#FF8A9099" height="17" />
 					<Label name="jiaoban_page_account" text="--" font="115" textcolor="#FF1F2329" height="19" />
 					<Label name="jiaoban_page_account" text="--" font="115" textcolor="#FF1F2329" height="19" />
@@ -14,7 +18,9 @@
 				<Control width="1" bkcolor="#FFF0F1F3" />
 				<Control width="1" bkcolor="#FFF0F1F3" />
 				<VerticalLayout inset="28,2,28,2" childpadding="8" childvalign="vcenter">
 				<VerticalLayout inset="28,2,28,2" childpadding="8" childvalign="vcenter">
 					<Label text="开班时间" font="12" textcolor="#FF8A9099" height="17" />
 					<Label text="开班时间" font="12" textcolor="#FF8A9099" height="17" />
-					<Combo name="jiaoban_page_init_time_select" width="200" height="26" vscrollbar="false" dropboxsize="200,240" font="116" textcolor="#FF1F2329" textpadding="4,0,0,0" tooltip="请选择本班次的开班时间" normalimage="file='Setting_Combox_Normal.png' corner='2,2,24,2'" hotimage="file='Setting_Combox_Hover.png' corner='2,2,24,2'" pushedimage="file='Setting_Combox_Click.png' corner='2,2,24,2'" />
+					<!-- 第五十三轮:开班时间不再由用户选择,直接取接口 /user/getlogintime 的
+					     最近一次登录时间(只读展示),据此计算班次时长与统计数据 -->
+					<Label name="jiaoban_page_init_time" text="--" font="116" textcolor="#FF1F2329" height="22" />
 				</VerticalLayout>
 				</VerticalLayout>
 				<Control width="1" bkcolor="#FFF0F1F3" />
 				<Control width="1" bkcolor="#FFF0F1F3" />
 				<VerticalLayout inset="28,2,28,2" childpadding="8" childvalign="vcenter">
 				<VerticalLayout inset="28,2,28,2" childpadding="8" childvalign="vcenter">
@@ -27,7 +33,7 @@
 					<Label name="jiaoban_page_duration" text="--" font="116" textcolor="#FF2E9B5C" height="22" />
 					<Label name="jiaoban_page_duration" text="--" font="116" textcolor="#FF2E9B5C" height="22" />
 				</VerticalLayout>
 				</VerticalLayout>
 			</HorizontalLayout>
 			</HorizontalLayout>
-			<VerticalLayout height="161" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="22,18,22,18" childpadding="14">
+			<VerticalLayout padding="0,0,28,0" height="161" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="22,18,22,18" childpadding="14">
 				<HorizontalLayout height="22" childvalign="vcenter">
 				<HorizontalLayout height="22" childvalign="vcenter">
 					<Control width="4" maxheight="18" bkcolor="#FF4A90E2" borderround="4,4" />
 					<Control width="4" maxheight="18" bkcolor="#FF4A90E2" borderround="4,4" />
 					<Control width="8" />
 					<Control width="8" />
@@ -41,7 +47,7 @@
 					<VerticalLayout maxheight="89" bkimage="file='jb_card_field.png' corner='16,16,16,16'" inset="17,15,17,15" childpadding="9"><Label text="店内营业额" font="12" textcolor="#FF5F6368" height="17" /><Label name="diannei_value" showhtml="true" font="120" textcolor="#FF4A90E2" height="33" bkimage="file='jb_pill_blue.png' corner='16,16,16,16'" textpadding="15,3,15,3" autocalcwidth="true" valign="top" text="{c #77ACE9}{f 14}¥{/f}{/c}{x 3}--{x 3}{c #77ACE9}{f 11}.00{/f}{/c}" /></VerticalLayout>
 					<VerticalLayout maxheight="89" bkimage="file='jb_card_field.png' corner='16,16,16,16'" inset="17,15,17,15" childpadding="9"><Label text="店内营业额" font="12" textcolor="#FF5F6368" height="17" /><Label name="diannei_value" showhtml="true" font="120" textcolor="#FF4A90E2" height="33" bkimage="file='jb_pill_blue.png' corner='16,16,16,16'" textpadding="15,3,15,3" autocalcwidth="true" valign="top" text="{c #77ACE9}{f 14}¥{/f}{/c}{x 3}--{x 3}{c #77ACE9}{f 11}.00{/f}{/c}" /></VerticalLayout>
 				</HorizontalLayout>
 				</HorizontalLayout>
 			</VerticalLayout>
 			</VerticalLayout>
-			<VerticalLayout height="161" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="22,18,22,18" childpadding="14">
+			<VerticalLayout padding="0,0,28,0" height="161" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="22,18,22,18" childpadding="14">
 				<HorizontalLayout height="22" childvalign="vcenter">
 				<HorizontalLayout height="22" childvalign="vcenter">
 					<Control width="4" maxheight="18" bkcolor="#FFE08A17" borderround="4,4" />
 					<Control width="4" maxheight="18" bkcolor="#FFE08A17" borderround="4,4" />
 					<Control width="8" />
 					<Control width="8" />
@@ -56,7 +62,7 @@
 					<VerticalLayout maxheight="89" bkimage="file='jb_card_field.png' corner='16,16,16,16'" inset="17,15,17,15" childpadding="9"><Label text="店内订单优惠金额" font="12" textcolor="#FF5F6368" height="17" /><Label name="diannei_youhui_value" showhtml="true" font="120" textcolor="#FFE08A17" height="33" bkimage="file='jb_pill_org.png' corner='16,16,16,16'" textpadding="15,3,15,3" autocalcwidth="true" valign="top" text="{c #E8A750}{f 14}¥{/f}{/c}{x 3}--{x 3}{c #E8A750}{f 11}.00{/f}{/c}" /></VerticalLayout>
 					<VerticalLayout maxheight="89" bkimage="file='jb_card_field.png' corner='16,16,16,16'" inset="17,15,17,15" childpadding="9"><Label text="店内订单优惠金额" font="12" textcolor="#FF5F6368" height="17" /><Label name="diannei_youhui_value" showhtml="true" font="120" textcolor="#FFE08A17" height="33" bkimage="file='jb_pill_org.png' corner='16,16,16,16'" textpadding="15,3,15,3" autocalcwidth="true" valign="top" text="{c #E8A750}{f 14}¥{/f}{/c}{x 3}--{x 3}{c #E8A750}{f 11}.00{/f}{/c}" /></VerticalLayout>
 				</HorizontalLayout>
 				</HorizontalLayout>
 			</VerticalLayout>
 			</VerticalLayout>
-			<VerticalLayout height="164" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="22,18,22,18" childpadding="14">
+			<VerticalLayout padding="0,0,28,0" height="164" bkimage="file='jb_card_group.png' corner='20,20,20,20'" inset="22,18,22,18" childpadding="14">
 				<HorizontalLayout height="22" childvalign="vcenter">
 				<HorizontalLayout height="22" childvalign="vcenter">
 					<Control width="4" maxheight="18" bkcolor="#FF2E9B5C" borderround="4,4" />
 					<Control width="4" maxheight="18" bkcolor="#FF2E9B5C" borderround="4,4" />
 					<Control width="8" />
 					<Control width="8" />
@@ -71,7 +77,7 @@
 					<VerticalLayout maxheight="92" bkimage="file='jb_card_field_hl.png' corner='16,16,16,16'" inset="17,15,17,15" childpadding="9"><Label text="现金净增长" font="12" textcolor="#FF5F6368" height="17" /><Label name="diannei_xianjin_zengzhang" showhtml="true" font="122" textcolor="#FF2E9B5C" height="36" bkimage="file='jb_pill_grn_hl.png' corner='18,18,18,18'" textpadding="15,3,15,3" autocalcwidth="true" valign="top" text="{c #62B585}{f 14}¥{/f}{/c}{x 3}--{x 3}{c #62B585}{f 11}.00{/f}{/c}" /></VerticalLayout>
 					<VerticalLayout maxheight="92" bkimage="file='jb_card_field_hl.png' corner='16,16,16,16'" inset="17,15,17,15" childpadding="9"><Label text="现金净增长" font="12" textcolor="#FF5F6368" height="17" /><Label name="diannei_xianjin_zengzhang" showhtml="true" font="122" textcolor="#FF2E9B5C" height="36" bkimage="file='jb_pill_grn_hl.png' corner='18,18,18,18'" textpadding="15,3,15,3" autocalcwidth="true" valign="top" text="{c #62B585}{f 14}¥{/f}{/c}{x 3}--{x 3}{c #62B585}{f 11}.00{/f}{/c}" /></VerticalLayout>
 				</HorizontalLayout>
 				</HorizontalLayout>
 			</VerticalLayout>
 			</VerticalLayout>
-			<HorizontalLayout height="50" childvalign="vcenter" inset="0,6,0,0">
+			<HorizontalLayout padding="0,0,28,0" height="50" childvalign="vcenter" inset="0,6,0,0">
 				<Control />
 				<Control />
 				<Button name="jiaoban_page_queren_btn" width="180" maxheight="44" text="✓  交班并退出登录" font="114" textcolor="#FFFFFFFF" normalimage="file='jb_btn_green_normal.png'" hotimage="file='jb_btn_green_hot.png'" pushedimage="file='jb_btn_green_pushed.png'" />
 				<Button name="jiaoban_page_queren_btn" width="180" maxheight="44" text="✓  交班并退出登录" font="114" textcolor="#FFFFFFFF" normalimage="file='jb_btn_green_normal.png'" hotimage="file='jb_btn_green_hot.png'" pushedimage="file='jb_btn_green_pushed.png'" />
 				<Control width="12" />
 				<Control width="12" />

+ 221 - 157
zhipuzi_pos_windows/page/CBaobiaoPageUI.cpp

@@ -29,6 +29,9 @@ void CBaobiaoPageUI::InitShow()
 	m_init_time = s_now + " 00:00:00";
 	m_init_time = s_now + " 00:00:00";
 	m_end_time = s_now + " 23:59:59";
 	m_end_time = s_now + " 23:59:59";
 
 
+	//默认停在「今天」
+	SetActiveTab(0);
+
 	Refresh();
 	Refresh();
 }
 }
 
 
@@ -99,28 +102,198 @@ bool CBaobiaoPageUI::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam
 	return false;
 	return false;
 }
 }
 
 
+//==================== 第五十六轮:报表页格式化与胶囊渲染 ====================
+
+//整数部分每三位加逗号(CLewaimaiString::DoubleToString 不带千分位)
+static std::wstring Baobiao_GroupDigits(const std::wstring& strIntPart)
+{
+	std::wstring strOut;
+	int nLen = (int)strIntPart.size();
+	for (int i = 0; i < nLen; i++)
+	{
+		if (i > 0 && (nLen - i) % 3 == 0)
+		{
+			strOut += L',';
+		}
+		strOut += strIntPart[i];
+	}
+	return strOut;
+}
+
+//把金额拆成整数部分与小数部分(小数部分含小数点)
+static void Baobiao_SplitMoney(double dValue, std::wstring& strIntPart, std::wstring& strDecPart)
+{
+	std::string s = CLewaimaiString::DoubleToString(dValue, 2);
+	std::wstring ws = CLewaimaiString::UTF8ToUnicode(s);
+
+	size_t nDot = ws.find(L'.');
+	if (nDot == std::wstring::npos)
+	{
+		strIntPart = ws;
+		strDecPart = L"";
+	}
+	else
+	{
+		strIntPart = ws.substr(0, nDot);
+		strDecPart = ws.substr(nDot);
+	}
+}
+
+//形如 ¥1,234.50(副标题用的纯文本,不带 showhtml 标记)
+static std::wstring Baobiao_MoneyText(double dValue)
+{
+	std::wstring strInt, strDec;
+	Baobiao_SplitMoney(dValue, strInt, strDec);
+	return std::wstring(L"\u00A5") + Baobiao_GroupDigits(strInt) + strDec;
+}
+
+//形如 59.8%(分母为 0 时给 --)
+//不用 swprintf_s:它是 MSVC 安全 CRT 扩展,依赖 <cstdio>,本项目 pch 不保证引入,
+//这里改成纯 std::to_wstring 拼接,零额外依赖。
+static std::wstring Baobiao_PercentText(int nPart, int nTotal)
+{
+	if (nTotal <= 0)
+	{
+		return L"--";
+	}
+
+	//先放大 1000 倍再四舍五入,取到十分位(59.8% 存成 598)
+	int nTenth = (int)(nPart * 1000.0 / nTotal + 0.5);
+
+	std::wstring strOut = std::to_wstring(nTenth / 10);
+	strOut += L'.';
+	strOut += std::to_wstring(nTenth % 10);
+	strOut += L'%';
+	return strOut;
+}
+
+//当前时刻 HH:MM
+static std::wstring Baobiao_ClockText()
+{
+	time_t now = time(NULL);
+	struct tm tmNow;
+	localtime_s(&tmNow, &now);
+
+	std::wstring strOut;
+	if (tmNow.tm_hour < 10)
+	{
+		strOut += L'0';
+	}
+	strOut += std::to_wstring(tmNow.tm_hour);
+	strOut += L':';
+	if (tmNow.tm_min < 10)
+	{
+		strOut += L'0';
+	}
+	strOut += std::to_wstring(tmNow.tm_min);
+	return strOut;
+}
+
+void CBaobiaoPageUI::SetActiveTab(int nIndex)
+{
+	//四态完整切换(第五十六轮补):main.xml 的 <Default name="Button"> 给所有按钮
+	//默认套了 btn_green_* 三态图,所以 hot / pushed 必须显式接管,否则悬浮和按下
+	//会突然变成全局绿按钮样式(浅绿底黑字),与胶囊 Tab 完全不协调。
+	//  未选中:常态灰底灰字,悬浮浅绿底(#D8EFE3)绿字,按下再深一档(#C4E8D4)
+	//  选中:常态绿底(#2E9B5C)白字粗体,悬浮亮一档(#3AA968),按下暗一档(#27884F)
+	static const wchar_t* TAB_NAMES[4] = { L"btn_jintian", L"btn_zuotian", L"btn_qitian", L"btn_sanshitian" };
+
+	for (int i = 0; i < 4; i++)
+	{
+		CButtonUI* pBtn = static_cast<CButtonUI*>(this->FindSubControl(TAB_NAMES[i]));
+		if (pBtn == NULL)
+		{
+			continue;
+		}
+
+		if (i == nIndex)
+		{
+			pBtn->SetNormalImage(L"file='bb_tab_active.png' corner='20,20,20,20'");
+			pBtn->SetHotImage(L"file='bb_tab_active_hot.png' corner='20,20,20,20'");
+			pBtn->SetPushedImage(L"file='bb_tab_active_pushed.png' corner='20,20,20,20'");
+			pBtn->SetTextColor(0xFFFFFFFF);
+			pBtn->SetHotTextColor(0xFFFFFFFF);
+			pBtn->SetPushedTextColor(0xFFFFFFFF);
+			pBtn->SetFont(115);
+		}
+		else
+		{
+			pBtn->SetNormalImage(L"");
+			pBtn->SetHotImage(L"file='bb_tab_hover.png' corner='20,20,20,20'");
+			pBtn->SetPushedImage(L"file='bb_tab_pushed.png' corner='20,20,20,20'");
+			pBtn->SetTextColor(0xFF5F6368);
+			pBtn->SetHotTextColor(0xFF2E9B5C);
+			pBtn->SetPushedTextColor(0xFF2E9B5C);
+			pBtn->SetFont(15);
+		}
+	}
+}
+
+void CBaobiaoPageUI::SetPillCount(const wchar_t* lpName, int nValue, const wchar_t* lpUnit, const wchar_t* lpLightColor)
+{
+	CLabelUI* pLabel = static_cast<CLabelUI*>(this->FindSubControl(lpName));
+	if (pLabel == NULL)
+	{
+		return;
+	}
+
+	//{c} 只准 6 位 #RRGGBB。写成 8 位(#FF77ACE9)会被 UIRender.cpp 的 _tcstol
+	//饱和成 0x7FFFFFFF,真机上画出来是一片近白。
+	std::wstring strText = std::to_wstring(nValue);
+	strText += L"{x 4}{c ";
+	strText += lpLightColor;
+	strText += L"}{f 12}";
+	strText += lpUnit;
+	strText += L"{/f}{/c}";
+
+	pLabel->SetText(strText.c_str());
+	//autocalcwidth 的估宽缓存在 SetText 后不会自动失效,必须重置 font 触发重算
+	pLabel->SetFont(pLabel->GetFont());
+}
+
+void CBaobiaoPageUI::SetPillMoney(const wchar_t* lpName, double dValue, const wchar_t* lpLightColor)
+{
+	CLabelUI* pLabel = static_cast<CLabelUI*>(this->FindSubControl(lpName));
+	if (pLabel == NULL)
+	{
+		return;
+	}
+
+	std::wstring strInt, strDec;
+	Baobiao_SplitMoney(dValue, strInt, strDec);
+
+	std::wstring strText = L"{c ";
+	strText += lpLightColor;
+	strText += L"}{f 14}\u00A5{/f}{/c}{x 3}";
+	strText += Baobiao_GroupDigits(strInt);
+
+	if (!strDec.empty())
+	{
+		strText += L"{c ";
+		strText += lpLightColor;
+		strText += L"}{f 12}";
+		strText += strDec;
+		strText += L"{/f}{/c}";
+	}
+
+	pLabel->SetText(strText.c_str());
+	pLabel->SetFont(pLabel->GetFont());
+}
+
+void CBaobiaoPageUI::SetSubText(const wchar_t* lpName, const std::wstring& strText)
+{
+	CLabelUI* pLabel = static_cast<CLabelUI*>(this->FindSubControl(lpName));
+	if (pLabel == NULL)
+	{
+		return;
+	}
+
+	pLabel->SetText(strText.c_str());
+}
+
 void CBaobiaoPageUI::ShowJintian()
 void CBaobiaoPageUI::ShowJintian()
 {
 {
-	//先处理顶部按钮状态变化
-	CButtonUI* jintian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_jintian"));
-	CControlUI* jintian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_jintian_line"));
-	jintian->SetTextColor(0xFF43A947);
-	jintian_line->SetVisible(true);
-
-	CButtonUI* zuotian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_zuotian"));
-	CControlUI* zuotian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_zuotian_line"));
-	zuotian->SetTextColor(0xFF555555);
-	zuotian_line->SetVisible(false);
-
-	CButtonUI* qitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_qitian"));
-	CControlUI * qitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_qitian_line"));
-	qitian->SetTextColor(0xFF555555);
-	qitian_line->SetVisible(false);
-
-	CButtonUI* sanshitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_sanshitian"));
-	CControlUI * sanshitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_sanshitian_line"));
-	sanshitian->SetTextColor(0xFF555555);
-	sanshitian_line->SetVisible(false);
+	SetActiveTab(0);
 
 
 	//然后处理日期
 	//然后处理日期
 	time_t now = time(NULL);
 	time_t now = time(NULL);
@@ -135,26 +308,7 @@ void CBaobiaoPageUI::ShowJintian()
 
 
 void CBaobiaoPageUI::ShowZuotian()
 void CBaobiaoPageUI::ShowZuotian()
 {
 {
-	//先处理顶部按钮状态变化
-	CButtonUI* jintian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_jintian"));
-	CControlUI* jintian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_jintian_line"));
-	jintian->SetTextColor(0xFF555555);
-	jintian_line->SetVisible(false);
-
-	CButtonUI* zuotian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_zuotian"));
-	CControlUI* zuotian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_zuotian_line"));
-	zuotian->SetTextColor(0xFF43A947);
-	zuotian_line->SetVisible(true);
-
-	CButtonUI* qitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_qitian"));
-	CControlUI * qitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_qitian_line"));
-	qitian->SetTextColor(0xFF555555);
-	qitian_line->SetVisible(false);
-
-	CButtonUI* sanshitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_sanshitian"));
-	CControlUI * sanshitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_sanshitian_line"));
-	sanshitian->SetTextColor(0xFF555555);
-	sanshitian_line->SetVisible(false);
+	SetActiveTab(1);
 
 
 	//然后处理日期
 	//然后处理日期
 	time_t now = time(NULL);
 	time_t now = time(NULL);
@@ -169,26 +323,7 @@ void CBaobiaoPageUI::ShowZuotian()
 
 
 void CBaobiaoPageUI::ShowQitian()
 void CBaobiaoPageUI::ShowQitian()
 {
 {
-	//先处理顶部按钮状态变化
-	CButtonUI* jintian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_jintian"));
-	CControlUI* jintian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_jintian_line"));
-	jintian->SetTextColor(0xFF555555);
-	jintian_line->SetVisible(false);
-
-	CButtonUI* zuotian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_zuotian"));
-	CControlUI* zuotian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_zuotian_line"));
-	zuotian->SetTextColor(0xFF555555);
-	zuotian_line->SetVisible(false);
-
-	CButtonUI* qitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_qitian"));
-	CControlUI * qitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_qitian_line"));
-	qitian->SetTextColor(0xFF43A947);
-	qitian_line->SetVisible(true);
-
-	CButtonUI* sanshitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_sanshitian"));
-	CControlUI * sanshitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_sanshitian_line"));
-	sanshitian->SetTextColor(0xFF555555);
-	sanshitian_line->SetVisible(false);
+	SetActiveTab(2);
 
 
 	//然后处理日期
 	//然后处理日期
 	time_t now = time(NULL);
 	time_t now = time(NULL);
@@ -205,26 +340,7 @@ void CBaobiaoPageUI::ShowQitian()
 
 
 void CBaobiaoPageUI::ShowSanshitian()
 void CBaobiaoPageUI::ShowSanshitian()
 {
 {
-	//先处理顶部按钮状态变化
-	CButtonUI* jintian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_jintian"));
-	CControlUI* jintian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_jintian_line"));
-	jintian->SetTextColor(0xFF555555);
-	jintian_line->SetVisible(false);
-
-	CButtonUI* zuotian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_zuotian"));
-	CControlUI* zuotian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_zuotian_line"));
-	zuotian->SetTextColor(0xFF555555);
-	zuotian_line->SetVisible(false);
-
-	CButtonUI* qitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_qitian"));
-	CControlUI * qitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_qitian_line"));
-	qitian->SetTextColor(0xFF555555);
-	qitian_line->SetVisible(false);
-
-	CButtonUI* sanshitian = static_cast<CButtonUI*>(this->FindSubControl(L"btn_sanshitian"));
-	CControlUI * sanshitian_line = static_cast<CControlUI*>(this->FindSubControl(L"btn_sanshitian_line"));
-	sanshitian->SetTextColor(0xFF43A947);
-	sanshitian_line->SetVisible(true);
+	SetActiveTab(3);
 
 
 	//然后处理日期
 	//然后处理日期
 	time_t now = time(NULL);
 	time_t now = time(NULL);
@@ -299,32 +415,37 @@ void CBaobiaoPageUI::DoRefresh()
 	//获得数据成功
 	//获得数据成功
 	rapidjson::Value& data = document["data"];
 	rapidjson::Value& data = document["data"];
 
 
-	std::string waimai_num = std::to_string(data["waimai_member"].GetInt());
-	std::string diannei_num = std::to_string(data["diannei_member"].GetInt());
-	std::string huiyuan_num = std::to_string(data["today_member"].GetInt());
-
-	std::string waimai_value = CLewaimaiString::DoubleToString(data["waimai_money"].GetFloat(), 2);
-	std::string diannei_value = CLewaimaiString::DoubleToString(data["diannei_money"].GetFloat(), 2);
-	std::string huiyuan_value = CLewaimaiString::DoubleToString(data["today_recharge"].GetFloat(), 2);
+	int nWaimaiNum = data["waimai_member"].GetInt();
+	int nDianneiNum = data["diannei_member"].GetInt();
+	int nHuiyuanNum = data["today_member"].GetInt();
 
 
-	//开始渲染数据
-	CLabelUI* waimainumLabel = static_cast<CLabelUI*>(this->FindSubControl(L"waimai_num"));
-	waimainumLabel->SetText(CLewaimaiString::UTF8ToUnicode(waimai_num).c_str());
+	double dWaimaiMoney = (double)data["waimai_money"].GetFloat();
+	double dDianneiMoney = (double)data["diannei_money"].GetFloat();
+	double dRecharge = (double)data["today_recharge"].GetFloat();
 
 
-	CLabelUI* waimaivalueLabel = static_cast<CLabelUI*>(this->FindSubControl(L"waimai_value"));
-	waimaivalueLabel->SetText(CLewaimaiString::UTF8ToUnicode(waimai_value).c_str());
+	int nTotalOrder = nWaimaiNum + nDianneiNum;
 
 
-	CLabelUI* dianneinumLabel = static_cast<CLabelUI*>(this->FindSubControl(L"diannei_num"));
-	dianneinumLabel->SetText(CLewaimaiString::UTF8ToUnicode(diannei_num).c_str());
+	//6 张字段卡的数字胶囊:外卖蓝、店内橙、会员绿
+	SetPillCount(L"waimai_num", nWaimaiNum, L"\u5355", L"#77ACE9");
+	SetPillMoney(L"waimai_value", dWaimaiMoney, L"#77ACE9");
+	SetPillCount(L"diannei_num", nDianneiNum, L"\u5355", L"#E8A750");
+	SetPillMoney(L"diannei_value", dDianneiMoney, L"#E8A750");
+	SetPillCount(L"huiyuan_num", nHuiyuanNum, L"\u4EBA", L"#62B585");
+	SetPillMoney(L"huiyuan_value", dRecharge, L"#62B585");
 
 
-	CLabelUI* dianneivalueLabel = static_cast<CLabelUI*>(this->FindSubControl(L"diannei_value"));
-	dianneivalueLabel->SetText(CLewaimaiString::UTF8ToUnicode(diannei_value).c_str());
+	//副标题全部由本次返回的数据现算,不额外发请求
+	SetSubText(L"waimai_num_sub", L"\u5360\u603B\u8BA2\u5355 " + Baobiao_PercentText(nWaimaiNum, nTotalOrder));
+	SetSubText(L"diannei_num_sub", L"\u5360\u603B\u8BA2\u5355 " + Baobiao_PercentText(nDianneiNum, nTotalOrder));
+	SetSubText(L"huiyuan_num_sub", L"\u65B0\u5BA2\u5360\u8BA2\u5355 " + Baobiao_PercentText(nHuiyuanNum, nTotalOrder));
 
 
-	CLabelUI* huiyuannumLabel = static_cast<CLabelUI*>(this->FindSubControl(L"huiyuan_num"));
-	huiyuannumLabel->SetText(CLewaimaiString::UTF8ToUnicode(huiyuan_num).c_str());
+	SetSubText(L"waimai_value_sub", L"\u5BA2\u5355\u4EF7 " + Baobiao_MoneyText(nWaimaiNum > 0 ? dWaimaiMoney / nWaimaiNum : 0.0));
+	SetSubText(L"diannei_value_sub", L"\u5BA2\u5355\u4EF7 " + Baobiao_MoneyText(nDianneiNum > 0 ? dDianneiMoney / nDianneiNum : 0.0));
+	SetSubText(L"huiyuan_value_sub", L"\u7B14\u5747 " + Baobiao_MoneyText(nHuiyuanNum > 0 ? dRecharge / nHuiyuanNum : 0.0));
 
 
-	CLabelUI* huiyuanvalueLabel = static_cast<CLabelUI*>(this->FindSubControl(L"huiyuan_value"));
-	huiyuanvalueLabel->SetText(CLewaimaiString::UTF8ToUnicode(huiyuan_value).c_str());
+	//顶部工具条右侧:统计区间 + 数据更新时间
+	SetSubText(L"bb_range_value",
+		CLewaimaiString::UTF8ToUnicode(m_init_time) + L" ~ " + CLewaimaiString::UTF8ToUnicode(m_end_time));
+	SetSubText(L"bb_update_time", L"\u6570\u636E\u5DF2\u66F4\u65B0 \u00B7 " + Baobiao_ClockText());
 
 
 	CContainerUI* pOrderListLayout = static_cast<CContainerUI*>(this->FindSubControl(_T("data_layout")));
 	CContainerUI* pOrderListLayout = static_cast<CContainerUI*>(this->FindSubControl(_T("data_layout")));
 	pOrderListLayout->SetVisible(true);
 	pOrderListLayout->SetVisible(true);
@@ -332,60 +453,3 @@ void CBaobiaoPageUI::DoRefresh()
 	this->FindSubControl(_T("loading"))->SetVisible(false);
 	this->FindSubControl(_T("loading"))->SetVisible(false);
 }
 }
 
 
-void CBaobiaoPageUI::SetPos(RECT rc, bool bNeedInvalidate)
-{
-	int m_nPageWidth = rc.right - rc.left;
-
-	//添加支付方式
-	int nWidth = m_nPageWidth;
-	if (nWidth == 0)
-	{
-		return;
-	}
-
-	//根据宽度计算每行显示的数量
-	int nMeihangNum = nWidth / 260;
-
-	if (nMeihangNum < 1)
-	{
-		nMeihangNum = 1;
-	}
-
-	int num = 0;
-
-	CHorizontalLayoutUI* pFenleiLayout = static_cast<CHorizontalLayoutUI*>(this->FindSubControl(_T("baobiao_page_yingye_items")));
-	for (int i = 0; i < 6; i++)
-	{
-		CVerticalLayoutUI* curItem = static_cast<CVerticalLayoutUI*>(pFenleiLayout->GetItemAt(i));
-
-		int curRow = num / nMeihangNum + 1;
-		int curCol = num % nMeihangNum + 1;
-
-		RECT rect;
-		rect.left = (curCol - 1) * 260 + 20;
-		rect.right = rect.left + 240;
-		rect.top = (curRow - 1) * 146 + 20;
-		rect.bottom = rect.top + 126;
-
-		curItem->SetFloat(true);
-
-		// 强制设置固定大小和位置
-		SIZE size;
-		size.cx = rect.left;
-		size.cy = rect.top;
-
-		curItem->SetFixedXY(size);
-		curItem->SetFixedWidth(rect.right - rect.left);
-		curItem->SetFixedHeight(rect.bottom - rect.top);
-
-		num++;
-	}
-
-	//调整区域高度
-	CVerticalLayoutUI* pLayout = static_cast<CVerticalLayoutUI*>(this->FindSubControl(_T("data_layout")));
-
-	int lastRow = (num - 1) / nMeihangNum + 1;
-	pLayout->SetFixedHeight(lastRow * 146 + 20 + 30);
-
-	CContainerUI::SetPos(rc, bNeedInvalidate);
-}

+ 11 - 2
zhipuzi_pos_windows/page/CBaobiaoPageUI.h

@@ -39,11 +39,20 @@ public:
 	void ShowQitian();
 	void ShowQitian();
 	void ShowSanshitian();
 	void ShowSanshitian();
 
 
+	//第五十六轮:顶部胶囊 Tab 的选中态统一在这里切换(改版后不再有 btn_xxx_line 下划线)
+	void SetActiveTab(int nIndex);
+
+	//数字胶囊:nValue 主数字 + lpUnit 单位(浅色小字),lpLightColor 为 6 位 #RRGGBB
+	void SetPillCount(const wchar_t* lpName, int nValue, const wchar_t* lpUnit, const wchar_t* lpLightColor);
+
+	//金额胶囊:¥ 与小数位走浅色小字,整数部分走主色并加千分位
+	void SetPillMoney(const wchar_t* lpName, double dValue, const wchar_t* lpLightColor);
+
+	void SetSubText(const wchar_t* lpName, const std::wstring& strText);
+
 	void Refresh();
 	void Refresh();
 	void HandleRefresh();
 	void HandleRefresh();
 	void DoRefresh();
 	void DoRefresh();
-
-	void SetPos(RECT rc, bool bNeedInvalidate = true);
 private:
 private:
 	
 	
 
 

+ 27 - 65
zhipuzi_pos_windows/page/CJiaobanPageUI.cpp

@@ -83,6 +83,11 @@ void CJiaobanPageUI::InitShow()
 	SetTextByName(_T("jiaoban_page_end_time"), CLewaimaiString::UTF8ToUnicode(m_end_time));
 	SetTextByName(_T("jiaoban_page_end_time"), CLewaimaiString::UTF8ToUnicode(m_end_time));
 	SetTextByName(_T("jiaoban_page_account"), CLewaimaiString::UTF8ToUnicode(CZhipuziHttpClient::GetInstance()->GetUsername()));
 	SetTextByName(_T("jiaoban_page_account"), CLewaimaiString::UTF8ToUnicode(CZhipuziHttpClient::GetInstance()->GetUsername()));
 
 
+	//第五十三轮:开班时间取自接口的「最近一次登录时间」。
+	//已经拉到过就继续显示上次的值(避免切回页面时被刷成 --),还没拉到则先显示占位。
+	SetTextByName(_T("jiaoban_page_init_time"),
+		(m_bTimeLoaded && !m_init_time.empty()) ? CLewaimaiString::UTF8ToUnicode(m_init_time) : L"--");
+
 	UpdateDurationLabel();
 	UpdateDurationLabel();
 
 
 	HideErrorTip();
 	HideErrorTip();
@@ -143,40 +148,8 @@ void CJiaobanPageUI::HandleSelectChangeMsg(TNotifyUI& msg)
 //处理下拉框、radio的切换事件
 //处理下拉框、radio的切换事件
 void CJiaobanPageUI::HandleItemSelectMsg(TNotifyUI& msg)
 void CJiaobanPageUI::HandleItemSelectMsg(TNotifyUI& msg)
 {
 {
-	CDuiString name = msg.pSender->GetName();
-
-	if (name == _T("jiaoban_page_init_time_select"))
-	{
-		//程序化选中(刚拉完时间列表自动选最后一项)不触发刷新,否则会和 DoJiaobanShijianOk 末尾的刷新撞车
-		if (m_bSettingCombo)
-		{
-			return;
-		}
-
-		CComboUI* com = static_cast<CComboUI*>(this->FindSubControl(_T("jiaoban_page_init_time_select")));
-		if (com == NULL)
-		{
-			return;
-		}
-
-		int sel = com->GetCurSel();
-		if (sel < 0)
-		{
-			return;
-		}
-
-		CControlUI* item = com->GetItemAt(sel);
-		if (item == NULL)
-		{
-			return;
-		}
-
-		m_init_time = CLewaimaiString::UnicodeToUTF8(std::wstring(item->GetText()));
-
-		UpdateDurationLabel();
-
-		Refresh();
-	}
+	//第五十三轮:开班时间不再由用户下拉选择(改由接口下发的最近一次登录时间直接决定),
+	//页面已无任何 Combo / Option,这里保持空实现即可。
 }
 }
 
 
 //处理编辑框输入内容改变事件
 //处理编辑框输入内容改变事件
@@ -296,55 +269,44 @@ void CJiaobanPageUI::HandleJiaobanShijian()
 		return;
 		return;
 	}
 	}
 
 
+	//第五十三轮:不再需要时间列表(页面已无下拉框),只取「最近一次登录时间」作为开班时间。
+	//接口 rows 按时间升序返回,最后一条即最近一次登录 —— 与改造前「默认选中最后一项」的语义一致。
 	rapidjson::Value& rows = data["rows"];
 	rapidjson::Value& rows = data["rows"];
 
 
-	m_shangban_times.clear();
+	std::string lastLoginTime;
 
 
-	//只保留最近 10 条
-	int qidian = 0;
-	if (rows.Size() > (rapidjson::SizeType)10)
+	for (rapidjson::SizeType i = 0; i < rows.Size(); ++i)
 	{
 	{
-		qidian = (int)rows.Size() - 10;
+		if (!rows[i].HasMember("init_time") || !rows[i]["init_time"].IsString())
+		{
+			continue;
+		}
+
+		lastLoginTime = rows[i]["init_time"].GetString();
 	}
 	}
 
 
-	for (rapidjson::SizeType i = (rapidjson::SizeType)qidian; i < rows.Size(); ++i)
+	if (lastLoginTime.empty())
 	{
 	{
-		m_shangban_times.push_back(rows[i]["init_time"].GetString());
+		LOG_INFO("no valid init_time in rows!");
+		m_errinfo = L"服务器返回的开班时间为空";
+		PostMessage(m_pManager->GetPaintWindow(), WM_JIAOBAN_TIME_FAIL, 0, 0);
+		return;
 	}
 	}
 
 
-	//取最后一个时间点作为默认开班时间
-	m_init_time = m_shangban_times[m_shangban_times.size() - 1];
+	m_init_time = lastLoginTime;
 
 
 	PostMessage(m_pManager->GetPaintWindow(), WM_JIAOBAN_TIME_OK, 0, 0);
 	PostMessage(m_pManager->GetPaintWindow(), WM_JIAOBAN_TIME_OK, 0, 0);
 }
 }
 
 
-//主线程:把时间列表填进下拉框(原来这段代码在子线程里,违反单线程约束)
+//主线程:把「最近一次登录时间」写进顶部条的只读 Label
 void CJiaobanPageUI::DoJiaobanShijianOk()
 void CJiaobanPageUI::DoJiaobanShijianOk()
 {
 {
 	m_is_handle = false;
 	m_is_handle = false;
 	m_bTimeLoaded = true;
 	m_bTimeLoaded = true;
 
 
-	CComboUI* com = static_cast<CComboUI*>(this->FindSubControl(_T("jiaoban_page_init_time_select")));
-	if (com != NULL)
-	{
-		com->RemoveAll();
-
-		for (size_t i = 0; i < m_shangban_times.size(); i++)
-		{
-			CListLabelElementUI* elem = new CListLabelElementUI();
-			elem->SetText(CLewaimaiString::UTF8ToUnicode(m_shangban_times[i]).c_str());
-			com->Add(elem);
-		}
-
-		if (!m_shangban_times.empty())
-		{
-			m_bSettingCombo = true;
-			com->SelectItem((int)m_shangban_times.size() - 1, false);
-			m_bSettingCombo = false;
-
-			com->SetText(CLewaimaiString::UTF8ToUnicode(m_init_time).c_str());
-		}
-	}
+	//第五十三轮:开班时间是只读值(取自接口),不再有下拉框可改选
+	SetTextByName(_T("jiaoban_page_init_time"),
+		m_init_time.empty() ? L"--" : CLewaimaiString::UTF8ToUnicode(m_init_time));
 
 
 	UpdateDurationLabel();
 	UpdateDurationLabel();
 
 

+ 4 - 7
zhipuzi_pos_windows/page/CJiaobanPageUI.h

@@ -35,7 +35,7 @@ public:
 	bool HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
 	bool HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
 
 
 private:
 private:
-	//第一步:拉取开班时间列表。子线程只抓数据,绝对不碰 UI
+	//第一步:拉取最近一次登录时间作为开班时间。子线程只抓数据,绝对不碰 UI
 	void InitJiaobanShijian();
 	void InitJiaobanShijian();
 	void HandleJiaobanShijian();
 	void HandleJiaobanShijian();
 	void DoJiaobanShijianOk();
 	void DoJiaobanShijianOk();
@@ -91,15 +91,14 @@ private:
 	//是否正在请求服务器
 	//是否正在请求服务器
 	bool m_is_handle = false;
 	bool m_is_handle = false;
 
 
-	//开班时间列表是否已加载成功(决定重试时走哪一步)
+	//开班时间(接口下发的最近一次登录时间)是否已加载成功(决定重试时走哪一步)
 	bool m_bTimeLoaded = false;
 	bool m_bTimeLoaded = false;
 
 
 	//统计数据是否已加载成功(未加载不允许交班,避免交出一份空数据)
 	//统计数据是否已加载成功(未加载不允许交班,避免交出一份空数据)
 	bool m_bDataLoaded = false;
 	bool m_bDataLoaded = false;
 
 
-	//程序化选中下拉项时置 true,屏蔽 SelectItem 派发出来的 itemselect,避免重复刷新
-	bool m_bSettingCombo = false;
-
+	//m_init_time = 开班时间(服务端下发,只读展示,用户不可改选)
+	//m_end_time   = 交班时间(本机当前时间)
 	std::string m_init_time;
 	std::string m_init_time;
 	std::string m_end_time;
 	std::string m_end_time;
 
 
@@ -117,8 +116,6 @@ private:
 	std::string m_diannei_xianjin_tuikuan;
 	std::string m_diannei_xianjin_tuikuan;
 	std::string m_diannei_xianjin_zengzhang;
 	std::string m_diannei_xianjin_zengzhang;
 
 
-	std::vector<std::string> m_shangban_times;
-
 	std::string m_response;
 	std::string m_response;
 
 
 	std::wstring m_errinfo;
 	std::wstring m_errinfo;

BIN
zhipuzi_pos_windows/resource/skin.zip