index.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <script setup lang="ts">
  2. import Card from "./components/Card.vue";
  3. import { getCardList } from "@/api/list";
  4. import { message } from "@/utils/message";
  5. import { ElMessageBox } from "element-plus";
  6. import { ref, onMounted, nextTick } from "vue";
  7. import dialogForm from "./components/DialogForm.vue";
  8. import { useRenderIcon } from "@/components/ReIcon/src/hooks";
  9. defineOptions({
  10. name: "ListCard"
  11. });
  12. const svg = `
  13. <path class="path" d="
  14. M 30 15
  15. L 28 17
  16. M 25.61 25.61
  17. A 15 15, 0, 0, 1, 15 30
  18. A 15 15, 0, 1, 1, 27.99 7.5
  19. L 15 15
  20. " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
  21. `;
  22. const INITIAL_DATA = {
  23. name: "",
  24. status: "",
  25. description: "",
  26. type: "",
  27. mark: ""
  28. };
  29. const pagination = ref({ current: 1, pageSize: 12, total: 0 });
  30. const productList = ref([]);
  31. const dataLoading = ref(true);
  32. const getCardListData = async () => {
  33. try {
  34. const { data } = await getCardList();
  35. productList.value = data.list;
  36. pagination.value = {
  37. ...pagination.value,
  38. total: data.list.length
  39. };
  40. } catch (e) {
  41. console.log(e);
  42. } finally {
  43. setTimeout(() => {
  44. dataLoading.value = false;
  45. }, 500);
  46. }
  47. };
  48. onMounted(() => {
  49. getCardListData();
  50. });
  51. const formDialogVisible = ref(false);
  52. const formData = ref({ ...INITIAL_DATA });
  53. const searchValue = ref("");
  54. const onPageSizeChange = (size: number) => {
  55. pagination.value.pageSize = size;
  56. pagination.value.current = 1;
  57. };
  58. const onCurrentChange = (current: number) => {
  59. pagination.value.current = current;
  60. };
  61. const handleDeleteItem = product => {
  62. ElMessageBox.confirm(
  63. product
  64. ? `确认删除后${product.name}的所有产品信息将被清空, 且无法恢复`
  65. : "",
  66. "提示",
  67. {
  68. type: "warning"
  69. }
  70. )
  71. .then(() => {
  72. message("删除成功", { type: "success" });
  73. })
  74. .catch(() => {});
  75. };
  76. const handleManageProduct = product => {
  77. formDialogVisible.value = true;
  78. nextTick(() => {
  79. formData.value = { ...product, status: product?.isSetup ? "1" : "0" };
  80. });
  81. };
  82. </script>
  83. <template>
  84. <div class="main">
  85. <div class="w-full flex justify-between mb-4">
  86. <el-button :icon="useRenderIcon('add')" @click="formDialogVisible = true">
  87. 新建产品
  88. </el-button>
  89. <el-input
  90. style="width: 300px"
  91. v-model="searchValue"
  92. placeholder="请输入产品名称"
  93. clearable
  94. >
  95. <template #suffix>
  96. <el-icon class="el-input__icon">
  97. <IconifyIconOffline
  98. v-show="searchValue.length === 0"
  99. icon="search"
  100. />
  101. </el-icon>
  102. </template>
  103. </el-input>
  104. </div>
  105. <div
  106. v-loading="dataLoading"
  107. :element-loading-svg="svg"
  108. element-loading-svg-view-box="-10, -10, 50, 50"
  109. >
  110. <el-empty
  111. description="暂无数据"
  112. v-show="
  113. productList
  114. .slice(
  115. pagination.pageSize * (pagination.current - 1),
  116. pagination.pageSize * pagination.current
  117. )
  118. .filter(v =>
  119. v.name.toLowerCase().includes(searchValue.toLowerCase())
  120. ).length === 0
  121. "
  122. />
  123. <template v-if="pagination.total > 0">
  124. <el-row :gutter="16">
  125. <el-col
  126. v-for="(product, index) in productList
  127. .slice(
  128. pagination.pageSize * (pagination.current - 1),
  129. pagination.pageSize * pagination.current
  130. )
  131. .filter(v =>
  132. v.name.toLowerCase().includes(searchValue.toLowerCase())
  133. )"
  134. :key="index"
  135. :xs="24"
  136. :sm="12"
  137. :md="8"
  138. :lg="6"
  139. :xl="4"
  140. >
  141. <Card
  142. :product="product"
  143. @delete-item="handleDeleteItem"
  144. @manage-product="handleManageProduct"
  145. />
  146. </el-col>
  147. </el-row>
  148. <el-pagination
  149. class="float-right"
  150. v-model:currentPage="pagination.current"
  151. :page-size="pagination.pageSize"
  152. :total="pagination.total"
  153. :page-sizes="[12, 24, 36]"
  154. :background="true"
  155. layout="total, sizes, prev, pager, next, jumper"
  156. @size-change="onPageSizeChange"
  157. @current-change="onCurrentChange"
  158. />
  159. </template>
  160. </div>
  161. <dialogForm v-model:visible="formDialogVisible" :data="formData" />
  162. </div>
  163. </template>