123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- <template>
- <Transition :enter-active-class="proxy?.animate.mask.enter" :leave-active-class="proxy?.animate.mask.leave">
- <div class="mask" v-if="optionWindow.show"></div>
- </Transition>
- <Transition :enter-active-class="proxy?.animate.dialog.enter" :leave-active-class="proxy?.animate.dialog.leave">
- <div class="optionWindow" v-if="optionWindow.show">
- <div class="box">
- <div class="top">
- <div class="title">手动选择</div>
- <div class="close" @click="close"></div>
- </div>
- <div class="content">
- <div class="searchBox">
- <el-select class="select" v-model="optionForm.grade" :popper-append-to-body="false" placeholder="年级"
- clearable>
- <el-option v-for="item in gradeLists" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- <el-select class="select" v-model="optionForm.class" :popper-append-to-body="false" placeholder="班级"
- clearable>
- <el-option v-for="item in classData" :key="item.value" :label="item.name" :value="item.id" />
- </el-select>
- <el-input class="input" v-model="optionForm.name" placeholder="请输入学生姓名" clearable />
- <el-button class="button" type="primary" @click="getSearchStudent">搜索</el-button>
- </div>
- <div class="tableBox">
- <el-table ref="myTable" :data="tableData" class="table" :class="{ 'table2': props.selectType == 'single' }"
- @cell-click="handleCellClickChange" @row-dblclick="handleDblclick" @select-all="handleSelectAll"
- highlight-current-row>
- <el-table-column type="selection" width="55" v-if="props.selectType == 'multiple'" />
- <el-table-column label="头像" width="120">
- <template #default="scope">
- <el-avatar :src="scope.row.face_pic || scope.row.logo_url" />
- </template>
- </el-table-column>
- <el-table-column prop="className" label="班级" width="180" />
- <el-table-column prop="name" label="姓名" width="180" />
- <el-table-column prop="genderName" label="性别" />
- <el-table-column prop="student_number" label="学号" />
- </el-table>
- </div>
- <div class="page">
- <el-pagination layout="prev, pager, next" :total="page.total" :page-size="page.size"
- :page-sizes="[20, 60, 120]" :current-page="page.page" @size-change="handleSizeChange"
- @current-change="handleCurrentChange" />
- </div>
- <div class="multipleList" v-if="props.selectType == 'multiple'">
- <ul ref="scrollContainer">
- <li v-for="item in selectValue" :key="item.student_id">
- <div class="pic">
- <img :src="item.face_pic || item.logo_url" />
- <i class="del" @click="delChooseStudent(item)"></i>
- </div>
- <div>{{ item.name }}</div>
- </li>
- </ul>
- </div>
- </div>
- <div class="bottom">
- <div class="btn" @click="confirm">确定</div>
- </div>
- </div>
- </div>
- </Transition>
- </template>
- <script setup lang="ts">
- import useAppStore from '@/store/modules/app';
- import dataDictionary from "@/utils/dataDictionary"
- const { proxy } = getCurrentInstance() as any;
- const emit = defineEmits(['returnData']);
- const myTable = ref();
- const scrollContainer = ref();
- //父值
- const props = defineProps({
- selectType: {
- type: String,
- default: 'single',//单选single 多选multiple
- },
- });
- //筛选班别
- const classData = computed(() => {
- optionForm.value.class = "";
- let list = classList.value.filter((item: any) => {
- return item.grade == optionForm.value.grade;
- })
- return list;
- });
- const data = reactive<any>({
- optionForm: {
- gesture: true,
- hasHB: false,
- },
- optionWindow: {
- show: false,
- time: "",
- },
- classList: [],
- tableData: [],
- page: {
- current: 1,
- size: 100,
- total: 0,
- },
- selectValue: [],
- });
- const { optionForm, optionWindow, classList, tableData, page, selectValue } = toRefs(data);
- //打开
- const open = (data: any) => {
- getClass();
- getStudent();
- selectValue.value = [];
- optionWindow.value.show = true;
- };
- //关闭
- const close = () => {
- optionWindow.value.show = false;
- };
- //获取班级列表
- const getClass = () => {
- const list: any = useAppStore().getClass();
- if (list.length) {
- classList.value = list;
- console.log("classList.value", classList.value)
- } else {
- let params = {
- per_page: 1000,
- page: 1,
- };
- proxy?.$http.common.classList(params).then((res: any) => {
- if (res.data.length > 0) {
- let myList: any = res.data;
- classList.value = myList;
- useAppStore().setClass(myList);
- }
- });
- }
- };
- //获取学生列表
- const getStudent = () => {
- let myInfo: any = localStorage.getItem("userInfo");
- let userInfo = JSON.parse(myInfo);
- let params: any = {
- school_id: userInfo.school_id,
- class_id: optionForm.value.class,
- page: page.value.current,
- per_page: page.value.size,
- };
- if (optionForm.value.name) {
- params.name = optionForm.value.name;
- }
- proxy?.$http.common.studentList(params).then((res: any) => {
- if (res.data.length > 0) {
- let list = res.data.map((item: any) => {
- let classObj = classList.value.find((items: any) => {
- return items.id == item.class_id;
- })
- item.className = classObj?.name || "";
- item.genderName = item.gender == 1 ? "男" : "女";
- item.student_id = item.id;
- return item;
- });
- tableData.value = list;
- nextTick(() => {
- //添加点选
- let ids = selectValue.value.map((item: any) => {
- return item.student_id
- })
- list.forEach((item: any) => {
- if (ids.includes(item.student_id)) {
- myTable.value.toggleRowSelection(item, true)
- }
- })
- })
- page.value.total = res.total;
- }
- });
- };
- //搜索
- const getSearchStudent = () => {
- page.value.current = 1;
- getStudent();
- };
- //切换页码
- const handleCurrentChange = (data: number) => {
- page.value.current = data;
- getStudent();
- };
- //切换页数
- const handleSizeChange = (data: number) => {
- page.value.current = 1;
- page.value.size = data;
- getStudent();
- };
- //单选行
- const handleCellClickChange = (data: any) => {
- if (props.selectType == 'single') {
- selectValue.value = [data];
- }
- if (props.selectType == 'multiple') {
- let ids = selectValue.value.map((item: any) => {
- return item.student_id;
- })
- if (!ids.includes(data.student_id)) {
- //不在内就添加
- myTable.value.toggleRowSelection(data, true)
- selectValue.value.push(data);
- nextTick(() => {
- scrollContainer.value.scrollLeft = scrollContainer.value.scrollWidth;
- });
- } else {
- //在内就移除
- myTable.value.toggleRowSelection(data, false)
- selectValue.value = selectValue.value.filter((item: any) => {
- return item.student_id != data.student_id
- })
- }
- }
- };
- //全选/不选操作
- const handleSelectAll = (data: any) => {
- selectValue.value = data;
- };
- //双击
- const handleDblclick = (data: any) => {
- if (props.selectType == 'single') {
- confirm();
- }
- };
- //删除已选学生
- const delChooseStudent = (data: any) => {
- selectValue.value = selectValue.value.filter((item: any) => {
- return item.student_id != data.student_id
- })
- //表格勾选也移除
- myTable.value.toggleRowSelection(data, false)
- };
- //确定
- const confirm = () => {
- console.log("selectValue.value", selectValue.value)
- if (selectValue.value.length == 0) {
- proxy?.$modal.msgWarning(`请选择!`);
- return false;
- }
- if (props.selectType == 'multiple') {
- emit('returnData', selectValue.value);
- } else {
- emit('returnData', selectValue.value[0]);
- }
- close();
- };
- //年级
- const gradeLists = computed(() => {
- let myInfo: any = localStorage.getItem("userInfo");
- let userInfo = JSON.parse(myInfo);
- let obj = dataDictionary.gradeLists.find((item) => {
- return userInfo.category == item.value
- })
- return obj != undefined ? obj.child : [];
- });
- onMounted(() => {
- })
- //暴露给父组件用
- defineExpose({
- open,
- close,
- optionWindow
- })
- </script>
- <style lang="scss" scoped>
- .mask {
- position: fixed;
- height: 100vh;
- width: 100vw;
- top: 0;
- left: 0;
- background: rgba(0, 0, 0, 0.3);
- z-index: 998;
- }
- .optionWindow {
- position: fixed;
- height: 100vh;
- width: 100vw;
- top: 0;
- left: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- color: #FFFFFF;
- z-index: 999;
- .box {
- width: 50%;
- border-radius: 1.6rem;
- background: linear-gradient(60deg, #092941 -85%, #2A484B 96%);
- box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.3);
- padding: 20px;
- .top {
- color: #ffffff;
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- .title {
- font-size: 1.93rem;
- color: #13ED84;
- }
- .close {}
- }
- .content {
- margin-bottom: 20px;
- .searchBox {
- margin-bottom: 10px;
- display: flex;
- justify-content: space-between;
- .select,
- .input {
- width: 27%;
- }
- .el-select__wrapper {
- border-radius: 15px;
- color: #1A293A;
- background: radial-gradient(30% 126% at 97% 6%, #35FFC6 0%, #00FFE8 100%) !important;
- }
- .el-input__wrapper {
- width: 25%;
- background: #ffffff;
- border-radius: 15px;
- }
- .button {
- color: #1A293A;
- background: radial-gradient(141% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
- box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.5577);
- border: none;
- }
- }
- .tableBox {
- .table {
- height: 52vh;
- border-radius: 1.6rem;
- margin-bottom: 10px;
- overflow: hidden;
- }
- .el-table__body tr {
- cursor: pointer;
- }
- .el-table__body tr.current-row>td.el-table__cell {
- color: #1A293A;
- background: #07FFE7;
- }
- }
- .page {
- .el-pagination {
- display: flex;
- justify-content: center;
- .el-pager {
- margin: 0 10px !important;
- background: #D8D8D8;
- box-sizing: border-box;
- border: 1px solid #979797;
- border-radius: 15px;
- overflow: hidden;
- }
- .btn-prev,
- .btn-next {
- border-radius: 50%;
- background: radial-gradient(116% 126% at 97% 6%, #35FFC6 0%, #00FFE8 100%);
- }
- }
- }
- .multipleList {
- ul {
- display: flex;
- overflow-x: scroll;
- padding: 15px 0 0px 0;
- li {
- margin-right: 20px;
- text-align: center;
- flex-shrink: 0;
- .pic {
- width: 40px;
- height: 40px;
- position: relative;
- border-radius: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- overflow: hidden;
- box-sizing: border-box;
- border: 1px solid rgba(255, 255, 255, 0.5);
- margin: 0 auto 5px auto;
- font-size: 12px;
- img {
- width: 100%;
- }
- .del {
- width: 100%;
- height: 100%;
- position: absolute;
- z-index: 2;
- right: 0;
- top: 0;
- box-sizing: border-box;
- border: 1px solid #979797;
- background-image: url("@/assets/images/common/close.png");
- background-position: center;
- background-repeat: no-repeat;
- background-size: 30% 30%;
- background-color: rgba(255, 255, 255, 0.5);
- border-radius: 50%;
- transition: all 0.5s;
- cursor: pointer;
- display: none;
- }
- }
- &:hover {
- .del {
- display: block;
- }
- }
- }
- &::-webkit-scrollbar {
- width: 6px;
- }
- &::-webkit-scrollbar-thumb {
- border-width: 2px;
- border-radius: 3px;
- border-style: dashed;
- border-color: transparent;
- background: rgb(27, 72, 92);
- background-clip: padding-box;
- }
- &::-webkit-scrollbar-button:hover {
- border-radius: 5px;
- background: rgba(26, 62, 78, 1);
- }
- }
- }
- }
- .bottom {
- height: 3.59rem;
- align-items: center;
- color: #ffffff;
- display: flex;
- justify-content: space-around;
- .btn {
- width: 33%;
- height: 3.59rem;
- line-height: 3.59rem;
- font-size: 2rem;
- margin: 0 auto;
- border-radius: 0.83rem;
- font-size: 2rem;
- text-align: center;
- color: #1A293A;
- background: radial-gradient(141% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
- box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.5577);
- cursor: pointer;
- }
- }
- }
- }
- ::v-deep(.table .el-table__body tr:hover>td.el-table__cell) {
- background: #dddddd;
- cursor: pointer;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- }
- ::v-deep(.table .el-table__body-wrapper .el-table-column--selection .el-checkbox) {
- pointer-events: none;
- }
- ::v-deep(.table2 .el-table__body tr.current-row > td) {
- background: #13ED84 !important;
- color: #ffffff !important;
- }
- </style>
|