优化 部分业务逻辑

This commit is contained in:
小肥羊 2025-08-25 18:44:43 +08:00
parent 3d3b8a45ae
commit d90c357cad
5 changed files with 108 additions and 99 deletions

View File

@ -10,13 +10,20 @@ 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 { ConditionalType, Dialog, TableColumn, 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";
@ -27,12 +34,12 @@ const props = defineProps({
//** */
Row: {
type: Object as PropType<any>,
default: () => ({})
default: () => ({}),
},
tableConfig: {
type: Object as PropType<TableConfig>,
default: () => ({})
}
default: () => ({}),
},
});
const table = ref<TableConfig>(props.tableConfig);
@ -78,13 +85,13 @@ const dialog = ref<Dialog>({
data: [],
custom: {},
component: null, //
visible: false //
visible: false, //
},
edit: {
id: -1,
title: "", // title
visible: false //
}
visible: false, //
},
});
const appB = ref<HTMLElement>(null);
@ -112,8 +119,7 @@ function intdata() {
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.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;
@ -137,21 +143,21 @@ function rowKeyFun(row) {
return row.customId;
}
function execute(obj, scope, btn) {
if (Object.prototype.toString.call(obj) === "[object Function]")
return obj(scope, btn);
if (Object.prototype.toString.call(obj) === "[object Function]") return obj(scope, btn);
return eval(obj);
}
function getOperationColumnWidth() {
let hFontSize = getComputedStyle(window.document.documentElement)[
"font-size"
].replace("px", "");
let hFontSize = getComputedStyle(window.document.documentElement)["font-size"].replace(
"px",
""
);
let defWidth = 10 + 2 + 30;
let width = eval(
table.value.operationColumnData
.filter(s => !s.topBtn && s.show)
.map(s => defWidth + s.label.length * (hFontSize || 16))
.filter((s) => !s.topBtn && s.show)
.map((s) => defWidth + s.label.length * (hFontSize || 16))
.join("+")
);
width = width < 100 ? 100 : width;
@ -190,13 +196,18 @@ function handleEdit(obj, row) {
dialog.value.visible = true;
dialog.value.width = "500px";
}
function handleCustom(obj, row, custom) {
async function handleCustom(obj, row, custom: ButtonCustomConfig) {
dialog.value.custom.data = row || [];
dialog.value.custom.custom = custom || [];
//
dialog.value.custom.component = defineAsyncComponent({
loader: () => import(/* @vite-ignore */ `../../views/${custom.src}.vue`)
loader: () => import(/* @vite-ignore */ `../../views/${custom.src}.vue`),
});
// let r = shallowRef(null);
// const module = await import(custom.src);
// r.value = module.default;
// dialog.value.custom.component = r;
dialog.value.width = custom.width;
dialog.value.title = custom.title;
dialog.value.edit.visible = false;
@ -215,11 +226,11 @@ function handleDelete(obj, row) {
return;
}
const ids: any[] = [];
row.forEach(it => {
row.forEach((it) => {
ids.push(it.id);
});
ElMessageBox.confirm("此操作将永久删除勾选记录, 是否继续?").then(() => {
Api.delete(ids).then(res => {
Api.delete(ids).then((res) => {
if (res.code === 200) {
handleReloadPaged();
ElMessage.success("删除成功");
@ -256,10 +267,7 @@ function handleSelectionChange(selection) {
}
//
function handleReloadPaged(reload = true) {
if (
table.value.search === undefined ||
table.value.search.PageIndex === undefined
) {
if (table.value.search === undefined || table.value.search.PageIndex === undefined) {
table.value.search.PageIndex = 0;
table.value.search.PageSize = 20;
}
@ -321,17 +329,17 @@ async function fetchInitData() {
element.type === undefined)
) {
if (element.type === "string" || element.type === undefined)
element.custom = row => row[key];
element.custom = (row) => row[key];
else {
element.custom = row => {
element.custom = (row) => {
let sc = element.setting.datasource.find(
s => s[element.setting.mapValue] + "" == row[key] + ""
(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];
element.custom = (row) => row[key];
}
}
setTimeout(() => {
@ -343,9 +351,7 @@ function showTips(item, value) {
if (item.width == undefined) {
return false;
}
return (
getByteLen(item.custom(value) + "") * 16 < item.width.replace("px", "")
);
return getByteLen(item.custom(value) + "") * 16 < item.width.replace("px", "");
}
function getByteLen(str) {
let len = 0;
@ -358,11 +364,11 @@ function getByteLen(str) {
function fetchPagedData() {
for (const iterator of table.value.search.defaultConditions) {
if (!iterator) continue;
if (!table.value.search.Conditions.find(s => s == iterator)) {
if (!table.value.search.Conditions.find((s) => s == iterator)) {
table.value.search.Conditions.push(iterator);
}
}
Api.PageList(table.value.search).then(res => {
Api.PageList(table.value.search).then((res) => {
if (res.code === 200) {
table.value.data = res.data.data.map((s, i) => {
return { ...s, customId: i };
@ -378,11 +384,7 @@ function fetchPagedData() {
<div ref="appB_S" class="search-container1">
<!-- 搜索项目 -->
<el-form v-if="table.search.show" :inline="true" :model="table.search">
<el-form-item
v-for="(o, n, i) in table.column"
v-show="o.search"
:key="i"
>
<el-form-item v-for="(o, n, i) in table.column" v-show="o.search" :key="i">
<el-date-picker
v-if="o.type.trim() == 'datetime'"
v-model="o.value as Date"
@ -424,10 +426,7 @@ function fetchPagedData() {
<el-input v-else v-model="o.value as string" :placeholder="o.label" />
</el-form-item>
<el-form-item>
<el-button
type="primary"
:icon="Search"
@click="handleReloadPaged(false)"
<el-button type="primary" :icon="Search" @click="handleReloadPaged(false)"
>查询</el-button
>
</el-form-item>
@ -471,7 +470,7 @@ function fetchPagedData() {
<!-- 头部按钮组 -->
<el-button
v-for="(e, i) in table.operationColumnData.filter(
s => s.topBtn && hasPerms(s.perms)
(s) => s.topBtn && hasPerms(s.perms)
)"
v-show="execute(e['show'], {}, e)"
:key="i"
@ -495,7 +494,7 @@ function fetchPagedData() {
<el-table-column
v-if="
table.operationColumn &&
table.operationColumnData.filter(s => !s.topBtn).length > 0
table.operationColumnData.filter((s) => !s.topBtn).length > 0
"
label="操作"
:width="getOperationColumnWidth()"
@ -504,7 +503,7 @@ function fetchPagedData() {
<div class="columnTemplate">
<el-button
v-for="(e, i) in table.operationColumnData.filter(
s => !s.topBtn && hasPerms(s.perms)
(s) => !s.topBtn && hasPerms(s.perms)
)"
v-show="execute(e['show'], scope, e)"
:key="i"

View File

@ -9,7 +9,7 @@ import { ruleRequired, ruleRequiredNumber } from "@/utils/rules";
const ControllerName = "ExamUserInfo";
defineOptions({
name: ControllerName
name: ControllerName,
});
const props = defineProps<{
@ -30,8 +30,13 @@ const tableData: TableConfig = {
PageSize: 60,
OrderBy: "AssignRanking", //
OrderByType: 0,
defaultConditions: [], //
Conditions: []
defaultConditions: [
{
FieldName: "ExamId",
FieldValue: props.data[0].examId + "",
},
], //
Conditions: [],
},
operationColumn: true, //
operationColumnData: [
@ -43,7 +48,7 @@ const tableData: TableConfig = {
click: (o, r, c) => {
tableData.search.OrderByType = 1;
c();
}
},
},
{
//
@ -53,7 +58,7 @@ const tableData: TableConfig = {
click: (o, r, c) => {
tableData.search.OrderByType = 0;
c();
}
},
},
{
topBtn: false, //
@ -64,9 +69,9 @@ const tableData: TableConfig = {
title: "考试学生班级详情", // title
src: "exam/userExam", //
width: "1600px", //
height: "800px" //
}
}
height: "800px", //
},
},
],
column: {
//
@ -74,78 +79,78 @@ const tableData: TableConfig = {
label: "姓名",
search: true,
searchType: ConditionalType.Like, //
width: "180px"
width: "180px",
},
语文: {
label: "语文",
search: false,
width: "100px",
custom: row => row.subjectDic.语文
custom: (row) => row.subjectDic.语文,
},
数学: {
label: "数学",
search: false,
width: "100px",
custom: row => row.subjectDic.数学
custom: (row) => row.subjectDic.数学,
},
英语: {
label: "英语",
search: false,
width: "100px",
custom: row => row.subjectDic.英语
custom: (row) => row.subjectDic.英语,
},
物理: {
label: "物理",
search: false,
width: "100px",
custom: row => row.subjectDic.物理
custom: (row) => row.subjectDic.物理,
},
化学: {
label: "化学",
search: false,
width: "100px",
custom: row => row.subjectDic.化学
custom: (row) => row.subjectDic.化学,
},
生物: {
label: "生物",
search: false,
width: "100px",
custom: row => row.subjectDic.生物
custom: (row) => row.subjectDic.生物,
},
政治: {
label: "政治",
search: false,
width: "100px",
custom: row => row.subjectDic.政治
custom: (row) => row.subjectDic.政治,
},
历史: {
label: "历史",
search: false,
width: "100px",
custom: row => row.subjectDic.历史
custom: (row) => row.subjectDic.历史,
},
地理: {
label: "地理",
search: false,
width: "100px",
custom: row => row.subjectDic.地理 ?? "--"
custom: (row) => row.subjectDic.地理 ?? "--",
},
assignScore: {
label: "赋分总分",
search: false,
width: "180px"
width: "180px",
},
assignRanking: {
label: "赋分后的排名",
search: false,
width: "200px"
}
width: "200px",
},
},
data: [],
pageData: {
total: 0
total: 0,
},
selectRows: []
selectRows: [],
};
const showTable = ref(false);
@ -160,10 +165,10 @@ const exam = props.data[0];
<template>
<div>
<div class="p-[10px] text-[1.5rem]">
<strong>学校</strong>{{ exam.schoolName }}&nbsp;&nbsp;
<strong>年级</strong>{{ exam.gradeLevel + exam.gradeYear }}&nbsp;&nbsp;
<strong>班级</strong>{{ exam.className }}&nbsp;&nbsp;
<strong>考试名称</strong>{{ exam.examName }}&nbsp;&nbsp;
<strong>学校</strong>{{ exam.schoolName }}&nbsp;&nbsp; <strong>年级</strong
>{{ exam.gradeLevel + exam.gradeYear }}&nbsp;&nbsp; <strong>班级</strong
>{{ exam.className }}&nbsp;&nbsp; <strong>考试名称</strong
>{{ exam.examName }}&nbsp;&nbsp;
<!-- <strong>考试类型</strong>{{exam.className}}&nbsp;&nbsp;
<strong>试卷类型</strong>{{exam.className}}&nbsp;&nbsp; -->
</div>

View File

@ -77,7 +77,7 @@
style="width: 180px"
>
<el-option
v-for="(item, i) in reliefSubTimeEnum"
v-for="(item, i) in reliefTypeEnum"
:key="i"
autocomplete="off"
:label="item.text"
@ -105,12 +105,14 @@
<el-select
v-model="form.gLSubject"
filterable
clearable
placeholder="历史/地理"
style="width: 180px"
>
<el-option
v-for="(item, i) in subject1"
:key="i"
clearable
autocomplete="off"
:label="item.text"
:value="item.value"
@ -121,6 +123,7 @@
<el-select
v-model="form.gSubject1"
filterable
clearable
placeholder="小学科"
style="width: 180px"
>
@ -161,8 +164,8 @@
</el-row>
<el-row class="pt-4">
<el-col :span="24">
<el-form-item label="职位" prop="positionIds" :rules="ruleRequired">
<el-button type="success" @click="CheckPosition()">分配职位</el-button>
<el-form-item label="就读班级" prop="positionIds" :rules="ruleRequired">
<el-button type="success" @click="CheckPosition()">选择就读班级</el-button>
</el-form-item>
</el-col>
</el-row>
@ -283,7 +286,7 @@ const formLabelWidth = "120px";
const size = "small";
const loading = ref(false);
const reliefSubTimeEnum = ref<ComboModel[]>();
const reliefTypeEnum = ref<ComboModel[]>();
const subject1 = ref<ComboModel[]>([
{ value: 4, text: "物理" },
@ -323,7 +326,7 @@ const defaultSubjectLevel = reactive({
const form = ref<FormData>({
id: props.id,
account: "",
userType: 2,
userType: 1,
level: 0,
passWord: "",
realName: "",
@ -443,7 +446,22 @@ const handleResetForm = () => {
};
const fetchInitData = async () => {
reliefSubTimeEnum.value = (await getenum("ReliefSubTimeEnum")).data;
reliefTypeEnum.value = `
1.复读生
2.艺术生
3.春招生
4.领导承诺批准全免
5.资源班
6.国际班
7.合同制收费学校
8.渠道商家属
9.新开班但领导承诺第一学期不收费`
.split("\n")
.filter((s) => s.trim())
.map((s) => {
const [value, text] = s.trim().split(".");
return { value: text.trim(), text: text.trim() };
});
};
const fetchFormData = async () => {
@ -494,7 +512,7 @@ const userTypeChange = () => {
};
const CheckPosition = () => {
dialog.title = "选择职位";
dialog.title = "选择就读班级";
dialog.visible = true;
PositionFormIds.value = positionList.value
.filter((s) => s.enable !== false)

View File

@ -84,28 +84,11 @@
</el-select>
</el-form-item>
<el-form-item style="width: 100px">
<el-select v-model="search.subjectId" placeholder="科目" clearable filterable>
<el-option
v-for="item in subjectList"
:key="item.value"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleReloadPaged" :icon="Search"
>查询</el-button
>
</el-form-item>
<el-form-item v-show="selectUser">
<el-button type="success" @click="selectUserCallBack()" icon="el-icon-check"
>选择用户</el-button
>
</el-form-item>
</el-form>
</div>
<div class="toolbar-container" v-show="!selectUser">

View File

@ -106,7 +106,9 @@
</el-form-item>
<el-form-item>
<el-button type="success" @click="asyncPosition">选择勾选职位</el-button>
<el-button type="success" @click="asyncPosition">{{
userType == 1 ? "选择勾选班级" : "选择勾选职位"
}}</el-button>
</el-form-item>
</el-form>
</div>
@ -163,7 +165,9 @@
<el-card class="box-card">
<div class="clearfix clearfixCss">
<span style="line-height: 32px; font-weight: 600"
>已选职位[{{ selectPositions.length }}]</span
>{{ userType == 1 ? "就读班级" : "已选职位" }}[{{
selectPositions.length
}}]</span
>
<el-button
style="float: right"