index.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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 ref="$table" v-model:query-items="queryItems" :scroll-x="1200" :columns="columns" :get-data="api.read">
  10. <MeQueryItem label="标题" :label-width="50">
  11. <n-input v-model:value="queryItems.title" type="text" placeholder="请输入标题" clearable>
  12. <template #password-visible-icon />
  13. </n-input>
  14. </MeQueryItem>
  15. <MeQueryItem label="状态" :label-width="50">
  16. <n-select
  17. v-model:value="queryItems.enable" clearable :options="[
  18. { label: '启用', value: 1 },
  19. { label: '停用', value: 0 },
  20. ]"
  21. />
  22. </MeQueryItem>
  23. </MeCrud>
  24. </CommonPage>
  25. </template>
  26. <script setup>
  27. import { MeCrud, MeQueryItem } from '@/components'
  28. import { useCrud } from '@/composables'
  29. import { formatDateTime } from '@/utils'
  30. import { NButton, NSwitch } from 'naive-ui'
  31. import api from './api'
  32. defineOptions({ name: 'RoleMgt' })
  33. const router = useRouter()
  34. const $table = ref(null)
  35. /** QueryBar筛选参数(可选) */
  36. const queryItems = ref({})
  37. onMounted(() => {
  38. $table.value?.handleSearch()
  39. })
  40. const { handleDelete }
  41. = useCrud({
  42. name: '文章',
  43. doCreate: api.create,
  44. doDelete: api.delete,
  45. doUpdate: api.update,
  46. initForm: { enable: true },
  47. refresh: (_, keepCurrentPage) => $table.value?.handleSearch(keepCurrentPage),
  48. })
  49. const columns = [
  50. { title: 'ID', key: 'id', width: '80' },
  51. { title: '标题', key: 'title', width: '200' },
  52. { title: '分类', key: 'category.title' },
  53. {
  54. title: '内容',
  55. key: 'content',
  56. width: '400',
  57. render: row => h('div', htmlspecialchars(row.translations?.length ? row.translations.find(i => i.locale === 'zh').content : row.content)),
  58. },
  59. { title: '创建人', key: 'user.username' },
  60. {
  61. title: '创建时间',
  62. key: 'createTime',
  63. render: row => h('span', formatDateTime(row.createTime)),
  64. },
  65. {
  66. title: '状态',
  67. key: 'enable',
  68. render: row =>
  69. h(
  70. NSwitch,
  71. {
  72. size: 'small',
  73. rubberBand: false,
  74. value: row.enable,
  75. loading: !!row.enableLoading,
  76. disabled: row.code === 'SUPER_ADMIN',
  77. onUpdateValue: () => handleEnable(row),
  78. },
  79. {
  80. checked: () => '启用',
  81. unchecked: () => '停用',
  82. },
  83. ),
  84. },
  85. {
  86. title: '操作',
  87. key: 'actions',
  88. width: 200,
  89. align: 'center',
  90. fixed: 'right',
  91. render(row) {
  92. return [
  93. h(
  94. NButton,
  95. {
  96. size: 'small',
  97. type: 'primary',
  98. style: 'margin-left: 12px;',
  99. disabled: row.code === 'SUPER_ADMIN',
  100. onClick: () => handleEdit(row),
  101. },
  102. {
  103. default: () => '编辑',
  104. icon: () => h('i', { class: 'i-material-symbols:edit-outline text-14' }),
  105. },
  106. ),
  107. h(
  108. NButton,
  109. {
  110. size: 'small',
  111. type: 'error',
  112. style: 'margin-left: 12px;',
  113. disabled: row.code === 'SUPER_ADMIN',
  114. onClick: () => handleDelete(row.id),
  115. },
  116. {
  117. default: () => '删除',
  118. icon: () => h('i', { class: 'i-material-symbols:delete-outline text-14' }),
  119. },
  120. ),
  121. ]
  122. },
  123. },
  124. ]
  125. async function handleEnable(row) {
  126. row.enableLoading = true
  127. try {
  128. console.log('row', row)
  129. await api.update({ ...row, id: row.id, enable: !row.enable })
  130. row.enableLoading = false
  131. $message.success('操作成功')
  132. $table.value?.handleSearch()
  133. }
  134. catch (error) {
  135. console.error(error)
  136. row.enableLoading = false
  137. }
  138. }
  139. function htmlspecialchars(str) {
  140. const div = document.createElement('div')
  141. div.innerHTML = str
  142. const text = div.textContent || ''
  143. return text.length > 150 ? `${text.substring(0, 150)}...` : text
  144. }
  145. function handleEdit(row) {
  146. router.push(`/article/edit/${row.id}`)
  147. }
  148. </script>