index.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <script setup lang="ts">
  2. import { ref } from "vue";
  3. import tree from "./tree.vue";
  4. import { useUser } from "./utils/hook";
  5. import { PureTableBar } from "@/components/RePureTableBar";
  6. import { useRenderIcon } from "@/components/ReIcon/src/hooks";
  7. import Upload from "~icons/ri/upload-line";
  8. import Role from "~icons/ri/admin-line";
  9. import Password from "~icons/ri/lock-password-line";
  10. import More from "~icons/ep/more-filled";
  11. import Delete from "~icons/ep/delete";
  12. import EditPen from "~icons/ep/edit-pen";
  13. import Refresh from "~icons/ep/refresh";
  14. import AddFill from "~icons/ri/add-circle-line";
  15. defineOptions({
  16. name: "SystemUser"
  17. });
  18. const treeRef = ref();
  19. const formRef = ref();
  20. const tableRef = ref();
  21. const {
  22. form,
  23. loading,
  24. columns,
  25. dataList,
  26. selectedNum,
  27. pagination,
  28. buttonClass,
  29. deviceDetection,
  30. onSearch,
  31. resetForm,
  32. onbatchDel,
  33. openDialog,
  34. handleUpdate,
  35. handleDelete,
  36. handleReset,
  37. handleSizeChange,
  38. onSelectionCancel,
  39. handleCurrentChange,
  40. handleSelectionChange
  41. } = useUser(tableRef, treeRef);
  42. </script>
  43. <template>
  44. <div :class="['flex', 'justify-between', deviceDetection() && 'flex-wrap']">
  45. <!-- <tree
  46. ref="treeRef"
  47. :class="['mr-2', deviceDetection() ? 'w-full' : 'min-w-[200px]']"
  48. :treeData="treeData"
  49. :treeLoading="treeLoading"
  50. @tree-select="onTreeSelect"
  51. /> -->
  52. <div :class="[deviceDetection() ? ['w-full', 'mt-2'] : 'width-calc']">
  53. <!-- <el-form
  54. ref="formRef"
  55. :inline="true"
  56. :model="form"
  57. class="search-form bg-bg_color w-full pl-8 pt-[12px] overflow-auto"
  58. >
  59. <el-form-item label="用户名称:" prop="username">
  60. <el-input
  61. v-model="form.username"
  62. placeholder="请输入用户名称"
  63. clearable
  64. class="w-[180px]!"
  65. />
  66. </el-form-item>
  67. <el-form-item label="手机号码:" prop="phone">
  68. <el-input
  69. v-model="form.phone"
  70. placeholder="请输入手机号码"
  71. clearable
  72. class="w-[180px]!"
  73. />
  74. </el-form-item>
  75. <el-form-item label="状态:" prop="status">
  76. <el-select
  77. v-model="form.status"
  78. placeholder="请选择"
  79. clearable
  80. class="w-[180px]!"
  81. >
  82. <el-option label="已开启" value="1" />
  83. <el-option label="已关闭" value="0" />
  84. </el-select>
  85. </el-form-item>
  86. <el-form-item>
  87. <el-button
  88. type="primary"
  89. :icon="useRenderIcon('ri/search-line')"
  90. :loading="loading"
  91. @click="onSearch"
  92. >
  93. 搜索
  94. </el-button>
  95. <el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
  96. 重置
  97. </el-button>
  98. </el-form-item>
  99. </el-form> -->
  100. <PureTableBar title="用户列表" :columns="columns" @refresh="onSearch">
  101. <template #buttons>
  102. <el-button
  103. type="primary"
  104. :icon="useRenderIcon(AddFill)"
  105. @click="openDialog()"
  106. >
  107. 新增用户
  108. </el-button>
  109. </template>
  110. <template v-slot="{ size, dynamicColumns }">
  111. <div
  112. v-if="selectedNum > 0"
  113. v-motion-fade
  114. class="bg-[var(--el-fill-color-light)] w-full h-[46px] mb-2 pl-4 flex items-center"
  115. >
  116. <div class="flex-auto">
  117. <span
  118. style="font-size: var(--el-font-size-base)"
  119. class="text-[rgba(42,46,54,0.5)] dark:text-[rgba(220,220,242,0.5)]"
  120. >
  121. 已选 {{ selectedNum }} 项
  122. </span>
  123. <el-button type="primary" text @click="onSelectionCancel">
  124. 取消选择
  125. </el-button>
  126. </div>
  127. <el-popconfirm title="是否确认删除?" @confirm="onbatchDel">
  128. <template #reference>
  129. <el-button type="danger" text class="mr-1!">
  130. 批量删除
  131. </el-button>
  132. </template>
  133. </el-popconfirm>
  134. </div>
  135. <pure-table
  136. ref="tableRef"
  137. row-key="id"
  138. adaptive
  139. :adaptiveConfig="{ offsetBottom: 108 }"
  140. align-whole="center"
  141. table-layout="auto"
  142. :loading="loading"
  143. :size="size"
  144. :data="dataList"
  145. :columns="dynamicColumns"
  146. :pagination="{ ...pagination, size }"
  147. :header-cell-style="{
  148. background: 'var(--el-fill-color-light)',
  149. color: 'var(--el-text-color-primary)'
  150. }"
  151. @selection-change="handleSelectionChange"
  152. @page-size-change="handleSizeChange"
  153. @page-current-change="handleCurrentChange"
  154. >
  155. <template #operation="{ row }">
  156. <el-button
  157. class="reset-margin"
  158. link
  159. type="primary"
  160. :size="size"
  161. :icon="useRenderIcon(EditPen)"
  162. @click="openDialog('修改', row)"
  163. >
  164. 修改
  165. </el-button>
  166. <el-popconfirm
  167. :title="`是否确认删除用户名为${row.username}的这条数据`"
  168. @confirm="handleDelete(row)"
  169. >
  170. <template #reference>
  171. <el-button
  172. class="reset-margin"
  173. link
  174. type="primary"
  175. :size="size"
  176. :icon="useRenderIcon(Delete)"
  177. >
  178. 删除
  179. </el-button>
  180. </template>
  181. </el-popconfirm>
  182. <el-dropdown>
  183. <el-button
  184. class="ml-3! mt-[2px]!"
  185. link
  186. type="primary"
  187. :size="size"
  188. :icon="useRenderIcon(More)"
  189. @click="handleUpdate(row)"
  190. />
  191. <template #dropdown>
  192. <el-dropdown-menu>
  193. <el-dropdown-item>
  194. <el-button
  195. :class="buttonClass"
  196. link
  197. type="primary"
  198. :size="size"
  199. :icon="useRenderIcon(Password)"
  200. @click="handleReset(row)"
  201. >
  202. 重置密码
  203. </el-button>
  204. </el-dropdown-item>
  205. </el-dropdown-menu>
  206. </template>
  207. </el-dropdown>
  208. </template>
  209. </pure-table>
  210. </template>
  211. </PureTableBar>
  212. </div>
  213. </div>
  214. </template>
  215. <style lang="scss" scoped>
  216. :deep(.el-dropdown-menu__item i) {
  217. margin: 0;
  218. }
  219. :deep(.el-button:focus-visible) {
  220. outline: none;
  221. }
  222. .main-content {
  223. margin: 24px 24px 0 !important;
  224. }
  225. .search-form {
  226. :deep(.el-form-item) {
  227. margin-bottom: 12px;
  228. }
  229. }
  230. // 修复Flex布局工具类定义,确保在所有浏览器中一致
  231. .flex {
  232. display: flex;
  233. }
  234. .justify-between {
  235. justify-content: space-between;
  236. }
  237. /* Tailwind flex-wrap 对应的传统 CSS */
  238. .flex-wrap {
  239. flex-wrap: wrap;
  240. }
  241. /* Tailwind w-full 对应的传统 CSS(宽度100%) */
  242. .w-full {
  243. width: 100%;
  244. }
  245. /* Tailwind mt-2 对应的传统 CSS(默认 0.5rem,即 8px,根据设计稿可调整) */
  246. .mt-2 {
  247. margin-top: 0.5rem; /* 或 8px,1rem = 16px 时等价 */
  248. }
  249. /* Tailwind w-[calc(100%)] 对应的传统 CSS(直接转换 calc 表达式) */
  250. .width-calc {
  251. width: calc(100%);
  252. }
  253. </style>