Commit bad29cb9 authored by daniel's avatar daniel

feat(markNoSelect): 自助选号

parent acc3ba60
...@@ -19,4 +19,6 @@ public class SettingTemplate { ...@@ -19,4 +19,6 @@ public class SettingTemplate {
private int seq; private int seq;
private int needTime;
} }
...@@ -265,8 +265,8 @@ ...@@ -265,8 +265,8 @@
</update> </update>
<insert id="initCmptSettings"> <insert id="initCmptSettings">
insert into gk_cmptsetting (id,cmptid,name,name_web, type,visibility,status,style,seq,create_date) insert into gk_cmptsetting (id,cmptid,name,name_web, type,visibility,status,style,seq,create_date,need_time)
select MD5(UUID()),#{cmptId},name,name, type,visibility,status,style,seq,now() from gk_cmptsetting_template select MD5(UUID()),#{cmptId},name,name, type,visibility,status,style,seq,now(),need_time from gk_cmptsetting_template
</insert> </insert>
<select id="getCommonEnrollCmptId" resultType="java.lang.Integer"> <select id="getCommonEnrollCmptId" resultType="java.lang.Integer">
......
package com.dlbridge.jadp.plugins.cmpt.web;
import com.dlbridge.jadp.common.interceptor.PageView;
import com.dlbridge.jadp.plugins.cmpt.dao.model.Cmpt;
import com.dlbridge.jadp.plugins.cmpt.service.CmptService;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
@RequestMapping(value = "/gk/markNoSelect/")
@RestController
@ApiIgnore
@Log4j2
public class MarkNoSelectController {
@Resource
private CmptService cmptService;
@RequestMapping("index/{cmptId}")
@PageView
public ModelAndView index(@PathVariable("cmptId") Integer cmptId, ModelAndView mv) {
Cmpt cmpt = cmptService.queryCmptBycmptId(cmptId);
mv.setViewName("cmpt/markNoSelect");
mv.addObject("cmpt", cmpt);
return mv;
}
}
...@@ -245,7 +245,8 @@ ...@@ -245,7 +245,8 @@
<div class="sort" id="sortable" style="clear: both;"> <div class="sort" id="sortable" style="clear: both;">
<div class="tip"> <div class="tip">
<span class="tip-one">注</span> <span class="tip-one">注</span>
<span class="tip-txt">下列功能可通过拖拽进行排序,直接影响本赛事小程序的功能列表顺序</span> <span
class="tip-txt">下列功能可通过拖拽进行排序,直接影响本赛事小程序的功能列表顺序,对于可设时间的模块双击即可设置</span>
</div> </div>
<c:forEach var="func" items="${funcs}"> <c:forEach var="func" items="${funcs}">
<div class="wzm-content-item ${func.style}" data-id="${func.id}"> <div class="wzm-content-item ${func.style}" data-id="${func.id}">
...@@ -263,11 +264,14 @@ ...@@ -263,11 +264,14 @@
</div> </div>
</div> </div>
<div data-status="${func.status}" <div data-status="${func.status}"
class="public ${func.status == 2 ? 'disabled':''} ${func.type == 11 ? 'disabled':''}"> class="public ${func.status == 2 ? 'disabled':''} ${func.type == 11 ? 'disabled':''}"
style="width:auto;">
<input class="check-box" type="checkbox" ${func.status==1 <input class="check-box" type="checkbox" ${func.status==1
? 'checked' :func.status==2?'disabled':''} ? 'checked' :func.status==2?'disabled':''}
${func.type==11 ? 'disabled' :''}> ${func.type==11 ? 'disabled' :''}>
<span class="public-text">公开</span> <span class="public-text">公开${func.needTime == 1 ?
'-可设时间':''}</span>
</div> </div>
<div class="b"> <div class="b">
<div class="radio ${func.visibility == 1 ? 'checked':'unchecked'} status" <div class="radio ${func.visibility == 1 ? 'checked':'unchecked'} status"
...@@ -300,7 +304,7 @@ ...@@ -300,7 +304,7 @@
<script type="text/javascript"> <script type="text/javascript">
// 将Java对象转换为JSON字符串 // 将Java对象转换为JSON字符串
let cmptFuncs = JSON.parse('${fns:toJson(funcs)}'); let cmptFuncs = JSON.parse('${fns:toJson(funcs)}');
// console.log({ cmptFuncs }) console.log({ cmptFuncs })
</script> </script>
</html> </html>
\ No newline at end of file
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!doctype html>
<html>
<head>
<title>自助选号</title>
<!-- Bootstrap CSS-->
<link rel="stylesheet" href="${ctxStatic}/newdermon/vendor/bootstrap/css/bootstrap.min.css">
<!-- Font Awesome CSS-->
<link rel="stylesheet"
href="${ctxStatic}/newdermon/vendor/font-awesome/css/font-awesome.min.css">
<!-- Fontastic Custom icon font-->
<link rel="stylesheet" href="${ctxStatic}/newdermon/css/fontastic.css">
<!-- Google fonts - Poppins -->
<link rel="stylesheet" href="${ctxStatic}/newdermon/css/font-css.css">
<!-- theme stylesheet-->
<link rel="stylesheet"
href="${ctxStatic}/newdermon/css/style.default.css?v=<%=System.currentTimeMillis()%>"
id="theme-stylesheet">
<!-- Custom stylesheet - for your changes-->
<link rel="stylesheet"
href="${ctxStatic}/newdermon/css/custom.css?v=<%=System.currentTimeMillis()%>">
<link rel="stylesheet" href="${ctxStatic}/newdermon/css/juery-ui-1.12.css">
<!-- Favicon-->
<link rel="shortcut icon" href="https://img.geexek.com/files/home/favicon.ico">
<link rel="stylesheet"
href="${ctxStatic}/newdermon/css/custom.css?v=<%=System.currentTimeMillis()%>">
<link rel="stylesheet"
href="${ctxStatic}/newdermon/css/main.css?v=<%=System.currentTimeMillis()%>">
<link rel="stylesheet" href="${ctxStatic}/cmpt/setting.css?v=<%=System.currentTimeMillis()%>">
<link rel="stylesheet"
href="${ctxStatic}/leaflet/css/leaflet.css?v=<%=System.currentTimeMillis()%>" />
<link rel="stylesheet" href="${ctxStatic}/leaflet/css/leaflet_label.css" />
<!-- Bootstrap CSS-->
<link rel="stylesheet" href="${ctxStatic}/css/base.css">
<script src="${ctxStatic}/My97DatePicker/WdatePicker.js" type="text/javascript"></script>
<script src="${ctxStatic}/newdermon/vendor/jquery/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8" src="${ctxStatic}/layer/layer.js"></script>
<link rel="stylesheet" href="${ctxStatic}/layer/skin/layer.css">
<link rel="stylesheet" href="/static/cmpt/score.css?<%=System.currentTimeMillis()%>">
<style>
.layui-layer-title {
color: white;
}
.layui-layer-btn {
color: white;
}
.right {
height: auto !important;
width: 80%;
margin: 0px 0px 0px 40px;
}
.action {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
}
.dialog {
width: 40vw;
max-height: 80vh;
height: auto;
z-index: 99;
display: flex;
flex-direction: column;
left: 50%;
transform: translate(-50%, 50%);
margin-left: 0;
padding: 20px;
border-radius: 10px;
}
.dialog input {
width: 100% !important;
}
.action div {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
user-select: none;
}
.submit {
display: inline-block;
width: 120px;
height: 45px;
text-align: center;
line-height: 45px;
color: white;
background: #ce3939;
border-radius: 4px;
letter-spacing: 1px;
cursor: pointer;
font-size: 16px;
}
.cancel {
width: 120px;
height: 45px;
background: #949494;
border-radius: 4px;
font-size: 16px;
color: #FFFFFF;
line-height: 45px;
text-align: center;
margin-right: 20px;
}
.input {
width: 100%;
height: 40px !important;
line-height: 40px !important;
border: 2px solid #F4F4F4;
border-radius: 4px;
margin-right: 30px;
margin-left: 0px;
padding-left: 12px;
background: rgba(247, 247, 247, 1);
border-radius: 4px;
border: 1px solid rgba(229, 229, 229, 1);
}
.title {
font-size: 24px;
font-weight: 500;
color: rgba(51, 51, 51, 1);
}
.form-label {
font-size: 15px;
color: rgb(92, 91, 91);
width: auto;
}
.form-item {
display: flex;
flex-direction: column;
/* height: 90px; */
padding: 5px 0;
}
.section {
display: flex;
background: rgba(255, 255, 255, 1);
border-radius: 4px;
flex-direction: column;
margin-bottom: 10px !important;
margin-top: 0px !important;
}
.tip {
font-size: 16px;
color: rgba(51, 51, 51, 1);
position: absolute;
right: 45px;
top: 10px;
}
.form-action {
display: flex;
justify-content: flex-end;
margin: 0 20px;
padding-top: 10px;
}
label {
/* width: auto; */
/* width: 200px; */
display: flex;
flex-direction: row;
align-items: center;
}
.label-box {
display: flex;
flex-direction: row;
align-items: center;
}
.dialog label input {
width: 20px !important;
height: 20px !important;
margin: 0 10px !important;
}
.cover {
width: 100%;
height: 100px;
background: rgba(247, 247, 247, 1);
border-radius: 4px;
border: 1px solid rgba(238, 238, 238, 1);
display: flex;
justify-content: center;
align-items: center;
}
.cover-img {
width: 300px;
cursor: pointer;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
height: 300px;
}
.icon-cover {
width: 34px;
height: 34px;
background-image: url("/static/images/icon_cover.png");
background-size: 100%;
background-repeat: no-repeat;
}
.section {
width: 100% !important;
display: flex;
flex-direction: column;
}
.rule-field tbody tr td:first-child {
padding-left: 5px !important;
height: auto !important;
}
tbody tr td {
font-size: 15px !important;
padding: 5px;
}
input[type=checkbox]::before {
border: none !important;
background: none !important;
}
input[type=checkbox]:checked::before {
border: none !important;
background: none !important;
}
input[type=checkbox] {
top: 0;
left: 0;
}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp"></jsp:include>
<div class="page-content d-flex align-items-stretch main-body">
<jsp:include page="../common/menu.jsp"></jsp:include>
<div class="right" id="app">
<div class="section flex flex-col gap-y-2">
<div class="flex flex-row items-center justify-between">
<div class="btn-group" role="group" aria-label="First group">
<button :class="[index==typeIndex?'btn-primary':'btn-default']"
@click="changeType(index)" type="button"
v-for="(typeOpt,index) in typeOptions" :key="index" class="btn btn-sm">
{{typeOpt.name}}
</button>
</div>
<div class="flex flex-row items-center gap-x-2 ml-auto">
<div class="btn-group" role="group" aria-label="First group">
<button :class="[index==statusIndex?'btn-danger':'btn-default']"
@click="changeStatus(index)" type="button"
v-for="(statusOpt,index) in statusOptions" :key="index"
class="btn btn-sm">
{{statusOpt.name}}({{statusOpt.count}})
</button>
</div>
<div class="input-group ml-2 mr-2">
<input type="text" class="form-control"
:placeholder="isEnroll?'请输入搜索关键字':'请输入参赛号'" @keyup.enter="refresh"
v-model="keyword" aria-label="Input group example"
aria-describedby="btnGroupAddon">
</div>
<div class="flex flex-row items-center gap-x-2">
<button class="btn btn-sm ml-auto btn-danger" @click="refresh">
搜索
</button>
</div>
</div>
</div>
<div class="flex flex-row items-center w-full justify-start gap-x-2">
<div>
<button class="btn btn-sm ml-auto btn-primary"
@click="importExcel('enroll')">
导入名单
</button>
</div>
<div>
<button class="btn btn-sm ml-auto btn-primary"
@click="importExcel('markNo')">
导入参赛号
</button>
</div>
<div>
<button class="btn btn-sm ml-auto btn-primary"
@click="exportExcel('enroll')">
导出选手名单
</button>
</div>
<div>
<button class="btn btn-sm ml-auto btn-primary"
@click="exportExcel('markNo')">
导出参赛号
</button>
</div>
<div>
<button class="btn btn-sm ml-auto btn-primary" @click="markNoSelect">
随机分配
</button>
</div>
</div>
</div>
<div style="margin-bottom: 50px">
<table style="width: 100%;" class="rule-field">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th style="text-align: center;padding-left:5px;">{{isEnroll?'姓名':'参赛号'}}
</th>
<th style="text-align: center">{{isEnroll?'参赛号':'分区'}}</th>
<th style="text-align: center">{{isEnroll?'手机号':'号段名'}}</th>
<th style="text-align: center">{{isEnroll?'分区':'状态'}}</th>
<th style="text-align: center">{{isEnroll?'更新时间':'是否自动分配'}}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in list" :data-id="item.id">
<td style="text-align: center;">
{{isEnroll?item.name:item.markNo}}
</td>
<td class="name" style="text-align: center;">
{{isEnroll?(item.markNo?item.markNo:'---'):item.zone}}
</td>
<td class="name" style="text-align: center;">
{{isEnroll?item.phone:item.groupName}}
</td>
<td class="name" style="text-align: center;">
{{isEnroll?item.zone:pickUpEnum[item.isPickUp]}}
</td>
<td class="name" style="text-align: center;">
{{isEnroll?item.updateTime:autoEnum[item.isAuto]}}
</td>
</tr>
</tbody>
</table>
<nav class="mt-2" aria-label="Page navigation">
<ul class="pagination">
<li class="page-item" v-if="page!==1" @click="preview"><a class="page-link"
href="#">Previous</a></li>
<li @click="changePage(item+1)" v-for="item,index in totalPage"
:key="item+'page'" class="page-item" :class="{active:(index+1)==page}">
<a class="page-link" href="#">{{item}}</a>
</li>
<li class="page-item" v-if="list.length===pageSize" @click="next"><a
class="page-link" href="#">Next</a></li>
<div class="ml-2 flex flex-row items-center gap-x-2">
<span>每页条数</span>
<select v-model="pageSize" @change="fetchData" style="width: 50px;">
<option :value="10">10</option>
<option :value="20">20</option>
<option :value="50">50</option>
<option :value="100">100</option>
<option :value="500">500</option>
</select>
<span>共{{pages}}页</span>
</div>
</ul>
</nav>
</div>
<div class="dialog" v-show="dialog">
<div>
<span class="text-2xl font-bold mb-3 text-main">
{{title}}
</span>
</div>
<div class="flex flex-col gap-y-3 flex-1 overflow-y-auto">
<input class="pt-2" @change="handleFileChange" type="file" ref="fileInput"
:placeholder="type==='enroll'?'请上传选号名单模板':'请上传参赛号入库模板'" />
<a :href="xlsxUrl">
{{type==='enroll'?'选号名单模板.xlsx':'参赛号入库模板.xlsx'}}
</a>
<span class="text-main">
文件上传(请上传.xlsx格式文件)
</span>
</div>
<div class="form-action">
<span @click="cancel" class="cancel cursor-pointer">取消</span>
<span @click="submit" class="submit">上传</span>
</div>
</div>
<div v-show="dialog"
style="position: fixed;height: 100%;width: 100%;background: black;z-index: 10;opacity: 0.5;top:0px;left:0px">
</div>
</div>
<script src="${ctxStatic}/vue/vue.js"></script>
<script>
// 正式环境
const eccUrl = "https://ecc.geexek.com"
const gtCmptId = getCId()
// ecc的请求地址
// const eccUrl = "http://localhost:8081"
// 模拟的cmptId
// const gtCmptId = 27262
// 选号模板
const markNoTemplateUrl = "https://geexekimgoss-sxk.oss-cn-hangzhou.aliyuncs.com/gk/common/markNoSelect/%E5%8F%82%E8%B5%9B%E5%8F%B7%E5%85%A5%E5%BA%93%E6%A8%A1%E7%89%88v1.xlsx"
// 选手模板
const enrollTemplateUrl = "https://geexekimgoss-sxk.oss-cn-hangzhou.aliyuncs.com/gk/common/markNoSelect/%E9%80%89%E5%8F%B7%E5%90%8D%E5%8D%95%E8%A1%A8%E6%A8%A1%E7%89%88v1.xlsx"
const app = new Vue({
el: '#app',
data: {
list: [],
dialog: false,
type: 'enroll',// 类型有enroll 和 markNo
title: '自助选号',
selectedFile: null, // 上传的文件
typeIndex: 0, // 是否是人员列表
typeOptions: [
{
name: "选手名单",
value: 1,
},
{
name: "参赛号列表",
value: 0,
},
],
// 分页相关
keyword: '',
page: 1,
pageSize: 10,
totalPage: 1,
pages: 0,
// 状态相关
statusIndex: 0,
statusOptions: [
{
name: "全部",
value: '',
count: 0
},
{
name: "已选",
value: 1,
count: 0
},
{
name: "未选",
value: 0,
count: 0
},
],
pickUpEnum: {
0: '待选',
1: '已选'
},
autoEnum: {
0: '否',
1: '是'
}
},
computed: {
// 文件下载地址
xlsxUrl() {
return this.type === 'enroll' ? enrollTemplateUrl : markNoTemplateUrl
},
// 是否是选手名单
isEnroll() {
return this.typeIndex === 0
}
},
mounted() {
this.fetchData();
this.getStats();
},
methods: {
// 随机分配
markNoSelect() {
layer.confirm("确认要随机分配吗?", () => {
$.ajax({
url: eccUrl + '/api-pick/v1/pick-up-batch?cmptId=' + gtCmptId,
type: 'get',
contentType: 'application/json',
beforeSend: () => {
layer.load()
},
success: (res) => {
layer.msg(res.code === 200 ? '分配成功!' : res.msg);
setTimeout(() => {
this.dialog = false;
this.fetchData();
this.getStats()
}, 1500)
},
complete: () => {
setTimeout(() => layer.closeAll(), 1500)
}
});
});
},
// 导出名单
exportExcel(type) {
const markNoUrl = '/api-pick/v1/export-markno-library-v1'
const enrollUrl = '/api-pick/v1/export-markno-enroll'
const url = eccUrl + (type === 'enroll' ? enrollUrl : markNoUrl)
window.location.href = url + '?cmptId=' + gtCmptId
},
// 处理文件选择
handleFileChange(event) {
this.selectedFile = event.target.files[0];
},
// 页面刷新
refresh() {
this.page = 1;
this.fetchData()
},
// 状态切换
changeStatus(index) {
this.page = 1
this.statusIndex = index;
this.fetchData()
},
// 状态切换
changeType(index) {
this.page = 1
this.typeIndex = index;
this.statusIndex = 0
this.keyword = ''
this.getStats()
this.fetchData()
},
// 分页
changePage(page) {
this.page = page
this.fetchData()
},
// 下一页
next() {
this.page += 1
this.fetchData()
},
// 上一也
preview() {
this.page -= 1
this.fetchData()
},
// 编辑
importExcel(type) {
this.type = type
this.title = type === 'enroll' ? '导入选号名单' : '导入参赛号入库'
this.dialog = true
},
// 保存
submit() {
if (!this.selectedFile) {
layer.msg('请先选择文件');
return;
}
const bag = { ...this.bag }
const formData = new FormData();
formData.append('file', this.selectedFile);
formData.append('cmptId', gtCmptId);
const url = eccUrl + (this.type === 'enroll' ? '/api-pick/v1/import-mark-enroll' : '/api-pick/v1/import-mark-library')
$.ajax({
url,
type: 'POST',
data: formData,
processData: false,
contentType: false,
beforeSend: () => {
layer.load()
},
success: (res) => {
layer.msg(res.code === 200 ? '保存成功!' : res.msg);
setTimeout(() => {
this.dialog = false;
this.fetchData();
this.getStats()
}, 1500)
},
complete: () => {
setTimeout(() => layer.closeAll(), 1500)
}
})
},
// 返回
cancel() {
this.dialog = false;
},
// 查询所有
fetchData() {
if (!getCId()) return
const url = eccUrl + (this.isEnroll ? '/api-pick/v1/enroll-page' : '/api-pick/v1/mark-list')
let params = {
cmptId: gtCmptId,
keyword: this.keyword,
isPickUp: this.statusOptions[this.statusIndex].value,
current: this.page,
size: this.pageSize
}
// 只对参赛号模糊搜索
if (!this.isEnroll && this.keyword) {
params.markNo = this.keyword
}
$.ajax({
type: 'post',
contentType: 'application/json',
url,
data: JSON.stringify(params),
beforeSend: () => {
layer.load()
},
complete: () => {
layer.closeAll()
},
success: (res) => {
this.list = res.data.records
if (res.data.records.length === this.pageSize) {
this.totalPage = this.page + 1
} else {
this.totalPage = this.page
}
this.pages = res.data.pages
// 总数的统计数
if (this.statusOptions[this.statusIndex].value === '') {
this.statusOptions[0].count = res.data.total
}
}
})
},
// 获取统计
getStats() {
const url = eccUrl + (this.isEnroll ? '/api-pick/v1/enroll-page' : '/api-pick/v1/mark-list')
let apis = [1, 0].map(v =>
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
cmptId: 27262,
isPickUp: v,
current: this.page,
size: this.pageSize
})
}).then(res => res.json())
)
Promise.all(apis).then(([res1, res2]) => {
this.statusOptions[1].count = res1.data.total
this.statusOptions[2].count = res2.data.total
})
},
}
});
</script>
</body>
</html>
\ No newline at end of file
...@@ -362,6 +362,13 @@ ...@@ -362,6 +362,13 @@
<span class="menu-txt">发票管理</span> <span class="menu-txt">发票管理</span>
</a> </a>
</li> </li>
<li class="markNoSelect menu-sub-item">
<a
href="/gk/markNoSelect/index/${cmpt.cmptId}?uId=${uId}&cId=${cId}&timestamp=${timestamp}&sign=${sign}">
<span class="left-arrow"></span>
<span class="menu-txt">自助选号</span>
</a>
</li>
</ul> </ul>
</li> </li>
</ul> </ul>
...@@ -424,7 +431,7 @@ ...@@ -424,7 +431,7 @@
var classes = ['cmptSetting', 'nameList', 'manual', 'contact', 'manage', var classes = ['cmptSetting', 'nameList', 'manual', 'contact', 'manage',
'route', 'road', 'equip', 'photo', 'news', 'cert', 'data', 'route', 'road', 'equip', 'photo', 'news', 'cert', 'data',
'banner', 'score', 'auto', 'scan', 'review', 'customer', 'rule', 'banner', 'score', 'auto', 'scan', 'review', 'customer', 'rule',
'outter-link', 'sure-letter', 'rankSetting', 'service', "module", "swiper", "bag", "invoice"]; 'outter-link', 'sure-letter', 'rankSetting', 'service', "module", "swiper", "bag", "invoice", "markNoSelect"];
let url = document.location.href; let url = document.location.href;
var done = false; var done = false;
for (var i in classes) { for (var i in classes) {
......
...@@ -1046,4 +1046,112 @@ ...@@ -1046,4 +1046,112 @@
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
} }
/* ... 现有代码 ... */ /* ... 现有代码 ... */
\ No newline at end of file
/* 文本颜色 */
.text-main {
color: #CE3939;
}
.text-white {
color: #fff;
}
.text-black {
color: #000;
}
.text-gray {
color: #9ca3af;
}
.text-red {
color: #ef4444;
}
.text-blue {
color: #3b82f6;
}
.text-green {
color: #10b981;
}
.text-yellow {
color: #f59e0b;
}
.text-indigo {
color: #6366f1;
}
.text-purple {
color: #8b5cf6;
}
.text-pink {
color: #ec4899;
}
/* 背景颜色 */
.bg-main {
background-color: #CE3939;
}
.bg-white {
background-color: #fff;
}
.bg-black {
background-color: #000;
}
.bg-gray {
background-color: #9ca3af;
}
.bg-red {
background-color: #ef4444;
}
.bg-blue {
background-color: #3b82f6;
}
.bg-green {
background-color: #10b981;
}
.bg-yellow {
background-color: #f59e0b;
}
.bg-indigo {
background-color: #6366f1;
}
.bg-purple {
background-color: #8b5cf6;
}
.bg-pink {
background-color: #ec4899;
}
/* 透明背景 */
.bg-transparent {
background-color: transparent;
}
/* 背景透明度 */
.bg-opacity-50 {
opacity: 0.5;
}
.bg-opacity-75 {
opacity: 0.75;
}
.bg-opacity-90 {
opacity: 0.9;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment