index.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <template>
  2. <div>
  3. <el-button type="primary" @click="openDialog()">新增名单</el-button>
  4. <el-table
  5. :data="tableData"
  6. border
  7. style="width: 100%; margin-top: 10px"
  8. v-loading="loading"
  9. >
  10. <el-table-column prop="plate_number" label="序号" align="center" min-width="50" />
  11. <el-table-column prop="plate_number" label="车牌号" align="center" min-width="100" />
  12. <el-table-column
  13. prop="type"
  14. label="名单类型"
  15. :formatter="formatType"
  16. align="center"
  17. min-width="100"
  18. />
  19. <el-table-column
  20. prop="access_start_time"
  21. label="开始时间"
  22. :formatter="formatTime"
  23. align="center"
  24. min-width="200"
  25. />
  26. <el-table-column
  27. prop="access_end_time"
  28. label="结束时间"
  29. :formatter="formatTime"
  30. align="center"
  31. min-width="200"
  32. />
  33. <el-table-column label="操作" align="center" width="180">
  34. <template #default="{ row }">
  35. <el-button size="small" type="primary" @click="editRow(row)">编辑</el-button>
  36. <el-button size="small" type="danger" @click="deleteRow(row)">删除</el-button>
  37. </template>
  38. </el-table-column>
  39. </el-table>
  40. <!-- 分页 -->
  41. <div style="margin-top: 15px; text-align: right">
  42. <el-pagination
  43. v-if="total > 0"
  44. background
  45. layout="prev, pager, next"
  46. :total="total"
  47. :page-size="pageSize"
  48. @current-change="handlePageChange"
  49. />
  50. </div>
  51. <!-- 弹窗 -->
  52. <el-dialog :title="dialogTitle" v-model="dialogVisible" width="500px">
  53. <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
  54. <el-form-item label="车牌号" prop="plate_number">
  55. <el-input v-model="form.plate_number" />
  56. </el-form-item>
  57. <el-form-item label="名单类型" prop="type">
  58. <el-select v-model="form.type" placeholder="请选择">
  59. <el-option label="白名单" value="whitelist" />
  60. <el-option label="黑名单" value="blacklist" />
  61. </el-select>
  62. </el-form-item>
  63. <el-form-item label="生效时间" prop="access_start_time">
  64. <el-date-picker
  65. v-model="form.access_start_time"
  66. type="datetime"
  67. placeholder="选择开始时间"
  68. style="width: 100%"
  69. />
  70. </el-form-item>
  71. <el-form-item label="结束时间" prop="access_end_time">
  72. <el-date-picker
  73. v-model="form.access_end_time"
  74. type="datetime"
  75. placeholder="选择结束时间"
  76. style="width: 100%"
  77. />
  78. </el-form-item>
  79. </el-form>
  80. <template #footer>
  81. <el-button @click="dialogVisible = false">取消</el-button>
  82. <el-button type="primary" @click="saveRow">保存</el-button>
  83. </template>
  84. </el-dialog>
  85. </div>
  86. </template>
  87. <script>
  88. // ==== 模拟API ====
  89. // 实际项目中你应替换为:
  90. // import { getWhitelist, addWhitelist, updateWhitelist, removeWhitelist } from '@/api/whitelist'
  91. import axios from "axios";
  92. export default {
  93. data() {
  94. return {
  95. tableData: [
  96. {
  97. id: 1,
  98. plate_number: "粤A12345",
  99. type: "whitelist",
  100. access_start_time: "2025-10-01 08:00:00",
  101. access_end_time: "2025-12-31 18:00:00"
  102. },
  103. {
  104. id: 2,
  105. plate_number: "粤B88888",
  106. type: "blacklist",
  107. access_start_time: "2025-09-01 00:00:00",
  108. access_end_time: "2026-01-01 00:00:00"
  109. },
  110. {
  111. id: 3,
  112. plate_number: "粤C66666",
  113. type: "whitelist",
  114. access_start_time: "2025-10-10 07:30:00",
  115. access_end_time: "2025-12-10 19:00:00"
  116. }
  117. ],
  118. loading: false,
  119. total: 0,
  120. pageSize: 10,
  121. currentPage: 1,
  122. dialogVisible: false,
  123. dialogTitle: "新增名单",
  124. editId: null,
  125. form: {
  126. plate_number: "",
  127. type: "whitelist",
  128. access_start_time: "",
  129. access_end_time: "",
  130. },
  131. rules: {
  132. plate_number: [{ required: true, message: "请输入车牌号", trigger: "blur" }],
  133. type: [{ required: true, message: "请选择名单类型", trigger: "change" }],
  134. access_start_time: [{ required: true, message: "请选择开始时间", trigger: "change" }],
  135. access_end_time: [{ required: true, message: "请选择结束时间", trigger: "change" }],
  136. },
  137. };
  138. },
  139. mounted() {
  140. // this.loadData();
  141. },
  142. methods: {
  143. // ===== 获取列表 =====
  144. async loadData() {
  145. this.loading = true;
  146. try {
  147. const { data } = await axios.get("/api/whitelist", {
  148. params: { page: this.currentPage, pageSize: this.pageSize },
  149. });
  150. this.tableData = data.records;
  151. this.total = data.total;
  152. } catch (e) {
  153. console.error(e);
  154. } finally {
  155. this.loading = false;
  156. }
  157. },
  158. // ===== 打开新增弹窗 =====
  159. openDialog() {
  160. console.log("openDialog")
  161. this.dialogTitle = "新增名单";
  162. this.form = {
  163. plate_number: "",
  164. type: "whitelist",
  165. access_start_time: "",
  166. access_end_time: "",
  167. };
  168. this.editId = null;
  169. this.dialogVisible = true;
  170. console.log("openDialog this.dialogVisible", this.dialogVisible)
  171. },
  172. // ===== 编辑 =====
  173. editRow(row) {
  174. this.dialogTitle = "编辑名单";
  175. this.form = { ...row };
  176. this.editId = row.id;
  177. this.dialogVisible = true;
  178. },
  179. // ===== 保存 =====
  180. async saveRow() {
  181. this.$refs.formRef.validate(async (valid) => {
  182. if (!valid) return;
  183. try {
  184. if (this.editId) {
  185. await axios.put(`/api/whitelist/${this.editId}`, this.form);
  186. this.$message.success("修改成功");
  187. } else {
  188. await axios.post("/api/whitelist", this.form);
  189. this.$message.success("新增成功");
  190. }
  191. this.dialogVisible = false;
  192. this.loadData();
  193. } catch (e) {
  194. console.error(e);
  195. this.$message.error("保存失败");
  196. }
  197. });
  198. },
  199. // ===== 删除 =====
  200. async deleteRow(row) {
  201. try {
  202. await this.$confirm(`确定要删除车牌 ${row.plate_number} 吗?`, "提示", {
  203. type: "warning",
  204. });
  205. await axios.delete(`/api/whitelist/${row.id}`);
  206. this.$message.success("删除成功");
  207. this.loadData();
  208. } catch (e) {
  209. if (e !== "cancel") this.$message.error("删除失败");
  210. }
  211. },
  212. // ===== 分页 =====
  213. handlePageChange(page) {
  214. this.currentPage = page;
  215. this.loadData();
  216. },
  217. // ===== 格式化类型 =====
  218. formatType(row) {
  219. return row.type === "whitelist" ? "白名单" : "黑名单";
  220. },
  221. // ===== 格式化时间 =====
  222. formatTime(row, column, cellValue) {
  223. if (!cellValue) return "";
  224. const date = new Date(cellValue);
  225. return date.toLocaleString();
  226. },
  227. },
  228. };
  229. </script>