Skip to main content

Dashboard

ภาพรวม​

Dashboard คือหน้าแรกที่ผู้ดูแล LINE OA เห็นทันทีหลังเลือก channel ที่จะเข้าทำงาน ใช้เป็นจุดเช็กสถานะภาพรวมของเพื่อนใน OA นั้น (จำนวนรวม, สัดส่วนที่ยัง active, สัดส่วนที่ถูกบล็อก) พร้อมดูแนวโน้มย้อนหลัง 7 วัน และรายการแคมเปญที่ตั้งเวลาไว้ล่วงหน้า ก่อนตัดสินใจว่าจะทำอะไรต่อในเมนูอื่น

บทบาทที่ใช้งาน — ทุกคนที่ผ่านการตรวจสิทธิ์ดูข้อมูลแดชบอร์ดฝั่งหน้าเว็บ (ดูรายละเอียดจริงของสิทธิ์นี้ในหัวข้อ สิทธิ์การเข้าถึง ด้านล่าง — ในทางปฏิบัติหมายถึงผู้ใช้ทุกคนที่ล็อกอินและเลือก LINE OA แล้ว)

หน้า Dashboard เต็มหน้าจอ แสดงเมนูซ้ายและองค์ประกอบทั้งหมด

เส้นทางผู้ใช้งาน​

1. เปิดเมนู Dashboard​

เลือก LINE OA ที่ต้องการทำงานจากมุมขวาบน (ป้าย "F Test" ในภาพ) ระบบจะพาเข้าหน้า Dashboard ให้โดยอัตโนมัติ หรือคลิกเมนู Dashboard ที่อยู่บนสุดของเมนูซ้ายได้ทุกเมื่อ

2. ดูการ์ดสรุป 3 ใบด้านบน​

การ์ด Total Friends, Active Friends, Blocked Users

  • Total Friends — ตัวเลขใหญ่แสดงจำนวนเพื่อนสะสมทั้งหมดของ OA ณ ปัจจุบัน พร้อมคำอธิบาย "All registered friends on LINE OA"
  • Active Friends — กราฟวงแหวนแบ่งสัดส่วนผู้เยี่ยมชม (Guest) กับสมาชิก (Member) ที่ ยังไม่ถูกบล็อก ในแต่ละกลุ่ม
  • Blocked Users — กราฟวงแหวนแบบเดียวกัน แต่แสดงเฉพาะผู้ที่ถูกบล็อกแล้ว แยกเป็นผู้เยี่ยมชมกับสมาชิก (ถ้าไม่มีข้อมูลทั้งสองกลุ่มจะขึ้นวงแหวนสีเทาพร้อมคำว่า "No data")

3. ดูกล่อง "Last 7 Days Activity"​

กล่อง Last 7 Days Activity แยก Guests กับ Members

กล่อง Guests (พื้นสีฟ้าอ่อน) และกล่อง Members (พื้นสีม่วงอ่อน) แต่ละกล่องมีตัวเลข Active และ Blocked ของ 7 วันล่าสุด ตัวเลขจะเป็นสีเขียวพร้อมเครื่องหมาย + เมื่อเป็นค่าบวก และเป็นสีแดงเมื่อเป็นค่าลบ — ดูคำอธิบายเชิงลึกของตัวเลขคู่นี้ในหัวข้อ รายละเอียดการคำนวณตัวเลข เพราะมีจุดที่เข้าใจผิดได้ง่าย

4. ดูการ์ด "Upcoming Activities"​

