499 lines
12 KiB
Vue
499 lines
12 KiB
Vue
<template>
|
|
<div class="app-container">
|
|
<div
|
|
style="color: #606266; font-size: 1.5em; font-weight: bold"
|
|
v-if="selectionCount == 1"
|
|
>
|
|
双击选中职位
|
|
</div>
|
|
<h2></h2>
|
|
<div class="search-container1">
|
|
<!-- 搜索项目 -->
|
|
<el-form :inline="true" :model="search">
|
|
<el-form-item>
|
|
<el-select
|
|
v-model="search.schoolId"
|
|
placeholder="学校"
|
|
clearable
|
|
filterable
|
|
@change="schoolChange"
|
|
>
|
|
<el-option
|
|
v-for="item in schoolList"
|
|
:key="item.value"
|
|
:label="item.text"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item>
|
|
<el-select
|
|
v-model="search.positionType"
|
|
placeholder="职位类型"
|
|
clearable
|
|
filterable
|
|
:disabled="userType > 0"
|
|
>
|
|
<el-option
|
|
v-for="item in positionList"
|
|
:key="item.value"
|
|
:label="item.text"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item>
|
|
<el-select
|
|
v-model="search.grade"
|
|
placeholder="年级"
|
|
clearable
|
|
filterable
|
|
@change="gradeChange"
|
|
>
|
|
<el-option
|
|
v-for="item in gradeList"
|
|
:key="item.value"
|
|
:label="item.text"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item>
|
|
<el-select v-model="search.classId" placeholder="班级" clearable filterable>
|
|
<el-option
|
|
v-for="item in classList"
|
|
:key="item.value"
|
|
:label="item.text"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item>
|
|
<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-select>
|
|
</el-form-item>
|
|
|
|
<!-- <el-form-item>
|
|
<el-select
|
|
v-model="search.status"
|
|
placeholder="状态"
|
|
clearable
|
|
filterable
|
|
>
|
|
<el-option
|
|
v-for="item in statusList"
|
|
:key="item.value"
|
|
:label="item.text"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item> -->
|
|
|
|
<el-form-item>
|
|
<el-button type="primary" @click="handleReloadPaged" :icon="Search"
|
|
>查询</el-button
|
|
>
|
|
</el-form-item>
|
|
|
|
<el-form-item>
|
|
<el-button type="success" @click="asyncPosition">选择勾选职位</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
<!-- <div class="toolbar-container">
|
|
<el-button type="success" plain @click="handleAdd"
|
|
>新增</el-button
|
|
>
|
|
<el-button type="primary" plain @click="handleEdit"
|
|
>修改</el-button
|
|
>
|
|
</div> -->
|
|
<div class="tableBox">
|
|
<el-table
|
|
:data="table.data"
|
|
ref="positionTb"
|
|
row-key="id"
|
|
:border="table.border"
|
|
@row-dblclick="rowDblclick"
|
|
height="600px"
|
|
style="width: 768px; max-width: 768px"
|
|
:expand-row-keys="tableExpandRowKeys"
|
|
:tree-props="{ children: 'children' }"
|
|
@selection-change="handleSelectionChange"
|
|
>
|
|
<el-table-column type="selection" width="40" />
|
|
<el-table-column prop="name" label="职位名称[双击行快速选择]" width="220">
|
|
<template #default="scope">
|
|
<span
|
|
>{{ scope.row.name }}
|
|
<el-tag v-show="selectPositions.find((s) => scope.row.Id == s.id)"
|
|
>已选</el-tag
|
|
>
|
|
</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="positionLevel" label="职级" width="80">
|
|
<template #default="scope">
|
|
<el-tag v-if="scope.row.positionLevel === 1" type="danger">教委</el-tag>
|
|
<el-tag v-else-if="scope.row.positionLevel === 2" type="warning">校级</el-tag>
|
|
<el-tag v-else-if="scope.row.positionLevel === 3">年级</el-tag>
|
|
<el-tag v-else-if="scope.row.positionLevel === 4" type="success">班级</el-tag>
|
|
<el-tag v-else-if="scope.row.positionLevel === 5" type="info">教师</el-tag>
|
|
<el-tag v-else-if="scope.row.positionType === 1" type="info">学生</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="学校 - 年级 - 班级 - 学科">
|
|
<template #default="scope">
|
|
<el-tag v-if="!scope.row.status" type="danger">锁定</el-tag>
|
|
{{ scope.row.schoolName }} {{ scope.row.grade }} {{ scope.row.className }}
|
|
{{ scope.row.subjectName }}
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-card class="box-card">
|
|
<div class="clearfix clearfixCss">
|
|
<span style="line-height: 32px; font-weight: 600"
|
|
>已选职位[{{ selectPositions.length }}]</span
|
|
>
|
|
<el-button
|
|
style="float: right"
|
|
type="success"
|
|
@click="handleConfirm"
|
|
:icon="Check"
|
|
>提交分配职位</el-button
|
|
>
|
|
</div>
|
|
<div class="positionGap">
|
|
<el-tag
|
|
v-for="(p, o) in selectPositions"
|
|
:key="o"
|
|
closable
|
|
@close="tagClose(p)"
|
|
>
|
|
{{ p.name }} {{ p.schoolName }} {{ p.grade }} {{ p.className }}
|
|
{{ p.subjectName }}
|
|
</el-tag>
|
|
</div>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import { ref, reactive, onMounted } from "vue";
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
import type { FormInstance } from "element-plus";
|
|
import {
|
|
getSchoolData,
|
|
getClassCombo,
|
|
getSubjectData,
|
|
getPositionList,
|
|
getPositions,
|
|
Position,
|
|
} from "@/api/userCenter";
|
|
import { ComboModel } from "@/components/hTable/hTable";
|
|
import { Check, Search } from "@element-plus/icons-vue";
|
|
|
|
interface SearchParams {
|
|
schoolId: string | number;
|
|
positionType: string | number;
|
|
grade: string;
|
|
classId: string | number;
|
|
subjectId: string | number;
|
|
status: string | number;
|
|
}
|
|
|
|
interface TableData {
|
|
data: Position[];
|
|
selectRows: Position[];
|
|
border: boolean;
|
|
}
|
|
|
|
interface Dialog {
|
|
id: number;
|
|
parentPosition: Position | null;
|
|
close: boolean;
|
|
title: string;
|
|
visible: boolean;
|
|
width: string;
|
|
}
|
|
|
|
const props = defineProps({
|
|
userType: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
positions: {
|
|
type: Array as () => number[],
|
|
default: () => [],
|
|
},
|
|
selectionCount: {
|
|
type: Number,
|
|
default: 999,
|
|
},
|
|
});
|
|
|
|
const emit = defineEmits(["handleCheckCallback", "handleCheckCallback"]);
|
|
|
|
const search = reactive<SearchParams>({
|
|
schoolId: "",
|
|
positionType: "",
|
|
grade: "",
|
|
classId: "",
|
|
subjectId: "",
|
|
status: 1,
|
|
});
|
|
|
|
const selectPositions = ref<Position[]>([]);
|
|
const schoolList = ref<ComboModel[]>([]);
|
|
const gradeList = ref<ComboModel[]>([
|
|
{ value: "初一", text: "初一" },
|
|
{ value: "初二", text: "初二" },
|
|
{ value: "初三", text: "初三" },
|
|
{ value: "高一", text: "高一" },
|
|
{ value: "高二", text: "高二" },
|
|
{ value: "高三", text: "高三" },
|
|
]);
|
|
const classList = ref<ComboModel[]>([]);
|
|
const subjectList = ref<ComboModel[]>([]);
|
|
const tableExpandRowKeys = ref<string[]>([]);
|
|
const positionList = ref<ComboModel[]>([
|
|
{ text: "学生", value: 1 },
|
|
{ text: "教师", value: 2 },
|
|
{ text: "管理员", value: 3 },
|
|
]);
|
|
const statusList = ref<ComboModel[]>([
|
|
{ text: "正常", value: 1 },
|
|
{ text: "锁定", value: 2 },
|
|
]);
|
|
|
|
const table = reactive<TableData>({
|
|
data: [],
|
|
selectRows: [],
|
|
border: true,
|
|
});
|
|
|
|
const dialog = reactive<Dialog>({
|
|
id: 0,
|
|
parentPosition: null,
|
|
close: false,
|
|
title: "编辑职位",
|
|
visible: false,
|
|
width: "800px",
|
|
});
|
|
|
|
const authDialog = reactive<Dialog>({
|
|
id: 0,
|
|
parentPosition: null,
|
|
close: false,
|
|
title: "职位授权",
|
|
visible: false,
|
|
width: "400px",
|
|
});
|
|
|
|
const positionTb = ref<FormInstance>();
|
|
|
|
const userTypeToPosition = () => {
|
|
switch (props.userType) {
|
|
case 1:
|
|
search.positionType = 1;
|
|
break;
|
|
case 2:
|
|
search.positionType = 2;
|
|
break;
|
|
case 15:
|
|
search.positionType = 3;
|
|
break;
|
|
default:
|
|
search.positionType = -1;
|
|
break;
|
|
}
|
|
};
|
|
|
|
const rowDblclick = (row: Position) => {
|
|
if (props.selectionCount === 1) {
|
|
emit("handleCheckCallback", [row]);
|
|
} else {
|
|
asyncPosition(null, [row]);
|
|
}
|
|
};
|
|
|
|
const handleReloadPaged = () => {
|
|
fetchPagedData();
|
|
};
|
|
|
|
const handleAdd = () => {
|
|
if (table.selectRows.length > 0) {
|
|
dialog.parentPosition = table.selectRows[0];
|
|
dialog.title = `${table.selectRows[0].name}-添加附属职位`;
|
|
} else {
|
|
dialog.title = "添加职位";
|
|
dialog.parentPosition = null;
|
|
}
|
|
dialog.id = 0;
|
|
dialog.visible = true;
|
|
};
|
|
|
|
const handleEdit = () => {
|
|
if (table.selectRows.length === 0) {
|
|
ElMessage.warning("未勾选记录");
|
|
return;
|
|
}
|
|
if (table.selectRows.length > 1) {
|
|
ElMessage.warning("当前操作只支持勾选一条记录");
|
|
return;
|
|
}
|
|
dialog.id = table.selectRows[0].id;
|
|
dialog.parentPosition = null;
|
|
dialog.title = "编辑职位";
|
|
dialog.visible = true;
|
|
};
|
|
|
|
const handleRefreshCallback = () => {
|
|
dialog.visible = false;
|
|
authDialog.visible = false;
|
|
handleReloadPaged();
|
|
};
|
|
|
|
const handleSelectionChange = (selection: Position[]) => {
|
|
table.selectRows = selection;
|
|
};
|
|
|
|
const fetchInitData = async () => {
|
|
const schoolRes = await getSchoolData();
|
|
if (schoolRes.code === 200) {
|
|
schoolList.value = schoolRes.data;
|
|
if (schoolList.value.length > 0) {
|
|
search.schoolId = schoolList.value[0].value;
|
|
schoolChange();
|
|
fetchPagedData();
|
|
}
|
|
}
|
|
|
|
const subjectRes = await getSubjectData();
|
|
if (subjectRes.code === 200) {
|
|
subjectList.value = subjectRes.data;
|
|
}
|
|
};
|
|
|
|
const schoolChange = () => {
|
|
search.grade = "";
|
|
search.classId = "";
|
|
search.subjectId = "";
|
|
getClass();
|
|
};
|
|
|
|
const gradeChange = () => {
|
|
search.classId = "";
|
|
search.subjectId = "";
|
|
getClass();
|
|
};
|
|
|
|
const getClass = async () => {
|
|
const data = {
|
|
schoolId: search.schoolId || 0,
|
|
grade: search.grade,
|
|
};
|
|
const res = await getClassCombo(data);
|
|
if (res.code === 200) {
|
|
classList.value = res.data;
|
|
}
|
|
};
|
|
|
|
const fetchPagedData = async () => {
|
|
const data = {
|
|
SchoolId: search.schoolId || 0,
|
|
Grade: search.grade,
|
|
ClassId: search.classId || 0,
|
|
SubjectId: search.subjectId || 0,
|
|
PositionType: search.positionType || 0,
|
|
Status: search.status || 0,
|
|
};
|
|
const res = await getPositionList(data);
|
|
if (res.code === 200) {
|
|
table.data = res.data;
|
|
tableExpandRowKeys.value = [];
|
|
tableExpandRowKeys.value = table.data.map((s) => s.id.toString());
|
|
debugger;
|
|
tableExpandRowKeys.value.push(
|
|
res.data.find((s) => s.id == 1).children.map((s) => s.id.toString())
|
|
);
|
|
}
|
|
};
|
|
|
|
const handleConfirm = () => {
|
|
if (selectPositions.value.length === 0) {
|
|
ElMessage.warning("请选择要分配的职位");
|
|
return;
|
|
}
|
|
emit("handleCheckCallback", selectPositions.value);
|
|
};
|
|
|
|
const tagClose = (p: Position) => {
|
|
selectPositions.value = selectPositions.value.filter((s) => s !== p);
|
|
};
|
|
|
|
const asyncPosition = (event: Event | null, rows?: Position[]) => {
|
|
const datas = rows || table.selectRows;
|
|
if (datas.length === 0) {
|
|
ElMessage.warning("请选择要分配的职位");
|
|
return;
|
|
}
|
|
const pIds = selectPositions.value.map((s) => s.id);
|
|
selectPositions.value = selectPositions.value.concat(
|
|
datas.filter((s) => !pIds.includes(s.id))
|
|
);
|
|
};
|
|
|
|
onMounted(async () => {
|
|
userTypeToPosition();
|
|
if (props.positions && props.positions.length > 0) {
|
|
const res = await getPositions(props.positions);
|
|
selectPositions.value = res.data.map((s) => ({ ...s }));
|
|
}
|
|
fetchInitData();
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.tableBox {
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex-wrap: nowrap;
|
|
align-content: center;
|
|
justify-content: flex-start;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
}
|
|
|
|
:deep(.el-card__header) {
|
|
padding: 8px 8px;
|
|
}
|
|
|
|
.clearfixCss {
|
|
width: 350px;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.positionGap {
|
|
height: calc(600px - 90px);
|
|
overflow-x: auto;
|
|
width: 350px;
|
|
gap: 10px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-wrap: nowrap;
|
|
justify-content: flex-start;
|
|
align-items: flex-start;
|
|
}
|
|
</style>
|