main.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. // 主要JavaScript功能
  2. // DOM加载完成后执行
  3. document.addEventListener('DOMContentLoaded', function() {
  4. // 初始化工具提示
  5. var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
  6. var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
  7. return new bootstrap.Tooltip(tooltipTriggerEl);
  8. });
  9. // 初始化弹出框
  10. var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
  11. var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
  12. return new bootstrap.Popover(popoverTriggerEl);
  13. });
  14. });
  15. // API请求封装
  16. const API = {
  17. // 基础URL
  18. baseURL: '/api/v1',
  19. // 获取认证令牌
  20. getAuthToken: function() {
  21. return localStorage.getItem('authToken');
  22. },
  23. // 设置认证令牌
  24. setAuthToken: function(token) {
  25. localStorage.setItem('authToken', token);
  26. },
  27. // 清除认证令牌
  28. clearAuthToken: function() {
  29. localStorage.removeItem('authToken');
  30. },
  31. // 通用请求方法
  32. request: function(method, url, data = null) {
  33. const options = {
  34. method: method,
  35. headers: {
  36. 'Content-Type': 'application/json',
  37. },
  38. };
  39. // 添加认证头
  40. const token = this.getAuthToken();
  41. if (token) {
  42. options.headers['Authorization'] = `Bearer ${token}`;
  43. }
  44. // 添加请求体
  45. if (data) {
  46. options.body = JSON.stringify(data);
  47. }
  48. return fetch(this.baseURL + url, options)
  49. .then(response => {
  50. if (!response.ok) {
  51. throw new Error(`HTTP error! status: ${response.status}`);
  52. }
  53. return response.json();
  54. });
  55. },
  56. // GET请求
  57. get: function(url) {
  58. return this.request('GET', url);
  59. },
  60. // POST请求
  61. post: function(url, data) {
  62. return this.request('POST', url, data);
  63. },
  64. // PUT请求
  65. put: function(url, data) {
  66. return this.request('PUT', url, data);
  67. },
  68. // DELETE请求
  69. delete: function(url) {
  70. return this.request('DELETE', url);
  71. }
  72. };
  73. // 用户认证相关功能
  74. const Auth = {
  75. // 登录
  76. login: function(username, password) {
  77. return API.post('/login', { username, password })
  78. .then(response => {
  79. if (response.code === 200) {
  80. API.setAuthToken(response.data.token);
  81. localStorage.setItem('user', JSON.stringify(response.data.user));
  82. return response.data;
  83. } else {
  84. throw new Error(response.message);
  85. }
  86. });
  87. },
  88. // 注册
  89. register: function(userData) {
  90. return API.post('/register', userData)
  91. .then(response => {
  92. if (response.code === 201) {
  93. return response.data;
  94. } else {
  95. throw new Error(response.message);
  96. }
  97. });
  98. },
  99. // 登出
  100. logout: function() {
  101. API.clearAuthToken();
  102. localStorage.removeItem('user');
  103. window.location.href = '/login';
  104. },
  105. // 获取当前用户
  106. getCurrentUser: function() {
  107. const userStr = localStorage.getItem('user');
  108. return userStr ? JSON.parse(userStr) : null;
  109. },
  110. // 检查是否已登录
  111. isLoggedIn: function() {
  112. return !!API.getAuthToken();
  113. }
  114. };
  115. // 商品相关功能
  116. const Products = {
  117. // 获取商品列表
  118. getList: function(page = 1, pageSize = 10, search = '') {
  119. let url = `/products?page=${page}&page_size=${pageSize}`;
  120. if (search) {
  121. url += `&search=${search}`;
  122. }
  123. return API.get(url);
  124. },
  125. // 获取商品详情
  126. getDetail: function(id) {
  127. return API.get(`/products/${id}`);
  128. },
  129. // 创建商品
  130. create: function(productData) {
  131. return API.post('/products', productData);
  132. },
  133. // 更新商品
  134. update: function(id, productData) {
  135. return API.put(`/products/${id}`, productData);
  136. },
  137. // 删除商品
  138. delete: function(id) {
  139. return API.delete(`/products/${id}`);
  140. }
  141. };
  142. // 购物车相关功能
  143. const Cart = {
  144. // 获取购物车内容
  145. getItems: function() {
  146. return API.get('/cart');
  147. },
  148. // 添加商品到购物车
  149. addItem: function(productId, quantity = 1) {
  150. return API.post('/cart/items', { product_id: productId, quantity });
  151. },
  152. // 更新购物车商品数量
  153. updateItem: function(itemId, quantity) {
  154. return API.put(`/cart/items/${itemId}`, { quantity });
  155. },
  156. // 删除购物车商品
  157. removeItem: function(itemId) {
  158. return API.delete(`/cart/items/${itemId}`);
  159. },
  160. // 清空购物车
  161. clear: function() {
  162. return API.delete('/cart');
  163. }
  164. };
  165. // 订单相关功能
  166. const Orders = {
  167. // 获取订单列表
  168. getList: function(page = 1, pageSize = 10) {
  169. return API.get(`/orders?page=${page}&page_size=${pageSize}`);
  170. },
  171. // 获取订单详情
  172. getDetail: function(id) {
  173. return API.get(`/orders/${id}`);
  174. },
  175. // 创建订单
  176. create: function(orderData) {
  177. return API.post('/orders', orderData);
  178. },
  179. // 更新订单状态
  180. updateStatus: function(id, status) {
  181. return API.put(`/orders/${id}`, { status });
  182. }
  183. };
  184. // 工具函数
  185. const Utils = {
  186. // 显示提示消息
  187. showAlert: function(message, type = 'info') {
  188. const alertDiv = document.createElement('div');
  189. alertDiv.className = `alert alert-${type} alert-dismissible fade show`;
  190. alertDiv.innerHTML = `
  191. ${message}
  192. <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
  193. `;
  194. const container = document.querySelector('.container');
  195. container.insertBefore(alertDiv, container.firstChild);
  196. // 5秒后自动关闭
  197. setTimeout(() => {
  198. alertDiv.remove();
  199. }, 5000);
  200. },
  201. // 格式化价格
  202. formatPrice: function(price) {
  203. return `¥${parseFloat(price).toFixed(2)}`;
  204. },
  205. // 格式化日期
  206. formatDate: function(dateString) {
  207. const date = new Date(dateString);
  208. return date.toLocaleDateString('zh-CN', {
  209. year: 'numeric',
  210. month: 'long',
  211. day: 'numeric',
  212. hour: '2-digit',
  213. minute: '2-digit'
  214. });
  215. },
  216. // 显示加载状态
  217. showLoading: function(element) {
  218. element.innerHTML = '<span class="loading"></span> 加载中...';
  219. element.disabled = true;
  220. },
  221. // 隐藏加载状态
  222. hideLoading: function(element, originalText) {
  223. element.innerHTML = originalText;
  224. element.disabled = false;
  225. },
  226. // 确认对话框
  227. confirm: function(message, callback) {
  228. if (confirm(message)) {
  229. callback();
  230. }
  231. }
  232. };
  233. // 页面初始化
  234. document.addEventListener('DOMContentLoaded', function() {
  235. // 检查登录状态
  236. if (Auth.isLoggedIn()) {
  237. const user = Auth.getCurrentUser();
  238. // 更新导航栏显示用户信息
  239. const navbar = document.querySelector('.navbar-nav');
  240. if (navbar) {
  241. // 隐藏登录/注册链接
  242. const loginLink = navbar.querySelector('a[href="/login"]');
  243. const registerLink = navbar.querySelector('a[href="/register"]');
  244. if (loginLink) loginLink.style.display = 'none';
  245. if (registerLink) registerLink.style.display = 'none';
  246. // 添加用户信息
  247. const userItem = document.createElement('li');
  248. userItem.className = 'nav-item dropdown';
  249. userItem.innerHTML = `
  250. <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
  251. ${user.username}
  252. </a>
  253. <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
  254. <li><a class="dropdown-item" href="/profile">个人信息</a></li>
  255. <li><a class="dropdown-item" href="/orders">我的订单</a></li>
  256. <li><hr class="dropdown-divider"></li>
  257. <li><a class="dropdown-item" href="#" onclick="Auth.logout()">退出登录</a></li>
  258. </ul>
  259. `;
  260. navbar.appendChild(userItem);
  261. }
  262. }
  263. });
  264. // 导出对象供其他脚本使用
  265. window.API = API;
  266. window.Auth = Auth;
  267. window.Products = Products;
  268. window.Cart = Cart;
  269. window.Orders = Orders;
  270. window.Utils = Utils;