From bb8a67886f3ed944ca247efd3d8216de7ee905f5 Mon Sep 17 00:00:00 2001 From: H0nGzA1 <2505811377@qq.com> Date: Mon, 20 Feb 2023 18:02:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E7=99=BD=E5=90=8D?= =?UTF-8?q?=E5=8D=95):=20=E2=9C=A8=20=E6=8E=A5=E5=8F=A3=E7=99=BD=E5=90=8D?= =?UTF-8?q?=E5=8D=95crud=EF=BC=8C=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/utils/service.ts | 257 +++++++++--------- web/src/views/system/apiWhiteList/curd.tsx | 222 --------------- web/src/views/system/whiteList/api.ts | 41 +++ web/src/views/system/whiteList/crud.tsx | 184 +++++++++++++ .../{apiWhiteList => whiteList}/index.vue | 11 +- 5 files changed, 357 insertions(+), 358 deletions(-) delete mode 100644 web/src/views/system/apiWhiteList/curd.tsx create mode 100644 web/src/views/system/whiteList/api.ts create mode 100644 web/src/views/system/whiteList/crud.tsx rename web/src/views/system/{apiWhiteList => whiteList}/index.vue (67%) diff --git a/web/src/utils/service.ts b/web/src/utils/service.ts index b9685b5..42bdf57 100644 --- a/web/src/utils/service.ts +++ b/web/src/utils/service.ts @@ -1,120 +1,124 @@ -import axios from "axios"; -import { get } from "lodash-es"; +import axios from 'axios'; +import { get } from 'lodash-es'; // @ts-ignore -import { errorLog, errorCreate } from "./tools.ts"; +import { errorLog, errorCreate } from './tools.ts'; // import { env } from "/src/utils/util.env"; // import { useUserStore } from "../store/modules/user"; import { Local, Session } from '/@/utils/storage'; -import qs from "qs"; +import qs from 'qs'; /** * @description 创建请求实例 */ function createService() { - // 创建一个 axios 实例 - const service = axios.create({ - timeout: 20000, - paramsSerializer: { - serialize(params) { - return qs.stringify(params, { allowDots: true }); - }, - }, - }); - // 请求拦截 - service.interceptors.request.use( - (config) => config, - (error) => { - // 发送失败 - console.log(error); - return Promise.reject(error); - } - ); - // 响应拦截 - service.interceptors.response.use( - (response) => { - if (response.config.responseType === "blob") { - return response; - } - // dataAxios 是 axios 返回数据中的 data - const dataAxios = response.data; - // 这个状态码是和后端约定的 - const { code } = dataAxios; - // 根据 code 进行判断 - if (code === undefined) { - // 如果没有 code 代表这不是项目后端开发的接口 - errorCreate(`非标准返回:${dataAxios}, ${response.config.url}`,false); - return dataAxios; - } else { - // 有 code 代表这是一个后端接口 可以进行进一步的判断 - switch (code) { - case 401: - Local.clear(); - Session.clear(); - window.location.reload(); - dataAxios.msg = "登录授权过期,请重新登录"; - errorCreate(`${dataAxios.msg}: ${response.config.url}`); - break - case 2000: - // @ts-ignore - if (response.config.unpack === false) { - //如果不需要解包 - return dataAxios; - } - return dataAxios; - default: - // 不是正确的 code - errorCreate(`${dataAxios.msg}: ${response.config.url}`); - return dataAxios; - } - } - }, - (error) => { - const status = get(error, "response.status"); - switch (status) { - case 400: - error.message = "请求错误"; - break; - case 401: - error.message = "未授权,请登录"; - break; - case 403: - error.message = "拒绝访问"; - break; - case 404: - error.message = `请求地址出错: ${error.response.config.url}`; - break; - case 408: - error.message = "请求超时"; - break; - case 500: - error.message = "服务器内部错误"; - break; - case 501: - error.message = "服务未实现"; - break; - case 502: - error.message = "网关错误"; - break; - case 503: - error.message = "服务不可用"; - break; - case 504: - error.message = "网关超时"; - break; - case 505: - error.message = "HTTP版本不受支持"; - break; - default: - break; - } - errorLog(error); - if (status === 401) { - // const userStore = useUserStore(); - // userStore.logout(); - } - return Promise.reject(error); - } - ); - return service; + // 创建一个 axios 实例 + const service = axios.create({ + timeout: 20000, + paramsSerializer: { + serialize(params) { + return qs.stringify(params, { allowDots: true }); + }, + }, + }); + // 请求拦截 + service.interceptors.request.use( + (config) => config, + (error) => { + // 发送失败 + console.log(error); + return Promise.reject(error); + } + ); + // 响应拦截 + service.interceptors.response.use( + (response) => { + if (response.config.responseType === 'blob') { + return response; + } + // dataAxios 是 axios 返回数据中的 data + const dataAxios = response.data; + // 这个状态码是和后端约定的 + const { code } = dataAxios; + // swagger判断 + if (dataAxios.swagger != undefined) { + return dataAxios; + } + // 根据 code 进行判断 + if (code === undefined) { + // 如果没有 code 代表这不是项目后端开发的接口 + errorCreate(`非标准返回:${dataAxios}, ${response.config.url}`, false); + return dataAxios; + } else { + // 有 code 代表这是一个后端接口 可以进行进一步的判断 + switch (code) { + case 401: + Local.clear(); + Session.clear(); + window.location.reload(); + dataAxios.msg = '登录授权过期,请重新登录'; + errorCreate(`${dataAxios.msg}: ${response.config.url}`); + break; + case 2000: + // @ts-ignore + if (response.config.unpack === false) { + //如果不需要解包 + return dataAxios; + } + return dataAxios; + default: + // 不是正确的 code + errorCreate(`${dataAxios.msg}: ${response.config.url}`); + return dataAxios; + } + } + }, + (error) => { + const status = get(error, 'response.status'); + switch (status) { + case 400: + error.message = '请求错误'; + break; + case 401: + error.message = '未授权,请登录'; + break; + case 403: + error.message = '拒绝访问'; + break; + case 404: + error.message = `请求地址出错: ${error.response.config.url}`; + break; + case 408: + error.message = '请求超时'; + break; + case 500: + error.message = '服务器内部错误'; + break; + case 501: + error.message = '服务未实现'; + break; + case 502: + error.message = '网关错误'; + break; + case 503: + error.message = '服务不可用'; + break; + case 504: + error.message = '网关超时'; + break; + case 505: + error.message = 'HTTP版本不受支持'; + break; + default: + break; + } + errorLog(error); + if (status === 401) { + // const userStore = useUserStore(); + // userStore.logout(); + } + return Promise.reject(error); + } + ); + return service; } /** @@ -122,24 +126,24 @@ function createService() { * @param {Object} service axios 实例 */ function createRequestFunction(service: any) { - return function (config: any) { - const configDefault = { - headers: { - "Content-Type": get(config, "headers.Content-Type", "application/json") - }, - timeout: 5000, - baseURL: import.meta.env.VITE_API_URL as any, - data: {} - }; + return function (config: any) { + const configDefault = { + headers: { + 'Content-Type': get(config, 'headers.Content-Type', 'application/json'), + }, + timeout: 5000, + baseURL: import.meta.env.VITE_API_URL as any, + data: {}, + }; - // const token = userStore.getToken; - const token = Session.get('token') - if (token != null) { - // @ts-ignore - configDefault.headers.Authorization = 'JWT ' + token; - } - return service(Object.assign(configDefault, config)); - }; + // const token = userStore.getToken; + const token = Session.get('token'); + if (token != null) { + // @ts-ignore + configDefault.headers.Authorization = 'JWT ' + token; + } + return service(Object.assign(configDefault, config)); + }; } // 用于真实网络请求的实例和请求方法 @@ -149,4 +153,3 @@ export const request = createRequestFunction(service); // 用于模拟网络请求的实例和请求方法 export const serviceForMock = createService(); export const requestForMock = createRequestFunction(serviceForMock); - diff --git a/web/src/views/system/apiWhiteList/curd.tsx b/web/src/views/system/apiWhiteList/curd.tsx deleted file mode 100644 index 87d8757..0000000 --- a/web/src/views/system/apiWhiteList/curd.tsx +++ /dev/null @@ -1,222 +0,0 @@ -import { CrudExpose, CrudOptions, AddReq, DelReq, EditReq, dict } from '@fast-crud/fast-crud'; -import _ from 'lodash-es'; -import {h} from 'vue'; -import {tabBarProps} from "element-plus"; -interface CreateCrudOptionsTypes { - crudOptions: CrudOptions; -} - -//此处为crudOptions配置 -export const createCrudOptions = function ({crudExpose}: {crudExpose: CrudExpose}): CreateCrudOptionsTypes { - //本地模拟后台crud接口方法 ----开始 - const records = [ - { - id: 1, - modifier_name: '超级管理员', - creator_name: '超级管理员', - create_datetime: '2022-05-24 13:43:21', - update_datetime: '2022-05-31 02:09:01', - description: 'null1111111', - modifier: '1', - dept_belong_id: '1', - url: '/api/system/dept_lazy_tree/', - method: 0, - enable_datasource: true, - creator: 1, - }, - { - id: 2, - modifier_name: '超级管理员', - creator_name: '超级管理员', - create_datetime: '2022-05-24 13:43:21', - update_datetime: '2022-05-31 02:09:01', - description: 'null22222', - modifier: '1', - dept_belong_id: '1', - url: '/api/system/dept_lazy_tree/', - method: 3, - enable_datasource: false, - creator: 1, - }, - ]; - const pageRequest = async (query: any) => { - return { - records, - currentPage: 1, - pageSize: 20, - total: records.length, - }; - }; - const editRequest = async (req: EditReq) => { - const target = _.find(records, (item) => { - return req.row.id === item.id; - }); - _.merge(target, req.form); - return target; - }; - const delRequest = async (req: DelReq) => { - _.remove(records, (item) => { - return item.id === req.row.id; - }); - }; - - const addRequest = async (req: AddReq) => { - const maxRecord = _.maxBy(records, (item) => { - return item.id; - }); - req.form.id = (maxRecord?.id || 0) + 1; - records.push(req.form); - return req.form; - }; - //本地模拟后台crud接口方法 ----结束 - return { - crudOptions: { - request: { - pageRequest, - addRequest, - editRequest, - delRequest, - }, - rowHandle: { - buttons: { - view: { show: false }, - }, - }, - form: { - labelWidth: '120px', - wrapper: { - is: 'el-dialog', - width: '600px', - }, - }, - columns: { - _index: { - title: '序号', - form: { show: false }, - column: { - //type: 'index', - align: 'center', - width: '70px', - columnSetDisabled: true, //禁止在列设置中选择 - formatter: (context) => { - //计算序号,你可以自定义计算规则,此处为翻页累加 - let index = context.index ?? 1; - let pagination = crudExpose.crudBinding.value.pagination; - return ((pagination.currentPage ?? 1) - 1) * pagination.pageSize + index + 1; - }, - }, - }, - search: { - title: '关键词', - column: { show: false }, - type: 'text', - search: { show: true }, - form: { - show: false, - component: { - placeholder: '输入关键词搜索', - }, - }, - }, - id: { - title: 'ID', - type: 'text', - column: { show: false }, - search: { show: false }, - form: { show: false }, - }, - method: { - title: '请求方式', - type: 'dict-select', - search: { show: true }, - dict: dict({ - data: [ - { - label: 'GET', - value: 0, - color: null, - }, - { - label: 'POST', - value: 1, - color: null, - }, - { - label: 'PUT', - value: 2, - color: null, - }, - { - label: 'DELETE', - value: 3, - color: null, - }, - ], - }), - form: { - component: { - maxlength: 20, - }, - }, - column: { - sortable: true, - }, - }, - url: { - title: '接口地址', - type: 'text', - search: { show: false }, - form: { - col: { span: 24 }, - helper: { - render() { - return 请正确填写,以免请求时被拦截。匹配单例使用正则,例如:/api/xx/.*?/ - }, - }, - component: { - maxlength: 20, - }, - }, - column: { - sortable: true, - }, - }, - enable_datasource: { - title: '数据权限认证', - search: { show: true }, - type: 'dict-radio', - dict: dict({ - data: [ - { - label: '启用', - value: true, - color: 'success', - }, - { - label: '禁用', - value: false, - color: 'danger', - }, - ], - }), - form: { - component: { - maxlength: 20, - }, - }, - }, - description: { - title: '备注', - type: 'textarea', - search: { show: false }, - form: { - col: { span: 24 }, - component: { - maxlength: 200, - }, - }, - }, - }, - }, - }; -}; diff --git a/web/src/views/system/whiteList/api.ts b/web/src/views/system/whiteList/api.ts new file mode 100644 index 0000000..f4653df --- /dev/null +++ b/web/src/views/system/whiteList/api.ts @@ -0,0 +1,41 @@ +import { request } from '/@/utils/service'; +import { PageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud'; + +export const apiPrefix = '/api/system/api_white_list/'; +export function GetList(query: PageQuery) { + return request({ + url: apiPrefix, + method: 'get', + data: query, + }); +} +export function GetObj(id: InfoReq) { + return request({ + url: apiPrefix + id, + method: 'get', + }); +} + +export function AddObj(obj: AddReq) { + return request({ + url: apiPrefix, + method: 'post', + data: obj, + }); +} + +export function UpdateObj(obj: EditReq) { + return request({ + url: apiPrefix + obj.id + '/', + method: 'put', + data: obj, + }); +} + +export function DelObj(id: DelReq) { + return request({ + url: apiPrefix + id + '/', + method: 'delete', + data: { id }, + }); +} diff --git a/web/src/views/system/whiteList/crud.tsx b/web/src/views/system/whiteList/crud.tsx new file mode 100644 index 0000000..b7109a3 --- /dev/null +++ b/web/src/views/system/whiteList/crud.tsx @@ -0,0 +1,184 @@ +import * as api from './api'; +import { dict, PageQuery, AddReq, DelReq, EditReq, CrudExpose, CrudOptions } from '@fast-crud/fast-crud'; +import { request } from '/@/utils/service'; +import { dictionary } from '/@/utils/dictionary'; +interface CreateCrudOptionsTypes { + crudOptions: CrudOptions; +} + +export const createCrudOptions = function ({ crudExpose }: { crudExpose: CrudExpose }): CreateCrudOptionsTypes { + const pageRequest = async (query: PageQuery) => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + return await api.UpdateObj(form); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + const addRequest = async ({ form }: AddReq) => { + return await api.AddObj(form); + }; + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest, + }, + columns: { + _index: { + title: '序号', + form: { show: false }, + column: { + //type: 'index', + align: 'center', + width: '70px', + columnSetDisabled: true, //禁止在列设置中选择 + formatter: (context) => { + //计算序号,你可以自定义计算规则,此处为翻页累加 + let index = context.index ?? 1; + let pagination = crudExpose.crudBinding.value.pagination; + return ((pagination.currentPage ?? 1) - 1) * pagination.pageSize + index + 1; + }, + }, + }, + search: { + title: '关键词', + column: { + show: false, + }, + search: { + show: true, + component: { + props: { + clearable: true, + }, + placeholder: '请输入关键词', + }, + }, + form: { + show: false, + component: { + props: { + clearable: true, + }, + }, + }, + }, + method: { + title: '请求方式', + sortable: true, + search: { + disabled: false, + }, + type: 'dict-select', + dict: dict({ + data: [ + { + label: 'GET', + value: 0, + }, + { + label: 'POST', + value: 1, + }, + { + label: 'PUT', + value: 2, + }, + { + label: 'DELETE', + value: 3, + }, + ], + }), + form: { + rules: [ + // 表单校验规则 + { + required: true, + message: '必填项', + }, + ], + component: { + span: 12, + }, + itemProps: { + class: { yxtInput: true }, + }, + }, + }, + url: { + title: '接口地址', + sortable: true, + search: { + disabled: true, + }, + type: 'dict-select', + dict: dict({ + async getData(dict: any) { + return request('/swagger.json').then((ret: any) => { + const res = Object.keys(ret.paths); + const data = []; + for (const item of res) { + const obj = { label: '', value: '' }; + obj.label = item; + obj.value = item; + data.push(obj); + } + return data; + }); + }, + }), + form: { + rules: [ + // 表单校验规则 + { + required: true, + message: '必填项', + }, + ], + component: { + span: 24, + props: { + elProps: { + allowCreate: true, + filterable: true, + clearable: true, + }, + }, + }, + itemProps: { + class: { yxtInput: true }, + }, + helper: { + render(h) { + return ; + }, + }, + }, + }, + enable_datasource: { + title: '数据权限认证', + search: { + disabled: false, + }, + width: 150, + type: 'dict-radio', + dict: dict({ + data: dictionary('button_status_bool'), + }), + form: { + value: true, + component: { + span: 12, + }, + }, + }, + }, + }, + }; +}; diff --git a/web/src/views/system/apiWhiteList/index.vue b/web/src/views/system/whiteList/index.vue similarity index 67% rename from web/src/views/system/apiWhiteList/index.vue rename to web/src/views/system/whiteList/index.vue index d2ff9e0..1fa8634 100644 --- a/web/src/views/system/apiWhiteList/index.vue +++ b/web/src/views/system/whiteList/index.vue @@ -1,18 +1,13 @@