SysConfig.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <template>
  2. <div class="sys-config admin-page">
  3. <div class="header admin-page-header">
  4. <h2 class="admin-page-title">系统配置</h2>
  5. <div class="flex items-center gap-sm">
  6. <el-input v-model="keyword" placeholder="搜索配置..." prefix-icon="el-icon-search" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
  7. <el-button type="primary" size="small" @click="addConfig" icon="el-icon-plus">新增配置</el-button>
  8. </div>
  9. </div>
  10. <el-table :data="list" v-loading="loading" border stripe :max-height="tableHeight">
  11. <el-table-column prop="configKey" label="配置键" min-width="200" show-overflow-tooltip />
  12. <el-table-column prop="configValue" label="配置值" min-width="250" show-overflow-tooltip />
  13. <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
  14. <el-table-column label="类型" width="90">
  15. <template slot-scope="{ row }">
  16. {{ typeLabel(row.valueType) }}
  17. </template>
  18. </el-table-column>
  19. <el-table-column label="操作" width="200" fixed="right">
  20. <template slot-scope="{ row }">
  21. <el-button size="mini" type="primary" @click="editConfig(row)">编辑</el-button>
  22. <el-dropdown trigger="hover" @command="(cmd) => handleActionCmd(row, cmd)">
  23. <el-button size="mini">
  24. 更多<i class="el-icon-arrow-down el-icon--right"></i>
  25. </el-button>
  26. <el-dropdown-menu slot="dropdown">
  27. <el-dropdown-item command="delete" icon="el-icon-delete">删除</el-dropdown-item>
  28. </el-dropdown-menu>
  29. </el-dropdown>
  30. </template>
  31. </el-table-column>
  32. </el-table>
  33. <el-pagination
  34. @size-change="onSizeChange"
  35. @current-change="onPageChange"
  36. :current-page="page"
  37. :page-size="size"
  38. :total="total"
  39. layout="total, prev, pager, next"
  40. class="pagination-wrap"
  41. />
  42. <!-- 编辑弹窗 -->
  43. <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px" :close-on-click-modal="false">
  44. <el-form :model="form" :rules="rules" ref="form" label-width="100px">
  45. <el-form-item label="配置键" prop="configKey">
  46. <el-input v-model="form.configKey" :disabled="!!form.id" placeholder="如: shop.welcome.banner" />
  47. </el-form-item>
  48. <el-form-item label="配置值" prop="configValue">
  49. <el-input v-if="form.valueType === 'text'" v-model="form.configValue" type="textarea" :rows="3" placeholder="配置值" />
  50. <el-input v-else v-model="form.configValue" placeholder="配置值" />
  51. </el-form-item>
  52. <el-form-item label="描述" prop="description">
  53. <el-input v-model="form.description" placeholder="配置项描述" />
  54. </el-form-item>
  55. <el-form-item label="值类型" prop="valueType">
  56. <el-select v-model="form.valueType" style="width: 100%;">
  57. <el-option label="字符串" value="string" />
  58. <el-option label="数字" value="number" />
  59. <el-option label="布尔值" value="boolean" />
  60. <el-option label="多行文本" value="text" />
  61. </el-select>
  62. </el-form-item>
  63. </el-form>
  64. <span slot="footer">
  65. <el-button @click="dialogVisible = false">取消</el-button>
  66. <el-button type="primary" @click="confirmSave" :loading="submitting">保存</el-button>
  67. </span>
  68. </el-dialog>
  69. </div>
  70. </template>
  71. <script>
  72. import { getSysConfigList, createSysConfig, updateSysConfig, deleteSysConfig } from '@/api/admin'
  73. export default {
  74. name: 'SysConfig',
  75. computed: {
  76. tableHeight() {
  77. return window.innerHeight - 300
  78. }
  79. },
  80. data() {
  81. return {
  82. list: [],
  83. loading: false,
  84. page: 1,
  85. size: 20,
  86. total: 0,
  87. dialogVisible: false,
  88. dialogTitle: '新增配置',
  89. submitting: false,
  90. form: {
  91. id: null,
  92. configKey: '',
  93. configValue: '',
  94. description: '',
  95. valueType: 'string'
  96. },
  97. keyword: '',
  98. rules: {
  99. configKey: [{ required: true, message: '请输入配置键', trigger: 'blur' }],
  100. configValue: [{ required: true, message: '请输入配置值', trigger: 'blur' }]
  101. }
  102. }
  103. },
  104. mounted() {
  105. this.loadList()
  106. },
  107. methods: {
  108. async loadList() {
  109. this.loading = true
  110. try {
  111. const res = await getSysConfigList({ keyword: this.keyword || undefined })
  112. this.list = res.data || []
  113. this.total = (res.data || []).length
  114. } catch (e) {
  115. this.$message.error('加载失败')
  116. } finally {
  117. this.loading = false
  118. }
  119. },
  120. handleSearch() {
  121. this.page = 1
  122. this.loadList()
  123. },
  124. onSizeChange(val) {
  125. this.size = val
  126. this.page = 1
  127. this.loadList()
  128. },
  129. onPageChange(val) {
  130. this.page = val
  131. this.loadList()
  132. },
  133. typeLabel(type) {
  134. const map = { string: '字符串', number: '数字', boolean: '布尔值', text: '多行文本' }
  135. return map[type] || type
  136. },
  137. addConfig() {
  138. this.form = { id: null, configKey: '', configValue: '', description: '', valueType: 'string' }
  139. this.dialogTitle = '新增配置'
  140. this.dialogVisible = true
  141. },
  142. editConfig(row) {
  143. this.form = { ...row }
  144. this.dialogTitle = '编辑配置'
  145. this.dialogVisible = true
  146. },
  147. async confirmSave() {
  148. const valid = await this.$refs.form.validate().catch(() => false)
  149. if (!valid) return
  150. this.submitting = true
  151. try {
  152. if (this.form.id) {
  153. await updateSysConfig(this.form.id, this.form)
  154. } else {
  155. await createSysConfig(this.form)
  156. }
  157. this.$message.success('保存成功')
  158. this.dialogVisible = false
  159. this.loadList()
  160. } catch (e) {
  161. this.$message.error('保存失败')
  162. } finally {
  163. this.submitting = false
  164. }
  165. },
  166. async deleteConfig(row) {
  167. try {
  168. await this.$confirm(`确认删除配置「${row.configKey}」?`, '警告', { type: 'warning' })
  169. await deleteSysConfig(row.id)
  170. this.$message.success('删除成功')
  171. this.loadList()
  172. } catch (e) {
  173. if (e !== 'cancel') this.$message.error('删除失败')
  174. }
  175. },
  176. handleActionCmd(row, cmd) {
  177. switch (cmd) {
  178. case 'delete':
  179. this.deleteConfig(row)
  180. break
  181. }
  182. }
  183. }
  184. }
  185. </script>
  186. <style scoped>
  187. .sys-config {
  188. padding: 20px;
  189. }
  190. </style>