This commit is contained in:
那些花儿
2025-09-19 14:45:06 +08:00
13 changed files with 229 additions and 119 deletions
@@ -118,7 +118,12 @@ public class ClientGroupController {
@At("/apply-leader/?") @At("/apply-leader/?")
@AdaptBy(type = JsonAdaptor.class) @AdaptBy(type = JsonAdaptor.class)
@SaCheckLogin(type = StpClientUtil.TYPE) @SaCheckLogin(type = StpClientUtil.TYPE)
public Result applyLeader(Long groupId) { public synchronized Result applyLeader(Long groupId) {
int count = clientActivityService.dao().count(ActGroupUser.class, Cnd.where(ActGroupUser::getGroupId, "=", groupId)
.and(ActGroupUser::getIsLeader, "=", 1));
if (count > 0){
return Result.error("该团队已有队长!");
}
clientActivityService.dao().update(ActGroupUser.class, clientActivityService.dao().update(ActGroupUser.class,
Chain.make("isLeader", true), Chain.make("isLeader", true),
Cnd.where(ActGroupUser::getGroupId, "=", groupId) Cnd.where(ActGroupUser::getGroupId, "=", groupId)
@@ -126,6 +131,17 @@ public class ClientGroupController {
return Result.success(); return Result.success();
} }
@At("/cancel-leader/?")
@AdaptBy(type = JsonAdaptor.class)
@SaCheckLogin(type = StpClientUtil.TYPE)
public synchronized Result cancelLeader(Long groupId) {
clientActivityService.dao().update(ActGroupUser.class,
Chain.make("isLeader", false),
Cnd.where(ActGroupUser::getGroupId, "=", groupId)
.and(ActGroupUser::getUserId, "=", StpClientUtil.STP.getLoginIdAsLong()));
return Result.success();
}
@At("/list-team/?") @At("/list-team/?")
@SaCheckLogin(type = StpClientUtil.TYPE) @SaCheckLogin(type = StpClientUtil.TYPE)
public Result listTeam(Long activityId) { public Result listTeam(Long activityId) {
@@ -167,6 +167,7 @@ public class ActScoreEnterController {
List<NutMap> listMap = activityService.listMap(sql); List<NutMap> listMap = activityService.listMap(sql);
List<ActivityItem> itemList = activityService.dao().query(ActivityItem.class, Cnd.where(ActivityItem::getActivityId, "=", activityId).asc(ActivityItem::getSort)); List<ActivityItem> itemList = activityService.dao().query(ActivityItem.class, Cnd.where(ActivityItem::getActivityId, "=", activityId).asc(ActivityItem::getSort));
itemList.forEach(item -> { itemList.forEach(item -> {
item.setCjName("成绩");
item.setScoreName("得分"); item.setScoreName("得分");
item.setRankingName("名次"); item.setRankingName("名次");
}); });
@@ -181,10 +182,12 @@ public class ActScoreEnterController {
Map<String, Object> itemListMap = new HashMap<>(); Map<String, Object> itemListMap = new HashMap<>();
itemList.forEach(item -> { itemList.forEach(item -> {
itemListMap.put("name",item.getName()); itemListMap.put("name",item.getName());
itemListMap.put("scoreName","成绩"); itemListMap.put("cjName","成绩");
itemListMap.put("rankingName","名次"); itemListMap.put("rankingName","名次");
itemListMap.put("scoreVal","t." + item.getName() + ".score"); itemListMap.put("scoreName","积分");
itemListMap.put("cjVal","t." + item.getName() + ".cj");
itemListMap.put("rankingVal","t." + item.getName() + ".ranking"); itemListMap.put("rankingVal","t." + item.getName() + ".ranking");
itemListMap.put("scoreVal","t." + item.getName() + ".score");
itemLists.add(itemListMap); itemLists.add(itemListMap);
}); });
for (int j = 0; j < listMap.size(); j++) { for (int j = 0; j < listMap.size(); j++) {
@@ -198,8 +201,9 @@ public class ActScoreEnterController {
ActItemGroupScore itemGroupScore = scoreList.stream().filter(score -> ActItemGroupScore itemGroupScore = scoreList.stream().filter(score ->
score.getGroupId().equals(group.getLong("id")) score.getGroupId().equals(group.getLong("id"))
&& score.getItemId().equals(item.getId())).findFirst().orElse(null); && score.getItemId().equals(item.getId())).findFirst().orElse(null);
group.put("score", itemGroupScore.getScore()); group.put("cj", itemGroupScore.getCj());
group.put("ranking", itemGroupScore.getRanking()); group.put("ranking", itemGroupScore.getRanking());
group.put("score", itemGroupScore.getScore());
} }
} }
} }
@@ -95,15 +95,21 @@ public class ActScoreEntryController {
@At("/save-score") @At("/save-score")
@SaCheckPermission("activity.group") @SaCheckPermission("activity.group")
@ApiOperation(value = "保存成绩", nickname = "/save-score", httpMethod = "POST") @ApiOperation(value = "保存成绩", nickname = "/save-score", httpMethod = "POST")
public Result saveScore(@Param("scores") ActItemGroupScore[] actItemGroupScore) { public Result saveScore(@Param("scores") ActItemGroupScore[] actItemGroupScore, @Param("activityId") String activityId) {
// 更新分数和名次 // 更新分数和名次
dao.updateIgnoreNull(actItemGroupScore); dao.updateIgnoreNull(actItemGroupScore);
// 更新总得分 //查询这个活动所有成绩
// ActGroup actGroup = dao.fetch(ActGroup.class, actItemGroupScore.getGroupId()); List<ActItemGroupScore> scoreList = dao.query(ActItemGroupScore.class, Cnd.where(ActItemGroupScore::getActivityId, "=", activityId));
// BigDecimal newTotalScore = actGroup.getTotalScore().add(actItemGroupScore.getScore()); for (ActItemGroupScore score : actItemGroupScore) {
// actGroup.setTotalScore(newTotalScore); Long groupId = score.getGroupId();
// dao.update(actGroup); //在找出这个队伍下面所有的分数
List<ActItemGroupScore> groupScoreList = scoreList.stream().filter(itemScore -> itemScore.getGroupId().equals(groupId)).toList();
BigDecimal totalScore = groupScoreList.stream()
.map(ActItemGroupScore::getScore) // 提取每个 score(BigDecimal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
dao.update(ActGroup.class, Chain.make("totalScore", totalScore), Cnd.where(ActGroup::getId, "=", groupId));
}
return Result.success(); return Result.success();
} }
@@ -47,4 +47,9 @@ public class ActItemGroupScore extends BaseModel {
@Comment("队伍排名") @Comment("队伍排名")
@ColDefine(type = ColType.VARCHAR, width = 50) @ColDefine(type = ColType.VARCHAR, width = 50)
private String ranking; private String ranking;
@Column
@Comment("成绩")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String cj;
} }
@@ -27,4 +27,5 @@ public class ActRankScore extends BaseModel {
@ColDefine(customType = "decimal", width = 10, precision = 2) @ColDefine(customType = "decimal", width = 10, precision = 2)
private BigDecimal score; private BigDecimal score;
} }
@@ -166,4 +166,9 @@ public class ActUser extends BaseModel {
@Default("0") @Default("0")
private Boolean isParty; private Boolean isParty;
@Column
@Comment("体重KG")
@ColDefine(type = ColType.DOUBLE)
private Double weight;
} }
@@ -60,6 +60,7 @@ public class ActivityItem extends BaseModel {
@Column @Column
@ColDefine(type = ColType.INT) @ColDefine(type = ColType.INT)
private Integer sort; private Integer sort;
private String cjName;
private String scoreName; private String scoreName;
private String rankingName; private String rankingName;
private String scoreVal; private String scoreVal;
Binary file not shown.
@@ -42,25 +42,30 @@ layout("/layouts/platform_1.html"){
<el-button type="primary" size="small" @click="openBigScreen">打开成绩大屏</el-button> <el-button type="primary" size="small" @click="openBigScreen">打开成绩大屏</el-button>
<el-button type="primary" size="small" @click="doExport">导出</el-button> <el-button type="primary" size="small" @click="doExport">导出</el-button>
</el-row> </el-row>
<el-table v-loading="tableLoading" show-overflow-tooltip :data="tableData" @cell-click="cellClick"> <el-table v-loading="tableLoading" show-overflow-tooltip :data="tableData" @cell-click="cellClick"
style="width: 100%">
<el-table-column label="队伍" prop="groupName" fixed="left" width="100px"></el-table-column> <el-table-column label="队伍" prop="groupName" fixed="left" width="100px"></el-table-column>
<el-table-column v-for="item in itemOptions" :key="item.id" :label="item.name" show-overflow-tooltip <el-table-column v-for="item in itemOptions" :key="item.id" :label="item.name">
width="10%">
<template slot="header" slot-scope="scope"> <template slot="header" slot-scope="scope">
<span v-html="formatName(item.name)"></span> <span v-html="formatName(item.name)"></span>
</template> </template>
<el-table-column label="成绩" :prop="item.id+item.name" min-width="50px"> <el-table-column label="成绩" :prop="item.id+item.name" min-width="50px" v-if="item.id!=='all'"
sortable>
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row[item.id]['totalScore']}} {{scope.row[item.id]['totalCj']}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="名次" :prop="item.id+item.name" min-width="50px" v-if="item.id!=='all'"> <el-table-column label="名次" :prop="item.id+item.name" min-width="50px" v-if="item.id!=='all'">
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row[item.id]['totalRank']}} {{scope.row[item.id]['totalRank']}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="积分" :prop="item.id+item.name" min-width="50px" sortable>
<template slot-scope="scope">
{{scope.row[item.id]['totalScore']}}
</template>
</el-table-column>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- <el-row type="flex" justify="end" class="mt-3"> <!-- <el-row type="flex" justify="end" class="mt-3">
@@ -96,7 +101,8 @@ layout("/layouts/platform_1.html"){
// 格式化名称 // 格式化名称
formatName(name) { formatName(name) {
if (!name) return "" if (!name) return ""
return name.match(/.{1,4}/g)?.join("<br>") || "" // return name.match(/.{1,4}/g)?.join("<br>") || ""
return name
}, },
// 获取活动 // 获取活动
listAct() { listAct() {
@@ -183,7 +189,8 @@ layout("/layouts/platform_1.html"){
row[item.id] = { row[item.id] = {
id: data.id, id: data.id,
totalScore: data.score ? data.score : null, totalScore: data.score ? data.score : null,
totalRank: data.ranking ? data.ranking : null totalRank: data.ranking ? data.ranking : null,
totalCj: data.cj ? data.cj : null
} }
} else { } else {
row[item.id] = { row[item.id] = {
@@ -92,6 +92,15 @@ layout("/layouts/platform_1.html"){
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="成绩" width="250">
<template slot-scope="scope">
<el-input
v-model="getScoreRecord(item.id, scope.row.id).cj"
placeholder="请输入成绩"
class="remark-input">
</el-input>
</template>
</el-table-column>
<el-table-column label="名次设置" width="220"> <el-table-column label="名次设置" width="220">
<template slot-scope="scope"> <template slot-scope="scope">
<el-select <el-select
@@ -108,7 +117,7 @@ layout("/layouts/platform_1.html"){
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="得分"> <el-table-column label="积分">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="score-value" <div class="score-value"
:class="{'has-score': getScoreRecord(item.id, scope.row.id).score}"> :class="{'has-score': getScoreRecord(item.id, scope.row.id).score}">
@@ -273,11 +282,13 @@ layout("/layouts/platform_1.html"){
itemId: score.itemId, itemId: score.itemId,
groupId: score.groupId, groupId: score.groupId,
score: score.score, score: score.score,
cj: score.cj,
ranking: score.ranking ranking: score.ranking
})) }))
const { code, msg } = await $.post("/platform/activity/scoreEntry/save-score", { const { code, msg } = await $.post("/platform/activity/scoreEntry/save-score", {
scores: JSON.stringify(postData) scores: JSON.stringify(postData),
activityId: this.pageForm.activityId
}) })
if (code === 0) { if (code === 0) {
@@ -64,7 +64,6 @@
<!-- </view>--> <!-- </view>-->
<view class="form-block"> <view class="form-block">
<view class="form-block-title"> <view class="form-block-title">
<t-icon name="usergroup"></t-icon> <t-icon name="usergroup"></t-icon>
@@ -78,7 +77,8 @@
</view> </view>
<!-- 所有人员的表单,使用v-show控制显示 --> <!-- 所有人员的表单,使用v-show控制显示 -->
<view v-for="(user, index) in formData.userList" :key="index" class="form-fields-container" v-show="activeTabIndex === index"> <view v-for="(user, index) in formData.userList" :key="index" class="form-fields-container"
v-show="activeTabIndex === index">
<t-form-item label="姓名" :name="`userList[${index}].userName`" <t-form-item label="姓名" :name="`userList[${index}].userName`"
:rules="[{required:true,message: '请输入姓名'}]"> :rules="[{required:true,message: '请输入姓名'}]">
<t-input v-model="user.userName" borderless placeholder="请输入内容"></t-input> <t-input v-model="user.userName" borderless placeholder="请输入内容"></t-input>
@@ -89,6 +89,10 @@
<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`"
:rules="[{required:true,message: '请输入体重'}]">
<t-input placeholder="0.00" suffix="KG" type="number" borderless v-model="user.weight"></t-input>
</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>
</t-form-item> </t-form-item>
@@ -119,25 +123,29 @@
<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}].traffic`" :rules="[{required:true,message: '请选择交通方式'}]"> <t-form-item label="交通方式" :name="`userList[${index}].traffic`"
:rules="[{required:true,message: '请选择交通方式'}]">
<t-radio-group v-model="user.traffic" class="radio-box"> <t-radio-group v-model="user.traffic" class="radio-box">
<t-radio :block="false" name="radio" :value="'自驾'" label="自驾"/> <t-radio :block="false" name="radio" :value="'自驾'" label="自驾"/>
<t-radio :block="false" name="radio" :value="'公共交通'" label="公共交通"/> <t-radio :block="false" name="radio" :value="'公共交通'" label="公共交通"/>
</t-radio-group> </t-radio-group>
</t-form-item> </t-form-item>
<t-form-item v-if="user.traffic === '自驾'" label="车牌号" :name="`userList[${index}].carNo`" :rules="[{required:true,message: '请输入车牌号'}]"> <t-form-item v-if="user.traffic === '自驾'" label="车牌号" :name="`userList[${index}].carNo`"
:rules="[{required:true,message: '请输入车牌号'}]">
<t-input v-model="user.carNo" borderless placeholder="请输入车牌号"></t-input> <t-input v-model="user.carNo" borderless placeholder="请输入车牌号"></t-input>
</t-form-item> </t-form-item>
<t-form-item v-if="user.traffic === '公共交通'" label="是否接站" :name="`userList[${index}].isStation`" :rules="[{required:true,message: '请选择是否接站'}]"> <t-form-item v-if="user.traffic === '公共交通'" label="是否接站" :name="`userList[${index}].isStation`"
:rules="[{required:true,message: '请选择是否接站'}]">
<t-radio-group v-model="user.isStation" class="radio-box"> <t-radio-group v-model="user.isStation" 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="否"/>
</t-radio-group> </t-radio-group>
</t-form-item> </t-form-item>
<t-form-item v-if="user.isStation" label="接站地址" :name="`userList[${index}].stationAddress`" :rules="[{required:true,message: '请输入接站地址'}]"> <t-form-item v-if="user.isStation" label="接站地址" :name="`userList[${index}].stationAddress`"
:rules="[{required:true,message: '请输入接站地址'}]">
<t-input v-model="user.stationAddress" borderless placeholder="请输入接站地址" maxlength="50"></t-input> <t-input v-model="user.stationAddress" borderless placeholder="请输入接站地址" maxlength="50"></t-input>
</t-form-item> </t-form-item>
@@ -156,7 +164,8 @@
<!-- <t-input v-model="user.equip" borderless placeholder="请填写才艺所需器材"></t-input>--> <!-- <t-input v-model="user.equip" borderless placeholder="请填写才艺所需器材"></t-input>-->
<!-- </t-form-item>--> <!-- </t-form-item>-->
<!-- </template>--> <!-- </template>-->
<t-form-item label="参加茶叙会" :name="`userList[${index}].isParty`" :rules="[{required:true,message: '请选择是否参加茶叙会'}]"> <t-form-item label="参加茶叙会" :name="`userList[${index}].isParty`"
:rules="[{required:true,message: '请选择是否参加茶叙会'}]">
<t-radio-group v-model="user.isParty" class="radio-box"> <t-radio-group v-model="user.isParty" 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="否"/>
@@ -208,7 +217,8 @@
</view> </view>
<view class="agreement-popup-footer"> <view class="agreement-popup-footer">
<t-button variant="outline" block @click="closeAgreementPopup" class="agreement-btn">取消</t-button> <t-button variant="outline" block @click="closeAgreementPopup" class="agreement-btn">取消</t-button>
<t-button theme="primary" block :disabled="!canConfirmAgreement" @click="confirmAgreement" class="agreement-btn"> <t-button theme="primary" block :disabled="!canConfirmAgreement" @click="confirmAgreement"
class="agreement-btn">
{{ canConfirmAgreement ? '确定并报名' : `请阅读(${agreementCountdown}秒)` }} {{ canConfirmAgreement ? '确定并报名' : `请阅读(${agreementCountdown}秒)` }}
</t-button> </t-button>
</view> </view>
@@ -225,7 +235,9 @@
<text class="notice-popup-title">重要提醒</text> <text class="notice-popup-title">重要提醒</text>
</view> </view>
<view class="notice-popup-content"> <view class="notice-popup-content">
<text class="notice-popup-text">请务必准确填写手机号码和身份证号码,信息有误将导致现场签到失败,影响您的正常使用。</text> <text class="notice-popup-text">
请务必准确填写手机号码和身份证号码,信息有误将导致现场签到失败,影响您的正常使用。
</text>
</view> </view>
<view class="notice-popup-footer"> <view class="notice-popup-footer">
<t-button theme="primary" block @click="closeNoticePopup" class="notice-btn"> <t-button theme="primary" block @click="closeNoticePopup" class="notice-btn">
@@ -905,8 +917,12 @@ function closeNoticePopup() {
} }
@keyframes fadeIn { @keyframes fadeIn {
from { opacity: 0.6; } from {
to { opacity: 1; } opacity: 0.6;
}
to {
opacity: 1;
}
} }
.user-actions { .user-actions {
@@ -47,7 +47,7 @@
<view v-else style="flex: 1;display: flex;justify-content: center;align-items: center"> <view v-else style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty <t-empty
image="/static/img/empty.png" image="/static/img/empty.png"
description="活动还没有自由组队,组队后方项目报名!" description="活动还没有自由组队,组队后方可项目报名!"
style="flex: 1"> style="flex: 1">
</t-empty> </t-empty>
</view> </view>
+49 -11
View File
@@ -80,19 +80,29 @@
<!-- 当前角色与申请队长 --> <!-- 当前角色与申请队长 -->
<div class="role-section"> <div class="role-section">
<div class="role-card" v-if="team.isSelfLeader"> <div v-if="team.isSelfLeader">
<div class="role-card">
<div class="role-icon"> <div class="role-icon">
<i class="bi bi-trophy"></i> <t-icon name="user-safety"></t-icon>
</div> </div>
<div class="role-info"> <div class="role-info">
<div class="role-title">您是队长</div> <div class="role-title">您是队长</div>
<div class="role-desc">拥有团队所有管理权限</div> <div class="role-desc">拥有团队所有管理权限</div>
</div> </div>
</div>
<t-button block
class="leader-apply-btn"
theme="danger"
variant="outline"
@click="cancelLeader">
取消成为队长
</t-button>
</div> </div>
<div v-if="team.teamIsLeader&&!team.isSelfLeader"> <div v-if="team.teamIsLeader&&!team.isSelfLeader">
<div class="role-card"> <div class="role-card">
<div class="role-icon"> <div class="role-icon">
<i class="bi bi-person"></i> <t-icon name="face-retouching"></t-icon>
</div> </div>
<div class="role-info"> <div class="role-info">
<div class="role-title">您是普通成员</div> <div class="role-title">您是普通成员</div>
@@ -104,7 +114,7 @@
<div v-if="!team.teamIsLeader&&!team.isSelfLeader"> <div v-if="!team.teamIsLeader&&!team.isSelfLeader">
<div class="role-card"> <div class="role-card">
<div class="role-icon"> <div class="role-icon">
<i class="bi bi-person"></i> <t-icon name="face-retouching"></t-icon>
</div> </div>
<div class="role-info"> <div class="role-info">
<div class="role-title">您是普通成员</div> <div class="role-title">您是普通成员</div>
@@ -125,7 +135,7 @@
</view> </view>
<view v-else style="flex: 1;display: flex;justify-content: center;align-items: center"> <view v-else style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty image="/static/img/empty.png" <t-empty image="/static/img/empty.png"
description="活动还没未开始,请耐心等待!" description="活动还未开始,请耐心等待!"
style="flex: 1"> style="flex: 1">
</t-empty> </t-empty>
</view> </view>
@@ -214,6 +224,35 @@ const actChange = (val) => {
getListAct() getListAct()
} }
// 取消成为队长
const cancelLeader = async () => {
// 弹出确认框
Dialog.confirm({
title: '温馨提示',
content: '确定要取消队长身份吗?',
confirmBtn: '确认取消',
cancelBtn: '再想想',
onConfirm: async () => {
try {
const {code, msg} = await useRequest().post('/client/group/cancel-leader/' + team.value.id);
if (code === 0) {
await getTeamInfo();
Toast({message: '取消成功', theme: 'success'});
} else {
await getTeamInfo();
Toast({message: msg, theme: 'error'});
}
} catch (e) {
Toast({message: e.message || '操作失败', theme: 'error'});
}
},
onCancel: () => {
// 用户取消,可选提示或什么都不做
// Toast({ message: '已取消操作', theme: 'warning' });
},
});
};
// 申请成为队长 // 申请成为队长
const onLeaderConfirm = async () => { const onLeaderConfirm = async () => {
try { try {
@@ -224,6 +263,7 @@ const onLeaderConfirm = async () => {
Toast({message: '申请成功', theme: 'success'}); Toast({message: '申请成功', theme: 'success'});
leaderConfirmVisible.value = false leaderConfirmVisible.value = false
} else { } else {
await getTeamInfo();
Toast({message: msg, theme: 'error'}); Toast({message: msg, theme: 'error'});
} }
} catch (e) { } catch (e) {
@@ -618,18 +658,16 @@ onLoad(() => {
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 20px; border-radius: 20px;
background: linear-gradient(120deg, #ff5f5c, #ff8c8a); //background: linear-gradient(120deg, #ff5f5c, #ff8c8a);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-right: 12px; margin-right: 12px;
box-shadow: 0 4px 12px rgba(255, 95, 92, 0.2); //box-shadow: 0 4px 12px rgba(255, 95, 92, 0.2);
color: #ff5f5c;
font-size: 22px;
} }
.role-icon i {
font-size: 20px;
color: white;
}
.role-info { .role-info {
flex: 1; flex: 1;