From fa0ab417e113021f7c4c8b20ac5b931477b5a3cd Mon Sep 17 00:00:00 2001 From: minom Date: Wed, 9 Sep 2026 16:51:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=BF=AB=E9=80=9F=E5=A0=B1?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/App_Code/api/orderController.cs | 78 +- web/admin/bill/index.aspx | 2 +- web/admin/hrs/basic/company.aspx | 11 + web/admin/pivot/pivot-01.aspx | 2 +- web/admin/print/TabletDesign.aspx | 724 +++++++++++++----- web/admin/print/tablet_edit/editorNewOne.html | 150 ++-- 6 files changed, 723 insertions(+), 244 deletions(-) diff --git a/web/App_Code/api/orderController.cs b/web/App_Code/api/orderController.cs index 4add9d4..c5d0dbe 100644 --- a/web/App_Code/api/orderController.cs +++ b/web/App_Code/api/orderController.cs @@ -1,4 +1,5 @@ using DocumentFormat.OpenXml.Drawing.Charts; +using DocumentFormat.OpenXml.Spreadsheet; using Model; using MyWeb; using Newtonsoft.Json; @@ -227,6 +228,8 @@ public class orderController : ApiController var hasList = _db.pro_order.AsNoTracking().Where(x => x.activity_num == po.activity_num).AsNoTracking().ToList(); var actItemList=_db.activity_relating.AsNoTracking().Where(x=>x.activity_num==po.activity_num).AsNoTracking().ToList(); List rp=new List(); + string print_id=string.Empty; + var items = _db.actItems.AsQueryable(); //要檢查是否已經報名 foreach (var item in list) { @@ -254,8 +257,10 @@ public class orderController : ApiController item.up_time= DateTime.Now; item.order_no= createOrderNumber(); item.activity_num= po.activity_num; - + item.activity = act; + print_id=string.Empty; _db.pro_order.Add(item); + _db.SaveChanges(); orders.Add(item); foreach (var detail in item.pro_order_detail) { @@ -286,17 +291,41 @@ public class orderController : ApiController detail.start_date= act.startDate_solar; detail.due_date= act.endDate_solar; detail.printed_files = ""; - detail.print_id= GenerateSequentialId(detail, item); + detail.actItem_num = actItem.num; + //if (string.IsNullOrEmpty(print_id)) + //{ + // print_id = GenerateSequentialId(detail, item); + //} + //else + //{ + // string last_three = print_id.Substring(print_id.Length - 3); + // if (int.TryParse(last_three, out int result)) + // { + // print_id = print_id.Substring(0, print_id.Length - 3) + string.Format("{0:D3}", result + 1); + // } + // else + // { + // string last_two = print_id.Substring(print_id.Length - 2); + // if (int.TryParse(last_two, out int result1)) + // { + // print_id = print_id.Substring(0, print_id.Length - 2) + string.Format("{0:D2}", result1 + 1); + // } + // } + //} + var defaultStyle=items.Where(i => i.num == detail.actItem_num).Select(i=>i.defaultStyle).FirstOrDefault(); + detail.style = defaultStyle==null?"":defaultStyle; + detail.print_id = GenerateSequentialId(detail, item); _db.pro_order_detail.Add(detail); + _db.SaveChanges(); } - + } //_db.pro_order.AddRange(orders); //_db.SaveChanges(); //_db.pro_order_detail.AddRange(order_details); - _db.SaveChanges(); + return Ok(new {result="Y",message="完成",data=rp}); } catch (Exception ex) @@ -979,7 +1008,7 @@ public class orderController : ApiController var last_order = _db.pro_order.Where(x => x.order_no == last_order_no).FirstOrDefault(); if (last_order != null) { - + var activity = _db.activities.Where(z => z.num == item.activity_num).FirstOrDefault(); new_pro_order.up_time = DateTime.Now; new_pro_order.reg_time = DateTime.Now; new_pro_order.phone = last_order.phone; @@ -991,13 +1020,17 @@ public class orderController : ApiController new_pro_order.customize_data = last_order.customize_data; new_pro_order.send_receipt = last_order.send_receipt; new_pro_order.receipt_title = last_order.receipt_title; + new_pro_order.activity = activity; _db.pro_order.Add(new_pro_order); - - + var items = _db.actItems.AsQueryable(); + string print_id = ""; + //判斷如果details只有一個,要檢查是否為功德主,是的話撈出牌位,做成功德主底下的 foreach (var item1 in details) {//如果item1 change_item_num 有值且不為0,表示要複製過來 + var last_detail = _db.pro_order_detail.Where(x => x.num == item1.num).FirstOrDefault(); var detail = new pro_order_detail(); + detail.order_no = new_pro_order.order_no; detail.actItem_num = (item1.change_item_num!=null&&item1.change_item_num!=0)?item1.change_item_num: last_detail.actItem_num; detail.f_num_tablet = last_detail.f_num_tablet; @@ -1005,14 +1038,39 @@ public class orderController : ApiController detail.price = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.price : last_detail.price; detail.qty = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.qty : last_detail.qty; detail.printed_files = "";//(item1.change_item_num != null && item1.change_item_num != 0) ? item1.printed_files : last_detail.printed_files; - detail.style = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.style : last_detail.style; + //要改抓回牌位的預設版型 + var defaultStyle = items.Where(i => i.num == detail.actItem_num).Select(i => i.defaultStyle).FirstOrDefault(); + detail.style = defaultStyle == null ? "" : defaultStyle; + //detail.style = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.style : last_detail.style; detail.UpdateTime = DateTime.Now; detail.start_date = DateTime.Now;//這兩個要用活動的 detail.due_date = DateTime.Now;// - detail.print_id= GenerateSequentialId(detail, new_pro_order); + // //因為還沒進資料庫,所以會跑出一樣的號碼 + //if (string.IsNullOrEmpty(print_id)) + //{ + // print_id = GenerateSequentialId(detail, new_pro_order); + //} + //else + //{ + // string last_three = print_id.Substring(print_id.Length - 3); + // if (int.TryParse(last_three, out int result)) + // { + // print_id = print_id.Substring(0,print_id.Length - 3)+string.Format("{0:D3}",result+1); + // } + // else + // { + // string last_two = print_id.Substring(print_id.Length - 2); + // if (int.TryParse(last_two, out int result1)) + // { + // print_id = print_id.Substring(0, print_id.Length - 2) + string.Format("{0:D2}", result1 + 1); + // } + // } + //} + detail.print_id =GenerateSequentialId(detail, new_pro_order); _db.pro_order_detail.Add(detail); + _db.SaveChanges(); } - _db.SaveChanges(); + return Ok(new { result = "Y", diff --git a/web/admin/bill/index.aspx b/web/admin/bill/index.aspx index 475657f..fbc002d 100644 --- a/web/admin/bill/index.aspx +++ b/web/admin/bill/index.aspx @@ -245,7 +245,7 @@ 'group-component': httpVueLoader('./group_reconcile.vue'), 'personal-component': httpVueLoader('./personal_reconcile.vue'), 'balance-component': httpVueLoader('./balance_reconcile.vue'), - 'verify_query-component': httpVueLoader('./verify_order_record_query.vue'), + 'verify_query-component': httpVueLoader('./audit.vue'), 'balance_query-component': httpVueLoader('./balance_reconcile_query.vue'), 'statistic_query-component': httpVueLoader('./statistic.vue'), }, diff --git a/web/admin/hrs/basic/company.aspx b/web/admin/hrs/basic/company.aspx index 22f5d19..d774861 100644 --- a/web/admin/hrs/basic/company.aspx +++ b/web/admin/hrs/basic/company.aspx @@ -28,6 +28,12 @@ :page.sync="data_table.page" :items-per-page.sync="data_table.pageSize" class="elevation-1"> + + @@ -101,6 +107,11 @@ itemsPerPageOptions: [5, 10, 20, 30], }, }, + modify_dialog: { + show: false, + mode:'view' + }, + currentView:'company-component', search: {} } }, diff --git a/web/admin/pivot/pivot-01.aspx b/web/admin/pivot/pivot-01.aspx index d9b2e25..0f22bc5 100644 --- a/web/admin/pivot/pivot-01.aspx +++ b/web/admin/pivot/pivot-01.aspx @@ -778,7 +778,7 @@ { text: '開始日期', value: '開始日期', width: 120 }, { text: '結束日期', value: '結束日期', width: 120 }, { text: '報名截止', value: '報名截止日', width: 120 }, - { text: '報名數', value: '功德數量', width: 100, align: 'center' }, + { text: '功德數量', value: '功德數量', width: 100, align: 'center' }, { text: '總金額', value: '合計', width: 120, align: 'end' }, { text: '操作', value: 'actions', width: 120, sortable: false, align: 'center' } ], diff --git a/web/admin/print/TabletDesign.aspx b/web/admin/print/TabletDesign.aspx index 7209180..110d06d 100644 --- a/web/admin/print/TabletDesign.aspx +++ b/web/admin/print/TabletDesign.aspx @@ -1593,6 +1593,7 @@ html, body, * { //}) //return $namelist; },*/ + renderNameList(names, el) { let h = Number(el.height); let w = Number(el.width); @@ -1614,16 +1615,23 @@ html, body, * { names = names[0].split("暨"); names[0] = names[0] + "暨"; } - const init_fontSize = Number(d.fontSize) > 40 ? 40 : Number(d.fontSize); + const init_fontSize = Number(el.style.fontSize) > 40 ? 40 : Number(el.style.fontSize); + // 1. 初始判定與特例條件計算 let items = names.map(name => { let l = name.length; - let isShort = (l * init_fontSize) <= (th + (v_gap / 2)); + // 應該用初始最大值而不是40 + let isShort = (l * 40) <= (th + (v_gap / 2)); return { name: name, l: l, isShort: isShort, isMulti: false, size: 0 }; }); let maxShortLen = Math.max(...items.filter(x => x.isShort).map(x => x.l), 1); + let allShort = items.every(x => x.isShort); + console.log("全短名:", items, allShort); + + // 🚀 動態防呆:不寫死字數!用「實際字體大小」計算是否放得進半高。 + // 這樣 13 個字會自動出局,而 3 個字的小牌位絕對能穩穩過關。 let fitsInHalf = items.every(x => (x.l * short_s * 1.333) <= (h / 2)); let isSpecial1 = allShort && fitsInHalf && items.length === 1; @@ -1650,12 +1658,16 @@ html, body, * { if (item.isShort) { let item_h = Math.max(th, maxShortLen * size_px); + + // 壓縮高度釋放空間 (支援反向放大字體) if (isSpecial) { if (isSpecial1 || isSpecial2) item_h = h / 2; if (isSpecial4) item_h = (h / 2) - (v_gap / 2); } else { let natural_h = maxShortLen * size_px; - if (item_h > natural_h * 1.5) item_h = natural_h * 1.5; + if (item_h > natural_h * 1.5) { + item_h = natural_h * 1.5; + } } if (current_col_h === 0) { @@ -1675,10 +1687,13 @@ html, body, * { current_col_h = 0; current_col_w = 0; } + let item_w = size_px; + if ((item.l * size_px) > (h - 10)) { item.isMulti = true; any_wrapped = true; + let chars_per_col = Math.floor((h - 10) / size_px); if (chars_per_col < 1) chars_per_col = 1; let item_cols = Math.ceil(item.l / chars_per_col); @@ -1686,26 +1701,20 @@ html, body, * { } else { item.isMulti = false; } + cols_width.push(item_w); } } if (current_col_h > 0) cols_width.push(current_col_w); + totalWidth = cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0); if (totalWidth <= w && (!any_wrapped || long_s === shrinkLimit)) { sizes = items.map(x => { let final_s = x.size; if (x.isShort) { - //let max_s_for_th = Math.floor(th / (maxShortLen * 1.333)); - //if (final_s > max_s_for_th) final_s = max_s_for_th; - let available_h = th; - if (isSpecial) { - if (isSpecial1 || isSpecial2) available_h = h / 2; - if (isSpecial4) available_h = (h / 2) - v_gap - 2; - } - let max_s_for_th = Math.floor(available_h / (maxShortLen * 1.333)); - + let max_s_for_th = Math.floor(th / (maxShortLen * 1.333)); if (final_s > max_s_for_th) { final_s = max_s_for_th; } @@ -1717,6 +1726,7 @@ html, body, * { let hasLong = items.some(x => !x.isShort); let hasShort = items.some(x => x.isShort); + if (hasLong && hasShort) { if (shrink_turn === 'long') { if (long_s > shrinkLimit) { long_s--; shrink_turn = 'short'; } @@ -1737,13 +1747,18 @@ html, body, * { } if (sizes.length === 0) { - sizes = names.map(name => ({ name: name, size: shrinkLimit, isMulti: false, isShort: true })); + sizes = names.map(name => { + return { name: name, size: shrinkLimit, isMulti: false, isShort: true }; + }); } + // 3. 建立外層 Flexbox 容器 let flexDir = isSpecial2 ? "column" : "row"; let flexJustify = isSpecial ? "center" : "flex-start"; let flexAlign = "center"; - //if (isSpecial4) v_gap = Number(h) / 4; + if (isSpecial4) { + v_gap = Number(h) / 4; + } let $namelist = $(`
`).css({ "writing-mode": "vertical-rl", @@ -1759,39 +1774,52 @@ html, body, * { border: "0px solid transparent", padding: "1px", "column-gap": `${v_gap}px`, - "font-family": el.style.fontFamily + "font-family": el.style.fontFamily || el.fontFamily }); + // 4. 渲染單一名稱 sizes.forEach(item => { let size_px = item.size * 1.333; + + // 🚀 關鍵修正:統一使用 maxShortLen 算出標準高度,保證所有短名字的「格子」一模一樣大! let natural_max_h = maxShortLen * size_px; let boxH_num = item.isShort ? Math.max(th, natural_max_h) : h; if (isSpecial) { if (isSpecial1 || isSpecial2) boxH_num = h / 2; - if (isSpecial4) boxH_num = (h / 2) - v_gap - 2; + if (isSpecial4) boxH_num = (h / 2) - (v_gap) - 2; } else if (item.isShort) { - if (boxH_num > natural_max_h * 1.5) boxH_num = natural_max_h * 1.5; + // 壓縮高度釋放空間時,同樣以統一的標準高度來判定 + if (boxH_num > natural_max_h * 1.5) { + boxH_num = natural_max_h * 1.5; + } } let minH = `${boxH_num}px`; let alignStyle = item.isMulti || (!item.isMulti && !item.isShort) ? "start" : "justify"; + let spanDisplay = "block"; let spanJustifyContent = "flex-start"; - let spanMarginTop = "0px"; - if (isSpecial1 || isSpecial2) spanMarginTop = `-${h / 4}px`; + // 🚀 新增:只針對單一短名賦予 1/4 的 margin-top + let spanMarginTop = "0px"; + if (isSpecial1 || isSpecial2) { + spanMarginTop = `-${h / 4}px`; + } + if (isSpecial1 || isSpecial2 || isSpecial4) { alignStyle = "justify"; spanJustifyContent = "space-between"; } + // 這裡依然保留各自的真實字數,只用來計算「字距」,不影響格子大小 let nameLen = item.name.length; let contentH = nameLen * size_px; let emptySpace = boxH_num - contentH; let gapsCount = nameLen > 1 ? (nameLen - 1) : 1; let avgGap = emptySpace / gapsCount; + // 防過度拉扯 (排除特例,保護單名/雙名的正常分散) if (!isSpecial && alignStyle === "justify" && avgGap > (size_px * 1.5)) { alignStyle = "justify"; spanDisplay = "block"; @@ -1813,63 +1841,124 @@ html, body, * { "text-justify": "inter-character", "word-break": "break-all" }); + $namelist.append($span); }); + + return $namelist; + }, + renderLiveList(names, el) { + let h = parseFloat(el.height); + let w = parseFloat(el.width); + let th = parseFloat(el.textHeight) || h; + let v_gap = parseFloat(el.textSpan) || 0; + let h_gap = 5; + let shrinkLimit = 4; + if (Number(el.height) < 300) shrinkLimit = 8; + else if (Number(el.height) < 500) shrinkLimit = 6; + + let s = parseFloat(el.style.fontSize); + if (names.length == 2) h = th + v_gap; + + let maxLen = Math.max(...names.map(x => x.length), 1); + + while (s >= shrinkLimit) { + let size_px = s * 1.333; + let current_col_h = 0; + let current_col_w = 0; + let cols_width = []; + let any_wrapped = false; + + for (let i = 0; i < names.length; i++) { + let l = names[i].length; + let natural_max_h = maxLen * size_px; + let item_h = Math.max(th, natural_max_h); + if (item_h > natural_max_h * 1.5) item_h = natural_max_h * 1.5; + + if (item_h > (h - 5)) { + any_wrapped = true; + if (current_col_h > 0) { + cols_width.push(current_col_w); + current_col_h = 0; + current_col_w = 0; + } + let chars_per_col = Math.floor((h - 5) / size_px); + if (chars_per_col < 1) chars_per_col = 1; + let item_cols = Math.ceil(l / chars_per_col); + cols_width.push(item_cols * (size_px * 1.1)); + } else { + if (current_col_h === 0) { + current_col_h = item_h; + current_col_w = size_px; + } else if (current_col_h + v_gap + item_h <= h) { + current_col_h += v_gap + item_h; + if (size_px > current_col_w) current_col_w = size_px; + } else { + cols_width.push(current_col_w); + current_col_h = item_h; + current_col_w = size_px; + } + } + } + if (current_col_h > 0) cols_width.push(current_col_w); + let totalWidth = cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0); + if (totalWidth <= w && (!any_wrapped || s === shrinkLimit)) break; + s -= 1; + } + + if (s < shrinkLimit) s = shrinkLimit; + + let $namelist = $(`
`).css({ + "writing-mode": "vertical-rl", + "display": "flex", + "flex-flow": "wrap", + "align-content": "center", + "align-items": "center", + "margin": "auto", + "width": `${w}px`, + "height": `${h}px`, + "border": "0px solid transparent", + "padding": "0px", + "font-family": el.style.fontFamily, + "column-gap": `${v_gap}px` + }); + + let self = this; + names.forEach(name => { + $namelist.append(self.renderLiveSpan(name, el, s, maxLen)); + }); return $namelist; }, - renderNameSpan(item, el, colWidth) { - let th = Number(el.textHeight) || Number(el.height) - //let minH = item.isMulti ? `${d.height}px` : `${d.textHeight}px`; - let minH = item.isShort ? `${th}px` : `${el.height}px` - ; - let alignStyle = item.isMulti ? "start" : "justify"; + renderLiveSpan(name, el, fontSize, maxLen = 1) { + let h = parseFloat(el.height); + let th = parseFloat(el.textHeight) || h; + let size_px = fontSize * 1.333; - return $(`${item.name}`).css({ - display: "block", - "min-height": minH, // 強制多行長名撐滿高度,避免其他名字墊底 - "max-height": `${el.height}px`, - width: "auto", - "line-height": "1.1", - "text-align": alignStyle, - "text-align-last": alignStyle, - "margin-left": "5px", + let natural_max_h = maxLen * size_px; + let boxH_num = Math.max(th, natural_max_h); + + if (boxH_num > natural_max_h * 1.5) { + boxH_num = natural_max_h * 1.5; + } + + let minH = `${boxH_num}px`; + + return $(`${name}`).css({ + "display": "block", + "min-height": minH, + "max-height": `${h}px`, + "width": "auto", + "text-align": "justify", + "text-align-last": "justify", + "margin-left": "0px", + "margin-top": "0px", "text-justify": "inter-character", - "word-break": "break-all" + "word-break": "break-all", + "white-space": "pre-line" }); - //// 為「這個名字」獨立計算出專屬的最完美字體大小 - //let indSize = this.calcIndividualFontSize(name, el, colWidth); - //// 2. 判斷是否發生了折行 (名字長度 * 單字像素高度 > 分配到的最大高度) - //let s_px = indSize * 1.333; - //let isMultiLine = (name.length * s_px) > Number(el.textHeight); - - //// 3. 根據是否折行動態決定對齊方式 - //// 單行:分散對齊 (justify) / 多行:置中對齊 (center) 或是改為 靠上對齊 (start) - //let alignStyle = isMultiLine ? "start" : "justify"; - - //return $(`${name}`).css({ - // display: "block", - // "min-height": `${el.textHeight}px`, - // "max-height": `${el.height}px`, - // width: "auto", - // "line-height": "1.1", - // "text-align": alignStyle, // ★ 動態套用對齊方式 - // "text-align-last": alignStyle, // ★ 動態套用最後一行對齊方式 - // "margin-left": "5px", - // "text-justify": "inter-character", - // "word-break": "break-all" - //}); - //return $(`${name}`).css({ - // display: "block", - // "min-height": `${el.textHeight}px`, - // "max-height": `${el.height}px`, - // width: `${rowWidth}px`, - // "text-align": "justify", - // "text-align-last": "justify", - - // "margin-left": "5px", - // "text-justify": "inter-character", - //});// "margin-bottom": `${el.textSpan}px`, }, + + /* renderLiveList(names, el) { //console.log("renderLiveList:", names); //$("#imp-text").updateActive("text",names) @@ -1997,130 +2086,407 @@ html, body, * { // "text-justify": "inter-character", //});//"margin-bottom": `${el.textSpan}px`, },*/ - renderLiveList(names, el) { - let h = parseFloat(el.height); - let w = parseFloat(el.width); - let th = parseFloat(el.textHeight) || h; - let v_gap = parseFloat(el.textSpan) || 0; - let h_gap = 5; - let shrinkLimit = 4; - if (Number(el.height) < 300) shrinkLimit = 8; - else if (Number(el.height) < 500) shrinkLimit = 6; + //renderNameList(names, el) { + // let h = Number(el.height); + // let w = Number(el.width); + // let th = Number(el.textHeight) || h; + // let v_gap = Number(el.textSpan) || 0; + // let h_gap = 5; + // let shrinkLimit = 6; - let s = parseFloat(el.style.fontSize); - if (names.length == 2) h = th + v_gap; + // if (h < 500) { + // shrinkLimit = 8; + // } else if (h < 300) { + // shrinkLimit = 12; + // } - let maxLen = Math.max(...names.map(x => x.length), 1); + // let long_s = Number(el.style.fontSize); + // let short_s = Number(el.style.fontSize); - while (s >= shrinkLimit) { - let size_px = s * 1.333; - let current_col_h = 0; - let current_col_w = 0; - let cols_width = []; - let any_wrapped = false; + // if (h < 500 && names.length == 1 && names[0].includes("暨無始劫以來累世冤親債主")) { + // names = names[0].split("暨"); + // names[0] = names[0] + "暨"; + // } + // const init_fontSize = Number(el.fontSize) > 40 ? 40 : Number(el.fontSize); + // // 1. 初始判定與特例條件計算 + // let items = names.map(name => { + // let l = name.length; + // let isShort = (l * init_fontSize) <= (th + (v_gap / 2)); + // return { name: name, l: l, isShort: isShort, isMulti: false, size: 0 }; + // }); - for (let i = 0; i < names.length; i++) { - let l = names[i].length; - let natural_max_h = maxLen * size_px; - let item_h = Math.max(th, natural_max_h); - if (item_h > natural_max_h * 1.5) item_h = natural_max_h * 1.5; + // let maxShortLen = Math.max(...items.filter(x => x.isShort).map(x => x.l), 1); + // let allShort = items.every(x => x.isShort); + // let fitsInHalf = items.every(x => (x.l * short_s * 1.333) <= (h / 2)); - if (item_h > (h - 5)) { - any_wrapped = true; - if (current_col_h > 0) { - cols_width.push(current_col_w); - current_col_h = 0; - current_col_w = 0; - } - let chars_per_col = Math.floor((h - 5) / size_px); - if (chars_per_col < 1) chars_per_col = 1; - let item_cols = Math.ceil(l / chars_per_col); - cols_width.push(item_cols * (size_px * 1.1)); - } else { - if (current_col_h === 0) { - current_col_h = item_h; - current_col_w = size_px; - } else if (current_col_h + v_gap + item_h <= h) { - current_col_h += v_gap + item_h; - if (size_px > current_col_w) current_col_w = size_px; - } else { - cols_width.push(current_col_w); - current_col_h = item_h; - current_col_w = size_px; - } - } - } - if (current_col_h > 0) cols_width.push(current_col_w); - let totalWidth = cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0); - if (totalWidth <= w && (!any_wrapped || s === shrinkLimit)) break; - s -= 1; - } + // let isSpecial1 = allShort && fitsInHalf && items.length === 1; + // let isSpecial2 = allShort && fitsInHalf && items.length === 2; + // let isSpecial4 = allShort && fitsInHalf && (items.length === 4 || items.length === 6 || items.length === 8); + // let isSpecial = isSpecial1 || isSpecial2 || isSpecial4; - if (s < shrinkLimit) s = shrinkLimit; + // let sizes = []; + // let shrink_turn = 'long'; - let $namelist = $(`
`).css({ - "writing-mode": "vertical-rl", - "display": "flex", - "flex-flow": "wrap", - "align-content": "center", - "align-items": "center", - "margin": "auto", - "width": `${w}px`, - "height": `${h}px`, - "border": "0px solid transparent", - "padding": "0px", - "font-family": el.style.fontFamily, - "column-gap": `${v_gap}px` - }); + // // 2. 模擬排版與字體縮放運算 + // while (true) { + // let totalWidth = 0; + // let current_col_h = 0; + // let current_col_w = 0; + // let cols_width = []; + // let any_wrapped = false; - let self = this; - names.forEach(name => { - $namelist.append(self.renderLiveSpan(name, el, s, maxLen)); - }); - return $namelist; - }, - renderLiveSpan(name, el, fontSize, maxLen = 1) { - let h = parseFloat(el.height); - let th = parseFloat(el.textHeight) || h; - let size_px = fontSize * 1.333; - let l = name.length; + // for (let i = 0; i < items.length; i++) { + // let item = items[i]; + // let s = item.isShort ? short_s : long_s; + // item.size = s; + // let size_px = s * 1.333; - let natural_max_h = maxLen * size_px; - let boxH_num = Math.max(th, natural_max_h); - if (boxH_num > natural_max_h * 1.5) boxH_num = natural_max_h * 1.5; + // if (item.isShort) { + // let item_h = Math.max(th, maxShortLen * size_px); + // if (isSpecial) { + // if (isSpecial1 || isSpecial2) item_h = h / 2; + // if (isSpecial4) item_h = (h / 2) - (v_gap / 2); + // } else { + // let natural_h = maxShortLen * size_px; + // if (item_h > natural_h * 1.5) item_h = natural_h * 1.5; + // } - let minH = `${boxH_num}px`; - let alignStyle = "justify"; - let spanDisplay = "block"; - let spanJustifyContent = "flex-start"; + // if (current_col_h === 0) { + // current_col_h = item_h; + // current_col_w = size_px; + // } else if ((current_col_h + v_gap + item_h) <= h) { + // current_col_h += (v_gap + item_h); + // if (size_px > current_col_w) current_col_w = size_px; + // } else { + // cols_width.push(current_col_w); + // current_col_h = item_h; + // current_col_w = size_px; + // } + // } else { + // if (current_col_h > 0) { + // cols_width.push(current_col_w); + // current_col_h = 0; + // current_col_w = 0; + // } + // let item_w = size_px; + // if ((item.l * size_px) > (h - 10)) { + // item.isMulti = true; + // any_wrapped = true; + // let chars_per_col = Math.floor((h - 10) / size_px); + // if (chars_per_col < 1) chars_per_col = 1; + // let item_cols = Math.ceil(item.l / chars_per_col); + // item_w = item_cols * (size_px * 1.1); + // } else { + // item.isMulti = false; + // } + // cols_width.push(item_w); + // } + // } - let contentH = l * size_px; - let emptySpace = boxH_num - contentH; - let gapsCount = l > 1 ? (l - 1) : 1; - let avgGap = emptySpace / gapsCount; + // if (current_col_h > 0) cols_width.push(current_col_w); + // totalWidth = cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0); - if (alignStyle === "justify" && avgGap > (size_px * 1.5)) { - alignStyle = "justify"; - spanDisplay = "block"; - spanJustifyContent = "space-between"; - } + // if (totalWidth <= w && (!any_wrapped || long_s === shrinkLimit)) { + // sizes = items.map(x => { + // let final_s = x.size; + // if (x.isShort) { + // //let max_s_for_th = Math.floor(th / (maxShortLen * 1.333)); + // //if (final_s > max_s_for_th) final_s = max_s_for_th; + // let available_h = th; + // if (isSpecial) { + // if (isSpecial1 || isSpecial2) available_h = h / 2; + // if (isSpecial4) available_h = (h / 2) - v_gap - 2; + // } + // let max_s_for_th = Math.floor(available_h / (maxShortLen * 1.333)); - return $(`${name}`).css({ - "display": spanDisplay, - "justify-content": spanJustifyContent, - "align-items": "center", - "min-height": minH, - "max-height": `${h}px`, - "width": "auto", - "text-align": alignStyle, - "text-align-last": alignStyle, - "margin-left": "0px", - "margin-top": "0px", - "text-justify": "inter-character", - "word-break": "break-all", - "white-space": "pre-line" - }); - }, + // if (final_s > max_s_for_th) { + // final_s = max_s_for_th; + // } + // } + // return { name: x.name, size: final_s, isMulti: x.isMulti, isShort: x.isShort }; + // }); + // break; + // } + + // let hasLong = items.some(x => !x.isShort); + // let hasShort = items.some(x => x.isShort); + // if (hasLong && hasShort) { + // if (shrink_turn === 'long') { + // if (long_s > shrinkLimit) { long_s--; shrink_turn = 'short'; } + // else if (short_s > shrinkLimit) { short_s--; shrink_turn = 'long'; } + // else break; + // } else { + // if (short_s > shrinkLimit) { short_s--; shrink_turn = 'long'; } + // else if (long_s > shrinkLimit) { long_s--; shrink_turn = 'short'; } + // else break; + // } + // } else if (hasLong) { + // if (long_s > shrinkLimit) long_s--; + // else break; + // } else { + // if (short_s > shrinkLimit) short_s--; + // else break; + // } + // } + + // if (sizes.length === 0) { + // sizes = names.map(name => ({ name: name, size: shrinkLimit, isMulti: false, isShort: true })); + // } + + // let flexDir = isSpecial2 ? "column" : "row"; + // let flexJustify = isSpecial ? "center" : "flex-start"; + // let flexAlign = "center"; + // //if (isSpecial4) v_gap = Number(h) / 4; + + // let $namelist = $(`
`).css({ + // "writing-mode": "vertical-rl", + // display: "flex", + // "flex-direction": flexDir, + // "flex-wrap": "wrap", + // "align-content": "center", + // "align-items": flexAlign, + // "justify-content": flexJustify, + // margin: "auto", + // width: `${w}px`, + // height: `${h}px`, + // border: "0px solid transparent", + // padding: "1px", + // "column-gap": `${v_gap}px`, + // "font-family": el.style.fontFamily + // }); + + // sizes.forEach(item => { + // let size_px = item.size * 1.333; + // let natural_max_h = maxShortLen * size_px; + // let boxH_num = item.isShort ? Math.max(th, natural_max_h) : h; + + // if (isSpecial) { + // if (isSpecial1 || isSpecial2) boxH_num = h / 2; + // if (isSpecial4) boxH_num = (h / 2) - v_gap - 2; + // } else if (item.isShort) { + // if (boxH_num > natural_max_h * 1.5) boxH_num = natural_max_h * 1.5; + // } + + // let minH = `${boxH_num}px`; + // let alignStyle = item.isMulti || (!item.isMulti && !item.isShort) ? "start" : "justify"; + // let spanDisplay = "block"; + // let spanJustifyContent = "flex-start"; + // let spanMarginTop = "0px"; + + // if (isSpecial1 || isSpecial2) spanMarginTop = `-${h / 4}px`; + // if (isSpecial1 || isSpecial2 || isSpecial4) { + // alignStyle = "justify"; + // spanJustifyContent = "space-between"; + // } + + // let nameLen = item.name.length; + // let contentH = nameLen * size_px; + // let emptySpace = boxH_num - contentH; + // let gapsCount = nameLen > 1 ? (nameLen - 1) : 1; + // let avgGap = emptySpace / gapsCount; + + // if (!isSpecial && alignStyle === "justify" && avgGap > (size_px * 1.5)) { + // alignStyle = "justify"; + // spanDisplay = "block"; + // spanJustifyContent = "start"; + // } + + // let $span = $(`${item.name}`).css({ + // "display": spanDisplay, + // "justify-content": spanJustifyContent, + // "align-items": "center", + // "min-height": minH, + // "max-height": `${h}px`, + // "width": "auto", + // "line-height": "1.1", + // "text-align": alignStyle, + // "text-align-last": alignStyle, + // "margin-left": "5px", + // "margin-top": spanMarginTop, + // "text-justify": "inter-character", + // "word-break": "break-all" + // }); + // $namelist.append($span); + // }); + // return $namelist; + //}, + //renderNameSpan(item, el, colWidth) { + // let th = Number(el.textHeight) || Number(el.height) + // //let minH = item.isMulti ? `${d.height}px` : `${d.textHeight}px`; + // let minH = item.isShort ? `${th}px` : `${el.height}px` + // ; + // let alignStyle = item.isMulti ? "start" : "justify"; + + // return $(`${item.name}`).css({ + // display: "block", + // "min-height": minH, // 強制多行長名撐滿高度,避免其他名字墊底 + // "max-height": `${el.height}px`, + // width: "auto", + // "line-height": "1.1", + // "text-align": alignStyle, + // "text-align-last": alignStyle, + // "margin-left": "5px", + // "text-justify": "inter-character", + // "word-break": "break-all" + // }); + // //// 為「這個名字」獨立計算出專屬的最完美字體大小 + // //let indSize = this.calcIndividualFontSize(name, el, colWidth); + // //// 2. 判斷是否發生了折行 (名字長度 * 單字像素高度 > 分配到的最大高度) + // //let s_px = indSize * 1.333; + // //let isMultiLine = (name.length * s_px) > Number(el.textHeight); + + // //// 3. 根據是否折行動態決定對齊方式 + // //// 單行:分散對齊 (justify) / 多行:置中對齊 (center) 或是改為 靠上對齊 (start) + // //let alignStyle = isMultiLine ? "start" : "justify"; + + // //return $(`${name}`).css({ + // // display: "block", + // // "min-height": `${el.textHeight}px`, + // // "max-height": `${el.height}px`, + // // width: "auto", + // // "line-height": "1.1", + // // "text-align": alignStyle, // ★ 動態套用對齊方式 + // // "text-align-last": alignStyle, // ★ 動態套用最後一行對齊方式 + // // "margin-left": "5px", + // // "text-justify": "inter-character", + // // "word-break": "break-all" + // //}); + // //return $(`${name}`).css({ + // // display: "block", + // // "min-height": `${el.textHeight}px`, + // // "max-height": `${el.height}px`, + // // width: `${rowWidth}px`, + // // "text-align": "justify", + // // "text-align-last": "justify", + + // // "margin-left": "5px", + // // "text-justify": "inter-character", + // //});// "margin-bottom": `${el.textSpan}px`, + //}, + //renderLiveList(names, el) { + // let h = parseFloat(el.height); + // let w = parseFloat(el.width); + // let th = parseFloat(el.textHeight) || h; + // let v_gap = parseFloat(el.textSpan) || 0; + // let h_gap = 5; + // let shrinkLimit = 4; + // if (Number(el.height) < 300) shrinkLimit = 8; + // else if (Number(el.height) < 500) shrinkLimit = 6; + + // let s = parseFloat(el.style.fontSize); + // if (names.length == 2) h = th + v_gap; + + // let maxLen = Math.max(...names.map(x => x.length), 1); + + // while (s >= shrinkLimit) { + // let size_px = s * 1.333; + // let current_col_h = 0; + // let current_col_w = 0; + // let cols_width = []; + // let any_wrapped = false; + + // for (let i = 0; i < names.length; i++) { + // let l = names[i].length; + // let natural_max_h = maxLen * size_px; + // let item_h = Math.max(th, natural_max_h); + // if (item_h > natural_max_h * 1.5) item_h = natural_max_h * 1.5; + + // if (item_h > (h - 5)) { + // any_wrapped = true; + // if (current_col_h > 0) { + // cols_width.push(current_col_w); + // current_col_h = 0; + // current_col_w = 0; + // } + // let chars_per_col = Math.floor((h - 5) / size_px); + // if (chars_per_col < 1) chars_per_col = 1; + // let item_cols = Math.ceil(l / chars_per_col); + // cols_width.push(item_cols * (size_px * 1.1)); + // } else { + // if (current_col_h === 0) { + // current_col_h = item_h; + // current_col_w = size_px; + // } else if (current_col_h + v_gap + item_h <= h) { + // current_col_h += v_gap + item_h; + // if (size_px > current_col_w) current_col_w = size_px; + // } else { + // cols_width.push(current_col_w); + // current_col_h = item_h; + // current_col_w = size_px; + // } + // } + // } + // if (current_col_h > 0) cols_width.push(current_col_w); + // let totalWidth = cols_width.reduce((a, b) => a + b, 0) + (cols_width.length > 1 ? (cols_width.length - 1) * h_gap : 0); + // if (totalWidth <= w && (!any_wrapped || s === shrinkLimit)) break; + // s -= 1; + // } + + // if (s < shrinkLimit) s = shrinkLimit; + + // let $namelist = $(`
`).css({ + // "writing-mode": "vertical-rl", + // "display": "flex", + // "flex-flow": "wrap", + // "align-content": "center", + // "align-items": "center", + // "margin": "auto", + // "width": `${w}px`, + // "height": `${h}px`, + // "border": "0px solid transparent", + // "padding": "0px", + // "font-family": el.style.fontFamily, + // "column-gap": `${v_gap}px` + // }); + + // let self = this; + // names.forEach(name => { + // $namelist.append(self.renderLiveSpan(name, el, s, maxLen)); + // }); + // return $namelist; + //}, + //renderLiveSpan(name, el, fontSize, maxLen = 1) { + // let h = parseFloat(el.height); + // let th = parseFloat(el.textHeight) || h; + // let size_px = fontSize * 1.333; + // let l = name.length; + + // let natural_max_h = maxLen * size_px; + // let boxH_num = Math.max(th, natural_max_h); + // if (boxH_num > natural_max_h * 1.5) boxH_num = natural_max_h * 1.5; + + // let minH = `${boxH_num}px`; + // let alignStyle = "justify"; + // let spanDisplay = "block"; + // let spanJustifyContent = "flex-start"; + + // let contentH = l * size_px; + // let emptySpace = boxH_num - contentH; + // let gapsCount = l > 1 ? (l - 1) : 1; + // let avgGap = emptySpace / gapsCount; + + // if (alignStyle === "justify" && avgGap > (size_px * 1.5)) { + // alignStyle = "justify"; + // spanDisplay = "block"; + // spanJustifyContent = "space-between"; + // } + + // return $(`${name}`).css({ + // "display": spanDisplay, + // "justify-content": spanJustifyContent, + // "align-items": "center", + // "min-height": minH, + // "max-height": `${h}px`, + // "width": "auto", + // "text-align": alignStyle, + // "text-align-last": alignStyle, + // "margin-left": "0px", + // "margin-top": "0px", + // "text-justify": "inter-character", + // "word-break": "break-all", + // "white-space": "pre-line" + // }); + //}, // 品字佈局邏輯:一上二下 renderRoster(names, el, rowWidth) { diff --git a/web/admin/print/tablet_edit/editorNewOne.html b/web/admin/print/tablet_edit/editorNewOne.html index 4c766c8..1fac470 100644 --- a/web/admin/print/tablet_edit/editorNewOne.html +++ b/web/admin/print/tablet_edit/editorNewOne.html @@ -55,6 +55,7 @@
+
@@ -159,6 +160,33 @@
+ + + +