Ver código fonte

feat: 添加系统阐述配置

Gaokun Wang 3 semanas atrás
pai
commit
db6379560a

+ 4 - 0
.env.development

@@ -26,3 +26,7 @@ VITE_PROXY = [["/dev-api","http://localhost:9040"]]
 # Optional: hash | history
 VITE_ROUTER_MODE = hash
 
+# 客户端id
+VITE_APP_CLIENT_ID = '7daa6e9b-8876-4918-8a12-b68cbfcdc680'
+
+

+ 4 - 1
.env.production

@@ -15,4 +15,7 @@ VITE_USE_MOCK = false
 
 # 路由模式
 # Optional: hash | history
-VITE_ROUTER_MODE = hash
+VITE_ROUTER_MODE = hash
+
+# 客户端id
+VITE_APP_CLIENT_ID = '7daa6e9b-8876-4918-8a12-b68cbfcdc680'

+ 37 - 0
src/api/interface/system/config.ts

@@ -0,0 +1,37 @@
+/**
+ * 查询参数
+ */
+export interface ConfigQuery extends PageQuery {
+  name?: string
+  configKey?: string
+  configValue?: string
+  status?: number
+}
+
+/**
+ * 接收后端返回信息
+ */
+export interface ConfigVO extends BaseEntity {
+  configId: number | string
+  name: string
+  configKey: string
+  isLock: string
+  configValue: string
+  category: string
+  orderNum: number
+  remark?: string
+}
+
+/**
+ * 传入后端的表单信息
+ */
+export interface ConfigBo {
+  configId: number | string
+  name: string
+  configKey: string
+  configValue: string
+  category: string
+  orderNum: number
+  status?: string
+  remark?: string
+}

+ 1 - 0
src/api/interface/system/dict.ts

