diff --git a/.env.development b/.env.development
index 17faa14..f8eaae4 100644
--- a/.env.development
+++ b/.env.development
@@ -7,4 +7,8 @@ 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_BASEURL = "http://192.168.2.33:5199/api"
+# 接口地址
+# VITE_API_BASEURL = "http://localhost:5199/api"
+#数据中心后台地址
+VITE_API_USERCENTER_URL = "https://dca.w.23544.com:8843/api"
diff --git a/.env.production b/.env.production
index 84e6086..55ffd00 100644
--- a/.env.production
+++ b/.env.production
@@ -10,4 +10,10 @@ VITE_CDN = false
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
-VITE_COMPRESSION = "none"
\ No newline at end of file
+VITE_COMPRESSION = "none"
+
+
+# 接口地址
+VITE_API_BASEURL = "https://learn-archives-admin.23544.com/api"
+#数据中心后台地址
+VITE_API_USERCENTER_URL = "https://dcb.23544.com/api"
\ No newline at end of file
diff --git a/.env.staging b/.env.staging
index 65b57e3..f613c0f 100644
--- a/.env.staging
+++ b/.env.staging
@@ -8,9 +8,15 @@ VITE_PUBLIC_PATH = /
VITE_ROUTER_HISTORY = "hash"
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
-VITE_CDN = true
+VITE_CDN = false
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
VITE_COMPRESSION = "none"
+
+
+# 接口地址
+VITE_API_BASEURL = "https://learn-archives-admin-dev.23544.com/api"
+#数据中心后台地址
+VITE_API_USERCENTER_URL = "https://dca.w.23544.com:8843/api"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 423ed2b..7f9b81f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,6 @@ tests/**/coverage/
*.ntvs*
*.njsproj
*.sln
-tsconfig.tsbuildinfo
\ No newline at end of file
+tsconfig.tsbuildinfo
+.vscode
+.vscode/settings.json
diff --git a/.husky/commit-msg b/.husky/commit-msg
deleted file mode 100644
index 5ee2d16..0000000
--- a/.husky/commit-msg
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
-PATH="/usr/local/bin:$PATH"
-
-npx --no-install commitlint --edit "$1"
\ No newline at end of file
diff --git a/.husky/common.sh b/.husky/common.sh
deleted file mode 100644
index 5f0540b..0000000
--- a/.husky/common.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-command_exists () {
- command -v "$1" >/dev/null 2>&1
-}
-
-# Workaround for Windows 10, Git Bash and Pnpm
-if command_exists winpty && test -t 1; then
- exec < /dev/tty
-fi
diff --git a/.husky/pre-commit b/.husky/pre-commit
deleted file mode 100644
index 6e229ea..0000000
--- a/.husky/pre-commit
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-. "$(dirname "$0")/common.sh"
-
-[ -n "$CI" ] && exit 0
-
-PATH="/usr/local/bin:$PATH"
-
-# Perform lint check on files in the staging area through .lintstagedrc configuration
-pnpm exec lint-staged
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 388b96f..975bb66 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,13 +1,14 @@
{
"editor.formatOnType": true,
- "editor.formatOnSave": true,
+ "editor.formatOnSave": false,
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.tabSize": 2,
"editor.formatOnPaste": true,
"editor.guides.bracketPairs": "active",
- "files.autoSave": "afterDelay",
+ // "files.autoSave": "afterDelay",
+ "files.autoSave": "off",
"git.confirmSync": false,
"workbench.startupEditor": "newUntitledFile",
"editor.suggestSelection": "first",
@@ -40,4 +41,5 @@
"v-ripple"
],
"vscodeCustomCodeColor.highlightValueColor": "#b392f0",
+ "vue3snippets.enable-compile-vue-file-on-did-save-code": true,
}
\ No newline at end of file
diff --git a/Dockerfiles/Dockerfile-staging/Dockerfile b/Dockerfiles/Dockerfile-staging/Dockerfile
new file mode 100644
index 0000000..e15a94f
--- /dev/null
+++ b/Dockerfiles/Dockerfile-staging/Dockerfile
@@ -0,0 +1,41 @@
+# 构建阶段
+FROM m.daocloud.io/docker.io/library/node:22.14.0 AS builder
+
+# 设置工作目录
+WORKDIR /app
+
+# 设置 npm 镜像源
+RUN npm config set registry https://registry.npmmirror.com/
+RUN npm config set fetch-retries 3
+RUN npm config set fetch-retry-mintimeout 5000
+RUN npm config set fetch-retry-maxtimeout 60000
+
+# 安装pnpm
+RUN npm install -g pnpm
+
+# 复制源代码
+COPY . .
+
+# 设置 pnpm 下载源
+RUN pnpm config set registry https://registry.npmmirror.com/
+
+# 安装依赖
+RUN pnpm i --fetch-timeout 300000
+
+# 构建项目
+RUN pnpm build:staging
+
+# 部署阶段
+FROM m.daocloud.io/docker.io/library/nginx:alpine
+
+# 复制构建产物到 Nginx 目录
+COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html
+
+# 复制 Nginx 配置
+COPY Dockerfiles/Dockerfile-staging/default.conf /etc/nginx/conf.d/default.conf
+
+# 暴露端口
+EXPOSE 80
+
+# 启动 Nginx
+CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/Dockerfiles/Dockerfile-staging/default.conf b/Dockerfiles/Dockerfile-staging/default.conf
new file mode 100644
index 0000000..3de8a37
--- /dev/null
+++ b/Dockerfiles/Dockerfile-staging/default.conf
@@ -0,0 +1,47 @@
+server {
+ listen 80;
+ server_name localhost;
+
+ # 基础设置
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+ try_files $uri $uri/ /index.html;
+
+ client_max_body_size 100m;
+
+ # 错误页面配置
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ internal; # 仅用于内部错误请求
+ }
+
+ # Gzip 压缩设置
+ gzip on;
+ gzip_min_length 1k;
+ gzip_comp_level 6;
+ gzip_types text/plain text/css text/javascript application/json
+ application/javascript application/x-javascript application/xml;
+ gzip_vary on;
+ gzip_disable "MSIE [1-6]\.";
+
+ # 静态资源缓存优化
+ location ~* \.(jpg|jpeg|gif|ico|css|js)$ {
+ expires 7d;
+ add_header Cache-Control "public, no-transform";
+ }
+
+ # API 代理配置
+ location /api/ {
+ proxy_pass http://learn-archives-api-svc:8080/api/;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme; # 添加协议头
+
+ # 优化代理性能
+ proxy_connect_timeout 30s;
+ proxy_send_timeout 60s;
+ proxy_read_timeout 60s;
+ proxy_buffering on;
+ }
+}
\ No newline at end of file
diff --git a/index.html b/index.html
index 1193eef..770aa19 100644
--- a/index.html
+++ b/index.html
@@ -2,6 +2,10 @@
+
+
+
+
>("get", `public/enum/${type}`);
+ return http.request>("get", `Public/enum/${type}`);
}
/**
* @description 获取枚举对象
@@ -15,5 +16,5 @@ export function getenum(type) {
* @return {object}
*/
export function getenumDic(type) {
- return http.request>("get", `public/enum/${type}/Dic`);
+ return http.request>("get", `Public/enum/${type}/Dic`);
}
diff --git a/src/api/exam.ts b/src/api/exam.ts
new file mode 100644
index 0000000..0cbf281
--- /dev/null
+++ b/src/api/exam.ts
@@ -0,0 +1,35 @@
+import { http } from "@/utils/http";
+// import type { Res } from "@/utils/http/types";
+
+/**
+ * @description 导入表单
+ * @return {object}
+ */
+export function ImportExamInfo(id: number, file: File) {
+ let formData = new FormData();
+ formData.append("eId", id.toString());
+ formData.append("file", file);
+ return http.request(
+ "post",
+ `ExamClassInfo/Import`,
+ {
+ data: formData
+ },
+ {
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded"
+ },
+ responseType: "blob"
+ }
+ );
+}
+
+/**
+ * @description 删除班级考试信息
+ * @return {object}
+ */
+export function DeleteExamInfo(data: { classId: number; examId: number }) {
+ return http.request("post", `ExamClassInfo/DeleteExamInfo`, {
+ data
+ });
+}
diff --git a/src/api/hTable.ts b/src/api/hTable.ts
index 8839c3b..e29d581 100644
--- a/src/api/hTable.ts
+++ b/src/api/hTable.ts
@@ -1,5 +1,6 @@
import { http } from "@/utils/http";
import type { Res } from "@/utils/http/types";
+import type { ComboModel } from "@/components/hTable/hTable";
export class hTableAPI {
url = "";
@@ -10,13 +11,9 @@ export class hTableAPI {
PageList(data = {}) {
return http.request>("post", `${this.url}/PageList`, { data });
}
- Info(id, tag = {}) {
- const pUrl = `${this.url}/${id}`;
+ 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) {
@@ -26,6 +23,9 @@ export class hTableAPI {
return http.request>("post", `${this.url}/Del`, { data });
}
querycombo(data) {
- return http.request>("post", `${this.url}/QueryCombo`, { data });
+ return http.request>("post", `${this.url}/QueryCombo`, {
+ data
+ });
}
}
+
diff --git a/src/api/menu.ts b/src/api/menu.ts
index dffe752..2250495 100644
--- a/src/api/menu.ts
+++ b/src/api/menu.ts
@@ -3,7 +3,7 @@ import type { Res } from "@/utils/http/types";
// 定义菜单项接口
export interface MenuItem {
- id: number;
+ id?: number;
name: string;
path?: string;
isButton: boolean;
@@ -22,3 +22,28 @@ export interface MenuItem {
export function MenuAll() {
return http.request>("get", `Menu/All`);
}
+
+/**
+ * @description 获取所有的菜单
+ * @return {object}
+ */
+export function Edit(info: MenuItem) {
+ return http.request>("post", `Menu/Edit`, { data: info });
+}
+/**
+ * @description 获取所有的菜单
+ * @return {object}
+ */
+export function Del(ids: number[]) {
+ return http.request>("post", `Menu/Del`, { data: ids });
+}
+/**获取角色的菜单 */
+export function RoleMenu(roleId: number) {
+ return http.request>("get", `MenuRelation/RoleMenu?roleId=${roleId}`);
+}
+/**修改角色菜单 */
+export function SetMenu(data: { roleId: number; menuId: number[] }) {
+ return http.request>("post", `MenuRelation/SetMenu`, {
+ data: data
+ });
+}
diff --git a/src/api/school.ts b/src/api/school.ts
new file mode 100644
index 0000000..8f8e2b6
--- /dev/null
+++ b/src/api/school.ts
@@ -0,0 +1,30 @@
+import { http } from "@/utils/http";
+import type { Res } from "@/utils/http/types";
+
+/**
+ * @description 获取枚举下拉
+ * @param {string} type 枚举类型 type=StatusEnum
+ * @return {object}
+ */
+export function getenum(type) {
+ return http.request>("get", `public/enum/${type}`);
+}
+/**
+ * @description 获取枚举对象
+ * @param {string} type 枚举类型 type=StatusEnum
+ * @return {object}
+ */
+export function getenumDic(type) {
+ return http.request>("get", `public/enum/${type}/Dic`);
+}
+
+export function getProvince() {
+ return http.request>("get", `address/province`);
+}
+export function getcity(c) {
+ return http.request>("get", `address/${c}/city`);
+}
+export function getregion(r) {
+ return http.request>("get", `address/${r}/region`);
+}
+
diff --git a/src/api/student.ts b/src/api/student.ts
new file mode 100644
index 0000000..d78e012
--- /dev/null
+++ b/src/api/student.ts
@@ -0,0 +1,74 @@
+import { http } from "@/utils/http";
+import { Res } from "@/utils/http/types";
+// import type { Res } from "@/utils/http/types";
+
+/**
+ * @description 导入表单
+ * @return {object}
+ */
+export function ImportTeacher(file: File) {
+ let formData = new FormData();
+ formData.append("file", file);
+ return http.request(
+ "post",
+ `Student/ImportTeacher`,
+ {
+ data: formData
+ },
+ {
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded"
+ },
+ responseType: "blob"
+ }
+ );
+}
+
+/**
+ * @description 导入表单
+ * @return {object}
+ */
+export function ImportStudent(file: File) {
+ let formData = new FormData();
+ formData.append("file", file);
+ return http.request(
+ "post",
+ `Student/Import`,
+ {
+ data: formData
+ },
+ {
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded"
+ },
+ responseType: "blob"
+ }
+ );
+}
+
+/**
+ * @description 修改学生拓展信息
+ * @return {object}
+ */
+export function EditStudent(data) {
+ return http.request>("post", `Student/EditInfo`, {
+ data
+ });
+}
+
+/**
+ * @description PageList
+ * @return {object}
+ */
+export function PageList(data) {
+ return http.request>("post", `Student/PageList`, {
+ data
+ });
+}
+/**
+ * @description StudentInfo
+ * @return {object}
+ */
+export function StudentInfo(uid) {
+ return http.request>("get", `Student/Info?uid=${uid}`);
+}
diff --git a/src/api/toschoolinfomanage.ts b/src/api/toschoolinfomanage.ts
new file mode 100644
index 0000000..c48da1f
--- /dev/null
+++ b/src/api/toschoolinfomanage.ts
@@ -0,0 +1,79 @@
+import { http } from "@/utils/http";
+import type { Res } from "@/utils/http/types";
+
+/**
+ * @description 获取学校枚举下拉
+ * @param {string} type 枚举类型 type=StatusEnum
+ * @return {object}
+ */
+export function getenumApi(data) {
+ return http.request>("post", `/SchoolBusiness/QueryCombo`, {
+ data
+ });
+}
+/**
+ * @description 获取学校枚举下拉
+ * @param {string} type 枚举类型 type=StatusEnum
+ * @return {object}
+ */
+export function getPageListApi(data) {
+ return http.request>("post", `/SchoolBusiness/QueryPageList`, {
+ data
+ });
+}
+/**
+ * @description 新增赴校信息或者编辑 id:0(新增),其他(编辑)
+ * @return {object}
+ */
+export function addOrEditApi(data: any) {
+ return http.request>("post", `/SchoolBusiness/Edit`, {
+ data
+ });
+}
+/**
+ * @description 获取赴校信息详情
+ * @param {string} type 枚举类型 type=StatusEnum
+ * @return {object}
+ */
+export function getSchoolBusinessDetailApi(id: string | number) {
+ return http.request>("get", `/SchoolBusiness/${id}`);
+}
+/**
+ * @description 删除赴校信息
+ * @return {object}
+ */
+export function deleteSchoolBusinessApi(data: Array) {
+ return http.request>("post", `/SchoolBusiness/Del`, {
+ data
+ });
+}
+/**
+ * @description 获取赴校人员下拉数据
+ * @return {object}
+ */
+export function getSchoolBusinessPeopleListApi(data: object) {
+ return http.request>("post", `/Admin/QueryCombo`, {
+ data
+ });
+}
+/**
+ * @description 导入excel
+ * @return {object}
+ */
+export function importExcel(file: File) {
+ let formData = new FormData();
+ formData.append("file", file);
+ return http.request(
+ "post",
+ `SchoolBusiness/Import`,
+ {
+ data: formData
+ },
+ {
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded"
+ },
+ responseType: "blob"
+ }
+ );
+}
\ No newline at end of file
diff --git a/src/api/userCenter.ts b/src/api/userCenter.ts
new file mode 100644
index 0000000..bfc6b15
--- /dev/null
+++ b/src/api/userCenter.ts
@@ -0,0 +1,201 @@
+import { ComboModel } from "@/components/hTable/hTable";
+import { http } from "@/utils/http";
+import type { Res, ResPage } from "@/utils/http/types";
+/**
+ * @description 获取枚举下拉
+ * @param {string} type 枚举类型 type=StatusEnum
+ * @return {object}
+ */
+export function getPageUserList(data: any) {
+ return http.request>(
+ "post",
+ `userCenter/back/users/getpageuserlist`,
+ {
+ data
+ }
+ );
+}
+/**
+ * @description 编辑学校
+ * @return {void}
+ */
+export function EditSchool(data: any) {
+ return http.request>("post", `userCenter/back/schools/add`, {
+ data
+ });
+}
+/**
+ * @description 获取学校
+ * @return {void}
+ */
+export function getSchoolData() {
+ return http.request>(
+ "get",
+ `userCenter/public/getschooldata`
+ );
+}
+/**
+ * @description 获取职位列表
+ * @return {void}
+ */
+export function getPositionList(data: any) {
+ return http.request>(
+ "post",
+ `userCenter/back/positions/getpositionlist`,
+ { data }
+ );
+}
+/**
+ * @description 云校下拉框数据
+ * @return {object}
+ */
+export function cloudSchoolCombo() {
+ let data = {
+ ValueName: "Id",
+ TextName: "Name"
+ };
+ return http.request>(
+ "post",
+ `userCenter/back/cloudschool/querycombo`,
+ {
+ data
+ }
+ );
+}
+/**
+ * @description 获取班级信息
+ * @return {object}
+ */
+export function getClassInfo(id) {
+ return http.request>("get", `userCenter/back/classes/${id}`);
+}
+/**
+ * @description 获取学校信息
+ * @return {object}
+ */
+export function getSchoolInfo(id) {
+ return http.request>("get", `userCenter/back/schools/${id}`);
+}
+
+/**
+ * @description 获取用户信息
+ * @return {object}
+ */
+export function getUserInfo(id) {
+ return http.request>(
+ "get",
+ `userCenter/back/users/getuserinfo?id=${id}`
+ );
+}
+
+/**
+ * @description 添加班级
+ * @return {object}
+ */
+export function addClasses(info: any) {
+ return http.request>("post", `userCenter/back/classes/addclass`, {
+ data: info
+ });
+}
+
+/**
+ * @description 添加班级
+ * @return {object}
+ */
+export function editUser(data: any) {
+ return http.request>("post", `userCenter/back/users/edituser`, {
+ data
+ });
+}
+
+/**
+ * @description 添加班级
+ * @return {object}
+ */
+export function getClassCombo(info: any) {
+ return http.request>("post", `userCenter/public/getclasscombo`, {
+ data: info
+ });
+}
+
+/**
+ * @description 获取科目
+ * @return {object}
+ */
+export function getSubjectData() {
+ return http.request>("get", `userCenter/public/getsubjectdata`);
+}
+/**
+ * @description 获取职位列表
+ * @return {object}
+ */
+export function getPositions(data) {
+ return http.request>("post", `userCenter/back/positions/positions`, {
+ data
+ });
+}
+
+//--------------------------interface----------------------------
+
+/**
+ * 职位信息
+ */
+export interface Position {
+ userId: number;
+ id: number;
+ name: string;
+ schoolId: number;
+ enable: boolean;
+ endTime: string | null;
+ schoolName: string;
+ graduationYear: number;
+ grade: string;
+ classId: number;
+ className: string;
+ subjectId: number;
+ subjectName: string;
+ positionType: number;
+ positionLevel: number;
+ status: boolean;
+}
+
+/**
+ * 用户详细信息
+ */
+export interface UserDetail {
+ id: number;
+ templateId: number;
+ phone: string;
+ edited: boolean;
+ userType: number;
+ cloudSchoolId: number;
+ account: string;
+ studentId: string;
+ realName: string;
+ sex: number;
+ subjectLevel: any;
+ birthDate: string;
+ residence: string;
+ national: string;
+ headImage: string;
+ idCard: string | null;
+ pid: number;
+ pname: string;
+ cid: number;
+ cname: string;
+ rid: number;
+ rname: string;
+ wx: string;
+ isPerfectInfo: number;
+ level: number;
+ state: number;
+ meetingAccount: string | null;
+ gkSubject: string | null;
+ glSubject: string | null;
+ gSubject1: string | null;
+ gSubject2: string | null;
+ thirdPartyId: string | null;
+ pointPenSN: string | null;
+ subjectLevels: null;
+ positions: Position[];
+}
diff --git a/src/components/hTable/hTable.ts b/src/components/hTable/hTable.ts
index eb1a905..c650c2b 100644
--- a/src/components/hTable/hTable.ts
+++ b/src/components/hTable/hTable.ts
@@ -1,68 +1,98 @@
export interface Dialog {
- /* 对话框是否可见 */
+ /** 对话框是否可见 */
visible: boolean;
- /* 是否显示关闭按钮 */
+ /** 是否显示关闭按钮 */
close: boolean;
- /* 对话框标题 */
+ /** 对话框标题 */
title: string;
- /* 对话框宽度 */
+ /** 对话框宽度 */
width: string;
/**自定义弹窗数据 */
custom: {
- /* 自定义对话框高度 */
+ /** 自定义对话框高度 */
height: string;
- /* 自定义对话框数据 */
+ /** 自定义对话框数据 */
data: any[];
- /* 自定义组件路径 */
+ /** 自定义组件路径 */
src?: string;
- /* 自定义配置项 */
+ /** 自定义配置项 */
custom: Record;
- /* 自定义对话框是否可见 */
+ /** 自定义对话框是否可见 */
visible: boolean;
- /* 异步加载组件 */
+ /** 异步加载组件 */
component: any;
};
edit: {
- /* 编辑项ID */
+ /** 编辑项ID */
id: number;
- /* 编辑对话框标题 */
+ /** 编辑对话框标题 */
title: string;
- /* 编辑对话框是否可见 */
+ /** 编辑对话框是否可见 */
visible: boolean;
row?: any;
tagData?: any;
};
}
-/* 按钮自定义配置 */
+/** 按钮自定义配置 */
export interface ButtonCustomConfig {
- /* 弹出框标题 */
+ /** 弹出框标题 */
title: string;
- /* 组件路径 */
+ /** 组件路径 */
src: string;
- /* 弹框宽度 */
+ /** 弹框宽度 */
width: string;
- /* 弹框高度 */
+ /** 弹框高度 */
height: string;
}
-/* 操作按钮配置 */
+/** 操作按钮配置 */
export interface OperationButton {
- /* 是否为头部按钮 */
+ /** 是否为头部按钮 */
topBtn: boolean;
- /* 是否显示 */
+ /** 按钮权限码 */
+ perms?: string;
+ /** 是否显示 */
show?: boolean;
- /* 按钮文本 */
+ /** 按钮文本 */
label: string;
- /* 按钮类型 */
- btnType: "add" | "edit" | "del" | "custom";
- /* 按钮样式 */
- btnStyle?: "success" | "danger";
- /* 自定义按钮配置 */
+ /** 按钮点击事件
+ * @tips btnType 为空时触发
+ * @param obj 当前按钮配置对象
+ * @param row 当前行数据
+ * @param handleReloadPaged 父表单刷新函数
+ */
+ click?: (obj, row, handleReloadPaged: (reload?: boolean) => void) => void;
+ /** 按钮类型 */
+ btnType?: "add" | "edit" | "del" | "custom";
+ /** 按钮样式 */
+ btnStyle?: "success" | "info" | "primary" | "danger" | "warning";
+ /** 自定义按钮配置 */
custom?: ButtonCustomConfig;
}
-/* 字段设置项 */
+/** 类型判断枚举 */
+export enum ConditionalType {
+ Equal,
+ Like,
+ GreaterThan,
+ GreaterThanOrEqual,
+ LessThan,
+ LessThanOrEqual,
+ In,
+ NotIn,
+ LikeLeft,
+ LikeRight,
+ NoEqual,
+ IsNullOrEmpty,
+ IsNot,
+ NoLike,
+ EqualNull,
+ InLike,
+ Range
+}
+
+/** 字段设置项 */
export interface FieldSetting {
/**map 时Value的取值的属性 */
mapValue?: string;
@@ -77,50 +107,45 @@ export interface FieldSetting {
* @returns 预期返回有效图片地址url
*/
imgUrl?: (value: any, row: any) => string;
- /* 数据源 */
- datasource?: Array<{
- Value: any;
- Text: string;
- }>;
+ /** 数据源 */
+ datasource?: ComboModel[];
}
-///* 表格列配置 */
+///** 表格列配置 */
//export interface TableEditColumn {}
-
-/* 表格列配置 */
+export interface ComboModel {
+ value: any;
+ text: string;
+}
+/** 表格列配置 */
export interface TableColumn {
- /* 显示标签 */
+ /** 显示标签 */
label: string;
- /* 是否可搜索 */
+ /** 是否可搜索 */
search: boolean;
- /* 搜索类型 */
- searchType?:
- | "Equal"
- | "NoEqual"
- | "Like"
- | "GreaterThan"
- | "LessThan"
- | "NoLike";
- /* 是否允许添加 */
- add: boolean;
- /* 是否允许修改 */
- edit: boolean;
- /* 列宽度 */
+ /** 搜索类型 */
+ searchType?: ConditionalType;
+ /** 是否允许添加 [false]*/
+ add?: boolean;
+ /** 是否允许修改 [false]*/
+ edit?: boolean;
+ /** 列宽度 [auto]*/
width?: string;
- /* 字段类型 */
- type?: string;
+ /** 字段类型 */
+ type?: "string" | "dropdown" | "switch" | "img" | "datetime" | "textarea";
/** 是否多选 */
multiple?: boolean;
/** 编辑时显示列 */
editShow?: boolean;
+ /**校验规则 */
rules?: any | Array;
/** 显示列 */
show?: boolean;
- /* 字段设置 */
+ /** 字段设置 */
setting?: FieldSetting;
- /* 修改时的编辑值 */
- valueE?: Array | string;
- /* 查询值 */
- value?: Array | string;
+ /** 修改时的编辑值 */
+ valueE?: Array | string | number | boolean | Date;
+ /** 查询值 */
+ value?: Array | string | number | boolean | Date;
/** textarea编辑时的行数 */
editRows?: number;
/**编辑时值发生变化 */
@@ -129,54 +154,73 @@ export interface TableColumn {
custom?: (row: any) => string;
}
-/* 分页数据 */
+/** 分页数据 */
export interface PageData {
- /* 总条数 */
+ /** 总条数 */
total: number;
}
-/* 搜索条件 */
+/** 分页数据 */
+export interface ConditionalModel {
+ /** 字段名称 */
+ FieldName: string;
+ /** 字段查询值 */
+ FieldValue: string;
+ /** 查询方式 */
+ ConditionalType?: ConditionalType;
+ /** C#类型名称 */
+ CSharpTypeName?: string;
+}
+
+/** 搜索条件 */
export interface SearchConditions {
- /* 是否显示搜索 */
+ /** 是否显示搜索 */
show: boolean;
- /* 当前页码 */
+ /** 当前页码 */
PageIndex: number;
- /* 每页大小 */
+ /** 每页大小 */
PageSize: number;
- /* 排序字段 */
+ /** 排序字段 */
OrderBy: string;
- /* 默认查询条件 */
- defaultConditions: any[];
- /* 查询条件 */
+ /**排序顺序
+ * @tips 0:升序 1:降序
+ * @默认 = 1
+ */
+ OrderByType?: 0 | 1;
+ /** 默认查询条件 */
+ defaultConditions: ConditionalModel[];
+ /** 查询条件 */
Conditions: any[];
}
-/* 表格配置 */
+/** 表格配置 */
export interface TableConfig {
- /* 搜索回调函数 */
+ /** 搜索回调函数 */
searchCallback?: (s: SearchConditions) => void;
- /* 新增/修改回调函数 */
+ /** 新增/修改回调函数 */
editCallback?: (from: any) => void;
- /* API地址 */
+ /** API地址 */
apiUrl: string;
- /* 是否显示选择列 */
+ /** 是否显示选择列 */
selectColumn: boolean;
- /* 搜索配置 */
+ /** 搜索配置 */
search: SearchConditions;
- /* 是否显示操作列 */
+ /** 是否显示操作列 */
operationColumn: boolean;
- /* 操作按钮配置 */
+ /** 操作按钮配置 */
operationColumnData: OperationButton[];
- /* 列配置 */
+ /** 列配置 */
column: Record;
- /* 表格数据 */
+ /** 表格数据 */
data: any[];
/**显示头部操作按钮 */
operationTop?: boolean;
- /* 分页数据 */
+ /** 分页数据 */
pageData: PageData;
- /* 选中行 */
+ /** 选中行 */
selectRows: any[];
- /* 是否显示边框 */
+ /** 是否显示边框 */
border: boolean;
+ /**是否显示 */
+ show?: boolean;
}
diff --git a/src/components/hTable/hTableEdit.vue b/src/components/hTable/hTableEdit.vue
index f35ec13..3e84f98 100644
--- a/src/components/hTable/hTableEdit.vue
+++ b/src/components/hTable/hTableEdit.vue
@@ -8,24 +8,24 @@ const props = defineProps({
//** 传入的表单数据 */
id: {
type: Number,
- default: -1
+ default: -1,
},
tableData: {
type: Object as PropType,
- default: null
+ default: null,
},
row: {
type: Object,
- default: null
+ default: null,
},
tagData: {
type: Object,
- default: () => {}
- }
+ default: () => {},
+ },
});
const emit = defineEmits(["handlePagedCallback"]);
const editFormRef = ref();
-const column: Record = {};
+const column = ref>({});
const editData = ref({
frorm: {},
isedit: props.id !== -1,
@@ -34,12 +34,12 @@ const editData = ref({
{
required: true,
message: "不能为空",
- trigger: "blur"
- }
+ trigger: "blur",
+ },
],
formLabelWidth: "120px",
size: "small",
- loading: false
+ loading: false,
});
const Api = new hTableAPI(editData.value.table.apiUrl);
onMounted(() => {
@@ -69,16 +69,16 @@ function handlePagedCallback() {
emit("handlePagedCallback"); // 传参给父组件
}
function handleSubmitForm() {
- editFormRef.value.validate(valid => {
+ editFormRef.value.validate((valid) => {
if (!valid) {
return;
}
editData.value.loading = true;
- let form = {};
+ let form: any = {};
if (editData.value.isedit) {
form = props.row;
- }
+ } else form.id = 0;
for (const key in column.value) {
const element = column.value[key];
if (element.valueE !== null && element.valueE !== "") {
@@ -88,7 +88,7 @@ function handleSubmitForm() {
if (editData.value.table.editCallback) {
editData.value.table.editCallback(form);
}
- Api.edit(form).then(res => {
+ Api.edit(form).then((res) => {
editData.value.loading = false;
if (res.code === 200) {
ElMessage.success("操作成功");
@@ -105,7 +105,7 @@ function handleResetForm() {
if (Array.isArray(item.valueE)) {
item.valueE = [];
} else if (typeof item.valueE === "number") {
- item.valueE = 0;
+ item.valueE = "";
} else if (typeof item.valueE === "boolean") {
item.valueE = false;
} else {
@@ -116,9 +116,9 @@ function handleResetForm() {
function fetchInitData() {}
function fetchFormData() {
editData.value.loading = false;
- handleResetForm();
if (editData.value.isedit) {
- Api.Info(props.id).then(res => {
+ handleResetForm();
+ Api.Info(props.id).then((res) => {
if (res.code === 200) {
editData.value.frorm = res.data;
for (const key in column.value) {
@@ -141,7 +141,6 @@ function fetchFormData() {
ref="editFormRef"
:model="editData.table.column"
:label-width="editData.formLabelWidth"
- size="small"
clearable
>
@@ -170,12 +169,12 @@ function fetchFormData() {
clearable
filterable
:placeholder="o.label"
- style="width: 100%"
+ class="elWidth"
@change="o.change"
>
-
+
- 立即提交
重置
@@ -216,3 +214,9 @@ function fetchFormData() {
+
diff --git a/src/components/hTable/index.vue b/src/components/hTable/index.vue
index ba33a09..e832ba8 100644
--- a/src/components/hTable/index.vue
+++ b/src/components/hTable/index.vue
@@ -10,33 +10,49 @@ import {
onUnmounted,
getCurrentInstance,
onBeforeMount,
- PropType
+ PropType,
+ shallowRef,
} from "vue";
import { Search } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { defineAsyncComponent, AsyncComponentLoader } from "vue";
-import { Dialog, TableConfig } from "./hTable";
+import {
+ ButtonCustomConfig,
+ ConditionalType,
+ Dialog,
+ TableColumn,
+ TableConfig,
+} from "./hTable";
import hTableEdit from "./hTableEdit.vue";
import { hTableAPI } from "@/api/hTable";
import { getenum } from "@/api/enum";
+//按钮权限
+import { hasPerms } from "@/utils/auth";
+const modules = import.meta.glob("/src/views/**/*.{vue,tsx}");
const props = defineProps({
//** 传入的表单数据 */
Row: {
type: Object as PropType,
- default: () => ({})
+ default: () => ({}),
},
tableConfig: {
type: Object as PropType,
- default: () => ({})
- }
+ default: () => ({}),
+ },
});
const table = ref(props.tableConfig);
+const tableShowColumn = ref>();
onBeforeMount(() => {
/* 初始化系统配置 */
nextTick(async () => {
intdata();
+ //过滤无法显示的列
+ tableShowColumn.value = Object.fromEntries(
+ Object.entries(table.value.column).filter(([_, s]) => s.show)
+ );
+
Api = new hTableAPI(table.value.apiUrl);
init.value = true;
tableShow.value = true;
@@ -55,7 +71,6 @@ onUnmounted(() => {});
// });
const tableShow = ref(false);
let Api: hTableAPI = null;
-const instance = getCurrentInstance();
const init = ref(false);
const tableHeight = ref(0);
@@ -70,13 +85,13 @@ const dialog = ref