index.vue 4.5 KB

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