diff --git a/.env.development b/.env.development index 17faa14..d70fc73 100644 --- a/.env.development +++ b/.env.development @@ -6,5 +6,7 @@ VITE_PUBLIC_PATH = / # 开发环境路由历史模式(Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数") VITE_ROUTER_HISTORY = "hash" - +# 接口地址 VITE_API_BASEURL = "http://localhost:5199/api" +#数据中心后台地址 +VITE_API_USERCENTER_URL = "https://dca.w.23544.com:8843/api/back" diff --git a/src/api/class.ts b/src/api/class.ts new file mode 100644 index 0000000..5589bda --- /dev/null +++ b/src/api/class.ts @@ -0,0 +1,12 @@ +import { http } from "@/utils/http"; +import type { Res } from "@/utils/http/types"; + +/** + * @description 获取所有的菜单 + * @return {object} + */ +export function addClasses(info: any) { + return http.request>("post", `classes/addclass`, { + data: info + }); +} diff --git a/src/api/hTable.ts b/src/api/hTable.ts index 038394e..e097d07 100644 --- a/src/api/hTable.ts +++ b/src/api/hTable.ts @@ -11,13 +11,9 @@ export class hTableAPI { PageList(data = {}) { return http.request>("post", `${this.url}/PageList`, { data }); } - Info(tag = {}) { - const pUrl = `${this.url}/Info`; + Info(tag) { + const pUrl = `${this.url}/${tag}`; let getUrl = pUrl; - for (const key in tag) { - const el = tag[key]; - getUrl += (getUrl === pUrl ? "?" : "&") + key + "=" + el; - } return http.request>("get", getUrl); } edit(data) { diff --git a/src/api/school.ts b/src/api/school.ts index 4891252..1a78add 100644 --- a/src/api/school.ts +++ b/src/api/school.ts @@ -33,5 +33,5 @@ export function getregion(r) { * @return {void} */ export function EditSchool(data: any) { - return http.request>("post", `School/Edit`, { data }); + return http.request>("post", `schools/add`, { data }); } diff --git a/src/components/hTable/hTableEdit.vue b/src/components/hTable/hTableEdit.vue index cd24367..19dce09 100644 --- a/src/components/hTable/hTableEdit.vue +++ b/src/components/hTable/hTableEdit.vue @@ -118,7 +118,7 @@ function fetchFormData() { editData.value.loading = false; if (editData.value.isedit) { handleResetForm(); - Api.Info({ id: props.id }).then(res => { + Api.Info(props.id).then(res => { if (res.code === 200) { editData.value.frorm = res.data; for (const key in column.value) { diff --git a/src/utils/http/index.ts b/src/utils/http/index.ts index bfd306b..49f6eb3 100644 --- a/src/utils/http/index.ts +++ b/src/utils/http/index.ts @@ -13,6 +13,59 @@ import { stringify } from "qs"; import NProgress from "../progress"; import { getToken, formatToken } from "@/utils/auth"; import { useUserStoreHook } from "@/store/modules/user"; +import { string } from "vue-types"; +import router from "@/router"; + +/**请求后端的地址 未配置则访问BaseURL */ +const apiServiceConfig = { + classes: import.meta.env.VITE_API_USERCENTER_URL, + schools: import.meta.env.VITE_API_USERCENTER_URL +}; + +function getAPIUrl(url: string): string { + let token = url.startsWith("/") ? url.split("/")[1] : url.split("/")[0]; + if (apiServiceConfig[token] != null) return apiServiceConfig[token]; + else return import.meta.env.VITE_API_BASEURL; +} + +const snakeToCamel = (str: string): string => { + // 处理蛇形命名(user_id → userId) + let result = str.replace(/_([a-zA-Z0-9])/g, (_, letter) => + letter.toUpperCase() + ); + + // 处理大驼峰命名(UserName → userName) + if (result.length > 0) { + result = result.charAt(0).toLowerCase() + result.slice(1); + } + + // 特殊场景:处理连续下划线(__type → Type) + result = result.replace(/^_+/, ""); + + return result; +}; + +/** + * 递归转换对象/数组的键名为小驼峰格式 + */ +const convertKeysToCamelCase = (data: any): T => { + if (Array.isArray(data)) { + return data.map(item => convertKeysToCamelCase(item)) as unknown as T; + } + + if (data !== null && typeof data === "object") { + return Object.keys(data).reduce((result, key) => { + const camelKey = snakeToCamel(key); + const value = data[key]; + return { + ...result, + [camelKey]: convertKeysToCamelCase(value) + }; + }, {}) as T; + } + + return data as T; +}; // 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1 const defaultConfig: AxiosRequestConfig = { @@ -64,6 +117,9 @@ class PureHttp { async (config: PureHttpRequestConfig): Promise => { // 开启进度条动画 NProgress.start(); + if (config.url.indexOf("http") === -1) { + config.baseURL = getAPIUrl(config.url); + } // 优先判断post/get等方法是否传入回调,否则执行初始化设置等回调 if (typeof config.beforeRequestCallback === "function") { config.beforeRequestCallback(config); @@ -124,6 +180,7 @@ class PureHttp { const $config = response.config; // 关闭进度条动画 NProgress.done(); + response.data = convertKeysToCamelCase(response.data); // 优先判断post/get等方法是否传入回调,否则执行初始化设置等回调 if (typeof $config.beforeResponseCallback === "function") { $config.beforeResponseCallback(response); @@ -140,6 +197,12 @@ class PureHttp { $error.isCancelRequest = Axios.isCancel($error); // 关闭进度条动画 NProgress.done(); + if (error.response?.status === 403) { + // 跳转到403页面 + router.push({ + path: "/error/403" + }); + } // 所有的响应异常 区分来源为取消请求/非取消请求 return Promise.reject($error); } diff --git a/src/utils/roles.ts b/src/utils/rules.ts similarity index 100% rename from src/utils/roles.ts rename to src/utils/rules.ts diff --git a/src/views/admin/index.vue b/src/views/admin/index.vue index 0f1c91e..6a2a671 100644 --- a/src/views/admin/index.vue +++ b/src/views/admin/index.vue @@ -9,7 +9,7 @@ import { rulePassword, rulePhone, ruleRequired -} from "@/utils/roles"; +} from "@/utils/rules"; const ControllerName = "Admin"; defineOptions({ diff --git a/src/views/class/edit.vue b/src/views/class/edit.vue new file mode 100644 index 0000000..a3fea06 --- /dev/null +++ b/src/views/class/edit.vue @@ -0,0 +1,347 @@ + + + + + diff --git a/src/views/class/index.vue b/src/views/class/index.vue index 78a25b4..8314e3c 100644 --- a/src/views/class/index.vue +++ b/src/views/class/index.vue @@ -5,13 +5,14 @@ import { onMounted, ref } from "vue"; import { fa } from "element-plus/es/locales.mjs"; import { hTableAPI } from "@/api/hTable"; import { getenum } from "@/api/enum"; -const ControllerName = "Class"; +import { ruleRequired } from "@/utils/rules"; +const ControllerName = "classes"; defineOptions({ name: ControllerName }); -const SchoolApi = new hTableAPI("School"); +const SchoolApi = new hTableAPI("schools"); function searchCallback(data) {} const table = ref<{ initTable: (config: TableConfig) => void }>(); @@ -38,11 +39,17 @@ const tableData: TableConfig = { btnType: "edit" // 按钮类型 add edit del custom }, { - // 操作按钮 - topBtn: true, // 是头部按钮 - label: "添加", - btnStyle: "success", - btnType: "add" // 按钮类型 add edit del custom + topBtn: true, // 头部按钮 + label: "新增", + btnType: "custom", // 按钮类型 add edit del custom + btnStyle: "success", // topBtn: true才生效 success danger + custom: { + // 按钮类型 custom 专用 + title: "新增班级", // 弹出框title + src: "class/edit", // 组件路径 + width: "550px", // 弹框宽度 + height: "520px" // 弹框高度 + } }, { topBtn: false, // 头部按钮 @@ -63,6 +70,7 @@ const tableData: TableConfig = { }, schoolId: { label: "学校", + rules: ruleRequired, width: "180px", search: true, type: "dropdown", @@ -72,6 +80,7 @@ const tableData: TableConfig = { }, name: { label: "名称", + rules: ruleRequired, width: "180px", search: true, searchType: "Like", @@ -80,6 +89,7 @@ const tableData: TableConfig = { }, Grade: { label: "年级", + rules: ruleRequired, width: "180px", type: "dropdown", custom: row => `${row.grade ?? ""}`, @@ -89,31 +99,56 @@ const tableData: TableConfig = { add: true, // 字段允许添加 edit: false // 字段允许修改 }, + GradeLevel: { + label: "年级", + search: false, + type: "dropdown", + searchType: "Like", // Equal等于/NoEqual不等于/Like包含/GreaterThan大于/LessThan小于/NoLike不包括 + add: true, // 字段允许添加 + edit: true, // 字段允许修改 + width: "70px", + setting: { + datasource: [ + { text: "初", value: "初" }, + { text: "高", value: "高" }, + { text: "小", value: "小" } + ] + } + }, + GraduationYear: { + label: "届", + search: false, + searchType: "Like", // Equal等于/NoEqual不等于/Like包含/GreaterThan大于/LessThan小于/NoLike不包括 + add: true, // 字段允许添加 + edit: true, // 字段允许修改 + width: "80px" + }, type: { label: "类型", - width: "150px", + rules: ruleRequired, + // width: "150px", type: "dropdown", search: true, add: true, // 字段允许添加 edit: true, // 字段允许修改 setting: {} - }, - createTime: { - label: "创建时间", - width: "180px", - type: "datetime", - search: true, - add: false, // 字段允许添加 - edit: false // 字段允许修改 - }, - remark: { - label: "备注", - type: "textarea", - editRows: 3, - search: false, - add: true, // 字段允许添加 - edit: true // 字段允许修改 } + // createTime: { + // label: "创建时间", + // width: "180px", + // type: "datetime", + // search: true, + // add: false, // 字段允许添加 + // edit: false // 字段允许修改 + // }, + // remark: { + // label: "备注", + // type: "textarea", + // editRows: 3, + // search: false, + // add: true, // 字段允许添加 + // edit: true // 字段允许修改 + // } }, data: [], pageData: { @@ -126,8 +161,20 @@ const showTable = ref(false); onMounted(async () => { //初始化数据原 - tableData.column.Grade.setting.datasource = (await getenum("GradeEnum")).data; - + tableData.column.Grade.setting.datasource = [ + { text: "初一", value: "初一" }, + { text: "初二", value: "初二" }, + { text: "初三", value: "初三" }, + { text: "高一", value: "高一" }, + { text: "高二", value: "高二" }, + { text: "高三", value: "高三" }, + { text: "一年级", value: "一年级" }, + { text: "二年级", value: "二年级" }, + { text: "三年级", value: "三年级" }, + { text: "四年级", value: "四年级" }, + { text: "五年级", value: "五年级" }, + { text: "六年级", value: "六年级" } + ]; tableData.column.type.setting.datasource = ( await getenum("ClassTypeEnum") ).data; diff --git a/src/views/grade/index.vue b/src/views/grade/index.vue new file mode 100644 index 0000000..7478824 --- /dev/null +++ b/src/views/grade/index.vue @@ -0,0 +1,136 @@ + + + diff --git a/src/views/menu/index.vue b/src/views/menu/index.vue index 6f09a21..265f1c6 100644 --- a/src/views/menu/index.vue +++ b/src/views/menu/index.vue @@ -42,7 +42,7 @@ -