index.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <template>
  2. <ele-page flex-table>
  3. <!-- Search Bar -->
  4. <div class="bg-white p-4 mb-4 rounded shadow-sm flex items-center justify-between">
  5. <div class="flex items-center space-x-2">
  6. <el-input v-model="searchQuery" placeholder="请输入书单名称" style="width: 240px" clearable />
  7. <el-button type="primary" @click="handleSearch">查询</el-button>
  8. <el-button @click="handleReset">重置</el-button>
  9. </div>
  10. <el-button type="primary" @click="handleAdd">添加书单</el-button>
  11. </div>
  12. <common-table ref="tableRef" :pageConfig="pageConfig" :columns="columns" :tools="false">
  13. <!-- 状态 -->
  14. <template #status="{ row }">
  15. <span :class="row.status === 'online' ? 'text-green-500' : 'text-gray-500'">
  16. {{ row.status === 'online' ? '已上架' : '已下架' }}
  17. </span>
  18. </template>
  19. <!-- 操作 -->
  20. <template #action="{ row }">
  21. <div class="flex items-center space-x-2">
  22. <el-button
  23. v-if="row.status === 'online'"
  24. size="small"
  25. type="primary"
  26. plain
  27. @click="handleStatusToggle(row)">
  28. 下架
  29. </el-button>
  30. <el-button
  31. v-else
  32. size="small"
  33. type="success"
  34. plain
  35. @click="handleStatusToggle(row)">
  36. 上架
  37. </el-button>
  38. <el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
  39. <el-button link type="primary" @click="handleDetail(row)">详情</el-button>
  40. <el-button link type="danger" @click="handleDelete(row)">删除</el-button>
  41. </div>
  42. </template>
  43. </common-table>
  44. <booklist-edit ref="editDialogRef" @success="handleSuccess" />
  45. </ele-page>
  46. </template>
  47. <script setup>
  48. import { ref, reactive } from 'vue';
  49. import CommonTable from '@/components/CommonPage/CommonTable.vue';
  50. import BooklistEdit from './components/booklist-edit.vue';
  51. import { EleMessage } from 'ele-admin-plus/es';
  52. defineOptions({ name: 'Booklist' });
  53. const tableRef = ref(null);
  54. const editDialogRef = ref(null);
  55. const searchQuery = ref('');
  56. const pageConfig = reactive({
  57. pageUrl: '/salesOps/booklist/list',
  58. fileName: '书单列表',
  59. cacheKey: 'booklist-list',
  60. params: {}
  61. });
  62. const columns = ref([
  63. { type: 'selection', width: 50, align: 'center' },
  64. { label: '编号', prop: 'code', width: 100, align: 'center' },
  65. { label: '书单名称', prop: 'name', align: 'center' },
  66. { label: '发布时间', prop: 'publishTime', align: 'center', width: 180 },
  67. { label: '书单类型', prop: 'typeLabel', align: 'center' },
  68. { label: '相关单品', prop: 'relatedItems', align: 'center' },
  69. { label: '状态', prop: 'status', slot: 'status', align: 'center' },
  70. { label: '排序', prop: 'sort', align: 'center', width: 80 },
  71. { label: '操作', prop: 'action', slot: 'action', align: 'center', width: 250 }
  72. ]);
  73. // Mock Data
  74. const mockList = ref([
  75. { id: 1, code: '0101', name: '诺贝尔文学奖', publishTime: '2021-06-26 12:00:00', type: 'single', typeLabel: '单排列', relatedItems: 10, status: 'online', sort: 1 },
  76. { id: 2, code: '100', name: '茅盾文学奖', publishTime: '2021-06-26 12:00:00', type: 'double', typeLabel: '双排列', relatedItems: 10, status: 'offline', sort: 1 },
  77. { id: 3, code: '10252', name: '樊登读书', publishTime: '2021-06-26 12:00:00', type: 'double', typeLabel: '双排列', relatedItems: 10, status: 'online', sort: 1 },
  78. { id: 4, code: '0101', name: '书嗨推荐', publishTime: '2021-06-26 12:00:00', type: 'single', typeLabel: '单排列', relatedItems: 10, status: 'online', sort: 1 },
  79. ]);
  80. const mockDatasource = ({ pages }) => {
  81. return new Promise((resolve) => {
  82. setTimeout(() => {
  83. let data = mockList.value;
  84. if (searchQuery.value) {
  85. data = data.filter(item => item.name.includes(searchQuery.value));
  86. }
  87. resolve({
  88. code: 0,
  89. msg: 'success',
  90. count: data.length,
  91. data: data
  92. });
  93. }, 300);
  94. });
  95. };
  96. const handleSearch = () => {
  97. reload();
  98. };
  99. const handleReset = () => {
  100. searchQuery.value = '';
  101. reload();
  102. };
  103. const reload = () => {
  104. tableRef.value?.reload();
  105. };
  106. const handleAdd = () => {
  107. editDialogRef.value?.handleOpen();
  108. };
  109. const handleEdit = (row) => {
  110. editDialogRef.value?.handleOpen(row);
  111. };
  112. const handleDetail = (row) => {
  113. EleMessage.info(`查看 ${row.name} 详情`);
  114. };
  115. const handleDelete = (row) => {
  116. EleMessage.confirm(`确定要删除 ${row.name} 吗?`)
  117. .then(() => {
  118. // TODO: Call API to delete
  119. // tableRef.value?.operatBatch({ method: 'delete', row, url: '/salesOps/booklist/delete' });
  120. EleMessage.success('删除成功');
  121. reload();
  122. })
  123. .catch(() => {});
  124. };
  125. const handleStatusToggle = (row) => {
  126. // TODO: Call API to update status
  127. // tableRef.value?.operatBatch({ method: 'post', row, url: '/salesOps/booklist/updateStatus' });
  128. EleMessage.success(`${row.name} 已${row.status === 'online' ? '上架' : '下架'}`);
  129. };
  130. const handleSuccess = () => {
  131. reload();
  132. };
  133. </script>