การ์ด Upcoming Activities ในสถานะไม่มีแคมเปญ พร้อมปุ่ม Create Campaign

  • การ์ดนี้ดึงรายการแคมเปญที่มีสถานะ ตั้งเวลาไว้ (Scheduled) ในช่วงตั้งแต่วันนี้ถึงอีก 7 วันข้างหน้า สูงสุด 10 รายการ เรียงจากวันที่ใกล้ที่สุดก่อน
  • แต่ละรายการแสดงวันที่ ชื่อแคมเปญ เวลาที่จะส่ง (พร้อมคำกำกับ "Today" / "Tomorrow" หรือวันที่จริง) และป้ายสถานะ คลิกที่รายการเพื่อเปิดฟอร์มแคมเปญนั้นในเมนู Campaign ทันที
  • กดปุ่ม View All เพื่อไปดูภาพรวมทั้งหมดที่เมนู Campaign Planner
  • ถ้าไม่มีแคมเปญตั้งเวลาไว้เลย (ตามภาพ) จะขึ้นสถานะว่างพร้อมปุ่ม Create Campaign พาไปที่หน้ารายการของเมนู Campaign เพื่อสร้างแคมเปญใหม่

5. ดูกราฟ "Friends Growth Trend"​

กราฟเส้น Friends Growth Trend 7 วันล่าสุด

กราฟเส้นแสดง 3 เส้น (Total Friends, Members, Guests) ของ 7 วันล่าสุด — ตัวเลขต้นสัปดาห์และท้ายสัปดาห์เป็นข้อมูลจริง แต่จุดระหว่างกลางเป็นการคำนวณเส้นตรงเฉลี่ยขึ้นมาเอง ไม่ใช่ยอดจริงของแต่ละวัน เพราะฝั่งเซิร์ฟเวอร์ยังไม่มี endpoint ที่คืนยอดรายวันให้ (ดูยืนยันในหัวข้อจุดที่ควรระวังด้านล่าง)

6. ดูกราฟ "Activity Overview"​

กราฟแท่ง Activity Overview เปรียบเทียบเพื่อนใหม่กับผู้ถูกบล็อก

กราฟแท่งเปรียบเทียบ "เพื่อนใหม่" กับ "ผู้ถูกบล็อก" รายวันของ 7 วันล่าสุด (ในภาพยังไม่มีข้อมูลเพราะยอดรวมทั้งสัปดาห์เป็น 0) — เช่นเดียวกับกราฟเส้นด้านบน ตัวเลขรายวันในกราฟนี้เป็นค่าที่สุ่มกระจายขึ้นใหม่ทุกครั้งที่วาดหน้าจอใหม่ โดยคงผลรวมทั้งสัปดาห์ให้ตรงกับข้อมูลจริงเท่านั้น

รายละเอียดการคำนวณตัวเลข (ตรวจสอบจากซอร์สโค้ดจริง)​

ยืนยันจากโมดูล internal/modules/dashboard/service.go ของ line-management-cms-api-go — ทุกยอดนับใช้เงื่อนไขฐานร่วมกัน 3 ข้อกับตาราง line_user คือ (1) line_oa_id ตรงกับ OA ที่กำลังทำงานอยู่ (2) created_date ไม่เกินวันที่ที่ต้องการดู (3) user_id IS NOT NULL (ต้องผูกกับผู้ใช้ LINE จริงแล้ว) และไม่รวมแถวที่ลบแบบ soft delete โดยอัตโนมัติ

