记得上下班打卡 | git大法好,push需谨慎

Commit 1ff59c56 authored by wangyifan's avatar wangyifan

Merge branch 'dev-wyf-1.5' into 'master'

Dev wyf 1.5

See merge request !410
parents ab2b517e 8bb4314f
-- 需求文档:https://zzvwci6syl.feishu.cn/wiki/ZrY1wpQCBi2QLukvyEVct8PynIe
-- 艺人管理表
CREATE TABLE `kylin_artist` (
`mid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`artist_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '艺人ID',
`artist_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '艺人名称',
`artist_type` tinyint(4) NOT NULL COMMENT '艺人类型 1音乐人 2艺术家 3厂牌 4品牌方',
`avatar_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '艺人头像',
`introduction` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '艺人简介',
`status` tinyint(4) DEFAULT '1' COMMENT '状态 1启用 0禁用',
`sort` int(11) DEFAULT '0' COMMENT '排序权重,越大越靠前',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`mid`),
UNIQUE KEY `uk_artist_id` (`artist_id`),
UNIQUE KEY `uk_artist_name` (`artist_name`),
KEY `idx_artist_type` (`artist_type`),
KEY `idx_status` (`status`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='艺人管理表';
-- 艺人相册表
CREATE TABLE `kylin_artist_album` (
`mid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`album_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '相册ID',
`artist_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '艺人ID',
`image_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '图片地址',
`sort` int(11) DEFAULT '0' COMMENT '排序权重,越大越靠前',
`status` tinyint(4) DEFAULT '1' COMMENT '状态 1启用 0禁用',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`mid`),
UNIQUE KEY `uk_album_id` (`album_id`),
KEY `idx_artist_id` (`artist_id`),
KEY `idx_status` (`status`),
KEY `idx_sort` (`sort`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='艺人相册表';
-- 艺人-演出关联表
CREATE TABLE `kylin_artist_performance` (
`mid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
`artist_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关联 kylin_artist.artist_id',
`performances_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关联演出ID kylin_performances.performances_id',
`times_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关联场次 kylin_ticket_times.ticket_times_id',
`sort` int(11) DEFAULT '0' COMMENT '该艺人在本演出中的排序权重,越大越靠前',
`created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`mid`),
UNIQUE KEY `uk_artist_performance` (`artist_id`,`performances_id`,`times_id`) USING BTREE COMMENT '艺人、演出、场次唯一索引',
KEY `idx_performances_id` (`performances_id`),
KEY `idx_artist_id` (`artist_id`)
) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='艺人-演出关联表';
-- 艺人操作记录表
CREATE TABLE `kylin_artist_operation_log` (
`mid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
`log_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '日志ID',
`artist_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关联艺人ID kylin_artist.artist_id',
`operation_type` tinyint(4) NOT NULL COMMENT '操作类型 1新增 2编辑 3删除',
`operation_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '修改内容描述',
`operator_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '操作人ID',
`operator_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '操作人名称',
`created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
PRIMARY KEY (`mid`),
KEY `idx_artist_id` (`artist_id`),
KEY `idx_log_id` (`log_id`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
\ No newline at end of file
......@@ -5,6 +5,7 @@ public class KylinRedisConst {
public static final String PERFORMANCES = "kylin:performances:id:";
public static final String PERFORMANCES_INVOICE_REMINDER = "kylin:performances:invoice_reminder:id:";
public static final String PERFORMANCES_NOTICE_REMIND_STATUS = "kylin:performances:noticeRemindStatus:id:";
public static final String PERFORMANCES_ARTISTS = "kylin:performances:artists:id:";
public static final String PERFORMANCES_TRUE_NAME = "kylin:performances_true_name:id:";
public static final String PERFORMANCES_LIST_CITY = "kylin:performances:city:";
public static final String PERFORMANCES_LIST_SYSTEM_RECOMMEND = "kylin:performances:systemRecommend";
......
package com.liquidnet.service.kylin.dto.param;
import com.liquidnet.service.kylin.entity.KylinArtist;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import java.time.LocalDateTime;
import java.util.List;
/**
* 艺人管理参数
*
* @author system
* @since 2026-02-04
*/
@Data
@ApiModel("艺人管理参数")
public class ArtistParam {
@ApiModelProperty(value = "艺人ID")
private String artistId;
@ApiModelProperty(value = "艺人名称")
private String artistName;
@ApiModelProperty(value = "艺人类型 1音乐人 2艺术家 3厂牌 4品牌方")
private Integer artistType;
@ApiModelProperty(value = "艺人头像")
private String avatarUrl;
@ApiModelProperty(value = "艺人简介")
private String introduction;
@ApiModelProperty(value = "艺人相册图片列表")
private List<String> albumImages;
@ApiModelProperty(value = "排序权重")
private Integer sort;
@ApiModelProperty(value = "状态 0禁用 1启用")
private Integer status;
@ApiModelProperty(value = "批量操作的ID列表")
private List<String> ids;
public KylinArtist getFields(String artistId, LocalDateTime createdAt) {
KylinArtist kylinArtist = new KylinArtist();
BeanUtils.copyProperties(this, kylinArtist);
if (artistId != null) {
kylinArtist.setArtistId(artistId);
}
if (createdAt != null) {
kylinArtist.setCreatedAt(createdAt);
}
kylinArtist.setUpdatedAt(LocalDateTime.now());
// 设置默认值
if (kylinArtist.getStatus() == null) {
kylinArtist.setStatus(1);
}
if (kylinArtist.getSort() == null) {
kylinArtist.setSort(0);
}
return kylinArtist;
}
}
package com.liquidnet.service.kylin.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 艺人搜索参数
*
* @author system
* @since 2026-02-04
*/
@Data
@ApiModel("艺人搜索参数")
public class ArtistSearchParam {
@ApiModelProperty(value = "艺人名称")
private String artistName;
@ApiModelProperty(value = "艺人ID")
private String artistId;
@ApiModelProperty(value = "艺人类型 1音乐人 2艺术家 3厂牌 4品牌方")
private Integer artistType;
@ApiModelProperty(value = "开始日期")
private String beginDate;
@ApiModelProperty(value = "结束日期")
private String endDate;
@ApiModelProperty(value = "当前页码")
private Integer pageNum = 1;
@ApiModelProperty(value = "每页数量")
private Integer pageSize = 10;
}
package com.liquidnet.service.kylin.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 艺人详情VO
*
* @author system
* @since 2026-02-04
*/
@Data
@ApiModel("艺人详情VO")
public class ArtistVo {
@ApiModelProperty(value = "艺人ID")
private String artistId;
@ApiModelProperty(value = "艺人名称")
private String artistName;
@ApiModelProperty(value = "艺人类型 1音乐人 2艺术家 3厂牌 4品牌方")
private Integer artistType;
@ApiModelProperty(value = "艺人类型名称")
private String artistTypeName;
@ApiModelProperty(value = "艺人头像")
private String avatarUrl;
@ApiModelProperty(value = "艺人简介")
private String introduction;
@ApiModelProperty(value = "艺人相册图片列表")
private List<String> albumImages;
@ApiModelProperty(value = "关联演出")
private List<PerformanceVo> performanceVoList;
@ApiModelProperty(value = "关联商品")
private List<ProductVo> productVoList;
@ApiModelProperty(value = "排序权重")
private Integer sort;
@ApiModelProperty(value = "状态")
private Integer status;
@ApiModelProperty(value = "创建时间")
private String createdAt;
@ApiModelProperty(value = "更新时间")
private String updatedAt;
@Data
@ApiModel("演出VO")
public static class PerformanceVo{
@ApiModelProperty("演出ID")
private String performanceId;
@ApiModelProperty("演出名称")
private String title;
@ApiModelProperty("演出开始时间")
private String timeStart;
@ApiModelProperty("场次ID")
private String timesId;
@ApiModelProperty("场次名称")
private String timeTitle;
}
@Data
@ApiModel("商品VO")
private static class ProductVo {
}
}
package com.liquidnet.service.kylin.dto.vo.returns;
import com.liquidnet.service.kylin.dao.KylinArtistPerformanceDao;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
@ApiModel("演出场次艺人阵容Vo")
public class KylinPerformanceArtistLineupVo implements Serializable {
@ApiModelProperty(value = "场次ID")
private String ticketTimesId;
@ApiModelProperty(value = "场次标题")
private String timeTitle;
@ApiModelProperty(value = "艺人列表")
private List<KylinPerformanceTimeArtist> artists;
@Data
@ApiModel("演出场次艺人")
public static class KylinPerformanceTimeArtist {
@ApiModelProperty(value = "艺人ID")
private String artistId;
@ApiModelProperty(value = "艺人名称")
private String artistName;
@ApiModelProperty(value = "艺人头像")
private String avatarUrl;
@ApiModelProperty(value = "演出ID")
private String performanceId;
@ApiModelProperty(value = "演出标题")
private String title;
@ApiModelProperty(value = "艺人排序 越大越靠前")
private Integer sort;
// 👇 静态转换方法:从 Dao 转为 Vo
public static KylinPerformanceTimeArtist from(KylinArtistPerformanceDao dao) {
if (dao == null) {
return null;
}
KylinPerformanceTimeArtist artist = new KylinPerformanceTimeArtist();
artist.setArtistId(dao.getArtistId());
artist.setArtistName(dao.getArtistName());
artist.setAvatarUrl(dao.getAvatarUrl());
artist.setPerformanceId(dao.getPerformanceId());
artist.setTitle(dao.getTitle());
artist.setSort(dao.getSort());
return artist;
}
}
}
......@@ -4,6 +4,7 @@ import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.kylin.dto.param.KylinCandyItemParam;
import com.liquidnet.service.kylin.dto.param.KylinPerformanceSubscribeParam;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinCandyVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinPerformanceArtistLineupVo;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
......@@ -35,22 +36,24 @@ public interface IKylinPerformancesService {
/**
* 演出预约
* @author zjp
*
* @param param
* @author zjp
* @return: com.liquidnet.service.base.ResponseDto<java.lang.String>
* @date 2024/3/12 14:39
*/
ResponseDto<String> performanceSubscribe(HttpServletRequest request,KylinPerformanceSubscribeParam param);
ResponseDto<String> performanceSubscribe(HttpServletRequest request, KylinPerformanceSubscribeParam param);
/**
* 是否演出预约
* @author zjp
*
* @param performancesId
* @param ticketTimesId
* @author zjp
* @return: com.liquidnet.service.base.ResponseDto<java.lang.Integer>
* @date 2024/3/6 14:45
*/
ResponseDto<Integer> performanceIsSubscribe(String performancesId,String ticketTimesId,String ticketsId);
ResponseDto<Integer> performanceIsSubscribe(String performancesId, String ticketTimesId, String ticketsId);
/*
......@@ -60,5 +63,12 @@ public interface IKylinPerformancesService {
* @param:
* @return:
**/
void deleteIsSubscribe(String performancesId,String ticketTimesId,String ticketsId);
void deleteIsSubscribe(String performancesId, String ticketTimesId, String ticketsId);
/**
* 根据演出ID获取演出阵容
* @param performancesId
* @return
*/
List<KylinPerformanceArtistLineupVo> performanceArtists(String performancesId);
}
package com.liquidnet.service.kylin.service.admin;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import com.liquidnet.service.kylin.dao.KylinArtistOperationLogDao;
import com.liquidnet.service.kylin.entity.KylinArtistOperationLog;
/**
* <p>
* 艺人操作日志 服务类
* </p>
*
* @author liquidnet
* @since 2026-03-04
*/
public interface IKylinArtistOperationLogService extends IService<KylinArtistOperationLog> {
/**
* 记录操作日志(自动获取当前用户)
*
* @param artistId 艺人ID
* @param operationType 操作类型 1新增 2编辑 3删除
* @param operationContent 操作内容描述
*/
void recordLog(String artistId, Integer operationType, String operationContent);
/**
* 记录操作日志(指定操作人)
*
* @param artistId 艺人ID
* @param operationType 操作类型 1新增 2编辑 3删除
* @param operationContent 操作内容描述
* @param operatorId 操作人ID
* @param operatorName 操作人名称
*/
void recordLog(String artistId, Integer operationType, String operationContent, String operatorId, String operatorName);
/**
* 获取艺人操作记录列表
*
* @param artistId 艺人ID
* @param pageNum 页码
* @param pageSize 每页数量
* @return 操作记录分页列表
*/
PageInfo<KylinArtistOperationLogDao> getOperationLogs(String artistId, Integer pageNum, Integer pageSize);
}
package com.liquidnet.service.kylin.service.admin;
import com.baomidou.mybatisplus.extension.service.IService;
import com.liquidnet.service.kylin.dao.KylinArtistAssociationStatusDto;
import com.liquidnet.service.kylin.dao.KylinArtistPerformanceDao;
import com.liquidnet.service.kylin.entity.KylinArtistPerformance;
import java.util.List;
import java.util.Map;
public interface IKylinArtistPerformanceService extends IService<KylinArtistPerformance> {
/**
* 获取指定场次的艺人阵容
* @param performancesId
* @param timesId
* @return
*/
List<KylinArtistPerformanceDao> getSessionArtists(String performancesId, String timesId);
/**
* 更新演出艺人排序
*
* @param performanceId
* @param orderData
* @return
*/
boolean updateArtistOrder(String performanceId, List<Map<String, Object>> orderData);
/**
* 删除演出艺人关联
*
* @param mid
* @param performanceId
* @return
*/
int deletePerformanceArtist(Long mid, String performanceId);
/**
* 获取所有艺人
* @param performancesId
* @param timesId
* @param keyword
* @return
*/
List<KylinArtistAssociationStatusDto> getAllArtists(String performancesId, String timesId, String keyword);
/**
* 修改艺人关联
* @param performancesId
* @param timesId
* @param artistOrders
* @return
*/
boolean updateArtistAssociations(String performancesId, String timesId, List<Map<String, Object>> artistOrders);
}
package com.liquidnet.service.kylin.service.admin;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import com.liquidnet.service.kylin.dao.KylinArtistDao;
import com.liquidnet.service.kylin.dto.param.ArtistParam;
import com.liquidnet.service.kylin.dto.param.ArtistSearchParam;
import com.liquidnet.service.kylin.dto.vo.ArtistVo;
import com.liquidnet.service.kylin.entity.KylinArtist;
import java.util.List;
/**
* <p>
* 艺人管理 服务类
* </p>
*
* @author liquidnet
* @since 2026-02-04
*/
public interface IKylinArtistService extends IService<KylinArtist> {
Boolean create(ArtistParam param);
Boolean update(ArtistParam param);
ArtistVo detail(String artistId);
PageInfo<KylinArtistDao> artistList(ArtistSearchParam param);
Boolean delete(List<String> artistIds);
Boolean checkArtistNameExists(String artistName, String artistId);
}
......@@ -26,6 +26,7 @@ import com.liquidnet.service.kylin.dto.param.SysDamaiParam;
import com.liquidnet.service.kylin.dto.vo.admin.*;
import com.liquidnet.service.kylin.dto.vo.partner.KylinPerformanceMisVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinPerformancesVo;
import com.liquidnet.service.kylin.dto.vo.partner.TicketTimesTicketCreatePartnerVo;
import com.liquidnet.service.kylin.entity.KylinOrderImport;
import com.liquidnet.service.kylin.service.admin.IKylinPerformancesAdminService;
import com.liquidnet.service.kylin.service.other.DamaiService;
......@@ -45,6 +46,7 @@ import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
......@@ -258,6 +260,41 @@ public class KylinPerformancesController extends BaseController {
return prefix + "/subscribe";
}
/**
* 演出阵容页面
*/
@GetMapping(value = "/artistLineup/{performancesId}")
public String artistLineup(@PathVariable("performancesId") String performancesId, ModelMap mmap) {
try {
// 获取演出信息
KylinPerformanceMisVo performance = kylinPerformancesService.performanceDetails(performancesId);
if (performance == null) {
mmap.put("errorMsg", "演出不存在");
return prefix + "/artistLineup";
}
// 将场次数据转换为JSON
List<TicketTimesTicketCreatePartnerVo> ticketTimes = performance.getTicketTimes();
String ticketTimesJson = "[]";
if (ticketTimes != null && !ticketTimes.isEmpty()) {
List<TicketTimesTicketCreatePartnerVo> collect = ticketTimes.stream()
.filter(f -> f.getType().equals(1))
.collect(Collectors.toList());
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
ticketTimesJson = mapper.writeValueAsString(collect);
}
mmap.put("performancesId", performancesId);
mmap.put("performanceTitle", performance.getTitle());
mmap.put("ticketTimesJson", ticketTimesJson);
return prefix + "/artistLineup";
} catch (Exception e) {
mmap.put("errorMsg", "加载演出阵容失败: " + e.getMessage());
return prefix + "/artistLineup";
}
}
@Log(title = "预约统计:导出列表")
@PostMapping("/subscribe/export")
@ResponseBody
......
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('艺人列表')"/>
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>艺人ID:</label>
<input type="text" name="artistId" placeholder="请输入艺人ID"/>
</li>
<li>
<label>艺人名称:</label>
<input type="text" name="artistName" placeholder="请输入艺人名称"/>
</li>
<li>
<label>艺人类型:</label>
<select name="artistType">
<option value="">全部</option>
<option value="1">音乐人</option>
<option value="2">艺术家</option>
<option value="3">厂牌</option>
<option value="4">品牌方</option>
</select>
</li>
<li class="select-time">
<label>入驻时间:</label>
<input type="text" class="time-input" id="beginDate" name="beginDate" placeholder="开始日期"/>
<span>-</span>
<input type="text" class="time-input" id="endDate" name="endDate" placeholder="结束日期"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="kylin:artist:create">
<i class="fa fa-plus"></i> 添加
</a>
</div>
<div class="col-sm-12 select-table table-bordered">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<script th:inline="javascript">
var updateFlag = [[${@permission.hasPermi('kylin:artist:update')}]];
var removeFlag = [[${@permission.hasPermi('kylin:artist:delete')}]];
var detailFlag = [[${@permission.hasPermi('kylin:artist:detail')}]];
var prefix = ctx + "kylin/artist";
$(function () {
var options = {
url: prefix + "/list",
updateUrl: prefix + "/update/{id}",
createUrl: prefix + "/create",
removeUrl: prefix + "/delete",
detailUrl: prefix + "/detail/{id}",
modalName: "艺人",
columns: [
{
field: 'artistId',
title: '艺人ID'
},
{
field: 'avatarUrl',
title: '艺人头像',
formatter: function(value, row, index) {
return $.table.imageView(value, "80", "80");
}
},
{
field: 'artistName',
title: '艺人名称'
},
{
field: 'artistTypeName',
title: '艺人类型',
},
{
field: 'createdAt',
title: '艺人入驻时间',
formatter: function(value, row, index) {
if (value) {
var date = new Date(value);
return date.getFullYear() + '-' +
String(date.getMonth() + 1).padStart(2, '0') + '-' +
String(date.getDate()).padStart(2, '0') + ' ' +
String(date.getHours()).padStart(2, '0') + ':' +
String(date.getMinutes()).padStart(2, '0') + ':' +
String(date.getSeconds()).padStart(2, '0');
}
return '';
}
},
{
field: 'performanceCount',
title: '关联演出',
formatter: function(value, row, index) {
return value || 0;
}
},
{
field: 'productCount',
title: '关联商品',
formatter: function(value, row, index) {
return value || 0;
}
},
{
title: '操作',
align: 'center',
formatter: function (value, row, index) {
var actions = [];
actions.push('<a class="btn btn-info btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick="$.operate.detail(\'' + row.artistId + '\')"><i class="fa fa-eye"></i>详情</a> ');
actions.push('<a class="btn btn-success btn-xs ' + updateFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.artistId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-warning btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick="showOperationLog(\'' + row.artistId + '\')"><i class="fa fa-history"></i>操作日志</a> ');
return actions.join('');
}
}]
};
$.table.init(options);
// 初始化日期选择器
layui.use('laydate', function(){
var laydate = layui.laydate;
// 开始日期
laydate.render({
elem: '#beginDate',
format: 'yyyy-MM-dd',
type: 'date',
done: function(value, date){
// 可以在这里添加日期选择后的逻辑
}
});
// 结束日期
laydate.render({
elem: '#endDate',
format: 'yyyy-MM-dd',
type: 'date',
done: function(value, date){
// 可以在这里添加日期选择后的逻辑
}
});
});
});
// 单条删除
function removeArtist(id) {
$.operate.remove(id, "删除后该艺人信息将无法被引用,也无法找回,确认要将该艺人删除吗?");
}
// 显示操作日志
function showOperationLog(artistId) {
var url = prefix + '/operationLog/' + artistId;
$.modal.openTab("艺人操作记录", url);
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('艺人操作记录')"/>
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<!-- 头部信息 -->
<div class="col-sm-12" style="margin-bottom: 15px;">
<div class="alert alert-info" style="margin-bottom: 0;">
<strong>艺人ID:</strong><span th:text="${artistId}">10001</span>
<strong style="margin-left: 30px;">艺人名称:</strong><span th:text="${artistName}">摩登天空</span>
</div>
</div>
<div class="col-sm-12 select-table table-bordered">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<script th:inline="javascript">
var artistId = [[${artistId}]];
var prefix = ctx + "kylin/artist";
$(function () {
var options = {
url: prefix + "/operationLogList",
queryParams: function(params) {
return {
pageNum: params.offset / params.limit + 1,
pageSize: params.limit,
artistId: artistId
};
},
columns: [
{
field: 'operationType',
title: '操作类型',
width: '10%',
formatter: function(value, row, index) {
var typeClass = '';
var typeName = row.operationTypeName || '未知';
if (value == 1) {
typeClass = 'label-success';
} else if (value == 2) {
typeClass = 'label-warning';
} else if (value == 3) {
typeClass = 'label-danger';
}
return '<span class="label ' + typeClass + '">' + typeName + '</span>';
}
},
{
field: 'createdAt',
title: '操作时间',
width: '20%'
},
{
field: 'operationContent',
title: '修改内容',
width: '50%'
},
{
field: 'operatorName',
title: '操作人',
width: '20%',
formatter: function(value, row, index) {
return value || '系统';
}
}
]
};
$.table.init(options);
});
</script>
</body>
</html>
......@@ -43,6 +43,8 @@
</li>
<li id="li-tab-11"><a data-toggle="tab" href="#tab-11" aria-expanded="false" onclick="subscribeInfo()">预约统计</a>
</li>
<li id="li-tab-12"><a data-toggle="tab" href="#tab-12" aria-expanded="false" onclick="artistLineupInfo()">演出阵容</a>
</li>
</ul>
<div class="tab-content">
<div id="tab-1" class="tab-pane">
......@@ -364,6 +366,13 @@
height=800px frameborder=0></iframe>
</div>
</div>
<div id="tab-12" class="tab-pane">
<div class="panel-body">
<iframe id="artist_lineup_iframe" name="artist_lineup_iframe" marginwidth=0 marginheight=0
width=100%
height=800px frameborder=0></iframe>
</div>
</div>
</div>
</div>
</div>
......@@ -564,6 +573,11 @@
document.getElementById("subscribe_iframe").src = "../subscribe/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", "");
}
//演出阵容
function artistLineupInfo() {
document.getElementById("artist_lineup_iframe").src = "../artistLineup/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", "");
}
$("#tab-nav-1").bind("click", function () {
$("#tab_iframe_1").attr("src", prefix + "/performanceStatic/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", ""));
});
......
package com.liquidnet.client.admin.zhengzai.kylin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liquidnet.client.admin.common.core.domain.entity.SysUser;
import com.liquidnet.client.admin.common.utils.ShiroUtils;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.kylin.dao.KylinArtistOperationLogDao;
import com.liquidnet.service.kylin.entity.KylinArtistOperationLog;
import com.liquidnet.service.kylin.mapper.KylinArtistOperationLogMapper;
import com.liquidnet.service.kylin.service.admin.IKylinArtistOperationLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
/**
* <p>
* 艺人操作日志 服务实现类
* </p>
*
* @author liquidnet
* @since 2026-03-04
*/
@Slf4j
@Service
public class KylinArtistOperationLogServiceImpl extends ServiceImpl<KylinArtistOperationLogMapper, KylinArtistOperationLog>
implements IKylinArtistOperationLogService {
@Override
public void recordLog(String artistId, Integer operationType, String operationContent) {
// 获取当前用户
String operatorId = "SYSTEM";
String operatorName = "系统";
try {
SysUser currentUser = ShiroUtils.getSysUser();
if (currentUser != null) {
operatorId = currentUser.getUserId().toString();
operatorName = currentUser.getUserName();
}
} catch (Exception e) {
log.warn("获取当前用户失败,使用系统默认值", e);
}
// 调用重载方法
recordLog(artistId, operationType, operationContent, operatorId, operatorName);
}
@Override
public void recordLog(String artistId, Integer operationType, String operationContent, String operatorId, String operatorName) {
try {
// 保存操作日志
KylinArtistOperationLog operLog = new KylinArtistOperationLog();
operLog.setLogId(IDGenerator.nextSnowId());
operLog.setArtistId(artistId);
operLog.setOperationType(operationType);
operLog.setOperationContent(operationContent);
operLog.setOperatorId(operatorId);
operLog.setOperatorName(operatorName);
operLog.setCreatedAt(LocalDateTime.now());
baseMapper.insert(operLog);
log.info("艺人操作日志记录成功: artistId={}, operationType={}, operator={}", artistId, operationType, operatorName);
} catch (Exception e) {
// 日志记录失败不影响主业务
log.error("保存艺人操作日志失败", e);
}
}
@Override
public PageInfo<KylinArtistOperationLogDao> getOperationLogs(String artistId, Integer pageNum, Integer pageSize) {
try {
PageHelper.startPage(pageNum != null ? pageNum : 1, pageSize != null ? pageSize : 10);
List<KylinArtistOperationLogDao> list = baseMapper.selectLogsByArtistId(artistId);
return new PageInfo<>(list);
} catch (Exception e) {
log.error("获取艺人操作记录失败, artistId: {}", artistId, e);
return new PageInfo<>();
}
}
}
package com.liquidnet.client.admin.zhengzai.kylin.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.client.admin.zhengzai.kylin.utils.DataUtils;
import com.liquidnet.service.kylin.dao.KylinArtistAssociationStatusDto;
import com.liquidnet.service.kylin.dao.KylinArtistPerformanceDao;
import com.liquidnet.service.kylin.entity.KylinArtist;
import com.liquidnet.service.kylin.entity.KylinArtistPerformance;
import com.liquidnet.service.kylin.mapper.KylinArtistMapper;
import com.liquidnet.service.kylin.mapper.KylinArtistPerformanceMapper;
import com.liquidnet.service.kylin.service.admin.IKylinArtistPerformanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.HashMap;
import java.util.stream.Collectors;
import com.liquidnet.service.kylin.service.admin.IKylinArtistOperationLogService;
@Slf4j
@Service
public class KylinArtistPerformanceServiceImpl extends ServiceImpl<KylinArtistPerformanceMapper, KylinArtistPerformance> implements IKylinArtistPerformanceService {
@Autowired
private KylinArtistPerformanceMapper artistPerformanceMapper;
@Autowired
private KylinArtistMapper artistMapper;
@Autowired
private DataUtils dataUtils;
@Autowired
private IKylinArtistOperationLogService operationLogService;
@Override
public List<KylinArtistPerformanceDao> getSessionArtists(String performancesId, String timesId) {
// 查询该场次的艺人
return artistPerformanceMapper.selectArtistsByPerformanceAndTimes(
performancesId, timesId
);
}
@Override
public boolean updateArtistOrder(String performanceId, List<Map<String, Object>> orderData) {
// 更新每个艺人的排序
for (Map<String, Object> item : orderData) {
Long mid = Long.valueOf(item.get("mid").toString());
Integer sort = Integer.valueOf(item.get("sort").toString());
log.info("[updateArtistOrder] mid: {}, sort: {}", mid, sort);
KylinArtistPerformance entity = artistPerformanceMapper.selectById(mid);
if (entity != null) {
entity.setSort(sort);
artistPerformanceMapper.updateById(entity);
}
}
// 删除缓存演出阵容
dataUtils.delPerformanceArtists(performanceId);
return true;
}
@Override
public int deletePerformanceArtist(Long mid, String performanceId) {
KylinArtistPerformance association = artistPerformanceMapper.selectById(mid);
if (association == null) {
return 0;
}
String artistId = association.getArtistId();
// 记录删除前的关联数量
Integer beforeCount = artistPerformanceMapper.selectCount(new QueryWrapper<KylinArtistPerformance>().eq("artist_id", artistId));
beforeCount = beforeCount == null ? 0 : beforeCount;
// 删除缓存演出阵容
dataUtils.delPerformanceArtists(performanceId);
int result = artistPerformanceMapper.deleteById(mid);
// 记录删除后的关联数量
Integer afterCount = artistPerformanceMapper.selectCount(new QueryWrapper<KylinArtistPerformance>().eq("artist_id", artistId));
afterCount = afterCount == null ? 0 : afterCount;
if (!beforeCount.equals(afterCount)) {
String logContent = String.format("更新关联演出数量:从[%d]场改为[%d]场,", beforeCount, afterCount);
operationLogService.recordLog(artistId, 2, logContent);
}
return result;
}
@Override
public List<KylinArtistAssociationStatusDto> getAllArtists(String performancesId, String timesId, String keyword) {
// 1. 获取所有艺人
List<KylinArtist> allArtists = artistMapper.selectList(new QueryWrapper<KylinArtist>()
.like(keyword != null && !keyword.isEmpty(), "artist_name", keyword)
.orderByDesc("created_at"));
// 2. 获取当前场次已关联的艺人,用 Map 保留各自的 sort 值
List<KylinArtistPerformanceDao> associatedArtists =
artistPerformanceMapper.selectArtistsByPerformanceAndTimes(performancesId, timesId);
// key: artistId value: 演出关联表中的 sort(越大越靠前)
Map<String, Integer> associatedSortMap = associatedArtists.stream()
.collect(Collectors.toMap(
KylinArtistPerformanceDao::getArtistId,
KylinArtistPerformanceDao::getSort,
(existing, replacement) -> existing // 重复 key 保留已有值
));
// 3. 组装返回结果
List<KylinArtistAssociationStatusDto> resultList = allArtists.stream().map(artist -> {
KylinArtistAssociationStatusDto dto = new KylinArtistAssociationStatusDto();
dto.setArtistId(artist.getArtistId());
dto.setArtistName(artist.getArtistName());
dto.setAvatarUrl(artist.getAvatarUrl());
boolean associated = associatedSortMap.containsKey(artist.getArtistId());
dto.setAssociated(associated);
// sort 取演出关联表的值;未关联的艺人 sort 置 0
dto.setSort(associated ? associatedSortMap.get(artist.getArtistId()) : 0);
return dto;
}).collect(Collectors.toList());
return resultList;
}
@Override
public boolean updateArtistAssociations(String performancesId, String timesId, List<Map<String, Object>> artistOrders) {
// 先查询该演出、场次下关联的旧艺人
List<KylinArtistPerformance> oldAssociations = artistPerformanceMapper.selectList(new QueryWrapper<KylinArtistPerformance>()
.eq("performances_id", performancesId)
.eq("times_id", timesId));
Set<String> affectedArtistIds = new HashSet<>(); // 旧关联的艺人ID set
if (oldAssociations != null) {
for (KylinArtistPerformance a : oldAssociations) {
affectedArtistIds.add(a.getArtistId());
}
}
if (artistOrders != null && !artistOrders.isEmpty()) {
for (Map<String, Object> item : artistOrders) {
String artistId = (String) item.get("artistId");
if (artistId != null) {
affectedArtistIds.add(artistId);
}
}
}
// Record before counts
Map<String, Integer> beforeCounts = new HashMap<>();
for (String artistId : affectedArtistIds) {
Integer count = artistPerformanceMapper.selectCount(new QueryWrapper<KylinArtistPerformance>().eq("artist_id", artistId));
beforeCounts.put(artistId, count == null ? 0 : count);
}
// 1. 删除当前场次所有已关联的艺人
artistPerformanceMapper.delete(new QueryWrapper<KylinArtistPerformance>()
.eq("performances_id", performancesId)
.eq("times_id", timesId));
// 2. 按前端传入的顺序重新关联,sort 越大越靠前
if (artistOrders != null && !artistOrders.isEmpty()) {
for (Map<String, Object> item : artistOrders) {
String artistId = (String) item.get("artistId");
Integer sort = item.get("sort") != null
? Integer.parseInt(item.get("sort").toString()) : 0;
KylinArtistPerformance newAssociation = new KylinArtistPerformance();
newAssociation.setPerformancesId(performancesId);
newAssociation.setTimesId(timesId);
newAssociation.setArtistId(artistId);
newAssociation.setSort(sort);
artistPerformanceMapper.insert(newAssociation);
}
}
// 3. Compare and log
for (String artistId : affectedArtistIds) {
Integer afterCount = artistPerformanceMapper.selectCount(new QueryWrapper<KylinArtistPerformance>().eq("artist_id", artistId));
afterCount = afterCount == null ? 0 : afterCount;
Integer beforeCount = beforeCounts.get(artistId);
if (!beforeCount.equals(afterCount)) {
String logContent = String.format("更新关联演出数量:从[%d]场改为[%d]场,", beforeCount, afterCount);
operationLogService.recordLog(artistId, 2, logContent);
}
}
// 删除缓存演出阵容
dataUtils.delPerformanceArtists(performancesId);
return true;
}
}
......@@ -621,4 +621,14 @@ public class DataUtils {
public static ArrayList<KylinOrderCoupons> getKylinOrderCouponsArrayList() {
return (ArrayList<KylinOrderCoupons>) kylinOrderCouponsArrayList.clone();
}
/**
* 删除演出阵容 缓存
* @param performancesId
*/
public void delPerformanceArtists(String performancesId) {
final String redisKey = KylinRedisConst.PERFORMANCES_ARTISTS + performancesId;
redisDataSourceUtil.getRedisKylinUtil().del(redisKey);
}
}
......@@ -53,4 +53,7 @@ public class RedisKeyExpireConst {
public static final long GOBLIN_BRACELET_USER_EXPIRE = 30 * 24 * 60 * 60;
// GOBLIN_BRACELET_RELATED_ORDER 过期30天
public static final long GOBLIN_BRACELET_RELATED_ORDER_EXPIRE = 30 * 24 * 60 * 60;
// 演出关联阵容缓存过期时间
public static final long PERFORMANCES_ARTISTS_EXPIRE = 30 * 24 * 60 * 60;
}
......@@ -58,8 +58,8 @@ info:
artifactId: '@project.artifactId@'
version: '@project.version@'
# -----------------------------------------------------------
#mybatis-plus:
# mapper-locations: classpath*:com.liquidnet.service.*.mapper/*Mapper.xml
mybatis-plus:
mapper-locations: classpath*:com.liquidnet.service.*.mapper/*Mapper.xml
# -----------------------------------------------------------
spring:
application:
......@@ -159,6 +159,8 @@ global-auth:
- ${liquidnet.info.context}/luckyBag/code/**
# 健康检查
- ${liquidnet.info.context}/health
# 演出阵容
- ${liquidnet.info.context}/performance/artists/**
oncheck-url-pattern:
- ${liquidnet.info.context}/order/details
- ${liquidnet.info.context}/order/transfer*
......
package com.liquidnet.service.kylin.dao;
import lombok.Data;
@Data
public class KylinArtistAssociationStatusDto {
/**
* 艺人ID
*/
private String artistId;
/**
* 艺人名称
*/
private String artistName;
/**
* 艺人头像地址
*/
private String avatarUrl;
/**
* 是否关联
*/
private boolean isAssociated;
/**
* 排序 越大越靠前
*/
private int sort;
}
package com.liquidnet.service.kylin.dao;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 艺人管理DAO - 用于列表展示
* </p>
*
* @author liquidnet
* @since 2026-02-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class KylinArtistDao implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 艺人ID
*/
private String artistId;
/**
* 艺人名称
*/
private String artistName;
/**
* 艺人类型 1音乐人 2艺术家 3厂牌 4品牌方
*/
private Integer artistType;
/**
* 艺人类型名称
*/
private String artistTypeName;
/**
* 艺人头像
*/
private String avatarUrl;
/**
* 艺人简介
*/
private String introduction;
/**
* 关联演出数量
*/
private Integer performanceCount;
/**
* 关联商品数量
*/
private Integer productCount;
/**
* 创建时间(艺人入驻时间)
*/
private LocalDateTime createdAt;
}
package com.liquidnet.service.kylin.dao;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* <p>
* 艺人操作记录DAO
* </p>
*
* @author liquidnet
* @since 2026-03-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class KylinArtistOperationLogDao implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 操作类型 1新增 2编辑 3删除
*/
private Integer operationType;
/**
* 操作类型名称
*/
private String operationTypeName;
/**
* 操作时间
*/
private String createdAt;
/**
* 修改内容
*/
private String operationContent;
/**
* 操作人
*/
private String operatorName;
}
package com.liquidnet.service.kylin.dao;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
public class KylinArtistPerformanceDao implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 关联记录ID
*/
private Long mid;
/**
* 艺人ID
*/
private String artistId;
/**
* 艺人名称
*/
private String artistName;
/**
* 艺人头像
*/
private String avatarUrl;
/**
* 演出ID
*/
private String performanceId;
/**
* 演出标题
*/
private String title;
/**
* 演出开始时间
*/
private String timeStart;
/**
* 演出场次ID
*/
private String timesId;
/**
* 演出场次标题
*/
private String timeTitle;
/**
* 排序权重
*/
private Integer sort;
}
package com.liquidnet.service.kylin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 艺人管理表
* </p>
*
* @author liquidnet
* @since 2026-02-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class KylinArtist implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Integer mid;
/**
* 艺人ID
*/
private String artistId;
/**
* 艺人名称
*/
private String artistName;
/**
* 艺人类型 1音乐人 2艺术家 3厂牌 4品牌方
*/
private Integer artistType;
/**
* 艺人头像
*/
private String avatarUrl;
/**
* 艺人简介
*/
private String introduction;
/**
* 状态 1启用 0禁用
*/
private Integer status;
/**
* 排序权重
*/
private Integer sort;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 修改时间
*/
private LocalDateTime updatedAt;
private static final KylinArtist obj = new KylinArtist();
public static KylinArtist getNew() {
try {
return (KylinArtist) obj.clone();
} catch (CloneNotSupportedException e) {
return new KylinArtist();
}
}
}
package com.liquidnet.service.kylin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 艺人相册表
* </p>
*
* @author liquidnet
* @since 2026-02-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class KylinArtistAlbum implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Integer mid;
/**
* 相册ID
*/
private String albumId;
/**
* 艺人ID
*/
private String artistId;
/**
* 图片地址
*/
private String imageUrl;
/**
* 排序权重
*/
private Integer sort;
/**
* 状态 1启用 0禁用
*/
private Integer status;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 修改时间
*/
private LocalDateTime updatedAt;
private static final KylinArtistAlbum obj = new KylinArtistAlbum();
public static KylinArtistAlbum getNew() {
try {
return (KylinArtistAlbum) obj.clone();
} catch (CloneNotSupportedException e) {
return new KylinArtistAlbum();
}
}
}
package com.liquidnet.service.kylin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 艺人操作记录表
* </p>
*
* @author liquidnet
* @since 2026-03-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class KylinArtistOperationLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Long mid;
/**
* 日志ID
*/
private String logId;
/**
* 关联艺人ID
*/
private String artistId;
/**
* 操作类型 1新增 2编辑 3删除
*/
private Integer operationType;
/**
* 修改内容描述
*/
private String operationContent;
/**
* 操作人ID
*/
private String operatorId;
/**
* 操作人名称
*/
private String operatorName;
/**
* 操作时间
*/
private LocalDateTime createdAt;
}
package com.liquidnet.service.kylin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = false)
public class KylinArtistPerformance implements Serializable{
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Long mid;
/**
* 关联 kylin_artist.artist_id
*/
private String artistId;
/**
* 关联 kylin_performances.performances_id
*/
private String performancesId;
/**
* 场次ID
*/
private String timesId;
/**
* 该艺人在本演出中的排序权重,越大越靠前
*/
private Integer sort;
/**
*创建时间
*/
private LocalDateTime createdAt;
/**
*更新时间
*/
private LocalDateTime updatedAt;
}
package com.liquidnet.service.kylin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liquidnet.service.kylin.entity.KylinArtistAlbum;
import java.util.List;
public interface KylinArtistAlbumMapper extends BaseMapper<KylinArtistAlbum> {
/**
* 根据艺人ID查询相册列表
*/
List<KylinArtistAlbum> selectByArtistId(String artistId);
/**
* 根据艺人ID删除相册(逻辑删除)
*/
int deleteByArtistId(String artistId);
}
package com.liquidnet.service.kylin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liquidnet.service.kylin.dao.KylinArtistDao;
import com.liquidnet.service.kylin.entity.KylinArtist;
import java.util.List;
import java.util.Map;
public interface KylinArtistMapper extends BaseMapper<KylinArtist> {
/**
* 搜索艺人列表
*/
List<KylinArtistDao> searchArtistList(Map<String, Object> paramMap);
/**
* 根据艺人名称查询是否存在
*/
KylinArtist selectByArtistName(String artistName);
}
package com.liquidnet.service.kylin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liquidnet.service.kylin.dao.KylinArtistOperationLogDao;
import com.liquidnet.service.kylin.entity.KylinArtistOperationLog;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 艺人操作记录 Mapper 接口
* </p>
*
* @author liquidnet
* @since 2026-03-04
*/
public interface KylinArtistOperationLogMapper extends BaseMapper<KylinArtistOperationLog> {
/**
* 根据艺人ID查询操作记录列表
*
* @param artistId 艺人ID
* @return 操作记录列表
*/
List<KylinArtistOperationLogDao> selectLogsByArtistId(@Param("artistId") String artistId);
}
package com.liquidnet.service.kylin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liquidnet.service.kylin.dao.KylinArtistPerformanceDao;
import com.liquidnet.service.kylin.entity.KylinArtistPerformance;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface KylinArtistPerformanceMapper extends BaseMapper<KylinArtistPerformance> {
/**
* 根据艺人ID查询关联的演出信息
*
* @param artistId 艺人ID
* @return 演出信息列表
*/
List<KylinArtistPerformanceDao> selectPerformanceDaoByArtistId(@Param("artistId") String artistId);
/**
* 根据演出ID和场次ID查询艺人阵容
*
* @param performancesId 演出ID
* @param timesId 场次ID
* @return 艺人阵容列表
*/
List<KylinArtistPerformanceDao> selectArtistsByPerformanceAndTimes(@Param("performancesId") String performancesId, @Param("timesId") String timesId);
/**
* 根据艺人ID列表查询关联的演出ID列表
*
* @param artistIds 艺人ID集合
* @return 演出ID列表
*/
List<String> selectPerformanceIdsByArtistIds(@Param("artistIds") List<String> artistIds);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liquidnet.service.kylin.mapper.KylinArtistAlbumMapper">
<!-- 根据艺人ID查询相册列表 -->
<select id="selectByArtistId" parameterType="java.lang.String" resultType="com.liquidnet.service.kylin.entity.KylinArtistAlbum">
SELECT
mid,
album_id,
artist_id,
image_url,
sort,
status,
created_at,
updated_at
FROM kylin_artist_album
WHERE artist_id = #{artistId} AND status = 1
ORDER BY sort DESC, mid DESC
</select>
<!-- 根据艺人ID删除相册(逻辑删除) -->
<update id="deleteByArtistId" parameterType="java.lang.String">
UPDATE kylin_artist_album
SET status = 0, updated_at = NOW()
WHERE artist_id = #{artistId}
</update>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liquidnet.service.kylin.mapper.KylinArtistMapper">
<!-- 搜索艺人列表 -->
<select id="searchArtistList" parameterType="java.util.Map" resultType="com.liquidnet.service.kylin.dao.KylinArtistDao">
SELECT
a.artist_id,
a.artist_name,
a.artist_type,
CASE a.artist_type
WHEN 1 THEN '音乐人'
WHEN 2 THEN '艺术家'
WHEN 3 THEN '厂牌'
WHEN 4 THEN '品牌方'
ELSE '未知'
END as artist_type_name,
a.avatar_url,
a.introduction,
a.created_at,
(SELECT COUNT(1) FROM kylin_artist_performance ap WHERE ap.artist_id = a.artist_id) as performance_count,
0 as product_count
FROM kylin_artist a
<where>
a.status = 1
<if test="artistId != null and artistId != ''">
AND a.artist_id = #{artistId}
</if>
<if test="artistName != null and artistName != ''">
AND a.artist_name LIKE CONCAT('%', #{artistName}, '%')
</if>
<if test="artistType != null and artistType != ''">
AND a.artist_type = #{artistType}
</if>
<if test="beginDate != null and beginDate != ''">
AND DATE(a.created_at) &gt;= #{beginDate}
</if>
<if test="endDate != null and endDate != ''">
AND DATE(a.created_at) &lt;= #{endDate}
</if>
</where>
ORDER BY a.sort DESC, a.mid DESC
</select>
<!-- 根据艺人名称查询是否存在 -->
<select id="selectByArtistName" parameterType="java.lang.String" resultType="com.liquidnet.service.kylin.entity.KylinArtist">
SELECT * FROM kylin_artist
WHERE artist_name = #{artistName} AND status = 1
LIMIT 1
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liquidnet.service.kylin.mapper.KylinArtistOperationLogMapper">
<!-- 根据艺人ID查询操作记录列表 -->
<select id="selectLogsByArtistId" parameterType="java.lang.String" resultType="com.liquidnet.service.kylin.dao.KylinArtistOperationLogDao">
SELECT
operation_type as operationType,
CASE operation_type
WHEN 1 THEN '新增'
WHEN 2 THEN '编辑'
WHEN 3 THEN '删除'
ELSE '未知'
END as operationTypeName,
DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as createdAt,
operation_content as operationContent,
operator_name as operatorName
FROM kylin_artist_operation_log
WHERE artist_id = #{artistId}
ORDER BY created_at DESC
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liquidnet.service.kylin.mapper.KylinArtistPerformanceMapper">
<select id="selectPerformanceDaoByArtistId" parameterType="java.lang.String" resultType="com.liquidnet.service.kylin.dao.KylinArtistPerformanceDao">
SELECT
ap.mid,
ap.artist_id as artistId,
a.artist_name as artistName,
a.avatar_url as avatarUrl,
p.performances_id as performanceId,
p.title,
DATE_FORMAT(p.time_start, '%Y-%m-%d %H:%i:%s') as timeStart,
t.ticket_times_id as timesId,
t.title as timeTitle,
ap.sort
FROM kylin_artist_performance ap
INNER JOIN kylin_artist a ON ap.artist_id = a.artist_id
INNER JOIN kylin_performances p ON ap.performances_id = p.performances_id
INNER JOIN kylin_ticket_times t ON ap.times_id = t.ticket_times_id
WHERE ap.artist_id = #{artistId}
ORDER BY ap.sort DESC, p.time_start DESC
</select>
<!-- 根据艺人ID获取关联演出数量 -->
<!-- <select id="countPerformancesByArtistId" parameterType="java.lang.String" resultType="java.lang.Integer">-->
<!-- SELECT COUNT(1)-->
<!-- FROM kylin_artist_performance-->
<!-- WHERE artist_id = #{artistId}-->
<!-- AND status = 1-->
<!-- </select>-->
<!-- 根据演出ID和场次ID查询艺人阵容 -->
<select id="selectArtistsByPerformanceAndTimes" resultType="com.liquidnet.service.kylin.dao.KylinArtistPerformanceDao">
SELECT
ap.mid,
ap.artist_id as artistId,
ap.times_id as timesId,
ap.sort,
a.artist_name as artistName,
a.avatar_url as avatarUrl,
p.performances_id as performanceId,
p.title,
DATE_FORMAT(p.time_start, '%Y-%m-%d %H:%i:%s') as timeStart,
t.title as timeTitle
FROM kylin_artist_performance ap
INNER JOIN kylin_artist a ON ap.artist_id = a.artist_id
INNER JOIN kylin_performances p ON ap.performances_id = p.performances_id
INNER JOIN kylin_ticket_times t ON ap.times_id = t.ticket_times_id
WHERE ap.performances_id = #{performancesId}
<if test="timesId != null and timesId != ''">
AND ap.times_id = #{timesId}
</if>
ORDER BY ap.sort DESC, ap.created_at ASC
</select>
<!-- 根据艺人ID列表查询关联的演出ID列表 -->
<select id="selectPerformanceIdsByArtistIds" resultType="java.lang.String">
SELECT DISTINCT performances_id
FROM kylin_artist_performance
WHERE artist_id IN
<foreach collection="artistIds" item="artistId" open="(" separator="," close=")">
#{artistId}
</foreach>
</select>
</mapper>
......@@ -7,11 +7,11 @@ import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.kylin.dto.param.KylinCandyParam;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinCandyVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinPerformanceArtistLineupVo;
import com.liquidnet.service.kylin.dto.vo.returns.PayDetailVo;
import com.liquidnet.service.kylin.service.IKylinLackRegistersService;
import com.liquidnet.service.kylin.service.IKylinPerformancesService;
import com.liquidnet.service.kylin.service.impl.KylinPerformancesServiceImpl;
import com.liquidnet.service.kylin.utils.DataUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
......@@ -228,6 +228,20 @@ public class KylinPerformancesController {
}
}
@GetMapping("artists/{performancesId}")
@ApiOperation("演出艺人阵容及场次详情")
@ApiImplicitParams({
@ApiImplicitParam(type = "path", dataType = "String", name = "performancesId", value = "演出id", required = true)
})
public ResponseDto<List<KylinPerformanceArtistLineupVo>> performanceArtists(@PathVariable("performancesId") String performancesId) {
List<KylinPerformanceArtistLineupVo> result = kylinPerformancesService.performanceArtists(performancesId);
if (result != null) {
return ResponseDto.success(result);
} else {
return ResponseDto.failure(ErrorMapping.get("20700"));
}
}
@GetMapping("payDetail")
@ApiOperation("支付前详情")
@ApiImplicitParams({
......
......@@ -146,6 +146,7 @@ public class KylinTicketTimesPartnerServiceImpl implements IKylinTicketTimesPart
@Override
public ResponseDto<String> deleteTimes(String ticketTimesId, String performanceId) {
try {
redisSlimeUtils.delPerformanceArtists(performanceId);
LocalDateTime updatedAt = LocalDateTime.now();
KylinTicketTimesPartnerVo data = mongoSlimeUtils.getTicketTimesPartnerVo(ticketTimesId);
if (data.getStatus() == 0) {
......@@ -193,6 +194,7 @@ public class KylinTicketTimesPartnerServiceImpl implements IKylinTicketTimesPart
@Override
public ResponseDto<KylinTicketTimesPartnerVo> changeTimes(CreateTicketTimesParam createTicketTimesParam) {
try {
redisSlimeUtils.delPerformanceArtists(createTicketTimesParam.getPerformancesId());
LocalDateTime updatedAt = LocalDateTime.now();
String title = "";
if (createTicketTimesParam.getType() == 1) {
......
......@@ -332,4 +332,13 @@ public class RedisSlimeUtils {
String redisKey = KylinRedisConst.PERFORMANCES_NOTICE_REMIND_STATUS + performanceId;
redisUtil.set(redisKey, noticeRemindStatus);
}
/**
* 删除演出-场次阵容 缓存
* @param performancesId
*/
public void delPerformanceArtists(String performancesId) {
final String redisKey = KylinRedisConst.PERFORMANCES_ARTISTS + performancesId;
redisUtil.del(redisKey);
}
}
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