diff --git a/.env.development b/.env.development index f8eaae4..8d3955a 100644 --- a/.env.development +++ b/.env.development @@ -7,8 +7,12 @@ VITE_PUBLIC_PATH = / # 开发环境路由历史模式(Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数") VITE_ROUTER_HISTORY = "hash" -VITE_API_BASEURL = "http://192.168.2.33:5199/api" # 接口地址 -# VITE_API_BASEURL = "http://localhost:5199/api" +VITE_API_BASEURL = "http://192.168.2.33:5199/api" #数据中心后台地址 VITE_API_USERCENTER_URL = "https://dca.w.23544.com:8843/api" + +# # 接口地址 +# VITE_API_BASEURL = "https://learn-archives-admin-dev.23544.com/api" +# #数据中心后台地址 +# VITE_API_USERCENTER_URL = "https://dca.w.23544.com:8843/api" diff --git a/src/api/student.ts b/src/api/student.ts index d78e012..51084d8 100644 --- a/src/api/student.ts +++ b/src/api/student.ts @@ -72,3 +72,13 @@ export function PageList(data) { export function StudentInfo(uid) { return http.request>("get", `Student/Info?uid=${uid}`); } + +/** + * @description 通过职位信息获取职位id + * @return {object} + */ +export function PosititonIds(data:any[]) { + return http.request>("post", `Student/PosititonIds`, { + data + }); +} diff --git a/src/api/userCenter.ts b/src/api/userCenter.ts index bfc6b15..51772a6 100644 --- a/src/api/userCenter.ts +++ b/src/api/userCenter.ts @@ -1,6 +1,7 @@ import { ComboModel } from "@/components/hTable/hTable"; import { http } from "@/utils/http"; import type { Res, ResPage } from "@/utils/http/types"; +import { Ref } from "vue"; /** * @description 获取枚举下拉 * @param {string} type 枚举类型 type=StatusEnum @@ -151,12 +152,14 @@ export interface Position { graduationYear: number; grade: string; classId: number; + gradeLevel: string; className: string; subjectId: number; subjectName: string; positionType: number; positionLevel: number; status: boolean; + classList?: ComboModel[]; } /** diff --git a/src/components/hTable/hTable.ts b/src/components/hTable/hTable.ts index c650c2b..6f0adea 100644 --- a/src/components/hTable/hTable.ts +++ b/src/components/hTable/hTable.ts @@ -93,13 +93,18 @@ export enum ConditionalType { } /** 字段设置项 */ -export interface FieldSetting { +export class FieldSetting { + + constructor() { + this.datasource = []; + this.mapValue= "value", + this.maplabel= "text" + + } /**map 时Value的取值的属性 */ mapValue?: string; /**map 时label的取值的属性 */ maplabel?: string; - /** 数据源 请求方式 */ - datasourceStr?: string; /** * 图片地址 获取方式 * @param value 当前值 @@ -116,44 +121,152 @@ export interface ComboModel { value: any; text: string; } -/** 表格列配置 */ -export interface TableColumn { - /** 显示标签 */ - label: string; - /** 是否可搜索 */ - search: boolean; - /** 搜索类型 */ - searchType?: ConditionalType; +/** 新增修改的配置 */ +export class TableColumnEdit { + /** + * + * @param add 字段可以添加 + * @param edit 字段可以修改 + * @param multiple [type=dropdown]是否多选 + * @param editShow 编辑时显示列 + * @param editRows [type=textarea]编辑时的行数 + * @param rules 校验规则 + */ + constructor( + add: boolean = false, + edit: boolean = false, + multiple: boolean = false, + editShow: boolean = true, + editRows: number = 3, + editDefault: any = "", + rules: any | Array = null, + change: () => void = null + ) { + this.add = add; + this.edit = edit; + this.multiple = multiple; + this.editShow = editShow; + this.editRows = editRows; + this.editDefault = editDefault; + this.rules = rules; + this.change = change; + } /** 是否允许添加 [false]*/ add?: boolean; /** 是否允许修改 [false]*/ edit?: boolean; - /** 列宽度 [auto]*/ - width?: string; - /** 字段类型 */ - type?: "string" | "dropdown" | "switch" | "img" | "datetime" | "textarea"; - /** 是否多选 */ + /** [type=dropdown]是否多选 */ multiple?: boolean; /** 编辑时显示列 */ editShow?: boolean; /**校验规则 */ rules?: any | Array; - /** 显示列 */ + /** [type=textarea]编辑时的行数 */ + editRows?: number; + + /** 新增编辑时的缓存值 */ + valueE?: Array | string | number | boolean | Date; + /** 新增编辑时的默认 */ + editDefault?: Array | string | number | boolean | Date; + + /**编辑时值发生变化 */ + change?: () => void; +} +/** 查询的配置 */ +export class TableColumnSearch { + /** + * + * @param yes 列是否可以查询 + * @param sort 列是否可以排序 + * @param searchType 查询时候的值比较类型 + */ + constructor(yes: boolean = false, + searchType: ConditionalType = ConditionalType.Like,sort: boolean = false){ + this.yes = yes; + this.sort = sort; + this.searchType = searchType; + } + /**可以查询 [false] */ + yes?: boolean; + /** 可以排序 [false]*/ + sort?: boolean; + /** 搜索类型 */ + searchType?: ConditionalType; + /** 查询缓存值 */ + value?: Array | string | number | boolean | Date; +} + +/** 表格列配置 */ +export class TableColumn { + constructor( + ) { + + this.type = "string"; + this.show = true; + this.search = new TableColumnSearch(); + this.edit = new TableColumnEdit(); + this.setting = {}; + } + + /** 显示标签 */ + label: string; + /** 查询配置 */ + search?: TableColumnSearch; + /** 编辑配置 */ + edit?: TableColumnEdit; + /** Table中展示宽度 [auto]*/ + width?: string; + /** 字段类型 */ + type?: "string" | "dropdown" | "switch" | "img" | "datetime" | "textarea"; + /** 显示列 [不会动态计算]*/ show?: boolean; /** 字段设置 */ setting?: FieldSetting; - /** 修改时的编辑值 */ - valueE?: Array | string | number | boolean | Date; - /** 查询值 */ - value?: Array | string | number | boolean | Date; - /** textarea编辑时的行数 */ - editRows?: number; - /**编辑时值发生变化 */ - change?: () => void; /**列值初始化时 如何获取默认取对应列*/ custom?: (row: any) => string; } + + +/** 表格列配置 */ +// export interface TableColumn { +// /** 显示标签 */ +// label: string; + +// /** 是否可搜索 */ +// search: boolean; +// /** 搜索类型 */ +// searchType?: ConditionalType; +// /** 是否允许添加 [false]*/ +// add?: boolean; +// /** 是否允许修改 [false]*/ +// edit?: boolean; +// /** Table中展示宽度 [auto]*/ +// width?: string; +// /** 字段类型 */ +// type?: "string" | "dropdown" | "switch" | "img" | "datetime" | "textarea"; +// /** 是否多选 */ +// multiple?: boolean; +// /** 编辑时显示列 */ +// editShow?: boolean; +// /**校验规则 */ +// rules?: any | Array; +// /** 显示列 */ +// show?: boolean; +// /** 字段设置 */ +// setting?: FieldSetting; +// /** 修改时的编辑值 */ +// valueE?: Array | string | number | boolean | Date; +// /** 查询值 */ +// value?: Array | string | number | boolean | Date; +// /** textarea编辑时的行数 */ +// editRows?: number; +// /**编辑时值发生变化 */ +// change?: () => void; +// /**列值初始化时 如何获取默认取对应列*/ +// custom?: (row: any) => string; +// } + /** 分页数据 */ export interface PageData { /** 总条数 */ @@ -173,24 +286,39 @@ export interface ConditionalModel { } /** 搜索条件 */ -export interface SearchConditions { +export class SearchConditions { + /** + * + */ + constructor() { + this.show = true; + this.showPage = true; + this.PageIndex = 0; + this.PageSize = 20; + this.OrderBy = "Id"; + this.OrderByType = 1; + this.defaultConditions = []; + this.Conditions = []; + } /** 是否显示搜索 */ - show: boolean; + show?: boolean; + /** 显示分页器 */ + showPage?:boolean; /** 当前页码 */ - PageIndex: number; + PageIndex?: number; /** 每页大小 */ - PageSize: number; + PageSize?: number; /** 排序字段 */ - OrderBy: string; + OrderBy?: string; /**排序顺序 * @tips 0:升序 1:降序 * @默认 = 1 */ OrderByType?: 0 | 1; /** 默认查询条件 */ - defaultConditions: ConditionalModel[]; + defaultConditions?: ConditionalModel[]; /** 查询条件 */ - Conditions: any[]; + Conditions?: any[]; } /** 表格配置 */ @@ -224,3 +352,82 @@ export interface TableConfig { /**是否显示 */ show?: boolean; } +/** 初始化表格数据 */ +export function intTableData(tValue: TableConfig): TableConfig { + if (!tValue.data) tValue.data = []; + if (!tValue.selectRows) tValue.selectRows = []; + if (tValue.border == null) tValue.border = true; + if (!tValue.pageData) tValue.pageData = { total: 0 }; + if (tValue.operationTop === undefined) tValue.operationTop = true; + + //分页查询配置 + tValue.search= { ...new SearchConditions(), ...tValue.search }; + + // 处理 column 的属性 + for (const key in tValue.column) { + tValue.column[key] = { ...new TableColumn(), ...tValue.column[key] }; + const element = tValue.column[key]; + + element.edit = { ...new TableColumnEdit(), ...element.edit }; + element.search = { ...new TableColumnSearch(), ...element.search }; + element.setting = { ...new FieldSetting(), ...element.setting }; + + if ( + element.custom == undefined && + (element.type === "switch" || + element.type === "dropdown" || + element.type === "string" || + element.type === undefined) + ) { + if (element.type === "string" || element.type === undefined) + element.custom = row => row[key]; + else { + element.custom = row => { + let sc = element.setting.datasource.find( + s => s[element.setting.mapValue] + "" == row[key] + "" + ); + return !sc ? row[key] : sc[element.setting.maplabel]; + }; + } + } else if (element.custom == undefined) { + element.custom = row => row[key]; + } + } + + // 处理 operationColumnData 的属性 + for (const key in tValue.operationColumnData) { + const element = tValue.operationColumnData[key]; + if (element.show === undefined) element.show = true; + } + return tValue; +} + +/** + * 生成 毕业届下拉 + */ +export function gradeComboModel(): ComboModel[] { + const now = new Date(); + const currentYear = now.getFullYear(); + const currentMonth = now.getMonth() + 1; + + const isAfterAugust = currentMonth >= 9; + const baseYear = isAfterAugust ? currentYear : currentYear - 1; + + const gradeOffsets = [ + { baseGradeName: "初", yearOffset: 0, grade: "初一" }, // 初一 + { baseGradeName: "初", yearOffset: 1, grade: "初二" }, // 初二 + { baseGradeName: "初", yearOffset: 2, grade: "初三" }, // 初三 + { baseGradeName: "高", yearOffset: 0, grade: "高一" }, // 高一 + { baseGradeName: "高", yearOffset: 1, grade: "高二" }, // 高二 + { baseGradeName: "高", yearOffset: 2, grade: "高三" }, // 高三 + ]; + + return gradeOffsets.map( + (item): ComboModel => { + const entranceYear = baseYear - item.yearOffset; + const graduationYear = entranceYear + 3; + let v = `${item.baseGradeName}${graduationYear}届`; + return { text: v + ` [${item.grade}]`, value: v }; + } + ); +} \ No newline at end of file diff --git a/src/components/hTable/hTableEdit.vue b/src/components/hTable/hTableEdit.vue index 3e84f98..4131bb6 100644 --- a/src/components/hTable/hTableEdit.vue +++ b/src/components/hTable/hTableEdit.vue @@ -55,11 +55,11 @@ function intiColumn() { for (const key in editData.value.table.column) { const element = editData.value.table.column[key]; if (editData.value.isedit) { - if (element.edit) { + if (element.edit.edit) { column.value[key] = element; } } else { - if (element.add) { + if (element.edit.add) { column.value[key] = element; } } @@ -81,8 +81,8 @@ function handleSubmitForm() { } else form.id = 0; for (const key in column.value) { const element = column.value[key]; - if (element.valueE !== null && element.valueE !== "") { - form[key] = element.valueE; + if (element.edit.valueE !== null && element.edit.valueE !== "") { + form[key] = element.edit.valueE; } } if (editData.value.table.editCallback) { @@ -102,14 +102,15 @@ function handleSubmitForm() { function handleResetForm() { for (const key in column.value) { let item = column.value[key]; - if (Array.isArray(item.valueE)) { - item.valueE = []; - } else if (typeof item.valueE === "number") { - item.valueE = ""; - } else if (typeof item.valueE === "boolean") { - item.valueE = false; + if (item.edit.editDefault != null) item.edit.valueE = item.edit.editDefault; + else if (Array.isArray(item.edit.valueE)) { + item.edit.valueE = []; + } else if (typeof item.edit.valueE === "number") { + item.edit.valueE = ""; + } else if (typeof item.edit.valueE === "boolean") { + item.edit.valueE = false; } else { - item.valueE = ""; + item.edit.valueE = ""; } } } @@ -123,7 +124,7 @@ function fetchFormData() { editData.value.frorm = res.data; for (const key in column.value) { const element = column.value[key]; - element.valueE = res.data[key]; + element.edit.valueE = res.data[key]; } } editData.value.loading = true; @@ -145,32 +146,32 @@ function fetchFormData() { >
- +
diff --git a/src/components/hTable/index.vue b/src/components/hTable/index.vue index e832ba8..2cde35e 100644 --- a/src/components/hTable/index.vue +++ b/src/components/hTable/index.vue @@ -15,13 +15,16 @@ import { } from "vue"; import { Search } from "@element-plus/icons-vue"; -import { ElMessage, ElMessageBox } from "element-plus"; +import { ElMessage, ElMessageBox, TableColumnCtx } from "element-plus"; import { defineAsyncComponent, AsyncComponentLoader } from "vue"; import { ButtonCustomConfig, ConditionalType, Dialog, + intTableData, TableColumn, + TableColumnEdit, + TableColumnSearch, TableConfig, } from "./hTable"; import hTableEdit from "./hTableEdit.vue"; @@ -74,6 +77,7 @@ let Api: hTableAPI = null; const init = ref(false); const tableHeight = ref(0); +let defaultOrderBy = null; const dialog = ref({ visible: false, @@ -107,36 +111,7 @@ function appStyle() { } function intdata() { - if (!table.value.data) table.value.data = []; - if (!table.value.selectRows) table.value.selectRows = []; - if (table.value.border == null) table.value.border = true; - if (!table.value.pageData) table.value.pageData = { total: 0 }; - if (table.value.operationTop === undefined) table.value.operationTop = true; - - // 处理 column 的属性 - for (const key in table.value.column) { - const element = table.value.column[key]; - if (element.add === undefined) element.add = false; - if (element.edit === undefined) element.edit = false; - // Vue 3 中直接赋值即可,不需要 $set - if (element.valueE === undefined) element.valueE = element.multiple ? [] : ""; - if (element.value === undefined) element.value = element.multiple ? [] : ""; - if (!element.type) element.type = "string"; - if (element.show === undefined) element.show = true; - if (element.editShow === undefined) element.editShow = true; - if (!element.setting) - element.setting = { datasource: [], mapValue: "value", maplabel: "text" }; - if (!element.setting.mapValue) element.setting.mapValue = "value"; - if (!element.setting.maplabel) element.setting.maplabel = "text"; - - if (!element.change) element.change = () => {}; - } - - // 处理 operationColumnData 的属性 - for (const key in table.value.operationColumnData) { - const element = table.value.operationColumnData[key]; - if (element.show === undefined) element.show = true; - } + intTableData(table.value); } function rowKeyFun(row) { @@ -256,13 +231,13 @@ function handleAddCallback() { function handleResetForm() { for (const key in table.value.column) { let item = table.value.column[key]; - if (Array.isArray(item.valueE)) { - item.valueE = []; - } else if (typeof item.valueE === "number") { - item.valueE = ""; - } else if (typeof item.valueE === "boolean") { + if (Array.isArray(item.edit.valueE)) { + item.edit.valueE = []; + } else if (typeof item.edit.valueE === "number") { + item.edit.valueE = ""; + } else if (typeof item.edit.valueE === "boolean") { } else { - item.valueE = ""; + item.edit.valueE = ""; } } } @@ -277,6 +252,21 @@ function pageIndexChange(o) { table.value.search.PageIndex = o - 1; fetchPagedData(); } + +/** + * 排序变化时 + * @param selection + */ +function sortChange(data: { column: TableColumnCtx; prop: string; order: any }) { + if (data.order == undefined) { + table.value.search.OrderBy = defaultOrderBy.OrderBy; + table.value.search.OrderByType = defaultOrderBy.OrderByType; + } else { + table.value.search.OrderBy = data.prop; + table.value.search.OrderByType = data.order === "ascending" ? 1 : 0; + } + handleReloadPaged(); +} // 勾选 function handleSelectionChange(selection) { console.log("selection-change", selection); @@ -287,17 +277,23 @@ function searchReload() { for (let name in table.value.column) { if ( !table.value.column[name].search || - table.value.column[name].value === undefined || - table.value.column[name].value === null || - table.value.column[name].value === "" + table.value.column[name].search.value === undefined || + table.value.column[name].search.value === null || + table.value.column[name].search.value === "" ) { continue; } - table.value.column[name].value = ""; + table.value.column[name].search.value = ""; } } // 查询 function handleReloadPaged(reload = true) { + if (defaultOrderBy == null) { + defaultOrderBy = { + OrderBy: table.value.search.OrderBy, + OrderByType: table.value.search.OrderByType, + }; + } if (table.value.search === undefined || table.value.search.PageIndex === undefined) { table.value.search.PageIndex = 0; table.value.search.PageSize = 20; @@ -306,9 +302,9 @@ function handleReloadPaged(reload = true) { for (let name in table.value.column) { if ( !table.value.column[name].search || - table.value.column[name].value === undefined || - table.value.column[name].value === null || - table.value.column[name].value === "" + table.value.column[name].search.value === undefined || + table.value.column[name].search.value === null || + table.value.column[name].search.value === "" ) { continue; } @@ -323,10 +319,10 @@ function handleReloadPaged(reload = true) { } else data.ConditionalType = ConditionalType.Equal; data.FieldName = name.charAt(0).toUpperCase() + name.slice(1); - data.FieldValue = table.value.column[name].value.toString(); + data.FieldValue = table.value.column[name].search.value.toString(); - if (table.value.column[name].searchType != undefined) { - let v: number = table.value.column[name].searchType || 0; + if (table.value.column[name].search.searchType != undefined) { + let v: number = table.value.column[name].search.searchType || 0; data.ConditionalType = v; } table.value.search.Conditions.push(data); @@ -342,37 +338,6 @@ function handleReloadPaged(reload = true) { } // 加载前置数据(如查询条件的下拉选择数据) async function fetchInitData() { - for (const key in table.value.column) { - const element = table.value.column[key]; - if (element.type === "dropdown") { - if (!element.setting.datasource) { - // 不安全取消 存在值就不处理 - // let rdata = await eval(element.setting.datasourceStr); - // element.setting.datasource = rdata.data; - // console.log(key + " " + element.setting.datasourceStr, rdata); - } - } - if ( - element.custom == undefined && - (element.type === "switch" || - element.type === "dropdown" || - element.type === "string" || - element.type === undefined) - ) { - if (element.type === "string" || element.type === undefined) - element.custom = (row) => row[key]; - else { - element.custom = (row) => { - let sc = element.setting.datasource.find( - (s) => s[element.setting.mapValue] + "" == row[key] + "" - ); - return !sc ? row[key] : sc[element.setting.maplabel]; - }; - } - } else if (element.custom == undefined) { - element.custom = (row) => row[key]; - } - } setTimeout(() => { init.value = true; appStyle(); @@ -415,10 +380,10 @@ function fetchPagedData() {
- +
- + 重置 - -
- - - - -
@@ -519,9 +451,9 @@ function fetchPagedData() { :data="table.data" :border="table.border" :highlight-current-row="true" - style="width: 100%" :row-key="rowKeyFun" @selection-change="handleSelectionChange" + @sort-change="sortChange" > diff --git a/src/utils/rules.ts b/src/utils/rules.ts index 3ca2c0f..1eed0f8 100644 --- a/src/utils/rules.ts +++ b/src/utils/rules.ts @@ -40,6 +40,14 @@ export const ruleNumber = [ trigger: "blur" } ]; +export const ruleClassName = [ + { + pattern: /^[1-9]\d*班$/, + message: "请输入正确班级名称[例:101班]", + trigger: "blur" + }, + ...ruleRequired +]; export const ruleRequiredNumber = [ { required: true, message: "不能为空", trigger: "blur" }, { diff --git a/src/views/admin/index.vue b/src/views/admin/index.vue index 46d8fda..d1b3168 100644 --- a/src/views/admin/index.vue +++ b/src/views/admin/index.vue @@ -1,6 +1,6 @@ diff --git a/src/views/toschoolinfomanage/index.vue b/src/views/toschoolinfomanage/index.vue index 55a58fa..7802a43 100644 --- a/src/views/toschoolinfomanage/index.vue +++ b/src/views/toschoolinfomanage/index.vue @@ -23,7 +23,7 @@ v-model="query.grade" placeholder="请选择年级" clearable - style="width: 140px" + style="width: 120px" > + 下载模版
- +