index.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <CommonPage>
  3. <template #action>
  4. <NButton type="primary" @click="router.push('article/add')">
  5. <i class="i-material-symbols:add mr-4 text-18" />
  6. 新增文章
  7. </NButton>
  8. </template>
  9. <MeCrud
  10. ref="$table"
  11. v-model:query-items="queryItems"
  12. :scroll-x="1200"
  13. :columns="columns"
  14. :get-data="api.read"
  15. >
  16. <MeQueryItem label="标题" :label-width="50">
  17. <n-input v-model:value="queryItems.title" type="text" placeholder="请输入标题名" clearable>
  18. <template #password-visible-icon />
  19. </n-input>
  20. </MeQueryItem>
  21. <MeQueryItem label="状态" :label-width="50">
  22. <n-select
  23. v-model:value="queryItems.enable"
  24. clearable
  25. :options="[
  26. { label: '启用', value: 1 },
  27. { label: '停用', value: 0 },
  28. ]"
  29. />
  30. </MeQueryItem>
  31. </MeCrud>
  32. <MeModal ref="modalRef" width="520px">
  33. <n-form
  34. ref="modalFormRef"
  35. label-placement="left"
  36. label-align="left"
  37. :label-width="80"
  38. :model="modalForm"
  39. >
  40. <n-form-item
  41. label="角色名"
  42. path="name"
  43. :rule="{
  44. required: true,
  45. message: '请输入角色名',
  46. trigger: ['input', 'blur'],
  47. }"
  48. >
  49. <n-input v-model:value="modalForm.name" />
  50. </n-form-item>
  51. <n-form-item
  52. label="角色编码"
  53. path="code"
  54. :rule="{
  55. required: true,
  56. message: '请输入角色编码',
  57. trigger: ['input', 'blur'],
  58. }"
  59. >
  60. <n-input v-model:value="modalForm.code" :disabled="modalAction !== 'add'" />
  61. </n-form-item>
  62. <n-form-item label="权限" path="permissionIds">
  63. <n-tree
  64. key-field="id"
  65. label-field="name"
  66. :selectable="false"
  67. :data="permissionTree"
  68. :checked-keys="modalForm.permissionIds"
  69. :on-update:checked-keys="(keys) => (modalForm.permissionIds = keys)"
  70. checkable check-on-click default-expand-all
  71. class="cus-scroll max-h-200 w-full"
  72. />
  73. </n-form-item>
  74. <n-form-item label="状态" path="enable">
  75. <NSwitch v-model:value="modalForm.enable">
  76. <template #checked>
  77. 启用
  78. </template>
  79. <template #unchecked>
  80. 停用
  81. </template>
  82. </NSwitch>
  83. </n-form-item>
  84. </n-form>
  85. </MeModal>
  86. </CommonPage>
  87. </template>
  88. <script setup>
  89. import { MeCrud, MeModal, MeQueryItem } from '@/components'
  90. import { useCrud } from '@/composables'
  91. import { NButton, NSwitch } from 'naive-ui'
  92. import api from './api'
  93. defineOptions({ name: 'RoleMgt' })
  94. const router = useRouter()
  95. const $table = ref(null)
  96. /** QueryBar筛选参数(可选) */
  97. const queryItems = ref({})
  98. onMounted(() => {
  99. $table.value?.handleSearch()
  100. })
  101. const { modalRef, modalFormRef, modalAction, modalForm, handleAdd, handleDelete, handleEdit }
  102. = useCrud({
  103. name: '文章',
  104. doCreate: api.create,
  105. doDelete: api.delete,
  106. doUpdate: api.update,
  107. initForm: { enable: true },
  108. refresh: (_, keepCurrentPage) => $table.value?.handleSearch(keepCurrentPage),
  109. })
  110. const columns = [
  111. { title: '标题名', key: 'title' },
  112. { title: '分类', key: 'category.title' },
  113. { title: '内容', key: 'content' },
  114. {
  115. title: '状态',
  116. key: 'enable',
  117. render: row =>
  118. h(
  119. NSwitch,
  120. {
  121. size: 'small',
  122. rubberBand: false,
  123. value: row.enable,
  124. loading: !!row.enableLoading,
  125. disabled: row.code === 'SUPER_ADMIN',
  126. onUpdateValue: () => handleEnable(row),
  127. },
  128. {
  129. checked: () => '启用',
  130. unchecked: () => '停用',
  131. },
  132. ),
  133. },
  134. {
  135. title: '操作',
  136. key: 'actions',
  137. width: 200,
  138. align: 'center',
  139. fixed: 'right',
  140. render(row) {
  141. return [
  142. h(
  143. NButton,
  144. {
  145. size: 'small',
  146. type: 'primary',
  147. style: 'margin-left: 12px;',
  148. disabled: row.code === 'SUPER_ADMIN',
  149. onClick: () => handleEdit(row),
  150. },
  151. {
  152. default: () => '编辑',
  153. icon: () => h('i', { class: 'i-material-symbols:edit-outline text-14' }),
  154. },
  155. ),
  156. h(
  157. NButton,
  158. {
  159. size: 'small',
  160. type: 'error',
  161. style: 'margin-left: 12px;',
  162. disabled: row.code === 'SUPER_ADMIN',
  163. onClick: () => handleDelete(row.id),
  164. },
  165. {
  166. default: () => '删除',
  167. icon: () => h('i', { class: 'i-material-symbols:delete-outline text-14' }),
  168. },
  169. ),
  170. ]
  171. },
  172. },
  173. ]
  174. async function handleEnable(row) {
  175. row.enableLoading = true
  176. try {
  177. await api.update({ id: row.id, enable: !row.enable })
  178. row.enableLoading = false
  179. $message.success('操作成功')
  180. $table.value?.handleSearch()
  181. }
  182. catch (error) {
  183. console.error(error)
  184. row.enableLoading = false
  185. }
  186. }
  187. const permissionTree = ref([])
  188. api.getAllPermissionTree().then(({ data = [] }) => (permissionTree.value = data))
  189. </script>