จุดที่ควรรู้เพื่ออ่านตัวเลขให้ถูก:

  • member และ guest ที่ API ส่งกลับมา คือยอดสะสมทั้งหมดของแต่ละกลุ่ม (รวมทั้งที่ยัง active และที่ถูกบล็อกไปแล้ว) ไม่ใช่ยอด active เพียว ๆ — การ์ด Active Friends ที่หน้าเว็บหักยอดบล็อกออกให้เห็นเฉพาะ active จริง (member - totalBlockedMembers, guest - totalBlockedGuests) ส่วนตัวเลขดิบจาก API ยังคงรวมทั้งสองกลุ่มไว้ด้วยกัน
  • blockGuest/blockMember เป็นคนละตัวชี้วัดกับ totalBlockedGuests/totalBlockedMembers — สองตัวหลังนับจากสถานะ follow ปัจจุบัน (follow = No) ณ วันนั้น ส่วน blockGuest/blockMember นับจากคนที่มี unfollow_date อยู่ในหรือก่อนวันนั้น เป็นตัวที่การ์ด "Last 7 Days Activity" ใช้แสดงคอลัมน์ Blocked
  • ตัวเลข "Active" ในกล่อง Last 7 Days Activity ไม่ได้หักยอดบล็อกออก — เป็นเพียงส่วนต่าง (valueDiff = ยอดปลายช่วง − ยอดต้นช่วง) ของ member หรือ guest แบบดิบที่รวมทั้งสองกลุ่มไว้ด้วยกันตามข้อด้านบน จึงเป็นคนละความหมายกับตัวเลข active ในการ์ด Active Friends ที่อยู่แถวบนสุด — ห้ามนำตัวเลขทั้งสองส่วนมาเทียบกันตรง ๆ
  • percentDiff คำนวณจาก (ยอดปลายช่วง − ยอดต้นช่วง) / (ยอดปลายช่วง หรือ 1 ถ้าเป็น 0) × 100 แต่ปัจจุบันหน้าเว็บยังไม่ได้นำค่านี้มาแสดงผลที่ใดเลย

เมนูที่เกี่ยวข้องกันในเส้นทางนี้​

  • Campaign — แหล่งข้อมูลของการ์ด "Upcoming Activities" และปลายทางของปุ่ม Create Campaign / การคลิกรายการแคมเปญ
  • Campaign Planner — ปลายทางของปุ่ม View All มุมมองปฏิทินของแคมเปญชุดเดียวกัน

จุดที่ควรระวัง​

  • กราฟเส้น (Friends Growth Trend) และกราฟแท่ง (Activity Overview) ไม่ใช่ข้อมูลรายวันจริง โค้ดฝั่งหน้าเว็บมีคอมเมนต์ระบุตรงว่า "Note: Replace this with actual daily data when backend supports it" — กราฟเส้นใช้การประมาณค่าเชิงเส้น (linear interpolation) ระหว่างยอดต้นสัปดาห์กับปลายสัปดาห์ ส่วนกราฟแท่งสุ่มกระจายผลต่างรายสัปดาห์ลงในแต่ละวันใหม่ทุกครั้งที่วาดหน้าจอ (ตัวเลขรายวันจึงเปลี่ยนไปเรื่อย ๆ แม้ข้อมูลจริงไม่เปลี่ยน) มีเพียงยอดรวมทั้งสัปดาห์เท่านั้นที่ตรงกับข้อมูลจริง
  • ตัวกรองช่วงวันที่มีอยู่ในโค้ดแต่ยังไม่เปิดให้ใช้จริง — หน้า Dashboard เตรียม state และฟังก์ชัน onChangeDate ไว้ในไฟล์ dashboard.tsx แล้ว แต่ยังไม่มี date-range picker ใด ๆ วางอยู่บนหน้าจอให้ผู้ใช้กด ในทางปฏิบัติหน้านี้จึงล็อกช่วงเวลาไว้ที่ 7 วันล่าสุดเสมอ
  • มีฟีเจอร์ "Top Rich Menu" หลงเหลืออยู่ในซอร์สโค้ดแต่ไม่ได้แสดงผลจริง — พบไฟล์ TopRichMenu.tsx, dashboard-top-list.container.tsx และฟังก์ชัน getTopRichMenu() (เรียก /dashboard/top-rich-menu) อยู่ในโค้ดฝั่งหน้าเว็บ แต่ไม่ถูก import ไปใช้ในหน้า Dashboard จริงเลย และฝั่ง backend ก็ไม่ได้ลงทะเบียน route นี้ไว้ด้วยซ้ำ — คอมเมนต์ในซอร์ส backend ยืนยันว่า endpoint นี้ "ถูกปิดไว้ตั้งแต่ระบบเดิม" (disabled in TS) จึงเป็นโค้ดที่หลงเหลือ ไม่มีผลต่อผู้ใช้งานจริงในหน้าจอปัจจุบัน
  • หากตัวเลขเพื่อนดูไม่ตรงกับความเป็นจริง ต้นเหตุมักอยู่ที่ระบบซิงก์ผู้ติดตามหรือ webhook ที่อัปเดตตาราง line_user ไม่ใช่ที่หน้า Dashboard เอง เพราะหน้านี้เป็นเพียงตัวนับข้อมูลที่มีอยู่ ณ ขณะนั้น