@@ -16,6 +16,7 @@ export interface DictVO extends BaseEntity {
   dictLabel: string
   dictValue: string
   category: string
+  isLock: string
   callbackShowStyle: string
   orderNum: number
   remark?: string

+ 44 - 0
src/api/module/system/config.ts

@@ -0,0 +1,44 @@
+import http from '@/axios'
+import { ConfigBo, ConfigQuery, ConfigVO } from '@/api/interface/system/config'
+
+class ConfigApi {
+  /**
+   * @name 查询分页
+   * @returns returns
+   */
+  static page = (params: ConfigQuery): Promise<ResultData<any>> => {
+    return http.get<ConfigVO>({ url: '/system/config/page', params })
+  }
+
+  /**
+   * @name 查询列表
+   * @returns returns
+   */
+  static list = (params: ConfigBo): Promise<ResultData<any>> => {
+    return http.get<ConfigVO>({ url: '/system/config/list', params })
+  }
+
+  /**
+   * @name 添加
+   * @returns returns
+   */
+  static add = (data: ConfigBo): Promise<ResultData<any>> => {
+    return http.post({ url: '/system/config/add', data })
+  }
+  /**
+   * @name 更新
+   * @returns returns
+   */
+  static edit = (data: ConfigBo): Promise<ResultData<any>> => {
+    return http.post({ url: '/system/config/edit', data })
+  }
+
+  /**
+   * @name 更新
+   * @returns returns
+   */
+  static delete = (data: ConfigBo): Promise<ResultData<any>> => {
+    return http.delete({ url: '/system/config/delete', data })
+  }
+}
+export default ConfigApi

+ 1 - 0
src/axios/config.ts

@@ -7,6 +7,7 @@ const defaultRequestInterceptors = (config: InternalAxiosRequestConfig) => {
   const userStore = useUserStoreWithOut()
   if (config.headers && typeof config.headers.set === 'function') {
     config.headers.set('Authorization', 'Bearer ' + userStore.token)
+    config.headers.set('clientId', import.meta.env.VITE_APP_CLIENT_ID)
   }
   return config
 }

+ 1 - 0
src/types/auto-components.d.ts

@@ -17,6 +17,7 @@ declare module 'vue' {
     AppTools: typeof import('./../layouts/components/AppTools/index.vue')['default']
     AppTransverse: typeof import('./../layouts/container/AppTransverse/index.vue')['default']
     ColSetting: typeof import('./../components/ProTable/ColSetting.vue')['default']
+    ConfigDrawer: typeof import('./../views/system/config/components/ConfigDrawer.vue')['default']
     DictDrawer: typeof import('./../views/system/dict/components/DictDrawer.vue')['default']
     EcoDialog: typeof import('./../components/EcoDialog/index.vue')['default']
     EcoDialogForm: typeof import('./../components/EcoDialogForm/index.vue')['default']

+ 1 - 1
src/views/login/index.vue

@@ -34,7 +34,7 @@ const loginForm = reactive({
   account: 'superadmin',
   password: 'admin123',
   grantType: 'password',
-  clientId: '7daa6e9b-8876-4918-8a12-b68cbfcdc680',
+  clientId: import.meta.env.VITE_APP_CLIENT_ID,
   tenantId: '1'
 })
 

+ 109 - 0
src/views/system/config/components/ConfigDrawer.vue

@@ -0,0 +1,109 @@
+<template>
+  <ElDrawer ref="elDrawerRef" v-model="drawerVisible" :title="drawerProps.title" v-bind="$attrs" destroy-on-close>
+    <template #header="scope">
+      <slot name="header" v-bind="scope">
+        <div style="display: flex">
+          <slot name="title">
+            <span style="flex: 1">{{ drawerProps.title }}</span>
+          </slot>
+        </div>
+      </slot>
+    </template>
+
+    <el-form ref="ruleFormRef" label-width="100px" label-suffix=" :" :rules="rules" :model="drawerProps.row" @submit.enter.prevent="handleConfirm">
+      <el-form-item label="参数名称" prop="name">
+        <el-input v-model="drawerProps.row.name" placeholder="填写参数名称" clearable />
+      </el-form-item>
+      <el-form-item label="参数Key" prop="configKey">
+        <el-input v-model="drawerProps.row.configKey" placeholder="填写参数Key" clearable />
+      </el-form-item>
+      <el-form-item label="参数Value" prop="configValue">
+        <el-input v-model="drawerProps.row.configValue" placeholder="填写参数Value" clearable />
+      </el-form-item>
+      <el-form-item label="排序" prop="orderNum">
+        <el-input-number v-model="drawerProps.row.orderNum" :precision="0" :min="1" :max="999999" />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-radio-group v-model="drawerProps.row.status">
+          <el-radio-button :value="item.dictValue" v-for="(item, index) in commonStatus" :key="index" :label="item.dictLabel" />
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input v-model="drawerProps.row.remark" placeholder="请填写备注" clearable />
+      </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <slot name="footer">
+        <ElButton @click="drawerVisible = false">取 消</ElButton>
+        <ElButton type="primary" @click="handleConfirm()">确 定</ElButton>
+      </slot>
+    </template>
+  </ElDrawer>
+</template>
+
+<script setup lang="ts" name="ConfigForm">
+import { ConfigBo } from '@/api/interface/system/config'
+import { ResultEnum } from '@/enums/HttpEnum'
+import { useDictOptions } from '@/hooks'
+
+const commonStatus = useDictOptions('COMMON_STATUS')
+
+import { FormInstance } from 'element-plus'
+const rules = reactive({
+  name: [{ required: true, message: '请填写参数名称' }],
+  configKey: [{ required: true, message: '请填参数Key' }],
+  configValue: [{ required: true, message: '请填参数Value' }],
+  orderNum: [{ required: true, message: '排序不能为空' }],
+  status: [{ required: true, message: '状态不能为空' }]
+})
+
+interface EcoDrawerProps {
+  api?: (params: any) => Promise<any> // 调用接口
+  title: string // 顶部标题
+  isView: boolean
+  row: Partial<ConfigBo>
+  getTableList?: () => void
+}
+
+const drawerVisible = ref(false)
+const drawerProps = ref<EcoDrawerProps>({
+  isView: false,
+  title: '',
+  row: {}
+})
+
+// emit
+const emit = defineEmits(['submit'])
+
+// 接收父组件传过来的参数
+const acceptParams = (params: EcoDrawerProps) => {
+  drawerProps.value = params
+  drawerVisible.value = true
+}
+
+// 提交数据(新增/编辑)
+const ruleFormRef = ref<FormInstance>()
+const handleConfirm = () => {
+  ruleFormRef.value!.validate(async valid => {
+    if (!valid) return
+    try {
+      const { code } = await drawerProps.value.api!(drawerProps.value.row)
+      if (code == ResultEnum.SUCCESS) {
+        ElMessage.success({ message: `${drawerProps.value.title}成功!` })
+        drawerProps.value.getTableList!()
+        emit('submit')
+        drawerVisible.value = false
+      }
+    } catch (error) {
+      console.log(error)
+    }
+  })
+}
+
+defineExpose({
+  acceptParams
+})
+</script>
+
+<style scoped lang="scss"></style>

+ 88 - 1
src/views/system/config/index.vue

@@ -1,3 +1,90 @@
 <template>
-  <div>系统配置</div>
+  <div class="table-box">
+    <ProTable
+      ref="proTableRef"
+      title="参数配置"
+      row-key="configId"
+      :indent="20"
+      :columns="columns"
+      :search-columns="searchColumns"
+      :request-api="getTableList">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" icon="CirclePlus" @click="openDrawer('新增')"> 新增 </el-button>
+        <el-button type="danger" icon="Delete" plain :disabled="!scope.isSelected" @click="batchDelete(scope.selectedListIds)"> 批量删除 </el-button>
+      </template>
+
+      <template #operation="{ row }">
+        <el-button type="primary" link icon="EditPen" @click="openDrawer('编辑', row)"> 编辑 </el-button>
+        <el-button v-if="row.isLock !== '1'" type="primary" link icon="Delete" @click="deleteRow(row)"> 删除 </el-button>
+      </template>
+    </ProTable>
+    <ConfigDrawer ref="drawerRef" size="40%" />
+  </div>
 </template>
+<script lang="tsx" setup name="ConfigManage">
+import ConfigApi from '@/api/module/system/config'
+import ConfigDrawer from './components/ConfigDrawer.vue'
+import { ColumnProps, ProTableInstance, SearchProps } from '@/components/ProTable/interface'
+import { useDictOptions, useHandleData } from '@/hooks'
+import { ConfigBo, ConfigQuery, ConfigVO } from '@/api/interface/system/config'
+
+const proTableRef = ref<ProTableInstance>()
+
+// 表格配置项
+const columns: ColumnProps<ConfigVO>[] = [
+  { type: 'selection', width: 60, selectable: row => row.isLock !== '1' },
+  { type: 'index', width: 60 },
+  { prop: 'name', label: '参数名称' },
+  { prop: 'configKey', label: '参数Key', tag: true },
+  { prop: 'configValue', label: '参数Value' },
+  {
+    prop: 'status',
+    label: '状态',
+    tag: true,
+    enum: useDictOptions('COMMON_STATUS'),
+    width: 80,
+    fieldNames: { label: 'dictLabel', value: 'dictValue', tagType: 'callbackShowStyle' }
+  },
+  { prop: 'orderNum', label: '排序' },
+  { prop: 'remark', label: '备注' },
+  { prop: 'createByName', label: '创建人' },
+  { prop: 'createTime', label: '创建时间' },
+  { prop: 'operation', label: '操作', width: 250, fixed: 'right' }
+]
+
+// 表格配置项
+const searchColumns: SearchProps[] = [
+  { prop: 'name', label: '参数名称', el: 'input' },
+  { prop: 'configValue', label: '参数Value', el: 'input' }
+]
+
+// 获取table列表
+const getTableList = (params: ConfigQuery) => ConfigApi.page(params)
+
+// 单行删除
+const deleteRow = async (row: ConfigVO) => {
+  await useHandleData(ConfigApi.delete, [row.configId], `删除【${row.configKey}】数据`)
+  proTableRef.value?.getTableList()
+}
+
+// 批量删除信息
+const batchDelete = async (ids: (string | number)[]) => {
+  await useHandleData(ConfigApi.delete, ids, '删除所选数据')
+  proTableRef.value?.clearSelection()
+  proTableRef.value?.getTableList()
+}
+
+// 打开 drawer(新增、查看、编辑)
+const drawerRef = ref<InstanceType<typeof ConfigDrawer> | null>(null)
+const openDrawer = (title: string, row: Partial<ConfigBo> = {}) => {
+  const params = {
+    title,
+    row: { ...row },
+    isView: title === '查看',
+    api: title === '新增' ? ConfigApi.add : title === '编辑' ? ConfigApi.edit : undefined,
+    getTableList: proTableRef.value?.getTableList
+  }
+  drawerRef.value?.acceptParams(params)
+}
+</script>

+ 4 - 6
src/views/system/dict/index.vue

@@ -29,14 +29,12 @@
   </div>
 </template>
 <script lang="tsx" setup name="DIctManage">
-import { RoleInfo, RoleQuery } from '@/api/interface/system/role'
 import DictApi from '@/api/module/system/dict'
 import DictDrawer from './components/DictDrawer.vue'
 import TreeFilter from '@/components/TreeFilter/index.vue'
 import { ColumnProps, ProTableInstance, SearchProps } from '@/components/ProTable/interface'
-import { OrgFormBo } from '@/api/interface/system/org'
 import { useDictOptions, useHandleData } from '@/hooks'
-import { DictVO } from '@/api/interface/system/dict'
+import { DictBo, DictQuery, DictVO } from '@/api/interface/system/dict'
 const initParam = reactive({ dictId: '', parentId: '' })
 
 const selectTreeId = ref<string>('')
@@ -58,7 +56,7 @@ const refreshTree = () => {
 }
 
 // 表格配置项
-const columns: ColumnProps<RoleInfo>[] = [
+const columns: ColumnProps<DictVO>[] = [
   { type: 'selection', width: 60, selectable: row => row.isLock !== '1' },
   { prop: 'dictLabel', label: '字典标签' },
   { prop: 'dictValue', label: '字典值' },
@@ -81,7 +79,7 @@ const columns: ColumnProps<RoleInfo>[] = [
 const searchColumns: SearchProps[] = [{ prop: 'dictLabel', label: '字典标签', el: 'input' }]
 
 // 获取table列表
-const getTableList = (params: RoleQuery) => DictApi.page(params)
+const getTableList = (params: DictQuery) => DictApi.page(params)
 
 // 单行删除
 const deleteRow = async (row: DictVO) => {
@@ -100,7 +98,7 @@ const batchDelete = async (ids: (string | number)[]) => {
 
 // 打开 drawer(新增、查看、编辑)
 const drawerRef = ref<InstanceType<typeof DictDrawer> | null>(null)
-const openDrawer = (title: string, row: Partial<OrgFormBo> = {}) => {
+const openDrawer = (title: string, row: Partial<DictBo> = {}) => {
   const params = {
     title,
     row: title === '新增' ? { parentId: selectTreeId.value } : { ...row },