2023.6.16
1. 精进了一些功能 2. 修复了一些BUG 3. 整合了前端
@ -2,6 +2,10 @@ package com.sdut.labex.Factory;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.sdut.labex.entity.BorrowInfo;
|
import com.sdut.labex.entity.BorrowInfo;
|
||||||
|
import com.sdut.labex.utils.UserHolder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File: BorrowInfoFactory
|
* File: BorrowInfoFactory
|
||||||
@ -9,17 +13,23 @@ import com.sdut.labex.entity.BorrowInfo;
|
|||||||
* Author: springforest
|
* Author: springforest
|
||||||
* Description:
|
* Description:
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class BorrowInfoFactory {
|
public class BorrowInfoFactory {
|
||||||
public static BorrowInfo createBorrowInfo(JSONObject jsonObject) {
|
public static BorrowInfo createBorrowInfo(JSONObject jsonObject) {
|
||||||
BorrowInfo borrowInfo = new BorrowInfo();
|
BorrowInfo borrowInfo = new BorrowInfo();
|
||||||
|
try {
|
||||||
borrowInfo.setId(jsonObject.getInteger("id"));
|
borrowInfo.setId(jsonObject.getInteger("id"));
|
||||||
borrowInfo.setApplyUser(jsonObject.getString("applyUser"));
|
borrowInfo.setApplyUser(UserHolder.getUser().getUsername());
|
||||||
borrowInfo.setTime(jsonObject.getString("time"));
|
|
||||||
borrowInfo.setDate(jsonObject.getDate("date"));
|
borrowInfo.setDate(jsonObject.getDate("date"));
|
||||||
borrowInfo.setApplyDate(jsonObject.getDate("applyDate"));
|
borrowInfo.setApplyDate(new Date());
|
||||||
borrowInfo.setIsAdmit(jsonObject.getInteger("isAdmit"));
|
borrowInfo.setIsAdmit(jsonObject.getInteger("isAdmit"));
|
||||||
borrowInfo.setRoomName(jsonObject.getString("roomName"));
|
borrowInfo.setRoomName(jsonObject.getString("roomName"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error("json解析错误");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return borrowInfo;
|
return borrowInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.sdut.labex.config;
|
|||||||
|
|
||||||
import com.sdut.labex.interceptor.TokenInterceptor;
|
import com.sdut.labex.interceptor.TokenInterceptor;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@ -17,10 +18,10 @@ public class MVBConfig implements WebMvcConfigurer {
|
|||||||
@Resource
|
@Resource
|
||||||
private TokenInterceptor tokenInterceptor;
|
private TokenInterceptor tokenInterceptor;
|
||||||
|
|
||||||
//@Override
|
@Override
|
||||||
//public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
// registry.addInterceptor(tokenInterceptor)
|
registry.addInterceptor(tokenInterceptor)
|
||||||
// .excludePathPatterns("/login/**")
|
.excludePathPatterns("/login/**")
|
||||||
// .excludePathPatterns("/register/**");
|
.excludePathPatterns("/register/**");
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,7 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File: BorrowInfoController
|
* File: BorrowInfoController
|
||||||
@ -29,35 +27,13 @@ public class BorrowInfoController {
|
|||||||
|
|
||||||
@PostMapping("/borrowInfo")
|
@PostMapping("/borrowInfo")
|
||||||
public ResVo addBorrowInfo(@RequestBody JSONObject jsonObject) {
|
public ResVo addBorrowInfo(@RequestBody JSONObject jsonObject) {
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
map.put("name", jsonObject.getString("username"));
|
|
||||||
map.put("date", jsonObject.getString("date"));
|
|
||||||
map.put("reason", jsonObject.getString("reason"));
|
|
||||||
map.put("applyDate", jsonObject.getString("applyDate"));
|
|
||||||
map.put("roomName", jsonObject.getString("roomName"));
|
|
||||||
|
|
||||||
JSONArray timeList = jsonObject.getJSONArray("time");
|
JSONArray timeList = jsonObject.getJSONArray("time");
|
||||||
|
BorrowInfo borrowInfo = BorrowInfoFactory.createBorrowInfo(jsonObject);
|
||||||
boolean isAnyRoomBorrowed = false;
|
List<String> list = new ArrayList<>();
|
||||||
|
|
||||||
for (Object item : timeList) {
|
for (Object item : timeList) {
|
||||||
map.put("time", item.toString());
|
list.add(item.toString());
|
||||||
int code = borrowInfoService.isBorrowed(map);
|
|
||||||
if (code == 1) {
|
|
||||||
return ResVo.error("借用失败,所选时段教室被占用");
|
|
||||||
} else if (code == 0) {
|
|
||||||
isAnyRoomBorrowed = true;
|
|
||||||
}
|
}
|
||||||
}
|
return borrowInfoService.borrow(list, borrowInfo);
|
||||||
|
|
||||||
if (isAnyRoomBorrowed) {
|
|
||||||
for (Object item : timeList) {
|
|
||||||
map.put("time", item.toString());
|
|
||||||
borrowInfoService.borrow(map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResVo.ok("借用成功");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/borrowInfo/notBorrowedYet")
|
@PostMapping("/borrowInfo/notBorrowedYet")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.sdut.labex.controller;
|
package com.sdut.labex.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.sdut.labex.service.TableService;
|
import com.sdut.labex.service.TableService;
|
||||||
import com.sdut.labex.utils.ResVo;
|
import com.sdut.labex.utils.ResVo;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -19,9 +20,10 @@ public class TableController {
|
|||||||
@Resource
|
@Resource
|
||||||
private TableService tableService;
|
private TableService tableService;
|
||||||
|
|
||||||
@GetMapping("/getUnusedTable/{date}/{roomName}")
|
@PostMapping("/getUnusedTable")
|
||||||
public ResVo getUnusedTable(@PathVariable("date") String date,
|
public ResVo getUnusedTable(@RequestBody JSONObject jsonObject) {
|
||||||
@PathVariable("roomName") String roomName) {
|
String roomName = jsonObject.getString("roomName");
|
||||||
|
String date = jsonObject.getString("date");
|
||||||
if (roomName.equals("")) {
|
if (roomName.equals("")) {
|
||||||
roomName = "9教207";
|
roomName = "9教207";
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,10 @@ public class TimeOptionController {
|
|||||||
@Resource
|
@Resource
|
||||||
private TimeOptionService timeOptionService;
|
private TimeOptionService timeOptionService;
|
||||||
|
|
||||||
@PostMapping("/timeOption")
|
@PostMapping("/timeOption/{name}")
|
||||||
public ResVo addTimeOption(@RequestBody JSONObject jsonObject) {
|
public ResVo addTimeOption(@PathVariable("name") String name) {
|
||||||
TimeOption timeOption = new TimeOption();
|
TimeOption timeOption = new TimeOption();
|
||||||
timeOption.setName(jsonObject.getString("name"));
|
timeOption.setName(name);
|
||||||
return timeOptionService.addTimeOption(timeOption);
|
return timeOptionService.addTimeOption(timeOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,9 +36,9 @@ public class TimeOptionController {
|
|||||||
return timeOptionService.updateTimeOption(timeOption);
|
return timeOptionService.updateTimeOption(timeOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/timeOption")
|
@DeleteMapping("/timeOption/{id}")
|
||||||
public ResVo deleteTimeOption(@RequestBody JSONObject jsonObject) {
|
public ResVo deleteTimeOption(@PathVariable("id") Integer id) {
|
||||||
return timeOptionService.deleteTimeOption(jsonObject.getInteger("id"));
|
return timeOptionService.deleteTimeOption(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/timeOption")
|
@GetMapping("/timeOption")
|
||||||
|
@ -50,4 +50,16 @@ public class UserController {
|
|||||||
User user = UserFactory.createUser(jsonObject);
|
User user = UserFactory.createUser(jsonObject);
|
||||||
return userService.update(user);
|
return userService.update(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/user/{pageNum}/{pageSize}")
|
||||||
|
public ResVo getUser(@RequestBody JSONObject jsonObject, @PathVariable("pageNum") int pageNum, @PathVariable("pageSize") int pageSize) {
|
||||||
|
User user = UserFactory.createUser(jsonObject);
|
||||||
|
return userService.getUser(pageNum, pageSize, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/user")
|
||||||
|
public ResVo add(@RequestBody JSONObject jsonObject) {
|
||||||
|
User user = UserFactory.createUser(jsonObject);
|
||||||
|
return userService.add(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,10 @@ import java.util.Map;
|
|||||||
public interface BorrowInfoMapper extends BaseMapper<BorrowInfo> {
|
public interface BorrowInfoMapper extends BaseMapper<BorrowInfo> {
|
||||||
public Page<BorrowInfo> queryBorrowInfoByOptions(Page<BorrowInfo> page, BorrowInfo borrowInfo);
|
public Page<BorrowInfo> queryBorrowInfoByOptions(Page<BorrowInfo> page, BorrowInfo borrowInfo);
|
||||||
|
|
||||||
public BorrowInfo borrow(Map<String, String> map);
|
|
||||||
|
|
||||||
public void addTimeTable(Map<String, String> map);
|
public void addTimeTable(Map<String, String> map);
|
||||||
|
|
||||||
public List<BorrowInfo> listAllByDateAndRoom(String date, String room);
|
public List<BorrowInfo> listAllByDateAndRoom(String date, String room);
|
||||||
|
|
||||||
public BorrowInfo isBorrowed(@Param("roomName") String roomName, @Param("time") String time, @Param("date") String date);
|
|
||||||
|
|
||||||
public List<Room> notBorrowedYet(@Param("timeList") List<String> timeList, @Param("date") String date);
|
public List<Room> notBorrowedYet(@Param("timeList") List<String> timeList, @Param("date") String date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.sdut.labex.mapper;
|
package com.sdut.labex.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.sdut.labex.entity.User;
|
import com.sdut.labex.entity.User;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
@ -15,4 +16,6 @@ import java.util.List;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface UserMapper extends BaseMapper<User> {
|
public interface UserMapper extends BaseMapper<User> {
|
||||||
public void insertBatch(List<User> list);
|
public void insertBatch(List<User> list);
|
||||||
|
|
||||||
|
public Page<User> getUser(Page<User> page, User user);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import com.sdut.labex.entity.BorrowInfo;
|
|||||||
import com.sdut.labex.utils.ResVo;
|
import com.sdut.labex.utils.ResVo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author springforest
|
* @author springforest
|
||||||
@ -14,7 +13,7 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public interface BorrowInfoService extends IService<BorrowInfo> {
|
public interface BorrowInfoService extends IService<BorrowInfo> {
|
||||||
|
|
||||||
public ResVo borrow(Map<String, String> map);
|
public ResVo borrow(List<String> timeList, BorrowInfo borrowInfo);
|
||||||
|
|
||||||
public ResVo deleteBorrowInfoById(Integer id);
|
public ResVo deleteBorrowInfoById(Integer id);
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ public interface BorrowInfoService extends IService<BorrowInfo> {
|
|||||||
|
|
||||||
public ResVo notBorrowedYet(List<String> timeList, String date);
|
public ResVo notBorrowedYet(List<String> timeList, String date);
|
||||||
|
|
||||||
public int isBorrowed(Map<String, String> map);
|
public int isBorrowed(BorrowInfo borrowInfo);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,4 +24,6 @@ public interface UserService extends IService<User> {
|
|||||||
public ResVo update(User user);
|
public ResVo update(User user);
|
||||||
|
|
||||||
public ResVo addBatch(MultipartFile file);
|
public ResVo addBatch(MultipartFile file);
|
||||||
|
|
||||||
|
public ResVo getUser(int pageNum, int pageSize, User user);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.sdut.labex.service.impl;
|
package com.sdut.labex.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.sdut.labex.entity.BorrowInfo;
|
import com.sdut.labex.entity.BorrowInfo;
|
||||||
@ -8,14 +10,12 @@ import com.sdut.labex.mapper.BorrowInfoMapper;
|
|||||||
import com.sdut.labex.service.BorrowInfoService;
|
import com.sdut.labex.service.BorrowInfoService;
|
||||||
import com.sdut.labex.utils.ResVo;
|
import com.sdut.labex.utils.ResVo;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.ValueOperations;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author springforest
|
* @author springforest
|
||||||
@ -33,20 +33,34 @@ public class BorrowInfoServiceImpl extends ServiceImpl<BorrowInfoMapper, BorrowI
|
|||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResVo borrow(Map<String, String> map) {
|
public ResVo borrow(List<String> timeList, BorrowInfo borrowInfo) {
|
||||||
try {
|
boolean isAnyRoomBorrowed = false;
|
||||||
synchronized (this) {//线程锁
|
|
||||||
//默认为通过审核(0未审核,1通过,2拒绝)
|
for (String item : timeList) {
|
||||||
map.put("isAdmit", "1");
|
BorrowInfo newBorrowInfo = new BorrowInfo();
|
||||||
borrowInfoMapper.borrow(map);
|
BeanUtil.copyProperties(borrowInfo, newBorrowInfo); // 使用BeanUtil进行属性拷贝
|
||||||
|
newBorrowInfo.setTime(item.toString());
|
||||||
|
int code = this.isBorrowed(newBorrowInfo);
|
||||||
|
if (code == 1) {
|
||||||
|
return ResVo.error("借用失败,所选时段教室被占用");
|
||||||
|
} else if (code == 0) {
|
||||||
|
isAnyRoomBorrowed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAnyRoomBorrowed) {
|
||||||
|
for (String item : timeList) {
|
||||||
|
BorrowInfo newBorrowInfo = new BorrowInfo();
|
||||||
|
BeanUtil.copyProperties(borrowInfo, newBorrowInfo);
|
||||||
|
newBorrowInfo.setTime(item.toString());
|
||||||
|
newBorrowInfo.setIsAdmit(1);
|
||||||
|
borrowInfoMapper.insert(newBorrowInfo);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return ResVo.error("借用失败");
|
|
||||||
}
|
}
|
||||||
return ResVo.ok("借用成功");
|
return ResVo.ok("借用成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResVo deleteBorrowInfoById(Integer id) {
|
public ResVo deleteBorrowInfoById(Integer id) {
|
||||||
if (borrowInfoMapper.selectById(id) == null) {
|
if (borrowInfoMapper.selectById(id) == null) {
|
||||||
@ -75,32 +89,20 @@ public class BorrowInfoServiceImpl extends ServiceImpl<BorrowInfoMapper, BorrowI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResVo notBorrowedYet(List<String> timeList, String date) {
|
public ResVo notBorrowedYet(List<String> timeList, String date) {
|
||||||
List<Room> RBI;
|
List<Room> RBI = borrowInfoMapper.notBorrowedYet(timeList, date);
|
||||||
String key = "notBorrowedYet:" + timeList.toString() + "_" + date;
|
|
||||||
ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
|
|
||||||
//拆箱的 'redisTemplate.hasKey(key)' 可能产生 'java.lang.NullPointerException
|
|
||||||
if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
|
|
||||||
//缓存命中
|
|
||||||
return (ResVo) valueOperations.get(key);
|
|
||||||
} else {
|
|
||||||
//缓存未命中,先添加缓存
|
|
||||||
RBI = borrowInfoMapper.notBorrowedYet(timeList, date);
|
|
||||||
Map<String, Object> res = new HashMap<>();
|
Map<String, Object> res = new HashMap<>();
|
||||||
res.put("list", RBI);
|
res.put("list", RBI);
|
||||||
//存入缓存
|
|
||||||
valueOperations.set(key, ResVo.ok(res));
|
|
||||||
//设置过期时间
|
|
||||||
redisTemplate.expire(key, 12, TimeUnit.HOURS);
|
|
||||||
return ResVo.ok(res);
|
return ResVo.ok(res);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int isBorrowed(Map<String, String> map) {
|
public int isBorrowed(BorrowInfo borrowInfo) {
|
||||||
String date = map.get("date");
|
QueryWrapper<BorrowInfo> queryWrapper = new QueryWrapper<>();
|
||||||
String time = map.get("time");
|
queryWrapper.select("id").eq("room_name", borrowInfo.getRoomName())
|
||||||
String roomName = map.get("roomName");
|
.eq("time", borrowInfo.getTime()).eq("date", borrowInfo.getDate());
|
||||||
if (borrowInfoMapper.isBorrowed(roomName, time, date) != null) {
|
|
||||||
|
if (borrowInfoMapper.selectOne(queryWrapper) != null) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.sdut.labex.service.impl;
|
package com.sdut.labex.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.sdut.labex.dto.TimeTable;
|
import com.sdut.labex.dto.TimeTable;
|
||||||
import com.sdut.labex.entity.BorrowInfo;
|
import com.sdut.labex.entity.BorrowInfo;
|
||||||
import com.sdut.labex.entity.Room;
|
import com.sdut.labex.entity.Room;
|
||||||
@ -39,45 +40,37 @@ public class TableServiceImpl implements TableService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResVo getUnUsedTable(String room, String date) {
|
public ResVo getUnUsedTable(String room, String date) {
|
||||||
List<BorrowInfo> borrowedList = borrowInfoMapper.listAllByDateAndRoom(room, date);
|
QueryWrapper<BorrowInfo> queryWrapper = new QueryWrapper<>();
|
||||||
log.info("borrowedList: " + borrowedList.toString());
|
queryWrapper.eq("date", date);
|
||||||
Map<String, List<String>> tempMap = new HashMap<>();
|
List<BorrowInfo> borrowedList = borrowInfoMapper.selectList(queryWrapper);
|
||||||
// 获取所有教室
|
|
||||||
List<Room> roomList = roomMapper.selectList(null);
|
Map<String, Set<String>> tempMap = new HashMap<>();
|
||||||
// 获取所有时间(按顺序)
|
List<Room> roomList = roomMapper.selectList(null);
|
||||||
List<TimeOption> timeOptionList = timeOptionMapper.selectList(null);
|
List<TimeOption> timeOptionList = timeOptionMapper.selectList(new QueryWrapper<TimeOption>().orderByAsc("order_number"));
|
||||||
|
|
||||||
try {
|
|
||||||
for (TimeOption time : timeOptionList) {
|
for (TimeOption time : timeOptionList) {
|
||||||
List<String> rooms = new ArrayList<>();
|
Set<String> rooms = new HashSet<>();
|
||||||
tempMap.put(time.getName(), rooms);
|
tempMap.put(time.getName(), rooms);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BorrowInfo item : borrowedList) {
|
for (BorrowInfo item : borrowedList) {
|
||||||
log.info(item.toString());
|
|
||||||
tempMap.get(item.getTime()).add(item.getRoomName());
|
tempMap.get(item.getTime()).add(item.getRoomName());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return ResVo.error("解析时间或记录出错");
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
List<List<String>> res = new ArrayList<>();
|
List<List<String>> res = new ArrayList<>();
|
||||||
|
|
||||||
// 获取不在borrowedList中的教室
|
|
||||||
for (TimeOption key : timeOptionList) {
|
for (TimeOption key : timeOptionList) {
|
||||||
List<String> rooms = new ArrayList<>();
|
List<String> rooms = new ArrayList<>();
|
||||||
for (Room item : roomList) {
|
for (Room item : roomMapper.selectList(new QueryWrapper<Room>().in("name", tempMap.get(key.getName())))) {
|
||||||
if (!tempMap.get(key.getName()).contains(item.getName())) {
|
|
||||||
rooms.add(item.getName());
|
rooms.add(item.getName());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
res.add(rooms);
|
res.add(rooms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (room != null && !room.isEmpty()) {
|
if (room != null && !room.isEmpty()) {
|
||||||
for (List<String> rooms : res) {
|
for (List<String> rooms : res) {
|
||||||
rooms.removeIf(r -> !r.equals(room));
|
rooms.removeIf(r -> !r.contains(room));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +78,7 @@ public class TableServiceImpl implements TableService {
|
|||||||
return ResVo.ok(map);
|
return ResVo.ok(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResVo uploadTable(MultipartFile file, String startDate, String roomName) {
|
public ResVo uploadTable(MultipartFile file, String startDate, String roomName) {
|
||||||
try {
|
try {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.sdut.labex.service.impl;
|
package com.sdut.labex.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.sdut.labex.entity.User;
|
import com.sdut.labex.entity.User;
|
||||||
import com.sdut.labex.mapper.UserMapper;
|
import com.sdut.labex.mapper.UserMapper;
|
||||||
@ -17,6 +18,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File: UserServiceImpl
|
* File: UserServiceImpl
|
||||||
@ -44,7 +46,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|||||||
map.put("id", user.getId());
|
map.put("id", user.getId());
|
||||||
map.put("role", user.getRole());
|
map.put("role", user.getRole());
|
||||||
map.put("username", user.getUsername());
|
map.put("username", user.getUsername());
|
||||||
map.put("classId", user.getClassName());
|
map.put("className", user.getClassName());
|
||||||
map.put("department", user.getDepartment());
|
map.put("department", user.getDepartment());
|
||||||
String token = JWTUtil.getTokenByMap(map);
|
String token = JWTUtil.getTokenByMap(map);
|
||||||
map.put("token", token);
|
map.put("token", token);
|
||||||
@ -121,7 +123,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|||||||
return ResVo.error("解析Excel出错");
|
return ResVo.error("解析Excel出错");
|
||||||
}
|
}
|
||||||
|
|
||||||
int startRow = 0;
|
int startRow = 1;
|
||||||
int endRow = excel.totalRows;
|
int endRow = excel.totalRows;
|
||||||
List<User> list = new ArrayList<>();
|
List<User> list = new ArrayList<>();
|
||||||
for (int i = startRow; i < endRow; i++) {
|
for (int i = startRow; i < endRow; i++) {
|
||||||
@ -129,13 +131,20 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|||||||
|
|
||||||
//学号
|
//学号
|
||||||
try {
|
try {
|
||||||
|
if (excel.readCell(i, 0) == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
user.setId(excel.readCell(i, 0));
|
user.setId(excel.readCell(i, 0));
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return ResVo.error("Excel格式错误:第" + (i + 1) + "行第1列");
|
return ResVo.error("Excel格式错误:第" + (i + 1) + "行第1列");
|
||||||
}
|
}
|
||||||
//姓名
|
//姓名
|
||||||
try {
|
try {
|
||||||
|
if (excel.readCell(i, 1) == null) {
|
||||||
|
return ResVo.error("Excel格式错误:第" + (i + 1) + "行第2列");
|
||||||
|
}
|
||||||
user.setUsername(excel.readCell(i, 1));
|
user.setUsername(excel.readCell(i, 1));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -147,6 +156,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|||||||
user.setRole("student");
|
user.setRole("student");
|
||||||
//班级
|
//班级
|
||||||
try {
|
try {
|
||||||
|
if (excel.readCell(i, 2) == null) {
|
||||||
|
return ResVo.error("Excel格式错误:第" + (i + 1) + "行第3列");
|
||||||
|
}
|
||||||
user.setClassName(excel.readCell(i, 2));
|
user.setClassName(excel.readCell(i, 2));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -154,6 +166,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|||||||
}
|
}
|
||||||
//学院
|
//学院
|
||||||
try {
|
try {
|
||||||
|
if (excel.readCell(i, 3) == null) {
|
||||||
|
return ResVo.error("Excel格式错误:第" + (i + 1) + "行第4列");
|
||||||
|
}
|
||||||
user.setDepartment(excel.readCell(i, 3));
|
user.setDepartment(excel.readCell(i, 3));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -162,12 +177,24 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|||||||
|
|
||||||
list.add(user);
|
list.add(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userMapper.deleteBatchIds(list.stream().map(User::getId).collect(Collectors.toList()));
|
||||||
try {
|
try {
|
||||||
userMapper.insertBatch(list);
|
userMapper.insertBatch(list);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return ResVo.error("批量添加失败");
|
return ResVo.error("批量添加失败");
|
||||||
}
|
}
|
||||||
return ResVo.ok();
|
return ResVo.ok("批量添加成功" + list.size() + "条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResVo getUser(int pageNum, int pageSize, User user) {
|
||||||
|
Page<User> page = new Page<>(pageNum, pageSize);
|
||||||
|
userMapper.getUser(page, user);
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("total", page.getTotal());
|
||||||
|
map.put("list", page.getRecords());
|
||||||
|
return ResVo.ok(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,6 @@
|
|||||||
insert into borrow_info (apply_user, time, date, apply_date, is_admit, room_name)
|
insert into borrow_info (apply_user, time, date, apply_date, is_admit, room_name)
|
||||||
VALUES (#{applyUser}, #{time}, #{date}, #{applyDate}, 1, #{roomName});
|
VALUES (#{applyUser}, #{time}, #{date}, #{applyDate}, 1, #{roomName});
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="borrow" parameterType="map">
|
|
||||||
insert into borrow_info(name, time, date, applyDate, isAdmit, room_name)
|
|
||||||
values (#{name}, #{time}, #{date}, #{applyDate}, #{isAdmit}, #{roomName})
|
|
||||||
</insert>
|
|
||||||
|
|
||||||
<select id="queryBorrowInfoByOptions" resultType="com.sdut.labex.entity.BorrowInfo">
|
<select id="queryBorrowInfoByOptions" resultType="com.sdut.labex.entity.BorrowInfo">
|
||||||
select *
|
select *
|
||||||
@ -39,13 +35,7 @@
|
|||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
<select id="isBorrowed" resultType="com.sdut.labex.entity.BorrowInfo">
|
|
||||||
select *
|
|
||||||
from borrow_info
|
|
||||||
where date = #{date}
|
|
||||||
and time = #{time}
|
|
||||||
and roomName = #{roomName};
|
|
||||||
</select>
|
|
||||||
<select id="notBorrowedYet" resultType="com.sdut.labex.entity.Room">
|
<select id="notBorrowedYet" resultType="com.sdut.labex.entity.Room">
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM room
|
FROM room
|
||||||
|
@ -21,4 +21,15 @@
|
|||||||
#{item.role})
|
#{item.role})
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
<select id="getUser" resultType="com.sdut.labex.entity.User" parameterType="object">
|
||||||
|
select * from user
|
||||||
|
<where>
|
||||||
|
<if test="user.id != ''">
|
||||||
|
and id = #{user.id}
|
||||||
|
</if>
|
||||||
|
<if test="user.username != ''">
|
||||||
|
and username = #{user.username}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
0
web/babel.config.js
Normal file → Executable file
0
web/jsconfig.json
Normal file → Executable file
0
web/package-lock.json
generated
Normal file → Executable file
0
web/package.json
Normal file → Executable file
0
web/public/favicon.ico
Normal file → Executable file
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
0
web/public/index.html
Normal file → Executable file
59
web/src/App.vue
Normal file → Executable file
@ -1,34 +1,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<img src="./assets/logo.png">
|
<div class="background">
|
||||||
<div>
|
<router-view></router-view>
|
||||||
<p>
|
|
||||||
If Element Plus is successfully added to this project, you'll see an
|
|
||||||
<code v-text="'<el-button>'"></code>
|
|
||||||
below
|
|
||||||
</p>
|
|
||||||
<el-button type="primary">el-button</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
<Footer/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HelloWorld from './components/HelloWorld.vue'
|
|
||||||
|
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
mounted() {
|
||||||
|
document.title = "计算机科学与技术学院教室预约系统";
|
||||||
|
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.bodyScale()
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
bodyScale() {
|
||||||
|
var devicewidth = document.documentElement.clientWidth; //获取当前分辨率下的可视区域宽度
|
||||||
|
var scale = devicewidth / 1800; // 除以设计稿的尺寸
|
||||||
|
document.body.style.zoom = scale; // 放大缩小相应倍数
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
HelloWorld
|
Footer
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.background{
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 1024px;
|
||||||
|
min-height: 900px !important;
|
||||||
|
/*width: 1440px;*/
|
||||||
|
/*height: 900px;*/
|
||||||
|
/*display: flex;*/
|
||||||
|
/*justify-content: center;*/
|
||||||
|
/*min-width: 1440px;*/
|
||||||
|
}
|
||||||
#app {
|
#app {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Noto Sans SC, emoji;
|
||||||
-webkit-font-smoothing: antialiased;
|
/*position: absolute;*/
|
||||||
-moz-osx-font-smoothing: grayscale;
|
/*top: 0;*/
|
||||||
text-align: center;
|
/*right: 0;*/
|
||||||
color: #2c3e50;
|
/*left: 0;*/
|
||||||
margin-top: 60px;
|
/*bottom: 0;*/
|
||||||
|
/*margin: auto;*/
|
||||||
|
/*overflow-x: hidden;*/
|
||||||
|
/*min-width: 1024px !important;*/
|
||||||
|
/*min-height: 1080px !important;*/
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
BIN
web/src/assets/img/loginBac.png
Executable file
After Width: | Height: | Size: 46 KiB |
BIN
web/src/assets/img/logo.png
Executable file
After Width: | Height: | Size: 803 B |
BIN
web/src/assets/img/logoW.png
Executable file
After Width: | Height: | Size: 51 KiB |
BIN
web/src/assets/img/picture/211.png
Executable file
After Width: | Height: | Size: 535 KiB |
BIN
web/src/assets/img/picture/other.jpg
Executable file
After Width: | Height: | Size: 328 KiB |
BIN
web/src/assets/img/院标2.0.png
Executable file
After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 6.7 KiB |
21
web/src/components/Footer.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div style="display: flex;width: 100%;justify-content: center">
|
||||||
|
<el-button style="border: 1px solid transparent" text @click="dialogVisible = true">© 2023 . All Rights Reserved | Designed by 张开源、臧群、彭凯 | 1.0
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Footer",
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
dialogVisible:false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -1,59 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hello">
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
<p>
|
|
||||||
For a guide and recipes on how to configure / customize this project,<br>
|
|
||||||
check out the
|
|
||||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
|
||||||
</p>
|
|
||||||
<h3>Installed CLI Plugins</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Essential Links</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
|
||||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
|
||||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
|
||||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
|
||||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Ecosystem</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
|
||||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
|
||||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'HelloWorld',
|
|
||||||
props: {
|
|
||||||
msg: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
h3 {
|
|
||||||
margin: 40px 0 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
</style>
|
|
120
web/src/components/Table.vue
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<!--教室使用情况表-->
|
||||||
|
<h4>可用教室</h4>
|
||||||
|
<el-table :data="tableData" border>
|
||||||
|
<el-table-column prop="date"/>
|
||||||
|
<el-table-column v-for="(val,index) in timeSet" :key="index" :label="val" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-space direction="vertical">
|
||||||
|
<div v-for="(room,i) in scope.row.rooms[index]">
|
||||||
|
<el-tag size="small">{{ room }}</el-tag>
|
||||||
|
</div>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-form label-width="120px" :inline="true" style="margin-top: 20px;margin-bottom: -20px">
|
||||||
|
<el-form-item label="教室筛选">
|
||||||
|
<div v-for="(item,i) in rooms">
|
||||||
|
<el-tag type="warning" @click="subForm.roomName = item.name" style="cursor: pointer;margin-right: 20px;">
|
||||||
|
{{ item.name }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Table",
|
||||||
|
props: ["msg"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
rooms: [],
|
||||||
|
subForm: {
|
||||||
|
date: '',
|
||||||
|
roomName: ''
|
||||||
|
},
|
||||||
|
timeSet: ['第一节', '第二节', '第三节', '第四节', '第五节', '第六节', '第七节', '第八节', '第九节', '第十节'],
|
||||||
|
tableData: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'msg.date'(newVal, oldVal) {
|
||||||
|
//监测到日期变化,自动更新时间
|
||||||
|
this.subForm.date = newVal;
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
'subForm.roomName'(newVal, oldVal) {
|
||||||
|
//监测到教室变化,自动更新时间
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
//此处传递的是引用
|
||||||
|
this.subForm.date = this.$props.msg.date;
|
||||||
|
this.subForm.roomName = this.$props.msg.roomName;
|
||||||
|
this.init();
|
||||||
|
this.getAllRoom();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
//初始化表格数据函数
|
||||||
|
this.tableData = [];
|
||||||
|
//因为borrowForm中的Date会在发送请求的时候发生变化,所以在此处先取出来
|
||||||
|
let tempDate = this.subForm.date;
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
this.tableData.push({
|
||||||
|
date: this.setTimes(tempDate, i).substring(5, 10),
|
||||||
|
rooms: []
|
||||||
|
})
|
||||||
|
this.subForm.date = this.setTimes(tempDate, i);
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getTableData(i);
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
//将日期恢复至最初的时间,防止下次调用时改变周期
|
||||||
|
this.subForm.date = tempDate;
|
||||||
|
},
|
||||||
|
getAllRoom() {
|
||||||
|
this.$http({
|
||||||
|
method: 'get',
|
||||||
|
url: '/room'
|
||||||
|
}).then(res => {
|
||||||
|
this.rooms = res.data.list;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTableData(offset) {
|
||||||
|
this.$http({
|
||||||
|
url: '/getUnusedTable',
|
||||||
|
method: 'post',
|
||||||
|
data: this.subForm
|
||||||
|
}).then(res => {
|
||||||
|
this.tableData[offset].rooms = res.data.list;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//以指定的时间为基准,获取偏移量
|
||||||
|
setTimes(selDate, offset) {
|
||||||
|
let dataOp = null;
|
||||||
|
if (selDate != null) {
|
||||||
|
//selDate的格式为2022-10-14,先转换
|
||||||
|
let year = parseInt(selDate.substring(0, 4));
|
||||||
|
//Date中月份是0-11
|
||||||
|
let month = parseInt(selDate.substring(5, 7)) - 1;
|
||||||
|
let day = parseInt(selDate.substring(8, 10));
|
||||||
|
dataOp = new Date(year, month, day);
|
||||||
|
} else {
|
||||||
|
//获取当前时间
|
||||||
|
dataOp = new Date()
|
||||||
|
}
|
||||||
|
|
||||||
|
dataOp.setDate(dataOp.getDate() + offset)
|
||||||
|
return String(dataOp.getFullYear()) + '-' + String((dataOp.getMonth() + 1) < 10 ? '0' + (dataOp.getMonth() + 1) : (dataOp.getMonth() + 1)) + '-' + ((dataOp.getDate() + 1) <= 10 ? '0' + (dataOp.getDate()) : (dataOp.getDate()));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
19
web/src/main.js
Normal file → Executable file
@ -3,7 +3,26 @@ import App from './App.vue'
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import installElementPlus from './plugins/element'
|
import installElementPlus from './plugins/element'
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
installElementPlus(app)
|
installElementPlus(app)
|
||||||
app.use(store).use(router).mount('#app')
|
app.use(store).use(router).mount('#app')
|
||||||
|
|
||||||
|
app.config.globalProperties.$http = axios;
|
||||||
|
//接口请求的基准路径
|
||||||
|
axios.defaults.baseURL = 'http://localhost:8080/';
|
||||||
|
// axios.defaults.baseURL = 'http://211.64.28.110:8080/';
|
||||||
|
|
||||||
|
// 添加请求拦截器
|
||||||
|
|
||||||
|
axios.interceptors.request.use(config => {
|
||||||
|
// 在发送请求之前做些什么
|
||||||
|
// 判断是否存在token,如果存在将每个页面header添加token
|
||||||
|
if (sessionStorage.getItem("token")) {
|
||||||
|
config.headers.token = sessionStorage.getItem("token");
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
})
|
||||||
|
0
web/src/plugins/element.js
Normal file → Executable file
80
web/src/router/index.js
Normal file → Executable file
@ -1,20 +1,64 @@
|
|||||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
import HomeView from '../views/HomeView.vue'
|
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
redirect:'/Login'
|
||||||
component: HomeView
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/about',
|
path: '/Home',
|
||||||
name: 'about',
|
name: 'Home',
|
||||||
// route level code-splitting
|
redirect: '/BorrowRoom',
|
||||||
// this generates a separate chunk (about.[hash].js) for this route
|
component: () => import('../views/Home.vue'),
|
||||||
// which is lazy-loaded when the route is visited.
|
//---------------------教室借用相关-----------------------------
|
||||||
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
|
children:[
|
||||||
|
{
|
||||||
|
path: '/BorrowRoom',
|
||||||
|
name: 'BorrowRoom',
|
||||||
|
component: () => import('../views/BorrowRoom/BorrowRoom.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/BorrowInfoList',
|
||||||
|
name: 'BorrowInfoList',
|
||||||
|
component: () => import('../views/BorrowRoom/RecordList.vue')
|
||||||
|
},
|
||||||
|
//---------------------管理员部分-----------------------------
|
||||||
|
{
|
||||||
|
path: '/Admit',
|
||||||
|
name: 'Admit',
|
||||||
|
component: () => import('../views/Admin/Admit.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/UserManage',
|
||||||
|
name: 'UserManage',
|
||||||
|
component: () => import('../views/Admin/UserManage.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/RoomTimeAndReasonManage',
|
||||||
|
name: 'RoomTimeAndReasonManage',
|
||||||
|
component: () => import('../views/Admin/RoomAndTimeManage.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/Personal',
|
||||||
|
name: 'Personal',
|
||||||
|
component: () => import('../views/Personal.vue')
|
||||||
|
},
|
||||||
|
//---------------------教师--------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
path: '/ApplyExperiment',
|
||||||
|
name: 'ApplyExperiment',
|
||||||
|
component: () => import('../views/ApplyExperiment/ApplyExperiment.vue')
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
//---------------------用户/Admin--------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
path: '/Login',
|
||||||
|
name: 'Login',
|
||||||
|
component: () => import('../views/Login.vue')
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
@ -22,4 +66,22 @@ const router = createRouter({
|
|||||||
routes
|
routes
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//导航守卫
|
||||||
|
//开启前先做白名单
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
//页面拦截
|
||||||
|
if (to.name !== 'Login') {
|
||||||
|
let role = window.sessionStorage.getItem("role");
|
||||||
|
// let token = window.sessionStorage.getItem("token");
|
||||||
|
if (!role) {
|
||||||
|
// return next({ name: 'Login' });
|
||||||
|
}
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
0
web/src/store/index.js
Normal file → Executable file
@ -1,5 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="about">
|
|
||||||
<h1>This is an about page</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
99
web/src/views/Admin/Admit.vue
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<el-table :data="admitlist" stripe border v-loading="loading" :highlight-current-row="true">
|
||||||
|
<el-table-column align="center" prop="date" label="日期" width="120" />
|
||||||
|
<el-table-column align="center" prop="time" label="时间" width="120" />
|
||||||
|
<el-table-column align="center" prop="roomName" label="教室名称" width="100" />
|
||||||
|
<el-table-column align="center" prop="reason" label="用途" width="150"/>
|
||||||
|
<el-table-column align="center" prop="name" label="借用人" />
|
||||||
|
<el-table-column align="center" prop="applyDate" label="申请时间" width="180"/>
|
||||||
|
<el-table-column align="center" label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="success" @click="access(scope.row.id)" v-show="userInfo.role === 'admin'">允许</el-button>
|
||||||
|
<el-button type="danger" @click="deny(scope.row.id)" v-show="userInfo.role === 'admin'">拒绝</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Admit",
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
loading: true,
|
||||||
|
userInfo:{
|
||||||
|
userId:'',
|
||||||
|
role:'',
|
||||||
|
username:'',
|
||||||
|
userDepart:'',
|
||||||
|
},
|
||||||
|
admitlist:[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.userInfo.role = window.sessionStorage.getItem("role");
|
||||||
|
this.userInfo.userId = window.sessionStorage.getItem("userId");
|
||||||
|
this.getAllAdmit()
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
getAllAdmit(){
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
url:'/admit',
|
||||||
|
method:'get',
|
||||||
|
}).then(({data})=>{
|
||||||
|
if (data.code !== 200){
|
||||||
|
ElMessage({
|
||||||
|
message: '信息获取失败',
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
this.admitlist = data.list;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
access(id){
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
url:'/admit/access/' + id,
|
||||||
|
method:'put',
|
||||||
|
}).then(({data})=>{
|
||||||
|
if (data.code !== 200){
|
||||||
|
ElMessage({
|
||||||
|
message: '操作失败',
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
this.getAllAdmit();
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deny(id){
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
url:'/admit/deny/' + id,
|
||||||
|
method:'put',
|
||||||
|
}).then(({data})=>{
|
||||||
|
if (data.code !== 200){
|
||||||
|
ElMessage({
|
||||||
|
message: '操作失败',
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
this.getAllAdmit();
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
274
web/src/views/Admin/RoomAndTimeManage.vue
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
<template>
|
||||||
|
<el-page-header content="系统管理" style="margin-bottom: 30px" @back="this.$router.push('/Login')"/>
|
||||||
|
<div class="bac" style="padding-left: 40px">
|
||||||
|
<el-space>
|
||||||
|
<!--时间管理-->
|
||||||
|
<el-card shadow="always" :v-loading="isLoading" style="width: 500px;height: 300px">
|
||||||
|
<el-space style="margin-bottom: 10px">
|
||||||
|
<el-input placeholder="时间段名称" v-model="this.timeName"/>
|
||||||
|
<el-button @click="addTime">添加时间段</el-button>
|
||||||
|
</el-space>
|
||||||
|
<el-table
|
||||||
|
:data="times"
|
||||||
|
highlight-current-row
|
||||||
|
max-height="220">
|
||||||
|
<el-table-column label="ID" prop="id"></el-table-column>
|
||||||
|
<el-table-column label="时间段名称" prop="name"></el-table-column>
|
||||||
|
<el-table-column label="操作" >
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="danger" @click="removeTime(scope.row.id)" v-show="scope.row.id!==0">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</el-space>
|
||||||
|
|
||||||
|
<!--教室管理-->
|
||||||
|
<el-card shadow="always" :v-loading="isLoading" style="width: 1050px;height: 450px;margin-top: 40px;">
|
||||||
|
<el-space>
|
||||||
|
<el-button @click="dialogVisible = true" style="margin-bottom: 10px">添加教室</el-button>
|
||||||
|
</el-space>
|
||||||
|
<el-table
|
||||||
|
:data="rooms"
|
||||||
|
highlight-current-row
|
||||||
|
max-height="500">
|
||||||
|
<el-table-column align="center" label="ID" prop="id" width="50px"></el-table-column>
|
||||||
|
<el-table-column align="center" label="教室名称" prop="name" ></el-table-column>
|
||||||
|
<el-table-column align="center" label="描述" prop="description" width="300px"></el-table-column>
|
||||||
|
<el-table-column align="center" label="状态">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-show="scope.row.status === 1">可用</el-tag>
|
||||||
|
<el-tag type="danger" v-show="scope.row.status === 2">维护中</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" >
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" @click="getRoomFromRow(scope.row)">更新</el-button>
|
||||||
|
<el-button type="danger" @click="removeRoom(scope.row.id)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!--添加教室-->
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
title="活动管理"
|
||||||
|
width="30%"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
label-width="100px"
|
||||||
|
:model="roomInfo"
|
||||||
|
style="max-width: 460px"
|
||||||
|
>
|
||||||
|
<el-form-item label="教室ID">
|
||||||
|
<el-input v-model="roomInfo.id" :disabled="isUpdate"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教室名称">
|
||||||
|
<el-input v-model="roomInfo.name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="描述">
|
||||||
|
<el-input v-model="roomInfo.description" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-switch
|
||||||
|
v-model="roomInfo.status"
|
||||||
|
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||||
|
active-text="可用"
|
||||||
|
inactive-text="维护"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmForm">确认</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ElMessage, ElMessageBox} from "element-plus";
|
||||||
|
let formData = new FormData();
|
||||||
|
export default {
|
||||||
|
name: "RoomAndTimeManage",
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
dialogVisible:false,
|
||||||
|
isLoading:true,
|
||||||
|
//时间段
|
||||||
|
timeName:'',
|
||||||
|
times:[],
|
||||||
|
//教室
|
||||||
|
roomInfo:{
|
||||||
|
id:'',
|
||||||
|
name:'',
|
||||||
|
description:'',
|
||||||
|
status:true,
|
||||||
|
imgUrl:'',
|
||||||
|
},
|
||||||
|
rooms:[],
|
||||||
|
isUpdate:false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getAllTime();
|
||||||
|
this.getAllRoom();
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
//时间段
|
||||||
|
getAllTime(){
|
||||||
|
this.$http({
|
||||||
|
method:'get',
|
||||||
|
url:'/timeOption'
|
||||||
|
}).then(({data}) =>{
|
||||||
|
this.times = data.list;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addTime(){
|
||||||
|
this.$http({
|
||||||
|
method:'post',
|
||||||
|
url:'/timeOption/' + this.timeName,
|
||||||
|
}).then(({data})=>{
|
||||||
|
if (data.code ===200){
|
||||||
|
//利用延时解决更新列表错误的问题
|
||||||
|
this.timer = setTimeout(() => { //设置延迟执行
|
||||||
|
this.getAllTime();
|
||||||
|
this.timeName = '';
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
removeTime(id){
|
||||||
|
this.$http({
|
||||||
|
method:'delete',
|
||||||
|
url:'/timeOption/' + id,
|
||||||
|
}).then(({data})=>{
|
||||||
|
if (data.code === 200){
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '删除成功',
|
||||||
|
})
|
||||||
|
this.getAllTime();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//教室
|
||||||
|
getAllRoom(){
|
||||||
|
this.$http({
|
||||||
|
method:'get',
|
||||||
|
url:'/room'
|
||||||
|
}).then(res =>{
|
||||||
|
this.rooms = res.data.list;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
confirmForm(){
|
||||||
|
if (this.isUpdate) {
|
||||||
|
this.updateRoom();
|
||||||
|
}else {
|
||||||
|
this.addRoom()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addRoom(){
|
||||||
|
if (this.roomInfo.status){
|
||||||
|
this.roomInfo.status = '1';
|
||||||
|
}else {
|
||||||
|
this.roomInfo.status = '2';
|
||||||
|
}
|
||||||
|
this.$http({
|
||||||
|
method:'post',
|
||||||
|
url:'/room',
|
||||||
|
data:this.roomInfo
|
||||||
|
}).then(({data})=>{
|
||||||
|
if (data.code ===200){
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '添加成功',
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
ElMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: data.msg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.roomInfo.status = true;
|
||||||
|
this.roomInfo.name = '';
|
||||||
|
this.roomInfo.imgUrl = '';
|
||||||
|
this.roomInfo.description = '';
|
||||||
|
this.isUpdate = false;
|
||||||
|
//利用延时解决更新列表错误的问题
|
||||||
|
this.timer = setTimeout(() => { //设置延迟执行
|
||||||
|
this.getAllTime();
|
||||||
|
this.getAllRoom();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
},
|
||||||
|
removeRoom(id){
|
||||||
|
this.$http({
|
||||||
|
method:'delete',
|
||||||
|
url:'/room/' + id,
|
||||||
|
}).then(({data})=>{
|
||||||
|
if (data.code === 200){
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '删除成功',
|
||||||
|
})
|
||||||
|
this.getAllRoom();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getRoomFromRow(row) {
|
||||||
|
this.isUpdate = true;
|
||||||
|
this.roomInfo = JSON.parse(JSON.stringify(row));
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.roomInfo.status = this.roomInfo.status === 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateRoom(){
|
||||||
|
if (this.roomInfo.status){
|
||||||
|
this.roomInfo.status = '1';
|
||||||
|
}else {
|
||||||
|
this.roomInfo.status = '2';
|
||||||
|
}
|
||||||
|
this.$http({
|
||||||
|
method: 'put',
|
||||||
|
url: '/room',
|
||||||
|
data: this.roomInfo
|
||||||
|
}).then(({data}) => {
|
||||||
|
if (data.code === 200) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '修改成功',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: data.msg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.timer = setTimeout(() => { //设置延迟执行
|
||||||
|
this.getAllTime();
|
||||||
|
this.getAllRoom();
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.roomInfo.status = true;
|
||||||
|
this.roomInfo.name = '';
|
||||||
|
this.roomInfo.imgUrl = '';
|
||||||
|
this.roomInfo.description = '';
|
||||||
|
this.isUpdate = false;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
222
web/src/views/Admin/UserManage.vue
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<el-page-header content="用户管理" style="margin-bottom: 30px" @back="this.$router.push('/Login')"/>
|
||||||
|
<el-card style="max-width: 1200px;margin:0 auto;background-color: #f9fafb">
|
||||||
|
<div style="display: flex;justify-content: space-between;align-items: center">
|
||||||
|
<el-space>
|
||||||
|
<el-button type="primary" style="margin-right: 10px;" @click="dialogVisibleForAdd = true">添加成员</el-button>
|
||||||
|
<el-upload :on-change="fileChange" :show-file-list="false" :auto-upload="false">
|
||||||
|
<el-button type="warning" :loading="loading">上传</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</el-space>>
|
||||||
|
</div>
|
||||||
|
<!--表格展示-->
|
||||||
|
<div style="margin-top: 20px">
|
||||||
|
<el-table :data="userList" border stripe v-loading="loading">
|
||||||
|
<el-table-column align="center" prop="id" label="ID"/>
|
||||||
|
<el-table-column align="center" prop="username" label="姓名" />
|
||||||
|
<el-table-column align="center" prop="className" label="班级"/>
|
||||||
|
<el-table-column align="center" prop="department" label="学院"/>
|
||||||
|
<el-table-column align="center" prop="role" label="身份"/>
|
||||||
|
<el-table-column align="center" label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" @click="update(scope.row)">
|
||||||
|
<span style="margin-left: 3px">更新</span>
|
||||||
|
</el-button>
|
||||||
|
<el-button type="danger" @click="remove(scope.row.id)">
|
||||||
|
<span style="margin-left: 3px">删除</span>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="getUser"
|
||||||
|
@current-change="getUser"
|
||||||
|
v-model:current-page="pageNum"
|
||||||
|
|
||||||
|
v-model:page-size="pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
<!--添加用户的对话框-->
|
||||||
|
<el-dialog title="添加用户" v-model="dialogVisibleForAdd" width="30%" style="padding-top: 30px">
|
||||||
|
<el-form ref="addForm" :model="addForm" label-width="100px">
|
||||||
|
<el-form-item label="工号">
|
||||||
|
<el-input :disabled="isEdit" v-model="addForm.id" placeholder="请输入工号..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="姓名">
|
||||||
|
<el-input v-model="addForm.username" placeholder="请输入姓名..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="班级">
|
||||||
|
<el-input v-model="addForm.className" placeholder="请输入班级..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="学院">
|
||||||
|
<el-input v-model="addForm.department" placeholder="请输入班级..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="密码">
|
||||||
|
<el-input v-model="addForm.password" placeholder="请输入密码..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身份">
|
||||||
|
<el-input v-model="addForm.role" placeholder="请输入密码..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="addUser">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisibleForAdd = false">取 消</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ElMessage, ElMessageBox} from "element-plus";
|
||||||
|
let formData = new FormData;
|
||||||
|
export default {
|
||||||
|
name: "UserManage",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading:true,
|
||||||
|
isEdit:false,
|
||||||
|
|
||||||
|
pageSize:30,
|
||||||
|
pageNum:1,
|
||||||
|
total:0,
|
||||||
|
|
||||||
|
addForm:{
|
||||||
|
id:'',
|
||||||
|
username:'',
|
||||||
|
role:'teacher',
|
||||||
|
password:'123456',
|
||||||
|
className:'',
|
||||||
|
department:''
|
||||||
|
},
|
||||||
|
userList:[],
|
||||||
|
dialogVisibleForAdd: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getUser();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getUser() {
|
||||||
|
this.loading = true;
|
||||||
|
this.userList = [];
|
||||||
|
this.$http({
|
||||||
|
method: 'post',
|
||||||
|
url: '/user/' + this.pageNum + '/' + this.pageSize,
|
||||||
|
data:{
|
||||||
|
id:'',
|
||||||
|
username:''
|
||||||
|
}
|
||||||
|
}).then(({data}) => {
|
||||||
|
this.userList = data.list;
|
||||||
|
this.total = data.total;
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addUser() {
|
||||||
|
let method = '';
|
||||||
|
if(this.isEdit){
|
||||||
|
method = 'put';
|
||||||
|
}else {
|
||||||
|
method = 'post';
|
||||||
|
}
|
||||||
|
this.$http({
|
||||||
|
method: method,
|
||||||
|
url: '/user' ,
|
||||||
|
data: this.addForm
|
||||||
|
}).then(({data}) => {
|
||||||
|
if (data.code === 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '操作成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
this.isEdit = false;
|
||||||
|
this.dialogVisibleForAdd = false;
|
||||||
|
this.addForm.username = '';
|
||||||
|
this.addForm.id = '';
|
||||||
|
this.addForm.password = '123456';
|
||||||
|
this.getUser();
|
||||||
|
}else {
|
||||||
|
ElMessage({
|
||||||
|
message: data.msg,
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
update(row){
|
||||||
|
this.addForm = JSON.parse(JSON.stringify(row));
|
||||||
|
this.isEdit = true;
|
||||||
|
|
||||||
|
this.dialogVisibleForAdd = true;
|
||||||
|
},
|
||||||
|
remove(id) {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
'该操作不可撤销',
|
||||||
|
'警告',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
this.$http({
|
||||||
|
method: 'delete',
|
||||||
|
url: '/user/' + id,
|
||||||
|
}).then(res => {
|
||||||
|
this.getUser();
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '删除成功',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
ElMessage({
|
||||||
|
type: 'info',
|
||||||
|
message: '删除已取消',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fileChange(files, fileList) {
|
||||||
|
formData.append('file', files.raw)
|
||||||
|
files = null;
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
method: 'post',
|
||||||
|
url: '/addUserBatch',
|
||||||
|
data: formData,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
this.$notify({
|
||||||
|
title: '上传成功',
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$notify({
|
||||||
|
title: '文件解析失败',
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
formData = null;
|
||||||
|
formData = new FormData();
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
114
web/src/views/ApplyExperiment/ApplyExperiment.vue
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<el-page-header content="实验项目申请" style="margin-bottom: 30px" @back="this.$router.push('/Home')"/>
|
||||||
|
<el-card>
|
||||||
|
<div>
|
||||||
|
<form @submit.prevent="onSubmit">
|
||||||
|
<el-form-item label="项目名称">
|
||||||
|
<el-input v-model="form.name" type="text" id="name" required/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="项目类型">
|
||||||
|
<el-checkbox-group v-model="form.type">
|
||||||
|
<el-checkbox label="类型一" name="type" />
|
||||||
|
<el-checkbox label="类型二" name="type" />
|
||||||
|
<el-checkbox label="类型三" name="type" />
|
||||||
|
<el-checkbox label="类型四" name="type" />
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="form.desc" type="textarea" style="margin-left: 30px"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item class="btn-Ex">
|
||||||
|
<el-button type="primary" @click="onSubmit">确认</el-button>
|
||||||
|
<el-button @click="cancelApply">取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<el-card style="margin-top: 10px">
|
||||||
|
<span style="width: 100%">待规划项目</span>
|
||||||
|
<el-radio-group v-model="size">
|
||||||
|
<el-radio label="large">Large</el-radio>
|
||||||
|
<el-radio>Default</el-radio>
|
||||||
|
<el-radio label="small">Small</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-table :data="itemList" style="width: 100%">
|
||||||
|
<el-table-column fixed prop="name" label="项目名称" width="150" />
|
||||||
|
<el-table-column prop="type" label="项目种类" width="120" />
|
||||||
|
<el-table-column prop="state" label="审批状态" width="120" />
|
||||||
|
<el-table-column prop="address" label="项目描述" width="600" />
|
||||||
|
<el-table-column fixed="right" label="操作" width="120">
|
||||||
|
<template #default>
|
||||||
|
<el-button link type="primary" size="small" @click="setting"
|
||||||
|
>Detail</el-button
|
||||||
|
>
|
||||||
|
<el-button link type="primary" size="small">设置</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
const size = ref('')
|
||||||
|
computed(() => {
|
||||||
|
const marginMap = {
|
||||||
|
large: '32px',
|
||||||
|
default: '28px',
|
||||||
|
small: '24px',
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
marginTop: marginMap[size.value] || marginMap.default,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
export default {
|
||||||
|
name: 'ApplyExperiment',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
itemList: [],
|
||||||
|
form: {
|
||||||
|
name: '',
|
||||||
|
type: [],
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
size:'',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 在组件挂载后立即从后台获取元素列表
|
||||||
|
axios.get('http://localhost:8080/room').then(response => {
|
||||||
|
this.itemList = response.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onSubmit() {
|
||||||
|
axios.post('http://localhost:8080/room', this.form)
|
||||||
|
.then(response => {
|
||||||
|
console.log(response.data);
|
||||||
|
// 处理成功响应
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
// 处理错误
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancelApply(){
|
||||||
|
this.$router.push('/Home');
|
||||||
|
},
|
||||||
|
setting(){
|
||||||
|
this.$router.push('/BorrowRoom')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.btn-Ex {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
234
web/src/views/BorrowRoom/BorrowRoom.vue
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
<template>
|
||||||
|
<el-page-header content="借用登记" style="margin-bottom: 30px" @back="this.$router.push('/Login')"/>
|
||||||
|
<el-card>
|
||||||
|
<Table :msg="borrowForm"/>
|
||||||
|
<el-divider/>
|
||||||
|
<div>
|
||||||
|
<el-form label-width="120px" :inline="true">
|
||||||
|
<el-form-item label="日期">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="borrowForm.date"
|
||||||
|
type="date"
|
||||||
|
placeholder="请选择借用日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
@change="getRoom"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="时间">
|
||||||
|
<el-select
|
||||||
|
v-model="borrowForm.time"
|
||||||
|
placeholder="请选择借用时间"
|
||||||
|
style="width: 200px"
|
||||||
|
multiple
|
||||||
|
collapse-tags
|
||||||
|
@change="getRoom"
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in TimeOption"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<el-divider/>
|
||||||
|
<div style="margin-left:20px;margin-right:20px;padding-left: 70px;padding-top: 40px;padding-bottom: 30px">
|
||||||
|
<el-space :size="45" wrap>
|
||||||
|
<div v-for="(item,i) in Rooms">
|
||||||
|
<el-card :body-style="{ padding: '0px' }" style="width: 200px;">
|
||||||
|
|
||||||
|
<div style="padding: 14px">
|
||||||
|
<div style="margin-bottom: 10px">{{ item.name }}</div>
|
||||||
|
<div style="width: 100%;padding-left: 10px;padding-right: 10px">
|
||||||
|
<el-space wrap v-for="(subItem,j) in item.description">
|
||||||
|
<el-tag style="margin-top: 10px">{{ subItem }}</el-tag>
|
||||||
|
</el-space>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button type="primary" @click="preBorrow(item.name)" v-if="item.status === 1" style="width: 100%">
|
||||||
|
借用该教室
|
||||||
|
</el-button>
|
||||||
|
<el-button type="info" disabled v-if="item.status === 2" style="width: 100%">维护中</el-button>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</el-space>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<el-dialog
|
||||||
|
v-model="confirmDialogVisible"
|
||||||
|
title="请确认您的借用信息"
|
||||||
|
width="30%"
|
||||||
|
>
|
||||||
|
<el-form label-width="120px">
|
||||||
|
<el-form-item label="教室">
|
||||||
|
{{ borrowForm.roomName }}
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="借用日期">
|
||||||
|
{{ borrowForm.date }}
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="借用时间">
|
||||||
|
<el-space v-for="(item,i) in borrowForm.time">
|
||||||
|
<el-tag>{{ item }}</el-tag>
|
||||||
|
</el-space>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="confirmDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmBorrow">确认</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ElMessage, ElMessageBox} from "element-plus";
|
||||||
|
import Table from "../../components/Table"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "BorrowRoom",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
TimeOption: [],
|
||||||
|
userInfo: {
|
||||||
|
userId: '',
|
||||||
|
role: '',
|
||||||
|
username: '',
|
||||||
|
userDepart: '',
|
||||||
|
newPwd: '',
|
||||||
|
oldPwd: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
Rooms: [],
|
||||||
|
|
||||||
|
isMedia: '',
|
||||||
|
|
||||||
|
borrowForm: {
|
||||||
|
applyUser: '',
|
||||||
|
time: [],
|
||||||
|
date: '',
|
||||||
|
roomName: '',
|
||||||
|
},
|
||||||
|
|
||||||
|
confirmDialogVisible: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
//因为执行顺序问题,不宜使用Table组件中的setTimes
|
||||||
|
this.borrowForm.date = this.setTimes(0);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.userInfo.role = window.sessionStorage.getItem('role');
|
||||||
|
this.userInfo.username = window.sessionStorage.getItem("username");
|
||||||
|
this.userInfo.userId = window.sessionStorage.getItem("userId");
|
||||||
|
this.getAllTimeOptions();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getRoom() {
|
||||||
|
if (this.borrowForm.date === '' || this.borrowForm.time.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$http({
|
||||||
|
method: 'post',
|
||||||
|
url: '/borrowInfo/notBorrowedYet',
|
||||||
|
data: this.borrowForm
|
||||||
|
}).then(({data}) => {
|
||||||
|
if (data.code !== 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '教室信息获取失败,请联系管理员',
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.Rooms = data.list;
|
||||||
|
|
||||||
|
for (let i = 0; i < this.Rooms.length; i++) {
|
||||||
|
this.Rooms[i].description = this.Rooms[i].description.split(';');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
//借用请求预处理
|
||||||
|
preBorrow(roomName) {
|
||||||
|
if (this.borrowForm.date === '' || this.borrowForm.time.length === 0) {
|
||||||
|
ElMessage({
|
||||||
|
message: '请完善借用信息',
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.borrowForm.roomName = roomName;
|
||||||
|
//添加借用人信息
|
||||||
|
this.borrowForm.applyUser = this.userInfo.username;
|
||||||
|
this.confirmDialogVisible = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
confirmBorrow() {
|
||||||
|
this.confirmDialogVisible = false;
|
||||||
|
this.$http({
|
||||||
|
method: 'post',
|
||||||
|
url: '/borrowInfo',
|
||||||
|
data: this.borrowForm
|
||||||
|
}).then(res => {
|
||||||
|
if (res.data.code !== 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '登记失败,' + res.data.msg,
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.messageAlert();
|
||||||
|
this.getRoom();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
messageAlert() {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
'登记成功',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确认',
|
||||||
|
type: 'success',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
getAllTimeOptions() {
|
||||||
|
this.$http({
|
||||||
|
url: '/timeOption',
|
||||||
|
method: 'get',
|
||||||
|
}).then(({data}) => {
|
||||||
|
for (let i = 0; i < data.list.length; i++) {
|
||||||
|
this.TimeOption.push({
|
||||||
|
label: data.list[i].name,
|
||||||
|
key: data.list[i].name,
|
||||||
|
value: data.list[i].name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//以指定的时间为基准,获取偏移量
|
||||||
|
setTimes(offset) {
|
||||||
|
//获取当前时间
|
||||||
|
let dataOp = new Date()
|
||||||
|
|
||||||
|
dataOp.setDate(dataOp.getDate() + offset)
|
||||||
|
return String(dataOp.getFullYear()) + '-' + String((dataOp.getMonth() + 1) < 10 ? '0' + (dataOp.getMonth() + 1) : (dataOp.getMonth() + 1)) + '-' + ((dataOp.getDate() + 1) <= 10 ? '0' + (dataOp.getDate()) : (dataOp.getDate()));
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Table,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
278
web/src/views/BorrowRoom/RecordList.vue
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
<template>
|
||||||
|
<el-page-header content="借用记录" style="margin-bottom: 30px" @back="this.$router.push('/Login')"/>
|
||||||
|
<el-card>
|
||||||
|
<el-form label-width="120px">
|
||||||
|
<el-form-item label="日期">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="subForm.date"
|
||||||
|
type="date"
|
||||||
|
placeholder="请选择借用日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
@change="getBorrowInfo"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="时间">
|
||||||
|
<el-select
|
||||||
|
v-model="subForm.time"
|
||||||
|
placeholder="请选择借用时间"
|
||||||
|
style="width: 200px"
|
||||||
|
@change="getBorrowInfo"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in TimeOption"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="教室">
|
||||||
|
<el-select
|
||||||
|
v-model="subForm.roomName"
|
||||||
|
placeholder="请选择教室"
|
||||||
|
style="width: 200px"
|
||||||
|
@change="getBorrowInfo">
|
||||||
|
<el-option
|
||||||
|
v-for="item in Rooms"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="导入课表" v-show="userInfo.role === 'admin'">
|
||||||
|
<a href="/static/template.xls" download="课表模板.xlsx">
|
||||||
|
<el-button type="primary" style="margin-right: 10px;" :loading="loading">下载模板</el-button>
|
||||||
|
</a>
|
||||||
|
<el-breadcrumb :separator-icon="ArrowRight" style="margin-right: 20px;">
|
||||||
|
<el-date-picker v-model="this.startDate" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="学期开始日期"/>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<el-upload :on-change="fileChange" :show-file-list="false" :auto-upload="false">
|
||||||
|
<el-button type="warning" :loading="loading">上传</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="下载记录" v-show="userInfo.role === 'admin'">
|
||||||
|
<el-button type="primary" @click="exportExcel">导出记录</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-divider />
|
||||||
|
<div>
|
||||||
|
<el-table :data="borrowInfo" stripe border v-loading="loading" :highlight-current-row="true">
|
||||||
|
<el-table-column align="center" prop="date" label="日期" width="120" />
|
||||||
|
<el-table-column align="center" prop="time" label="时间" width="120" />
|
||||||
|
<el-table-column align="center" prop="roomName" label="教室名称" width="100" />
|
||||||
|
<el-table-column align="center" prop="reason" label="用途" width="180"/>
|
||||||
|
<el-table-column align="center" prop="name" label="借用人" />
|
||||||
|
<el-table-column align="center" prop="applyDate" label="申请时间" width="200"/>
|
||||||
|
<el-table-column align="center" width="100" label="状态">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-show="scope.row.isAdmit === '0'" type="warning">待审核</el-tag>
|
||||||
|
<el-tag v-show="scope.row.isAdmit === '2'" type="danger">拒绝</el-tag>
|
||||||
|
<el-tag v-show="scope.row.isAdmit === '1'" type="success">通过</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="danger" @click="cancel(scope.row.id)" v-show="userInfo.role === 'admin' || userInfo.username === scope.row.name">撤销</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
@size-change="getBorrowInfo"
|
||||||
|
@current-change="getBorrowInfo"
|
||||||
|
v-model:current-page="subForm.pageNum"
|
||||||
|
|
||||||
|
v-model:page-size="subForm.pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="subForm.total">
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
let formData = new FormData;
|
||||||
|
export default {
|
||||||
|
name: "BorrowInfoList",
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
loading:true,
|
||||||
|
TimeOption:[],
|
||||||
|
Rooms:[],
|
||||||
|
|
||||||
|
userInfo:{
|
||||||
|
userId:'',
|
||||||
|
role:'',
|
||||||
|
username:'',
|
||||||
|
userDepart:'',
|
||||||
|
},
|
||||||
|
|
||||||
|
borrowInfo:[],
|
||||||
|
|
||||||
|
subForm:{
|
||||||
|
date:'',
|
||||||
|
time:'',
|
||||||
|
reason:'',
|
||||||
|
userId:'',
|
||||||
|
roomName:'',
|
||||||
|
pageNum:1,
|
||||||
|
pageSize: 30,
|
||||||
|
total:0
|
||||||
|
},
|
||||||
|
|
||||||
|
startDate:null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.userInfo.role = window.sessionStorage.getItem("role");
|
||||||
|
this.userInfo.userId = window.sessionStorage.getItem("userId");
|
||||||
|
this.userInfo.username = window.sessionStorage.getItem("username");
|
||||||
|
this.getBorrowInfo();
|
||||||
|
this.getAllRooms();
|
||||||
|
this.getAllTimeOptions();
|
||||||
|
console.log(this.userInfo)
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
getAllTimeOptions(){
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
url:'/timeOption',
|
||||||
|
method:'get',
|
||||||
|
}).then(({data})=>{
|
||||||
|
for(let i=0;i<data.list.length;i++){
|
||||||
|
this.TimeOption.push({
|
||||||
|
label:data.list[i].name,
|
||||||
|
key:data.list[i].name,
|
||||||
|
value:data.list[i].name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getAllRooms(){
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
url:'/room',
|
||||||
|
method:'get',
|
||||||
|
}).then(({data})=>{
|
||||||
|
for(let i=0;i<data.list.length;i++){
|
||||||
|
this.Rooms.push({
|
||||||
|
label:data.list[i].name,
|
||||||
|
key:data.list[i].name,
|
||||||
|
value:data.list[i].name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getBorrowInfo(){
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
method:'post',
|
||||||
|
url: '/borrowInfo',
|
||||||
|
data:this.subForm
|
||||||
|
}).then(res =>{
|
||||||
|
console.log(res);
|
||||||
|
if (res.data.code !== 200){
|
||||||
|
ElMessage({
|
||||||
|
message: '教室信息获取失败',
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
this.borrowInfo = res.data.RBI;
|
||||||
|
this.subForm.total = res.data.total;
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancel(id){
|
||||||
|
this.$http({
|
||||||
|
method:'delete',
|
||||||
|
url: '/borrowInfo/' + parseInt(id),
|
||||||
|
}).then(res =>{
|
||||||
|
ElMessage({
|
||||||
|
message: '撤销成功',
|
||||||
|
type: 'success',
|
||||||
|
})
|
||||||
|
this.getBorrowInfo();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
fileChange(files, fileList) {
|
||||||
|
formData.append('file', files.raw)
|
||||||
|
files = null;
|
||||||
|
this.importTimeTable();
|
||||||
|
},
|
||||||
|
|
||||||
|
importTimeTable(){
|
||||||
|
this.loading = true;
|
||||||
|
if (this.startDate === null || this.subForm.roomName === ''){
|
||||||
|
alert("请选择日期和教室");
|
||||||
|
this.loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
formData.append("startDate",this.startDate);
|
||||||
|
formData.append("roomName",this.subForm.roomName);
|
||||||
|
|
||||||
|
this.$http({
|
||||||
|
method: 'post',
|
||||||
|
url: '/file/importTimeTable',
|
||||||
|
data: formData,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
this.$notify({
|
||||||
|
title: '上传成功',
|
||||||
|
message: '',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
this.getBorrowInfo();
|
||||||
|
} else {
|
||||||
|
this.$notify({
|
||||||
|
title: '文件解析失败',
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
formData = null;
|
||||||
|
formData = new FormData();
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exportExcel() {
|
||||||
|
this.loading = true;
|
||||||
|
this.$http({
|
||||||
|
method: 'get',
|
||||||
|
url: '/borrowInfo/exportExcel',
|
||||||
|
responseType: "arraybuffer"
|
||||||
|
}).then((file) => {
|
||||||
|
//流文件下载
|
||||||
|
let content = file.data;
|
||||||
|
// 组装a标签
|
||||||
|
let elink = document.createElement("a");
|
||||||
|
// 设置下载文件名
|
||||||
|
|
||||||
|
elink.download ="借用记录.xls";
|
||||||
|
elink.style.display = "none";
|
||||||
|
let blob = new Blob([content], {type: "application/xls"})
|
||||||
|
elink.href = URL.createObjectURL(blob);
|
||||||
|
document.body.appendChild(elink);
|
||||||
|
elink.click();
|
||||||
|
document.body.removeChild(elink);
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
58
web/src/views/Home.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="background">
|
||||||
|
<el-container>
|
||||||
|
<el-aside width="200px">
|
||||||
|
<div style="height: 100%;background-color: #334154">
|
||||||
|
<el-menu
|
||||||
|
active-text-color="#1989FA"
|
||||||
|
background-color="#334154"
|
||||||
|
class="el-menu-vertical-demo"
|
||||||
|
default-active="2"
|
||||||
|
text-color="#fff"
|
||||||
|
:router="true">
|
||||||
|
<div style="height: 70px;width: 100%;padding-top: 20px">
|
||||||
|
<img src="../assets/img/logoW.png" style="height: 60%;width: 80%; margin-left: 20px;margin-top: 5px" alt="">
|
||||||
|
</div>
|
||||||
|
<el-menu-item index="/ApplyExperiment">实验项目申请</el-menu-item>
|
||||||
|
<el-menu-item index="/BorrowRoom">教室借用</el-menu-item>
|
||||||
|
<el-menu-item index="/RecordList">记录查询</el-menu-item>
|
||||||
|
<el-menu-item index="/Admit" >项目审核</el-menu-item>
|
||||||
|
<el-menu-item index="/UserManage" >用户管理</el-menu-item>
|
||||||
|
<el-menu-item index="/RoomTimeAndReasonManage" >系统管理</el-menu-item>
|
||||||
|
<el-menu-item index="/Personal">个人信息</el-menu-item>
|
||||||
|
</el-menu>
|
||||||
|
</div>
|
||||||
|
</el-aside>
|
||||||
|
<el-main>
|
||||||
|
<router-view></router-view>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Home",
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
userInfo:{
|
||||||
|
userId:'',
|
||||||
|
role:'',
|
||||||
|
username:'',
|
||||||
|
userDepart:'',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.userInfo.role = window.sessionStorage.getItem("role");
|
||||||
|
this.userInfo.userId = window.sessionStorage.getItem("userId");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.background{
|
||||||
|
width: 1440px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,18 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="home">
|
|
||||||
<img alt="Vue logo" src="../assets/logo.png">
|
|
||||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// @ is an alias to /src
|
|
||||||
import HelloWorld from '@/components/HelloWorld.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'HomeView',
|
|
||||||
components: {
|
|
||||||
HelloWorld
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
97
web/src/views/Login.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bac">
|
||||||
|
<div class="loginBox">
|
||||||
|
<p>账号密码登陆</p>
|
||||||
|
<el-space direction="vertical" :size="30">
|
||||||
|
<el-input v-model="subform.id" placeholder="学号" clearable style="width: 240px;height: 40px;"/>
|
||||||
|
<el-input v-model="subform.password" placeholder="密码" type="password" style="width: 240px;height: 40px;"/>
|
||||||
|
</el-space>
|
||||||
|
<el-button type="primary" @click="login()" @keyup.enter="login()" style="width: 240px;height: 40px;font-size: 14px">登陆</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Avatar, Key } from '@element-plus/icons-vue'
|
||||||
|
import {ElNotification} from "element-plus";
|
||||||
|
export default {
|
||||||
|
name: 'Login',
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
subform:{
|
||||||
|
id:'',
|
||||||
|
password:'',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
document.addEventListener('keydown', this.handleEnterKey);
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
handleEnterKey(){
|
||||||
|
// 检查是否按下回车键(keyCode为13)
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
// 触发按钮的点击事件
|
||||||
|
this.login();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
login(){
|
||||||
|
this.$http({
|
||||||
|
method:'post',
|
||||||
|
url:'/login',
|
||||||
|
data:this.subform
|
||||||
|
}).then(res =>{
|
||||||
|
if(res.data.code!==200){
|
||||||
|
ElNotification({
|
||||||
|
title: '登陆失败',
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
}else if (res.data.code === 200){
|
||||||
|
ElNotification({
|
||||||
|
title: '登陆成功',
|
||||||
|
message: '你好,' + res.data.username,
|
||||||
|
type: 'success',
|
||||||
|
})
|
||||||
|
|
||||||
|
//保存信息
|
||||||
|
window.sessionStorage.setItem('role',res.data.role);
|
||||||
|
window.sessionStorage.setItem('username',res.data.username);
|
||||||
|
window.sessionStorage.setItem('userId', res.data.id.toString());
|
||||||
|
window.sessionStorage.setItem('token', res.data.token);
|
||||||
|
|
||||||
|
this.$router.push('/Home');
|
||||||
|
}else {
|
||||||
|
ElNotification({
|
||||||
|
title: '服务器错误',
|
||||||
|
message: '工具人QQ:3231977651',
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
components:{
|
||||||
|
Avatar,
|
||||||
|
Key
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.bac{
|
||||||
|
width: 1440px;
|
||||||
|
height: 900px;
|
||||||
|
background: url("../assets/img/loginBac.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
.loginBox{
|
||||||
|
width: 250px;
|
||||||
|
height: 320px;
|
||||||
|
position: absolute;
|
||||||
|
left: 62%;
|
||||||
|
top: 320px;
|
||||||
|
}
|
||||||
|
</style>
|
92
web/src/views/Personal.vue
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<template>
|
||||||
|
<!--个人信息-->
|
||||||
|
<el-page-header content="个人信息" style="margin-bottom: 30px" @back="this.$router.push('/Login')"/>
|
||||||
|
<el-card style="padding-left: 60px;padding-right: 60px">
|
||||||
|
<el-descriptions title="个人信息" border>
|
||||||
|
<el-descriptions-item label="用户ID">{{userInfo.userId}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="用户名">{{userInfo.username}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="身份">{{userInfo.role}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="操作">
|
||||||
|
<el-button type="primary" @click="pwdVisable=true">修改密码</el-button>
|
||||||
|
<el-button type="danger" @click="logout">退出</el-button>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
<el-dialog
|
||||||
|
v-model="pwdVisable"
|
||||||
|
title="修改密码"
|
||||||
|
width="30%"
|
||||||
|
>
|
||||||
|
<el-form label-width="120px">
|
||||||
|
<el-form-item label="旧密码">
|
||||||
|
<el-input v-model="userInfo.oldPwd"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="新密码">
|
||||||
|
<el-input v-model="userInfo.newPwd"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="pwdVisable = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="changePwd">确认</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Personal",
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
userInfo:{
|
||||||
|
userId:'',
|
||||||
|
role:'',
|
||||||
|
username:'',
|
||||||
|
userDepart:'',
|
||||||
|
newPwd:'',
|
||||||
|
oldPwd:''
|
||||||
|
},
|
||||||
|
pwdVisable:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.userInfo.role = window.sessionStorage.getItem('role');
|
||||||
|
this.userInfo.name = window.sessionStorage.getItem("username");
|
||||||
|
this.userInfo.username = window.sessionStorage.getItem("username");
|
||||||
|
this.userInfo.userId = window.sessionStorage.getItem("userId");
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
changePwd(){
|
||||||
|
this.$http({
|
||||||
|
url:'/changePwd',
|
||||||
|
method:'put',
|
||||||
|
data:this.userInfo
|
||||||
|
}).then(({data})=> {
|
||||||
|
if (data.code === 200){
|
||||||
|
ElMessage({
|
||||||
|
message: '修改成功',
|
||||||
|
type: 'success',
|
||||||
|
})
|
||||||
|
this.pwdVisable = false;
|
||||||
|
}else {
|
||||||
|
ElMessage({
|
||||||
|
message: '修改失败,' + data.msg,
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
logout(){
|
||||||
|
window.sessionStorage.clear();
|
||||||
|
this.$router.push('/Login')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
20
web/vue.config.js
Normal file → Executable file
@ -2,3 +2,23 @@ const { defineConfig } = require('@vue/cli-service')
|
|||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
transpileDependencies: true
|
transpileDependencies: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// module.exports = {
|
||||||
|
// chainWebpack: config => {
|
||||||
|
// config.module
|
||||||
|
// .rule('vue')
|
||||||
|
// .use('vue-loader')
|
||||||
|
// .tap(options => {
|
||||||
|
// options.compilerOptions.isCustomElement = tag => tag.startsWith('el-')
|
||||||
|
// return options
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// config.module
|
||||||
|
// .rule('ts')
|
||||||
|
// .use('ts-loader')
|
||||||
|
// .tap(options => {
|
||||||
|
// options.appendTsSuffixTo = [/\.vue$/]
|
||||||
|
// return options
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|