You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

250 lines
7.9 KiB

1 day ago
  1. import express, { json } from 'express';
  2. import { createConnection } from 'mysql2';
  3. const app = express();
  4. const port = 3000;
  5. // 啟用 CORS 和 JSON 處理
  6. app.use(json());
  7. app.use((req, res, next) => {
  8. res.header('Access-Control-Allow-Origin', '*');
  9. res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  10. next();
  11. });
  12. // 建立 MySQL 連線
  13. const connection = createConnection({
  14. host: '192.168.1.69',
  15. port: 3310,
  16. user: 'root',
  17. password: '123456',
  18. database: 'eoffice11'
  19. });
  20. // 測試資料庫連線
  21. connection.connect(err => {
  22. if (err) {
  23. console.error('無法連接到 MySQL 資料庫:', err);
  24. return;
  25. }
  26. console.log('已成功連接到 MySQL 資料庫');
  27. });
  28. const statusMap = {
  29. 0: '待審批',
  30. 1: '審批中',
  31. 2: '已批准',
  32. 3: '拒絕',
  33. 4: '會議開始',
  34. 5: '會議結束'
  35. };
  36. function toTaipeiISOString(date) {
  37. if (!date) return null;
  38. return new Date(date).toLocaleString('sv-SE', { timeZone: 'Asia/Taipei' });
  39. }
  40. // 取得身分驗證
  41. app.get('/api/calendar/getAuth', (req, res) => {
  42. const { id } = req.query;
  43. const sql = `
  44. SELECT ur.user_id
  45. FROM user_role ur
  46. JOIN role_basic_info rbi ON ur.role_id = rbi.role_id
  47. WHERE rbi.role_name = '櫃檯人員' and ur.user_id = '${id}'
  48. `;
  49. connection.query(sql, (err, results) => {
  50. if (err) {
  51. console.error('查詢錯誤:', err);
  52. return res.status(500).json({ error: '資料庫查詢失敗' });
  53. }
  54. if (results.length > 0) {
  55. res.json({ success: true });
  56. } else {
  57. res.json({ success: false });
  58. }
  59. });
  60. });
  61. // 取得所有會議室
  62. app.get('/api/calendar/getMeetingRoom', (req, res) => {
  63. connection.query('SELECT room_id, room_name FROM meeting_rooms', (err, results) => {
  64. if (err) {
  65. console.error('查詢錯誤:', err);
  66. return res.status(500).json({ error: '資料庫查詢失敗' });
  67. }
  68. const mapped = results.map(row => ({
  69. id: row.room_id,
  70. name: row.room_name
  71. }));
  72. res.json(mapped);
  73. });
  74. });
  75. // 取得該會議資料
  76. app.get('/api/calendar/getMeetingApplyById', (req, res) => {
  77. const { meetingId } = req.query;
  78. const sql = `
  79. SELECT ma.*, ubi.user_name AS apply_user_name
  80. FROM meeting_apply ma
  81. LEFT JOIN user_basic_info ubi ON ma.meeting_apply_user = ubi.user_id
  82. WHERE ma.meeting_apply_id = ? LIMIT 1
  83. `;
  84. connection.query(sql, [meetingId], (err, results) => {
  85. if (err) {
  86. console.error('查詢錯誤:', err);
  87. return res.status(500).json({ error: '資料庫查詢失敗' });
  88. }
  89. if (results.length > 0) {
  90. const row = results[0];
  91. res.json({
  92. id: row.meeting_apply_id,
  93. roomId: row.meeting_room_id,
  94. subject: row.meeting_subject,
  95. applyUser: row.meeting_apply_user,
  96. applyUserName: row.apply_user_name,
  97. otherJoinMember: row.meeting_other_join_member,
  98. type: row.meeting_type,
  99. beginTime: toTaipeiISOString(row.meeting_begin_time),
  100. endTime: toTaipeiISOString(row.meeting_end_time),
  101. remark: row.meeting_remark,
  102. status: statusMap[row.meeting_status],
  103. approvalOpinion: row.meeting_approval_opinion,
  104. beginRemark: row.meeting_begin_remark,
  105. endRemark: row.meeting_end_remark,
  106. conflict: row.conflict,
  107. falseDelete: row.false_delete,
  108. applyTime: toTaipeiISOString(row.meeting_apply_time),
  109. deletedAt: toTaipeiISOString(row.deleted_at),
  110. createdAt: toTaipeiISOString(row.created_at),
  111. updatedAt: toTaipeiISOString(row.updated_at),
  112. reminderTiming: row.meeting_reminder_timing,
  113. signType: row.sign_type,
  114. signWifi: row.meeting_sign_wifi,
  115. externalUser: row.meeting_external_user,
  116. reminderTime: toTaipeiISOString(row.meeting_reminder_time),
  117. signUser: row.meeting_sign_user,
  118. externalReminderType: row.external_reminder_type,
  119. sign: row.sign,
  120. response: row.meeting_response,
  121. approvalUser: row.meeting_approval_user,
  122. createTime: toTaipeiISOString(row.meeting_create_time),
  123. attenceType: row.attence_type,
  124. interfaceId: row.interface_id,
  125. videoInfo: row.meeting_video_info,
  126. isRepeat: !!row.is_repeat,
  127. repeatInterval: row.repeat_interval,
  128. repeatType: row.repeat_type,
  129. repeatEndType: row.repeat_end_type,
  130. repeatEndNumber: row.repeat_end_number,
  131. repeatRemove: row.repeat_remove,
  132. parentId: row.meeting_parent_id,
  133. repeatEndDate: toTaipeiISOString(row.repeat_end_date),
  134. cycleBeginTime: toTaipeiISOString(row.cycle_begin_time),
  135. cycleEndTime: toTaipeiISOString(row.cycle_end_time),
  136. createFrom: row.create_from
  137. });
  138. } else {
  139. res.status(404).json({ error: '查無資料' });
  140. }
  141. });
  142. });
  143. // 取得會議申請(依月份)
  144. app.get('/api/calendar/getMeetingApply', (req, res) => {
  145. const { Date: dateStr } = req.query; // YYYYMM
  146. const { roomId } = req.query; //如果為null,則查詢所有會議室
  147. const { old } = req.query; //如果為null,則查詢所有會議室
  148. if (!dateStr || !/^\d{6}$/.test(dateStr)) {
  149. return res.status(400).json({ error: '請提供正確的 Date 參數 (YYYYMM)' });
  150. }
  151. const year = dateStr.substring(0, 4);
  152. const month = dateStr.substring(4, 6);
  153. const start = `${year}-${month}-01`;
  154. const end = `${year}-${month}-31`;
  155. const sql = `
  156. select
  157. ma.meeting_apply_id,
  158. ma.meeting_room_id,
  159. ubi.user_name as meeting_apply_user,
  160. ma.meeting_subject,
  161. ma.meeting_remark,
  162. ma.meeting_begin_time,
  163. ma.meeting_end_time,
  164. ma.meeting_status,
  165. ma.meeting_parent_id,
  166. ma.false_delete,
  167. ma.is_repeat,
  168. ma.created_at,
  169. ma.updated_at
  170. from meeting_apply ma
  171. left join user_basic_info ubi
  172. on ma.meeting_apply_user = ubi.user_id
  173. where ma.is_repeat = 0
  174. ${roomId ? `and ma.meeting_room_id = ${roomId}` : ''}
  175. ${old === 'true' ? '' : `and ma.meeting_status != 5`}
  176. ${old === 'true' ? '' : `and ma.false_delete != 1`}
  177. and ma.meeting_begin_time >= '${start}'
  178. and ma.meeting_begin_time <= '${end}'
  179. order by ma.meeting_begin_time asc
  180. `;
  181. connection.query(sql, [start, end], (err, results) => {
  182. if (err) {
  183. console.error('查詢錯誤:', err);
  184. return res.status(500).json({ error: '資料庫查詢失敗' });
  185. }
  186. // 依照前端interface格式轉換欄位
  187. const mapped = results.map(row => ({
  188. id: row.meeting_apply_id,
  189. roomId: row.meeting_room_id,
  190. subject: row.meeting_subject,
  191. remark: row.meeting_remark,
  192. beginTime: toTaipeiISOString(row.meeting_begin_time),
  193. endTime: toTaipeiISOString(row.meeting_end_time),
  194. status: statusMap[row.meeting_status],
  195. parentId: row.meeting_parent_id,
  196. falseDelete: row.false_delete,
  197. isRepeat: !!row.is_repeat,
  198. createdBy: row.meeting_apply_user,
  199. createdAt: toTaipeiISOString(row.created_at),
  200. updatedAt: toTaipeiISOString(row.updated_at)
  201. }));
  202. res.json(mapped);
  203. });
  204. });
  205. app.put('/api/calendar/closeMeeting', (req, res) => {
  206. const { meetingId } = req.body;
  207. const sql = `
  208. UPDATE meeting_apply
  209. SET meeting_status = 5, false_delete = 1
  210. WHERE meeting_apply_id = ${meetingId}
  211. `;
  212. connection.query(sql, (err, results) => {
  213. if (err) {
  214. console.error('查詢錯誤:', err);
  215. return res.status(500).json({ error: '資料庫查詢失敗' });
  216. }
  217. res.json(results);
  218. });
  219. });
  220. app.put('/api/calendar/closeAllRepeatMeeting', (req, res) => {
  221. const { parentId } = req.body;
  222. const sql = `
  223. UPDATE meeting_apply
  224. SET meeting_status = 5, false_delete = 1
  225. WHERE meeting_parent_id = ${parentId}
  226. OR meeting_apply_id = ${parentId}
  227. `;
  228. connection.query(sql, (err, results) => {
  229. if (err) {
  230. console.error('查詢錯誤:', err);
  231. return res.status(500).json({ error: '資料庫查詢失敗' });
  232. }
  233. res.json(results);
  234. });
  235. });
  236. // 啟動伺服器
  237. app.listen(port, () => {
  238. console.log(`API 伺服器運行於 http://localhost:${port}`);
  239. });