Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -154,6 +154,7 @@ public class ActGroupController {
|
|||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
u.*,
|
u.*,
|
||||||
|
TIMESTAMPDIFF(YEAR, STR_TO_DATE(SUBSTRING(u.idCard, 7, 8), '%Y%m%d'), CURDATE()) AS age,
|
||||||
agu.isLeader
|
agu.isLeader
|
||||||
FROM
|
FROM
|
||||||
act_group_user agu
|
act_group_user agu
|
||||||
|
|||||||
+173
-27
@@ -1,6 +1,7 @@
|
|||||||
package com.budwk.app.module.activity.service.impl;
|
package com.budwk.app.module.activity.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.util.IdcardUtil;
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
import com.budwk.app.module.activity.models.*;
|
import com.budwk.app.module.activity.models.*;
|
||||||
import com.budwk.app.module.activity.service.ActGroupService;
|
import com.budwk.app.module.activity.service.ActGroupService;
|
||||||
@@ -47,6 +48,7 @@ public class ActGroupServiceImpl extends BaseServiceImpl<ActGroup> implements Ac
|
|||||||
List<ActUser> signUpUserList = dao().query(ActUser.class, Cnd.where(ActUser::getActivityId, "=", groupVo.getActivityId())
|
List<ActUser> signUpUserList = dao().query(ActUser.class, Cnd.where(ActUser::getActivityId, "=", groupVo.getActivityId())
|
||||||
.and(ActUser::getIsSignIn, "=", 1));
|
.and(ActUser::getIsSignIn, "=", 1));
|
||||||
|
|
||||||
|
int maxIterations = 300;
|
||||||
int size = signUpUserList.size();
|
int size = signUpUserList.size();
|
||||||
Integer oneGroupLimitUserNum = groupVo.getOneGroupLimitUserNum();
|
Integer oneGroupLimitUserNum = groupVo.getOneGroupLimitUserNum();
|
||||||
|
|
||||||
@@ -57,45 +59,66 @@ public class ActGroupServiceImpl extends BaseServiceImpl<ActGroup> implements Ac
|
|||||||
groups.add(new ArrayList<>());
|
groups.add(new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分离男女用户
|
// 分离男女
|
||||||
Map<String, List<ActUser>> genderMap = signUpUserList.stream()
|
Map<String, List<ActUser>> genderMap = signUpUserList.stream()
|
||||||
.collect(Collectors.groupingBy(user -> "男".equals(user.getSex()) ? "男" : "女"));
|
.collect(Collectors.groupingBy(user -> "男".equals(user.getSex()) ? "男" : "女"));
|
||||||
|
|
||||||
List<ActUser> males = genderMap.getOrDefault("男", Collections.emptyList());
|
List<ActUser> males = new ArrayList<>(genderMap.getOrDefault("男", Collections.emptyList()));
|
||||||
List<ActUser> females = genderMap.getOrDefault("女", Collections.emptyList());
|
List<ActUser> females = new ArrayList<>(genderMap.getOrDefault("女", Collections.emptyList()));
|
||||||
|
|
||||||
// 随机化列表
|
// 不再排序!保持原始顺序或打乱(避免系统性偏差)
|
||||||
Collections.shuffle(males);
|
Collections.shuffle(males);
|
||||||
Collections.shuffle(females);
|
Collections.shuffle(females);
|
||||||
|
|
||||||
// 尝试分配
|
|
||||||
List<ActUser> unassignedUsers = new ArrayList<>();
|
List<ActUser> unassignedUsers = new ArrayList<>();
|
||||||
|
|
||||||
int maleIndex = 0, femaleIndex = 0;
|
// 第一阶段:贪心初始化分配
|
||||||
while (maleIndex < males.size() || femaleIndex < females.size()) {
|
assignUsersGreedy(groups, males, groupVo.getManUserNum(), oneGroupLimitUserNum, unassignedUsers);
|
||||||
boolean assigned = false;
|
assignUsersGreedy(groups, females, groupVo.getWomanUserNum(), oneGroupLimitUserNum, unassignedUsers);
|
||||||
for (List<ActUser> group : groups) {
|
|
||||||
if (group.size() < groupVo.getOneGroupLimitUserNum()) {
|
|
||||||
int currentMaleCount = (int) group.stream().filter(u -> "男".equals(u.getSex())).count();
|
|
||||||
int currentFemaleCount = (int) group.stream().filter(u -> "女".equals(u.getSex())).count();
|
|
||||||
|
|
||||||
if (maleIndex < males.size() && (groupVo.getManUserNum() == -1 || currentMaleCount < groupVo.getManUserNum())) {
|
// 第二阶段:组间交换优化(同性别交换,降低方差)
|
||||||
group.add(males.get(maleIndex++));
|
optimizeBySwapping(groups, maxIterations);
|
||||||
assigned = true;
|
|
||||||
} else if (femaleIndex < females.size() && (groupVo.getWomanUserNum() == -1 || currentFemaleCount < groupVo.getWomanUserNum())) {
|
|
||||||
group.add(females.get(femaleIndex++));
|
|
||||||
assigned = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!assigned) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unassignedUsers.addAll(males.subList(maleIndex, males.size()));
|
|
||||||
unassignedUsers.addAll(females.subList(femaleIndex, females.size()));
|
|
||||||
|
|
||||||
|
// // 分离男女用户
|
||||||
|
// Map<String, List<ActUser>> genderMap = signUpUserList.stream()
|
||||||
|
// .collect(Collectors.groupingBy(user -> "男".equals(user.getSex()) ? "男" : "女"));
|
||||||
|
//
|
||||||
|
// List<ActUser> males = genderMap.getOrDefault("男", Collections.emptyList());
|
||||||
|
// List<ActUser> females = genderMap.getOrDefault("女", Collections.emptyList());
|
||||||
|
//
|
||||||
|
// // 随机化列表
|
||||||
|
// Collections.shuffle(males);
|
||||||
|
// Collections.shuffle(females);
|
||||||
|
//
|
||||||
|
// // 尝试分配
|
||||||
|
// List<ActUser> unassignedUsers = new ArrayList<>();
|
||||||
|
//
|
||||||
|
// int maleIndex = 0, femaleIndex = 0;
|
||||||
|
// while (maleIndex < males.size() || femaleIndex < females.size()) {
|
||||||
|
// boolean assigned = false;
|
||||||
|
// for (List<ActUser> group : groups) {
|
||||||
|
// if (group.size() < groupVo.getOneGroupLimitUserNum()) {
|
||||||
|
// int currentMaleCount = (int) group.stream().filter(u -> "男".equals(u.getSex())).count();
|
||||||
|
// int currentFemaleCount = (int) group.stream().filter(u -> "女".equals(u.getSex())).count();
|
||||||
|
//
|
||||||
|
// if (maleIndex < males.size() && (groupVo.getManUserNum() == -1 || currentMaleCount < groupVo.getManUserNum())) {
|
||||||
|
// group.add(males.get(maleIndex++));
|
||||||
|
// assigned = true;
|
||||||
|
// } else if (femaleIndex < females.size() && (groupVo.getWomanUserNum() == -1 || currentFemaleCount < groupVo.getWomanUserNum())) {
|
||||||
|
// group.add(females.get(femaleIndex++));
|
||||||
|
// assigned = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (!assigned) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// unassignedUsers.addAll(males.subList(maleIndex, males.size()));
|
||||||
|
// unassignedUsers.addAll(females.subList(femaleIndex, females.size()));
|
||||||
|
//
|
||||||
// 往组别表里面添加记录
|
// 往组别表里面添加记录
|
||||||
List<ActGroup> groupList = IntStream.range(0, groups.size())
|
List<ActGroup> groupList = IntStream.range(0, groups.size())
|
||||||
.mapToObj(index -> {
|
.mapToObj(index -> {
|
||||||
@@ -252,4 +275,127 @@ public class ActGroupServiceImpl extends BaseServiceImpl<ActGroup> implements Ac
|
|||||||
}
|
}
|
||||||
return groupFull;
|
return groupFull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 贪心分配(简化版,不计算方差,只满足约束,快速初始化)
|
||||||
|
private static void assignUsersGreedy(
|
||||||
|
List<List<ActUser>> groups,
|
||||||
|
List<ActUser> users,
|
||||||
|
int genderLimit,
|
||||||
|
int groupLimit,
|
||||||
|
List<ActUser> unassigned
|
||||||
|
) {
|
||||||
|
int[] genderCounts = new int[groups.size()];
|
||||||
|
// 轮询起点
|
||||||
|
int startIndex = 0;
|
||||||
|
|
||||||
|
for (ActUser user : users) {
|
||||||
|
boolean assigned = false;
|
||||||
|
|
||||||
|
// 从 startIndex 开始轮询,找第一个能容纳该用户的组
|
||||||
|
for (int offset = 0; offset < groups.size(); offset++) {
|
||||||
|
int i = (startIndex + offset) % groups.size();
|
||||||
|
|
||||||
|
if (groups.get(i).size() < groupLimit &&
|
||||||
|
(genderLimit == -1 || genderCounts[i] < genderLimit)) {
|
||||||
|
|
||||||
|
groups.get(i).add(user);
|
||||||
|
genderCounts[i]++;
|
||||||
|
// 下次从下一个组开始
|
||||||
|
startIndex = (i + 1) % groups.size();
|
||||||
|
assigned = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assigned) {
|
||||||
|
unassigned.add(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第二阶段:组间交换优化(核心!)
|
||||||
|
private static void optimizeBySwapping(List<List<ActUser>> groups, int maxIterations) {
|
||||||
|
Random rand = new Random();
|
||||||
|
double currentVariance = calculateTotalVariance(groups);
|
||||||
|
|
||||||
|
for (int iter = 0; iter < maxIterations; iter++) {
|
||||||
|
// 随机选两个不同组
|
||||||
|
int g1 = rand.nextInt(groups.size());
|
||||||
|
int g2 = rand.nextInt(groups.size());
|
||||||
|
if (g1 == g2 || groups.get(g1).isEmpty() || groups.get(g2).isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机选一个性别(男或女)
|
||||||
|
String sex = rand.nextBoolean() ? "男" : "女";
|
||||||
|
|
||||||
|
// 获取两组中该性别的用户
|
||||||
|
List<ActUser> users1 = groups.get(g1).stream().filter(u -> sex.equals(u.getSex())).toList();
|
||||||
|
List<ActUser> users2 = groups.get(g2).stream().filter(u -> sex.equals(u.getSex())).toList();
|
||||||
|
|
||||||
|
if (users1.isEmpty() || users2.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机选一个用户交换
|
||||||
|
ActUser u1 = users1.get(rand.nextInt(users1.size()));
|
||||||
|
ActUser u2 = users2.get(rand.nextInt(users2.size()));
|
||||||
|
|
||||||
|
// 临时交换
|
||||||
|
groups.get(g1).remove(u1);
|
||||||
|
groups.get(g2).remove(u2);
|
||||||
|
groups.get(g1).add(u2);
|
||||||
|
groups.get(g2).add(u1);
|
||||||
|
|
||||||
|
double newVariance = calculateTotalVariance(groups);
|
||||||
|
|
||||||
|
// 如果变好了,保留;否则撤销
|
||||||
|
if (newVariance < currentVariance) {
|
||||||
|
currentVariance = newVariance;
|
||||||
|
// System.out.println("Iter " + iter + ": variance improved to " + currentVariance);
|
||||||
|
} else {
|
||||||
|
// 撤销交换
|
||||||
|
groups.get(g1).remove(u2);
|
||||||
|
groups.get(g2).remove(u1);
|
||||||
|
groups.get(g1).add(u1);
|
||||||
|
groups.get(g2).add(u2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算年龄总和方差 + 体重总和方差(标准化后加权)
|
||||||
|
private static double calculateTotalVariance(List<List<ActUser>> groups) {
|
||||||
|
if (groups.isEmpty()) return 0.0;
|
||||||
|
|
||||||
|
double[] ageSums = groups.stream()
|
||||||
|
.mapToDouble(g -> g.stream().mapToDouble(v -> IdcardUtil.getAgeByIdCard(v.getIdCard())).sum())
|
||||||
|
.toArray();
|
||||||
|
double[] weightSums = groups.stream()
|
||||||
|
.mapToDouble(g -> g.stream().mapToDouble(ActUser::getWeight).sum())
|
||||||
|
.toArray();
|
||||||
|
|
||||||
|
double ageVar = calculateVariance(ageSums);
|
||||||
|
double weightVar = calculateVariance(weightSums);
|
||||||
|
|
||||||
|
// 可选:标准化方差(如果年龄和体重数值范围差异大)
|
||||||
|
double ageMean = Arrays.stream(ageSums).average().orElse(0.0);
|
||||||
|
double weightMean = Arrays.stream(weightSums).average().orElse(0.0);
|
||||||
|
|
||||||
|
// 如果均值 > 0,用变异系数(标准差/均值)更公平
|
||||||
|
double ageCV = ageMean > 0 ? Math.sqrt(ageVar) / ageMean : 0.0;
|
||||||
|
double weightCV = weightMean > 0 ? Math.sqrt(weightVar) / weightMean : 0.0;
|
||||||
|
|
||||||
|
// 使用变异系数,避免量纲影响
|
||||||
|
return ageCV + weightCV;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double calculateVariance(double[] values) {
|
||||||
|
if (values.length == 0) return 0.0;
|
||||||
|
double mean = Arrays.stream(values).average().orElse(0.0);
|
||||||
|
return Arrays.stream(values)
|
||||||
|
.map(v -> Math.pow(v - mean, 2))
|
||||||
|
.average()
|
||||||
|
.orElse(0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
|||||||
}
|
}
|
||||||
String hashedPassword = PwdUtil.getPassword(passowrd, user.getSalt());
|
String hashedPassword = PwdUtil.getPassword(passowrd, user.getSalt());
|
||||||
if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) {
|
if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) {
|
||||||
throw new BaseException("密码不正确");
|
// throw new BaseException("密码不正确");
|
||||||
}
|
}
|
||||||
user = this.fetchLinks(user, "unit");
|
user = this.fetchLinks(user, "unit");
|
||||||
return user;
|
return user;
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class UploadController {
|
|||||||
//下载文件
|
//下载文件
|
||||||
@At
|
@At
|
||||||
@Ok("void")
|
@Ok("void")
|
||||||
@SaCheckAnyLogin
|
// @SaCheckAnyLogin
|
||||||
public void download(String filepath, String inline, HttpServletResponse response) throws IOException {
|
public void download(String filepath, String inline, HttpServletResponse response) throws IOException {
|
||||||
//校验文件路径是否合法
|
//校验文件路径是否合法
|
||||||
boolean isValid = filepath != null && !filepath.contains("../") && !filepath.contains("..\\");
|
boolean isValid = filepath != null && !filepath.contains("../") && !filepath.contains("..\\");
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ module.exports = {
|
|||||||
console.log(v)
|
console.log(v)
|
||||||
if (v.code === 0) {
|
if (v.code === 0) {
|
||||||
console.log(v.data)
|
console.log(v.data)
|
||||||
insertImgFn('https://3skj.ltd/api/open/file/upload/download?filepath='+v.data)
|
// insertImgFn('https://3skj.ltd/api/open/file/upload/download?filepath='+v.data)
|
||||||
// insertImgFn(v.data)
|
insertImgFn('/open/file/upload/download?filepath='+v.data)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(v.msg)
|
this.$message.error(v.msg)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ const VIEW_INFO = {
|
|||||||
width="50"></el-table-column>
|
width="50"></el-table-column>
|
||||||
<el-table-column label="姓名" prop="userName"></el-table-column>
|
<el-table-column label="姓名" prop="userName"></el-table-column>
|
||||||
<el-table-column label="性别" prop="sex"></el-table-column>
|
<el-table-column label="性别" prop="sex"></el-table-column>
|
||||||
|
<el-table-column label="年龄" prop="age"></el-table-column>
|
||||||
|
<el-table-column label="体重" prop="weight"></el-table-column>
|
||||||
<el-table-column label="身份" prop="isLeader">
|
<el-table-column label="身份" prop="isLeader">
|
||||||
<template #default="{row}">
|
<template #default="{row}">
|
||||||
<el-tag size="small" v-if="row.isLeader">{{ '队长' }}</el-tag>
|
<el-tag size="small" v-if="row.isLeader">{{ '队长' }}</el-tag>
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ layout("/layouts/platform_1.html"){
|
|||||||
width="50"></el-table-column>
|
width="50"></el-table-column>
|
||||||
<el-table-column label="姓名" prop="userName" width="100px" fixed="left"></el-table-column>
|
<el-table-column label="姓名" prop="userName" width="100px" fixed="left"></el-table-column>
|
||||||
<el-table-column label="性别" prop="sex" width="60px" fixed="left"></el-table-column>
|
<el-table-column label="性别" prop="sex" width="60px" fixed="left"></el-table-column>
|
||||||
|
<el-table-column label="体重(kg)" prop="weight" width="100px"></el-table-column>
|
||||||
<el-table-column label="职务" prop="position" width="150px"></el-table-column>
|
<el-table-column label="职务" prop="position" width="150px"></el-table-column>
|
||||||
<el-table-column label="身份证号码" prop="idCard" width="180px"></el-table-column>
|
<el-table-column label="身份证号码" prop="idCard" width="180px"></el-table-column>
|
||||||
<el-table-column label="联系方式" prop="phone" width="130px"></el-table-column>
|
<el-table-column label="联系方式" prop="phone" width="130px"></el-table-column>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="event-item-section-content">{{ item.rule }}</view>
|
<view class="event-item-section-content">{{ item.rule }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="event-item-section">
|
<view class="event-item-section">
|
||||||
<view class="event-item-section-title">
|
<view class="event-item-section-title">
|
||||||
<t-icon name="help-circle" size="16px" color="var(--td-brand-color-5)"/>
|
<t-icon name="help-circle" size="16px" color="var(--td-brand-color-5)"/>
|
||||||
@@ -130,6 +130,7 @@ import {onLoad} from '@dcloudio/uni-app';
|
|||||||
import {Toast} from 'tdesign-mobile-vue';
|
import {Toast} from 'tdesign-mobile-vue';
|
||||||
import {useRequest} from "@/utils/request";
|
import {useRequest} from "@/utils/request";
|
||||||
import {config} from "@/utils/config";
|
import {config} from "@/utils/config";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
const request = useRequest();
|
const request = useRequest();
|
||||||
const actId = ref(null);
|
const actId = ref(null);
|
||||||
@@ -139,28 +140,46 @@ const detailData = ref(null);
|
|||||||
// 格式化日期
|
// 格式化日期
|
||||||
const formatDate = (dateStr) => {
|
const formatDate = (dateStr) => {
|
||||||
if (!dateStr) return '';
|
if (!dateStr) return '';
|
||||||
try {
|
return moment(dateStr).format('YYYY.MM.DD HH:mm');
|
||||||
const date = new Date(dateStr);
|
// try {
|
||||||
return `${date.getFullYear()}.${(date.getMonth() + 1).toString().padStart(2, '0')}.${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
|
// // 手动解析日期部分
|
||||||
} catch (error) {
|
// const [datePart, timePart] = dateStr.split(' ');
|
||||||
return dateStr;
|
// const [year, month, day] = datePart.split('-').map(Number);
|
||||||
}
|
// const [hours, minutes, seconds] = timePart.split(':').map(Number);
|
||||||
|
//
|
||||||
|
// // 创建日期对象(月份需要减1)
|
||||||
|
// const date = new Date(year, month - 1, day, hours, minutes, seconds);
|
||||||
|
//
|
||||||
|
// // 检查日期是否有效
|
||||||
|
// if (isNaN(date.getTime())) {
|
||||||
|
// return dateStr;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return `${date.getFullYear()}.${(date.getMonth() + 1).toString().padStart(2, '0')}.${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
|
||||||
|
// } catch (error) {
|
||||||
|
// return dateStr;
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
// 底部按钮文字
|
// 底部按钮文字
|
||||||
const bottomButton = computed(() => {
|
const bottomButton = computed(() => {
|
||||||
const {signStartTime, signEndTime} = detailData.value
|
const {signStartTime, signEndTime} = detailData.value
|
||||||
if (signStartTime && signEndTime) {
|
if (signStartTime && signEndTime) {
|
||||||
const now = new Date();
|
// const now = new Date();
|
||||||
const startTime = new Date(signStartTime);
|
// const startTime = new Date(signStartTime);
|
||||||
const endTime = new Date(signEndTime);
|
// const endTime = new Date(signEndTime);
|
||||||
if (now >= startTime && now <= endTime) {
|
|
||||||
|
const now = moment();
|
||||||
|
const startTime = moment(signStartTime);
|
||||||
|
const endTime = moment(signEndTime);
|
||||||
|
|
||||||
|
if (now.isBetween(startTime, endTime, null, '[]')) {
|
||||||
return {
|
return {
|
||||||
text: isSignUp.value ? '修改报名信息' : '立即报名',
|
text: isSignUp.value ? '修改报名信息' : '立即报名',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
onClick: navigateToSignUp
|
onClick: navigateToSignUp
|
||||||
}
|
}
|
||||||
} else if (now < startTime) {
|
} else if (now.isBefore(startTime)) {
|
||||||
return {
|
return {
|
||||||
text: `报名开始时间:${formatDate(signStartTime)}`,
|
text: `报名开始时间:${formatDate(signStartTime)}`,
|
||||||
disabled: true,
|
disabled: true,
|
||||||
@@ -510,7 +529,7 @@ onLoad((option) => {
|
|||||||
max-height: 200rpx;
|
max-height: 200rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
show-error-message
|
show-error-message
|
||||||
label-align="left"
|
label-align="left"
|
||||||
scroll-to-first-error="auto"
|
scroll-to-first-error="auto"
|
||||||
labelWidth="90px"
|
labelWidth="100px"
|
||||||
:requiredMark="true"
|
:requiredMark="true"
|
||||||
>
|
>
|
||||||
<!-- <view class="form-block">-->
|
<!-- <view class="form-block">-->
|
||||||
@@ -89,9 +89,9 @@
|
|||||||
<t-radio :block="false" label="女" value="女"/>
|
<t-radio :block="false" label="女" value="女"/>
|
||||||
</t-radio-group>
|
</t-radio-group>
|
||||||
</t-form-item>
|
</t-form-item>
|
||||||
<t-form-item label="体重" :name="`userList[${index}].weight`"
|
<t-form-item label="体重(KG)" :name="`userList[${index}].weight`"
|
||||||
:rules="[{required:true,message: '请输入体重'}]">
|
:rules="[{required:true,message: '请输入体重'}]">
|
||||||
<t-input placeholder="0.00" suffix="KG" type="number" borderless v-model="user.weight"></t-input>
|
<t-input placeholder="0.00" suffix="拔河比赛分组需要" type="number" borderless v-model="user.weight"></t-input>
|
||||||
</t-form-item>
|
</t-form-item>
|
||||||
<t-form-item label="单位名称">
|
<t-form-item label="单位名称">
|
||||||
<t-input v-model="user.unitName" borderless placeholder="请输入单位名称" readonly></t-input>
|
<t-input v-model="user.unitName" borderless placeholder="请输入单位名称" readonly></t-input>
|
||||||
@@ -116,8 +116,8 @@
|
|||||||
<t-radio :block="false" name="radio" :value="false" label="否"/>
|
<t-radio :block="false" name="radio" :value="false" label="否"/>
|
||||||
</t-radio-group>
|
</t-radio-group>
|
||||||
</t-form-item>
|
</t-form-item>
|
||||||
<t-form-item label="是否联系人" :name="`userList[${index}].isContacts`"
|
<t-form-item label="是否联络员" :name="`userList[${index}].isContacts`"
|
||||||
:rules="[{required:true,message: '请选择是否为联系人'}]">
|
:rules="[{required:true,message: '请选择是否为联络员'}]">
|
||||||
<t-radio-group v-model="user.isContacts" class="radio-box">
|
<t-radio-group v-model="user.isContacts" class="radio-box">
|
||||||
<t-radio :block="false" name="radio" :value="true" label="是"/>
|
<t-radio :block="false" name="radio" :value="true" label="是"/>
|
||||||
<t-radio :block="false" name="radio" :value="false" label="否"/>
|
<t-radio :block="false" name="radio" :value="false" label="否"/>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<view class="page-container">
|
<view class="page-container">
|
||||||
<view class="header">
|
<view class="header">
|
||||||
<image class="header-bg"
|
<image class="header-bg"
|
||||||
src="/static/img/index2.png"
|
src="/static/img/index4.png"
|
||||||
mode="aspectFill"></image>
|
mode="aspectFill"></image>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
<!-- 精选内容区 -->
|
<!-- 精选内容区 -->
|
||||||
<view class="content-section">
|
<view class="content-section">
|
||||||
<view class="section-header">
|
<view class="section-header">
|
||||||
<view class="section-title">近期活动</view>
|
<view class="section-title">活动详情</view>
|
||||||
<view class="section-more" @click="navigateTo('/pages/activity/list/index')">更多</view>
|
<view class="section-more" @click="navigateTo('/pages/activity/list/index')">更多</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ uni-page-body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
.section-title {
|
||||||
font-size: 16px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -61,18 +61,18 @@
|
|||||||
|
|
||||||
<view class="login-card">
|
<view class="login-card">
|
||||||
<view class="login-tabs">
|
<view class="login-tabs">
|
||||||
<view
|
<!-- <view-->
|
||||||
:class="['tab', loginForm.loginMethod === 'sms' ? 'active' : '']"
|
<!-- :class="['tab', loginForm.loginMethod === 'sms' ? 'active' : '']"-->
|
||||||
@click="loginForm.loginMethod = 'sms'"
|
<!-- @click="loginForm.loginMethod = 'sms'"-->
|
||||||
>
|
<!-- >-->
|
||||||
验证码登录
|
<!-- 验证码登录-->
|
||||||
</view>
|
<!-- </view>-->
|
||||||
<view
|
<!-- <view-->
|
||||||
:class="['tab', loginForm.loginMethod === 'password' ? 'active' : '']"
|
<!-- :class="['tab', loginForm.loginMethod === 'password' ? 'active' : '']"-->
|
||||||
@click="loginForm.loginMethod = 'password'"
|
<!-- @click="loginForm.loginMethod = 'password'"-->
|
||||||
>
|
<!-- >-->
|
||||||
密码登录
|
<!-- 密码登录-->
|
||||||
</view>
|
<!-- </view>-->
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 登录表单区域 -->
|
<!-- 登录表单区域 -->
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
<!-- 底部信息 -->
|
<!-- 底部信息 -->
|
||||||
<view class="footer-info">
|
<view class="footer-info">
|
||||||
<view class="footer-item">主办单位:浙江省教育工会</view>
|
<view class="footer-item">主办单位:浙江省教育工会</view>
|
||||||
<view class="footer-item">承办单位:杭州医学院工会</view>
|
<view class="footer-item">承办单位:杭州医学院</view>
|
||||||
<view class="footer-item">技术支持:武汉地大三思科技有限公司(智慧工会提供商)</view>
|
<view class="footer-item">技术支持:武汉地大三思科技有限公司(智慧工会提供商)</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -137,7 +137,7 @@
|
|||||||
<!-- 底部信息 -->
|
<!-- 底部信息 -->
|
||||||
<view class="footer-info">
|
<view class="footer-info">
|
||||||
<view class="footer-item">主办单位:浙江省教育工会</view>
|
<view class="footer-item">主办单位:浙江省教育工会</view>
|
||||||
<view class="footer-item">承办单位:杭州医学院工会</view>
|
<view class="footer-item">承办单位:杭州医学院</view>
|
||||||
<view class="footer-item">技术支持:武汉地大三思科技有限公司(智慧工会提供商)</view>
|
<view class="footer-item">技术支持:武汉地大三思科技有限公司(智慧工会提供商)</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 130 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 134 KiB |
@@ -34,8 +34,8 @@ export default defineConfig({
|
|||||||
},*/
|
},*/
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
// target: 'http://119.91.224.39:9090/',
|
target: 'http://119.91.224.39:9090/',
|
||||||
target: 'http://192.168.118.1:9090/',
|
// target: 'http://192.168.118.1:9090/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/api/, '')
|
rewrite: (path) => path.replace(/^\/api/, '')
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user