สิทธิ์การเข้าถึง (ตรวจสอบจากซอร์สโค้ดจริง)​

  • ฝั่งหน้าเว็บ — หน้า Dashboard ถูกครอบด้วย PermissionGuard ตรวจ action VIEW ของ subject dashboard (ไฟล์ src/app/dashboard/page.tsx) ก่อน render เนื้อหา ถ้าไม่ผ่านจะไม่เห็นทั้งเมนูและหน้านี้
  • ฝั่งเซิร์ฟเวอร์ — มี endpoint จริงเพียงตัวเดียวคือ GET /api/dashboard/total-friends ต้องผ่าน JWT กลางที่บังคับกับทุกเส้นทางที่ไม่ประกาศเป็น public และมี policy annotation ประกาศไว้ว่าต้องมีสิทธิ์ read ของโมดูล dashboard — แต่ middleware ที่ตรวจ policy นี้ถูกเขียนให้เป็น no-op โดยเจตนา คอมเมนต์ในซอร์สระบุตรงว่า "Enforcement disabled — allow all authenticated requests (TS parity)" เพื่อคงพฤติกรรมเดิมของระบบ NestJS ต้นทางที่ปิดการบังคับสิทธิ์ระดับนี้ไว้ทั้งระบบ
  • ผลคือผู้ใช้ที่ล็อกอินสำเร็จและมี LINE OA ผูกกับ token แล้ว เรียก endpoint นี้ได้เสมอไม่ว่าสิทธิ์ย่อยจะเป็นอย่างไร การซ่อนเมนู/หน้าฝั่งหน้าเว็บจึงเป็นเพียงการควบคุมสิ่งที่ผู้ใช้ทั่วไปมองเห็น ไม่ใช่การปิดกั้นที่ตัว API จริง

ไฟล์อ้างอิงจากซอร์สโค้ด​

Frontend (cms-web-2026)

  • src/app/dashboard/page.tsx — จุดเข้าหน้า, ตัวครอบสิทธิ์
  • src/components/dashboard/dashboard.tsx, dashboard.container.tsx — โครงหน้าและ state ตัวกรองวันที่ (ยังไม่มี UI ให้ใช้)
  • src/components/dashboard/dashboard-chart/ — dashboard-chart.container.tsx (ดึงข้อมูลและคำนวณ), dashboard-chart.tsx (จัดวาง), pie-card.tsx, score-card.tsx
  • src/components/dashboard/charts/ — friends-growth-chart.tsx, activity-bar-chart.tsx, doughnut-chart.tsx
  • src/components/dashboard/upcoming-activities/ — ตัวควบคุมและ UI ของการ์ดกิจกรรมที่กำลังจะถึง
  • src/services/dashboard.service.ts — เรียก GET /dashboard/total-friends (และ getTopRichMenu ที่ไม่ถูกใช้งานจริง)

Backend (line-management-cms-api-go)

  • internal/modules/dashboard/controller.go — ลงทะเบียนเส้นทางเดียวคือ GET /dashboard/total-friends
  • internal/modules/dashboard/service.go — ตรรกะการนับและเปรียบเทียบยอด
  • internal/modules/dashboard/dto.go, types.go — โครงสร้างพารามิเตอร์และผลลัพธ์
  • internal/modules/auth/policy.go — จุดที่ยืนยันว่า CheckPolicies เป็น no-op ทั้งระบบ

ดูรายละเอียดเชิงเทคนิคเพิ่มเติม (เวอร์ชันก่อนหน้าของทีมเอกสาร) ที่ หน้าแดชบอร์ด