ตารางรายการและหน้าต่างค้นหา
จอบัญชีใช้ 3 ชิ้นส่วนร่วมกันทุกจอ: SmlDataList (ตารางรายการด้านซ้าย/ล่างของจอหลัก), SmlLookupInput (ช่องกรอกรหัส + ชื่อ) และ SmlLookupModal (หน้าต่างค้นหาเลือกรหัส)
ทั้งสามใช้ queryList/queryLimit ประกอบ SQL ที่เบราว์เซอร์ (ตัวเรียก API และตัวประกอบ SQL ฝั่งเบราว์เซอร์ (api-client, query-client, sml-query-builder)) และรับสิทธิ์จอจาก พื้นที่ทำงานแบบแท็บ MDI และสิทธิ์จอ (TabWorkspace)
ทำงานอย่างไร
SmlDataList (SmlDataList.tsx, 1,370 บรรทัด)
- props หลัก:
rows, loading, selectedId, idKey, columns, listKey, tableName, defaultSql, ตัวจัดการonSelect/onNew/onEdit/onEditRow/onRowDoubleClick/onCopy, ช่องค้นหาkeyword/onKeywordChange/onSearch/onRefresh,auto/onAutoChange(ค้นอัตโนมัติ),onClose,hotkeysActive,strictCommands. - โหลดทีละ 30 แถวแล้วเลื่อนลงเพื่อโหลดเพิ่ม:
INITIAL_BATCH_SIZE=30,LOAD_MORE_STEP=30(บรรทัด 61-62) ใช้IntersectionObserver(~470). - สิทธิ์: อ่าน
rightsจากtabsCtx.screenRights(140-141) ถ้าไม่มีสิทธิ์เพิ่ม/แก้ไข จะไม่ส่ง handler ปุ่ม ใหม่/คัดลอก/แก้ไข ต่อ. - คีย์เก็บค่าตั้งของผู้ใช้
effectiveListKey=listKey||tabsCtx.screenKey||activeKey|| ลายเซ็นdatalist_...จากคอลัมน์ (150-156). - ค้นหาในหน้าจอ (
processedRows, ~306): ตัดคำsegmentSearchTokens, จับคู่matchSegmentedAndLike(ทุกคำ) ถ้าไม่เจอจึงจับคู่บางส่วน + ให้คะแนนscoreSearchMatch; กรองขั้นสูงAdvancedFilterModal(รหัสจาก-ถึง, ชื่อ 1, ชื่อ 2); แล้วเรียงตามหัวคอลัมน์. - คีย์ลัด (เมื่อ
hotkeysActiveและแท็บมองเห็น):Ctrl+Fโฟกัสช่องค้นหา (577),Insert/Alt+Nเพิ่มใหม่ (585), ลูกศร/Home/End/PageUp/PageDownเลื่อนแถว (601-626).SmlShortcutsModal(105 บรรทัด) แสดงรายการคีย์ลัดทั้งหมด รวมCtrl+SและEscapeที่จอแม่ใช้ (จอข้อมูลหลักมาตรฐานและจอ master-detail (StandardMasterScreen / MasterDetailScreen)).
ปรับแต่งคอลัมน์ต่อผู้ใช้ (SmlDataListCustomizeModal.tsx, 1,401 บรรทัด)
- สองแท็บ: "columns" (เลือก/เรียง/ตั้งความกว้างคอลัมน์) และ "sql" (394). ชื่อไทยของฟิลด์อยู่ที่
FIELD_THAI_LABELS(77), ชุดคอลัมน์สินค้าสำเร็จรูปITEM_DATALIST_PRESETS(162), รูปแบบเซลล์formatDataListCellValue(227). - เก็บค่าที่ DB ต่อผู้ใช้ผ่าน
POST /api/process/master/datalistget(loadUserDataListConfigFromDb, 326) และ.../datalistsave(saveUserDataListConfigToDb, 352) และสำรองที่localStorageด้วยคีย์จากgetUserDataListStorageKey(295). - โหมด
useCustomSql(398): ผู้ใช้เขียน SQL เองแทนdefaultSql;SmlDataListรันผ่านqueryLimit(sqlClean, 500, 0, true)(~217) แล้วใช้ผลเป็นcustomSqlRows(268). (ยังไม่ยืนยัน: backend จำกัดให้เป็น SELECT อย่างเดียวหรือไม่)
SmlLookupInput (SmlLookupInput.tsx, 174 บรรทัด) - ช่องกรอกรหัส
- props:
value, nameValue, onChange, table, title, whereClause, onOpenLookup, uppercase, notFoundLabel. - เมื่อออกจากช่อง (
onBlur, บรรทัด 126)fetchName(51) ดึงชื่อด้วยqueryListจากตารางที่แปลงชื่อเล่นแล้ว;whereClauseที่มี;หรือ--ถูกปฏิเสธ; ถ้าไม่พบรหัสจะเปิดSmlDialogเตือน (เนื้อหาเรียกnotFoundLabel).
SmlLookupModal (SmlLookupModal.tsx, 1,090 บรรทัด) - หน้าต่างค้นหา
- props (129+):
open, title, tableName|table, whereClause, orderBy="code", items(ส่ง rows เองแทนค้น DB),columns,pageSize=50,initialValue,onSelect,onPickWithLocation(row, whCode, shelfCode, withUnit)(145),itemSearchTools(147),onClose. - ลำดับหาตาราง:
resolveLookupTable(name)แปลงชื่อเล่นเป็นตารางจริงผ่านLOOKUP_TABLE_MAP(lookup-tables.ts:4; ตัวอย่างwarehouse->ic_warehouse,gl_account->gl_chart_of_account,staff->erp_user,item->ic_inventory,customer->ar_customer); ไม่ผ่านแผนที่ใช้ชื่อเดิม. - กันฉีด SQL ฝั่งหน้าจอ: ชื่อตารางต้องผ่าน
SAFE_IDENT_RE(43) และอยู่ในALLOWED_LOOKUP_TABLES(44, สร้างจากLOOKUP_TABLE_MAP+ รายชื่อตารางที่อนุญาต) ไม่งั้นแสดงตารางว่าง;whereClauseที่มี;หรือ--ก็ถูกตัดทิ้งเป็นว่าง (ไม่ใช่ข้ามตัวกรอง) - เช็กที่ 238-244. - คอลัมน์: ถ้าผู้เรียกไม่ส่ง
columnsใช้LOOKUP_SCREEN_COLUMNS[ตาราง](lookup-tables.ts:100, ถอดจากsmlerpviewtemplate.xmlของ SMLERP เดิมสำหรับจอสินค้า/ลูกหนี้/เจ้าหนี้) หรือค่าเริ่ม รหัส / ชื่อ / ชื่อ (ภาษาอังกฤษ) (150-156);LookupScreenColumnมีexpr(นิพจน์ SQL),search,numKind: "qty"|"amount"(81). ตารางในNO_NAME2_TABLES(ic_dimension_name,ar_dealer, บรรทัด 110) ไม่ selectname_2. - ค้นหา: หน่วงเวลาเล็กน้อยแล้ว
queryLimit(sql, pageSize, (หน้า-1)*pageSize, true)เรียง "รหัสตรงเป๊ะ -> ขึ้นต้นด้วยคำค้น -> อื่นๆ" ตามด้วยคอลัมน์ที่เรียง; ใช้buildSmlSearchWhere(kw, searchFields, strict=true)(ทุกคำต้องตรง) ถ้าไม่เจอเลยจึงลองแบบหลวม (N-1 คำ) และตั้งธงpartialServer->isPartialFallback(บรรทัด 362) เพื่อบอกว่าเป็นผลแบบใกล้เคียง (รูปแบบข้อความที่แสดง ยังไม่ยืนยัน). - คีย์ในหน้าต่าง: ลูกศร ขึ้น/ลง เลือกแถว,
Enterเลือก,PageUp/PageDownเปลี่ยนหน้า (495-511); ถ้าEnterตอนผลยังไม่มา จะจำไว้ใช้เมื่อโหลดเสร็จ (enterWhilePendingRef). - โหมดค้นสินค้า (เมื่อตาราง
ic_inventoryและitemSearchTools): ช่องยิงบาร์โค้ดแปลงเป็นic_codeด้วย SQL ตารางic_inventory_barcode(~450), ดูยอดคงเหลือด้วยStockBalanceModal, เลือกพร้อมคลัง/ที่เก็บ/หน่วยผ่านonPickWithLocation.
ตัวกรองตามชนิดเอกสาร (src/lib/lookup-filters.ts, ส่งเป็น whereClause)
itemLookupWhere(transFlag, refDocNo, refTransFlag)(32): ตัดสินค้าitem_type=5ออก (ยกเว้นชุด flag ในNO_ITEM_TYPE_FILTER), ถ้าเป็นเอกสารที่ดึงจากอ้างอิง (REF_LIMITED_ITEMS) ให้เห็นเฉพาะสินค้าในเอกสารต้นทาง (ic_trans_detail), ซ่อนสินค้าหยุดซื้อ (is_hold_purchase) ในเอกสารซื้อ และเลิกขาย (is_hold_sale) ในเอกสารขาย.saleLookupWhere(transFlag)(48): พนักงานขายของเอกสารสั่งจอง/สั่งขาย/ขาย ต้องis_login_user=0.shelfLookupWhere(whCode)(57): เฉพาะที่เก็บของคลังที่เลือก (whcode=...).- ไฟล์นี้อ้างตรรกะจาก C# SMLERP เดิมในคอมเมนต์ (ไม่ import อะไรเพื่อให้
node --testรันได้).
ข้อควรระวัง
- ตารางใหม่ที่จะใช้กับ lookup ต้องเพิ่มชื่อในแผนที่/รายการ
ALLOWED_LOOKUP_TABLESไม่งั้นหน้าต่างจะว่างโดยไม่มีข้อความผิดพลาด. whereClauseที่ประกอบจากค่าผู้ใช้ต้องescapeSqlก่อน (ดูquoteในlookup-filters.ts:11).- การจำกัดคอลัมน์ของ
SmlLookupModalใช้ชื่อฟิลด์เป็นตัวระบุ SQL จึงต้องผ่านSAFE_IDENT_RE(คอลัมน์ที่ใช้exprต้องเป็นค่าคงที่ในโค้ด ไม่ใช่ค่าจากผู้ใช้).
ที่มาในโค้ด
frontend/account/master/SmlDataList.tsx:61-62,140-156,191-268,306,470,577-626- โหลดทีละชุด, สิทธิ์, คีย์ตั้งค่า, ค้นหา, คีย์ลัดfrontend/account/master/SmlDataListCustomizeModal.tsx:77,162,227,295,326,352,394,398- ปรับแต่งคอลัมน์/SQL ต่อผู้ใช้frontend/account/master/SmlLookupInput.tsx:1-174- ช่องรหัส + ชื่อfrontend/account/master/SmlLookupModal.tsx:43-44,110,129-147,242,450,495-511- ตารางที่อนุญาต, props, ค้นหา, คีย์frontend/src/lib/lookup-tables.ts:4,74,81,100,141- แผนที่ชื่อเล่นตาราง, คอลัมน์ต่อจอfrontend/src/lib/lookup-filters.ts:32,48,57- ตัวกรอง lookup ตามชนิดเอกสาร
ดูเพิ่ม
ภาพรวม Frontend ของ SML Ai Account (Frontend overview) · จอข้อมูลหลักมาตรฐานและจอ master-detail (StandardMasterScreen / MasterDetailScreen) · ตัวเรียก API และตัวประกอบ SQL ฝั่งเบราว์เซอร์ (api-client, query-client, sml-query-builder) · พื้นที่ทำงานแบบแท็บ MDI และสิทธิ์จอ (TabWorkspace) · จอเอกสารธุรกรรมแบบเดียวกันทุกจอ (UniversalTransScreen) · เครื่องฟอร์มแบบ schema (SchemaForm, FieldDef, useRecordForm) และจอตั้งค่าระบบ