index.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <template>
  2. <div class="main animate__animated animate__backInRight">
  3. <custom-search-bar
  4. v-model="searchForm"
  5. :fields="fields.filter((f) => f.filter)"
  6. @search="search"
  7. @reset="toReset"
  8. ></custom-search-bar>
  9. <custom-table
  10. :data="data"
  11. :fields="fields"
  12. @search="search"
  13. :total="total"
  14. :opera="opera"
  15. @view="toView"
  16. @exam="toExam"
  17. @delete="toDelete"
  18. >
  19. <template #role="{ row }">
  20. <div class="tags">
  21. <el-tag type="primary">{{ getRole(row.role) }}</el-tag>
  22. </div>
  23. </template>
  24. </custom-table>
  25. <el-dialog
  26. v-model="dialog.show"
  27. :title="dialog.title"
  28. :destroy-on-close="false"
  29. @close="toClose"
  30. >
  31. <el-row>
  32. <el-col :span="24" v-if="dialog.type == '1'">
  33. <user></user>
  34. </el-col>
  35. <el-col :span="24" v-if="dialog.type == '2'">
  36. <custom-form
  37. v-model="examForm"
  38. :fields="examFormFields"
  39. :rules="examRules"
  40. @save="toExamSave"
  41. >
  42. <template #status>
  43. <el-option
  44. v-for="i in statusList"
  45. :key="i._id"
  46. :label="i.label"
  47. :value="i.value"
  48. ></el-option>
  49. </template>
  50. </custom-form>
  51. </el-col>
  52. </el-row>
  53. </el-dialog>
  54. </div>
  55. </template>
  56. <script setup>
  57. // 组件
  58. import user from './parts/user.vue'
  59. // API 引用
  60. import { StudentStore } from '@/store/api/user/student'
  61. import { RoleStore } from '@/store/api/system/role'
  62. import { DictDataStore } from '@/store/api/system/dictData'
  63. import { cloneDeep, get } from 'lodash-es'
  64. const $checkRes = inject('$checkRes')
  65. const store = StudentStore()
  66. const dictDataStore = DictDataStore()
  67. const roleStore = RoleStore()
  68. const { t } = useI18n()
  69. const loading = ref(false)
  70. let skip = 0
  71. let limit = inject('limit')
  72. const data = ref([])
  73. const total = ref(0)
  74. onMounted(async () => {
  75. loading.value = true
  76. await searchOther()
  77. await search({ skip, limit })
  78. loading.value = false
  79. })
  80. const fields = [
  81. { label: t('pages.user.account'), model: 'account', filter: true },
  82. { label: t('pages.user.nick_name'), model: 'nick_name', filter: true },
  83. { label: t('pages.user.email'), model: 'email' },
  84. { label: t('pages.user.phone'), model: 'phone', filter: true },
  85. { label: t('pages.user.role'), model: 'role', custom: true },
  86. { label: t('pages.user.status'), model: 'status', format: (i) => getDict(i) }
  87. ]
  88. const opera = [
  89. { label: t('common.view'), method: 'view' },
  90. { label: t('common.exam'), method: 'exam', type: 'warning', display: (i) => i.status === '0' },
  91. {
  92. label: t('common.delete'),
  93. method: 'delete',
  94. confirm: true,
  95. type: 'danger'
  96. }
  97. ]
  98. const searchForm = ref({})
  99. const dialog = ref({ type: '1', show: false, title: t('pages.user.dialogTitle') })
  100. // 查询
  101. const search = async (query = { skip: 0, limit }) => {
  102. const info = { skip: query.skip, limit: query.limit, ...searchForm.value }
  103. const res = await store.query(info)
  104. if (res.errcode == '0') {
  105. data.value = res.data
  106. total.value = res.total
  107. }
  108. }
  109. // 表单验证
  110. const ruleFormRef = ref()
  111. const form = ref({})
  112. // 审核
  113. const examFormFields = [{ label: t('pages.user.status'), model: 'status', type: 'select' }]
  114. const examRules = reactive({
  115. status: [{ required: true, message: t('common.statusMessage'), trigger: 'blur' }]
  116. })
  117. const examForm = ref({})
  118. // 字典表
  119. const statusList = ref([])
  120. const roleList = ref([])
  121. const genderList = ref([])
  122. const searchOther = async () => {
  123. let result
  124. // 状态
  125. result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
  126. if ($checkRes(result)) statusList.value = result.data
  127. // 性别
  128. result = await dictDataStore.query({ code: 'gender', is_use: '0' })
  129. if ($checkRes(result)) genderList.value = result.data
  130. // 角色
  131. result = await roleStore.query({ is_use: '0' })
  132. if ($checkRes(result)) roleList.value = result.data
  133. }
  134. const toDelete = async (data) => {
  135. const res = await store.del(data._id)
  136. if ($checkRes(res, true)) {
  137. search({ skip: 0, limit })
  138. }
  139. }
  140. const getRole = (data) => {
  141. const res = roleList.value.find((f) => f.code === data)
  142. return get(res, 'name')
  143. }
  144. const getDict = (data) => {
  145. const res = statusList.value.find((f) => f.value == data)
  146. return get(res, 'label')
  147. }
  148. // 查看
  149. const toView = async (data) => {
  150. form.value = data
  151. dialog.value = { type: '1', show: true, title: t('pages.user.dialogTitle') }
  152. }
  153. // 审核
  154. const toExam = (data) => {
  155. examForm.value = data
  156. dialog.value = { type: '2', show: true, title: t('pages.user.examDialogTitle') }
  157. }
  158. // 审核保存
  159. const toExamSave = async () => {
  160. const data = cloneDeep(examForm.value)
  161. let res = await store.update(data)
  162. if ($checkRes(res, true)) {
  163. search({ skip: 0, limit })
  164. toClose()
  165. }
  166. }
  167. const toClose = () => {
  168. form.value = {}
  169. dialog.value = { show: false }
  170. }
  171. // 重置
  172. const toReset = async () => {
  173. searchForm.value = {}
  174. await search({ skip, limit })
  175. }
  176. // provide
  177. provide('cloneDeep', cloneDeep)
  178. provide('ruleFormRef ', ruleFormRef)
  179. provide('form', form)
  180. // 字典
  181. provide('statusList', statusList)
  182. provide('genderList', genderList)
  183. // 方法
  184. provide('getRole', getRole)
  185. </script>
  186. <style scoped lang="scss">
  187. .tags {
  188. display: flex;
  189. justify-content: center;
  190. grid-gap: 0.5rem;
  191. gap: 0.5rem;
  192. }
  193. </style>