commit
This commit is contained in:
+9
-2
@@ -37,7 +37,7 @@ public class GuildHallController {
|
|||||||
|
|
||||||
@At("")
|
@At("")
|
||||||
@SaCheckPermission("guildHall.management")
|
@SaCheckPermission("guildHall.management")
|
||||||
@Ok("beetl:/platform/zhgh/democratic/teachercongress/guildhall/index.html")
|
@Ok("beetl:/platform/zhgh/democratic/teachercongress/guildhall/manage/index.html")
|
||||||
public void index() {
|
public void index() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,10 +90,17 @@ public class GuildHallController {
|
|||||||
return Result.success(dao.fetch(GuildHall.class, id));
|
return Result.success(dao.fetch(GuildHall.class, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("guildHall.management")
|
||||||
|
@ApiOperation("查询会议厅多个")
|
||||||
|
public Result selectList() {
|
||||||
|
return Result.success(dao.query(GuildHall.class, Cnd.NEW()));
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("guildHall.management")
|
@SaCheckPermission("guildHall.management")
|
||||||
@ApiOperation("查询座位")
|
@ApiOperation("查询座位")
|
||||||
public Result selectSeat(String hallId) {
|
public Result selectSeatList(String hallId) {
|
||||||
List<GuildHallSeat> list = dao.query(GuildHallSeat.class, Cnd.where(GuildHallSeat::getHallId, "=", hallId)
|
List<GuildHallSeat> list = dao.query(GuildHallSeat.class, Cnd.where(GuildHallSeat::getHallId, "=", hallId)
|
||||||
.asc(GuildHallSeat::getRowNumber).asc(GuildHallSeat::getColNumber));
|
.asc(GuildHallSeat::getRowNumber).asc(GuildHallSeat::getColNumber));
|
||||||
|
|
||||||
|
|||||||
+45
-1
@@ -1,21 +1,33 @@
|
|||||||
package com.budwk.app.zhgh.democratic.teachercongress.guildhall.controller;
|
package com.budwk.app.zhgh.democratic.teachercongress.guildhall.controller;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.budwk.app.base.annotation.SLog;
|
import com.budwk.app.base.annotation.SLog;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHall;
|
||||||
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallMeeting;
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallMeeting;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallSeat;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallSeatSelect;
|
||||||
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.service.GuildHallMeetingService;
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.service.GuildHallMeetingService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Api("会议厅会议")
|
@Api("会议厅会议")
|
||||||
@IocBean
|
@IocBean
|
||||||
@At("/platform/guildHall/meeting")
|
@At("/platform/guildHall/meeting")
|
||||||
@@ -50,17 +62,32 @@ public class GuildHallMeetingController {
|
|||||||
@SaCheckPermission("guildHall.meeting")
|
@SaCheckPermission("guildHall.meeting")
|
||||||
@SLog(tag = "会议厅会议", msg = "保存会议厅会议")
|
@SLog(tag = "会议厅会议", msg = "保存会议厅会议")
|
||||||
@ApiOperation("保存会议厅会议")
|
@ApiOperation("保存会议厅会议")
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Result save(GuildHallMeeting meeting) {
|
public Result save(GuildHallMeeting meeting) {
|
||||||
dao.insert(meeting);
|
dao.insert(meeting);
|
||||||
return Result.success();
|
List<GuildHallSeat> seats = dao.query(GuildHallSeat.class, Cnd.where("hallId", "=", meeting.getHallId()));
|
||||||
|
List<GuildHallSeatSelect> selects = BeanUtil.copyToList(seats, GuildHallSeatSelect.class);
|
||||||
|
for (GuildHallSeatSelect select : selects) {
|
||||||
|
select.setMeetingId(meeting.getId());
|
||||||
|
}
|
||||||
|
dao.insert(selects);
|
||||||
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("guildHall.meeting")
|
@SaCheckPermission("guildHall.meeting")
|
||||||
@SLog(tag = "会议厅会议", msg = "修改会议厅会议")
|
@SLog(tag = "会议厅会议", msg = "修改会议厅会议")
|
||||||
@ApiOperation("修改会议厅会议")
|
@ApiOperation("修改会议厅会议")
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Result update(GuildHallMeeting meeting) {
|
public Result update(GuildHallMeeting meeting) {
|
||||||
dao.update(meeting);
|
dao.update(meeting);
|
||||||
|
dao.clear(GuildHallSeatSelect.class, Cnd.where("hallId", "=", meeting.getHallId()));
|
||||||
|
List<GuildHallSeat> seats = dao.query(GuildHallSeat.class, Cnd.where("hallId", "=", meeting.getHallId()));
|
||||||
|
List<GuildHallSeatSelect> selects = BeanUtil.copyToList(seats, GuildHallSeatSelect.class);
|
||||||
|
for (GuildHallSeatSelect select : selects) {
|
||||||
|
select.setMeetingId(meeting.getId());
|
||||||
|
}
|
||||||
|
dao.insert(selects);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,4 +100,21 @@ public class GuildHallMeetingController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("guildHall")
|
||||||
|
@ApiOperation("查询会议")
|
||||||
|
public Result selectList() {
|
||||||
|
List<NutMap> results = new ArrayList<>();
|
||||||
|
List<GuildHallMeeting> meetings = dao.query(GuildHallMeeting.class, Cnd.NEW().desc("startTime"));
|
||||||
|
for (GuildHallMeeting meeting : meetings) {
|
||||||
|
if(DateUtil.compare(DateUtil.date(), meeting.getEndTime()) > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
NutMap nutMap = Lang.obj2nutmap(meeting);
|
||||||
|
GuildHall hall = dao.fetch(GuildHall.class, meeting.getHallId());
|
||||||
|
nutMap.put("address", hall.getAddress());
|
||||||
|
results.add(nutMap);
|
||||||
|
}
|
||||||
|
return Result.success(results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+140
@@ -0,0 +1,140 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.teachercongress.guildhall.controller;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.PageForm;
|
||||||
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHall;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallMeeting;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.service.GuildHallService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName GuildHallSeatSummaryController
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2025/10/24 16:25
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
@Api("会议选座统计")
|
||||||
|
@IocBean
|
||||||
|
@At("/platform/guildHall/seatSummary")
|
||||||
|
@Ok("json:full")
|
||||||
|
public class GuildHallSeatSummaryController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
@Inject
|
||||||
|
private GuildHallService guildHallService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@SaCheckPermission("guildHall.seatSummary")
|
||||||
|
@Ok("beetl:/platform/zhgh/democratic/teachercongress/guildhall/seatSummary/index.html")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("guildHall.seatSummary")
|
||||||
|
@ApiOperation("分页查询")
|
||||||
|
public Result pageData(PageForm pageForm,
|
||||||
|
@Param(value = "meetingId") String meetingId) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
u.userName,
|
||||||
|
u.loginName,
|
||||||
|
u.unitName as unitName,
|
||||||
|
u.unionName as unionName,
|
||||||
|
u.mobile,
|
||||||
|
u.sex,
|
||||||
|
t1.rowNumber,
|
||||||
|
t1.colNumber
|
||||||
|
FROM
|
||||||
|
`guild_hall_seat_select` t1
|
||||||
|
LEFT JOIN `vw_user` u ON u.id = t1.userId
|
||||||
|
WHERE
|
||||||
|
t1.userId IS NOT NULL AND t1.meetingId = @meetingId
|
||||||
|
order by t1.rowNumber ASC,t1.colNumber ASC
|
||||||
|
""");
|
||||||
|
sql.setParam("meetingId", meetingId);
|
||||||
|
Pagination pagination = guildHallService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||||
|
return Result.success(pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("guildHall.seatSummary")
|
||||||
|
@ApiOperation("查询会议")
|
||||||
|
public Result listMeeting() {
|
||||||
|
List<GuildHallMeeting> meetings = dao.query(GuildHallMeeting.class, Cnd.NEW().desc("startTime"));
|
||||||
|
return Result.success(meetings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("guildHall.seatSummary")
|
||||||
|
public void exportExcel(String meetingId, HttpServletResponse response) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
u.userName,
|
||||||
|
u.loginName,
|
||||||
|
u.unitName as unitName,
|
||||||
|
u.unionName as unionName,
|
||||||
|
u.mobile,
|
||||||
|
u.sex,
|
||||||
|
t1.rowNumber,
|
||||||
|
t1.colNumber,
|
||||||
|
CONCAT(t1.rowNumber,'排',t1.colNumber,'列') seat
|
||||||
|
FROM
|
||||||
|
`guild_hall_seat_select` t1
|
||||||
|
LEFT JOIN `vw_user` u ON u.id = t1.userId
|
||||||
|
WHERE
|
||||||
|
t1.userId IS NOT NULL AND t1.meetingId = @meetingId
|
||||||
|
order by t1.rowNumber ASC,t1.colNumber ASC
|
||||||
|
""");
|
||||||
|
sql.setParam("meetingId",meetingId);
|
||||||
|
|
||||||
|
List<NutMap> list = guildHallService.listMap(sql);
|
||||||
|
|
||||||
|
List<ExcelExportEntity> exportEntities = new ArrayList<>();
|
||||||
|
exportEntities.add(new ExcelExportEntity("姓名", "userName", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("工号", "loginName", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("性别", "sex", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("单位", "unitName", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("分工会", "unionName", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("手机号", "mobile", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("座位", "seat", 20));
|
||||||
|
|
||||||
|
try {
|
||||||
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setSheetName("选座人员");
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
|
||||||
|
CommonDownloadUtil.download("选座人员.xlsx", workbook, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.teachercongress.guildhall.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallMeeting;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallSeat;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.models.GuildHallSeatSelect;
|
||||||
|
import com.budwk.app.zhgh.democratic.teachercongress.guildhall.service.GuildHallService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName GuildHallSelectSeatController
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2025/10/24 15:22
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
@Api("会议选座")
|
||||||
|
@IocBean
|
||||||
|
@At("/platform/guildHall/selectSeat")
|
||||||
|
@Ok("json:full")
|
||||||
|
public class GuildHallSelectSeatController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
@Inject
|
||||||
|
private GuildHallService guildHallService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@SaCheckPermission("guildHall.selectSeat")
|
||||||
|
@Ok("beetl:/platform/zhgh/democratic/teachercongress/guildhall/selectSeat/index.html")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/h5")
|
||||||
|
@SaCheckPermission("h5.guildHall.selectSeat")
|
||||||
|
@Ok("beetl:/platform/zhghh5/democratic/teachercongress/guildhall/selectSeat/index.html")
|
||||||
|
public void h5Index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("guildHall.selectSeat")
|
||||||
|
public Result loadSeats(@Param("meetingId") String meetingId) {
|
||||||
|
// 已选择情况
|
||||||
|
List<GuildHallSeatSelect> selectedSeats = dao.query(GuildHallSeatSelect.class, Cnd.where("meetingId", "=", meetingId));
|
||||||
|
|
||||||
|
for (GuildHallSeatSelect selectedSeat : selectedSeats) {
|
||||||
|
if (selectedSeat.getUserId() != null) {
|
||||||
|
selectedSeat.setIsOccupied(true);
|
||||||
|
selectedSeat.setOccupiedBy(selectedSeat.getUserId());
|
||||||
|
selectedSeat.setIsMine(selectedSeat.getUserId().equals(SecurityUtil.getUserId()));
|
||||||
|
} else {
|
||||||
|
selectedSeat.setIsOccupied(false);
|
||||||
|
selectedSeat.setIsMine(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 座位排序 首先按seatRowNum 再按seatColNum
|
||||||
|
selectedSeats.sort((o1, o2) -> {
|
||||||
|
int compare = o1.getRowNumber().compareTo(o2.getRowNumber());
|
||||||
|
if (compare == 0) {
|
||||||
|
return o1.getColNumber().compareTo(o2.getColNumber());
|
||||||
|
}
|
||||||
|
return compare;
|
||||||
|
});
|
||||||
|
return Result.success(selectedSeats);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("guildHall.selectSeat")
|
||||||
|
public Result doSelect(@Param("meetingId") String meetingId, Integer rowNumber, Integer colNumber) {
|
||||||
|
GuildHallSeatSelect oldSeat = dao.fetch(GuildHallSeatSelect.class, Cnd.where("meetingId", "=", meetingId).and("userId", "=", SecurityUtil.getUserId()));
|
||||||
|
if(oldSeat != null){
|
||||||
|
oldSeat.setUserId(null);
|
||||||
|
oldSeat.setSelectTime(null);
|
||||||
|
dao.update(oldSeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuildHallSeatSelect seat = dao.fetch(GuildHallSeatSelect.class, Cnd.where("meetingId", "=", meetingId).and("rowNumber", "=", rowNumber).and("colNumber", "=", colNumber));
|
||||||
|
seat.setUserId(SecurityUtil.getUserId());
|
||||||
|
seat.setSelectTime(new Date());
|
||||||
|
dao.update(seat);
|
||||||
|
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -58,4 +58,9 @@ public class GuildHallMeeting extends BaseModel {
|
|||||||
@ColDefine(type = ColType.INT)
|
@ColDefine(type = ColType.INT)
|
||||||
private Integer groupId;
|
private Integer groupId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("会厅Id")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
|
private String hallId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -7,6 +7,8 @@ import lombok.experimental.Accessors;
|
|||||||
import org.nutz.dao.entity.annotation.*;
|
import org.nutz.dao.entity.annotation.*;
|
||||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Table("guild_hall_seat")
|
@Table("guild_hall_seat")
|
||||||
@@ -39,9 +41,15 @@ public class GuildHallSeat extends BaseModel {
|
|||||||
@ColDefine(type = ColType.INT)
|
@ColDefine(type = ColType.INT)
|
||||||
private Integer colNumber;
|
private Integer colNumber;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("座位编号")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String seatNumber;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("是否启用")
|
@Comment("是否启用")
|
||||||
@ColDefine(type = ColType.BOOLEAN)
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
@Default("1")
|
@Default("1")
|
||||||
private Boolean enable;
|
private Boolean enable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.teachercongress.guildhall.models;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName GuildHallSeatSelect
|
||||||
|
* @Author JyuHsin
|
||||||
|
* @Date 2025/10/24 15:55
|
||||||
|
* @Version 1.0
|
||||||
|
* @Description TODO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table("guild_hall_seat_select")
|
||||||
|
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||||
|
@Comment("会议厅座位")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@TableIndexes(value = {
|
||||||
|
@Index(name = "INDEX_GUILD_HALL_SEAT_HALL_ID", fields = "hallId",unique = false)
|
||||||
|
})
|
||||||
|
public class GuildHallSeatSelect extends GuildHallSeat{
|
||||||
|
|
||||||
|
@Name
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
@Comment("ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("会议id")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String meetingId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("用户id")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("选座时间")
|
||||||
|
@ColDefine(type = ColType.DATETIME)
|
||||||
|
private Date selectTime;
|
||||||
|
|
||||||
|
private Boolean isOccupied;
|
||||||
|
private String occupiedBy;
|
||||||
|
private Boolean isMine;
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -48,6 +48,7 @@ module.exports = {
|
|||||||
<el-select placeholder="参加人员范围"
|
<el-select placeholder="参加人员范围"
|
||||||
v-model="internalGroupId"
|
v-model="internalGroupId"
|
||||||
clearable
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
filterable>
|
filterable>
|
||||||
<el-option v-for="item in groupOptions"
|
<el-option v-for="item in groupOptions"
|
||||||
:label="item.groupName"
|
:label="item.groupName"
|
||||||
@@ -55,7 +56,7 @@ module.exports = {
|
|||||||
:key="item.groupId"
|
:key="item.groupId"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-button @click="$refs.drawerUserScope.userScopeDialog = true" type="primary" icon="el-icon-setting">设置
|
<el-button @click="$refs.drawerUserScope.userScopeDialog = true" type="primary" icon="el-icon-setting" class="ml10">设置
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ const jcdt = {
|
|||||||
<div class="jcdt-content">
|
<div class="jcdt-content">
|
||||||
<div class="jcdt-list">
|
<div class="jcdt-list">
|
||||||
<div class="jcdt-item" v-for="item in list" :key="item.title" @click="onLink(item)">
|
<div class="jcdt-item" v-for="item in list" :key="item.title" @click="onLink(item)">
|
||||||
<div class="date">{{item.date}}</div>
|
<div class="date" v-if="item.date">{{item.date}}</div>
|
||||||
<div class="title">{{item.title}}</div>
|
<div class="title">{{item.title}}</div>
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<img :src="item.image" alt="">
|
<img v-if="item.image" :src="item.image" alt="">
|
||||||
|
<img v-else src="/assets/platform/img/v4/not-image.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="summary">{{item.summary}}</div>
|
<div class="summary">{{item.summary}}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,7 +39,7 @@ const jcdt = {
|
|||||||
style: /*language=CSS*/ `
|
style: /*language=CSS*/ `
|
||||||
.jcdt-wrapper {
|
.jcdt-wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-image: url(https://cdgh.ncu.edu.cn/images/index_bg2.png);
|
background-image: url(/assets/platform/img/v4/home-bg.png);
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ layout("/layouts/platform.html"){
|
|||||||
</search-item>
|
</search-item>
|
||||||
<search-item label="场地类型">
|
<search-item label="场地类型">
|
||||||
<el-select v-model="pageForm.siteType" @change="doSearch" style="width: 100%"
|
<el-select v-model="pageForm.siteType" @change="doSearch" style="width: 100%"
|
||||||
placeholder="请选择慰问类型" filterable clearable>
|
placeholder="请选择场地类型" filterable clearable>
|
||||||
<el-option v-for="item in typeOptions"
|
<el-option v-for="item in typeOptions"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ layout("/layouts/platform.html"){
|
|||||||
</search-item>
|
</search-item>
|
||||||
<search-item label="场地类型">
|
<search-item label="场地类型">
|
||||||
<el-select v-model="pageForm.siteType" @change="doSearch" style="width: 100%"
|
<el-select v-model="pageForm.siteType" @change="doSearch" style="width: 100%"
|
||||||
placeholder="请选择慰问类型" filterable clearable>
|
placeholder="请选择场地类型" filterable clearable>
|
||||||
<el-option v-for="item in typeOptions"
|
<el-option v-for="item in typeOptions"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ layout("/layouts/platform.html"){
|
|||||||
</search-item>
|
</search-item>
|
||||||
<search-item label="场地类型">
|
<search-item label="场地类型">
|
||||||
<el-select v-model="pageForm.siteType" @change="doSearch" style="width: 100%"
|
<el-select v-model="pageForm.siteType" @change="doSearch" style="width: 100%"
|
||||||
placeholder="请选择慰问类型" filterable clearable>
|
placeholder="请选择场地类型" filterable clearable>
|
||||||
<el-option v-for="item in typeOptions"
|
<el-option v-for="item in typeOptions"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|||||||
+1
-1
@@ -123,7 +123,7 @@ const seat = {
|
|||||||
|
|
||||||
loadSeats() {
|
loadSeats() {
|
||||||
// 加载现有座位数据
|
// 加载现有座位数据
|
||||||
this.$axios.post('/platform/guildHall/selectSeat', {hallId: this.row.id}).then(res => {
|
this.$axios.post('/platform/guildHall/selectSeatList', {hallId: this.row.id}).then(res => {
|
||||||
if (res.code === 0 && res.data && res.data.length > 0) {
|
if (res.code === 0 && res.data && res.data.length > 0) {
|
||||||
this.seats = res.data
|
this.seats = res.data
|
||||||
// 根据现有数据计算行列数
|
// 根据现有数据计算行列数
|
||||||
+24
-12
@@ -9,7 +9,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-input placeholder="请输入名称" clearable v-model="pageForm.searchKeyword"></el-input>
|
<el-input placeholder="请输入名称" clearable v-model="pageForm.searchKeyword"></el-input>
|
||||||
</search-item>
|
</search-item>
|
||||||
<search-item label="年度">
|
<search-item label="年度">
|
||||||
<el-date-picker v-model="pageForm.year" type="year" placeholder="请选择年度"></el-date-picker>
|
<el-date-picker v-model="pageForm.year" type="year" placeholder="请选择年度" style="width: 100%;"></el-date-picker>
|
||||||
</search-item>
|
</search-item>
|
||||||
</search>
|
</search>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -31,6 +31,7 @@ layout("/layouts/platform.html"){
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<!--#include("/layouts/pagination.html"){}#-->
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="70%">
|
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="70%">
|
||||||
@@ -40,7 +41,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="年度" prop="year">
|
<el-form-item label="年度" prop="year">
|
||||||
<el-date-picker v-model="formData.year" type="year" value-format="yyyy"
|
<el-date-picker v-model="formData.year" type="year" value-format="yyyy"
|
||||||
placeholder="选择年度"></el-date-picker>
|
placeholder="选择年度" style="width: 100%;"></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="开始时间" prop="startTime">
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
@@ -60,6 +61,11 @@ layout("/layouts/platform.html"){
|
|||||||
style="width: 100%;">
|
style="width: 100%;">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="会厅选择" prop="hallId">
|
||||||
|
<el-select v-model="formData.hallId" placeholder="请选择会厅" style="width: 100%">
|
||||||
|
<el-option v-for="item in hallList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="内容" prop="content">
|
<el-form-item label="内容" prop="content">
|
||||||
<text-editor v-model="formData.content"></text-editor>
|
<text-editor v-model="formData.content"></text-editor>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -83,12 +89,14 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
formRules: {
|
formRules: {
|
||||||
name: [{required: true, message: '请输入名称', trigger: 'blur'}],
|
name: [{required: true, message: '必填', trigger: 'blur'}],
|
||||||
year: [{required: true, message: '请选择年度', trigger: 'change'}],
|
year: [{required: true, message: '必填', trigger: 'change'}],
|
||||||
startTime: [{required: true, message: '请选择开始时间', trigger: 'change'}],
|
startTime: [{required: true, message: '必填', trigger: 'change'}],
|
||||||
endTime: [{required: true, message: '请选择结束时间', trigger: 'change'}],
|
endTime: [{required: true, message: '必填', trigger: 'change'}],
|
||||||
content: [{required: true, message: '请输入内容', trigger: 'blur'}]
|
hallId: [{required: true, message: '必填', trigger: 'blur'}],
|
||||||
}
|
content: [{required: true, message: '必填', trigger: 'blur'}],
|
||||||
|
},
|
||||||
|
hallList: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -106,6 +114,7 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
onEdit(row) {
|
onEdit(row) {
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
|
row.year = row.year.toString()
|
||||||
this.formData = {...row}
|
this.formData = {...row}
|
||||||
},
|
},
|
||||||
onSave() {
|
onSave() {
|
||||||
@@ -139,13 +148,16 @@ layout("/layouts/platform.html"){
|
|||||||
this.$message.success(res.msg)
|
this.$message.success(res.msg)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
selectList() {
|
||||||
|
this.$axios.post('/platform/guildHall/selectList').then(res => {
|
||||||
|
this.hallList = res.data
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.selectList();
|
||||||
this.doSearch();
|
this.doSearch();
|
||||||
setTimeout(() => {
|
|
||||||
console.log(this.$refs.tableRef.columns)
|
|
||||||
},2000)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform.html"){
|
||||||
|
#-->
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<guava>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<search @search="doSearch">
|
||||||
|
<search-item label="会议">
|
||||||
|
<el-select clearable v-model="pageForm.meetingId" filterable placeholder="请选择会议">
|
||||||
|
<el-option
|
||||||
|
v-for="item in meetings"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</search-item>
|
||||||
|
</search>
|
||||||
|
</el-card>
|
||||||
|
<el-card shadow="never" class="mt20">
|
||||||
|
<table-tool label="选座人员">
|
||||||
|
<el-button size="small" type="primary" @click="exportExcel">导出选座人员</el-button>
|
||||||
|
</table-tool>
|
||||||
|
<el-table :data="tableData" @sort-change='pageOrder'>
|
||||||
|
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="姓名" prop="userName"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="工号" prop="loginName"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="性别" prop="sex"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="所属单位" prop="unitName"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="所属工会" prop="unionName"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="联系方式" prop="mobile"></el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="座位" prop="seat">
|
||||||
|
<template scope="{row}">
|
||||||
|
{{row.rowNumber + '排' + row.colNumber + '列'}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!--#include("/layouts/pagination.html"){}#-->
|
||||||
|
</el-card>
|
||||||
|
</guava>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
let vue = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
mixins: [initTableMixins],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
meetings: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 加载会议列表
|
||||||
|
loadMeetings() {
|
||||||
|
$.post('/platform/guildHall/seatSummary/listMeeting').then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.meetings = res.data
|
||||||
|
if (this.meetings.length > 0) {
|
||||||
|
this.pageForm.meetingId = this.meetings[0].id
|
||||||
|
}
|
||||||
|
this.pageData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exportExcel() {
|
||||||
|
this.$downLoad(loc() + "/exportExcel", {
|
||||||
|
meetingId: this.pageForm.meetingId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
this.loadMeetings()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
+837
@@ -0,0 +1,837 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container-seat {
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-seat {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-seat h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-seat p {
|
||||||
|
opacity: 0.9;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content-seat {
|
||||||
|
display: flex;
|
||||||
|
min-height: calc(100vh - 80px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-area {
|
||||||
|
flex: 1;
|
||||||
|
padding: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage {
|
||||||
|
text-align: center;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #1867b0;
|
||||||
|
color: white;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-seat-svg {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(10, 1fr);
|
||||||
|
gap: 8px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
width: fit-content;
|
||||||
|
justify-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-number {
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-back, .seat-cushion, .seat-armrest {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat.available .seat-back {
|
||||||
|
fill: #f8f9fa;
|
||||||
|
stroke: #dee2e6;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.available .seat-cushion {
|
||||||
|
fill: #ffffff;
|
||||||
|
stroke: #dee2e6;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.available .seat-armrest {
|
||||||
|
fill: #e9ecef;
|
||||||
|
stroke: #dee2e6;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.available .seat-number {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat.available:hover .seat-back {
|
||||||
|
fill: #e3f2fd;
|
||||||
|
stroke: #1867b0;
|
||||||
|
}
|
||||||
|
.seat.available:hover .seat-cushion {
|
||||||
|
fill: #f0f8ff;
|
||||||
|
stroke: #1867b0;
|
||||||
|
}
|
||||||
|
.seat.available:hover .seat-armrest {
|
||||||
|
fill: #e3f2fd;
|
||||||
|
stroke: #1867b0;
|
||||||
|
}
|
||||||
|
.seat.available:hover .seat-number {
|
||||||
|
color: #1867b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat.occupied .seat-back {
|
||||||
|
fill: #adb5bd;
|
||||||
|
stroke: #6c757d;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.occupied .seat-cushion {
|
||||||
|
fill: #d0d0d0;
|
||||||
|
stroke: #6c757d;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.occupied .seat-armrest {
|
||||||
|
fill: #adb5bd;
|
||||||
|
stroke: #6c757d;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.occupied .seat-number {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.seat.occupied {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat.selected .seat-back {
|
||||||
|
fill: #0d47a1;
|
||||||
|
stroke: #1867b0;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
.seat.selected .seat-cushion {
|
||||||
|
fill: #1867b0;
|
||||||
|
stroke: #0d47a1;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
.seat.selected .seat-armrest {
|
||||||
|
fill: #0d47a1;
|
||||||
|
stroke: #1867b0;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
.seat.selected .seat-number {
|
||||||
|
/*color: white;*/
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat.my-seat .seat-back {
|
||||||
|
fill: #c62828;
|
||||||
|
stroke: #ff3742;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
.seat.my-seat .seat-cushion {
|
||||||
|
fill: #ff4757;
|
||||||
|
stroke: #c62828;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
.seat.my-seat .seat-armrest {
|
||||||
|
fill: #c62828;
|
||||||
|
stroke: #ff3742;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
.seat.my-seat .seat-number {
|
||||||
|
/*color: white;*/
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat.disabled .seat-back {
|
||||||
|
fill: #f5f5f5;
|
||||||
|
stroke: #cccccc;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.disabled .seat-cushion {
|
||||||
|
fill: #f0f0f0;
|
||||||
|
stroke: #cccccc;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.disabled .seat-armrest {
|
||||||
|
fill: #f5f5f5;
|
||||||
|
stroke: #cccccc;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.seat.disabled .seat-number {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.seat.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-seat {
|
||||||
|
width: 300px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-left: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h3 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: #555;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #1867b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #1867b0;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover:not(:disabled) {
|
||||||
|
background-color: #155a8a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: #6c757d;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover:not(:disabled) {
|
||||||
|
background-color: #5a6268;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-booking {
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 3px solid #1867b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-booking p {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-booking strong {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-success {
|
||||||
|
background-color: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
border: 1px solid #c3e6cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-error {
|
||||||
|
background-color: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
border: 1px solid #f5c6cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 50px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.main-content-seat {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-seat {
|
||||||
|
width: 100%;
|
||||||
|
border-left: none;
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-grid {
|
||||||
|
gap: 6px;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-seat {
|
||||||
|
padding: 15px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-area, .sidebar-seat {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 会议选择弹窗样式 */
|
||||||
|
.meeting-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-modal-content {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 30px;
|
||||||
|
max-width: 600px;
|
||||||
|
width: 90%;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-modal h2 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item {
|
||||||
|
border: 2px solid #e0e0e0;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item:hover {
|
||||||
|
border-color: #1867b0;
|
||||||
|
background: #f0f8ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item.selected {
|
||||||
|
border-color: #1867b0;
|
||||||
|
background: #e8f4fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-info {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-time {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
margin-top: 25px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn {
|
||||||
|
padding: 10px 25px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn-primary {
|
||||||
|
background-color: #1867b0;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn-primary:hover:not(:disabled) {
|
||||||
|
background-color: #155a8a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn-secondary {
|
||||||
|
background-color: #6c757d;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn-secondary:hover:not(:disabled) {
|
||||||
|
background-color: #5a6268;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btn:disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<guava>
|
||||||
|
<!-- 会议选择弹窗 -->
|
||||||
|
<div v-if="showMeetingModal" class="meeting-modal">
|
||||||
|
<div class="meeting-modal-content">
|
||||||
|
<h2>请选择会议</h2>
|
||||||
|
<div class="meeting-list">
|
||||||
|
<div
|
||||||
|
v-for="meeting in meetings"
|
||||||
|
:key="meeting.id"
|
||||||
|
:class="['meeting-item', { selected: selectedMeetingId === meeting.id }]"
|
||||||
|
@click="selectMeeting(meeting)"
|
||||||
|
>
|
||||||
|
<div class="meeting-name">{{ meeting.name }}</div>
|
||||||
|
<div class="meeting-info">地点:{{ meeting.address }}</div>
|
||||||
|
<div class="meeting-time">时间:{{ meeting.startTime }} 至 {{ meeting.endTime }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-buttons">
|
||||||
|
<button
|
||||||
|
class="modal-btn"
|
||||||
|
@click="showMeetingModal = false"
|
||||||
|
>
|
||||||
|
取消选择
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="modal-btn modal-btn-primary"
|
||||||
|
@click="confirmMeetingSelection"
|
||||||
|
:disabled="!selectedMeetingId"
|
||||||
|
>
|
||||||
|
确认选择
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-seat">
|
||||||
|
<div class="header-seat" v-if="meeting">
|
||||||
|
<h1>{{ meeting.name }}</h1>
|
||||||
|
<p>{{ meeting.startTime + ' 至 ' + meeting.endTime}}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main-content-seat">
|
||||||
|
<div class="seat-area">
|
||||||
|
<!-- <div class="stage">主席台</div>-->
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
<div class="legend-item">
|
||||||
|
<svg class="legend-seat-svg" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#f8f9fa" stroke="#dee2e6" stroke-width="1"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#ffffff" stroke="#dee2e6" stroke-width="1"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#e9ecef" stroke="#dee2e6" stroke-width="1"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#e9ecef" stroke="#dee2e6" stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
<span>可选座位</span>
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<svg class="legend-seat-svg" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#adb5bd" stroke="#6c757d" stroke-width="1"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#d0d0d0" stroke="#6c757d" stroke-width="1"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#adb5bd" stroke="#6c757d" stroke-width="1"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#adb5bd" stroke="#6c757d" stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
<span>已被占用</span>
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<svg class="legend-seat-svg" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#0d47a1" stroke="#1867b0" stroke-width="2"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#1867b0" stroke="#0d47a1" stroke-width="2"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#0d47a1" stroke="#1867b0" stroke-width="2"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#0d47a1" stroke="#1867b0" stroke-width="2"/>
|
||||||
|
</svg>
|
||||||
|
<span>当前选择</span>
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<svg class="legend-seat-svg" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#c62828" stroke="#ff3742" stroke-width="2"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#ff4757" stroke="#c62828" stroke-width="2"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#c62828" stroke="#ff3742" stroke-width="2"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#c62828" stroke="#ff3742" stroke-width="2"/>
|
||||||
|
</svg>
|
||||||
|
<span>我的座位</span>
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<svg class="legend-seat-svg" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#f5f5f5" stroke="#cccccc" stroke-width="1"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#f0f0f0" stroke="#cccccc" stroke-width="1"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#f5f5f5" stroke="#cccccc" stroke-width="1"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#f5f5f5" stroke="#cccccc" stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
<span>禁用座位</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="loading" class="loading">
|
||||||
|
<p>正在加载座位信息...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="seat-grid" :style="gridStyle">
|
||||||
|
<div
|
||||||
|
v-for="seat in seats"
|
||||||
|
:key="seat.id"
|
||||||
|
:class="getSeatClass(seat)"
|
||||||
|
class="seat"
|
||||||
|
@click="selectSeat(seat)"
|
||||||
|
:title="getSeatTitle(seat)"
|
||||||
|
>
|
||||||
|
<svg class="seat-icon" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- 座位靠背 -->
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" class="seat-back"/>
|
||||||
|
<!-- 座位坐垫 -->
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" class="seat-cushion"/>
|
||||||
|
<!-- 扶手 -->
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" class="seat-armrest"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" class="seat-armrest"/>
|
||||||
|
</svg>
|
||||||
|
<span class="seat-number">{{ seat.rowNumber }}-{{ seat.colNumber }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar-seat">
|
||||||
|
<div class="section">
|
||||||
|
<h3>操作列</h3>
|
||||||
|
<button
|
||||||
|
class="btn btn-primary mt10"
|
||||||
|
@click="showMeetingModal = true"
|
||||||
|
>
|
||||||
|
切换会议
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="section">
|
||||||
|
<h3>座位选择</h3>
|
||||||
|
|
||||||
|
<div v-if="selectedSeat" class="my-booking" style="border-left-color: #28a745;">
|
||||||
|
<p><strong>选中座位:</strong> {{ selectedSeat.seatNumber }}</p>
|
||||||
|
<p><strong>位置:</strong> 第{{ selectedSeat.rowNumber }}排第{{ selectedSeat.colNumber }}列</p>
|
||||||
|
</div>
|
||||||
|
<div v-else class="my-booking">
|
||||||
|
<p style="color: #999;">请点击座位进行选择</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="alertMessage" :class="'alert alert-' + alertType">
|
||||||
|
{{ alertMessage }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="btn btn-primary mt10"
|
||||||
|
@click="confirmSelection"
|
||||||
|
:disabled="!selectedSeat || submitting"
|
||||||
|
>
|
||||||
|
{{ submitting ? '提交中...' : '提交选座' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>我的座位</h3>
|
||||||
|
<div v-if="myCurrentSeat" class="my-booking">
|
||||||
|
<p><strong>座位号:</strong> {{ myCurrentSeat.rowNumber }}-{{ myCurrentSeat.colNumber }} </p>
|
||||||
|
<p><strong>位置:</strong> 第{{ myCurrentSeat.rowNumber }}排第{{ myCurrentSeat.colNumber }}列</p>
|
||||||
|
<p><strong>选择时间:</strong> {{ formatTime(myCurrentSeat.selectTime) }}</p>
|
||||||
|
</div>
|
||||||
|
<div v-else class="my-booking">
|
||||||
|
<p style="color: #999;">暂未选择座位</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</guava>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
meetings: [], // 会议列表
|
||||||
|
selectedMeetingId: null, // 选中的会议ID
|
||||||
|
showMeetingModal: true, // 显示会议选择弹窗
|
||||||
|
meeting: null,
|
||||||
|
seats: [],
|
||||||
|
selectedSeat: null,
|
||||||
|
myCurrentSeat: null,
|
||||||
|
loading: false,
|
||||||
|
submitting: false,
|
||||||
|
alertMessage: '',
|
||||||
|
alertType: 'success',
|
||||||
|
seatConfig: {
|
||||||
|
rows: 8,
|
||||||
|
cols: 12
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loadMeetings();
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
gridStyle() {
|
||||||
|
return {
|
||||||
|
'grid-template-columns': 'repeat(' + this.seatConfig.cols + ', 1fr)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 加载会议列表
|
||||||
|
loadMeetings() {
|
||||||
|
$.post('/platform/guildHall/meeting/selectList').then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.meetings = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 选择会议
|
||||||
|
selectMeeting(meeting) {
|
||||||
|
this.selectedMeetingId = meeting.id;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 确认会议选择
|
||||||
|
confirmMeetingSelection() {
|
||||||
|
if (!this.selectedMeetingId) {
|
||||||
|
this.$message.error('请选择一个会议');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedMeeting = this.meetings.find(m => m.id === this.selectedMeetingId);
|
||||||
|
if (selectedMeeting) {
|
||||||
|
this.meeting = selectedMeeting
|
||||||
|
this.loadSeats();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询选座情况
|
||||||
|
async loadSeats() {
|
||||||
|
if (!this.meeting.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
const {code,data,msg} = await $.post('/platform/guildHall/selectSeat/loadSeats', {meetingId: this.meeting.id})
|
||||||
|
if (code === 0) {
|
||||||
|
if(data.length === 0) {
|
||||||
|
this.$message.warning('该会议暂未设置座位')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.seats = data;
|
||||||
|
this.myCurrentSeat = this.seats.find(seat => seat.isMine);
|
||||||
|
// 根据现有数据计算行列数
|
||||||
|
const maxRow = Math.max(...this.seats.map(s => parseInt(s.rowNumber)))
|
||||||
|
const maxCol = Math.max(...this.seats.map(s => parseInt(s.colNumber)))
|
||||||
|
this.seatConfig.rows = maxRow
|
||||||
|
this.seatConfig.cols = maxCol
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
this.showMeetingModal = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
selectSeat(seat) {
|
||||||
|
if (!seat.enable) {
|
||||||
|
this.$message.error('该座位已被禁用');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat.isOccupied && !seat.isMine) {
|
||||||
|
this.$message.error('该座位已被占用');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat.isMine) {
|
||||||
|
this.$message.success('这是您当前的座位');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedSeat = seat;
|
||||||
|
this.$set(this.selectedSeat, 'seatNumber', seat.rowNumber + '-' + seat.colNumber)
|
||||||
|
},
|
||||||
|
|
||||||
|
async confirmSelection() {
|
||||||
|
if (!this.selectedSeat) {
|
||||||
|
this.$message.error('请先选择座位');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.submitting = true;
|
||||||
|
const {code,data,msg} = await $.post('/platform/guildHall/selectSeat/doSelect', {
|
||||||
|
meetingId: this.meeting.id,
|
||||||
|
seatNumber: this.selectedSeat.seatNumber,
|
||||||
|
rowNumber: this.selectedSeat.rowNumber,
|
||||||
|
colNumber: this.selectedSeat.colNumber
|
||||||
|
})
|
||||||
|
this.submitting = false
|
||||||
|
|
||||||
|
if (code === 0) {
|
||||||
|
this.$message.success("选座成功")
|
||||||
|
this.loadSeats();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getSeatClass(seat) {
|
||||||
|
if (!seat.enable) return 'disabled';
|
||||||
|
if (seat.isMine) return 'my-seat';
|
||||||
|
if (seat === this.selectedSeat) return 'selected';
|
||||||
|
if (seat.isOccupied) return 'occupied';
|
||||||
|
return 'available';
|
||||||
|
},
|
||||||
|
|
||||||
|
getSeatTitle(seat) {
|
||||||
|
if (seat.isMine) return '我的座位';
|
||||||
|
if (seat === this.selectedSeat) return '当前选择';
|
||||||
|
if (seat.status === 1) return '已被占用';
|
||||||
|
return '点击选择此座位';
|
||||||
|
},
|
||||||
|
|
||||||
|
formatTime(time) {
|
||||||
|
if (!time) return '';
|
||||||
|
return new Date(time).toLocaleString('zh-CN');
|
||||||
|
},
|
||||||
|
|
||||||
|
showAlert(message, type) {
|
||||||
|
this.alertMessage = message;
|
||||||
|
this.alertType = type;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.alertMessage = '';
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -234,6 +234,7 @@ const apply = {
|
|||||||
selectTime(item) {
|
selectTime(item) {
|
||||||
if((item.dateStr + ' ' + item.startTime + '-' + item.endTime) !== (this.selected.dateStr + ' ' + this.selected.startTime + '-' + this.selected.endTime)) {
|
if((item.dateStr + ' ' + item.startTime + '-' + item.endTime) !== (this.selected.dateStr + ' ' + this.selected.startTime + '-' + this.selected.endTime)) {
|
||||||
this.$set(this.selected, 'day', item.dateStr)
|
this.$set(this.selected, 'day', item.dateStr)
|
||||||
|
this.$set(this.selected, "dateStr", item.dateStr)
|
||||||
this.$set(this.selected, 'startTime', item.startTime)
|
this.$set(this.selected, 'startTime', item.startTime)
|
||||||
this.$set(this.selected, 'endTime', item.endTime)
|
this.$set(this.selected, 'endTime', item.endTime)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+908
@@ -0,0 +1,908 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform_h5.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
*{
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.mobile-seat-container {
|
||||||
|
background: #f7f8fa;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding-bottom: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-header {
|
||||||
|
background: white;
|
||||||
|
padding: 16px;
|
||||||
|
border-bottom: 1px solid #ebedf0;
|
||||||
|
/*position: sticky;*/
|
||||||
|
/*top: 0;*/
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-header .meeting-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #323233;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-header .meeting-time {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #969799;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-stage {
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px;
|
||||||
|
background: transparent;
|
||||||
|
margin: 16px;
|
||||||
|
border-radius: 16px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.15));
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-text {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1565c0;
|
||||||
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
background: linear-gradient(45deg, #1976d2, #42a5f5);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-legend {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: white;
|
||||||
|
margin: 0 16px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-legend-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-legend-seat {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat-area {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoom-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
/*background: rgba(128, 128, 128, 0.1);*/
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoom-controls .van-button {
|
||||||
|
background: rgba(128, 128, 128, 0.2) !important;
|
||||||
|
border: 1px solid rgba(128, 128, 128, 0.3) !important;
|
||||||
|
color: #666 !important;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 2px 6px !important;
|
||||||
|
height: 24px !important;
|
||||||
|
min-width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoom-controls .van-button:disabled {
|
||||||
|
background: rgba(128, 128, 128, 0.1) !important;
|
||||||
|
color: #ccc !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoom-level {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #666;
|
||||||
|
padding: 3px 6px;
|
||||||
|
background: rgba(128, 128, 128, 0.15);
|
||||||
|
border-radius: 6px;
|
||||||
|
min-width: 45px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seat-grid-container {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
position: relative;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat-grid {
|
||||||
|
display: grid;
|
||||||
|
/*grid-template-columns: repeat(10, 1fr);*/
|
||||||
|
gap: 4px;
|
||||||
|
background: white;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
width: 100%;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 60vh;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
/* 隐藏滚动条 */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
-ms-overflow-style: none; /* IE 和 Edge */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏 Webkit 浏览器的滚动条 */
|
||||||
|
.mobile-seat-grid::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
position: relative;
|
||||||
|
touch-action: manipulation;
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat-number {
|
||||||
|
font-size: 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 座位状态样式 */
|
||||||
|
.mobile-seat.available .seat-back {
|
||||||
|
fill: #f8f9fa;
|
||||||
|
stroke: #dee2e6;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.available .seat-cushion {
|
||||||
|
fill: #ffffff;
|
||||||
|
stroke: #dee2e6;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.available .seat-armrest {
|
||||||
|
fill: #e9ecef;
|
||||||
|
stroke: #dee2e6;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.available .mobile-seat-number {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.available:active .seat-back {
|
||||||
|
fill: #e3f2fd;
|
||||||
|
stroke: #1867b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.available:active .seat-cushion {
|
||||||
|
fill: #f0f8ff;
|
||||||
|
stroke: #1867b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.available:active .seat-armrest {
|
||||||
|
fill: #e3f2fd;
|
||||||
|
stroke: #1867b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.occupied .seat-back {
|
||||||
|
fill: #adb5bd;
|
||||||
|
stroke: #6c757d;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.occupied .seat-cushion {
|
||||||
|
fill: #d0d0d0;
|
||||||
|
stroke: #6c757d;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.occupied .seat-armrest {
|
||||||
|
fill: #adb5bd;
|
||||||
|
stroke: #6c757d;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.occupied .mobile-seat-number {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.occupied {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.selected .seat-back {
|
||||||
|
fill: #0d47a1;
|
||||||
|
stroke: #1867b0;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.selected .seat-cushion {
|
||||||
|
fill: #1867b0;
|
||||||
|
stroke: #0d47a1;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.selected .seat-armrest {
|
||||||
|
fill: #0d47a1;
|
||||||
|
stroke: #1867b0;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.selected .mobile-seat-number {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.my-seat .seat-back {
|
||||||
|
fill: #c62828;
|
||||||
|
stroke: #ff3742;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.my-seat .seat-cushion {
|
||||||
|
fill: #ff4757;
|
||||||
|
stroke: #c62828;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.my-seat .seat-armrest {
|
||||||
|
fill: #c62828;
|
||||||
|
stroke: #ff3742;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.my-seat .mobile-seat-number {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.disabled .seat-back {
|
||||||
|
fill: #f5f5f5;
|
||||||
|
stroke: #cccccc;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.disabled .seat-cushion {
|
||||||
|
fill: #f0f0f0;
|
||||||
|
stroke: #cccccc;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.disabled .seat-armrest {
|
||||||
|
fill: #f5f5f5;
|
||||||
|
stroke: #cccccc;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.disabled .mobile-seat-number {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-bottom-panel {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: white;
|
||||||
|
border-top: 1px solid #ebedf0;
|
||||||
|
padding: 16px;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-selected-info {
|
||||||
|
background: #f0f8ff;
|
||||||
|
border: 1px solid #1989fa;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-selected-info .seat-info {
|
||||||
|
color: #1989fa;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-my-seat-info {
|
||||||
|
background: #fff2f0;
|
||||||
|
border: 1px solid #ff4757;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
margin-top: 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-my-seat-info .seat-info {
|
||||||
|
color: #ff4757;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 60px 20px;
|
||||||
|
color: #969799;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 会议选择弹窗样式 */
|
||||||
|
.meeting-modal-content {
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-modal-content .van-nav-bar__text {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item {
|
||||||
|
border: 1px solid #ebedf0;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background: white;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item:active {
|
||||||
|
background: #f0f8ff;
|
||||||
|
border-color: #1989fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item.selected {
|
||||||
|
background: #f0f8ff;
|
||||||
|
border-color: #1989fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #323233;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-info {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #646566;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #969799;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 375px) {
|
||||||
|
.mobile-seat-grid {
|
||||||
|
grid-template-columns: repeat(8, 28px);
|
||||||
|
gap: 3px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat-icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-seat-number {
|
||||||
|
font-size: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<van-nav-bar title="会议选座" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
|
||||||
|
|
||||||
|
<!-- 会议选择弹窗 -->
|
||||||
|
<van-popup v-model="showMeetingModal" position="bottom" :close-on-click-overlay="false">
|
||||||
|
<div class="meeting-modal-content">
|
||||||
|
<van-nav-bar title="选择会议"></van-nav-bar>
|
||||||
|
<div style="padding: 16px;">
|
||||||
|
<div v-for="meeting in meetings" :key="meeting.id"
|
||||||
|
:class="['meeting-item', { selected: selectedMeetingId === meeting.id }]"
|
||||||
|
@click="selectMeeting(meeting)">
|
||||||
|
<div class="meeting-name">{{ meeting.name }}</div>
|
||||||
|
<div class="meeting-info">地点:{{ meeting.address }}</div>
|
||||||
|
<div class="meeting-time">时间:{{ meeting.startTime }} 至 {{ meeting.endTime }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; gap: 22px">
|
||||||
|
<van-button block @click="showMeetingModal = false" style="margin-top: 16px;">
|
||||||
|
取消选择
|
||||||
|
</van-button>
|
||||||
|
|
||||||
|
<van-button block type="info" :disabled="!selectedMeetingId"
|
||||||
|
@click="confirmMeetingSelection" style="margin-top: 16px;">
|
||||||
|
确认选择
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-popup>
|
||||||
|
|
||||||
|
<div class="mobile-seat-container">
|
||||||
|
<!-- 头部信息 -->
|
||||||
|
<div class="mobile-header" v-if="meeting">
|
||||||
|
<div class="meeting-title">{{ meeting.name }}</div>
|
||||||
|
<div class="meeting-time">{{ meeting.startTime }} 至 {{ meeting.endTime }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 主席台 -->
|
||||||
|
<div class="mobile-stage">
|
||||||
|
<svg class="stage-svg" viewBox="0 0 320 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- 背景装饰 -->
|
||||||
|
<rect x="0" y="0" width="320" height="100" fill="url(#bgGradient)" rx="12" ry="12"/>
|
||||||
|
|
||||||
|
<!-- 主舞台基座 -->
|
||||||
|
<ellipse cx="160" cy="75" rx="140" ry="15" fill="url(#baseGradient)" opacity="0.8"/>
|
||||||
|
|
||||||
|
<!-- 主舞台平台 -->
|
||||||
|
<path d="M 30 45 Q 30 35 40 35 L 280 35 Q 290 35 290 45 L 285 65 Q 285 70 280 70 L 40 70 Q 35 70 35 65 Z"
|
||||||
|
fill="url(#stageGradient)" stroke="url(#stageStroke)" stroke-width="2"/>
|
||||||
|
|
||||||
|
<!-- 台阶层次 -->
|
||||||
|
<path d="M 45 50 Q 45 45 50 45 L 270 45 Q 275 45 275 50 L 272 62 Q 272 65 270 65 L 50 65 Q 47 65 47 62 Z"
|
||||||
|
fill="url(#stepGradient)" stroke="#1976d2" stroke-width="1"/>
|
||||||
|
|
||||||
|
<!-- 装饰花纹 -->
|
||||||
|
<path d="M 60 52 Q 65 50 70 52 Q 75 54 80 52" stroke="#ffffff" stroke-width="1.5" fill="none" opacity="0.7"/>
|
||||||
|
<path d="M 240 52 Q 245 50 250 52 Q 255 54 260 52" stroke="#ffffff" stroke-width="1.5" fill="none" opacity="0.7"/>
|
||||||
|
|
||||||
|
<!-- 中央装饰 -->
|
||||||
|
<circle cx="160" cy="52" r="8" fill="url(#centerGradient)" stroke="#ffffff" stroke-width="1" opacity="0.9"/>
|
||||||
|
<circle cx="160" cy="52" r="4" fill="#ffd700" opacity="0.8"/>
|
||||||
|
|
||||||
|
<!-- 聚光灯光束 -->
|
||||||
|
<path d="M 80 20 L 85 35 L 75 35 Z" fill="url(#lightGradient)" opacity="0.6"/>
|
||||||
|
<path d="M 160 15 L 167 35 L 153 35 Z" fill="url(#lightGradient)" opacity="0.8"/>
|
||||||
|
<path d="M 240 20 L 245 35 L 235 35 Z" fill="url(#lightGradient)" opacity="0.6"/>
|
||||||
|
|
||||||
|
<!-- 聚光灯 -->
|
||||||
|
<circle cx="80" cy="18" r="4" fill="#ffd700" stroke="#ffb300" stroke-width="1"/>
|
||||||
|
<circle cx="160" cy="13" r="5" fill="#ffd700" stroke="#ffb300" stroke-width="1"/>
|
||||||
|
<circle cx="240" cy="18" r="4" fill="#ffd700" stroke="#ffb300" stroke-width="1"/>
|
||||||
|
|
||||||
|
<!-- 星光效果 -->
|
||||||
|
<g opacity="0.8">
|
||||||
|
<path d="M 100 25 L 102 30 L 107 30 L 103 33 L 105 38 L 100 35 L 95 38 L 97 33 L 93 30 L 98 30 Z" fill="#ffd700"/>
|
||||||
|
<path d="M 220 28 L 222 32 L 226 32 L 223 35 L 225 39 L 220 36 L 215 39 L 217 35 L 214 32 L 218 32 Z" fill="#ffd700"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 渐变定义 -->
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#e3f2fd;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#bbdefb;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="stageGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#1e88e5;stop-opacity:1" />
|
||||||
|
<stop offset="30%" style="stop-color:#1976d2;stop-opacity:1" />
|
||||||
|
<stop offset="70%" style="stop-color:#1565c0;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#0d47a1;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="stageStroke" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#42a5f5;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#1565c0;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="stepGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#42a5f5;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#1976d2;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="baseGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#90caf9;stop-opacity:0.6" />
|
||||||
|
<stop offset="100%" style="stop-color:#1976d2;stop-opacity:0.8" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient id="centerGradient" cx="50%" cy="50%" r="50%">
|
||||||
|
<stop offset="0%" style="stop-color:#ffffff;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#1976d2;stop-opacity:1" />
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="lightGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#fff9c4;stop-opacity:0.9" />
|
||||||
|
<stop offset="100%" style="stop-color:#fff59d;stop-opacity:0.3" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<div class="stage-text">主席台</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 图例 -->
|
||||||
|
<div class="mobile-legend">
|
||||||
|
<div class="mobile-legend-item">
|
||||||
|
<svg class="mobile-legend-seat" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#f8f9fa" stroke="#dee2e6"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#ffffff" stroke="#dee2e6"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#e9ecef" stroke="#dee2e6"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#e9ecef" stroke="#dee2e6"
|
||||||
|
stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
<span>可选</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-legend-item">
|
||||||
|
<svg class="mobile-legend-seat" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#adb5bd" stroke="#6c757d"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#d0d0d0" stroke="#6c757d"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#adb5bd" stroke="#6c757d"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#adb5bd" stroke="#6c757d"
|
||||||
|
stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
<span>占用</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-legend-item">
|
||||||
|
<svg class="mobile-legend-seat" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#0d47a1" stroke="#1867b0"
|
||||||
|
stroke-width="2"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#1867b0" stroke="#0d47a1"
|
||||||
|
stroke-width="2"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#0d47a1" stroke="#1867b0"
|
||||||
|
stroke-width="2"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#0d47a1" stroke="#1867b0"
|
||||||
|
stroke-width="2"/>
|
||||||
|
</svg>
|
||||||
|
<span>选中</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-legend-item">
|
||||||
|
<svg class="mobile-legend-seat" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#c62828" stroke="#ff3742"
|
||||||
|
stroke-width="2"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#ff4757" stroke="#c62828"
|
||||||
|
stroke-width="2"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#c62828" stroke="#ff3742"
|
||||||
|
stroke-width="2"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#c62828" stroke="#ff3742"
|
||||||
|
stroke-width="2"/>
|
||||||
|
</svg>
|
||||||
|
<span>我的</span>
|
||||||
|
</div>
|
||||||
|
<div class="mobile-legend-item">
|
||||||
|
<svg class="mobile-legend-seat" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" fill="#f5f5f5" stroke="#cccccc"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" fill="#f0f0f0" stroke="#cccccc"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" fill="#f5f5f5" stroke="#cccccc"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" fill="#f5f5f5" stroke="#cccccc"
|
||||||
|
stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
<span>禁用</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 座位区域 -->
|
||||||
|
<div class="mobile-seat-area">
|
||||||
|
<van-loading v-if="loading" type="spinner" color="#1989fa" class="mobile-loading">
|
||||||
|
正在加载座位信息...
|
||||||
|
</van-loading>
|
||||||
|
|
||||||
|
<div v-else class="seat-grid-container">
|
||||||
|
<div class="mobile-seat-grid" id="seatGrid" :style="gridStyle">
|
||||||
|
<div v-for="seat in seats" :key="seat.id"
|
||||||
|
:class="getSeatClass(seat)"
|
||||||
|
class="mobile-seat"
|
||||||
|
@click="selectSeat(seat)">
|
||||||
|
<svg class="mobile-seat-icon" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="5" width="34" height="20" rx="3" ry="3" class="seat-back"/>
|
||||||
|
<rect x="5" y="22" width="40" height="18" rx="4" ry="4" class="seat-cushion"/>
|
||||||
|
<rect x="2" y="20" width="6" height="15" rx="2" ry="2" class="seat-armrest"/>
|
||||||
|
<rect x="42" y="20" width="6" height="15" rx="2" ry="2" class="seat-armrest"/>
|
||||||
|
</svg>
|
||||||
|
<span class="mobile-seat-number">{{ seat.rowNumber }}-{{ seat.colNumber }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 缩放控制按钮 -->
|
||||||
|
<div class="zoom-controls">
|
||||||
|
<van-button type="default" size="mini" @click="zoomOut" :disabled="currentScale <= 0.5">
|
||||||
|
<van-icon name="minus" size="12" />
|
||||||
|
缩小
|
||||||
|
</van-button>
|
||||||
|
<div class="zoom-level">
|
||||||
|
<van-icon name="search" size="12" />
|
||||||
|
{{ Math.round(currentScale * 100) }}%
|
||||||
|
</div>
|
||||||
|
<van-button type="default" size="mini" @click="resetZoom">
|
||||||
|
<van-icon name="replay" size="12" />
|
||||||
|
重置
|
||||||
|
</van-button>
|
||||||
|
<van-button type="default" size="mini" @click="zoomIn" :disabled="currentScale >= 3">
|
||||||
|
<van-icon name="plus" size="12" />
|
||||||
|
放大
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 我的座位信息 -->
|
||||||
|
<div v-if="myCurrentSeat" class="mobile-my-seat-info" style="margin: 16px;">
|
||||||
|
<div style="margin-bottom: 4px;">我的座位</div>
|
||||||
|
<div class="seat-info">{{ myCurrentSeat.rowNumber }}-{{ myCurrentSeat.colNumber }} (第{{ myCurrentSeat.rowNumber }}排第{{
|
||||||
|
myCurrentSeat.colNumber }}列)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部操作面板 -->
|
||||||
|
<div class="mobile-bottom-panel">
|
||||||
|
<div v-if="selectedSeat" class="mobile-selected-info">
|
||||||
|
<div style="margin-bottom: 4px;">已选择座位</div>
|
||||||
|
<div class="seat-info">{{ selectedSeat.rowNumber }}-{{ selectedSeat.colNumber }} (第{{ selectedSeat.rowNumber }}排第{{
|
||||||
|
selectedSeat.colNumber }}列)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; gap: 22px">
|
||||||
|
<van-button type="info" block @click="showMeetingModal = true">
|
||||||
|
切换会议
|
||||||
|
</van-button>
|
||||||
|
|
||||||
|
<van-button type="info" block :disabled="!selectedSeat || submitting"
|
||||||
|
:loading="submitting" @click="confirmSelection">
|
||||||
|
{{ submitting ? '提交中...' : '确认选座' }}
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const vue = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
meetings: [], // 会议列表
|
||||||
|
selectedMeetingId: null, // 选中的会议ID
|
||||||
|
showMeetingModal: true, // 显示会议选择弹窗
|
||||||
|
meeting: null,
|
||||||
|
seats: [],
|
||||||
|
selectedSeat: null,
|
||||||
|
myCurrentSeat: null,
|
||||||
|
loading: false,
|
||||||
|
submitting: false,
|
||||||
|
currentScale: 1, // 当前缩放比例
|
||||||
|
seatConfig: {
|
||||||
|
rows: 8,
|
||||||
|
cols: 12
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loadMeetings();
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initPinchZoom();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
gridStyle() {
|
||||||
|
return {
|
||||||
|
'grid-template-columns': 'repeat(' + this.seatConfig.cols + ', 1fr)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 加载会议列表
|
||||||
|
loadMeetings() {
|
||||||
|
$.post('/platform/guildHall/meeting/selectList').then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.meetings = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 选择会议
|
||||||
|
selectMeeting(meeting) {
|
||||||
|
this.selectedMeetingId = meeting.id;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 确认会议选择
|
||||||
|
confirmMeetingSelection() {
|
||||||
|
if (!this.selectedMeetingId) {
|
||||||
|
this.$toast('请选择一个会议');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedMeeting = this.meetings.find(m => m.id === this.selectedMeetingId);
|
||||||
|
if (selectedMeeting) {
|
||||||
|
this.meeting = selectedMeeting
|
||||||
|
this.loadSeats();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询选座情况
|
||||||
|
async loadSeats() {
|
||||||
|
if (!this.meeting.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
const {
|
||||||
|
code,
|
||||||
|
data,
|
||||||
|
msg
|
||||||
|
} = await $.post('/platform/guildHall/selectSeat/loadSeats', {meetingId: this.meeting.id})
|
||||||
|
if (code === 0) {
|
||||||
|
this.seats = data;
|
||||||
|
this.myCurrentSeat = this.seats.find(seat => seat.isMine);
|
||||||
|
// 根据现有数据计算行列数
|
||||||
|
const maxRow = Math.max(...this.seats.map(s => parseInt(s.rowNumber)))
|
||||||
|
const maxCol = Math.max(...this.seats.map(s => parseInt(s.colNumber)))
|
||||||
|
this.seatConfig.rows = maxRow
|
||||||
|
this.seatConfig.cols = maxCol
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
this.showMeetingModal = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
selectSeat(seat) {
|
||||||
|
if (!seat.enable) {
|
||||||
|
this.$toast('该座位已被禁用');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat.isOccupied && !seat.isMine) {
|
||||||
|
this.$toast('该座位已被占用');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat.isMine) {
|
||||||
|
this.$toast('这是您当前的座位');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedSeat = seat;
|
||||||
|
// 添加触觉反馈
|
||||||
|
if (navigator.vibrate) {
|
||||||
|
navigator.vibrate(50);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async confirmSelection() {
|
||||||
|
if (!this.selectedSeat) {
|
||||||
|
this.$toast('请先选择座位');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.submitting = true;
|
||||||
|
const {code, data, msg} = await $.post('/platform/guildHall/selectSeat/doSelect', {
|
||||||
|
meetingId: this.meeting.id,
|
||||||
|
rowNumber: this.selectedSeat.rowNumber,
|
||||||
|
colNumber: this.selectedSeat.colNumber
|
||||||
|
})
|
||||||
|
this.submitting = false
|
||||||
|
|
||||||
|
if (code === 0) {
|
||||||
|
this.$toast.success("选座成功")
|
||||||
|
this.selectedSeat = null;
|
||||||
|
this.loadSeats();
|
||||||
|
} else {
|
||||||
|
this.$toast.fail(msg || '选座失败');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getSeatClass(seat) {
|
||||||
|
if (!seat.enable) {
|
||||||
|
return 'disabled';
|
||||||
|
}
|
||||||
|
if (seat.isMine) return 'my-seat';
|
||||||
|
if (seat === this.selectedSeat) return 'selected';
|
||||||
|
if (seat.isOccupied) return 'occupied';
|
||||||
|
return 'available';
|
||||||
|
},
|
||||||
|
|
||||||
|
getSeatTitle(seat) {
|
||||||
|
if (seat.isMine) return '我的座位';
|
||||||
|
if (seat === this.selectedSeat) return '当前选择';
|
||||||
|
if (seat.status === 1) return '已被占用';
|
||||||
|
return '点击选择此座位';
|
||||||
|
},
|
||||||
|
|
||||||
|
formatTime(time) {
|
||||||
|
if (!time) return '';
|
||||||
|
return new Date(time).toLocaleString('zh-CN');
|
||||||
|
},
|
||||||
|
|
||||||
|
// 放大
|
||||||
|
zoomIn() {
|
||||||
|
if (this.currentScale < 3) {
|
||||||
|
this.currentScale = Math.min(3, this.currentScale + 0.2);
|
||||||
|
this.applyZoom();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 缩小
|
||||||
|
zoomOut() {
|
||||||
|
if (this.currentScale > 0.5) {
|
||||||
|
this.currentScale = Math.max(0.5, this.currentScale - 0.2);
|
||||||
|
this.applyZoom();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 重置缩放
|
||||||
|
resetZoom() {
|
||||||
|
this.currentScale = 1;
|
||||||
|
this.applyZoom();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 应用缩放
|
||||||
|
applyZoom() {
|
||||||
|
const seats = document.querySelectorAll('.mobile-seat');
|
||||||
|
const seatGrid = document.querySelector('.mobile-seat-grid');
|
||||||
|
|
||||||
|
seats.forEach(seat => {
|
||||||
|
seat.style.transform = 'scale(' + this.currentScale + ')';
|
||||||
|
seat.style.transformOrigin = 'center center';
|
||||||
|
seat.style.transition = 'transform 0.2s ease';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 动态调整网格间距
|
||||||
|
if (seatGrid) {
|
||||||
|
const baseGap = 4;
|
||||||
|
const adjustedGap = baseGap * this.currentScale * 5;
|
||||||
|
seatGrid.style.gap = adjustedGap + 'px';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 初始化双指缩放功能(已替换为按钮控制)
|
||||||
|
initPinchZoom() {
|
||||||
|
// 双指缩放功能已被按钮控制替代,保留此方法以避免错误
|
||||||
|
console.log('双指缩放功能已替换为按钮控制');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
Reference in New Issue
Block a user