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

Commit 27870405 authored by 姜秀龙's avatar 姜秀龙

Merge branch 'master' into jxl_20240313_prod

# Conflicts:
#	liquidnet-bus-client/liquidnet-client-admin/liquidnet-client-admin-zhengzai/src/main/java/com/liquidnet/client/admin/zhengzai/kylin/service/impl/KylinDamaiServiceImpl.java
#	liquidnet-bus-config/liquidnet-config/liquidnet-service-kylin.yml
parents 3c328cd0 33e4675b
This diff is collapsed.
-- 需求文档: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
-- ----------------------------
-- 1. 护照实体表 (预先生成,供用户扫码绑定)
-- ----------------------------
CREATE TABLE `adam_caomei_passport` (
`mid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`passport_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '护照编号 (全局唯一,用于生成二维码)',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '绑定状态: 0-未绑定, 1-已绑定, 2-已作废',
`user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '绑定的用户ID',
`bound_at` datetime DEFAULT NULL COMMENT '首次绑定时间',
`unbound_at` datetime DEFAULT NULL COMMENT '最近一次解绑时间 (后台操作解绑时记录)',
`batch_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '生成/印刷批次号 (便于后期溯源管理)',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '后台运营备注',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`mid`),
UNIQUE KEY `uk_passport_no` (`passport_no`),
KEY `idx_user_id` (`user_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='草莓护照-实体编号表';
-- ----------------------------
-- 2. 徽章配置表 (运营后台配置,已移除 claimed_count,后台列表实时 COUNT 统计)
-- ----------------------------
CREATE TABLE `adam_caomei_badge` (
`mid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`badge_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '徽章ID',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '徽章名称',
`icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '徽章图标 (Emoji字符或图片URL)',
`type` tinyint(4) NOT NULL COMMENT '徽章类型: 1-护照纪念徽章, 2-演出纪念徽章, 3-特殊徽章',
`performance_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '关联演出ID (仅演出纪念徽章必填,其他类型为空)',
`display_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '上架状态: 0-下架(默认), 1-已发布',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`mid`),
KEY `idx_badge_id` (`badge_id`),
KEY `idx_type_status` (`type`,`display_status`),
KEY `idx_performance_id` (`performance_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='草莓护照-徽章配置表';
-- ----------------------------
-- 3. 用户徽章获得记录表 (支撑用户徽章墙与后台领取人数统计)
-- ----------------------------
CREATE TABLE `adam_caomei_user_badge` (
`mid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户id',
`badge_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '徽章ID',
`source` tinyint(4) NOT NULL COMMENT '获取途径: 1-绑定护照自动发放, 2-购票自动发放, 3-补签审核通过, 4-现场管理员手动发放',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '获得时间',
PRIMARY KEY (`mid`),
UNIQUE KEY `uk_user_badge` (`user_id`,`badge_id`) COMMENT '联合唯一索引: 同一用户同一徽章只能获得一次',
KEY `idx_badge_id` (`badge_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='草莓护照-用户徽章获得记录表';
-- ----------------------------
-- 4. 徽章补签申请记录表 (支撑补签审核流程)
-- ----------------------------
CREATE TABLE `adam_caomei_badge_apply_record` (
`mid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`apply_record_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '补签id',
`user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户id',
`badge_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '申请补签的徽章ID',
`performance_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '关联的演出ID (冗余字段,便于后台筛选)',
`proof_image_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单截图/凭证图片URL',
`audit_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '审核状态: 0-待审核, 1-已通过, 2-已驳回',
`reject_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '驳回理由 (驳回时必填,用户端可见)',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '申请时间',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '审核/更新时间',
PRIMARY KEY (`mid`),
KEY `idx_record_id`(`apply_record_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_audit_status` (`audit_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='草莓护照-徽章补签申请记录表';
-- 2026-04-13 新增排序字段
ALTER TABLE `adam_caomei_badge` ADD COLUMN `sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序值,数值越大越靠前' AFTER `display_status`;
-- 2026-04-16 新增分享文案字段
ALTER TABLE `adam_caomei_badge` ADD COLUMN `share_text` varchar(255) NOT NULL DEFAULT '' COMMENT '徽章分享文案' AFTER `sort`;
-- 2026-04-23 新增徽章副标题字段
ALTER TABLE `adam_caomei_badge` ADD COLUMN `sub_title` varchar(32) NOT NULL DEFAULT '' COMMENT '徽章副标题(最多20字)' AFTER `name`;
-- TODO 上线前需要运行:adam_caomei_passport_inserts_BATCH-CAOMEI-B1.sql
\ No newline at end of file
......@@ -20,6 +20,12 @@ public class AdamRedisConst {
public static final String INFO_THIRD_PARTY = PREFIX.concat("info:third_party:");
public static final String INFO_ENTERS = PREFIX.concat("info:enters:");
public static final String INFO_ADDRESSES = PREFIX.concat("info:addresses:");
public static final String INFO_CAOMEI_BADGE_PUBLISHED = PREFIX.concat("info:caomei:badge:published");
public static final String INFO_CAOMEI_BADGE_USER = PREFIX.concat("info:caomei:badge:user:");
/**
* 身份证号已支付演出ID列表(短缓存,缓解 kylin_order_ticket_entities 无身份证索引时的热点查询压力)
*/
public static final String INFO_CAOMEI_PAID_PERFORMANCE_IDS_BY_IDCARD = PREFIX.concat("info:caomei:paid_performance_ids:idcard:");
/**
* {adam:info:biz:{uid},List<com.liquidnet.service.adam.dto.vo.AdamUserBizAcctVo>}
*/
......@@ -36,6 +42,12 @@ public class AdamRedisConst {
*/
public static final String INFO_CERTIFICATION_JUNK = PREFIX.concat("info:certification_junk:");
/**
* 身份证号 -> 已绑定实名的 uid(用于快速判重:同一身份证只能实名一个账号)
* value: uid(String)
*/
public static final String INFO_REAL_NAME_UID_BY_IDCARD = PREFIX.concat("info:real_name:uid_by_idcard:");
public static final String INFO_MEMBER_JOINUS = PREFIX.concat("info:member:joinus:");
public static final String INFO_MEMBER_SIMPLE = PREFIX.concat("info:member:simple");
public static final String INFO_MEMBER_CATEGORY = PREFIX.concat("info:member:category:");
......
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("草莓护照-补签审核搜索参数")
public class AdamCaomeiBadgeApplyAuditSearchParam {
@ApiModelProperty(value = "用户名/姓名")
private String userName;
@ApiModelProperty(value = "审核状态:0-待审核 1-已通过 2-已驳回")
private Integer auditStatus;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel("草莓徽章-补签申请参数")
public class AdamCaomeiBadgeApplyParam {
@NotBlank(message = "徽章ID不能为空")
@ApiModelProperty(value = "徽章ID", required = true)
private String badgeId;
@NotBlank(message = "凭证图片不能为空")
@ApiModelProperty(value = "订单截图/凭证图片URL", required = true)
private String proofImageUrl;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
@ApiModel("草莓徽章-认领参数")
public class AdamCaomeiBadgeClaimParam {
@NotEmpty(message = "徽章ID列表不能为空")
@ApiModelProperty(value = "徽章ID列表", required = true)
private List<@NotBlank(message = "徽章ID不能为空") String> badgeIds;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("草莓护照-徽章领取用户搜索参数")
public class AdamCaomeiBadgeClaimUserSearchParam {
@ApiModelProperty(value = "徽章ID")
private String badgeId;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 草莓护照-徽章管理参数
*/
@Data
@ApiModel("草莓护照-徽章管理参数")
public class AdamCaomeiBadgeParam {
@ApiModelProperty(value = "主键ID")
private Long mid;
@ApiModelProperty(value = "徽章ID")
private String badgeId;
@ApiModelProperty(value = "徽章名称")
private String name;
@ApiModelProperty(value = "徽章副标题")
private String subTitle;
@ApiModelProperty(value = "徽章图标 (Emoji字符或图片URL)")
private String icon;
@ApiModelProperty(value = "徽章类型: 1-护照纪念徽章, 2-演出纪念徽章, 3-特殊徽章")
private Integer type;
@ApiModelProperty(value = "关联演出ID (仅演出纪念徽章必填,其他类型为空)")
private String performanceId;
@ApiModelProperty(value = "上架状态: 0-下架(默认), 1-已发布")
private Integer displayStatus;
@ApiModelProperty(value = "排序值,数值越大越靠前")
private Integer sort;
@ApiModelProperty(value = "徽章分享文案")
private String shareText;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 草莓护照-徽章搜索参数
*/
@Data
@ApiModel("草莓护照-徽章搜索参数")
public class AdamCaomeiBadgeSearchParam {
@ApiModelProperty(value = "徽章名称")
private String name;
@ApiModelProperty(value = "徽章类型: 1-护照纪念徽章, 2-演出纪念徽章, 3-特殊徽章")
private Integer type;
@ApiModelProperty(value = "上架状态: 0-下架(默认), 1-已发布")
private Integer displayStatus;
@ApiModelProperty(value = "添加时间起(yyyy-MM-dd)")
private String createdAtBegin;
@ApiModelProperty(value = "添加时间止(yyyy-MM-dd)")
private String createdAtEnd;
@ApiModelProperty(value = "当前页码")
private Integer pageNum = 1;
@ApiModelProperty(value = "每页数量")
private Integer pageSize = 10;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel("草莓护照-编号参数")
public class AdamCaomeiPassportNoParam {
@NotBlank(message = "护照编码不能为空")
@ApiModelProperty(value = "护照实体编号(扫码或手输)", required = true)
private String passportNo;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("草莓护照-护照管理搜索参数")
public class AdamCaomeiPassportSearchParam {
@ApiModelProperty(value = "护照编号")
private String passportNo;
@ApiModelProperty(value = "关联用户名(昵称/真实姓名模糊)")
private String userName;
@ApiModelProperty(value = "手机号")
private String mobile;
@ApiModelProperty(value = "证件号")
private String idCard;
@ApiModelProperty(value = "绑定状态:0-未绑定 1-已绑定 2-已作废,空为全部")
private Integer bindStatus;
}
package com.liquidnet.service.adam.dto.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("二要素认证参数")
public class AdamIdentityParam {
@ApiModelProperty(value = "姓名(手动填写时传)")
private String name;
@ApiModelProperty(value = "证件号(手动填写时传)")
private String idCard;
@ApiModelProperty(value = "入场人ID(选择观演人时传)")
private String entersId;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
@ApiModel("草莓护照-补签审核详情")
public class AdamCaomeiBadgeApplyAuditDetailVo {
@ApiModelProperty(value = "申请ID")
private String applyRecordId;
@ApiModelProperty(value = "申请账号")
private String userId;
@ApiModelProperty(value = "用户名")
private String nickname;
@ApiModelProperty(value = "姓名")
private String realName;
@ApiModelProperty(value = "证件号(脱敏)")
private String idCard;
@ApiModelProperty(value = "申请徽章ID")
private String badgeId;
@ApiModelProperty(value = "申请徽章")
private String badgeName;
@ApiModelProperty(value = "关联演出ID")
private String performanceId;
@ApiModelProperty(value = "关联演出")
private String performanceName;
@ApiModelProperty(value = "申请附件")
private String proofImageUrl;
@ApiModelProperty(value = "申请附件 URL 列表(解析自原始字段)")
private List<String> proofImageUrls;
@ApiModelProperty(value = "审核状态:0-待审核 1-已通过 2-已驳回")
private Integer auditStatus;
@ApiModelProperty(value = "驳回理由")
private String rejectReason;
@ApiModelProperty(value = "申请时间")
private Date createdAt;
@ApiModelProperty(value = "审核时间")
private Date updatedAt;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
@ApiModel("草莓护照-补签审核列表")
public class AdamCaomeiBadgeApplyAuditVo {
@ApiModelProperty(value = "申请ID")
private String applyRecordId;
@ApiModelProperty(value = "申请账号")
private String userId;
@ApiModelProperty(value = "用户名")
private String nickname;
@ApiModelProperty(value = "姓名")
private String realName;
@ApiModelProperty(value = "证件号(脱敏)")
private String idCard;
@ApiModelProperty(value = "申请徽章")
private String badgeName;
@ApiModelProperty(value = "关联演出")
private String performanceName;
@ApiModelProperty(value = "申请附件")
private String proofImageUrl;
@ApiModelProperty(value = "申请附件 URL 列表(解析自原始字段)")
private List<String> proofImageUrls;
@ApiModelProperty(value = "审核状态:0-待审核 1-已通过 2-已驳回")
private Integer auditStatus;
@ApiModelProperty(value = "申请时间")
private Date createdAt;
}
package com.liquidnet.service.adam.dto.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.liquidnet.commons.lang.util.DateUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("草莓徽章-补签记录(用户端)")
public class AdamCaomeiBadgeApplyRecordUserVo {
@ApiModelProperty("补签申请ID")
private String applyRecordId;
@ApiModelProperty("申请徽章名称")
private String badgeName;
@ApiModelProperty("申请时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateUtil.DATE_FULL_STR)
private Date applyTime;
@ApiModelProperty("审核状态:0-待审核 1-已通过 2-已驳回")
private Integer auditStatus;
@ApiModelProperty("驳回理由")
private String rejectReason;
@ApiModelProperty("是否可重新上传(仅驳回状态为 true)")
private Boolean canReupload;
@ApiModelProperty("凭证图片")
private String proofImageUrl;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("草莓护照-徽章领取用户")
public class AdamCaomeiBadgeClaimUserVo {
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "手机号(脱敏)")
private String mobile;
@ApiModelProperty(value = "领取时间")
private Date claimedAt;
@ApiModelProperty(value = "获取途径: 1-绑定护照自动发放, 2-购票自动发放, 3-补签审核通过, 4-现场管理员手动发放")
private Integer source;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* 草莓护照-徽章视图对象
*/
@Data
@ApiModel("草莓护照-徽章视图对象")
public class AdamCaomeiBadgeVo {
@ApiModelProperty(value = "主键ID")
private Long mid;
@ApiModelProperty(value = "徽章ID")
private String badgeId;
@ApiModelProperty(value = "徽章名称")
private String name;
@ApiModelProperty(value = "徽章副标题")
private String subTitle;
@ApiModelProperty(value = "徽章图标 (Emoji字符或图片URL)")
private String icon;
@ApiModelProperty(value = "徽章类型: 1-护照纪念徽章, 2-演出纪念徽章, 3-特殊徽章")
private Integer type;
@ApiModelProperty(value = "关联演出ID")
private String performanceId;
@ApiModelProperty(value = "上架状态: 0-下架(默认), 1-已发布")
private Integer displayStatus;
@ApiModelProperty(value = "排序值,数值越大越靠前")
private Integer sort;
@ApiModelProperty(value = "徽章分享文案")
private String shareText;
@ApiModelProperty(value = "添加时间")
private Date createdAt;
@ApiModelProperty(value = "更新时间")
private Date updatedAt;
@ApiModelProperty(value = "领取人数")
private Integer claimedCount;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("草莓护照-用户已领徽章项")
public class AdamCaomeiPassportBadgeItemVo {
@ApiModelProperty(value = "徽章ID")
private String badgeId;
@ApiModelProperty(value = "徽章名称")
private String badgeName;
@ApiModelProperty(value = "图标")
private String icon;
@ApiModelProperty(value = "领取时间")
private Date claimedAt;
@ApiModelProperty(value = "获取途径 source")
private Integer source;
}
package com.liquidnet.service.adam.dto.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.liquidnet.commons.lang.util.DateUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("草莓护照-货架徽章项(含认领状态与交互提示)")
public class AdamCaomeiPassportBadgeShelfItemVo {
@ApiModelProperty("徽章ID")
private String badgeId;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("副标题")
private String subTitle;
@ApiModelProperty("图标")
private String icon;
@ApiModelProperty("分享文案")
private String shareText;
@ApiModelProperty("类型 1护照 2演出 3特殊")
private Integer type;
@ApiModelProperty("关联演出ID(演出纪念徽章)")
private String performanceId;
@ApiModelProperty("关联演出名称(type=2 时用于按演出分组展示;无数据时可能为演出ID)")
private String performanceName;
@ApiModelProperty("是否已认领")
private boolean claimed;
@ApiModelProperty("认领时间(未认领为空)")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateUtil.DATE_FULL_STR)
private Date claimedAt;
@ApiModelProperty("是否可认领(护照徽章未发放完全,或演出徽章有票未领)")
private boolean claimable;
@ApiModelProperty("是否存在补签待审核(仅演出徽章生效)")
private boolean applyPending;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
@ApiModel("草莓护照-护照详情")
public class AdamCaomeiPassportDetailVo {
@ApiModelProperty(value = "护照主键")
private Long mid;
@ApiModelProperty(value = "护照编号")
private String passportNo;
@ApiModelProperty(value = "绑定状态")
private Integer status;
@ApiModelProperty(value = "绑定用户uid")
private String userId;
@ApiModelProperty(value = "首次绑定时间")
private Date boundAt;
@ApiModelProperty(value = "批次号")
private String batchNo;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "手机号(脱敏)")
private String mobile;
@ApiModelProperty(value = "真实姓名")
private String realName;
@ApiModelProperty(value = "证件号(脱敏)")
private String idCard;
@ApiModelProperty(value = "已领取徽章")
private List<AdamCaomeiPassportBadgeItemVo> badges;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel("草莓护照-C端首页聚合")
public class AdamCaomeiPassportHomeVo {
@ApiModelProperty("个人信息卡片")
private AdamCaomeiPassportUserCardVo userCard;
@ApiModelProperty("已认领徽章(全部获得记录,用于网格墙)")
private List<AdamCaomeiPassportUserClaimedBadgeVo> claimedBadges;
@ApiModelProperty("全部上架徽章(扁平列表;演出类含 performanceName,前端可按类型或按演出分组展示)")
private List<AdamCaomeiPassportBadgeShelfItemVo> allBadges;
}
package com.liquidnet.service.adam.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("草莓护照-护照管理列表")
public class AdamCaomeiPassportListVo {
@ApiModelProperty(value = "主键")
private Long mid;
@ApiModelProperty(value = "护照ID/编号")
private String passportNo;
@ApiModelProperty(value = "关联用户昵称")
private String nickname;
@ApiModelProperty(value = "真实姓名")
private String realName;
@ApiModelProperty(value = "手机号(脱敏)")
private String mobile;
@ApiModelProperty(value = "证件号(脱敏)")
private String idCard;
@ApiModelProperty(value = "绑定状态 0未绑定 1已绑定 2已作废")
private Integer bindStatus;
@ApiModelProperty(value = "已领取徽章数")
private Integer claimedBadgeCount;
}
package com.liquidnet.service.adam.dto.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.liquidnet.commons.lang.util.DateUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("草莓护照-首页个人信息卡片")
public class AdamCaomeiPassportUserCardVo {
@ApiModelProperty("头像")
private String avatar;
@ApiModelProperty("昵称")
private String nickname;
@ApiModelProperty("是否已实名认证")
private boolean realNameVerified;
@ApiModelProperty("护照编号(未绑定时为空)")
private String passportNo;
@ApiModelProperty("护照获得时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateUtil.DATE_FULL_STR)
private Date passportClaimedAt;
@ApiModelProperty("是否已绑定实体护照")
private boolean passportBound;
}
package com.liquidnet.service.adam.dto.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.liquidnet.commons.lang.util.DateUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@ApiModel("草莓护照-已认领徽章(墙)")
public class AdamCaomeiPassportUserClaimedBadgeVo {
@ApiModelProperty("徽章ID")
private String badgeId;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("副标题")
private String subTitle;
@ApiModelProperty("图标")
private String icon;
@ApiModelProperty("分享文案")
private String shareText;
@ApiModelProperty("类型 1护照类型徽章 2演出类型徽章 3特殊徽章")
private Integer type;
@ApiModelProperty("关联演出名称(仅 type=2 有值)")
private String performanceName;
@ApiModelProperty("获得时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateUtil.DATE_FULL_STR)
private Date claimedAt;
@ApiModelProperty("获取途径: 1-绑定护照自动发放, 2-购票自动发放, 3-补签审核通过, 4-现场管理员手动发放")
private Integer source;
}
package com.liquidnet.service.adam.service;
import com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeApplyParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyRecordUserVo;
import com.liquidnet.service.base.ResponseDto;
import java.util.List;
/**
* 草莓徽章(用户端)
*/
public interface IAdamCaomeiBadgeUserService {
/**
* 认领徽章
*/
ResponseDto<List<String>> claimBadges(List<String> badgeIds, String uid);
/**
* 补签申请记录列表(用户端)
*/
ResponseDto<List<AdamCaomeiBadgeApplyRecordUserVo>> getApplyRecords(String uid);
/**
* 发起补签申请(驳回后可再次提交)
*/
ResponseDto<String> applyBadge(AdamCaomeiBadgeApplyParam param, String uid);
}
package com.liquidnet.service.adam.service;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportHomeVo;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportUserClaimedBadgeVo;
import com.liquidnet.service.base.ResponseDto;
import java.util.List;
/**
* 草莓护照(用户端)
*/
public interface IAdamCaomeiPassportUserService {
/**
* 绑定实体护照:校验编号有效性、是否可绑;通过则写入并发放已上架护照纪念徽章(type=1)
*/
ResponseDto<List<AdamCaomeiPassportUserClaimedBadgeVo>> bindPassport(String passportNo);
/**
* 护照首页:个人信息、实名状态、已认领墙、按类型分组的全部上架徽章
*/
ResponseDto<AdamCaomeiPassportHomeVo> getPassportHome();
/**
* 校验当前登录用户是否已绑定护照
*/
ResponseDto<Boolean> checkPassportBound();
}
......@@ -72,4 +72,13 @@ public interface IAdamUserService {
AdamRealInfoVo identityForUpsert(String uid, String name, String idCard, String mobile, boolean updateFlg);
AdamRealInfoVo identityForUpdate(String uid, String mobile, int idType, int node, String idCard, String idName);
/**
* 二要素认证
* @param uid
* @param name
* @param idCard
* @return
*/
AdamRealInfoVo verifyTwoElements(String uid, String name, String idCard);
}
......@@ -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;
......@@ -32,33 +33,42 @@ public interface IKylinPerformancesService {
ResponseDto<Integer> isSubscribe(String performancesId);
ResponseDto<List<KylinCandyVo>> kylinCandy(List<KylinCandyItemParam> data, String roadShowId);
/**
* 演出预约
*
* @param param
* @author zjp
* @param param
* @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 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);
/*
* @description:删除预约演出票种
* @author: zjp
* @date: 2024/5/15 14:10
* @param:
* @return:
* @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);
}
package com.liquidnet.service.kylin.service.other;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.kylin.entity.KylinTicketTimes;
import com.liquidnet.service.kylin.entity.KylinTickets;
......@@ -15,4 +16,7 @@ public interface DamaiService {
//订单
Boolean sycOrder(long timeId, String ticketsId, long ticketsmId,long ticketIdMemberKey);
//定时同步大麦(扫描所有开启同步的演出)
ResponseDto<Boolean> scheduledSyncDamai();
}
......@@ -126,6 +126,18 @@ public class BaseController
return rspData;
}
/**
* 响应分页数据(用于查询结果已转为 VO 列表,但需保留 PageHelper 总条数的场景)
*/
protected TableDataInfo getDataTable(PageInfo<?> pageInfo)
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(0);
rspData.setRows(pageInfo.getList());
rspData.setTotal(pageInfo.getTotal());
return rspData;
}
/**
* 响应返回结果
*
......
package com.liquidnet.client.admin.web.controller.zhengzai.adam;
import com.github.pagehelper.PageInfo;
import com.liquidnet.client.admin.common.annotation.Log;
import com.liquidnet.client.admin.common.core.controller.BaseController;
import com.liquidnet.client.admin.common.core.domain.AjaxResult;
import com.liquidnet.client.admin.common.core.page.TableDataInfo;
import com.liquidnet.client.admin.common.enums.BusinessType;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamCaomeiBadgeApplyAuditAdminService;
import com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeApplyAuditSearchParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyAuditDetailVo;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Api(tags = "草莓护照-补签审核")
@Controller
@RequestMapping("adam/caomei/badgeApplyAudit")
public class AdamCaomeiBadgeApplyAuditController extends BaseController {
private final String prefix = "zhengzai/adam/caomei/badgeApplyAudit";
@Autowired
private IAdamCaomeiBadgeApplyAuditAdminService badgeApplyAuditAdminService;
@RequiresPermissions("adam:caomei:badgeApplyAudit:list")
@GetMapping()
public String view() {
return prefix + "/list";
}
@RequiresPermissions("adam:caomei:badgeApplyAudit:list")
@PostMapping("list")
@ResponseBody
public TableDataInfo list(AdamCaomeiBadgeApplyAuditSearchParam param) {
startPage();
PageInfo<?> pageInfo = badgeApplyAuditAdminService.listApplyAudits(param);
return getDataTable(pageInfo);
}
@RequiresPermissions("adam:caomei:badgeApplyAudit:list")
@GetMapping("detail/{applyRecordId}")
public String detail(@PathVariable("applyRecordId") String applyRecordId, ModelMap mmap) {
AdamCaomeiBadgeApplyAuditDetailVo detail = badgeApplyAuditAdminService.getApplyAuditDetail(applyRecordId);
mmap.put("detail", detail);
return prefix + "/detail";
}
@RequiresPermissions("adam:caomei:badgeApplyAudit:edit")
@Log(title = "草莓护照-补签审核:通过", businessType = BusinessType.UPDATE)
@PostMapping("pass")
@ResponseBody
public AjaxResult pass(@RequestParam("applyRecordId") String applyRecordId) {
boolean ok = badgeApplyAuditAdminService.passApplyAudit(applyRecordId);
if (!ok) {
return error("审核通过失败:申请不存在或当前状态不可操作");
}
return success();
}
@RequiresPermissions("adam:caomei:badgeApplyAudit:edit")
@Log(title = "草莓护照-补签审核:驳回", businessType = BusinessType.UPDATE)
@PostMapping("reject")
@ResponseBody
public AjaxResult reject(@RequestParam("applyRecordId") String applyRecordId,
@RequestParam("rejectReason") String rejectReason) {
if (StringUtils.isBlank(rejectReason)) {
return error("驳回理由不能为空");
}
boolean ok = badgeApplyAuditAdminService.rejectApplyAudit(applyRecordId, rejectReason);
if (!ok) {
return error("驳回失败:申请不存在或当前状态不可操作");
}
return success();
}
}
package com.liquidnet.client.admin.web.controller.zhengzai.adam;
import com.liquidnet.client.admin.common.annotation.Log;
import com.liquidnet.client.admin.common.core.controller.BaseController;
import com.liquidnet.client.admin.common.core.domain.AjaxResult;
import com.liquidnet.client.admin.common.core.page.TableDataInfo;
import com.liquidnet.client.admin.common.enums.BusinessType;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamCaomeiPassportAdminService;
import com.liquidnet.service.adam.dto.param.AdamCaomeiPassportSearchParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportDetailVo;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
@Api(tags = "草莓护照-护照管理")
@Controller
@RequestMapping("adam/caomei/passport")
public class AdamCaomeiPassportController extends BaseController {
private final String prefix = "zhengzai/adam/caomei/passport";
@Autowired
private IAdamCaomeiPassportAdminService adamCaomeiPassportAdminService;
@RequiresPermissions("adam:caomei:passport:list")
@GetMapping()
public String view() {
return prefix + "/passport_list";
}
@RequiresPermissions("adam:caomei:passport:list")
@PostMapping("list")
@ResponseBody
public TableDataInfo list(AdamCaomeiPassportSearchParam param) {
startPage();
PageInfo<?> pageInfo = adamCaomeiPassportAdminService.listPassports(param);
return getDataTable(pageInfo);
}
@RequiresPermissions("adam:caomei:passport:list")
@GetMapping("bound/count")
@ResponseBody
public AjaxResult boundCount() {
return AjaxResult.success(adamCaomeiPassportAdminService.countBoundPassports());
}
@RequiresPermissions("adam:caomei:passport:list")
@GetMapping("detail/{passportNo}")
public String detail(@PathVariable("passportNo") String passportNo, ModelMap mmap) {
AdamCaomeiPassportDetailVo detail = adamCaomeiPassportAdminService.getPassportDetail(passportNo);
mmap.put("detail", detail);
return prefix + "/passport_detail";
}
@RequiresPermissions("adam:caomei:passport:edit")
@Log(title = "草莓护照-护照解绑", businessType = BusinessType.UPDATE)
@PostMapping("unbind")
@ResponseBody
public AjaxResult unbind(@RequestParam("passportNo") String passportNo) {
boolean ok = adamCaomeiPassportAdminService.unbindPassport(passportNo);
if (!ok) {
return error("解绑失败:护照不存在或当前未绑定用户");
}
return success();
}
}
......@@ -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" >
<head>
<th:block th:include="include :: header('新增徽章')" />
<th:block th:include="include :: bootstrap-fileinput-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-badge-add">
<div class="form-group">
<label class="col-sm-3 control-label is-required">徽章名称:</label>
<div class="col-sm-8">
<input name="name" class="form-control" type="text" maxlength="50" required placeholder="最多50个字">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">徽章副标题:</label>
<div class="col-sm-8">
<input name="subTitle" class="form-control" type="text" maxlength="20" placeholder="最多20个字">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">徽章图标:</label>
<div class="col-sm-8">
<input type="hidden" name="icon" id="badgeIconUrl" value="">
<div id="badgeIconPreviewWrap" class="m-b" style="display:none;">
<img id="badgeIconPreview" src="" alt="预览" style="max-height:96px;border-radius:4px;border:1px solid #eee;"/>
</div>
<div class="file-loading">
<input id="fileinput-badge-icon" type="file" name="file" data-browse-on-zone-click="true">
</div>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 支持 jpg、png、gif、webp,单张最大 5M;上传后自动保存为图片地址。</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">徽章类型:</label>
<div class="col-sm-8">
<select name="type" class="form-control m-b" required onchange="typeChange(this.value)">
<option value="">请选择</option>
<option value="1">护照纪念徽章</option>
<option value="2">演出纪念徽章</option>
<!-- <option value="3">特殊徽章</option> -->
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">排序:</label>
<div class="col-sm-8">
<input name="sort" class="form-control" type="number" min="0" value="0" placeholder="数值越大越靠前">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">分享文案:</label>
<div class="col-sm-8">
<textarea name="shareText" class="form-control" rows="3" maxlength="255" placeholder="请输入徽章分享文案"></textarea>
</div>
</div>
<div class="form-group" id="ticketTimesDiv" style="display: none;">
<label class="col-sm-3 control-label is-required">关联演出:</label>
<div class="col-sm-8">
<input name="performanceId" id="performanceId" class="form-control" type="text" placeholder="请输入演出ID">
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 演出纪念徽章必填</span>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: bootstrap-fileinput-js" />
<script type="text/javascript" th:inline="javascript">
var prefix = ctx + "adam/caomei/badge";
var platformUrl = /*[[${platformUrl}]]*/ '';
function typeChange(val) {
if (val == 2) {
$("#ticketTimesDiv").show();
$("#performanceId").prop("required", true);
} else {
$("#ticketTimesDiv").hide();
$("#performanceId").prop("required", false);
$("#performanceId").val("");
}
}
$("#form-badge-add").validate({
focusCleanup: true
});
function submitHandler() {
if (!$("#badgeIconUrl").val()) {
$.modal.msgWarning("请先上传徽章图标");
return;
}
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-badge-add').serialize());
}
}
$(function () {
$("#fileinput-badge-icon").fileinput({
'theme': 'explorer-fas',
'uploadUrl': platformUrl + "/platform/basicServices/alOss/upload/unsm",
"uploadExtraData": {
"pathName": "other",
"buckType": 1
},
autoReplace: true,
dropZoneTitle: "点击或拖拽上传徽章图标",
maxFileCount: 1,
maxFileSize: 5120,
allowedFileExtensions: ['jpg', 'jpeg', 'png', 'gif', 'webp'],
msgSizeTooLarge: '文件 "{name}" ({size} KB) 超过了允许大小 {maxSize} KB,最大支持上传5M文件'
}).on("filebatchselected", function () {
$(this).fileinput("upload");
}).on("fileuploaded", function (event, data) {
if (!data.response || !data.response.data || !data.response.data.ossPath) {
$.modal.alertWarning((data.response && data.response.msg) ? data.response.msg : "图片上传失败");
return;
}
var fullUrl = "https://img.zhengzai.tv/" + data.response.data.ossPath;
$("#badgeIconUrl").val(fullUrl);
$("#badgeIconPreview").attr("src", fullUrl);
$("#badgeIconPreviewWrap").show();
});
});
</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">
<input type="hidden" id="badgeId" th:value="${badgeId}">
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "adam/caomei/badge";
$(function() {
var options = {
url: prefix + "/claimUsers/list",
queryParams: function(params) {
var curParams = {
pageSize: params.limit,
pageNum: params.offset / params.limit + 1,
searchValue: params.search,
orderByColumn: params.sort,
isAsc: params.order,
badgeId: $("#badgeId").val()
};
return curParams;
},
modalName: "领取用户",
columns: [
{
field: 'nickname',
title: '用户昵称'
},
{
field: 'mobile',
title: '手机号'
},
{
field: 'claimedAt',
title: '领取时间'
},
{
field: 'source',
title: '获取途径',
formatter: function(value, row, index) {
if (value == 1) return '绑定护照自动发放';
if (value == 2) return '购票自动发放';
if (value == 3) return '补签审核通过';
if (value == 4) return '现场管理员手动发放';
return '未知';
}
}
]
};
$.table.init(options);
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('徽章详情')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-badge-detail" th:object="${badge}">
<div class="form-group">
<label class="col-sm-3 control-label">徽章名称:</label>
<div class="col-sm-8">
<div class="form-control-static" th:text="*{name}"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">徽章副标题:</label>
<div class="col-sm-8">
<div class="form-control-static" th:text="*{subTitle != null and subTitle != '' ? subTitle : '-'}"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">徽章图标:</label>
<div class="col-sm-8">
<div class="form-control-static">
<span th:if="*{icon != null and (!icon.startsWith('http') and !icon.startsWith('/'))}" style="font-size: 24px;" th:text="*{icon}"></span>
<img th:if="*{icon != null and (icon.startsWith('http') or icon.startsWith('/'))}" th:src="*{icon}" style="max-height: 30px;"/>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">徽章类型:</label>
<div class="col-sm-8">
<div class="form-control-static" th:if="*{type == 1}">护照纪念徽章</div>
<div class="form-control-static" th:if="*{type == 2}">演出纪念徽章</div>
<div class="form-control-static" th:if="*{type == 3}">特殊徽章</div>
</div>
</div>
<div class="form-group" th:style="${badge.type == 2 ? 'display:block;' : 'display:none;'}">
<label class="col-sm-3 control-label">关联演出:</label>
<div class="col-sm-8">
<div class="form-control-static" th:text="*{performanceId}"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<div class="form-control-static" th:if="*{displayStatus == 1}">已发布</div>
<div class="form-control-static" th:if="*{displayStatus == 0}">下架</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">排序:</label>
<div class="col-sm-8">
<div class="form-control-static" th:text="*{sort}"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">分享文案:</label>
<div class="col-sm-8">
<div class="form-control-static" th:text="*{shareText}"></div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
$(function() {
// 隐藏底部的确认按钮,只保留关闭按钮
var index = parent.layer.getFrameIndex(window.name);
if (index) {
var $layero = parent.$("#layui-layer" + index);
$layero.find(".layui-layer-btn0").hide(); // 隐藏确认按钮
}
});
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改徽章')" />
<th:block th:include="include :: bootstrap-fileinput-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-badge-edit" th:object="${badge}">
<input name="badgeId" th:field="*{badgeId}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label is-required">徽章名称:</label>
<div class="col-sm-8">
<input name="name" th:field="*{name}" class="form-control" type="text" maxlength="50" required placeholder="最多50个字">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">徽章副标题:</label>
<div class="col-sm-8">
<input name="subTitle" th:field="*{subTitle}" class="form-control" type="text" maxlength="20" placeholder="最多20个字">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">徽章图标:</label>
<div class="col-sm-8">
<input type="hidden" name="icon" id="badgeIconUrl" th:value="*{icon}">
<div id="badgeIconPreviewWrap" class="m-b"
th:style="${badge.icon != null and (#strings.startsWith(badge.icon, 'http') or #strings.startsWith(badge.icon, '/'))} ? '' : 'display:none;'">
<img id="badgeIconPreview" alt="当前图标"
th:src="${badge.icon != null and (#strings.startsWith(badge.icon, 'http') or #strings.startsWith(badge.icon, '/'))} ? ${badge.icon} : ''"
style="max-height:96px;border-radius:4px;border:1px solid #eee;"/>
</div>
<p id="badgeIconLegacyHint" class="help-block"
th:if="${badge.icon != null and !(#strings.startsWith(badge.icon, 'http') or #strings.startsWith(badge.icon, '/'))}">
当前为 Emoji 文本:<strong th:text="${badge.icon}"></strong>,上传图片保存后将替换为图片地址。
</p>
<div class="file-loading">
<input id="fileinput-badge-icon" type="file" name="file" data-browse-on-zone-click="true">
</div>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 支持 jpg、png、gif、webp,单张最大 5M;重新上传将覆盖地址。</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">徽章类型:</label>
<div class="col-sm-8">
<input type="hidden" name="type" th:value="*{type}"/>
<select class="form-control m-b" disabled>
<option th:selected="${badge.type == 1}" value="1">护照纪念徽章</option>
<option th:selected="${badge.type == 2}" value="2">演出纪念徽章</option>
</select>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 徽章类型保存后不可修改</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">排序:</label>
<div class="col-sm-8">
<input name="sort" th:field="*{sort}" class="form-control" type="number" min="0" placeholder="数值越大越靠前">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">分享文案:</label>
<div class="col-sm-8">
<textarea name="shareText" th:field="*{shareText}" class="form-control" rows="3" maxlength="255" placeholder="请输入徽章分享文案"></textarea>
</div>
</div>
<div class="form-group" id="ticketTimesDiv" th:style="${badge.type == 2 ? 'display:block;' : 'display:none;'}">
<label class="col-sm-3 control-label is-required">关联演出:</label>
<div class="col-sm-8">
<input name="performanceId" id="performanceId" th:field="*{performanceId}" class="form-control" type="text" placeholder="请输入演出ID" th:required="${badge.type == 2}">
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 演出纪念徽章必填</span>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: bootstrap-fileinput-js" />
<script type="text/javascript" th:inline="javascript">
var prefix = ctx + "adam/caomei/badge";
var platformUrl = /*[[${platformUrl}]]*/ '';
function typeChange(val) {
if (val == 2 || val == '2') {
$("#ticketTimesDiv").show();
$("#performanceId").prop("required", true);
} else {
$("#ticketTimesDiv").hide();
$("#performanceId").prop("required", false);
$("#performanceId").val("");
}
}
$(function () {
typeChange($('input[name="type"]').val());
$("#fileinput-badge-icon").fileinput({
'theme': 'explorer-fas',
'uploadUrl': platformUrl + "/platform/basicServices/alOss/upload/unsm",
"uploadExtraData": {
"pathName": "other",
"buckType": 1
},
autoReplace: true,
dropZoneTitle: "点击或拖拽上传徽章图标(可选,用于更换)",
maxFileCount: 1,
maxFileSize: 5120,
allowedFileExtensions: ['jpg', 'jpeg', 'png', 'gif', 'webp'],
msgSizeTooLarge: '文件 "{name}" ({size} KB) 超过了允许大小 {maxSize} KB,最大支持上传5M文件'
}).on("filebatchselected", function () {
$(this).fileinput("upload");
}).on("fileuploaded", function (event, data) {
if (!data.response || !data.response.data || !data.response.data.ossPath) {
$.modal.alertWarning((data.response && data.response.msg) ? data.response.msg : "图片上传失败");
return;
}
var fullUrl = "https://img.zhengzai.tv/" + data.response.data.ossPath;
$("#badgeIconUrl").val(fullUrl);
$("#badgeIconPreview").attr("src", fullUrl);
$("#badgeIconPreviewWrap").show();
$("#badgeIconLegacyHint").hide();
});
});
$("#form-badge-edit").validate({
focusCleanup: true
});
function submitHandler() {
if (!$("#badgeIconUrl").val()) {
$.modal.msgWarning("请先上传徽章图标(若为历史 Emoji 数据,请上传一张图片作为图标)");
return;
}
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-badge-edit').serialize());
}
}
</script>
</body>
</html>
<!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>
徽章名称:<input type="text" name="name"/>
</li>
<li>
徽章类型:<select name="type" th:with="type=${@dict.getType('adam_caomei_badge_type')}">
<option value="">所有</option>
<option value="1">护照纪念徽章</option>
<option value="2">演出纪念徽章</option>
<!-- <option value="3">特殊徽章</option> -->
</select>
</li>
<li>
状态:<select name="displayStatus">
<option value="">所有</option>
<option value="0">下架</option>
<option value="1">已发布</option>
</select>
</li>
<li class="select-time">
<label>添加时间:</label>
<input type="text" class="time-input" id="badgeCreatedBegin" placeholder="开始日期" name="createdAtBegin"/>
<span> - </span>
<input type="text" class="time-input" id="badgeCreatedEnd" placeholder="结束日期" name="createdAtEnd"/>
</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="adam:caomei:badge:add">
<i class="fa fa-plus"></i> 新增
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('adam:caomei:badge:edit')}]];
var prefix = ctx + "adam/caomei/badge";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
modalName: "草莓护照徽章",
columns: [{
checkbox: true
},
{
field: 'mid',
title: '主键ID',
visible: false
},
{
field: 'badgeId',
title: '徽章ID'
},
{
field: 'icon',
title: '图标',
formatter: function(value, row, index) {
// 如果是图片链接,可以用 $.table.imageView(value)
// 如果是 emoji,直接返回
if(value && (value.startsWith('http') || value.startsWith('/'))) {
return $.table.imageView(value);
}
return '<span style="font-size: 24px;">' + value + '</span>';
}
},
{
field: 'name',
title: '名称'
},
{
field: 'subTitle',
title: '副标题',
formatter: function(value) {
return value ? value : '-';
}
},
{
field: 'type',
title: '类型',
formatter: function(value, row, index) {
if (value == 1) return '<span class="badge badge-info">护照纪念</span>';
if (value == 2) return '<span class="badge badge-primary">演出纪念</span>';
if (value == 3) return '<span class="badge badge-warning">特殊徽章</span>';
return value;
}
},
{
field: 'createdAt',
title: '添加时间',
formatter: function(value, row, index) {
if (!value) return '-';
return value.length >= 10 ? value.substring(0, 10) : value;
}
},
{
field: 'claimedCount',
title: '领取人数'
},
{
field: 'sort',
title: '排序(越大越靠前)'
},
{
field: 'displayStatus',
title: '状态',
align: 'center',
formatter: function (value, row, index) {
if (value == 1) {
return '<span class="badge badge-primary" style="background-color: #e6f3ff; color: #1890ff; padding: 5px 10px; border-radius: 4px;">已发布</span>';
} else {
return '<span class="badge badge-default" style="background-color: #f5f5f5; color: #999; padding: 5px 10px; border-radius: 4px;">下架</span>';
}
}
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
// 详情按钮
actions.push('<a class="btn btn-info btn-sm" style="margin-right: 5px;" href="javascript:void(0)" onclick="detail(\'' + row.badgeId + '\')"><i class="fa fa-eye"></i>详情</a>');
// 仅下架状态可修改(编辑)
if (row.displayStatus == 0) {
actions.push('<a class="btn btn-success btn-sm ' + editFlag + '" style="margin-right: 5px;" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.badgeId + '\')"><i class="fa fa-edit"></i>编辑</a>');
}
// 下架/发布按钮
if (row.displayStatus == 1) {
actions.push('<a class="btn btn-danger btn-sm" style="margin-right: 5px;" href="javascript:void(0)" onclick="disable(\'' + row.badgeId + '\')"><i class="fa fa-arrow-down"></i>下架</a>');
} else {
actions.push('<a class="btn btn-primary btn-sm" style="margin-right: 5px;" href="javascript:void(0)" onclick="enable(\'' + row.badgeId + '\')"><i class="fa fa-upload"></i>发布</a>');
}
// 领取用户按钮
actions.push('<a class="btn btn-warning btn-sm" href="javascript:void(0)" onclick="claimedUsers(\'' + row.badgeId + '\')"><i class="fa fa-users"></i>领取用户</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
/* 徽章下架 */
function disable(badgeId) {
$.modal.confirm("确认要下架该徽章吗?", function() {
$.operate.post(prefix + "/changeStatus", { "badgeId": badgeId, "displayStatus": 0 });
});
}
/* 徽章发布 */
function enable(badgeId) {
$.modal.confirm("确认要发布该徽章吗?", function() {
$.operate.post(prefix + "/changeStatus", { "badgeId": badgeId, "displayStatus": 1 });
});
}
/* 详情 */
function detail(badgeId) {
$.modal.open("徽章详情", prefix + "/detail/" + badgeId);
}
/* 领取用户 */
function claimedUsers(badgeId) {
if (!badgeId) {
$.modal.msgError("未找到徽章ID");
return;
}
$.modal.openOptions({
title: "领取用户",
url: prefix + "/claimUsers/" + badgeId,
skin: 'layui-layer-gray',
btn: ['关闭'],
yes: function (index, layero) {
layer.close(index);
}
});
}
</script>
</body>
</html>
\ No newline at end of file
<!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" th:if="${detail != null}">
<div class="row">
<div class="col-sm-12">
<div class="ibox">
<div class="ibox-title"><h5>申请信息</h5></div>
<div class="ibox-content">
<table class="table table-bordered table-striped">
<tbody>
<tr><td class="col-sm-2">申请ID</td><td th:text="${detail.applyRecordId}">-</td></tr>
<tr><td>申请账号</td><td th:text="${detail.userId}">-</td></tr>
<tr><td>用户名</td><td th:text="${detail.nickname != null && detail.nickname != '' ? detail.nickname : '-'}">-</td></tr>
<tr><td>姓名</td><td th:text="${detail.realName != null && detail.realName != '' ? detail.realName : '-'}">-</td></tr>
<tr><td>证件号</td><td th:text="${detail.idCard != null && detail.idCard != '' ? detail.idCard : '-'}">-</td></tr>
<tr><td>申请徽章</td><td th:text="${detail.badgeName != null && detail.badgeName != '' ? detail.badgeName : '-'}">-</td></tr>
<tr><td>关联演出</td><td th:text="${detail.performanceName != null && detail.performanceName != '' ? detail.performanceName : '-'}">-</td></tr>
<tr>
<td>申请附件</td>
<td>
<span th:if="${detail.proofImageUrls == null or detail.proofImageUrls.isEmpty()}">-</span>
<a th:each="u : ${detail.proofImageUrls}" th:href="${u}" target="_blank" style="display:inline-block;margin:0 8px 8px 0;">
<img th:src="${u}" style="max-height: 90px; border-radius: 4px;"/>
</a>
</td>
</tr>
<tr>
<td>审核状态</td>
<td>
<span th:if="${detail.auditStatus == 0}" class="label label-warning">待审核</span>
<span th:if="${detail.auditStatus == 1}" class="label label-success">已通过</span>
<span th:if="${detail.auditStatus == 2}" class="label label-danger">已驳回</span>
</td>
</tr>
<tr><td>申请时间</td><td th:text="${detail.createdAt != null ? #dates.format(detail.createdAt, 'yyyy-MM-dd HH:mm:ss') : '-'}">-</td></tr>
<tr><td>审核时间</td><td th:text="${detail.updatedAt != null ? #dates.format(detail.updatedAt, 'yyyy-MM-dd HH:mm:ss') : '-'}">-</td></tr>
<tr th:if="${detail.auditStatus == 2}">
<td>驳回理由</td>
<td th:text="${detail.rejectReason != null && detail.rejectReason != '' ? detail.rejectReason : '-'}">-</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="container-div" th:if="${detail == null}">
<div class="alert alert-warning">未找到申请信息</div>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
$(function() {
// 详情弹窗无需确认按钮,仅保留关闭
var index = parent.layer.getFrameIndex(window.name);
if (index) {
var $layero = parent.$("#layui-layer" + index);
$layero.find(".layui-layer-btn0").hide();
}
});
</script>
</body>
</html>
<!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>
用户名/姓名:<input type="text" name="userName" placeholder="昵称或姓名"/>
</li>
<li>
申请状态:
<select name="auditStatus">
<option value="">全部</option>
<option value="0">待审核</option>
<option value="1">已通过</option>
<option value="2">已驳回</option>
</select>
</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="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var detailFlag = [[${@permission.hasPermi('adam:caomei:badgeApplyAudit:list')}]];
var passFlag = [[${@permission.hasPermi('adam:caomei:badgeApplyAudit:edit')}]];
var rejectFlag = [[${@permission.hasPermi('adam:caomei:badgeApplyAudit:edit')}]];
var prefix = ctx + "adam/caomei/badgeApplyAudit";
$(function() {
var options = {
url: prefix + "/list",
formId: "formId",
modalName: "补签审核",
columns: [
{ field: 'applyRecordId', title: '申请ID' },
{ field: 'userId', title: '申请账号' },
{ field: 'realName', title: '姓名', formatter: function(v) { return v || '-'; } },
{ field: 'idCard', title: '证件号', formatter: function(v) { return v || '-'; } },
{ field: 'badgeName', title: '申请徽章', formatter: function(v) { return v || '-'; } },
{ field: 'performanceName', title: '关联演出', formatter: function(v) { return v || '-'; } },
{
field: 'proofImageUrl',
title: '申请附件',
align: 'center',
formatter: function(value, row) {
var urls = row.proofImageUrls;
if (!urls || urls.length === 0) {
if (!value) return '-';
urls = [value];
}
var html = [];
for (var i = 0; i < urls.length; i++) {
var u = urls[i];
if (!u) continue;
html.push('<a href="' + u + '" target="_blank" title="查看原图"><img src="' + u + '" style="height:32px;max-width:60px;margin:0 2px;cursor:pointer;border-radius:3px;"/></a>');
}
return html.length ? html.join('') : '-';
}
},
{
field: 'auditStatus',
title: '审核状态',
align: 'center',
formatter: function(value) {
if (value === 0) return '<span class="label label-warning">待审核</span>';
if (value === 1) return '<span class="label label-success">已通过</span>';
if (value === 2) return '<span class="label label-danger">已驳回</span>';
return '-';
}
},
{
title: '操作',
align: 'center',
formatter: function(value, row) {
var actions = [];
actions.push('<a class="btn btn-info btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick=\'detail(' + JSON.stringify(row.applyRecordId) + ')\'><i class="fa fa-eye"></i>详情</a> ');
if (row.auditStatus === 0) {
actions.push('<a class="btn btn-success btn-xs ' + passFlag + '" href="javascript:void(0)" onclick=\'passAudit(' + JSON.stringify(row.applyRecordId) + ')\'><i class="fa fa-check"></i>通过</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + rejectFlag + '" href="javascript:void(0)" onclick=\'rejectAudit(' + JSON.stringify(row.applyRecordId) + ')\'><i class="fa fa-close"></i>驳回</a>');
}
return actions.join('');
}
}
]
};
$.table.init(options);
});
function detail(applyRecordId) {
$.modal.open("补签详情", prefix + "/detail/" + encodeURIComponent(applyRecordId));
}
function passAudit(applyRecordId) {
$.modal.confirm("确认审核通过并为用户发放对应徽章吗?", function() {
$.operate.post(prefix + "/pass", { applyRecordId: applyRecordId });
});
}
function rejectAudit(applyRecordId) {
layer.prompt({
title: "请输入驳回理由",
formType: 2,
maxlength: 255
}, function(value, index) {
layer.close(index);
var reason = $.trim(value);
if (!reason) {
$.modal.msgError("驳回理由不能为空");
return;
}
$.operate.post(prefix + "/reject", { applyRecordId: applyRecordId, rejectReason: reason });
});
}
</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" th:if="${detail != null}">
<div class="row">
<div class="col-sm-12">
<div class="ibox">
<div class="ibox-title"><h5>护照信息</h5></div>
<div class="ibox-content">
<table class="table table-bordered table-striped">
<tbody>
<tr><td class="col-sm-2">护照编号</td><td th:text="${detail.passportNo}">-</td></tr>
<tr><td>绑定状态</td>
<td>
<span th:if="${detail.status == 1}" class="label label-info">已绑定</span>
<span th:if="${detail.status == 0}" class="label label-default">未绑定</span>
<span th:if="${detail.status == 2}" class="label label-warning">已作废</span>
</td>
</tr>
<tr><td>批次号</td><td th:text="${detail.batchNo != null ? detail.batchNo : '-'}">-</td></tr>
<tr><td>首次绑定时间</td><td th:text="${detail.boundAt != null ? #dates.format(detail.boundAt, 'yyyy-MM-dd HH:mm:ss') : '-'}">-</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-12" th:if="${detail.userId != null and detail.userId != ''}">
<div class="ibox">
<div class="ibox-title"><h5>关联用户信息</h5></div>
<div class="ibox-content">
<table class="table table-bordered table-striped">
<tbody>
<tr><td class="col-sm-2">用户ID</td><td th:text="${detail.userId}">-</td></tr>
<tr><td>昵称</td><td th:text="${detail.nickname}">-</td></tr>
<tr><td>手机号</td><td th:text="${detail.mobile}">-</td></tr>
<tr><td>真实姓名</td><td th:text="${detail.realName}">-</td></tr>
<tr><td>证件号</td><td th:text="${detail.idCard}">-</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-12" th:if="${detail.userId == null or detail.userId == ''}">
<div class="alert alert-info">当前护照未绑定用户</div>
</div>
<div class="col-sm-12" th:if="${detail.badges != null and !#lists.isEmpty(detail.badges)}">
<div class="ibox">
<div class="ibox-title"><h5>已领取徽章</h5></div>
<div class="ibox-content">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>徽章名称</th>
<th>图标</th>
<th>领取时间</th>
<th>获取途径</th>
</tr>
</thead>
<tbody>
<tr th:each="b : ${detail.badges}">
<td th:text="${b.badgeName}">-</td>
<td>
<span th:if="${b.icon != null and (b.icon.startsWith('http') or b.icon.startsWith('/'))}">
<img th:src="${b.icon}" style="max-height:28px;"/>
</span>
<span th:if="${b.icon != null and !(b.icon.startsWith('http') or b.icon.startsWith('/'))}" th:text="${b.icon}" style="font-size:22px;"></span>
</td>
<td th:text="${b.claimedAt != null ? #dates.format(b.claimedAt, 'yyyy-MM-dd HH:mm:ss') : '-'}">-</td>
<td>
<span th:if="${b.source == 1}">绑定护照自动发放</span>
<span th:if="${b.source == 2}">购票自动发放</span>
<span th:if="${b.source == 3}">补签审核通过</span>
<span th:if="${b.source == 4}">现场管理员手动发放</span>
<span th:if="${b.source == null or b.source &lt; 1 or b.source &gt; 4}">未知</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="container-div" th:if="${detail == null}">
<div class="alert alert-warning">未找到护照信息</div>
</div>
<th:block th:include="include :: footer" />
</body>
</html>
<!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>护照编号:</label>
<input type="text" name="passportNo" placeholder="模糊匹配"/>
</li>
<li>
<label>绑定状态:</label>
<select name="bindStatus">
<option value="">全部</option>
<option value="1">已绑定</option>
<option value="0">未绑定</option>
<option value="2">已作废</option>
</select>
</li>
<li>
<label>用户昵称/姓名:</label>
<input type="text" name="userName" placeholder="昵称或真实姓名"/>
</li>
<li>
<label>手机号:</label>
<input type="text" name="mobile" placeholder="完整或片段"/>
</li>
<li>
<label>证件号:</label>
<input type="text" name="idCard" 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="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var unbindFlag = [[${@permission.hasPermi('adam:caomei:passport:edit')}]];
var detailFlag = [[${@permission.hasPermi('adam:caomei:passport:list')}]];
var prefix = ctx + "adam/caomei/passport";
$(function() {
var options = {
url: prefix + "/list",
formId: "formId",
modalName: "护照",
columns: [
{ field: 'mid', title: '主键', visible: false },
{ field: 'passportNo', title: '护照ID' },
{
field: 'nickname',
title: '关联用户',
formatter: function(value, row, index) {
if (!value && row.bindStatus !== 1) {
return '<span class="text-muted">未绑定用户</span>';
}
return value || '-';
}
},
{ field: 'realName', title: '姓名', formatter: function(v) { return v || '-'; } },
{ field: 'mobile', title: '手机号', formatter: function(v) { return v || '-'; } },
{ field: 'idCard', title: '证件号', formatter: function(v) { return v || '-'; } },
{
field: 'bindStatus',
title: '绑定状态',
align: 'center',
formatter: function(value) {
if (value === 1) {
return '<span class="label label-info">已绑定</span>';
}
if (value === 0) {
return '<span class="label label-default">未绑定</span>';
}
if (value === 2) {
return '<span class="label label-warning">已作废</span>';
}
return value;
}
},
{ field: 'claimedBadgeCount', title: '已领取徽章数', align: 'center' },
{
title: '操作',
align: 'center',
formatter: function(value, row) {
var actions = [];
actions.push('<a class="btn btn-info btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick=\'openDetail(' + JSON.stringify(row.passportNo) + ')\'><i class="fa fa-eye"></i>查看详情</a> ');
if (row.bindStatus === 1) {
actions.push('<a class="btn btn-warning btn-xs ' + unbindFlag + '" href="javascript:void(0)" onclick=\'unbind(' + JSON.stringify(row.passportNo) + ')\'><i class="fa fa-unlink"></i>解绑用户</a>');
}
return actions.join('');
}
}
]
};
$.table.init(options);
setTimeout(function() {
renderBoundPassportCountToolbar();
loadBoundPassportCount();
}, 0);
});
function renderBoundPassportCountToolbar() {
if ($("#boundPassportCountBox").length > 0) {
return;
}
var html = '' +
'<div id="boundPassportCountBox" class="pull-left" style="margin-top: 10px; margin-right: 8px;">' +
' <span style="display: inline-block; line-height: 30px; margin-right: 6px;">已绑定护照数量:<strong id="boundPassportCount">加载中...</strong></span>' +
' <button type="button" class="btn btn-default btn-outline" onclick="loadBoundPassportCount()" title="刷新已绑定护照数量">' +
' <i class="fa fa-refresh"></i>' +
' </button>' +
'</div>';
var $toolbar = $(".fixed-table-toolbar").first();
if ($toolbar.length > 0) {
$toolbar.prepend(html);
}
}
function loadBoundPassportCount() {
$.get(prefix + "/bound/count", function(res) {
if (res && res.code === 0) {
$("#boundPassportCount").text(res.data || 0);
} else {
$("#boundPassportCount").text("-");
}
});
}
function openDetail(passportNo) {
$.modal.openTab("护照详情", prefix + "/detail/" + encodeURIComponent(passportNo));
}
function unbind(passportNo) {
$.modal.confirm("解绑后该护照将变为未绑定状态,用户需重新绑定。确认解绑?", function() {
$.operate.post(prefix + "/unbind", { passportNo: passportNo });
});
}
</script>
</body>
</html>
<!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>
......@@ -7,66 +7,72 @@
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-damai-edit" th:object="${kylinPerformanceDamaiVo}">
<div class="form-group">
<label class="col-sm-3 control-label is-required">performances_id</label>
<label class="col-sm-3 control-label">演出ID</label>
<div class="col-sm-8">
<input name="performancesId" th:field="*{performancesId}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">演出名称:</label>
<label class="col-sm-3 control-label">演出名称:</label>
<div class="col-sm-8">
<input name="title" th:field="*{title}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">是否同步</label>
<label class="col-sm-3 control-label is-required">是否开启同步大麦</label>
<div class="col-sm-8" th:if="*{syncDamai==1}">
<div class="radio check-box">
<input type="radio" value="1" name="performance_sync_damai" checked>同步</label>
<input type="radio" value="1" name="performance_sync_damai" checked>开启同步</label>
</div>
<div class="radio check-box">
<input type="radio" value="0" name="performance_sync_damai">同步</label>
<input type="radio" value="0" name="performance_sync_damai">关闭同步</label>
</div>
</div>
<div class="col-sm-8" th:if="*{syncDamai==0}">
<div class="radio check-box">
<input type="radio" value="1" name="performance_sync_damai">同步</label>
<input type="radio" value="1" name="performance_sync_damai">开启同步</label>
</div>
<div class="radio check-box">
<input type="radio" value="0" name="performance_sync_damai" checked>同步</label>
<input type="radio" value="0" name="performance_sync_damai" checked>关闭同步</label>
</div>
</div>
</div>
<div th:each="tickets : ${kylinPerformanceDamaiVo.damaiTickets}">
<div class="form-group">
<label class="col-sm-3 control-label is-required">票种名称:</label>
<div class="col-sm-8">
<input name="title" th:value="${tickets.title}" class="form-control" type="text" readonly>
<input name="ticketsId" th:value="${tickets.ticketsId}" class="form-control" type="hidden" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">是否同步:</label>
<div class="col-sm-8" th:if="${tickets.syncDamai==1}">
<div class="radio check-box">
<input type="radio" value="1" th:name="'ticket_syncDamai:'+${tickets.ticketsId}"
checked>同步</label>
</div>
<div class="radio check-box">
<input type="radio" value="0" th:name="'ticket_syncDamai:'+${tickets.ticketsId}">不同步</label>
</div>
</div>
<div class="col-sm-8" th:if="${tickets.syncDamai==0}">
<div class="radio check-box">
<input type="radio" value="1" th:name="'ticket_syncDamai:'+${tickets.ticketsId}">同步</label>
</div>
<div class="radio check-box">
<input type="radio" value="0" th:name="'ticket_syncDamai:'+${tickets.ticketsId}" checked>
不同步</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-8">
<span style="color: #EF9C26;font-size: 14px;">说明:开启同步大麦后,该演出的票务订单每隔一分钟同步大麦一次,直至售票结束;"开启后再关闭"需注意关闭同步后产生的的演出订单信息,及时对订单信息进行处理,避免订单信息遗漏导致的的客诉问题</span>
</div>
</div>
<!-- <div th:each="tickets : ${kylinPerformanceDamaiVo.damaiTickets}">-->
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label is-required">票种名称:</label>-->
<!-- <div class="col-sm-8">-->
<!-- <input name="title" th:value="${tickets.title}" class="form-control" type="text" readonly>-->
<!-- <input name="ticketsId" th:value="${tickets.ticketsId}" class="form-control" type="hidden" required>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label is-required">是否同步:</label>-->
<!-- <div class="col-sm-8" th:if="${tickets.syncDamai==1}">-->
<!-- <div class="radio check-box">-->
<!-- <input type="radio" value="1" th:name="'ticket_syncDamai:'+${tickets.ticketsId}"-->
<!-- checked>同步</label>-->
<!-- </div>-->
<!-- <div class="radio check-box">-->
<!-- <input type="radio" value="0" th:name="'ticket_syncDamai:'+${tickets.ticketsId}">不同步</label>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="col-sm-8" th:if="${tickets.syncDamai==0}">-->
<!-- <div class="radio check-box">-->
<!-- <input type="radio" value="1" th:name="'ticket_syncDamai:'+${tickets.ticketsId}">同步</label>-->
<!-- </div>-->
<!-- <div class="radio check-box">-->
<!-- <input type="radio" value="0" th:name="'ticket_syncDamai:'+${tickets.ticketsId}" checked>-->
<!-- 不同步</label>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<button type="button" class="btn btn-w-m btn-success" onclick="submitHandler()">
修改
......@@ -89,15 +95,15 @@
status: parseInt($("input[name^='performance_sync_damai']:checked").val())
}
paramList.push(param)
var ticketObj = JSON.parse('[[${kylinPerformanceDamaiVo.damaiTickets}]]');
$.each(ticketObj, function (i, damaiTickets) {
var param = {
id:damaiTickets.ticketsId,
type:"ticket",
status:parseInt($("input[name^='ticket_syncDamai:"+damaiTickets.ticketsId+"']:checked").val())
}
paramList.push(param)
});
// var ticketObj = JSON.parse('[[${kylinPerformanceDamaiVo.damaiTickets}]]');
// $.each(ticketObj, function (i, damaiTickets) {
// var param = {
// id:damaiTickets.ticketsId,
// type:"ticket",
// status:parseInt($("input[name^='ticket_syncDamai:"+damaiTickets.ticketsId+"']:checked").val())
// }
// paramList.push(param)
// });
$.operate.post(prefix + "/damai/change",
{params:JSON.stringify(paramList)},
......
......@@ -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>
......@@ -376,6 +385,7 @@
const auditStatus = '[[${kylinPerformanceMisVo.auditStatus}]]';
const status = '[[${kylinPerformanceMisVo.status}]]';
const fieldStatus = '[[${kylinPerformanceMisVo.fieldAuditStatus}]]';
const type = '[[${kylinPerformanceMisVo.type}]]';
const endTime = new Date('[[${kylinPerformanceMisVo.timeEnd}]]'.replaceAll("\"", "")).valueOf();
const now = new Date().valueOf();
// const et = new Date(endTime.replaceAll("\"", "")).valueOf();
......@@ -418,7 +428,7 @@
}
var damaiFlag = [[${@permission.hasPermi('kylin:performances:damai')}]];
if (damaiFlag == "hidden") {
if (damaiFlag == "hidden" || type != 101) {
document.getElementById("li-tab-5").style.display = "none";
}
......@@ -434,7 +444,7 @@
var orderImportFlag = [[${@permission.hasPermi('kylin:performances:orderImport')}]];
if (orderImportFlag == "hidden") {
document.getElementById("li-tab-8").style.display = "none";
document.getElementById("li-tab-8"). style.display = "none";
}
var payTxt = [[${@permission.hasPermi('kylin:performances:payTxt')}]];
......@@ -563,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("\"", ""));
});
......
......@@ -156,9 +156,9 @@
} else {
actions.push('<a class="btn btn-success btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick="$.operate.detailTab(\'' + row.performancesId + '\')"><i class="fa fa-edit"></i>查看</a> ');
}
if (row.syncDamai == 1) {
actions.push('<a class="btn btn-warning btn-xs ' + expertFlag + '" href="javascript:void(0)" onclick="f(\'' + row.performancesId + '\')"><i class="fa fa-remove"></i>同步</a>');
}
// if (row.syncDamai == 1) {
// actions.push('<a class="btn btn-warning btn-xs ' + expertFlag + '" href="javascript:void(0)" onclick="f(\'' + row.performancesId + '\')"><i class="fa fa-remove"></i>同步</a>');
// }
return actions.join('');
}
}]
......
package com.liquidnet.client.admin.zhengzai.adam.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeClaimUserSearchParam;
import com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeSearchParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeClaimUserVo;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeVo;
import com.liquidnet.service.adam.entity.AdamCaomeiBadge;
/**
* 草莓护照-徽章管理
*/
public interface IAdamCaomeiBadgeAdminService extends IService<AdamCaomeiBadge> {
/**
* 徽章管理(每个徽章领取人数)
* @param param
* @return
*/
PageInfo<AdamCaomeiBadgeVo> listWithClaimedCount(AdamCaomeiBadgeSearchParam param);
/**
* 徽章领取用户列表
* @param param
* @return
*/
PageInfo<AdamCaomeiBadgeClaimUserVo> listClaimUsers(AdamCaomeiBadgeClaimUserSearchParam param);
/**
* 清除用户端「上架草莓徽章列表」Redis 缓存,与 adam 侧 {@code AdamRdmService#delPublishedCaomeiBadges} 一致。
* 后台新增/编辑/上下架成功后应调用,避免用户端仍读到旧列表。
*/
void delPublishedCaomeiBadges();
/**
* kylin 演出是否存在(performances_id)
*/
boolean kylinPerformanceExists(String performancesId);
/**
* 是否存在与名称相同的其他徽章(trim 后精确匹配)
*
* @param name 徽章名称
* @param excludeBadgeId 编辑时排除当前徽章 ID;新增传 null 或空
*/
boolean existsOtherBadgeWithSameName(String name, String excludeBadgeId);
}
package com.liquidnet.client.admin.zhengzai.adam.service;
import com.github.pagehelper.PageInfo;
import com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeApplyAuditSearchParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyAuditDetailVo;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyAuditVo;
public interface IAdamCaomeiBadgeApplyAuditAdminService {
PageInfo<AdamCaomeiBadgeApplyAuditVo> listApplyAudits(AdamCaomeiBadgeApplyAuditSearchParam param);
AdamCaomeiBadgeApplyAuditDetailVo getApplyAuditDetail(String applyRecordId);
boolean passApplyAudit(String applyRecordId);
boolean rejectApplyAudit(String applyRecordId, String rejectReason);
}
package com.liquidnet.client.admin.zhengzai.adam.service;
import com.github.pagehelper.PageInfo;
import com.liquidnet.service.adam.dto.param.AdamCaomeiPassportSearchParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportDetailVo;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportListVo;
/**
* 草莓护照-护照管理
*/
public interface IAdamCaomeiPassportAdminService {
PageInfo<AdamCaomeiPassportListVo> listPassports(AdamCaomeiPassportSearchParam param);
int countBoundPassports();
AdamCaomeiPassportDetailVo getPassportDetail(String passportNo);
boolean unbindPassport(String passportNo);
}
package com.liquidnet.client.admin.zhengzai.adam.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamCaomeiBadgeApplyAuditAdminService;
import com.liquidnet.client.admin.zhengzai.adam.util.CaomeiBadgeApplyProofUrls;
import com.liquidnet.service.adam.dto.AdamCaomeiBadgeApplyAuditDetailDto;
import com.liquidnet.service.adam.dto.AdamCaomeiBadgeApplyAuditDto;
import com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeApplyAuditSearchParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyAuditDetailVo;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyAuditVo;
import com.liquidnet.service.adam.entity.AdamCaomeiBadgeApplyRecord;
import com.liquidnet.service.adam.mapper.AdamCaomeiBadgeApplyRecordMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class AdamCaomeiBadgeApplyAuditAdminServiceImpl implements IAdamCaomeiBadgeApplyAuditAdminService {
@Autowired
private AdamCaomeiBadgeApplyRecordMapper badgeApplyRecordMapper;
@Override
public PageInfo<AdamCaomeiBadgeApplyAuditVo> listApplyAudits(AdamCaomeiBadgeApplyAuditSearchParam param) {
if (param == null) {
param = new AdamCaomeiBadgeApplyAuditSearchParam();
}
List<AdamCaomeiBadgeApplyAuditDto> rows = badgeApplyRecordMapper.selectAuditList(
StringUtils.trimToEmpty(param.getUserName()),
param.getAuditStatus()
);
PageInfo<AdamCaomeiBadgeApplyAuditDto> dtoPage = new PageInfo<>(rows);
List<AdamCaomeiBadgeApplyAuditVo> voList = dtoPage.getList().stream().map(item -> {
AdamCaomeiBadgeApplyAuditVo vo = new AdamCaomeiBadgeApplyAuditVo();
BeanUtils.copyProperties(item, vo);
vo.setIdCard(maskIdCard(item.getIdCard()));
vo.setProofImageUrls(CaomeiBadgeApplyProofUrls.parse(item.getProofImageUrl()));
return vo;
}).collect(Collectors.toList());
PageInfo<AdamCaomeiBadgeApplyAuditVo> voPage = new PageInfo<>(voList);
voPage.setTotal(dtoPage.getTotal());
return voPage;
}
@Override
public AdamCaomeiBadgeApplyAuditDetailVo getApplyAuditDetail(String applyRecordId) {
if (StringUtils.isBlank(applyRecordId)) {
return null;
}
AdamCaomeiBadgeApplyAuditDetailDto detail = badgeApplyRecordMapper.selectAuditDetailByApplyRecordId(applyRecordId.trim());
if (detail == null) {
return null;
}
AdamCaomeiBadgeApplyAuditDetailVo vo = new AdamCaomeiBadgeApplyAuditDetailVo();
BeanUtils.copyProperties(detail, vo);
vo.setIdCard(maskIdCard(detail.getIdCard()));
vo.setProofImageUrls(CaomeiBadgeApplyProofUrls.parse(detail.getProofImageUrl()));
return vo;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean passApplyAudit(String applyRecordId) {
if (StringUtils.isBlank(applyRecordId)) {
return false;
}
AdamCaomeiBadgeApplyRecord record = badgeApplyRecordMapper.selectOne(
Wrappers.lambdaQuery(AdamCaomeiBadgeApplyRecord.class)
.eq(AdamCaomeiBadgeApplyRecord::getApplyRecordId, applyRecordId.trim())
.last("limit 1")
);
if (record == null || record.getAuditStatus() == null || record.getAuditStatus() != 0) {
return false;
}
if (StringUtils.isBlank(record.getUserId()) || StringUtils.isBlank(record.getBadgeId())) {
return false;
}
int updated = badgeApplyRecordMapper.passAudit(applyRecordId.trim());
if (updated <= 0) {
return false;
}
return true;
}
@Override
public boolean rejectApplyAudit(String applyRecordId, String rejectReason) {
if (StringUtils.isBlank(applyRecordId) || StringUtils.isBlank(rejectReason)) {
return false;
}
return badgeApplyRecordMapper.rejectAudit(applyRecordId.trim(), rejectReason.trim()) > 0;
}
private static String maskIdCard(String idCard) {
if (StringUtils.isBlank(idCard)) {
// 未实名或无证件信息
return "";
}
if (idCard.length() > 8) {
return idCard.substring(0, 4) + "****" + idCard.substring(idCard.length() - 4);
}
return "****";
}
}
......@@ -53,4 +53,10 @@ 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;
// 已发布状态徽章过期时间:30天
public static final long CAOMEI_BADGE_PUBLISHED_EXPIRE = 30 * 24 * 60 * 60;
}
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